import { describe, it, expect } from 'vitest'; import { LoginViewDataBuilder } from './LoginViewDataBuilder'; import type { LoginPageDTO } from '@/lib/services/auth/types/LoginPageDTO'; describe('LoginViewDataBuilder', () => { describe('happy paths', () => { it('should transform LoginPageDTO to LoginViewData correctly', () => { const loginPageDTO: LoginPageDTO = { returnTo: '/dashboard', hasInsufficientPermissions: false, }; const result = LoginViewDataBuilder.build(loginPageDTO); expect(result).toEqual({ returnTo: '/dashboard', hasInsufficientPermissions: false, showPassword: false, showErrorDetails: false, formState: { fields: { email: { value: '', error: undefined, touched: false, validating: false }, password: { value: '', error: undefined, touched: false, validating: false }, rememberMe: { value: false, error: undefined, touched: false, validating: false }, }, isValid: true, isSubmitting: false, submitError: undefined, submitCount: 0, }, isSubmitting: false, submitError: undefined, }); }); it('should handle insufficient permissions flag correctly', () => { const loginPageDTO: LoginPageDTO = { returnTo: '/admin', hasInsufficientPermissions: true, }; const result = LoginViewDataBuilder.build(loginPageDTO); expect(result.hasInsufficientPermissions).toBe(true); expect(result.returnTo).toBe('/admin'); }); it('should handle empty returnTo path', () => { const loginPageDTO: LoginPageDTO = { returnTo: '', hasInsufficientPermissions: false, }; const result = LoginViewDataBuilder.build(loginPageDTO); expect(result.returnTo).toBe(''); expect(result.hasInsufficientPermissions).toBe(false); }); }); describe('data transformation', () => { it('should preserve all DTO fields in the output', () => { const loginPageDTO: LoginPageDTO = { returnTo: '/dashboard', hasInsufficientPermissions: false, }; const result = LoginViewDataBuilder.build(loginPageDTO); expect(result.returnTo).toBe(loginPageDTO.returnTo); expect(result.hasInsufficientPermissions).toBe(loginPageDTO.hasInsufficientPermissions); }); it('should not modify the input DTO', () => { const loginPageDTO: LoginPageDTO = { returnTo: '/dashboard', hasInsufficientPermissions: false, }; const originalDTO = { ...loginPageDTO }; LoginViewDataBuilder.build(loginPageDTO); expect(loginPageDTO).toEqual(originalDTO); }); it('should initialize form fields with default values', () => { const loginPageDTO: LoginPageDTO = { returnTo: '/dashboard', hasInsufficientPermissions: false, }; const result = LoginViewDataBuilder.build(loginPageDTO); expect(result.formState.fields.email.value).toBe(''); expect(result.formState.fields.email.error).toBeUndefined(); expect(result.formState.fields.email.touched).toBe(false); expect(result.formState.fields.email.validating).toBe(false); expect(result.formState.fields.password.value).toBe(''); expect(result.formState.fields.password.error).toBeUndefined(); expect(result.formState.fields.password.touched).toBe(false); expect(result.formState.fields.password.validating).toBe(false); expect(result.formState.fields.rememberMe.value).toBe(false); expect(result.formState.fields.rememberMe.error).toBeUndefined(); expect(result.formState.fields.rememberMe.touched).toBe(false); expect(result.formState.fields.rememberMe.validating).toBe(false); }); it('should initialize form state with default values', () => { const loginPageDTO: LoginPageDTO = { returnTo: '/dashboard', hasInsufficientPermissions: false, }; const result = LoginViewDataBuilder.build(loginPageDTO); expect(result.formState.isValid).toBe(true); expect(result.formState.isSubmitting).toBe(false); expect(result.formState.submitError).toBeUndefined(); expect(result.formState.submitCount).toBe(0); }); it('should initialize UI state flags correctly', () => { const loginPageDTO: LoginPageDTO = { returnTo: '/dashboard', hasInsufficientPermissions: false, }; const result = LoginViewDataBuilder.build(loginPageDTO); expect(result.showPassword).toBe(false); expect(result.showErrorDetails).toBe(false); expect(result.isSubmitting).toBe(false); expect(result.submitError).toBeUndefined(); }); }); describe('edge cases', () => { it('should handle special characters in returnTo path', () => { const loginPageDTO: LoginPageDTO = { returnTo: '/dashboard?param=value&other=test', hasInsufficientPermissions: false, }; const result = LoginViewDataBuilder.build(loginPageDTO); expect(result.returnTo).toBe('/dashboard?param=value&other=test'); }); it('should handle returnTo with hash fragment', () => { const loginPageDTO: LoginPageDTO = { returnTo: '/dashboard#section', hasInsufficientPermissions: false, }; const result = LoginViewDataBuilder.build(loginPageDTO); expect(result.returnTo).toBe('/dashboard#section'); }); it('should handle returnTo with encoded characters', () => { const loginPageDTO: LoginPageDTO = { returnTo: '/dashboard?redirect=%2Fadmin', hasInsufficientPermissions: false, }; const result = LoginViewDataBuilder.build(loginPageDTO); expect(result.returnTo).toBe('/dashboard?redirect=%2Fadmin'); }); }); describe('form state structure', () => { it('should have all required form fields', () => { const loginPageDTO: LoginPageDTO = { returnTo: '/dashboard', hasInsufficientPermissions: false, }; const result = LoginViewDataBuilder.build(loginPageDTO); expect(result.formState.fields).toHaveProperty('email'); expect(result.formState.fields).toHaveProperty('password'); expect(result.formState.fields).toHaveProperty('rememberMe'); }); it('should have consistent field state structure', () => { const loginPageDTO: LoginPageDTO = { returnTo: '/dashboard', hasInsufficientPermissions: false, }; const result = LoginViewDataBuilder.build(loginPageDTO); const fields = result.formState.fields; Object.values(fields).forEach((field) => { expect(field).toHaveProperty('value'); expect(field).toHaveProperty('error'); expect(field).toHaveProperty('touched'); expect(field).toHaveProperty('validating'); }); }); }); });