| 1 | import {
|
| 2 | filterByCategory,
|
| 3 | groupByDate,
|
| 4 | mergeAndSort,
|
| 5 | } from "@/lib/utils/history";
|
| 6 | import type { HistoryCard, HistoryCategory } from "@/lib/history/types";
|
| 7 |
|
| 8 | function card(
|
| 9 | id: string,
|
| 10 | category: HistoryCategory,
|
| 11 | at: Date,
|
| 12 | ): HistoryCard {
|
| 13 | return {
|
| 14 | id,
|
| 15 | category,
|
| 16 | timestamp: at.toISOString(),
|
| 17 | title: id,
|
| 18 | summary: "",
|
| 19 | } as HistoryCard;
|
| 20 | }
|
| 21 |
|
| 22 | describe("mergeAndSort", () => {
|
| 23 | it("flattens the buckets into one descending list", () => {
|
| 24 | const oldest = card("oldest", "mood", new Date(2025, 0, 1, 10, 0));
|
| 25 | const newest = card("newest", "sleep", new Date(2025, 0, 3, 10, 0));
|
| 26 | const middle = card("middle", "trigger", new Date(2025, 0, 2, 10, 0));
|
| 27 |
|
| 28 | const merged = mergeAndSort([[oldest, middle], [newest]]);
|
| 29 |
|
| 30 | expect(merged.map((c) => c.id)).toEqual(["newest", "middle", "oldest"]);
|
| 31 | });
|
| 32 |
|
| 33 | it("returns an empty list for no buckets", () => {
|
| 34 | expect(mergeAndSort([])).toEqual([]);
|
| 35 | });
|
| 36 | });
|
| 37 |
|
| 38 | describe("groupByDate", () => {
|
| 39 | it("groups into fixed, ordered date buckets", () => {
|
| 40 | const morning = card("m1", "mood", new Date(2025, 0, 15, 9, 0));
|
| 41 | const evening = card("s1", "sleep", new Date(2025, 0, 15, 20, 0));
|
| 42 | const previous = card("t1", "trigger", new Date(2025, 0, 14, 12, 0));
|
| 43 |
|
| 44 | const grouped = groupByDate(
|
| 45 | [morning, evening, previous],
|
| 46 | new Date(2025, 5, 1),
|
| 47 | );
|
| 48 |
|
| 49 | expect(Object.keys(grouped)).toEqual([
|
| 50 | "quarta-feira, 15 de janeiro",
|
| 51 | "terça-feira, 14 de janeiro",
|
| 52 | ]);
|
| 53 | expect(grouped["quarta-feira, 15 de janeiro"].map((c) => c.id)).toEqual([
|
| 54 | "m1",
|
| 55 | "s1",
|
| 56 | ]);
|
| 57 | expect(grouped["terça-feira, 14 de janeiro"].map((c) => c.id)).toEqual([
|
| 58 | "t1",
|
| 59 | ]);
|
| 60 | });
|
| 61 |
|
| 62 | it("adds the year only for cards outside the current year", () => {
|
| 63 | const thisYear = card("this", "mood", new Date(2026, 0, 15, 9, 0));
|
| 64 | const lastYear = card("last", "mood", new Date(2025, 0, 15, 9, 0));
|
| 65 |
|
| 66 | const grouped = groupByDate([thisYear, lastYear], new Date(2026, 5, 1));
|
| 67 |
|
| 68 | expect(Object.keys(grouped)).toEqual([
|
| 69 | "quinta-feira, 15 de janeiro",
|
| 70 | "quarta-feira, 15 de janeiro de 2025",
|
| 71 | ]);
|
| 72 | });
|
| 73 |
|
| 74 | it("returns no buckets for an empty list", () => {
|
| 75 | expect(groupByDate([])).toEqual({});
|
| 76 | });
|
| 77 | });
|
| 78 |
|
| 79 | describe("filterByCategory", () => {
|
| 80 | const cards = [
|
| 81 | card("m", "mood", new Date(2025, 0, 1, 10, 0)),
|
| 82 | card("s", "sleep", new Date(2025, 0, 2, 10, 0)),
|
| 83 | card("t", "trigger", new Date(2025, 0, 3, 10, 0)),
|
| 84 | card("c", "care_action", new Date(2025, 0, 4, 10, 0)),
|
| 85 | ];
|
| 86 |
|
| 87 | it.each([
|
| 88 | ["mood", ["m"]],
|
| 89 | ["sleep", ["s"]],
|
| 90 | ["trigger", ["t"]],
|
| 91 | ["care_action", ["c"]],
|
| 92 | ] as const)("keeps only the %s cards", (category, ids) => {
|
| 93 | expect(filterByCategory(cards, category).map((c) => c.id)).toEqual(ids);
|
| 94 | });
|
| 95 |
|
| 96 | it("keeps everything for 'all'", () => {
|
| 97 | expect(filterByCategory(cards, "all").map((c) => c.id)).toEqual([
|
| 98 | "m",
|
| 99 | "s",
|
| 100 | "t",
|
| 101 | "c",
|
| 102 | ]);
|
| 103 | });
|
| 104 | });
|