Files
tf2wikipricing/__tests__/schema.test.ts
xenticore fa7276a53c feat: add support for festive weapon variants
on schema update, festive variants are linked. on content injection, if if finds a festive variant, it adds price rows for Festive and Strange Festive.
2025-04-02 18:54:39 -04:00

204 lines
7.4 KiB
TypeScript

import { describe, expect, test, mock } from "bun:test";
import { ItemSchema, ItemSlot, getItemIndexByName, getTradableStatusByDefindex, getTradableStatusByName, linkFestiveVariants, prepareSchema } from '../src/content/schemaService'
// Mock the storage and log functions
mock.module('../src/content/storage', () => ({
setStorageValue: mock(async (key: string, value: any) => {}),
getStorageValue: mock(async (key: string, defaultValue: any) => defaultValue)
}));
mock.module('../src/content/utils/log', () => ({
logDebug: mock(() => {}),
log: mock(() => {}),
logError: mock(() => {})
}));
const mockSchema: ItemSchema = {
'21': {
name: 'Flame Thrower',
slot: ItemSlot.Primary,
tradable: false,
hasAustraliumVariant: false,
canKillstreakify: true,
festiveVariant: null
},
'208': {
name: 'Flame Thrower',
slot: ItemSlot.Primary,
tradable: true,
hasAustraliumVariant: true,
canKillstreakify: true,
festiveVariant: 659
},
'659': {
name: 'Festive Flame Thrower',
slot: ItemSlot.Primary,
tradable: true,
hasAustraliumVariant: false,
canKillstreakify: true,
festiveVariant: null
},
'5021': {
name: 'Mann Co. Supply Crate Key',
slot: ItemSlot.Tool,
tradable: true,
hasAustraliumVariant: false,
canKillstreakify: false,
festiveVariant: null
},
'15141': {
name: 'Flame Thrower',
slot: ItemSlot.Primary,
tradable: true,
hasAustraliumVariant: false,
canKillstreakify: true,
festiveVariant: null
},
'69420': {
name: 'Non-Tradable Item',
slot: ItemSlot.Misc,
tradable: false,
hasAustraliumVariant: false,
canKillstreakify: false,
festiveVariant: null
}
}
describe('Schema Service', () => {
test('getItemIndexByName returns correct defindex', () => {
expect(getItemIndexByName(mockSchema, 'Flame Thrower')).toBe(208)
expect(getItemIndexByName(mockSchema, 'Mann Co. Supply Crate Key')).toBe(5021)
expect(getItemIndexByName(mockSchema, 'Non-Existent Item')).toBeNull()
})
test('getTradableStatusByDefindex returns correct status', () => {
expect(getTradableStatusByDefindex(mockSchema, 208)).toBe(true)
expect(getTradableStatusByDefindex(mockSchema, 5021)).toBe(true)
expect(getTradableStatusByDefindex(mockSchema, 69420)).toBe(false)
expect(() => getTradableStatusByDefindex(mockSchema, 999)).toThrow()
})
test('getTradableStatusByName returns correct status', () => {
expect(getTradableStatusByName(mockSchema, 'Flame Thrower')).toBe(true)
expect(getTradableStatusByName(mockSchema, 'Mann Co. Supply Crate Key')).toBe(true)
expect(getTradableStatusByName(mockSchema, 'Non-Tradable Item')).toBe(false)
expect(getTradableStatusByName(mockSchema, 'Non-Existent Item')).toBe(true)
})
test('prepareSchema fetches and processes schema correctly', async () => {
// Mock GM_fetch response
const mockResponse = {
ok: true,
json: async () => [
{
defindex: 1,
item_name: 'Test Item',
item_slot: 'misc',
attributes: [
{ "name": "cannot trade", "class": "cannot_trade", "value": 1 }
],
capabilities: {}
},
{
defindex: 208,
item_name: 'Flame Thrower',
item_slot: 'primary',
capabilities: { can_killstreakify: true }
}
]
};
// Mock GM_fetch
globalThis.GM_fetch = mock(async () => mockResponse);
const result = await prepareSchema();
expect(result).toEqual({
'1': {
name: 'Test Item',
slot: ItemSlot.Misc,
tradable: false,
canKillstreakify: false,
hasAustraliumVariant: false
},
'208': {
name: 'Flame Thrower',
slot: ItemSlot.Primary,
tradable: true,
canKillstreakify: true,
hasAustraliumVariant: true
}
});
});
describe('linkFestiveVariants', () => {
test('should link festive variants to their original counterparts', () => {
const testSchema = {
'21': { // Stock (should be ignored)
name: 'Flame Thrower',
slot: ItemSlot.Primary,
tradable: false,
hasAustraliumVariant: false,
canKillstreakify: false,
festiveVariant: null
},
'208': { // Original Flame Thrower
name: 'Flame Thrower',
slot: ItemSlot.Primary,
tradable: true,
hasAustraliumVariant: true,
canKillstreakify: true,
festiveVariant: null
},
'659': { // Festive Flame Thrower (should be detected)
name: 'Festive Flame Thrower',
slot: ItemSlot.Primary,
tradable: true,
hasAustraliumVariant: false,
canKillstreakify: true,
festiveVariant: null
},
'15141': { // Decorated (should be ignored)
name: 'Flame Thrower',
slot: ItemSlot.Primary,
tradable: true,
hasAustraliumVariant: false,
canKillstreakify: true,
festiveVariant: null
}
};
const mockResponseItems = [
{ item_class: 'tf_weapon_flamethrower', defindex: 21, item_name: 'Flame Thrower' }, // Incorrect; stock
{ item_class: 'tf_weapon_flamethrower', defindex: 208, item_name: 'Flame Thrower' }, // Original
{ item_class: 'tf_weapon_flamethrower', defindex: 659, item_name: 'Festive Flame Thrower' }, // Festive
{ item_class: 'tf_weapon_flamethrower', defindex: 15141, item_name: 'Flame Thrower' }, // Incorrect; decorated
];
linkFestiveVariants(mockResponseItems, testSchema)
expect(testSchema['21'].festiveVariant).toBeNull()
expect(testSchema['208'].festiveVariant).toBe(659)
expect(testSchema['659'].festiveVariant).toBeNull();
expect(testSchema['15141'].festiveVariant).toBeNull()
})
test('should not link if no festive variant exists', () => {
const testSchema = {
'163': {
name: 'Crit-a-Cola',
slot: ItemSlot.Secondary,
tradable: true,
hasAustraliumVariant: false,
canKillstreakify: false,
festiveVariant: null
}
};
const mockResponseItems = [
{ item_class: 'tf_weapon_lunchbox_drink', defindex: 163, item_name: 'Crit-a-Cola' }
];
linkFestiveVariants(mockResponseItems, testSchema);
expect(testSchema['163'].festiveVariant).toBeNull();
});
});
})