/**
* Integration Tests: get-front-page tool
*
* Tests the get-front-page tool with real HackerNews API calls.
* Verifies correct behavior for retrieving front page posts.
*/
import { describe, expect, it } from "vitest";
import { getFrontPageHandler } from "../../../src/tools/get-front-page.js";
describe("get-front-page integration", () => {
describe("Basic Front Page Request", () => {
it("should retrieve front page posts with default parameters", async () => {
const result = await getFrontPageHandler({});
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);
expect(data.hitsPerPage).toBe(30);
}
});
it("should return posts tagged with front_page", async () => {
const result = await getFrontPageHandler({});
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 have front_page tag
for (const hit of data.hits as { _tags: string[] }[]) {
expect(hit._tags).toContain("front_page");
}
}
});
it("should return stories (not comments)", async () => {
const result = await getFrontPageHandler({});
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);
// Front page should primarily contain stories
const hasStories = data.hits.some((hit: { _tags: string[] }) =>
hit._tags.includes("story")
);
expect(hasStories).toBe(true);
}
});
});
describe("Pagination", () => {
it("should support page navigation", async () => {
const page0 = await getFrontPageHandler({ page: 0 });
const page1 = await getFrontPageHandler({ 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 respect custom hitsPerPage", async () => {
const result = await getFrontPageHandler({ 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 provide pagination metadata", async () => {
const result = await getFrontPageHandler({});
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("Response Time", () => {
it("should return results in under 3 seconds", async () => {
const startTime = Date.now();
const result = await getFrontPageHandler({});
const endTime = Date.now();
expect(result.isError).toBe(false);
const duration = endTime - startTime;
expect(duration).toBeLessThan(3000);
});
});
describe("Error Handling", () => {
it("should return error for negative page number", async () => {
const result = await getFrontPageHandler({ 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 getFrontPageHandler({ 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 getFrontPageHandler({ hitsPerPage: 0 });
expect(result.isError).toBe(true);
});
});
});