import { describe, test } from "node:test"; import assert from "node:assert/strict"; import { generateHeatmap } from "../src/reports/heatmap.js"; import type { PostAnalytics } from "../src/models/types.js"; function createPost(date: string, impressions: number, engagementRate: number): PostAnalytics { return { id: `post-${date}`, title: `Post on ${date}`, publishedDate: date, metrics: { impressions, reactions: 10, comments: 5, shares: 2, clicks: 3, engagementRate, }, importedAt: "2026-04-01T00:00:00Z", exportSource: "test.csv", }; } describe("generateHeatmap", () => { // Verified days: 2026-04-06=Mon, 07=Tue, 08=Wed, 09=Thu, 12=Sun, 13=Mon, 14=Tue, 15=Wed const posts: PostAnalytics[] = [ createPost("2026-04-06", 1000, 3.0), // Monday createPost("2026-04-07", 2000, 4.0), // Tuesday createPost("2026-04-08", 1500, 3.5), // Wednesday createPost("2026-04-13", 3000, 5.0), // Monday createPost("2026-04-14", 2500, 4.5), // Tuesday createPost("2026-04-12", 800, 2.0), // Sunday ]; test("groups posts by day of week correctly", () => { const report = generateHeatmap(posts); const monday = report.byDayOfWeek.find(d => d.dayName === "Monday"); const tuesday = report.byDayOfWeek.find(d => d.dayName === "Tuesday"); const sunday = report.byDayOfWeek.find(d => d.dayName === "Sunday"); assert.equal(monday?.postCount, 2); assert.equal(tuesday?.postCount, 2); assert.equal(sunday?.postCount, 1); }); test("calculates correct averages per day", () => { const report = generateHeatmap(posts); const monday = report.byDayOfWeek.find(d => d.dayName === "Monday")!; const tuesday = report.byDayOfWeek.find(d => d.dayName === "Tuesday")!; assert.equal(monday.avgImpressions, 2000); // (1000+3000)/2 assert.equal(tuesday.avgImpressions, 2250); // (2000+2500)/2 assert.equal(monday.avgEngagementRate, 4.0); // (3.0+5.0)/2 }); test("handles days with no posts", () => { const report = generateHeatmap(posts); const friday = report.byDayOfWeek.find(d => d.dayName === "Friday")!; assert.equal(friday.postCount, 0); assert.equal(friday.avgImpressions, 0); assert.equal(friday.avgEngagementRate, 0); }); test("returns 7 entries ordered Mon-Sun", () => { const report = generateHeatmap(posts); assert.equal(report.byDayOfWeek.length, 7); assert.equal(report.byDayOfWeek[0].dayName, "Monday"); assert.equal(report.byDayOfWeek[6].dayName, "Sunday"); assert.deepEqual( report.byDayOfWeek.map(d => d.dayIndex), [1, 2, 3, 4, 5, 6, 7] ); }); test("identifies best day for impressions", () => { const report = generateHeatmap(posts); assert.equal(report.bestDayImpressions, "Tuesday"); }); test("identifies best day for engagement", () => { const report = generateHeatmap(posts); assert.equal(report.bestDayEngagement, "Tuesday"); // (4.0+4.5)/2 = 4.25 }); test("sets correct postsAnalyzed count", () => { const report = generateHeatmap(posts); assert.equal(report.postsAnalyzed, 6); }); test("handles empty post list", () => { const report = generateHeatmap([]); assert.equal(report.postsAnalyzed, 0); assert.equal(report.byDayOfWeek.length, 7); assert.equal(report.bestDayImpressions, "N/A"); assert.equal(report.bestDayEngagement, "N/A"); for (const day of report.byDayOfWeek) { assert.equal(day.postCount, 0); } }); test("identifies best post per day", () => { const report = generateHeatmap(posts); const monday = report.byDayOfWeek.find(d => d.dayName === "Monday")!; assert.equal(monday.bestPost?.publishedDate, "2026-04-13"); // 3000 impressions }); test("calculates correct date range", () => { const report = generateHeatmap(posts); assert.equal(report.dateRange.from, "2026-04-06"); assert.equal(report.dateRange.to, "2026-04-14"); }); });