Skip to content

Commit

Permalink
Merge 0d1127c into 89e509e
Browse files Browse the repository at this point in the history
  • Loading branch information
Helias committed May 3, 2020
2 parents 89e509e + 0d1127c commit b818a35
Show file tree
Hide file tree
Showing 13 changed files with 309 additions and 31 deletions.
23 changes: 18 additions & 5 deletions src/app/features/quest/quest-preview/quest-preview.component.html
Expand Up @@ -28,30 +28,30 @@ <h5 id="title" *ngIf="!!service.title">{{ service.title }}</h5>
</p>
<!-- Quest starter -->
<p *ngIf="service.questGivenByItem$ | async as qitem">
<img [src]="'assets/img/quest/' + questStartIcon" id="questStartIcon">
<img [src]="'assets/img/quest/' + questStartIcon" id="itemQuestStartIcon">
Start:
<keira-icon [size]="'small'" [itemId]="qitem"></keira-icon>
<strong class="colored"> {{ service.questStarterItem$ | async }}</strong> <span class="greyed"> [{{ qitem }}]</span>
</p>
<div *ngIf="service.creatureQueststarterList.length > 0" id="npc-start">
<p *ngFor="let q of service.creatureQueststarterList">
<img [src]="'assets/img/quest/' + questStartIcon" id="questStartIcon"> NPC Start: <strong class="colored">{{ service.mysqlQueryService.getCreatureNameById(q.id) | async }}</strong> <span class="greyed"> [{{ q.id }}]</span>
<img [src]="'assets/img/quest/' + questStartIcon" id="creatureQuestStartIcon"> NPC Start: <strong class="colored">{{ service.mysqlQueryService.getCreatureNameById(q.id) | async }}</strong> <span class="greyed"> [{{ q.id }}]</span>
</p>
</div>
<div *ngIf="service.gameobjectQueststarterList.length > 0" id="go-start">
<p *ngFor="let q of service.gameobjectQueststarterList">
<img [src]="'assets/img/quest/' + questStartIcon" id="questStartIcon"> GO Start: <strong class="colored">{{ service.mysqlQueryService.getGameObjectNameById(q.id) | async }}</strong> <span class="greyed"> [{{ q.id }}]</span>
<img [src]="'assets/img/quest/' + questStartIcon" id="gameobjectQuestStartIcon"> GO Start: <strong class="colored">{{ service.mysqlQueryService.getGameObjectNameById(q.id) | async }}</strong> <span class="greyed"> [{{ q.id }}]</span>
</p>
</div>
<!-- Quest ender -->
<div *ngIf="service.creatureQuestenderList.length > 0" id="npc-end">
<p *ngFor="let q of service.creatureQuestenderList">
<img [src]="'assets/img/quest/' + questEndIcon" id="questEndIcon"> NPC End: <strong class="colored">{{ service.mysqlQueryService.getCreatureNameById(q.id) | async }}</strong> <span class="greyed"> [{{ q.id }}]</span>
<img [src]="'assets/img/quest/' + questEndIcon" id="creatureQuestEndIcon"> NPC End: <strong class="colored">{{ service.mysqlQueryService.getCreatureNameById(q.id) | async }}</strong> <span class="greyed"> [{{ q.id }}]</span>
</p>
</div>
<div *ngIf="service.gameobjectQuestenderList.length > 0" id="go-end">
<p *ngFor="let q of service.gameobjectQuestenderList">
<img [src]="'assets/img/quest/' + questEndIcon" id="questEndIcon"> GO End: <strong class="colored">{{ service.mysqlQueryService.getGameObjectNameById(q.id) | async }}</strong> <span class="greyed"> [{{ q.id }}]</span>
<img [src]="'assets/img/quest/' + questEndIcon" id="gameobjectQuestEndIcon"> GO End: <strong class="colored">{{ service.mysqlQueryService.getGameObjectNameById(q.id) | async }}</strong> <span class="greyed"> [{{ q.id }}]</span>
</p>
</div>
<p *ngIf="service.isRepeatable()">Repeatable</p>
Expand Down Expand Up @@ -98,6 +98,19 @@ <h5 id="title" *ngIf="!!service.title">{{ service.title }}</h5>
</li>
</ul>
</ng-container>

<div id="gains">
<p class="title">Gains</p>
<p id="rewardXP" *ngIf="service.rewardXP$ | async as xp">• {{ xp }} experience</p>
<p id="rewardTalents" *ngIf="service.questTemplate.RewardTalents">• {{ service.questTemplate.RewardTalents }} talent points</p>

<div id="rewardReputations" *ngFor="let i of [1,2,3,4,5]">
<p *ngIf="service.getRewardReputation(i, service.getRepReward$(i) | async); let repReward">
• {{ repReward }} reputation with {{ service.sqliteQueryService.getFactionNameById(service.questTemplate['RewardFactionID' + i]) | async }}
</p>
</div>

</div>
</div>
</perfect-scrollbar>
</div>
Expand Down
Expand Up @@ -6,18 +6,22 @@ import { QuestModule } from '../quest.module';
import { RouterTestingModule } from '@angular/router/testing';
import { QuestPreviewService } from './quest-preview.service';
import { PageObject } from '@keira-shared/testing/page-object';
import { QuestTemplateService } from '../quest-template/quest-template.service';
import { QuestTemplateAddonService } from '../quest-template-addon/quest-template-addon.service';
import { QuestTemplate } from '@keira-shared/types/quest-template.type';
import { QuestTemplateAddon } from '@keira-shared/types/quest-template-addon.type';
import { createMockObject } from '@keira-shared/utils/helpers';

class QuestPreviewComponentPage extends PageObject<QuestPreviewComponent> {
get title() { return this.query<HTMLHeadElement>('#title'); }
get level() { return this.query<HTMLParagraphElement>('#level'); }
get minLevel() { return this.query<HTMLParagraphElement>('#minlevel'); }
get startIcon() { return this.query<HTMLImageElement>('#questStartIcon'); }
get endIcon() { return this.query<HTMLImageElement>('#questEndIcon'); }
get creatureQuestStartIcon() { return this.query<HTMLImageElement>('#creatureQuestStartIcon'); }
get creatureQuestEndIcon() { return this.query<HTMLImageElement>('#creatureQuestEndIcon'); }
get questType() { return this.query<HTMLParagraphElement>('#type'); }
get classes() { return this.query<HTMLParagraphElement>('#classes'); }
get requiredSkill() { return this.query<HTMLParagraphElement>('#requiredSkill'); }
get rewardXP() { return this.query<HTMLParagraphElement>('#rewardXP'); }
get rewardTalents() { return this.query<HTMLParagraphElement>('#rewardTalents'); }
get rewardReputations() { return this.query<HTMLParagraphElement>('#rewardReputations'); }
get providedItem() { return this.query<HTMLParagraphElement>('#provided-item'); }

getRaces(assert = true) { return this.query<HTMLParagraphElement>('#races', assert); }
Expand All @@ -37,13 +41,11 @@ describe('QuestPreviewComponent', () => {

function setup() {
const service = TestBed.inject(QuestPreviewService);
const questTemplateService = TestBed.inject(QuestTemplateService);
const questTemplateAddonService = TestBed.inject(QuestTemplateAddonService);
const fixture: ComponentFixture<QuestPreviewComponent> = TestBed.createComponent(QuestPreviewComponent);
const component: QuestPreviewComponent = fixture.componentInstance;
const page = new QuestPreviewComponentPage(fixture);

return { fixture, component, service, page, questTemplateService, questTemplateAddonService };
return { fixture, component, service, page };
}

it('ngOnInit should initialise services', () => {
Expand Down Expand Up @@ -83,22 +85,23 @@ describe('QuestPreviewComponent', () => {

fixture.detectChanges();

expect(page.startIcon.src).toContain('assets/img/quest/quest_start.gif');
expect(page.endIcon.src).toContain('assets/img/quest/quest_end.gif');
expect(page.creatureQuestStartIcon.src).toContain('assets/img/quest/quest_start.gif');
expect(page.creatureQuestEndIcon.src).toContain('assets/img/quest/quest_end.gif');

periodicQuestSpy.and.returnValue('Daily');

fixture.detectChanges();

expect(page.startIcon.src).toContain('assets/img/quest/quest_start_daily.gif');
expect(page.endIcon.src).toContain('assets/img/quest/quest_end_daily.gif');
expect(page.creatureQuestStartIcon.src).toContain('assets/img/quest/quest_start_daily.gif');
expect(page.creatureQuestEndIcon.src).toContain('assets/img/quest/quest_end_daily.gif');
page.removeElement();
});

it('should show questType', () => {
const { fixture, service, page, questTemplateService } = setup();
const { fixture, service, page } = setup();
const questTemplate = createMockObject({ QuestInfoID: 41 }, QuestTemplate);
spyOnProperty(service, 'periodicQuest', 'get').and.returnValue('Daily');
questTemplateService.form.controls.QuestInfoID.setValue(41);
spyOnProperty(service, 'questTemplate', 'get').and.returnValue(questTemplate);

fixture.detectChanges();

Expand Down Expand Up @@ -136,7 +139,7 @@ describe('QuestPreviewComponent', () => {
});

it('should show required skill', async() => {
const { fixture, service, page, questTemplateAddonService } = setup();
const { fixture, service, page } = setup();
spyOnProperty(service, 'requiredSkill$', 'get').and.returnValue(Promise.resolve('Jewelcrafting'));

fixture.detectChanges();
Expand All @@ -145,7 +148,9 @@ describe('QuestPreviewComponent', () => {

expect(page.requiredSkill.innerText).toContain('Jewelcrafting');

questTemplateAddonService.form.controls.RequiredSkillPoints.setValue(10);
const questTemplateAddon = createMockObject({ RequiredSkillPoints: 10 }, QuestTemplateAddon);
spyOnProperty(service, 'questTemplateAddon', 'get').and.returnValue(questTemplateAddon);

fixture.detectChanges();
expect(page.requiredSkill.innerText).toContain('(10)');
page.removeElement();
Expand All @@ -166,4 +171,42 @@ describe('QuestPreviewComponent', () => {
expect(page.providedItem.innerText).toContain(mockStartItemName);
page.removeElement();
});

it('should show rewardXP', async() => {
const { fixture, service, page } = setup();
const questTemplate = createMockObject({ RewardXPDifficulty: 2, QuestLevel: 10 }, QuestTemplate);
spyOnProperty(service, 'rewardXP$', 'get').and.returnValue(Promise.resolve('200'));
spyOnProperty(service, 'questTemplate', 'get').and.returnValue(questTemplate);

fixture.detectChanges();
await fixture.whenStable();
fixture.detectChanges();

expect(page.rewardXP.innerText).toContain('200');

fixture.debugElement.nativeElement.remove();
});

it('should show RewardTalents', () => {
const { fixture, page, service } = setup();
const questTemplate = createMockObject({ RewardTalents: 2 }, QuestTemplate);
spyOnProperty(service, 'questTemplate', 'get').and.returnValue(questTemplate);

fixture.detectChanges();

expect(page.rewardTalents.innerText).toContain('2 talent points');
fixture.debugElement.nativeElement.remove();
});

it('should show rewardReputations', () => {
const { fixture, page, service } = setup();
const questTemplate = createMockObject({ RewardFactionID1: 72, RewardFactionValue1: 123 }, QuestTemplate);
spyOnProperty(service, 'questTemplate', 'get').and.returnValue(questTemplate);

fixture.detectChanges();

expect(page.rewardReputations.innerText).toContain('123');
fixture.debugElement.nativeElement.remove();
});

});
13 changes: 13 additions & 0 deletions src/app/features/quest/quest-preview/quest-preview.model.ts
@@ -1,3 +1,5 @@
import { TableRow } from '@keira-shared/types/general';

export interface Quest {
id: number;
title: string;
Expand All @@ -10,3 +12,14 @@ export interface DifficultyLevel {
green?: number;
grey?: number;
}

export class QuestReputationReward extends TableRow {
faction: number = 1;
quest_rate: number = 1;
quest_daily_rate: number = 1;
quest_weekly_rate: number = 1;
quest_monthly_rate: number = 1;
quest_repeatable_rate: number = 1;
creature_rate: number = 1;
spell_rate: number = 1;
}
122 changes: 119 additions & 3 deletions src/app/features/quest/quest-preview/quest-preview.service.spec.ts
Expand Up @@ -14,7 +14,10 @@ import { QuestHandlerService } from '../quest-handler.service';
import { MysqlQueryService } from '@keira-shared/services/mysql-query.service';
import { of } from 'rxjs';
import { DifficultyLevel } from './quest-preview.model';
import { QUEST_FLAG_DAILY, QUEST_FLAG_WEEKLY, QUEST_FLAG_SPECIAL_MONTHLY } from '@keira-shared/constants/quest-preview';
import { QUEST_FLAG_DAILY, QUEST_FLAG_WEEKLY, QUEST_FLAG_SPECIAL_MONTHLY,
QUEST_FLAG_SPECIAL_REPEATABLE, QUEST_FLAG_REPEATABLE, QUEST_PERIOD
} from '@keira-shared/constants/quest-preview';
import { SqliteQueryService } from '@keira-shared/services/sqlite-query.service';

describe('QuestPreviewService', () => {

Expand All @@ -33,6 +36,7 @@ describe('QuestPreviewService', () => {
const setup = () => {
const service = TestBed.inject(QuestPreviewService);
const mysqlQueryService = TestBed.inject(MysqlQueryService);
const sqliteQueryService = TestBed.inject(SqliteQueryService);
const questTemplateService = TestBed.inject(QuestTemplateService);
const questTemplateAddonService = TestBed.inject(QuestTemplateAddonService);
const questRequestItemsService = TestBed.inject(QuestRequestItemsService);
Expand All @@ -53,6 +57,7 @@ describe('QuestPreviewService', () => {
return {
service,
mysqlQueryService,
sqliteQueryService,
questTemplateService,
questTemplateAddonService,
questRequestItemsService,
Expand Down Expand Up @@ -146,18 +151,55 @@ describe('QuestPreviewService', () => {
const mockID = 123;
const mockItem = '1234';
const mockItemName = 'Helias Item';
const mockQuestReputationReward = {
faction: 1,
quest_rate: 1,
quest_daily_rate: 1,
quest_weekly_rate: 1,
quest_monthly_rate: 1,
quest_repeatable_rate: 1,
creature_rate: 1,
spell_rate: 1,
};

spyOn(mysqlQueryService, 'getItemByStartQuest').and.callFake(() => of(mockItem).toPromise());
spyOn(mysqlQueryService, 'getItemNameByStartQuest').and.callFake(() => of(mockItemName).toPromise());
spyOn(mysqlQueryService, 'getItemByStartQuest').and.callFake(() => Promise.resolve(mockItem));
spyOn(mysqlQueryService, 'getItemNameByStartQuest').and.callFake(() => Promise.resolve(mockItemName));
spyOn(mysqlQueryService, 'getReputationRewardByFaction').and.callFake(() => Promise.resolve([mockQuestReputationReward]));
questTemplateService.form.controls.ID.setValue(mockID);

expect(await service.questGivenByItem$).toBe(mockItem);
expect(await service.questStarterItem$).toBe(mockItemName);
expect(await service.getRepReward$(1)).toEqual([mockQuestReputationReward]);

expect(mysqlQueryService.getItemByStartQuest).toHaveBeenCalledTimes(1);
expect(mysqlQueryService.getItemByStartQuest).toHaveBeenCalledWith(mockID);
expect(mysqlQueryService.getItemNameByStartQuest).toHaveBeenCalledTimes(1);
expect(mysqlQueryService.getItemNameByStartQuest).toHaveBeenCalledWith(mockID);
expect(mysqlQueryService.getReputationRewardByFaction).toHaveBeenCalledTimes(1);
expect(mysqlQueryService.getReputationRewardByFaction).toHaveBeenCalledWith(null);
});

it('sqliteQuery', async() => {
const { service, sqliteQueryService, questTemplateService, questTemplateAddonService } = setup();
const mockSkillName = 'Mock Skill';
const mockSkill = 755;
const mockRewardXP = '450';
const mockDifficulty = 1;
const mockQuestLevel = 2;
questTemplateAddonService.form.controls.RequiredSkillID.setValue(mockSkill);
questTemplateService.form.controls.RewardXPDifficulty.setValue(mockDifficulty);
questTemplateService.form.controls.QuestLevel.setValue(mockQuestLevel);

spyOn(sqliteQueryService, 'getSkillNameById').and.callFake(() => Promise.resolve(mockSkillName));
spyOn(sqliteQueryService, 'getRewardXP').and.callFake(() => Promise.resolve(mockRewardXP));

expect(await service.requiredSkill$).toBe(mockSkillName);
expect(await service.rewardXP$).toBe(mockRewardXP);

expect(sqliteQueryService.getSkillNameById).toHaveBeenCalledTimes(1);
expect(sqliteQueryService.getSkillNameById).toHaveBeenCalledWith(mockSkill);
expect(sqliteQueryService.getRewardXP).toHaveBeenCalledTimes(1);
expect(sqliteQueryService.getRewardXP).toHaveBeenCalledWith(mockDifficulty, mockQuestLevel);
});

it('difficultyLevels', () => {
Expand Down Expand Up @@ -372,4 +414,78 @@ describe('QuestPreviewService', () => {
expect(mysqlQueryService.getQuestTitleById).toHaveBeenCalledTimes(1);
expect(mysqlQueryService.getQuestTitleById).toHaveBeenCalledWith(id);
});

it('isRepeatable', () => {
const { service, questTemplateService, questTemplateAddonService } = setup();

expect(service.isRepeatable()).toBe(false);

questTemplateAddonService.form.controls.SpecialFlags.setValue(QUEST_FLAG_SPECIAL_REPEATABLE);
expect(service.isRepeatable()).toBe(true);

questTemplateService.form.controls.Flags.setValue(QUEST_FLAG_REPEATABLE);
expect(service.isRepeatable()).toBe(true);
});

describe('getRewardReputation', () => {
const mockRepValue = 123;
const mockRepFaction = 1;
const dailyRate = 3;
const weeklyRate = 4;
const monthlyRate = 5;
const repeatableRate = 6;
const questRate = 7;
const mockQuestReputationReward1 = {
faction: 1, quest_rate: 1, quest_daily_rate: 1, quest_weekly_rate: 1,
quest_monthly_rate: 1, quest_repeatable_rate: 1, creature_rate: 1, spell_rate: 1,
};
const mockQuestReputationReward2 = {
faction: 2, quest_rate: questRate, quest_daily_rate: dailyRate, quest_weekly_rate: weeklyRate,
quest_monthly_rate: monthlyRate, quest_repeatable_rate: repeatableRate, creature_rate: 2, spell_rate: 2,
};

it('with empty QuestReputationReward', () => {
const { service } = setup();
expect(service.getRewardReputation(1, [])).toBe(null);
});

it('QuestReputation values 1', () => {
const { service, questTemplateService } = setup();
questTemplateService.form.controls.RewardFactionID1.setValue(mockRepFaction);
questTemplateService.form.controls.RewardFactionValue1.setValue(mockRepValue);

expect(service.getRewardReputation(1, [])).toBe(mockRepValue);
expect(service.getRewardReputation(1, [mockQuestReputationReward1])).toBe(mockRepValue);
});

it('all dailyType and normal quest_rate', () => {
const { service, questTemplateService } = setup();
const getPeriodicQuestSpy: Spy = spyOn<any>(service, 'getPeriodicQuest');
questTemplateService.form.controls.RewardFactionID1.setValue(mockRepFaction);
questTemplateService.form.controls.RewardFactionValue1.setValue(mockRepValue);

getPeriodicQuestSpy.and.returnValue(QUEST_PERIOD.DAILY);
expect(service.getRewardReputation(1, [mockQuestReputationReward2])).toBe(mockRepValue * (dailyRate - 1));

getPeriodicQuestSpy.and.returnValue(QUEST_PERIOD.WEEKLY);
expect(service.getRewardReputation(1, [mockQuestReputationReward2])).toBe(mockRepValue * (weeklyRate - 1));

getPeriodicQuestSpy.and.returnValue(QUEST_PERIOD.MONTHLY);
expect(service.getRewardReputation(1, [mockQuestReputationReward2])).toBe(mockRepValue * (monthlyRate - 1));

getPeriodicQuestSpy.and.returnValue('mockPeriod');
expect(service.getRewardReputation(1, [mockQuestReputationReward2])).toBe(mockRepValue * (questRate - 1));
});

it('in case of repeatable quest', () => {
const { service, questTemplateService } = setup();
spyOn(service, 'isRepeatable').and.returnValue(true);
questTemplateService.form.controls.RewardFactionID1.setValue(mockRepFaction);
questTemplateService.form.controls.RewardFactionValue1.setValue(mockRepValue);

expect(service.getRewardReputation(1, [mockQuestReputationReward2])).toBe(mockRepValue * (repeatableRate - 1));
});

});

});

0 comments on commit b818a35

Please sign in to comment.