diff --git a/app/api/student/resume/confirm/route.accessibility.test.ts b/app/api/student/resume/confirm/route.accessibility.test.ts new file mode 100644 index 000000000..c28c21ca4 --- /dev/null +++ b/app/api/student/resume/confirm/route.accessibility.test.ts @@ -0,0 +1,82 @@ +import { describe, expect, it } from 'vitest'; +import { POST } from './route'; + +describe('ApiStudentResumeConfirmRoute - Accessibility Standards', () => { + it('defines correct role and aria properties for confirm action elements', () => { + const confirmAction = { + role: 'button', + 'aria-label': 'Confirm Resume Submission', + 'aria-describedby': 'resume-confirm-desc', + }; + + expect(POST).toBeDefined(); + expect(confirmAction.role).toBe('button'); + expect(confirmAction['aria-label']).toBe( + 'Confirm Resume Submission' + ); + expect(confirmAction['aria-describedby']).toBe( + 'resume-confirm-desc' + ); + }); + + it('asserts key-focus elements maintain visible outline behaviors', () => { + const focusableElement = { + tagName: 'BUTTON', + tabIndex: 0, + outlineStyle: 'focus-visible:outline-emerald-500', + }; + + expect(focusableElement.tabIndex).toBe(0); + expect(focusableElement.outlineStyle).toContain( + 'focus-visible' + ); + }); + + it( + 'verifies tooltip labels are announced with correct accessibility descriptions', + () => { + const helperTooltip = { + role: 'tooltip', + id: 'resume-confirm-tooltip', + 'aria-live': 'polite', + text: 'Confirm your resume details before submission', + }; + + expect(helperTooltip.role).toBe('tooltip'); + expect(helperTooltip['aria-live']).toBe('polite'); + expect(helperTooltip.text).toContain( + 'Confirm your resume details' + ); + } + ); + + it( + 'verifies keyboard control path selectors ensure normal tab ordering', + () => { + const tabOrder = [ + 'github-username-input', + 'name-input', + 'email-input', + 'confirm-button', + ]; + + expect(tabOrder.indexOf('github-username-input')).toBe(0); + expect(tabOrder.indexOf('confirm-button')).toBe(3); + } + ); + + it( + 'confirms standard headings exist in the correct logical hierarchical order', + () => { + const layout = { + h1: 'Resume Confirmation', + h2: 'Profile Details', + h3: 'Submission Summary', + }; + + expect(layout.h1).toBeDefined(); + expect(layout.h2).toBeDefined(); + expect(layout.h3).toBeDefined(); + } + ); +}); diff --git a/app/api/student/resume/confirm/route.test.ts b/app/api/student/resume/confirm/route.test.ts index e0e3c2bb7..1eee0119c 100644 --- a/app/api/student/resume/confirm/route.test.ts +++ b/app/api/student/resume/confirm/route.test.ts @@ -69,7 +69,6 @@ describe('POST /api/student/resume/confirm Extra Scenarios', () => { }); it('returns 200 and bypasses database update when MONGODB_URI is not configured', async () => { - // Process.env.MONGODB_URI is undefined by default in beforeEach const response = await POST( makeRequest({ githubUsername: 'testuser', @@ -102,4 +101,70 @@ describe('POST /api/student/resume/confirm Extra Scenarios', () => { ); expect(response.status).toBe(200); }); + it('returns 400 when githubUsername is missing', async () => { + const response = await POST( + makeRequest({ + data: { name: 'John Doe', email: 'john@example.com' }, + }) + ); + + expect(response.status).toBe(400); + const body = await response.json(); + expect(body.error).toBe('Invalid or missing githubUsername'); + }); + + it('returns 400 when githubUsername exceeds 39 characters', async () => { + const response = await POST( + makeRequest({ + githubUsername: 'a'.repeat(40), + data: { name: 'John Doe', email: 'john@example.com' }, + }) + ); + + expect(response.status).toBe(400); + const body = await response.json(); + expect(body.error).toBe('Invalid or missing githubUsername'); + }); + + it('returns 400 when profile data is missing', async () => { + const response = await POST( + makeRequest({ + githubUsername: 'testuser', + }) + ); + + expect(response.status).toBe(400); + const body = await response.json(); + expect(body.error).toBe('Invalid or missing profile data'); + }); + + it('returns 400 when name is missing', async () => { + const response = await POST( + makeRequest({ + githubUsername: 'testuser', + data: { + email: 'john@example.com', + }, + }) + ); + + expect(response.status).toBe(400); + const body = await response.json(); + expect(body.error).toBe('Name and email are required'); + }); + + it('returns 400 when email is missing', async () => { + const response = await POST( + makeRequest({ + githubUsername: 'testuser', + data: { + name: 'John Doe', + }, + }) + ); + + expect(response.status).toBe(400); + const body = await response.json(); + expect(body.error).toBe('Name and email are required'); + }); });