Some checks failed
Deploy to Test Environment / deploy-to-test (push) Has been cancelled
- Added a new notes file regarding the deprecation of the Google AI JavaScript SDK. - Removed unused imports and fixed duplicate imports in admin and auth route tests. - Enhanced type safety in error handling for unique constraint violations in auth routes. - Simplified gamification route tests by removing unnecessary imports. - Updated price route to improve type safety by casting request body. - Improved mock implementations in system route tests for better type handling. - Cleaned up user routes by removing unused imports. - Enhanced AI API client tests with more robust type definitions for form data. - Updated recipe database tests to remove unused error imports. - Refactored flyer processing service tests for better type safety and clarity. - Improved logger client to use `unknown` instead of `any` for better type safety. - Cleaned up notification service tests to ensure proper type casting. - Updated queue service tests to remove unnecessary imports and improve type handling. - Refactored queue service workers tests for better type safety in job processors. - Cleaned up user routes integration tests by removing unused imports. - Enhanced tests setup for unit tests to improve type safety in mocked Express requests. - Updated PDF converter tests for better type safety in mocked return values. - Improved price parser tests to ensure proper handling of null and undefined inputs.
129 lines
4.5 KiB
TypeScript
129 lines
4.5 KiB
TypeScript
import { describe, it, expect, vi, beforeEach, beforeAll } from 'vitest';
|
|
import type { Toaster } from './notificationService';
|
|
|
|
// --- FIX LEDGER ---
|
|
// 1. Initial attempt: Spy on default export property. Failed (0 calls).
|
|
// 2. Attempt: Hoisted spies attached to default export. Failed (0 calls).
|
|
// 3. Attempt: Function-as-object mock. Failed (TS error / 0 calls).
|
|
// 4. Attempt: Plain object mock. Failed (0 calls).
|
|
// 5. Attempt: Mock default export as a simple object using Object.assign. Failed (0 calls).
|
|
// 6. Attempt: Remove mock factory. Import real module and use vi.spyOn on the default export. Failed (0 calls).
|
|
// 7. Strategy: Dependency Injection. Failed (0 calls). This indicates the exported function itself is a mock (spy), likely due to implicit automocking or preserved mock state.
|
|
// 8. Current Strategy: Explicitly unmock the service module to force Vitest to load the actual implementation.
|
|
|
|
// Remove the broken mock factory
|
|
vi.unmock('../lib/toast');
|
|
// Explicitly unmock the service under test
|
|
vi.unmock('./notificationService');
|
|
|
|
describe('Notification Service', () => {
|
|
beforeAll(() => {
|
|
if (typeof window === 'undefined') {
|
|
throw new Error('Test environment is not JSDOM. Window is undefined.');
|
|
}
|
|
|
|
// Polyfill matchMedia if it doesn't exist (common JSDOM issue)
|
|
Object.defineProperty(window, 'matchMedia', {
|
|
writable: true,
|
|
value: vi.fn().mockImplementation(query => ({
|
|
matches: false,
|
|
media: query,
|
|
onchange: null,
|
|
addListener: vi.fn(),
|
|
removeListener: vi.fn(),
|
|
addEventListener: vi.fn(),
|
|
removeEventListener: vi.fn(),
|
|
dispatchEvent: vi.fn(),
|
|
})),
|
|
});
|
|
});
|
|
|
|
beforeEach(() => {
|
|
vi.resetModules();
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe('notifySuccess', () => {
|
|
it('should call the injected toaster.success with correct options', async () => {
|
|
const mockToaster = {
|
|
success: vi.fn(),
|
|
error: vi.fn(),
|
|
};
|
|
|
|
const { notifySuccess } = await import('./notificationService');
|
|
|
|
const message = 'Operation was successful!';
|
|
notifySuccess(message, mockToaster);
|
|
|
|
expect(mockToaster.success).toHaveBeenCalledTimes(1);
|
|
expect(mockToaster.success).toHaveBeenCalledWith(
|
|
message,
|
|
expect.objectContaining({
|
|
style: expect.any(Object),
|
|
iconTheme: {
|
|
primary: '#10B981',
|
|
secondary: '#fff',
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
it('should not throw an error and should log a warning if the toaster is invalid', async () => {
|
|
// Arrange
|
|
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
const invalidToaster = { success: undefined, error: vi.fn() }; // Missing success method
|
|
const message = 'This should not appear';
|
|
|
|
const { notifySuccess } = await import('./notificationService');
|
|
|
|
// Act
|
|
notifySuccess(message, invalidToaster as unknown as Toaster);
|
|
|
|
// Assert
|
|
expect(consoleWarnSpy).toHaveBeenCalledWith('[NotificationService] toast.success is not available. Message:', message);
|
|
consoleWarnSpy.mockRestore();
|
|
});
|
|
});
|
|
|
|
describe('notifyError', () => {
|
|
it('should call the injected toaster.error with correct options', async () => {
|
|
const mockToaster = {
|
|
success: vi.fn(),
|
|
error: vi.fn(),
|
|
};
|
|
|
|
const { notifyError } = await import('./notificationService');
|
|
|
|
const message = 'Something went wrong!';
|
|
notifyError(message, mockToaster);
|
|
|
|
expect(mockToaster.error).toHaveBeenCalledTimes(1);
|
|
expect(mockToaster.error).toHaveBeenCalledWith(
|
|
message,
|
|
expect.objectContaining({
|
|
style: expect.any(Object),
|
|
iconTheme: {
|
|
primary: '#EF4444',
|
|
secondary: '#fff',
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
it('should not throw an error and should log a warning if the toaster is invalid', async () => {
|
|
// Arrange
|
|
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
const invalidToaster = { success: vi.fn(), error: undefined }; // Missing error method
|
|
const message = 'This error should not appear';
|
|
|
|
const { notifyError } = await import('./notificationService');
|
|
|
|
// Act
|
|
notifyError(message, invalidToaster as unknown as Toaster);
|
|
|
|
// Assert
|
|
expect(consoleWarnSpy).toHaveBeenCalledWith('[NotificationService] toast.error is not available. Message:', message);
|
|
consoleWarnSpy.mockRestore();
|
|
});
|
|
});
|
|
}); |