Files
tf2wikipricing/__tests__/exchangeRateService.test.ts
2025-05-01 18:31:58 -04:00

97 lines
3.5 KiB
TypeScript

import { describe, expect, it, jest, mock, beforeEach, beforeAll } from "bun:test";
import { prepareExchangeRates, wipeExchangeRates } from '../src/content/exchangeRateService.ts'
import { getStorageValue, setStorageValue } from '../src/content/storage'
import { storage_exchangerates, storage_exchangerates_next, storage_exchangerates_update } from "../src/content/config";
import { logDebug, logError } from '../src/content/utils/log';
declare function GM_fetch(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response>
// Mock the storage functions
mock.module('../src/content/storage', () => ({
setStorageValue: mock(async (key: string, value: any) => {}),
getStorageValue: mock(async (key: string, defaultValue: any) => defaultValue)
}));
// Mock the log functions
mock.module('../src/content/utils/log', () => ({
logDebug: mock(() => {}),
log: mock(() => {}),
logError: mock(() => {})
}));
describe('wipeExchangeRates', () => {
it('should clear exchange rate storage and set update timestamps', async () => {
await wipeExchangeRates();
expect(setStorageValue).toHaveBeenCalledWith(storage_exchangerates, null);
expect(setStorageValue).toHaveBeenCalledWith(storage_exchangerates_update, expect.any(String));
expect(setStorageValue).toHaveBeenCalledWith(storage_exchangerates_next, expect.any(String));
expect(logDebug).toHaveBeenCalled();
});
});
describe('prepareExchangeRates', () => {
const mockRates = { USD: 1, EUR: 0.85, GBP: 0.73 };
beforeAll(() => {
jest
.spyOn(global, 'GM_fetch')
.mockImplementation(() => {
return Promise.resolve({
ok: false,
status: 500
} as Response);
});
});
beforeEach(() => {
jest.clearAllMocks();
});
it('should return stored rates if they are up to date', async () => {
(getStorageValue as jest.Mock).mockImplementation(async (key) => {
if (key === storage_exchangerates) return mockRates;
if (key === storage_exchangerates_update) return new Date().toISOString();
if (key === storage_exchangerates_next) return new Date(Date.now() + 100000).toISOString();
return null;
});
const rates = await prepareExchangeRates();
expect(rates).toEqual(mockRates);
expect(GM_fetch as jest.Mock).not.toHaveBeenCalled();
});
it('should fetch new rates when they are expired', async () => {
(getStorageValue as jest.Mock).mockImplementation(async (key) => {
if (key === storage_exchangerates_update) return new Date(Date.now() - 100000).toISOString();
if (key === storage_exchangerates_next) return new Date(Date.now() - 50000).toISOString();
return null;
});
const mockResponse = {
rates: mockRates,
time_next_update_utc: new Date(Date.now() + 100000).toISOString()
};
(GM_fetch as jest.Mock).mockResolvedValue({
ok: true,
json: async () => (mockResponse)
});
(chrome.runtime.sendMessage as jest.Fn).mockImplementation(() => mockResponse);
const rates = await prepareExchangeRates();
expect(rates).toEqual(mockRates);
expect(setStorageValue).toHaveBeenCalledWith(storage_exchangerates, mockRates);
});
it('should handle fetch errors gracefully', async () => {
(getStorageValue as jest.Mock).mockResolvedValue(null);
(GM_fetch as jest.Mock).mockResolvedValueOnce({
ok: false,
status: 500
} as Response);
(chrome.runtime.sendMessage as jest.Fn).mockImplementation(() => {});
const rates = await prepareExchangeRates();
expect(rates).toBeNull();
expect(logError).toHaveBeenCalled();
});
});