AI Implementation feature(883): Admin Area General Settings and Categories 1.01 (#23)

This commit was merged in pull request #23.
This commit is contained in:
2026-07-22 12:32:00 +00:00
parent fac3179427
commit 0a2b2664b4
9 changed files with 171 additions and 89 deletions
@@ -56,6 +56,37 @@ describe('GeneralSettingsSchema - validation rules', () => {
});
expect(r.success).toBe(true);
});
it('rejects a whitespace-only pageTitle', () => {
const r = GeneralSettingsSchema.safeParse({
pageTitle: ' ',
logo: '',
welcomeMarkdown: '',
themeKey: 'classic',
eventStartUtc: '2026-01-01T00:00:00Z',
eventEndUtc: '2026-02-01T00:00:00Z',
defaultChallengeIp: '127.0.0.1',
registrationsEnabled: false,
});
expect(r.success).toBe(false);
});
it('trims surrounding whitespace from a valid pageTitle', () => {
const r = GeneralSettingsSchema.safeParse({
pageTitle: ' OpenVelo ',
logo: '',
welcomeMarkdown: '',
themeKey: 'classic',
eventStartUtc: '2026-01-01T00:00:00Z',
eventEndUtc: '2026-02-01T00:00:00Z',
defaultChallengeIp: '127.0.0.1',
registrationsEnabled: false,
});
expect(r.success).toBe(true);
if (r.success) {
expect(r.data.pageTitle).toBe('OpenVelo');
}
});
});
describe('AdminGeneralService.updateSettings - happy path', () => {
+47 -1
View File
@@ -1,4 +1,11 @@
import { deriveEventState, endAfterStartValidator, toDatetimeLocal, toIsoUtc } from '../../frontend/src/app/features/admin/general.pure';
import {
deriveEventState,
endAfterStartValidator,
normalizePageTitle,
pageTitleError,
toDatetimeLocal,
toIsoUtc,
} from '../../frontend/src/app/features/admin/general.pure';
describe('deriveEventState', () => {
const start = '2026-01-01T00:00:00Z';
@@ -80,3 +87,42 @@ describe('datetime helpers', () => {
expect(toIsoUtc('')).toBe('');
});
});
describe('pageTitleError', () => {
it('returns "required" for empty input', () => {
expect(pageTitleError('')).toBe('required');
expect(pageTitleError(null)).toBe('required');
expect(pageTitleError(undefined)).toBe('required');
});
it('returns "required" for whitespace-only input', () => {
expect(pageTitleError(' ')).toBe('required');
expect(pageTitleError('\t\n ')).toBe('required');
});
it('returns null for a valid title', () => {
expect(pageTitleError('OpenVelo')).toBeNull();
});
it('returns "maxlength" when the raw string exceeds 120 characters', () => {
expect(pageTitleError('a'.repeat(121))).toBe('maxlength');
});
it('returns null when surrounding whitespace keeps the trimmed length within bounds', () => {
expect(pageTitleError(' OpenVelo ')).toBeNull();
});
});
describe('normalizePageTitle', () => {
it('returns an empty string for empty input', () => {
expect(normalizePageTitle('')).toBe('');
});
it('returns an empty string for whitespace-only input', () => {
expect(normalizePageTitle(' ')).toBe('');
});
it('trims surrounding whitespace from a valid title', () => {
expect(normalizePageTitle(' OpenVelo ')).toBe('OpenVelo');
});
});