Skip to main content
Glama
inventory.test.ts6.76 kB
import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { handleCreateItemTemplate, handleGiveItem, handleRemoveItem, handleEquipItem, handleUnequipItem, handleGetInventory } from '../../src/server/inventory-tools'; import { handleCreateCharacter } from '../../src/server/crud-tools'; import { closeTestDb } from '../../src/server/crud-tools'; describe('Inventory System', () => { const mockCtx = { sessionId: 'test-session' }; afterEach(() => { closeTestDb(); }); beforeEach(async () => { closeTestDb(); // Force DB init const { getDb } = await import('../../src/storage'); const db = getDb(':memory:'); const tables = db.prepare("SELECT name FROM sqlite_master WHERE type='table'").all(); console.log('Tables in test:', tables.map((t: any) => t.name)); }); // Helper to create a test character async function createTestCharacter(): Promise<string> { const charResult = await handleCreateCharacter({ name: 'Inventory Tester', hp: 10, maxHp: 10, ac: 10, level: 1, stats: { str: 10, dex: 10, con: 10, int: 10, wis: 10, cha: 10 } }, mockCtx); return JSON.parse(charResult.content[0].text).id; } // Helper to create a test item async function createTestItem(name: string, type: string, props?: object): Promise<string> { const result = await handleCreateItemTemplate({ name, type, weight: 5, value: 10, properties: props }, mockCtx); return JSON.parse(result.content[0].text).id; } it('should create item templates', async () => { const result = await handleCreateItemTemplate({ name: 'Iron Sword', type: 'weapon', weight: 5, value: 10, properties: { damage: '1d8' } }, mockCtx); const item = JSON.parse(result.content[0].text); expect(item.name).toBe('Iron Sword'); expect(item.id).toBeDefined(); // Create a shield too const shieldResult = await handleCreateItemTemplate({ name: 'Wooden Shield', type: 'armor', weight: 3, value: 5 }, mockCtx); const shield = JSON.parse(shieldResult.content[0].text); expect(shield.name).toBe('Wooden Shield'); expect(shield.id).toBeDefined(); }); it('should give items to character', async () => { // Create character and item fresh for this test const characterId = await createTestCharacter(); const swordId = await createTestItem('Iron Sword', 'weapon', { damage: '1d8' }); // Give sword await handleGiveItem({ characterId, itemId: swordId, quantity: 1 }, mockCtx); // Verify inventory const invResult = await handleGetInventory({ characterId }, mockCtx); const inventory = JSON.parse(invResult.content[0].text); expect(inventory.items).toHaveLength(1); expect(inventory.items[0].itemId).toBe(swordId); expect(inventory.items[0].quantity).toBe(1); }); it('should equip and unequip items', async () => { // Create character and item fresh for this test const characterId = await createTestCharacter(); const swordId = await createTestItem('Iron Sword', 'weapon', { damage: '1d8' }); // Give sword first await handleGiveItem({ characterId, itemId: swordId, quantity: 1 }, mockCtx); // Equip sword await handleEquipItem({ characterId, itemId: swordId, slot: 'mainhand' }, mockCtx); let invResult = await handleGetInventory({ characterId }, mockCtx); let inventory = JSON.parse(invResult.content[0].text); expect(inventory.items[0].equipped).toBe(true); expect(inventory.items[0].slot).toBe('mainhand'); // Unequip sword await handleUnequipItem({ characterId, itemId: swordId }, mockCtx); invResult = await handleGetInventory({ characterId }, mockCtx); inventory = JSON.parse(invResult.content[0].text); expect(inventory.items[0].equipped).toBe(false); expect(inventory.items[0].slot).toBeUndefined(); }); it('should remove items', async () => { // Create character and item fresh for this test const characterId = await createTestCharacter(); const swordId = await createTestItem('Iron Sword', 'weapon', { damage: '1d8' }); // Give sword first await handleGiveItem({ characterId, itemId: swordId, quantity: 1 }, mockCtx); // Now remove it await handleRemoveItem({ characterId, itemId: swordId, quantity: 1 }, mockCtx); const invResult = await handleGetInventory({ characterId }, mockCtx); const inventory = JSON.parse(invResult.content[0].text); expect(inventory.items).toHaveLength(0); }); it('should handle stacking items', async () => { // Create character fresh for this test const characterId = await createTestCharacter(); // Create potions const potionResult = await handleCreateItemTemplate({ name: 'Health Potion', type: 'consumable', weight: 0.5, value: 5 }, mockCtx); const potionId = JSON.parse(potionResult.content[0].text).id; // Give 5 potions await handleGiveItem({ characterId, itemId: potionId, quantity: 5 }, mockCtx); // Give 3 more await handleGiveItem({ characterId, itemId: potionId, quantity: 3 }, mockCtx); const invResult = await handleGetInventory({ characterId }, mockCtx); const inventory = JSON.parse(invResult.content[0].text); expect(inventory.items[0].quantity).toBe(8); }); // EDGE-004: Empty item names validation it('EDGE-004: should reject empty item names', async () => { await expect(handleCreateItemTemplate({ name: '', // Empty name - should be rejected type: 'misc', weight: 1, value: 10 }, mockCtx)).rejects.toThrow(); }); it('EDGE-004: should reject whitespace-only item names', async () => { await expect(handleCreateItemTemplate({ name: ' ', // Whitespace only - should be rejected type: 'misc', weight: 1, value: 10 }, mockCtx)).rejects.toThrow(); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mnehmos/rpg-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server