You've already forked tf2wikipricing
346 lines
13 KiB
TypeScript
346 lines
13 KiB
TypeScript
import { describe, expect, test, mock, beforeEach, jest } from "bun:test";
|
|
import { ItemSchema, ItemSlot, getItemIndexByName, getTradableStatusByDefindex, getTradableStatusByName, linkBotkillerVariants, 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 mockSchemaResponse = [
|
|
{
|
|
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 }
|
|
}
|
|
]
|
|
|
|
const mockSchema: ItemSchema = {
|
|
'21': {
|
|
name: 'Flame Thrower',
|
|
slot: ItemSlot.Primary,
|
|
tradable: false,
|
|
hasAustraliumVariant: false,
|
|
canKillstreakify: true,
|
|
festiveVariant: null,
|
|
botkillerVariants: null
|
|
},
|
|
'208': {
|
|
name: 'Flame Thrower',
|
|
slot: ItemSlot.Primary,
|
|
tradable: true,
|
|
hasAustraliumVariant: true,
|
|
canKillstreakify: true,
|
|
festiveVariant: 659,
|
|
botkillerVariants: [798, 807]
|
|
},
|
|
'659': {
|
|
name: 'Festive Flame Thrower',
|
|
slot: ItemSlot.Primary,
|
|
tradable: true,
|
|
hasAustraliumVariant: false,
|
|
canKillstreakify: true,
|
|
festiveVariant: null,
|
|
botkillerVariants: null
|
|
},
|
|
'798': {
|
|
name: 'Silver Botkiller Flame Thrower Mk.I',
|
|
slot: ItemSlot.Primary,
|
|
tradable: true,
|
|
hasAustraliumVariant: false,
|
|
canKillstreakify: true,
|
|
festiveVariant: null,
|
|
botkillerVariants: null
|
|
},
|
|
'807': {
|
|
name: 'Gold Botkiller Flame Thrower Mk.I',
|
|
slot: ItemSlot.Primary,
|
|
tradable: true,
|
|
hasAustraliumVariant: false,
|
|
canKillstreakify: true,
|
|
festiveVariant: null,
|
|
botkillerVariants: null
|
|
},
|
|
'5021': {
|
|
name: 'Mann Co. Supply Crate Key',
|
|
slot: ItemSlot.Tool,
|
|
tradable: true,
|
|
hasAustraliumVariant: false,
|
|
canKillstreakify: false,
|
|
festiveVariant: null,
|
|
botkillerVariants: null
|
|
},
|
|
'15141': {
|
|
name: 'Flame Thrower',
|
|
slot: ItemSlot.Primary,
|
|
tradable: true,
|
|
hasAustraliumVariant: false,
|
|
canKillstreakify: true,
|
|
festiveVariant: null,
|
|
botkillerVariants: null
|
|
},
|
|
'69420': {
|
|
name: 'Non-Tradable Item',
|
|
slot: ItemSlot.Misc,
|
|
tradable: false,
|
|
hasAustraliumVariant: false,
|
|
canKillstreakify: false,
|
|
festiveVariant: null,
|
|
botkillerVariants: 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 () => mockSchemaResponse
|
|
};
|
|
|
|
// Mock Chrome runtime message
|
|
(chrome.runtime.sendMessage as jest.Fn).mockImplementation(() => mockSchemaResponse);
|
|
|
|
// 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,
|
|
botkillerVariants: null
|
|
},
|
|
'208': { // Original Flame Thrower
|
|
name: 'Flame Thrower',
|
|
slot: ItemSlot.Primary,
|
|
tradable: true,
|
|
hasAustraliumVariant: true,
|
|
canKillstreakify: true,
|
|
festiveVariant: null,
|
|
botkillerVariants: null
|
|
},
|
|
'659': { // Festive Flame Thrower (should be detected)
|
|
name: 'Festive Flame Thrower',
|
|
slot: ItemSlot.Primary,
|
|
tradable: true,
|
|
hasAustraliumVariant: false,
|
|
canKillstreakify: true,
|
|
festiveVariant: null,
|
|
botkillerVariants: null
|
|
},
|
|
'15141': { // Decorated (should be ignored)
|
|
name: 'Flame Thrower',
|
|
slot: ItemSlot.Primary,
|
|
tradable: true,
|
|
hasAustraliumVariant: false,
|
|
canKillstreakify: true,
|
|
festiveVariant: null,
|
|
botkillerVariants: 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,
|
|
botkillerVariants: null
|
|
}
|
|
};
|
|
|
|
const mockResponseItems = [
|
|
{ item_class: 'tf_weapon_lunchbox_drink', defindex: 163, item_name: 'Crit-a-Cola' }
|
|
];
|
|
|
|
linkFestiveVariants(mockResponseItems, testSchema);
|
|
|
|
expect(testSchema['163'].festiveVariant).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('linkBotkillerVariants', () => {
|
|
test('should link botkiller variants to their original counterparts', () => {
|
|
const testSchema = {
|
|
'21': { // Original Rocket Launcher
|
|
name: 'Flame Thrower',
|
|
slot: ItemSlot.Primary,
|
|
tradable: false,
|
|
hasAustraliumVariant: false,
|
|
canKillstreakify: false,
|
|
festiveVariant: null,
|
|
botkillerVariants: null
|
|
},
|
|
'208': { // Original Flame Thrower
|
|
name: 'Flame Thrower',
|
|
slot: ItemSlot.Primary,
|
|
tradable: true,
|
|
hasAustraliumVariant: true,
|
|
canKillstreakify: true,
|
|
festiveVariant: null,
|
|
botkillerVariants: null
|
|
},
|
|
'798': {
|
|
name: 'Silver Botkiller Flame Thrower Mk. I',
|
|
slot: ItemSlot.Primary,
|
|
tradable: true,
|
|
hasAustraliumVariant: false,
|
|
canKillstreakify: true,
|
|
festiveVariant: null,
|
|
botkillerVariants: null
|
|
},
|
|
'807': {
|
|
name: 'Gold Botkiller Flame Thrower Mk. I',
|
|
slot: ItemSlot.Primary,
|
|
tradable: true,
|
|
hasAustraliumVariant: false,
|
|
canKillstreakify: true,
|
|
festiveVariant: null,
|
|
botkillerVariants: null
|
|
},
|
|
'15141': { // Decorated (should be ignored)
|
|
name: 'Flame Thrower',
|
|
slot: ItemSlot.Primary,
|
|
tradable: true,
|
|
hasAustraliumVariant: false,
|
|
canKillstreakify: true,
|
|
festiveVariant: null,
|
|
botkillerVariants: null
|
|
}
|
|
};
|
|
const mockResponseItems = [
|
|
{ item_class: 'tf_weapon_flamethrower', defindex: 21, item_name: 'Flame Thrower', item_type_name: 'Flame Thrower'
|
|
}, // Incorrect; stock
|
|
{
|
|
item_class: 'tf_weapon_flamethrower',
|
|
defindex: 208,
|
|
item_name: 'Flame Thrower',
|
|
item_type_name: 'Flame Thrower'
|
|
},
|
|
{
|
|
item_class: 'tf_weapon_flamethrower',
|
|
defindex: 798,
|
|
item_name: 'Silver Botkiller Flame Thrower Mk.I',
|
|
item_type_name: 'Flame Thrower'
|
|
},
|
|
{
|
|
item_class: 'tf_weapon_flamethrower',
|
|
defindex: 807,
|
|
item_name: 'Gold Botkiller Flame Thrower Mk.I',
|
|
item_type_name: 'Flame Thrower'
|
|
},
|
|
{ item_class: 'tf_weapon_flamethrower', defindex: 15141, item_name: 'Flame Thrower', item_type_name: 'Flame Thrower' }, // Incorrect; decorated
|
|
];
|
|
linkBotkillerVariants(mockResponseItems, testSchema);
|
|
expect(testSchema['21'].botkillerVariants).toBeNull()
|
|
expect(testSchema['208'].botkillerVariants).toEqual([798, 807]);
|
|
expect(testSchema['798'].botkillerVariants).toBeNull();
|
|
expect(testSchema['807'].botkillerVariants).toBeNull();
|
|
expect(testSchema['15141'].botkillerVariants).toBeNull()
|
|
});
|
|
|
|
test('should not link if no botkiller variants exist', () => {
|
|
const testSchema = {
|
|
'163': { // Crit-a-Cola
|
|
name: 'Crit-a-Cola',
|
|
slot: ItemSlot.Secondary,
|
|
tradable: true,
|
|
hasAustraliumVariant: false,
|
|
festiveVariant: null,
|
|
canKillstreakify: false,
|
|
botkillerVariants: null,
|
|
}
|
|
};
|
|
|
|
const mockResponseItems = [
|
|
{
|
|
item_class: 'tf_weapon_lunchbox_drink',
|
|
defindex: 163,
|
|
item_name: 'Crit-a-Cola',
|
|
item_type_name: 'Lunch Box',
|
|
}
|
|
];
|
|
|
|
linkBotkillerVariants(mockResponseItems, testSchema);
|
|
expect(testSchema['163'].botkillerVariants).toBeNull();
|
|
});
|
|
})
|
|
}) |