Skip to main content
Glama
crud-tools.test.ts9.67 kB
import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { handleCreateWorld, handleGetWorld, handleListWorlds, handleDeleteWorld, handleCreateCharacter, handleGetCharacter, handleUpdateCharacter, handleListCharacters, handleDeleteCharacter, closeTestDb } from '../../src/server/crud-tools'; const mockCtx = { sessionId: 'test-session' }; describe('World CRUD Tools', () => { afterEach(() => { closeTestDb(); }); describe('create_world', () => { it('should create a new world', async () => { const result = await handleCreateWorld({ name: 'Test World', seed: 'test-seed', width: 100, height: 100 }, mockCtx); expect(result.content).toHaveLength(1); const response = JSON.parse(result.content[0].text); expect(response.id).toBeDefined(); expect(response.name).toBe('Test World'); }); it('should validate world data', async () => { await expect(handleCreateWorld({ name: '', // Invalid: empty name seed: 'test', width: 100, height: 100 }, mockCtx)).rejects.toThrow(); }); }); describe('get_world', () => { let worldId: string; beforeEach(async () => { const result = await handleCreateWorld({ name: 'Get World', seed: 'seed-get', width: 50, height: 50 }, mockCtx); const world = JSON.parse(result.content[0].text); worldId = world.id; }); it('should retrieve an existing world', async () => { const result = await handleGetWorld({ id: worldId }, mockCtx); const world = JSON.parse(result.content[0].text); expect(world.id).toBe(worldId); expect(world.name).toBe('Get World'); }); it('should throw error for non-existent world', async () => { await expect(handleGetWorld({ id: 'non-existent' }, mockCtx)) .rejects.toThrow('World not found'); }); }); describe('list_worlds', () => { let worldId1: string; let worldId2: string; beforeEach(async () => { const result1 = await handleCreateWorld({ name: 'World 1', seed: 'seed1', width: 50, height: 50 }, mockCtx); worldId1 = JSON.parse(result1.content[0].text).id; const result2 = await handleCreateWorld({ name: 'World 2', seed: 'seed2', width: 60, height: 60 }, mockCtx); worldId2 = JSON.parse(result2.content[0].text).id; }); it('should list all worlds', async () => { const result = await handleListWorlds({}, mockCtx); const response = JSON.parse(result.content[0].text); expect(response.worlds.length).toBeGreaterThanOrEqual(2); expect(response.worlds.some((w: any) => w.id === worldId1)).toBe(true); expect(response.worlds.some((w: any) => w.id === worldId2)).toBe(true); }); }); describe('delete_world', () => { let worldId: string; beforeEach(async () => { const result = await handleCreateWorld({ name: 'Delete World', seed: 'seed-delete', width: 50, height: 50 }, mockCtx); worldId = JSON.parse(result.content[0].text).id; }); it('should delete a world', async () => { const result = await handleDeleteWorld({ id: worldId }, mockCtx); const response = JSON.parse(result.content[0].text); expect(response.message).toBe('World deleted'); // Verify it's gone await expect(handleGetWorld({ id: worldId }, mockCtx)) .rejects.toThrow('World not found'); }); }); }); describe('Character CRUD Tools', () => { afterEach(() => { closeTestDb(); }); describe('create_character', () => { it('should create a new character', async () => { const result = await handleCreateCharacter({ name: 'Hero', stats: { str: 16, dex: 14, con: 15, int: 10, wis: 12, cha: 8 }, hp: 30, maxHp: 30, ac: 16, level: 3 }, mockCtx); expect(result.content).toHaveLength(1); const response = JSON.parse(result.content[0].text); expect(response.id).toBeDefined(); expect(response.name).toBe('Hero'); }); it('should create an NPC with faction', async () => { const result = await handleCreateCharacter({ name: 'Goblin', stats: { str: 8, dex: 14, con: 10, int: 8, wis: 8, cha: 6 }, hp: 10, maxHp: 10, ac: 13, level: 1, factionId: 'goblins', behavior: 'hostile' }, mockCtx); const response = JSON.parse(result.content[0].text); expect(response.factionId).toBe('goblins'); expect(response.behavior).toBe('hostile'); }); }); describe('get_character', () => { let charId: string; beforeEach(async () => { const result = await handleCreateCharacter({ name: 'Fighter', stats: { str: 16, dex: 12, con: 14, int: 10, wis: 12, cha: 8 }, hp: 25, maxHp: 25, ac: 17, level: 2 }, mockCtx); charId = JSON.parse(result.content[0].text).id; }); it('should retrieve an existing character', async () => { const result = await handleGetCharacter({ id: charId }, mockCtx); const char = JSON.parse(result.content[0].text); expect(char.id).toBe(charId); expect(char.name).toBe('Fighter'); }); it('should throw error for non-existent character', async () => { await expect(handleGetCharacter({ id: 'non-existent' }, mockCtx)) .rejects.toThrow('Character not found'); }); }); describe('update_character', () => { let charId: string; beforeEach(async () => { const result = await handleCreateCharacter({ name: 'Wizard', stats: { str: 8, dex: 14, con: 12, int: 16, wis: 13, cha: 10 }, hp: 20, maxHp: 20, ac: 12, level: 2 }, mockCtx); charId = JSON.parse(result.content[0].text).id; }); it('should update character HP', async () => { const result = await handleUpdateCharacter({ id: charId, hp: 15 }, mockCtx); const response = JSON.parse(result.content[0].text); expect(response.hp).toBe(15); }); it('should update multiple fields', async () => { const result = await handleUpdateCharacter({ id: charId, hp: 18, level: 3 }, mockCtx); const response = JSON.parse(result.content[0].text); expect(response.hp).toBe(18); expect(response.level).toBe(3); }); }); describe('list_characters', () => { beforeEach(async () => { await handleCreateCharacter({ name: 'Rogue', stats: { str: 10, dex: 16, con: 12, int: 14, wis: 10, cha: 12 }, hp: 22, maxHp: 22, ac: 15, level: 2 }, mockCtx); await handleCreateCharacter({ name: 'Cleric', stats: { str: 14, dex: 10, con: 14, int: 10, wis: 16, cha: 12 }, hp: 24, maxHp: 24, ac: 16, level: 2 }, mockCtx); }); it('should list all characters', async () => { const result = await handleListCharacters({}, mockCtx); const response = JSON.parse(result.content[0].text); expect(response.characters.length).toBeGreaterThanOrEqual(2); }); }); describe('delete_character', () => { let charId: string; beforeEach(async () => { const result = await handleCreateCharacter({ name: 'Temp Character', stats: { str: 10, dex: 10, con: 10, int: 10, wis: 10, cha: 10 }, hp: 20, maxHp: 20, ac: 12, level: 1 }, mockCtx); charId = JSON.parse(result.content[0].text).id; }); it('should delete a character', async () => { const result = await handleDeleteCharacter({ id: charId }, mockCtx); const response = JSON.parse(result.content[0].text); expect(response.message).toBe('Character deleted'); // Verify it's gone await expect(handleGetCharacter({ id: charId }, mockCtx)) .rejects.toThrow('Character not found'); }); }); });

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