import '@angular/compiler'; import { FormBuilder } from '@angular/forms'; import { buildChallengeFormGroup, } from '../../frontend/src/app/features/admin/challenges/challenge-form-modal.component'; import { CATEGORY_ID_PATTERN, ChallengeFormDefaults, firstErrorTab, validateChallengeForm, } from '../../frontend/src/app/features/admin/challenges/challenge-form.pure'; function makeDefaults(overrides: Partial = {}): ChallengeFormDefaults { return { name: 'Missing Category Attempt', descriptionMd: 'desc', categoryId: '11111111-1111-4111-8111-111111111111', difficulty: 'MEDIUM', initialPoints: 100, minimumPoints: 50, decaySolves: 10, flag: 'flag{X}', protocol: 'WEB', port: null, ipAddress: '', enabled: true, ...overrides, }; } const VALID_CATEGORY_ID = '11111111-1111-4111-8111-111111111111'; describe('Job 902: challenge form Category validation', () => { it('CATEGORY_ID_PATTERN accepts a canonical UUID v4', () => { expect(CATEGORY_ID_PATTERN.test(VALID_CATEGORY_ID)).toBe(true); }); it('validateChallengeForm flags empty categoryId', () => { const errs = validateChallengeForm(makeDefaults({ categoryId: '' })); expect(errs.categoryId).toBe('Category is required'); }); it('validateChallengeForm flags whitespace-only categoryId', () => { const errs = validateChallengeForm(makeDefaults({ categoryId: ' ' })); expect(errs.categoryId).toBe('Category is required'); }); it('validateChallengeForm flags non-UUID categoryId (defense in depth)', () => { const errs = validateChallengeForm(makeDefaults({ categoryId: 'not-a-uuid' })); expect(errs.categoryId).toBe('Category is required'); }); it('validateChallengeForm accepts a well-formed UUID categoryId', () => { const errs = validateChallengeForm(makeDefaults()); expect(errs.categoryId).toBeUndefined(); }); it('firstErrorTab routes a categoryId error to the general tab', () => { expect(firstErrorTab({ categoryId: 'Category is required' })).toBe('general'); }); it('buildChallengeFormGroup applies a uuid validator on categoryId', () => { const form = buildChallengeFormGroup(new FormBuilder()); form.controls.categoryId.setValue('not-a-uuid'); form.controls.categoryId.markAsTouched(); expect(form.controls.categoryId.errors?.['uuid']).toBe(true); expect(form.controls.categoryId.errors?.['required']).toBeUndefined(); }); it('buildChallengeFormGroup uuid validator passes for a valid UUID v4', () => { const form = buildChallengeFormGroup(new FormBuilder()); form.controls.categoryId.setValue(VALID_CATEGORY_ID); form.controls.categoryId.markAsTouched(); expect(form.controls.categoryId.errors?.['uuid']).toBeUndefined(); }); it('buildChallengeFormGroup categoryId control still flags required for empty value', () => { const form = buildChallengeFormGroup(new FormBuilder()); form.controls.categoryId.setValue(''); form.controls.categoryId.markAsTouched(); expect(form.controls.categoryId.errors?.['required']).toBe(true); }); });