view data fixes
Some checks failed
Contract Testing / contract-tests (pull_request) Failing after 7m11s
Contract Testing / contract-snapshot (pull_request) Has been skipped

This commit is contained in:
2026-01-24 23:29:55 +01:00
parent c1750a33dd
commit 1b0a1f4aee
134 changed files with 10380 additions and 415 deletions

View File

@@ -0,0 +1,134 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { ForgotPasswordPageQuery } from './ForgotPasswordPageQuery';
import { AuthPageService } from '@/lib/services/auth/AuthPageService';
import { Result } from '@/lib/contracts/Result';
import { ForgotPasswordViewDataBuilder } from '@/lib/builders/view-data/ForgotPasswordViewDataBuilder';
import { SearchParamParser } from '@/lib/routing/search-params/SearchParamParser';
// Mock dependencies
const mockProcessForgotPasswordParams = vi.fn();
const mockProcessLoginParams = vi.fn();
const mockProcessResetPasswordParams = vi.fn();
const mockProcessSignupParams = vi.fn();
vi.mock('@/lib/services/auth/AuthPageService', () => {
return {
AuthPageService: class {
processForgotPasswordParams = mockProcessForgotPasswordParams;
processLoginParams = mockProcessLoginParams;
processResetPasswordParams = mockProcessResetPasswordParams;
processSignupParams = mockProcessSignupParams;
},
};
});
vi.mock('@/lib/routing/search-params/SearchParamParser', () => ({
SearchParamParser: {
parseAuth: vi.fn(),
},
}));
vi.mock('@/lib/builders/view-data/ForgotPasswordViewDataBuilder', () => ({
ForgotPasswordViewDataBuilder: {
build: vi.fn(),
},
}));
describe('ForgotPasswordPageQuery', () => {
let query: ForgotPasswordPageQuery;
let mockServiceInstance: any;
let mockSearchParams: URLSearchParams;
beforeEach(() => {
vi.clearAllMocks();
mockServiceInstance = {
processForgotPasswordParams: mockProcessForgotPasswordParams,
};
query = new ForgotPasswordPageQuery(mockServiceInstance as any);
mockSearchParams = new URLSearchParams('returnTo=/login&token=xyz789');
});
it('should return view data when search params are valid and service succeeds', async () => {
const parsedParams = { returnTo: '/login', token: 'xyz789' };
const serviceOutput = { email: 'test@example.com' };
const viewData = { email: 'test@example.com', returnTo: '/login' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processForgotPasswordParams.mockResolvedValue(Result.ok(serviceOutput));
(ForgotPasswordViewDataBuilder.build as any).mockReturnValue(viewData);
const result = await query.execute(mockSearchParams);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual(viewData);
expect(SearchParamParser.parseAuth).toHaveBeenCalledWith(mockSearchParams);
expect(mockServiceInstance.processForgotPasswordParams).toHaveBeenCalledWith(parsedParams);
expect(ForgotPasswordViewDataBuilder.build).toHaveBeenCalledWith(serviceOutput);
});
it('should return error when search params are invalid', async () => {
(SearchParamParser.parseAuth as any).mockReturnValue(Result.err('Invalid params'));
const result = await query.execute(mockSearchParams);
expect(result.isErr()).toBe(true);
expect(result.getError()).toBe('Invalid search parameters: Invalid params');
});
it('should return error when service fails', async () => {
const parsedParams = { returnTo: '/login', token: 'xyz789' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processForgotPasswordParams.mockResolvedValue(
Result.err({ message: 'Service error' })
);
const result = await query.execute(mockSearchParams);
expect(result.isErr()).toBe(true);
expect(result.getError()).toBe('Service error');
});
it('should return error on exception', async () => {
const parsedParams = { returnTo: '/login', token: 'xyz789' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processForgotPasswordParams.mockRejectedValue(new Error('Unexpected error'));
const result = await query.execute(mockSearchParams);
expect(result.isErr()).toBe(true);
expect(result.getError()).toBe('Unexpected error');
});
it('should provide a static execute method', async () => {
const parsedParams = { returnTo: '/login', token: 'xyz789' };
const serviceOutput = { email: 'test@example.com' };
const viewData = { email: 'test@example.com', returnTo: '/login' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processForgotPasswordParams.mockResolvedValue(Result.ok(serviceOutput));
(ForgotPasswordViewDataBuilder.build as any).mockReturnValue(viewData);
const result = await ForgotPasswordPageQuery.execute(mockSearchParams);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual(viewData);
});
it('should handle Record<string, string | string[] | undefined> input', async () => {
const recordParams = { returnTo: '/login', token: 'xyz789' };
const parsedParams = { returnTo: '/login', token: 'xyz789' };
const serviceOutput = { email: 'test@example.com' };
const viewData = { email: 'test@example.com', returnTo: '/login' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processForgotPasswordParams.mockResolvedValue(Result.ok(serviceOutput));
(ForgotPasswordViewDataBuilder.build as any).mockReturnValue(viewData);
const result = await query.execute(recordParams);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual(viewData);
expect(SearchParamParser.parseAuth).toHaveBeenCalledWith(recordParams);
});
});

View File

@@ -6,6 +6,12 @@ import { AuthPageService } from '@/lib/services/auth/AuthPageService';
import { ForgotPasswordViewData } from '@/lib/view-data/ForgotPasswordViewData';
export class ForgotPasswordPageQuery implements PageQuery<ForgotPasswordViewData, URLSearchParams | Record<string, string | string[] | undefined>> {
private readonly authService: AuthPageService;
constructor(authService?: AuthPageService) {
this.authService = authService || new AuthPageService();
}
async execute(searchParams: URLSearchParams | Record<string, string | string[] | undefined>): Promise<Result<ForgotPasswordViewData, string>> {
// Parse and validate search parameters
const parsedResult = SearchParamParser.parseAuth(searchParams);
@@ -17,7 +23,7 @@ export class ForgotPasswordPageQuery implements PageQuery<ForgotPasswordViewData
try {
// Use service to process parameters
const authService = new AuthPageService();
const authService = this.authService;
const serviceResult = await authService.processForgotPasswordParams({ returnTo, token });
if (serviceResult.isErr()) {
@@ -27,8 +33,9 @@ export class ForgotPasswordPageQuery implements PageQuery<ForgotPasswordViewData
// Transform to ViewData using builder
const viewData = ForgotPasswordViewDataBuilder.build(serviceResult.unwrap());
return Result.ok(viewData);
} catch (error: any) {
return Result.err(error.message || 'Failed to execute forgot password page query');
} catch (error: unknown) {
const message = error instanceof Error ? error.message : 'Failed to execute forgot password page query';
return Result.err(message);
}
}

View File

@@ -0,0 +1,134 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { LoginPageQuery } from './LoginPageQuery';
import { AuthPageService } from '@/lib/services/auth/AuthPageService';
import { Result } from '@/lib/contracts/Result';
import { LoginViewDataBuilder } from '@/lib/builders/view-data/LoginViewDataBuilder';
import { SearchParamParser } from '@/lib/routing/search-params/SearchParamParser';
// Mock dependencies
const mockProcessForgotPasswordParams = vi.fn();
const mockProcessLoginParams = vi.fn();
const mockProcessResetPasswordParams = vi.fn();
const mockProcessSignupParams = vi.fn();
vi.mock('@/lib/services/auth/AuthPageService', () => {
return {
AuthPageService: class {
processForgotPasswordParams = mockProcessForgotPasswordParams;
processLoginParams = mockProcessLoginParams;
processResetPasswordParams = mockProcessResetPasswordParams;
processSignupParams = mockProcessSignupParams;
},
};
});
vi.mock('@/lib/routing/search-params/SearchParamParser', () => ({
SearchParamParser: {
parseAuth: vi.fn(),
},
}));
vi.mock('@/lib/builders/view-data/LoginViewDataBuilder', () => ({
LoginViewDataBuilder: {
build: vi.fn(),
},
}));
describe('LoginPageQuery', () => {
let query: LoginPageQuery;
let mockServiceInstance: any;
let mockSearchParams: URLSearchParams;
beforeEach(() => {
vi.clearAllMocks();
mockServiceInstance = {
processLoginParams: mockProcessLoginParams,
};
query = new LoginPageQuery(mockServiceInstance as any);
mockSearchParams = new URLSearchParams('returnTo=/dashboard&token=abc123');
});
it('should return view data when search params are valid and service succeeds', async () => {
const parsedParams = { returnTo: '/dashboard', token: 'abc123' };
const serviceOutput = { success: true };
const viewData = { returnTo: '/dashboard', token: 'abc123' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processLoginParams.mockResolvedValue(Result.ok(serviceOutput));
(LoginViewDataBuilder.build as any).mockReturnValue(viewData);
const result = await query.execute(mockSearchParams);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual(viewData);
expect(SearchParamParser.parseAuth).toHaveBeenCalledWith(mockSearchParams);
expect(mockServiceInstance.processLoginParams).toHaveBeenCalledWith(parsedParams);
expect(LoginViewDataBuilder.build).toHaveBeenCalledWith(serviceOutput);
});
it('should return error when search params are invalid', async () => {
(SearchParamParser.parseAuth as any).mockReturnValue(Result.err('Invalid params'));
const result = await query.execute(mockSearchParams);
expect(result.isErr()).toBe(true);
expect(result.getError()).toBe('Invalid search parameters: Invalid params');
});
it('should return error when service fails', async () => {
const parsedParams = { returnTo: '/dashboard', token: 'abc123' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processLoginParams.mockResolvedValue(
Result.err({ message: 'Service error' })
);
const result = await query.execute(mockSearchParams);
expect(result.isErr()).toBe(true);
expect(result.getError()).toBe('Service error');
});
it('should return error on exception', async () => {
const parsedParams = { returnTo: '/dashboard', token: 'abc123' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processLoginParams.mockRejectedValue(new Error('Unexpected error'));
const result = await query.execute(mockSearchParams);
expect(result.isErr()).toBe(true);
expect(result.getError()).toBe('Unexpected error');
});
it('should provide a static execute method', async () => {
const parsedParams = { returnTo: '/dashboard', token: 'abc123' };
const serviceOutput = { success: true };
const viewData = { returnTo: '/dashboard', token: 'abc123' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processLoginParams.mockResolvedValue(Result.ok(serviceOutput));
(LoginViewDataBuilder.build as any).mockReturnValue(viewData);
const result = await LoginPageQuery.execute(mockSearchParams);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual(viewData);
});
it('should handle Record<string, string | string[] | undefined> input', async () => {
const recordParams = { returnTo: '/dashboard', token: 'abc123' };
const parsedParams = { returnTo: '/dashboard', token: 'abc123' };
const serviceOutput = { success: true };
const viewData = { returnTo: '/dashboard', token: 'abc123' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processLoginParams.mockResolvedValue(Result.ok(serviceOutput));
(LoginViewDataBuilder.build as any).mockReturnValue(viewData);
const result = await query.execute(recordParams);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual(viewData);
expect(SearchParamParser.parseAuth).toHaveBeenCalledWith(recordParams);
});
});

View File

@@ -6,6 +6,12 @@ import { AuthPageService } from '@/lib/services/auth/AuthPageService';
import { LoginViewData } from '@/lib/view-data/LoginViewData';
export class LoginPageQuery implements PageQuery<LoginViewData, URLSearchParams | Record<string, string | string[] | undefined>> {
private readonly authService: AuthPageService;
constructor(authService?: AuthPageService) {
this.authService = authService || new AuthPageService();
}
async execute(searchParams: URLSearchParams | Record<string, string | string[] | undefined>): Promise<Result<LoginViewData, string>> {
// Parse and validate search parameters
const parsedResult = SearchParamParser.parseAuth(searchParams);
@@ -17,7 +23,7 @@ export class LoginPageQuery implements PageQuery<LoginViewData, URLSearchParams
try {
// Use service to process parameters
const authService = new AuthPageService();
const authService = this.authService;
const serviceResult = await authService.processLoginParams({ returnTo, token });
if (serviceResult.isErr()) {
@@ -27,8 +33,9 @@ export class LoginPageQuery implements PageQuery<LoginViewData, URLSearchParams
// Transform to ViewData using builder
const viewData = LoginViewDataBuilder.build(serviceResult.unwrap());
return Result.ok(viewData);
} catch (error: any) {
return Result.err(error.message || 'Failed to execute login page query');
} catch (error: unknown) {
const message = error instanceof Error ? error.message : 'Failed to execute login page query';
return Result.err(message);
}
}

View File

@@ -0,0 +1,134 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { ResetPasswordPageQuery } from './ResetPasswordPageQuery';
import { AuthPageService } from '@/lib/services/auth/AuthPageService';
import { Result } from '@/lib/contracts/Result';
import { ResetPasswordViewDataBuilder } from '@/lib/builders/view-data/ResetPasswordViewDataBuilder';
import { SearchParamParser } from '@/lib/routing/search-params/SearchParamParser';
// Mock dependencies
const mockProcessForgotPasswordParams = vi.fn();
const mockProcessLoginParams = vi.fn();
const mockProcessResetPasswordParams = vi.fn();
const mockProcessSignupParams = vi.fn();
vi.mock('@/lib/services/auth/AuthPageService', () => {
return {
AuthPageService: class {
processForgotPasswordParams = mockProcessForgotPasswordParams;
processLoginParams = mockProcessLoginParams;
processResetPasswordParams = mockProcessResetPasswordParams;
processSignupParams = mockProcessSignupParams;
},
};
});
vi.mock('@/lib/routing/search-params/SearchParamParser', () => ({
SearchParamParser: {
parseAuth: vi.fn(),
},
}));
vi.mock('@/lib/builders/view-data/ResetPasswordViewDataBuilder', () => ({
ResetPasswordViewDataBuilder: {
build: vi.fn(),
},
}));
describe('ResetPasswordPageQuery', () => {
let query: ResetPasswordPageQuery;
let mockServiceInstance: any;
let mockSearchParams: URLSearchParams;
beforeEach(() => {
vi.clearAllMocks();
mockServiceInstance = {
processResetPasswordParams: mockProcessResetPasswordParams,
};
query = new ResetPasswordPageQuery(mockServiceInstance as any);
mockSearchParams = new URLSearchParams('returnTo=/login&token=reset123');
});
it('should return view data when search params are valid and service succeeds', async () => {
const parsedParams = { returnTo: '/login', token: 'reset123' };
const serviceOutput = { email: 'test@example.com' };
const viewData = { email: 'test@example.com', returnTo: '/login' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processResetPasswordParams.mockResolvedValue(Result.ok(serviceOutput));
(ResetPasswordViewDataBuilder.build as any).mockReturnValue(viewData);
const result = await query.execute(mockSearchParams);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual(viewData);
expect(SearchParamParser.parseAuth).toHaveBeenCalledWith(mockSearchParams);
expect(mockServiceInstance.processResetPasswordParams).toHaveBeenCalledWith(parsedParams);
expect(ResetPasswordViewDataBuilder.build).toHaveBeenCalledWith(serviceOutput);
});
it('should return error when search params are invalid', async () => {
(SearchParamParser.parseAuth as any).mockReturnValue(Result.err('Invalid params'));
const result = await query.execute(mockSearchParams);
expect(result.isErr()).toBe(true);
expect(result.getError()).toBe('Invalid search parameters: Invalid params');
});
it('should return error when service fails', async () => {
const parsedParams = { returnTo: '/login', token: 'reset123' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processResetPasswordParams.mockResolvedValue(
Result.err({ message: 'Service error' })
);
const result = await query.execute(mockSearchParams);
expect(result.isErr()).toBe(true);
expect(result.getError()).toBe('Service error');
});
it('should return error on exception', async () => {
const parsedParams = { returnTo: '/login', token: 'reset123' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processResetPasswordParams.mockRejectedValue(new Error('Unexpected error'));
const result = await query.execute(mockSearchParams);
expect(result.isErr()).toBe(true);
expect(result.getError()).toBe('Unexpected error');
});
it('should provide a static execute method', async () => {
const parsedParams = { returnTo: '/login', token: 'reset123' };
const serviceOutput = { email: 'test@example.com' };
const viewData = { email: 'test@example.com', returnTo: '/login' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processResetPasswordParams.mockResolvedValue(Result.ok(serviceOutput));
(ResetPasswordViewDataBuilder.build as any).mockReturnValue(viewData);
const result = await ResetPasswordPageQuery.execute(mockSearchParams);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual(viewData);
});
it('should handle Record<string, string | string[] | undefined> input', async () => {
const recordParams = { returnTo: '/login', token: 'reset123' };
const parsedParams = { returnTo: '/login', token: 'reset123' };
const serviceOutput = { email: 'test@example.com' };
const viewData = { email: 'test@example.com', returnTo: '/login' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processResetPasswordParams.mockResolvedValue(Result.ok(serviceOutput));
(ResetPasswordViewDataBuilder.build as any).mockReturnValue(viewData);
const result = await query.execute(recordParams);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual(viewData);
expect(SearchParamParser.parseAuth).toHaveBeenCalledWith(recordParams);
});
});

View File

@@ -6,6 +6,12 @@ import { AuthPageService } from '@/lib/services/auth/AuthPageService';
import { ResetPasswordViewData } from '@/lib/view-data/ResetPasswordViewData';
export class ResetPasswordPageQuery implements PageQuery<ResetPasswordViewData, URLSearchParams | Record<string, string | string[] | undefined>> {
private readonly authService: AuthPageService;
constructor(authService?: AuthPageService) {
this.authService = authService || new AuthPageService();
}
async execute(searchParams: URLSearchParams | Record<string, string | string[] | undefined>): Promise<Result<ResetPasswordViewData, string>> {
// Parse and validate search parameters
const parsedResult = SearchParamParser.parseAuth(searchParams);
@@ -17,7 +23,7 @@ export class ResetPasswordPageQuery implements PageQuery<ResetPasswordViewData,
try {
// Use service to process parameters
const authService = new AuthPageService();
const authService = this.authService;
const serviceResult = await authService.processResetPasswordParams({ returnTo, token });
if (serviceResult.isErr()) {
@@ -27,8 +33,9 @@ export class ResetPasswordPageQuery implements PageQuery<ResetPasswordViewData,
// Transform to ViewData using builder
const viewData = ResetPasswordViewDataBuilder.build(serviceResult.unwrap());
return Result.ok(viewData);
} catch (error: any) {
return Result.err(error.message || 'Failed to execute reset password page query');
} catch (error: unknown) {
const message = error instanceof Error ? error.message : 'Failed to execute reset password page query';
return Result.err(message);
}
}

View File

@@ -0,0 +1,134 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { SignupPageQuery } from './SignupPageQuery';
import { AuthPageService } from '@/lib/services/auth/AuthPageService';
import { Result } from '@/lib/contracts/Result';
import { SignupViewDataBuilder } from '@/lib/builders/view-data/SignupViewDataBuilder';
import { SearchParamParser } from '@/lib/routing/search-params/SearchParamParser';
// Mock dependencies
const mockProcessForgotPasswordParams = vi.fn();
const mockProcessLoginParams = vi.fn();
const mockProcessResetPasswordParams = vi.fn();
const mockProcessSignupParams = vi.fn();
vi.mock('@/lib/services/auth/AuthPageService', () => {
return {
AuthPageService: class {
processForgotPasswordParams = mockProcessForgotPasswordParams;
processLoginParams = mockProcessLoginParams;
processResetPasswordParams = mockProcessResetPasswordParams;
processSignupParams = mockProcessSignupParams;
},
};
});
vi.mock('@/lib/routing/search-params/SearchParamParser', () => ({
SearchParamParser: {
parseAuth: vi.fn(),
},
}));
vi.mock('@/lib/builders/view-data/SignupViewDataBuilder', () => ({
SignupViewDataBuilder: {
build: vi.fn(),
},
}));
describe('SignupPageQuery', () => {
let query: SignupPageQuery;
let mockServiceInstance: any;
let mockSearchParams: URLSearchParams;
beforeEach(() => {
vi.clearAllMocks();
mockServiceInstance = {
processSignupParams: mockProcessSignupParams,
};
query = new SignupPageQuery(mockServiceInstance as any);
mockSearchParams = new URLSearchParams('returnTo=/dashboard&token=signup456');
});
it('should return view data when search params are valid and service succeeds', async () => {
const parsedParams = { returnTo: '/dashboard', token: 'signup456' };
const serviceOutput = { email: 'newuser@example.com' };
const viewData = { email: 'newuser@example.com', returnTo: '/dashboard' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processSignupParams.mockResolvedValue(Result.ok(serviceOutput));
(SignupViewDataBuilder.build as any).mockReturnValue(viewData);
const result = await query.execute(mockSearchParams);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual(viewData);
expect(SearchParamParser.parseAuth).toHaveBeenCalledWith(mockSearchParams);
expect(mockServiceInstance.processSignupParams).toHaveBeenCalledWith(parsedParams);
expect(SignupViewDataBuilder.build).toHaveBeenCalledWith(serviceOutput);
});
it('should return error when search params are invalid', async () => {
(SearchParamParser.parseAuth as any).mockReturnValue(Result.err('Invalid params'));
const result = await query.execute(mockSearchParams);
expect(result.isErr()).toBe(true);
expect(result.getError()).toBe('Invalid search parameters: Invalid params');
});
it('should return error when service fails', async () => {
const parsedParams = { returnTo: '/dashboard', token: 'signup456' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processSignupParams.mockResolvedValue(
Result.err({ message: 'Service error' })
);
const result = await query.execute(mockSearchParams);
expect(result.isErr()).toBe(true);
expect(result.getError()).toBe('Service error');
});
it('should return error on exception', async () => {
const parsedParams = { returnTo: '/dashboard', token: 'signup456' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processSignupParams.mockRejectedValue(new Error('Unexpected error'));
const result = await query.execute(mockSearchParams);
expect(result.isErr()).toBe(true);
expect(result.getError()).toBe('Unexpected error');
});
it('should provide a static execute method', async () => {
const parsedParams = { returnTo: '/dashboard', token: 'signup456' };
const serviceOutput = { email: 'newuser@example.com' };
const viewData = { email: 'newuser@example.com', returnTo: '/dashboard' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processSignupParams.mockResolvedValue(Result.ok(serviceOutput));
(SignupViewDataBuilder.build as any).mockReturnValue(viewData);
const result = await SignupPageQuery.execute(mockSearchParams);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual(viewData);
});
it('should handle Record<string, string | string[] | undefined> input', async () => {
const recordParams = { returnTo: '/dashboard', token: 'signup456' };
const parsedParams = { returnTo: '/dashboard', token: 'signup456' };
const serviceOutput = { email: 'newuser@example.com' };
const viewData = { email: 'newuser@example.com', returnTo: '/dashboard' };
(SearchParamParser.parseAuth as any).mockReturnValue(Result.ok(parsedParams));
mockServiceInstance.processSignupParams.mockResolvedValue(Result.ok(serviceOutput));
(SignupViewDataBuilder.build as any).mockReturnValue(viewData);
const result = await query.execute(recordParams);
expect(result.isOk()).toBe(true);
expect(result.unwrap()).toEqual(viewData);
expect(SearchParamParser.parseAuth).toHaveBeenCalledWith(recordParams);
});
});

View File

@@ -6,6 +6,12 @@ import { AuthPageService } from '@/lib/services/auth/AuthPageService';
import { SignupViewData } from '@/lib/view-data/SignupViewData';
export class SignupPageQuery implements PageQuery<SignupViewData, URLSearchParams | Record<string, string | string[] | undefined>> {
private readonly authService: AuthPageService;
constructor(authService?: AuthPageService) {
this.authService = authService || new AuthPageService();
}
async execute(searchParams: URLSearchParams | Record<string, string | string[] | undefined>): Promise<Result<SignupViewData, string>> {
// Parse and validate search parameters
const parsedResult = SearchParamParser.parseAuth(searchParams);
@@ -17,7 +23,7 @@ export class SignupPageQuery implements PageQuery<SignupViewData, URLSearchParam
try {
// Use service to process parameters
const authService = new AuthPageService();
const authService = this.authService;
const serviceResult = await authService.processSignupParams({ returnTo, token });
if (serviceResult.isErr()) {
@@ -27,8 +33,9 @@ export class SignupPageQuery implements PageQuery<SignupViewData, URLSearchParam
// Transform to ViewData using builder
const viewData = SignupViewDataBuilder.build(serviceResult.unwrap());
return Result.ok(viewData);
} catch (error: any) {
return Result.err(error.message || 'Failed to execute signup page query');
} catch (error: unknown) {
const message = error instanceof Error ? error.message : 'Failed to execute signup page query';
return Result.err(message);
}
}