Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Seb/sin case refactoring #480

Merged
merged 7 commits into from
Mar 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import type { SinCaseService } from '~/.server/domain/multi-channel/case-api-service';
import type { PersonSinCase } from '~/.server/domain/multi-channel/case-api-service-models';
import type { SinCaseDto } from '~/.server/domain/multi-channel/sin-case-models';
import { serverEnvironment } from '~/.server/environment';
import { AppError } from '~/errors/app-error';
import { ErrorCodes } from '~/errors/error-codes';

export function getDefaultSinCaseService(): SinCaseService {
return {
getCases: async (): Promise<PersonSinCase[]> => {
getSinCases: async (): Promise<SinCaseDto[]> => {
const response = await fetch(`${serverEnvironment.INTEROP_SIN_REG_API_BASE_URL}/cases`);
if (!response.ok) throw new AppError(`Cases not found.`, ErrorCodes.SIN_CASE_NOT_FOUND);
return response.json();
},

getCaseById: async (id: string): Promise<PersonSinCase> => {
getSinCaseById: async (id: string): Promise<SinCaseDto> => {
const response = await fetch(`${serverEnvironment.INTEROP_SIN_REG_API_BASE_URL}/cases/${id}`);
if (!response.ok) throw new AppError(`Case with ID '${id}' not found.`, ErrorCodes.SIN_CASE_NOT_FOUND);
return response.json();
Expand Down
Empty file.
198 changes: 52 additions & 146 deletions frontend/app/.server/domain/multi-channel/case-api-service-mock.ts
Original file line number Diff line number Diff line change
@@ -1,156 +1,62 @@
import type { SinCaseService } from '~/.server/domain/multi-channel/case-api-service';
import type { PersonSinCase } from '~/.server/domain/multi-channel/case-api-service-models';
import { APPLICANT_PRIMARY_DOCUMENT_CHOICE, APPLICANT_STATUS_IN_CANADA } from '~/domain/constants';
import { fakeSinCaseDtos } from '~/.server/domain/multi-channel/sin-case-faker';
import type { SinCaseDto } from '~/.server/domain/multi-channel/sin-case-models';
import { hasAnySinCases, listAllSinCases, setSinCases, getSinCaseByKey } from '~/.server/domain/multi-channel/sin-cases-store';
import { AppError } from '~/errors/app-error';
import { ErrorCodes } from '~/errors/error-codes';

/**
* Provides a mock implementation of the `SinCaseService`.
* This service simulates fetching SIN cases by either returning stored cases
* or generating a mock dataset if none exist.
*
* @returns An implementation of `SinCaseService` with mocked data.
*/
export function getMockSinCaseService(): SinCaseService {
/**
* Retrieves all SIN cases from the store.
* If no cases exist, it generates a mock dataset and stores it before returning.
*
* @returns A promise resolving to an array of `SinCaseDto` objects.
*/
async function getSinCases(): Promise<SinCaseDto[]> {
if (await hasAnySinCases()) {
return await listAllSinCases();
}

// Initialize dataset with mock data
const generatedDataset = fakeSinCaseDtos();
await setSinCases(generatedDataset);
return generatedDataset;
}

return {
getCases: async (): Promise<PersonSinCase[]> => {
return new Promise((resolve) => resolve(mockCases));
/**
* Retrieves all SIN cases, generating mock data if necessary.
*
* @returns A promise resolving to an array of `SinCaseDto` objects.
*/
async getSinCases(): Promise<SinCaseDto[]> {
const sinCases = await getSinCases();
return Promise.resolve(sinCases);
},

getCaseById: async (id: string): Promise<PersonSinCase> =>
new Promise((resolve, reject) => {
const _case = mockCases.find(({ caseId }) => caseId === id);
if (_case) return resolve(_case);
reject(new AppError(`Case with ID '${id}' not found.`, ErrorCodes.SIN_CASE_NOT_FOUND));
}),
};
}
/**
* Retrieves a SIN case by its unique ID.
* Throws an `AppError` if the case does not exist.
*
* @param id - The unique identifier of the SIN case.
* @returns A promise resolving to a `SinCaseDto` object.
* @throws {AppError} If the case is not found, an error with code `SIN_CASE_NOT_FOUND` is thrown.
*/
async getSinCaseById(id: string): Promise<SinCaseDto> {
const sinCase = await getSinCaseByKey(id);

const mockCases = [
{
caseId: '00000000000000',
birthDetails: {
country: 'f8914e7c-2c95-ea11-a812-000d3a0c2b5d',
province: '925808d0-3195-ea11-a812-000d3a0c2b5d',
city: 'City',
fromMultipleBirth: true,
},
contactInformation: {
preferredLanguage: '564190000',
primaryPhoneNumber: '+15005005000',
emailAddress: '[email protected]',
country: 'f8914e7c-2c95-ea11-a812-000d3a0c2b5d',
province: '925808d0-3195-ea11-a812-000d3a0c2b5d',
address: '123 City',
postalCode: 'H0H0H0',
city: 'City',
},
currentNameInfo: { preferredSameAsDocumentName: true as const },
parentDetails: [
{
unavailable: false,
givenName: 'Robert',
lastName: 'Doe',
birthLocation: {
country: 'f8914e7c-2c95-ea11-a812-000d3a0c2b5d',
province: '925808d0-3195-ea11-a812-000d3a0c2b5d',
city: 'City',
},
},
{
unavailable: false,
givenName: 'Jane',
lastName: 'Doe',
birthLocation: {
country: 'f8914e7c-2c95-ea11-a812-000d3a0c2b5d',
province: '925808d0-3195-ea11-a812-000d3a0c2b5d',
city: 'City',
},
},
],
personalInformation: {
firstNamePreviouslyUsed: ['Robert'],
lastNameAtBirth: 'Doe',
lastNamePreviouslyUsed: [],
gender: '564190001',
},
previousSin: { hasPreviousSin: '564190000', socialInsuranceNumber: '800000002' },
primaryDocuments: {
currentStatusInCanada: APPLICANT_STATUS_IN_CANADA.canadianCitizenBornOutsideCanada,
documentType: APPLICANT_PRIMARY_DOCUMENT_CHOICE.certificateOfCanadianCitizenship,
registrationNumber: '12345678',
clientNumber: '1234567890',
givenName: 'John',
lastName: 'Doe',
dateOfBirthYear: '1900',
dateOfBirthMonth: '01',
dateOfBirthDay: '01',
dateOfBirth: '1900-01-01',
gender: '564190001',
citizenshipDateYear: '1900',
citizenshipDateMonth: '01',
citizenshipDateDay: '01',
citizenshipDate: '1900-01-01',
},
privacyStatement: { agreedToTerms: true as const },
requestDetails: { scenario: '564190000', type: '564190004' },
secondaryDocument: { documentType: '564190000', expiryYear: '2026', expiryMonth: '01' },
},
{
caseId: '00000000000001',
birthDetails: {
country: 'f8914e7c-2c95-ea11-a812-000d3a0c2b5d',
province: '925808d0-3195-ea11-a812-000d3a0c2b5d',
city: 'City',
fromMultipleBirth: false,
},
contactInformation: {
preferredLanguage: '564190000',
primaryPhoneNumber: '+15005005000',
emailAddress: '[email protected]',
country: 'f8914e7c-2c95-ea11-a812-000d3a0c2b5d',
province: '925808d0-3195-ea11-a812-000d3a0c2b5d',
address: '123 City',
postalCode: 'H0H0H0',
city: 'City',
},
currentNameInfo: {
preferredSameAsDocumentName: false,
firstName: 'Johnny',
lastName: 'Doe',
supportingDocuments: { required: false as const },
},
parentDetails: [
{
unavailable: false,
givenName: 'Robert',
lastName: 'Doe',
birthLocation: {
country: 'f8914e7c-2c95-ea11-a812-000d3a0c2b5d',
province: '925808d0-3195-ea11-a812-000d3a0c2b5d',
city: 'City',
},
},
],
personalInformation: {
firstNamePreviouslyUsed: ['Robert'],
lastNameAtBirth: 'Doe',
lastNamePreviouslyUsed: [],
gender: '564190001',
},
previousSin: { hasPreviousSin: '564190001' },
primaryDocuments: {
currentStatusInCanada: APPLICANT_STATUS_IN_CANADA.canadianCitizenBornOutsideCanada,
documentType: APPLICANT_PRIMARY_DOCUMENT_CHOICE.certificateOfCanadianCitizenship,
registrationNumber: '12345678',
clientNumber: '1234567890',
givenName: 'John',
lastName: 'Doe',
dateOfBirthYear: '1900',
dateOfBirthMonth: '01',
dateOfBirthDay: '01',
dateOfBirth: '1900-01-01',
gender: '564190001',
citizenshipDateYear: '1900',
citizenshipDateMonth: '01',
citizenshipDateDay: '01',
citizenshipDate: '1900-01-01',
if (!sinCase) {
throw new AppError(`Case with ID '${id}' not found.`, ErrorCodes.SIN_CASE_NOT_FOUND);
}

return Promise.resolve(sinCase);
},
privacyStatement: { agreedToTerms: true as const },
requestDetails: { scenario: '564190000', type: '564190004' },
secondaryDocument: { documentType: '564190000', expiryYear: '2026', expiryMonth: '01' },
},
];
};
}
6 changes: 3 additions & 3 deletions frontend/app/.server/domain/multi-channel/case-api-service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { getDefaultSinCaseService } from '~/.server/domain/multi-channel/case-api-service-default';
import { getMockSinCaseService } from '~/.server/domain/multi-channel/case-api-service-mock';
import type { PersonSinCase } from '~/.server/domain/multi-channel/case-api-service-models';
import type { SinCaseDto } from '~/.server/domain/multi-channel/sin-case-models';
import { serverEnvironment } from '~/.server/environment';

export type SinCaseService = {
getCases(): Promise<PersonSinCase[]>;
getCaseById(id: string): Promise<PersonSinCase>;
getSinCases(): Promise<SinCaseDto[]>;
getSinCaseById(id: string): Promise<SinCaseDto>;
};

export function getSinCaseService(): SinCaseService {
Expand Down
Loading