diff --git a/frontend/src/pages/settings/settings-api-tokens.test.tsx b/frontend/src/pages/settings/settings-api-tokens.test.tsx new file mode 100644 index 00000000..52cd9ded --- /dev/null +++ b/frontend/src/pages/settings/settings-api-tokens.test.tsx @@ -0,0 +1,24 @@ +import { describe, expect, it } from 'vitest'; + +import { tokenNameSchema } from './settings-api-tokens'; + +describe('tokenNameSchema', () => { + it('accepts a name at the 100-character boundary', () => { + expect(tokenNameSchema.safeParse('a'.repeat(100)).success).toBe(true); + }); + + it('rejects a name one character over the 100-character cap', () => { + expect(tokenNameSchema.safeParse('a'.repeat(101)).success).toBe(false); + }); + + it('trims surrounding whitespace before length-checking', () => { + expect(tokenNameSchema.safeParse(` ${'a'.repeat(100)} `)).toMatchObject({ + data: 'a'.repeat(100), + success: true, + }); + }); + + it('defaults an omitted name to an empty string', () => { + expect(tokenNameSchema.safeParse(undefined)).toMatchObject({ data: '', success: true }); + }); +}); diff --git a/frontend/src/pages/settings/settings-api-tokens.tsx b/frontend/src/pages/settings/settings-api-tokens.tsx index e9b0055f..b3e97242 100644 --- a/frontend/src/pages/settings/settings-api-tokens.tsx +++ b/frontend/src/pages/settings/settings-api-tokens.tsx @@ -63,7 +63,7 @@ import { baseUrl } from '@/models/api'; type APIToken = ApiTokenFragmentFragment; // 100 mirrors the backend cap (server/models/api_tokens.go + the createAPIToken/updateAPIToken resolvers). -const tokenNameSchema = z.string().trim().max(100, 'Token name must be 100 characters or less').default(''); +export const tokenNameSchema = z.string().trim().max(100, 'Token name must be 100 characters or less').default(''); const createTokenFormSchema = z.object({ // Nullable in form input (the date picker starts empty); the refine gates