84 lines
3.1 KiB
TypeScript
84 lines
3.1 KiB
TypeScript
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> = {}): 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);
|
|
});
|
|
});
|