AI Implementation feature(896): Admin Area General Settings and Categories 1.14 (#36)
This commit was merged in pull request #36.
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
import '@angular/compiler';
|
||||
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
||||
import {
|
||||
syncCategoryForm,
|
||||
CategoryFormMode,
|
||||
} from '../../frontend/src/app/features/admin/categories/category-form-modal.component';
|
||||
import { AdminCategory } from '../../frontend/src/app/core/services/admin.service';
|
||||
|
||||
function buildForm(): FormGroup<{
|
||||
name: FormControl<string>;
|
||||
abbreviation: FormControl<string>;
|
||||
description: FormControl<string>;
|
||||
}> {
|
||||
const fb = new FormBuilder();
|
||||
return fb.nonNullable.group({
|
||||
name: fb.nonNullable.control('', []),
|
||||
abbreviation: fb.nonNullable.control('', []),
|
||||
description: fb.nonNullable.control(''),
|
||||
});
|
||||
}
|
||||
|
||||
function makeRow(overrides: Partial<AdminCategory> = {}): AdminCategory {
|
||||
return {
|
||||
id: 'row-1',
|
||||
name: 'Cryptography',
|
||||
abbreviation: 'CRY',
|
||||
description: 'Cryptographic challenges',
|
||||
iconPath: '',
|
||||
isSystem: true,
|
||||
systemKey: 'CRY',
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
describe('syncCategoryForm - edit prefill', () => {
|
||||
it('populates name, abbreviation, description for a system row and locks abbreviation', () => {
|
||||
const form = buildForm();
|
||||
const result = syncCategoryForm(form, 'edit', makeRow());
|
||||
|
||||
expect(form.controls.name.value).toBe('Cryptography');
|
||||
expect(form.controls.abbreviation.value).toBe('CRY');
|
||||
expect(form.controls.description.value).toBe('Cryptographic challenges');
|
||||
expect(result.abbreviationReadonly).toBe(true);
|
||||
expect(result.iconPreview).toBeNull();
|
||||
});
|
||||
|
||||
it('does not lock abbreviation for a user (non-system) row', () => {
|
||||
const form = buildForm();
|
||||
const result = syncCategoryForm(
|
||||
form,
|
||||
'edit',
|
||||
makeRow({
|
||||
name: 'Misc',
|
||||
abbreviation: 'MSC',
|
||||
description: 'Other',
|
||||
isSystem: false,
|
||||
systemKey: null,
|
||||
}),
|
||||
);
|
||||
|
||||
expect(form.controls.name.value).toBe('Misc');
|
||||
expect(form.controls.abbreviation.value).toBe('MSC');
|
||||
expect(form.controls.description.value).toBe('Other');
|
||||
expect(result.abbreviationReadonly).toBe(false);
|
||||
});
|
||||
|
||||
it('re-populates when invoked a second time with a different category', () => {
|
||||
const form = buildForm();
|
||||
syncCategoryForm(
|
||||
form,
|
||||
'edit',
|
||||
makeRow({ name: 'Alpha', abbreviation: 'AAA', description: 'first', isSystem: false, systemKey: null }),
|
||||
);
|
||||
expect(form.controls.name.value).toBe('Alpha');
|
||||
expect(form.controls.abbreviation.value).toBe('AAA');
|
||||
|
||||
const result = syncCategoryForm(
|
||||
form,
|
||||
'edit',
|
||||
makeRow({ name: 'Bravo', abbreviation: 'BBB', description: 'second', isSystem: false, systemKey: null }),
|
||||
);
|
||||
|
||||
expect(form.controls.name.value).toBe('Bravo');
|
||||
expect(form.controls.abbreviation.value).toBe('BBB');
|
||||
expect(form.controls.description.value).toBe('second');
|
||||
expect(result.abbreviationReadonly).toBe(false);
|
||||
});
|
||||
|
||||
it('clears the form when invoked with mode="create" and a null category', () => {
|
||||
const form = buildForm();
|
||||
syncCategoryForm(form, 'edit', makeRow());
|
||||
expect(form.controls.name.value).toBe('Cryptography');
|
||||
|
||||
const result = syncCategoryForm(form, 'create', null);
|
||||
|
||||
expect(form.controls.name.value).toBe('');
|
||||
expect(form.controls.abbreviation.value).toBe('');
|
||||
expect(form.controls.description.value).toBe('');
|
||||
expect(result.abbreviationReadonly).toBe(false);
|
||||
expect(result.iconPreview).toBeNull();
|
||||
});
|
||||
|
||||
it('marks controls as pristine and untouched after prefill', () => {
|
||||
const form = buildForm();
|
||||
syncCategoryForm(form, 'edit', makeRow());
|
||||
expect(form.controls.name.pristine).toBe(true);
|
||||
expect(form.controls.name.touched).toBe(false);
|
||||
expect(form.controls.abbreviation.pristine).toBe(true);
|
||||
expect(form.controls.abbreviation.touched).toBe(false);
|
||||
expect(form.controls.description.pristine).toBe(true);
|
||||
expect(form.controls.description.touched).toBe(false);
|
||||
});
|
||||
|
||||
it('returns iconPreview from category.iconPath when set', () => {
|
||||
const form = buildForm();
|
||||
const result = syncCategoryForm(
|
||||
form,
|
||||
'edit',
|
||||
makeRow({ iconPath: '/uploads/icons/cry.png' }),
|
||||
);
|
||||
expect(result.iconPreview).toBe('/uploads/icons/cry.png');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user