Skip to main content
Glama
wei
by wei
get-item.test.ts6.37 kB
/** * Integration Tests: get-item tool * * Tests the get-item tool with real HackerNews API calls. * Verifies correct behavior for retrieving items with nested comments. */ import { describe, expect, it } from "vitest"; import { getItemHandler } from "../../../src/tools/get-item.js"; /** * Helper: Check if item has nested children */ function hasNestedChildren(children: { children?: unknown[] }[]): boolean { return children.some((child) => child.children && child.children.length > 0); } /** * Helper: Find child with children */ function findChildWithChildren( children: { children?: unknown[] }[] ): { children?: unknown[] } | undefined { return children.find((child) => child.children && child.children.length > 0); } /** * Helper: Validate children structure recursively */ function validateChildren(item: { children?: unknown[] }): boolean { if (!item.children) return true; if (!Array.isArray(item.children)) return false; return item.children.every((child: unknown) => { if (typeof child !== "object" || child === null) return false; const childObj = child as { children?: unknown[] }; return validateChildren(childObj); }); } describe("get-item integration", () => { describe("Story Retrieval", () => { it("should retrieve a story by ID", async () => { // Using a well-known story ID (pg's "How to Start a Startup" is 8863) const result = await getItemHandler({ itemId: "8863" }); expect(result.isError).toBe(false); expect(result.content).toHaveLength(1); const content = result.content[0]; expect(content.type).toBe("text"); if (content.type === "text") { const data = JSON.parse(content.text); expect(data).toHaveProperty("id"); expect(data).toHaveProperty("type"); expect(data).toHaveProperty("author"); expect(data).toHaveProperty("title"); expect(data).toHaveProperty("created_at"); expect(data).toHaveProperty("children"); expect(data.type).toBe("story"); expect(Array.isArray(data.children)).toBe(true); } }); it("should include story metadata", async () => { const result = await getItemHandler({ itemId: "8863" }); expect(result.isError).toBe(false); const content = result.content[0]; if (content.type === "text") { const data = JSON.parse(content.text); expect(data.id).toBeTruthy(); expect(data.author).toBeTruthy(); expect(typeof data.created_at_i).toBe("number"); // Story should have a title if (data.type === "story") { expect(data.title).toBeTruthy(); } } }); it("should retrieve children array for stories", async () => { const result = await getItemHandler({ itemId: "8863" }); expect(result.isError).toBe(false); const content = result.content[0]; if (content.type === "text") { const data = JSON.parse(content.text); expect(data).toHaveProperty("children"); expect(Array.isArray(data.children)).toBe(true); } }); }); describe("Comment Retrieval", () => { it("should retrieve a comment by ID", async () => { // Using a known comment ID from HN const result = await getItemHandler({ itemId: "2921983" }); expect(result.isError).toBe(false); const content = result.content[0]; if (content.type === "text") { const data = JSON.parse(content.text); expect(data.type).toBe("comment"); expect(data).toHaveProperty("text"); expect(data).toHaveProperty("author"); expect(data).toHaveProperty("parent_id"); } }); it("should include comment text and author", async () => { const result = await getItemHandler({ itemId: "2921983" }); expect(result.isError).toBe(false); const content = result.content[0]; if (content.type === "text") { const data = JSON.parse(content.text); expect(data.text).toBeTruthy(); expect(data.author).toBeTruthy(); } }); }); describe("Nested Comments", () => { it("should fetch nested comment structure", async () => { // Item 8863 is a story with comments const result = await getItemHandler({ itemId: "8863" }); expect(result.isError).toBe(false); const content = result.content[0]; if (content.type === "text") { const data = JSON.parse(content.text); expect(Array.isArray(data.children)).toBe(true); // If there are children, verify they have the expected structure if (data.children.length > 0) { const firstChild = data.children[0]; expect(firstChild).toHaveProperty("id"); expect(firstChild).toHaveProperty("author"); } } }); it("should handle multiple levels of nesting", async () => { const result = await getItemHandler({ itemId: "8863" }); expect(result.isError).toBe(false); const content = result.content[0]; if (content.type === "text") { const data = JSON.parse(content.text); // Check if there are nested children (comments with replies) if (data.children && data.children.length > 0) { const nested = hasNestedChildren(data.children); // If there are nested comments, verify structure if (nested) { const childWithChildren = findChildWithChildren(data.children); expect(Array.isArray(childWithChildren?.children)).toBe(true); } } } }); it("should preserve comment tree structure", async () => { const result = await getItemHandler({ itemId: "8863" }); expect(result.isError).toBe(false); const content = result.content[0]; if (content.type === "text") { const data = JSON.parse(content.text); expect(validateChildren(data)).toBe(true); } }); }); describe("Error Handling", () => { it("should return error for empty itemId", async () => { const result = await getItemHandler({ itemId: "" }); expect(result.isError).toBe(true); const content = result.content[0]; if (content.type === "text") { expect(content.text).toContain("itemId"); } }); it("should return error for missing itemId", async () => { const result = await getItemHandler({}); expect(result.isError).toBe(true); }); it("should handle non-existent item ID", async () => { // Using a very high number that likely doesn't exist const result = await getItemHandler({ itemId: "999999999999" }); expect(result.isError).toBe(true); const content = result.content[0]; if (content.type === "text") { expect(content.text).toBeTruthy(); } }); }); });

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/wei/hn-mcp-server'

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