several fixes to various tests
All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 14m14s

This commit is contained in:
2025-12-26 23:37:39 -08:00
parent c4742959e4
commit 768d02b9ed
20 changed files with 1113 additions and 63 deletions

View File

@@ -178,6 +178,45 @@ describe('AI API Client (Network Mocking with MSW)', () => {
});
});
describe('uploadAndProcessFlyer error handling', () => {
it('should throw a structured error with JSON body on non-ok response', async () => {
const mockFile = new File(['content'], 'flyer.pdf', { type: 'application/pdf' });
const checksum = 'checksum-abc-123';
const errorBody = { message: 'Checksum already exists', flyerId: 99 };
server.use(
http.post('http://localhost/api/ai/upload-and-process', () => {
return HttpResponse.json(errorBody, { status: 409 });
}),
);
// The function now throws a structured object, not an Error instance.
await expect(aiApiClient.uploadAndProcessFlyer(mockFile, checksum)).rejects.toEqual({
status: 409,
body: errorBody,
});
});
it('should throw a structured error with text body on non-ok, non-JSON response', async () => {
const mockFile = new File(['content'], 'flyer.pdf', { type: 'application/pdf' });
const checksum = 'checksum-abc-123';
const errorText = 'Internal Server Error';
server.use(
http.post('http://localhost/api/ai/upload-and-process', () => {
return HttpResponse.text(errorText, { status: 500 });
}),
);
// The function now throws a structured object, not an Error instance.
// The catch block in the implementation wraps the text in a message property.
await expect(aiApiClient.uploadAndProcessFlyer(mockFile, checksum)).rejects.toEqual({
status: 500,
body: { message: errorText },
});
});
});
describe('getJobStatus', () => {
it('should send a GET request to the correct job status URL', async () => {
const jobId = 'job-id-456';
@@ -192,6 +231,66 @@ describe('AI API Client (Network Mocking with MSW)', () => {
});
});
describe('getJobStatus error handling', () => {
const jobId = 'job-id-789';
it('should throw a JobFailedError if job state is "failed"', async () => {
const failedStatus: aiApiClient.JobStatus = {
id: jobId,
state: 'failed',
progress: { message: 'AI model exploded', errorCode: 'AI_ERROR' },
returnValue: null,
failedReason: 'Raw error from BullMQ',
};
server.use(
http.get(`http://localhost/api/ai/jobs/${jobId}/status`, () => {
return HttpResponse.json(failedStatus);
}),
);
await expect(aiApiClient.getJobStatus(jobId)).rejects.toThrow(
new aiApiClient.JobFailedError('AI model exploded', 'AI_ERROR'),
);
});
it('should use failedReason for JobFailedError if progress message is missing', async () => {
const failedStatus: aiApiClient.JobStatus = {
id: jobId,
state: 'failed',
progress: null, // No progress object
returnValue: null,
failedReason: 'Raw error from BullMQ',
};
server.use(
http.get(`http://localhost/api/ai/jobs/${jobId}/status`, () => {
return HttpResponse.json(failedStatus);
}),
);
await expect(aiApiClient.getJobStatus(jobId)).rejects.toThrow(
new aiApiClient.JobFailedError('Raw error from BullMQ', 'UNKNOWN_ERROR'),
);
});
it('should throw a generic error if the API response is not ok', async () => {
const errorBody = { message: 'Job not found' };
server.use(
http.get(`http://localhost/api/ai/jobs/${jobId}/status`, () => {
return HttpResponse.json(errorBody, { status: 404 });
}),
);
await expect(aiApiClient.getJobStatus(jobId)).rejects.toThrow('Job not found');
});
it('should throw a generic error if the API response is not valid JSON', async () => {
server.use(http.get(`http://localhost/api/ai/jobs/${jobId}/status`, () => HttpResponse.text('Invalid JSON')));
await expect(aiApiClient.getJobStatus(jobId)).rejects.toThrow(expect.any(SyntaxError));
});
});
describe('isImageAFlyer', () => {
it('should construct FormData and send a POST request', async () => {
const mockFile = new File(['dummy image content'], 'flyer.jpg', { type: 'image/jpeg' });