Skip to main content
Glama
wei
by wei
get-latest-posts.test.ts6.71 kB
/** * Integration Tests: get-latest-posts tool * * Tests the get-latest-posts tool with real HackerNews API calls. * Verifies correct behavior for retrieving latest posts by date. */ import { describe, expect, it } from "vitest"; import { getLatestPostsHandler } from "../../../src/tools/get-latest-posts.js"; describe("get-latest-posts integration", () => { describe("All Types", () => { it("should retrieve latest posts without filters", async () => { const result = await getLatestPostsHandler({}); 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("hits"); expect(data).toHaveProperty("nbHits"); expect(data).toHaveProperty("page"); expect(data).toHaveProperty("nbPages"); expect(data).toHaveProperty("hitsPerPage"); expect(Array.isArray(data.hits)).toBe(true); expect(data.hits.length).toBeGreaterThan(0); expect(data.page).toBe(0); } }); it("should return posts sorted by date (most recent first)", async () => { const result = await getLatestPostsHandler({}); expect(result.isError).toBe(false); const content = result.content[0]; if (content.type === "text") { const data = JSON.parse(content.text); expect(data.hits.length).toBeGreaterThan(1); // Verify timestamps are in descending order (newest first) const timestamps = data.hits .filter((hit: { created_at_i?: number }) => hit.created_at_i) .map((hit: { created_at_i: number }) => hit.created_at_i); for (let i = 0; i < timestamps.length - 1; i++) { expect(timestamps[i]).toBeGreaterThanOrEqual(timestamps[i + 1]); } } }); }); describe("Filter by Tags", () => { it("should filter by story tag", async () => { const result = await getLatestPostsHandler({ tags: ["story"] }); expect(result.isError).toBe(false); const content = result.content[0]; if (content.type === "text") { const data = JSON.parse(content.text); expect(data.hits.length).toBeGreaterThan(0); // All results should be stories for (const hit of data.hits as { _tags: string[] }[]) { expect(hit._tags).toContain("story"); } } }); it("should filter by comment tag", async () => { const result = await getLatestPostsHandler({ tags: ["comment"] }); expect(result.isError).toBe(false); const content = result.content[0]; if (content.type === "text") { const data = JSON.parse(content.text); expect(data.hits.length).toBeGreaterThan(0); // All results should be comments for (const hit of data.hits as { _tags: string[] }[]) { expect(hit._tags).toContain("comment"); } } }); it("should maintain date sorting with tag filter", async () => { const result = await getLatestPostsHandler({ tags: ["story"] }); expect(result.isError).toBe(false); const content = result.content[0]; if (content.type === "text") { const data = JSON.parse(content.text); // Verify timestamps are still in descending order const timestamps = data.hits .filter((hit: { created_at_i?: number }) => hit.created_at_i) .map((hit: { created_at_i: number }) => hit.created_at_i); for (let i = 0; i < timestamps.length - 1; i++) { expect(timestamps[i]).toBeGreaterThanOrEqual(timestamps[i + 1]); } } }); it("should handle multiple tags", async () => { const result = await getLatestPostsHandler({ tags: ["story", "show_hn"], }); expect(result.isError).toBe(false); const content = result.content[0]; if (content.type === "text") { const data = JSON.parse(content.text); expect(data.hits.length).toBeGreaterThan(0); // Results should match one of the tags for (const hit of data.hits as { _tags: string[] }[]) { const hasMatchingTag = hit._tags.includes("story") || hit._tags.includes("show_hn"); expect(hasMatchingTag).toBe(true); } } }); }); describe("Pagination", () => { it("should respect custom hitsPerPage", async () => { const result = await getLatestPostsHandler({ hitsPerPage: 10 }); expect(result.isError).toBe(false); const content = result.content[0]; if (content.type === "text") { const data = JSON.parse(content.text); expect(data.hitsPerPage).toBe(10); expect(data.hits.length).toBeLessThanOrEqual(10); } }); it("should return different results for different pages", async () => { const page0 = await getLatestPostsHandler({ page: 0 }); const page1 = await getLatestPostsHandler({ page: 1 }); expect(page0.isError).toBe(false); expect(page1.isError).toBe(false); const content0 = page0.content[0]; const content1 = page1.content[0]; if (content0.type === "text" && content1.type === "text") { const data0 = JSON.parse(content0.text); const data1 = JSON.parse(content1.text); // If there are results on both pages, they should be different if (data0.hits.length > 0 && data1.hits.length > 0) { const firstId0 = data0.hits[0].objectID; const firstId1 = data1.hits[0].objectID; expect(firstId0).not.toBe(firstId1); } expect(data0.page).toBe(0); expect(data1.page).toBe(1); } }); it("should provide pagination metadata", async () => { const result = await getLatestPostsHandler({}); expect(result.isError).toBe(false); const content = result.content[0]; if (content.type === "text") { const data = JSON.parse(content.text); expect(typeof data.nbHits).toBe("number"); expect(typeof data.nbPages).toBe("number"); expect(typeof data.page).toBe("number"); expect(typeof data.hitsPerPage).toBe("number"); if (data.nbHits > 0) { expect(data.nbPages).toBeGreaterThan(0); } } }); }); describe("Error Handling", () => { it("should return error for negative page number", async () => { const result = await getLatestPostsHandler({ page: -1 }); expect(result.isError).toBe(true); const content = result.content[0]; if (content.type === "text") { expect(content.text).toBeTruthy(); } }); it("should return error for invalid hitsPerPage", async () => { const result = await getLatestPostsHandler({ hitsPerPage: 2000 }); expect(result.isError).toBe(true); const content = result.content[0]; if (content.type === "text") { expect(content.text).toBeTruthy(); } }); it("should return error for hitsPerPage below minimum", async () => { const result = await getLatestPostsHandler({ hitsPerPage: 0 }); expect(result.isError).toBe(true); }); }); });

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