- Migrated `useAuth` hooks to use functions from auto-generated API client for improved maintainability and OpenAPI compliance. - Replaced manual API calls with SDK functions (`login`, `register`, `logout`, etc.) and added error type guards for runtime safety (`isTokenWithUser`, `isSuccessResponse`). - Enhanced hooks with better error logging, optional success callbacks, and stricter type annotations. - Refactored `Logout` and `LogoutAll` mutations to handle missing tokens gracefully and clear local state on server failure. - Added tests for API type guards and updated functionality of hooks to validate proper behaviors. - Removed legacy `client-config.ts` to align with new API client utilization. - Improved inline documentation for hooks with detailed descriptions and usage guidance.
99 lines
2.6 KiB
JavaScript
99 lines
2.6 KiB
JavaScript
// Learn more: https://github.com/testing-library/jest-dom
|
|
import '@testing-library/jest-dom'
|
|
import 'whatwg-fetch'; // Polyfill fetch API for MSW
|
|
import { Crypto } from '@peculiar/webcrypto';
|
|
|
|
// Mock window object
|
|
global.window = global.window || {};
|
|
|
|
// Mock BroadcastChannel for MSW
|
|
global.BroadcastChannel = class BroadcastChannel {
|
|
constructor(name) {
|
|
this.name = name;
|
|
}
|
|
postMessage() {}
|
|
close() {}
|
|
addEventListener() {}
|
|
removeEventListener() {}
|
|
};
|
|
|
|
// Use real Web Crypto API polyfill for Node environment
|
|
const cryptoPolyfill = new Crypto();
|
|
|
|
// Store references before assignment
|
|
const subtleRef = cryptoPolyfill.subtle;
|
|
const getRandomValuesRef = cryptoPolyfill.getRandomValues.bind(cryptoPolyfill);
|
|
|
|
// Use Object.defineProperty to ensure properties aren't overridden
|
|
if (!global.crypto) {
|
|
global.crypto = {};
|
|
}
|
|
|
|
Object.defineProperty(global.crypto, 'subtle', {
|
|
value: subtleRef,
|
|
writable: false,
|
|
configurable: true,
|
|
enumerable: true,
|
|
});
|
|
|
|
Object.defineProperty(global.crypto, 'getRandomValues', {
|
|
value: getRandomValuesRef,
|
|
writable: false,
|
|
configurable: true,
|
|
enumerable: true,
|
|
});
|
|
|
|
// Mock TextEncoder/TextDecoder if not available
|
|
if (typeof TextEncoder === 'undefined') {
|
|
global.TextEncoder = class TextEncoder {
|
|
encode(str) {
|
|
const buf = Buffer.from(str, 'utf-8');
|
|
return new Uint8Array(buf);
|
|
}
|
|
};
|
|
}
|
|
|
|
if (typeof TextDecoder === 'undefined') {
|
|
global.TextDecoder = class TextDecoder {
|
|
decode(arr) {
|
|
return Buffer.from(arr).toString('utf-8');
|
|
}
|
|
};
|
|
}
|
|
|
|
// Mock localStorage (must be on global to satisfy typeof checks)
|
|
global.localStorage = {
|
|
getItem: jest.fn(),
|
|
setItem: jest.fn(),
|
|
removeItem: jest.fn(),
|
|
clear: jest.fn(),
|
|
length: 0,
|
|
key: jest.fn(),
|
|
};
|
|
|
|
// Mock sessionStorage (must be on global to satisfy typeof checks)
|
|
global.sessionStorage = {
|
|
getItem: jest.fn(),
|
|
setItem: jest.fn(),
|
|
removeItem: jest.fn(),
|
|
clear: jest.fn(),
|
|
length: 0,
|
|
key: jest.fn(),
|
|
};
|
|
|
|
// Reset storage mocks before each test
|
|
beforeEach(() => {
|
|
// Don't use clearAllMocks - it breaks the mocks
|
|
// Instead reset individual storage mock return values
|
|
if (global.localStorage && typeof global.localStorage.getItem.mockReset === 'function') {
|
|
global.localStorage.getItem.mockReset().mockReturnValue(null);
|
|
global.localStorage.setItem.mockReset();
|
|
global.localStorage.removeItem.mockReset();
|
|
}
|
|
if (global.sessionStorage && typeof global.sessionStorage.getItem.mockReset === 'function') {
|
|
global.sessionStorage.getItem.mockReset().mockReturnValue(null);
|
|
global.sessionStorage.setItem.mockReset();
|
|
global.sessionStorage.removeItem.mockReset();
|
|
}
|
|
});
|