You've already forked tf2wikipricing
test: add price service and prices.tf tests
This commit is contained in:
109
__tests__/priceService.test.ts
Normal file
109
__tests__/priceService.test.ts
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
import { describe, expect, test, jest, mock, beforeEach } from "bun:test";
|
||||||
|
import { ItemPriceData, fetchPrice, fetchKeyPrice } from '../src/content/priceService'
|
||||||
|
import { PricesResponse, priceUsingPricesTF } from '../src/content/pricing/pricestf'
|
||||||
|
import { getStorageValue, setStorageValue } from '../src/content/storage'
|
||||||
|
import { defindex_key } from "../src/content/config";
|
||||||
|
|
||||||
|
// Mock the storage module
|
||||||
|
mock.module('../src/content/storage', () => ({
|
||||||
|
getStorageValue: jest.fn(),
|
||||||
|
setStorageValue: jest.fn()
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Mock the pricing module
|
||||||
|
mock.module('../src/content/pricing/pricestf', () => ({
|
||||||
|
priceUsingPricesTF: jest.fn()
|
||||||
|
}))
|
||||||
|
|
||||||
|
describe('Price Service', () => {
|
||||||
|
const mockToken = 'test-token'
|
||||||
|
const mockDefIndex = 105 // Brigade Helm
|
||||||
|
const mockQuality = 11 // Strange
|
||||||
|
const mockSku = `${mockDefIndex};${mockQuality}`
|
||||||
|
const mockDate = new Date()
|
||||||
|
const mockTtl = 30 * 60 * 1000 // 30 minutes
|
||||||
|
|
||||||
|
const mockPriceResponse: PricesResponse = {
|
||||||
|
keys: 1,
|
||||||
|
metal: 21.33
|
||||||
|
}
|
||||||
|
|
||||||
|
const mockKeyPriceResponse: PricesResponse = {
|
||||||
|
keys: 0,
|
||||||
|
metal: 60.11
|
||||||
|
}
|
||||||
|
|
||||||
|
const mockCachedData: ItemPriceData = {
|
||||||
|
sku: mockSku,
|
||||||
|
update: new Date(Date.now() - 15 * 60 * 1000), // 15 minutes ago
|
||||||
|
ttl: mockTtl,
|
||||||
|
keys: 1,
|
||||||
|
metal: 21.11,
|
||||||
|
scmPrice: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('fetchPrice returns cached data if available and not expired', async () => {
|
||||||
|
(getStorageValue as jest.Mock).mockResolvedValue(mockCachedData)
|
||||||
|
|
||||||
|
const result = await fetchPrice(mockToken, mockDefIndex, mockQuality)
|
||||||
|
|
||||||
|
expect(getStorageValue).toHaveBeenCalledWith(expect.stringContaining(mockSku), null)
|
||||||
|
expect(result).toEqual(mockCachedData)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('fetchPrice fetches new data when cache is expired', async () => {
|
||||||
|
const expiredCache: ItemPriceData = { ...mockCachedData, update: new Date(Date.now() - 2 * mockTtl) };
|
||||||
|
(getStorageValue as jest.Mock).mockResolvedValue(expiredCache);
|
||||||
|
(priceUsingPricesTF as jest.Mock).mockResolvedValue(mockPriceResponse)
|
||||||
|
|
||||||
|
const result = await fetchPrice(mockToken, mockDefIndex, mockQuality)
|
||||||
|
|
||||||
|
expect(priceUsingPricesTF).toHaveBeenCalledWith(mockToken, mockDefIndex, mockQuality)
|
||||||
|
expect(setStorageValue).toHaveBeenCalled()
|
||||||
|
expect(result.metal).not.toBe(mockCachedData.metal)
|
||||||
|
expect(result.metal).toBe(mockPriceResponse.metal)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('fetchPrice rejects with 401 when no token provided', async () => {
|
||||||
|
await expect(fetchPrice('', mockDefIndex, mockQuality)).rejects.toBe(401)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('fetchPrice handles pricing API errors', async () => {
|
||||||
|
const testError = 500;
|
||||||
|
(priceUsingPricesTF as jest.Mock).mockRejectedValue(testError);
|
||||||
|
(getStorageValue as jest.Mock).mockResolvedValue(null)
|
||||||
|
|
||||||
|
await expect(fetchPrice(mockToken, mockDefIndex, mockQuality)).rejects.toBe(testError)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('fetchKeyPrice uses correct parameters', async () => {
|
||||||
|
(getStorageValue as jest.Mock).mockResolvedValue(null);
|
||||||
|
(priceUsingPricesTF as jest.Mock).mockResolvedValue(mockKeyPriceResponse)
|
||||||
|
|
||||||
|
const result = await fetchKeyPrice(mockToken)
|
||||||
|
|
||||||
|
expect(priceUsingPricesTF).toHaveBeenCalledWith(mockToken, defindex_key, 6)
|
||||||
|
expect(result.keys).toBe(0) // A key cannot cost a key :P
|
||||||
|
expect(result.metal).toBe(mockKeyPriceResponse.metal)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('ItemPriceData.toString() returns formatted string', () => {
|
||||||
|
const data = new ItemPriceData()
|
||||||
|
data.sku = mockSku
|
||||||
|
data.update = mockDate
|
||||||
|
data.ttl = mockTtl
|
||||||
|
data.keys = 1
|
||||||
|
data.metal = 10.66
|
||||||
|
data.scmPrice = 2.68
|
||||||
|
|
||||||
|
const result = data.toString()
|
||||||
|
expect(result).toContain(`Price for ${mockSku}`)
|
||||||
|
expect(result).toContain(`"keys":${data.keys}`)
|
||||||
|
expect(result).toContain(`"metal":${data.metal}`)
|
||||||
|
expect(result).toContain(`"scmPrice":${data.scmPrice}`)
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user