diff --git a/libs/features/quest/src/quest-template-locale/quest-template-locale.component.html b/libs/features/quest/src/quest-template-locale/quest-template-locale.component.html
index f5727560ead..9156f32cf6c 100644
--- a/libs/features/quest/src/quest-template-locale/quest-template-locale.component.html
+++ b/libs/features/quest/src/quest-template-locale/quest-template-locale.component.html
@@ -18,6 +18,16 @@
+
+
+
+
+
diff --git a/libs/features/quest/src/quest-template-locale/quest-template-locale.component.ts b/libs/features/quest/src/quest-template-locale/quest-template-locale.component.ts
index 5c3986f1fb5..c7ce7f2d92d 100644
--- a/libs/features/quest/src/quest-template-locale/quest-template-locale.component.ts
+++ b/libs/features/quest/src/quest-template-locale/quest-template-locale.component.ts
@@ -1,9 +1,9 @@
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
-import { EMOTE, QuestTemplateLocale } from '@keira/shared/acore-world-model';
+import { QUEST_LOCALE, QuestTemplateLocale } from '@keira/shared/acore-world-model';
import { MultiRowEditorComponent } from '@keira/shared/base-abstract-classes';
import { EditorButtonsComponent, QueryOutputComponent, TopBarComponent } from '@keira/shared/base-editor-components';
-import { GameobjectSelectorBtnComponent, SingleValueSelectorBtnComponent } from '@keira/shared/selectors';
+import { SingleValueSelectorBtnComponent } from '@keira/shared/selectors';
import { TranslateModule } from '@ngx-translate/core';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import { QuestHandlerService } from '../quest-handler.service';
@@ -30,16 +30,14 @@ import { NgxDatatableModule } from '@siemens/ngx-datatable';
SingleValueSelectorBtnComponent,
QuestPreviewComponent,
Model3DViewerComponent,
- GameobjectSelectorBtnComponent,
AsyncPipe,
EditorButtonsComponent,
NgxDatatableModule,
],
})
export class QuestTemplateLocaleComponent extends MultiRowEditorComponent {
- readonly EMOTE = EMOTE;
-
protected override readonly editorService = inject(QuestTemplateLocaleService);
readonly handlerService = inject(QuestHandlerService);
readonly questPreviewService = inject(QuestPreviewService);
+ protected readonly QUEST_LOCALE = QUEST_LOCALE;
}
diff --git a/libs/features/quest/src/quest-template-locale/quest-template-locale.integration.spec.ts b/libs/features/quest/src/quest-template-locale/quest-template-locale.integration.spec.ts
new file mode 100644
index 00000000000..dbd1087fb6a
--- /dev/null
+++ b/libs/features/quest/src/quest-template-locale/quest-template-locale.integration.spec.ts
@@ -0,0 +1,198 @@
+import { QuestTemplateLocale } from '@keira/shared/acore-world-model';
+import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { MysqlQueryService } from '@keira/shared/db-layer';
+import { of } from 'rxjs';
+import { QuestPreviewService } from '../quest-preview/quest-preview.service';
+import { QuestHandlerService } from '../quest-handler.service';
+import { QuestTemplateLocaleComponent } from './quest-template-locale.component';
+import { MultiRowEditorPageObject, TranslateTestingModule } from '@keira/shared/test-utils';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { ToastrModule } from 'ngx-toastr';
+import { ModalModule } from 'ngx-bootstrap/modal';
+import { RouterTestingModule } from '@angular/router/testing';
+import { KEIRA_APP_CONFIG_TOKEN, KEIRA_MOCK_CONFIG } from '@keira/shared/config';
+import Spy = jasmine.Spy;
+
+class QuestTemplateLocalePage extends MultiRowEditorPageObject { }
+
+describe('QuestTemplateLocale integration tests', () => {
+ const id = 1234;
+ let fixture: ComponentFixture;
+ let queryService: MysqlQueryService;
+ let querySpy: Spy;
+ let handlerService: QuestHandlerService;
+ let page: QuestTemplateLocalePage;
+
+ beforeEach(waitForAsync(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ BrowserAnimationsModule,
+ ToastrModule.forRoot(),
+ ModalModule.forRoot(),
+ QuestTemplateLocaleComponent,
+ RouterTestingModule,
+ TranslateTestingModule,
+ ],
+ providers: [QuestHandlerService, { provide: KEIRA_APP_CONFIG_TOKEN, useValue: KEIRA_MOCK_CONFIG }],
+ }).compileComponents();
+ }));
+
+ function setup(creatingNew: boolean) {
+ const originalRow = new QuestTemplateLocale();
+ originalRow.ID = id;
+
+ handlerService = TestBed.inject(QuestHandlerService);
+ handlerService['_selected'] = `${id}`;
+ handlerService.isNew = creatingNew;
+
+ queryService = TestBed.inject(MysqlQueryService);
+ querySpy = spyOn(queryService, 'query').and.returnValue(of([]));
+ spyOn(queryService, 'queryValue').and.returnValue(of());
+
+ spyOn(queryService, 'selectAll').and.returnValue(of(creatingNew ? [] : [originalRow]));
+ const initializeServicesSpy = spyOn(TestBed.inject(QuestPreviewService), 'initializeServices');
+ if (creatingNew) {
+ initializeServicesSpy.and.callThrough();
+ }
+
+ fixture = TestBed.createComponent(QuestTemplateLocaleComponent);
+ page = new QuestTemplateLocalePage(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('id').disabled).toBe(true);
+ expect(page.getInputById('title').disabled).toBe(true);
+ expect(page.getInputById('details').disabled).toBe(true);
+ expect(page.getInputById('objectives').disabled).toBe(true);
+ expect(page.getInputById('end-text').disabled).toBe(true);
+ expect(page.getInputById('completed-text').disabled).toBe(true);
+ expect(page.getInputById('objective-text-1').disabled).toBe(true);
+ expect(page.getInputById('objective-text-2').disabled).toBe(true);
+ expect(page.getInputById('objective-text-3').disabled).toBe(true);
+ expect(page.getInputById('objective-text-4').disabled).toBe(true);
+ expect(page.getEditorTableRowsCount()).toBe(0);
+ });
+
+ it('should correctly update the unsaved status', () => {
+ expect(handlerService.isQuestTemplateLocaleUnsaved).toBe(false);
+ page.addNewRow();
+ expect(handlerService.isQuestTemplateLocaleUnsaved).toBe(true);
+ page.deleteRow();
+ expect(handlerService.isQuestTemplateLocaleUnsaved).toBe(false);
+ });
+
+ it('adding new rows and executing the query should correctly work', () => {
+ const expectedQuery =
+ 'DELETE FROM `quest_template_locale` WHERE (`ID` = 1234) AND (`locale` IN (\'0\', \'1\', \'2\'));\n' +
+ 'INSERT INTO `quest_template_locale` (`ID`, `locale`, `Title`, `Details`, `Objectives`, `EndText`, `CompletedText`, ' +
+ '`ObjectiveText1`, `ObjectiveText2`, `ObjectiveText3`, `ObjectiveText4`, `VerifiedBuild`) VALUES\n' +
+ "(1234, '0', '', '', '', '', '', '', '', '', '', 0),\n" +
+ "(1234, '1', '', '', '', '', '', '', '', '', '', 0),\n" +
+ "(1234, '2', '', '', '', '', '', '', '', '', '', 0);";
+ 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.expectDiffQueryToContain(expectedQuery);
+
+ page.clickExecuteQuery();
+ 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 `quest_template_locale` WHERE (`ID` = 1234) AND (`locale` IN (\'0\'));\n' +
+ 'INSERT INTO `quest_template_locale` (`ID`, `locale`, `Title`, `Details`, `Objectives`, `EndText`, `CompletedText`, ' +
+ '`ObjectiveText1`, `ObjectiveText2`, `ObjectiveText3`, `ObjectiveText4`, `VerifiedBuild`) VALUES\n' +
+ "(1234, '0', '', '', '', '', '', '', '', '', '', 0);",
+ );
+ page.expectFullQueryToContain(
+ 'DELETE FROM `quest_template_locale` WHERE (`ID` = 1234);\n' +
+ 'INSERT INTO `quest_template_locale` (`ID`, `locale`, `Title`, `Details`, `Objectives`, `EndText`, `CompletedText`, ' +
+ '`ObjectiveText1`, `ObjectiveText2`, `ObjectiveText3`, `ObjectiveText4`, `VerifiedBuild`) VALUES\n' +
+ "(1234, '0', '', '', '', '', '', '', '', '', '', 0);",
+ );
+
+ page.setInputValueById('title', 'test');
+ page.expectDiffQueryToContain(
+ 'DELETE FROM `quest_template_locale` WHERE (`ID` = 1234) AND (`locale` IN (\'0\'));\n' +
+ 'INSERT INTO `quest_template_locale` (`ID`, `locale`, `Title`, `Details`, `Objectives`, `EndText`, `CompletedText`, ' +
+ '`ObjectiveText1`, `ObjectiveText2`, `ObjectiveText3`, `ObjectiveText4`, `VerifiedBuild`) VALUES\n' +
+ "(1234, '0', 'test', '', '', '', '', '', '', '', '', 0);",
+ );
+ page.expectFullQueryToContain(
+ 'DELETE FROM `quest_template_locale` WHERE (`ID` = 1234);\n' +
+ 'INSERT INTO `quest_template_locale` (`ID`, `locale`, `Title`, `Details`, `Objectives`, `EndText`, `CompletedText`, ' +
+ '`ObjectiveText1`, `ObjectiveText2`, `ObjectiveText3`, `ObjectiveText4`, `VerifiedBuild`) VALUES\n' +
+ "(1234, '0', 'test', '', '', '', '', '', '', '', '', 0);",
+ );
+
+ page.setInputValueById('completed-text', 'test2');
+ page.expectDiffQueryToContain(
+ 'DELETE FROM `quest_template_locale` WHERE (`ID` = 1234) AND (`locale` IN (\'0\'));\n' +
+ 'INSERT INTO `quest_template_locale` (`ID`, `locale`, `Title`, `Details`, `Objectives`, `EndText`, `CompletedText`, ' +
+ '`ObjectiveText1`, `ObjectiveText2`, `ObjectiveText3`, `ObjectiveText4`, `VerifiedBuild`) VALUES\n' +
+ "(1234, '0', 'test', '', '', '', 'test2', '', '', '', '', 0);",
+ );
+ page.expectFullQueryToContain(
+ 'DELETE FROM `quest_template_locale` WHERE (`ID` = 1234);\n' +
+ 'INSERT INTO `quest_template_locale` (`ID`, `locale`, `Title`, `Details`, `Objectives`, `EndText`, `CompletedText`, ' +
+ '`ObjectiveText1`, `ObjectiveText2`, `ObjectiveText3`, `ObjectiveText4`, `VerifiedBuild`) VALUES\n' +
+ "(1234, '0', 'test', '', '', '', 'test2', '', '', '', '', 0);",
+ );
+
+ page.setInputValueById('locale', 'deDE');
+ page.expectDiffQueryToContain(
+ 'DELETE FROM `quest_template_locale` WHERE (`ID` = 1234) AND (`locale` IN (\'deDE\'));\n' +
+ 'INSERT INTO `quest_template_locale` (`ID`, `locale`, `Title`, `Details`, `Objectives`, `EndText`, `CompletedText`, ' +
+ '`ObjectiveText1`, `ObjectiveText2`, `ObjectiveText3`, `ObjectiveText4`, `VerifiedBuild`) VALUES\n' +
+ "(1234, 'deDE', 'test', '', '', '', 'test2', '', '', '', '', 0);",
+ );
+ page.expectFullQueryToContain(
+ 'DELETE FROM `quest_template_locale` WHERE (`ID` = 1234);\n' +
+ 'INSERT INTO `quest_template_locale` (`ID`, `locale`, `Title`, `Details`, `Objectives`, `EndText`, `CompletedText`, ' +
+ '`ObjectiveText1`, `ObjectiveText2`, `ObjectiveText3`, `ObjectiveText4`, `VerifiedBuild`) VALUES\n' +
+ "(1234, 'deDE', 'test', '', '', '', 'test2', '', '', '', '', 0);",
+ );
+ });
+
+ it('adding a row changing its values and duplicate it should correctly update the queries', () => {
+ page.addNewRow();
+ page.setInputValueById('title', '1');
+ page.setInputValueById('completed-text', '2');
+ page.setInputValueById('locale', 'deDE');
+ page.duplicateSelectedRow();
+
+ page.expectDiffQueryToContain(
+ 'DELETE FROM `quest_template_locale` WHERE (`ID` = 1234) AND (`locale` IN (\'deDE\', \'0\'));\n' +
+ 'INSERT INTO `quest_template_locale` (`ID`, `locale`, `Title`, `Details`, `Objectives`, `EndText`, `CompletedText`, ' +
+ '`ObjectiveText1`, `ObjectiveText2`, `ObjectiveText3`, `ObjectiveText4`, `VerifiedBuild`) VALUES\n' +
+ "(1234, 'deDE', '1', '', '', '', '2', '', '', '', '', 0),\n" +
+ "(1234, '0', '1', '', '', '', '2', '', '', '', '', 0);",
+ );
+ page.expectFullQueryToContain(
+ 'DELETE FROM `quest_template_locale` WHERE (`ID` = 1234);\n' +
+ 'INSERT INTO `quest_template_locale` (`ID`, `locale`, `Title`, `Details`, `Objectives`, `EndText`, `CompletedText`, ' +
+ '`ObjectiveText1`, `ObjectiveText2`, `ObjectiveText3`, `ObjectiveText4`, `VerifiedBuild`) VALUES\n' +
+ "(1234, 'deDE', '1', '', '', '', '2', '', '', '', '', 0),\n" +
+ "(1234, '0', '1', '', '', '', '2', '', '', '', '', 0);",
+ );
+ });
+ });
+});
diff --git a/libs/features/quest/src/quest-template-locale/quest-template-locale.service.spec.ts b/libs/features/quest/src/quest-template-locale/quest-template-locale.service.spec.ts
new file mode 100644
index 00000000000..357b5fe0ace
--- /dev/null
+++ b/libs/features/quest/src/quest-template-locale/quest-template-locale.service.spec.ts
@@ -0,0 +1,27 @@
+import { TestBed } from '@angular/core/testing';
+import { RouterTestingModule } from '@angular/router/testing';
+import { MysqlQueryService, SqliteService } from '@keira/shared/db-layer';
+import { instance, mock } from 'ts-mockito';
+import { ToastrService } from 'ngx-toastr';
+import { QuestTemplateLocaleService } from './quest-template-locale.service';
+import { QuestHandlerService } from '../quest-handler.service';
+
+describe('QuestTemplateLocaleService', () => {
+ beforeEach(() =>
+ TestBed.configureTestingModule({
+ imports: [RouterTestingModule],
+ providers: [
+ { provide: MysqlQueryService, useValue: instance(mock(MysqlQueryService)) },
+ { provide: ToastrService, useValue: instance(mock(ToastrService)) },
+ { provide: SqliteService, useValue: instance(mock(SqliteService)) },
+ QuestHandlerService,
+ QuestTemplateLocaleService,
+ ],
+ }),
+ );
+
+ it('should be created', () => {
+ const service: QuestTemplateLocaleService = TestBed.inject(QuestTemplateLocaleService);
+ expect(service).toBeTruthy();
+ });
+});
diff --git a/libs/shared/acore-world-model/src/entities/quest-template-locale.type.ts b/libs/shared/acore-world-model/src/entities/quest-template-locale.type.ts
index 60cd948c16b..5fbf468aa49 100644
--- a/libs/shared/acore-world-model/src/entities/quest-template-locale.type.ts
+++ b/libs/shared/acore-world-model/src/entities/quest-template-locale.type.ts
@@ -1,9 +1,19 @@
-import { TableRow } from '@keira/shared/constants';
+import { Option, TableRow } from '@keira/shared/constants';
export const QUEST_TEMPLATE_LOCALE_TABLE = 'quest_template_locale';
export const QUEST_TEMPLATE_LOCALE_ID = 'ID';
export const QUEST_TEMPLATE_LOCALE_ID_2 = 'locale';
+export const QUEST_LOCALE: Option[] = [
+ { value: 'deDE', name: 'German (Germany)' },
+ { value: 'esES', name: 'Spanish (Spain)' },
+ { value: 'esMX', name: 'Spanish (Mexico)' },
+ { value: 'frFR', name: 'French (France)' },
+ { value: 'ruRU', name: 'Russian (Russia)' },
+ { value: 'zhCN', name: 'Chinese (China)' },
+ { value: 'zhTW', name: 'Chinese (Taiwan)' }
+];
+
export class QuestTemplateLocale extends TableRow {
ID: number = 0;
locale: string = '';
diff --git a/libs/shared/base-abstract-classes/src/service/editors/multi-row-editor.service.ts b/libs/shared/base-abstract-classes/src/service/editors/multi-row-editor.service.ts
index bea6a2cf107..1c2f8c702ff 100644
--- a/libs/shared/base-abstract-classes/src/service/editors/multi-row-editor.service.ts
+++ b/libs/shared/base-abstract-classes/src/service/editors/multi-row-editor.service.ts
@@ -135,8 +135,10 @@ export abstract class MultiRowEditorService extends EditorSe
}
protected isRowIdTaken(id: number) {
+ const searchId = id.toString();
for (const row of this._newRows) {
- if (row[this._entitySecondIdField] === id) {
+ const rowId = row[this._entitySecondIdField].toString();
+ if (rowId === searchId) {
return true;
}
}
@@ -223,7 +225,10 @@ export abstract class MultiRowEditorService extends EditorSe
if (this._entityIdField) {
this.addIdToNewRow(newRow);
}
- newRow[this._entitySecondIdField as keyof T] = this.getNextFreeRowId() as T[keyof T];
+ const nextId = this.getNextFreeRowId();
+ newRow[this._entitySecondIdField as keyof T] = typeof newRow[this._entitySecondIdField as keyof T] === 'string'
+ ? String(nextId) as T[keyof T]
+ : nextId as T[keyof T];
this._newRows = [...this._newRows, { ...newRow }];
this.updateDiffQuery();