Skip to content

Commit

Permalink
feat: Item editors (#91)
Browse files Browse the repository at this point in the history
* feat: ItemTemplate editor

* test: add some integration test cases

* Added item loot template

* Added disenchant, prospecting and milling loot

* Added item-enchantment-template

* chore: added faction-rank to item-template-component

* Updated tooltips

* Updated tooltips

* chore: add options for item-template

* chore: add more options and flags for item-template

* chore: remove useless space

* chore: remove useless space

* Updated item-template tooltips

* chore: add all tooltips

* chore: add selectors in html

* chore: add more selectors

* Added selectors in item_template

* Fixed BagFamily field name
  • Loading branch information
FrancescoBorzi authored and Helias committed Sep 1, 2019
1 parent 9ec6588 commit 44defb2
Show file tree
Hide file tree
Showing 50 changed files with 3,450 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,13 @@

<br>

<span class="category-title">Gameobject Data</span>
<span class="category-title">
Gameobject Data
<i
class="fas fa-info-circle ml-1" [placement]="'auto'"
[tooltip]="GAMEOBJECT_DATA_TOOLTIP"
></i>
</span>

<div class="row">
<div class="form-group col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2" *ngFor="let item of [].constructor(24); let i = index">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export class GameobjectTemplateComponent extends SingleRowEditorComponent<Gameob

public readonly GAMEOBJECT_TYPE = GAMEOBJECT_TYPE;
public readonly GAMEOBJECT_ICON = GAMEOBJECT_ICON;
public readonly GAMEOBJECT_DATA_TOOLTIP = 'Data0-Data23 fields change their meanings according to the selected TYPE. ' +
'Keira3 will try to reflect their names and show tooltips accordingly whenever the gameobject TYPE is changed';

/* istanbul ignore next */ // because of: https://github.com/gotwarlost/istanbul/issues/690
constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Component } from '@angular/core';

import { ItemHandlerService } from '../../../../services/handlers/item-handler.service';
import { DisenchantLootTemplate } from '../../../../types/disenchant-loot-template.type';
import { DisenchantLootTemplateService } from '../../../../services/editors/item/disenchant-loot-template.service';
import { LootTemplateComponent } from '../../shared/loot-template/loot-template.component';

@Component({
selector: 'app-disenchant-loot-template',
templateUrl: '../../shared/loot-template/loot-template.component.html',
styleUrls: ['../../shared/loot-template/loot-template.component.scss']
})
export class DisenchantLootTemplateComponent extends LootTemplateComponent<DisenchantLootTemplate> {

/* istanbul ignore next */ // because of: https://github.com/gotwarlost/istanbul/issues/690
constructor(
public editorService: DisenchantLootTemplateService,
public handlerService: ItemHandlerService,
) {
super(editorService, handlerService);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { of } from 'rxjs';
import Spy = jasmine.Spy;

import { DisenchantLootTemplateComponent } from './disenchant-loot-template.component';
import { DisenchantLootTemplateModule } from './disenchant-loot-template.module';
import { QueryService } from '../../../../services/query.service';
import { DisenchantLootTemplate } from '../../../../types/disenchant-loot-template.type';
import { ItemHandlerService } from '../../../../services/handlers/item-handler.service';
import { MultiRowEditorPageObject } from '../../../../test-utils/multi-row-editor-page-object';
import { DisenchantLootTemplateService } from '../../../../services/editors/item/disenchant-loot-template.service';

class DisenchantLootTemplatePage extends MultiRowEditorPageObject<DisenchantLootTemplateComponent> {}

describe('DisenchantLootTemplate integration tests', () => {
let component: DisenchantLootTemplateComponent;
let fixture: ComponentFixture<DisenchantLootTemplateComponent>;
let queryService: QueryService;
let querySpy: Spy;
let handlerService: ItemHandlerService;
let page: DisenchantLootTemplatePage;

const id = 1234;

const originalRow0 = new DisenchantLootTemplate();
const originalRow1 = new DisenchantLootTemplate();
const originalRow2 = new DisenchantLootTemplate();
originalRow0.Entry = originalRow1.Entry = originalRow2.Entry = id;
originalRow0.Item = 0;
originalRow1.Item = 1;
originalRow2.Item = 2;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
DisenchantLootTemplateModule,
RouterTestingModule,
],
})
.compileComponents();
}));

function setup(creatingNew: boolean, lootId = id) {
spyOn(TestBed.get(DisenchantLootTemplateService), 'getLootId').and.returnValue(of(
{ results: [{ lootId }] }
));

handlerService = TestBed.get(ItemHandlerService);
handlerService['_selected'] = `${id}`;
handlerService.isNew = creatingNew;

queryService = TestBed.get(QueryService);
querySpy = spyOn(queryService, 'query').and.returnValue(of());

spyOn(queryService, 'selectAll').and.returnValue(of(
{ results: creatingNew ? [] : [originalRow0, originalRow1, originalRow2] }
));

fixture = TestBed.createComponent(DisenchantLootTemplateComponent);
component = fixture.componentInstance;
page = new DisenchantLootTemplatePage(fixture);
fixture.autoDetectChanges(true);
fixture.detectChanges();
}

describe('Creating new', () => {
beforeEach(() => setup(true));

it('should correctly initialise', () => {
page.expectDiffQueryToBeEmpty();
page.expectFullQueryToBeEmpty();
expect(page.formError.hidden).toBe(true);
expect(page.addNewRowBtn.disabled).toBe(false);
expect(page.deleteSelectedRowBtn.disabled).toBe(true);
expect(page.getInputById('Item').disabled).toBe(true);
expect(page.getInputById('Reference').disabled).toBe(true);
expect(page.getInputById('Chance').disabled).toBe(true);
expect(page.getInputById('QuestRequired').disabled).toBe(true);
expect(page.getInputById('LootMode').disabled).toBe(true);
expect(page.getInputById('GroupId').disabled).toBe(true);
expect(page.getInputById('MinCount').disabled).toBe(true);
expect(page.getInputById('MaxCount').disabled).toBe(true);
expect(page.getInputById('Comment').disabled).toBe(true);
expect(page.getEditorTableRowsCount()).toBe(0);
});

it('adding new rows and executing the query should correctly work', () => {
const expectedQuery = 'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234) AND (`Item` IN (0, 1, 2));\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, ' +
'`MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 0, 0, 100, 0, 1, 0, 1, 1, \'\'),\n' +
'(1234, 1, 0, 100, 0, 1, 0, 1, 1, \'\'),\n' +
'(1234, 2, 0, 100, 0, 1, 0, 1, 1, \'\');';
querySpy.calls.reset();

page.addNewRow();
expect(page.getEditorTableRowsCount()).toBe(1);
page.addNewRow();
expect(page.getEditorTableRowsCount()).toBe(2);
page.addNewRow();
expect(page.getEditorTableRowsCount()).toBe(3);
page.clickExecuteQuery();

page.expectDiffQueryToContain(expectedQuery);
expect(querySpy).toHaveBeenCalledTimes(1);
expect(querySpy.calls.mostRecent().args[0]).toContain(expectedQuery);
});

it('adding a row and changing its values should correctly update the queries', () => {
page.addNewRow();
page.expectDiffQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234) AND (`Item` IN (0));\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, ' +
'`GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 0, 0, 100, 0, 1, 0, 1, 1, \'\');'
);
page.expectFullQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234);\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, ' +
'`GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 0, 0, 100, 0, 1, 0, 1, 1, \'\');'
);

page.setInputValueById('Chance', '1');
page.expectDiffQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234) AND (`Item` IN (0));\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, ' +
'`GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 0, 0, 1, 0, 1, 0, 1, 1, \'\');'
);
page.expectFullQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234);\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, ' +
'`GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 0, 0, 1, 0, 1, 0, 1, 1, \'\');'
);

page.setInputValueById('QuestRequired', '2');
page.expectDiffQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234) AND (`Item` IN (0));\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, ' +
'`GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 0, 0, 1, 2, 1, 0, 1, 1, \'\');'
);
page.expectFullQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234);\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, ' +
'`GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 0, 0, 1, 2, 1, 0, 1, 1, \'\');'
);

page.setInputValueById('Item', '123');
page.expectDiffQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234) AND (`Item` IN (123));\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, ' +
'`GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 123, 0, 1, 2, 1, 0, 1, 1, \'\');'
);
page.expectFullQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234);\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, ' +
'`GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 123, 0, 1, 2, 1, 0, 1, 1, \'\');'
);
});
});

describe('Editing existing', () => {
beforeEach(() => setup(false));

it('should correctly initialise', () => {
expect(page.formError.hidden).toBe(true);
page.expectDiffQueryToBeShown();
page.expectDiffQueryToBeEmpty();
page.expectFullQueryToContain('' +
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234);\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, ' +
'`GroupId`, `MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 0, 0, 100, 0, 1, 0, 1, 1, \'\'),\n' +
'(1234, 1, 0, 100, 0, 1, 0, 1, 1, \'\'),\n' +
'(1234, 2, 0, 100, 0, 1, 0, 1, 1, \'\');');
expect(page.getEditorTableRowsCount()).toBe(3);
});

it('deleting rows should correctly work', () => {
page.deleteRow(1);
expect(page.getEditorTableRowsCount()).toBe(2);
page.expectDiffQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234) AND (`Item` IN (1));'
);
page.expectFullQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234);\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, ' +
'`MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 0, 0, 100, 0, 1, 0, 1, 1, \'\'),\n' +
'(1234, 2, 0, 100, 0, 1, 0, 1, 1, \'\');'
);

page.deleteRow(1);
expect(page.getEditorTableRowsCount()).toBe(1);
page.expectDiffQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234) AND (`Item` IN (1, 2));'
);
page.expectFullQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234);\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, ' +
'`MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 0, 0, 100, 0, 1, 0, 1, 1, \'\');'
);

page.deleteRow(0);
expect(page.getEditorTableRowsCount()).toBe(0);
page.expectDiffQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE `Entry` = 1234;'
);
page.expectFullQueryToBeEmpty();
});

it('editing existing rows should correctly work', () => {
page.clickRowOfDatatable(1);
page.setInputValueById('LootMode', 1);

page.clickRowOfDatatable(2);
page.setInputValueById('GroupId', 2);

page.expectDiffQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234) AND (`Item` IN (2));\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, ' +
'`MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 2, 0, 100, 0, 1, 2, 1, 1, \'\');'
);
page.expectFullQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234);\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, ' +
'`MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 0, 0, 100, 0, 1, 0, 1, 1, \'\'),\n' +
'(1234, 1, 0, 100, 0, 1, 0, 1, 1, \'\'),\n' +
'(1234, 2, 0, 100, 0, 1, 2, 1, 1, \'\');'
);
});

it('combining add, edit and delete should correctly work', () => {
page.addNewRow();
expect(page.getEditorTableRowsCount()).toBe(4);

page.clickRowOfDatatable(1);
page.setInputValueById('Chance', 10);
expect(page.getEditorTableRowsCount()).toBe(4);

page.deleteRow(2);
expect(page.getEditorTableRowsCount()).toBe(3);

page.expectDiffQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234) AND (`Item` IN (1, 2, 3));\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, ' +
'`MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 1, 0, 10, 0, 1, 0, 1, 1, \'\'),\n' +
'(1234, 3, 0, 100, 0, 1, 0, 1, 1, \'\');'
);
page.expectFullQueryToContain(
'DELETE FROM `disenchant_loot_template` WHERE (`Entry` = 1234);\n' +
'INSERT INTO `disenchant_loot_template` (`Entry`, `Item`, `Reference`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, ' +
'`MinCount`, `MaxCount`, `Comment`) VALUES\n' +
'(1234, 0, 0, 100, 0, 1, 0, 1, 1, \'\'),\n' +
'(1234, 1, 0, 10, 0, 1, 0, 1, 1, \'\'),\n' +
'(1234, 3, 0, 100, 0, 1, 0, 1, 1, \'\');'
);
});

it('using the same row id for multiple rows should correctly show an error', () => {
page.clickRowOfDatatable(2);
page.setInputValueById('Item', 0);

page.expectUniqueError();
});
});

it('should correctly show the warning if the loot id is not correctly set in the item template', () => {
setup(true, 0);

expect(page.query('.alert-info').innerText).toContain(
'You have to set the field `DisenchantID` of item_template in order to enable this feature.'
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';

import { TopBarModule } from '../../shared/top-bar/top-bar.module';
import { QueryOutputModule } from '../../shared/query-output/query-output.module';
import { DisenchantLootTemplateComponent } from './disenchant-loot-template.component';
import { ItemSelectorModule } from '../../shared/selectors/item-selector/item-selector.module';
import { TooltipModule } from 'ngx-bootstrap';
import { FlagsSelectorModule } from '../../shared/selectors/flags-selector/flags-selector.module';
import { NgxDatatableModule } from '@swimlane/ngx-datatable';

@NgModule({
declarations: [
DisenchantLootTemplateComponent,
],
imports: [
BrowserModule,
ReactiveFormsModule,
TopBarModule,
QueryOutputModule,
TooltipModule.forRoot(),
ItemSelectorModule,
FlagsSelectorModule,
NgxDatatableModule,
],
exports: [
DisenchantLootTemplateComponent,
],
})
export class DisenchantLootTemplateModule {}
Loading

0 comments on commit 44defb2

Please sign in to comment.