mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 14:32:03 +00:00
style: apply prettier across the tree
One-shot prettier pass so the new format:check gate starts from a clean baseline. Formatting only — no behaviour change. Generator-owned and vendored artifacts stay untouched via .prettierignore.
This commit is contained in:
1 parent
b3fea2ef59
commit
1f4ba5939d
1000 files changed
+12130
-8385
No files matched your search
@@ -60,12 +60,14 @@ vi.mock("next/headers", () => ({
|
||||
// `recomputeUserMoodRollups` aggregate. The warm-up is fire-and-
|
||||
// forget on the route so its return value is irrelevant for parity.
|
||||
vi.mock("@/lib/rollups/mood-rollups", async () => {
|
||||
const actual = await vi.importActual<typeof import("@/lib/rollups/mood-rollups")>(
|
||||
"@/lib/rollups/mood-rollups",
|
||||
);
|
||||
const actual = await vi.importActual<
|
||||
typeof import("@/lib/rollups/mood-rollups")
|
||||
>("@/lib/rollups/mood-rollups");
|
||||
return {
|
||||
...actual,
|
||||
ensureUserMoodRollupsFresh: vi.fn().mockResolvedValue({ recomputed: false }),
|
||||
ensureUserMoodRollupsFresh: vi
|
||||
.fn()
|
||||
.mockResolvedValue({ recomputed: false }),
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -24,12 +24,20 @@ vi.mock("@/lib/crypto", () => ({
|
||||
decrypt: (s: string) => s.replace(/^enc:/, ""),
|
||||
}));
|
||||
vi.mock("@/lib/auth/session", () => ({ getSession: vi.fn() }));
|
||||
vi.mock("@/lib/auth/audit", () => ({ auditLog: vi.fn().mockResolvedValue(undefined) }));
|
||||
vi.mock("@/lib/auth/audit", () => ({
|
||||
auditLog: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
vi.mock("@/lib/logging/transports", () => ({ emitIfSampled: vi.fn() }));
|
||||
vi.mock("@/lib/db-compat", () => ({ ensureDbCompatibility: vi.fn().mockResolvedValue(undefined) }));
|
||||
vi.mock("@/lib/db-compat", () => ({
|
||||
ensureDbCompatibility: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
vi.mock("next/headers", () => ({
|
||||
headers: vi.fn(async () => ({ get: () => null })),
|
||||
cookies: vi.fn(async () => ({ get: () => undefined, set: () => {}, delete: () => {} })),
|
||||
cookies: vi.fn(async () => ({
|
||||
get: () => undefined,
|
||||
set: () => {},
|
||||
delete: () => {},
|
||||
})),
|
||||
}));
|
||||
|
||||
import { POST } from "../custom/route";
|
||||
@@ -59,19 +67,40 @@ describe("POST /api/mood/tags/custom", () => {
|
||||
it("creates a custom tag and returns it (custom:true, decrypted label)", async () => {
|
||||
db.moodTag.count.mockResolvedValue(3);
|
||||
db.moodTag.create.mockResolvedValue({
|
||||
key: "custom:abc", icon: "Heart", kind: "BINARY", scaleMin: 1, scaleMax: 5, inverse: false,
|
||||
key: "custom:abc",
|
||||
icon: "Heart",
|
||||
kind: "BINARY",
|
||||
scaleMin: 1,
|
||||
scaleMax: 5,
|
||||
inverse: false,
|
||||
});
|
||||
const res = await POST(jsonReq("http://localhost/api/mood/tags/custom", "POST", { label: "Date night", icon: "Heart" }));
|
||||
const res = await POST(
|
||||
jsonReq("http://localhost/api/mood/tags/custom", "POST", {
|
||||
label: "Date night",
|
||||
icon: "Heart",
|
||||
}),
|
||||
);
|
||||
expect(res.status).toBe(201);
|
||||
const body = (await res.json()) as { data: { custom: boolean; label: string; labelKey: null; key: string } };
|
||||
expect(body.data).toMatchObject({ custom: true, label: "Date night", labelKey: null, key: "custom:abc" });
|
||||
const body = (await res.json()) as {
|
||||
data: { custom: boolean; label: string; labelKey: null; key: string };
|
||||
};
|
||||
expect(body.data).toMatchObject({
|
||||
custom: true,
|
||||
label: "Date night",
|
||||
labelKey: null,
|
||||
key: "custom:abc",
|
||||
});
|
||||
// Label is stored encrypted, never plaintext.
|
||||
expect(db.moodTag.create.mock.calls[0][0].data.labelEncrypted).toBe("enc:Date night");
|
||||
expect(db.moodTag.create.mock.calls[0][0].data.labelEncrypted).toBe(
|
||||
"enc:Date night",
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects over the per-user cap with 422", async () => {
|
||||
db.moodTag.count.mockResolvedValue(50);
|
||||
const res = await POST(jsonReq("http://localhost/api/mood/tags/custom", "POST", { label: "X" }));
|
||||
const res = await POST(
|
||||
jsonReq("http://localhost/api/mood/tags/custom", "POST", { label: "X" }),
|
||||
);
|
||||
expect(res.status).toBe(422);
|
||||
expect(db.moodTag.create).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -79,21 +108,38 @@ describe("POST /api/mood/tags/custom", () => {
|
||||
it("defaults to the seeded custom category without a categoryKey (v1.13 contract)", async () => {
|
||||
db.moodTag.count.mockResolvedValue(0);
|
||||
db.moodTag.create.mockResolvedValue({
|
||||
key: "custom:x", icon: null, kind: "BINARY", scaleMin: 1, scaleMax: 5, inverse: false,
|
||||
key: "custom:x",
|
||||
icon: null,
|
||||
kind: "BINARY",
|
||||
scaleMin: 1,
|
||||
scaleMax: 5,
|
||||
inverse: false,
|
||||
});
|
||||
await POST(jsonReq("http://localhost/api/mood/tags/custom", "POST", { label: "X" }));
|
||||
await POST(
|
||||
jsonReq("http://localhost/api/mood/tags/custom", "POST", { label: "X" }),
|
||||
);
|
||||
expect(db.moodTagCategory.findFirst).not.toHaveBeenCalled();
|
||||
expect(db.moodTag.create.mock.calls[0][0].data.categoryId).toBe("mtc_custom");
|
||||
expect(db.moodTag.create.mock.calls[0][0].data.categoryId).toBe(
|
||||
"mtc_custom",
|
||||
);
|
||||
});
|
||||
|
||||
it("resolves categoryKey to a seeded OR own group (v1.17.0) and 422s an unknown one", async () => {
|
||||
db.moodTag.count.mockResolvedValue(0);
|
||||
db.moodTagCategory.findFirst.mockResolvedValue({ id: "cg1" });
|
||||
db.moodTag.create.mockResolvedValue({
|
||||
key: "custom:x", icon: null, kind: "BINARY", scaleMin: 1, scaleMax: 5, inverse: false,
|
||||
key: "custom:x",
|
||||
icon: null,
|
||||
kind: "BINARY",
|
||||
scaleMin: 1,
|
||||
scaleMax: 5,
|
||||
inverse: false,
|
||||
});
|
||||
const ok = await POST(
|
||||
jsonReq("http://localhost/api/mood/tags/custom", "POST", { label: "X", categoryKey: "customcat:g1" }),
|
||||
jsonReq("http://localhost/api/mood/tags/custom", "POST", {
|
||||
label: "X",
|
||||
categoryKey: "customcat:g1",
|
||||
}),
|
||||
);
|
||||
expect(ok.status).toBe(201);
|
||||
expect(db.moodTag.create.mock.calls[0][0].data.categoryId).toBe("cg1");
|
||||
@@ -107,7 +153,10 @@ describe("POST /api/mood/tags/custom", () => {
|
||||
|
||||
db.moodTagCategory.findFirst.mockResolvedValue(null);
|
||||
const bad = await POST(
|
||||
jsonReq("http://localhost/api/mood/tags/custom", "POST", { label: "X", categoryKey: "customcat:theirs" }),
|
||||
jsonReq("http://localhost/api/mood/tags/custom", "POST", {
|
||||
label: "X",
|
||||
categoryKey: "customcat:theirs",
|
||||
}),
|
||||
);
|
||||
expect(bad.status).toBe(422);
|
||||
});
|
||||
@@ -119,14 +168,19 @@ describe("PATCH/DELETE /api/mood/tags/custom/:key", () => {
|
||||
it("404s when the key is not the caller's own custom tag", async () => {
|
||||
db.moodTag.findFirst.mockResolvedValue(null);
|
||||
const res = await PATCH(
|
||||
jsonReq("http://localhost/api/mood/tags/custom/custom:x", "PATCH", { isActive: false }),
|
||||
jsonReq("http://localhost/api/mood/tags/custom/custom:x", "PATCH", {
|
||||
isActive: false,
|
||||
}),
|
||||
params("custom:x"),
|
||||
);
|
||||
expect(res.status).toBe(404);
|
||||
});
|
||||
|
||||
it("404s a non-custom key without touching the DB", async () => {
|
||||
const res = await DELETE(new NextRequest("http://localhost/api/mood/tags/custom/happy"), params("happy"));
|
||||
const res = await DELETE(
|
||||
new NextRequest("http://localhost/api/mood/tags/custom/happy"),
|
||||
params("happy"),
|
||||
);
|
||||
expect(res.status).toBe(404);
|
||||
expect(db.moodTag.findFirst).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -135,22 +189,34 @@ describe("PATCH/DELETE /api/mood/tags/custom/:key", () => {
|
||||
db.moodTag.findFirst.mockResolvedValue({ id: "id1" });
|
||||
db.moodTagCategory.findFirst.mockResolvedValue({ id: "cg1" });
|
||||
db.moodTag.update.mockResolvedValue({
|
||||
key: "custom:x", icon: null, kind: "BINARY", scaleMin: 1, scaleMax: 5,
|
||||
inverse: false, isActive: true, labelEncrypted: "enc:X",
|
||||
key: "custom:x",
|
||||
icon: null,
|
||||
kind: "BINARY",
|
||||
scaleMin: 1,
|
||||
scaleMax: 5,
|
||||
inverse: false,
|
||||
isActive: true,
|
||||
labelEncrypted: "enc:X",
|
||||
});
|
||||
const res = await PATCH(
|
||||
jsonReq("http://localhost/api/mood/tags/custom/custom:x", "PATCH", { categoryKey: "customcat:g1" }),
|
||||
jsonReq("http://localhost/api/mood/tags/custom/custom:x", "PATCH", {
|
||||
categoryKey: "customcat:g1",
|
||||
}),
|
||||
params("custom:x"),
|
||||
);
|
||||
expect(res.status).toBe(200);
|
||||
expect(db.moodTag.update.mock.calls[0][0].data).toEqual({ categoryId: "cg1" });
|
||||
expect(db.moodTag.update.mock.calls[0][0].data).toEqual({
|
||||
categoryId: "cg1",
|
||||
});
|
||||
});
|
||||
|
||||
it("422s a move to an unknown / foreign group without writing", async () => {
|
||||
db.moodTag.findFirst.mockResolvedValue({ id: "id1" });
|
||||
db.moodTagCategory.findFirst.mockResolvedValue(null);
|
||||
const res = await PATCH(
|
||||
jsonReq("http://localhost/api/mood/tags/custom/custom:x", "PATCH", { categoryKey: "ghost" }),
|
||||
jsonReq("http://localhost/api/mood/tags/custom/custom:x", "PATCH", {
|
||||
categoryKey: "ghost",
|
||||
}),
|
||||
params("custom:x"),
|
||||
);
|
||||
expect(res.status).toBe(422);
|
||||
@@ -159,15 +225,26 @@ describe("PATCH/DELETE /api/mood/tags/custom/:key", () => {
|
||||
|
||||
it("soft-deactivates by default and hard-deletes on ?purge=true", async () => {
|
||||
db.moodTag.findFirst.mockResolvedValue({ id: "id1" });
|
||||
const soft = await DELETE(new NextRequest("http://localhost/api/mood/tags/custom/custom:abc"), params("custom:abc"));
|
||||
const soft = await DELETE(
|
||||
new NextRequest("http://localhost/api/mood/tags/custom/custom:abc"),
|
||||
params("custom:abc"),
|
||||
);
|
||||
expect(soft.status).toBe(200);
|
||||
expect(db.moodTag.update).toHaveBeenCalledWith({ where: { id: "id1" }, data: { isActive: false } });
|
||||
expect(db.moodTag.update).toHaveBeenCalledWith({
|
||||
where: { id: "id1" },
|
||||
data: { isActive: false },
|
||||
});
|
||||
expect(db.moodTag.delete).not.toHaveBeenCalled();
|
||||
|
||||
vi.clearAllMocks();
|
||||
vi.mocked(getSession).mockResolvedValue(SESSION_OK as never);
|
||||
db.moodTag.findFirst.mockResolvedValue({ id: "id1" });
|
||||
const purge = await DELETE(new NextRequest("http://localhost/api/mood/tags/custom/custom:abc?purge=true"), params("custom:abc"));
|
||||
const purge = await DELETE(
|
||||
new NextRequest(
|
||||
"http://localhost/api/mood/tags/custom/custom:abc?purge=true",
|
||||
),
|
||||
params("custom:abc"),
|
||||
);
|
||||
expect(purge.status).toBe(200);
|
||||
expect(db.moodTag.delete).toHaveBeenCalledWith({ where: { id: "id1" } });
|
||||
});
|
||||
@@ -176,7 +253,9 @@ describe("PATCH/DELETE /api/mood/tags/custom/:key", () => {
|
||||
describe("PUT /api/mood/tags/:key/hidden", () => {
|
||||
it("rejects a custom key with 400 (custom tags hide via isActive)", async () => {
|
||||
const res = await PUT(
|
||||
jsonReq("http://localhost/api/mood/tags/custom:abc/hidden", "PUT", { hidden: true }),
|
||||
jsonReq("http://localhost/api/mood/tags/custom:abc/hidden", "PUT", {
|
||||
hidden: true,
|
||||
}),
|
||||
{ params: Promise.resolve({ key: "custom:abc" }) },
|
||||
);
|
||||
expect(res.status).toBe(400);
|
||||
@@ -185,7 +264,9 @@ describe("PUT /api/mood/tags/:key/hidden", () => {
|
||||
it("upserts a hide row for a catalogue tag", async () => {
|
||||
db.moodTag.findFirst.mockResolvedValue({ id: "t_sad" });
|
||||
const res = await PUT(
|
||||
jsonReq("http://localhost/api/mood/tags/sad/hidden", "PUT", { hidden: true }),
|
||||
jsonReq("http://localhost/api/mood/tags/sad/hidden", "PUT", {
|
||||
hidden: true,
|
||||
}),
|
||||
{ params: Promise.resolve({ key: "sad" }) },
|
||||
);
|
||||
expect(res.status).toBe(200);
|
||||
|
||||
@@ -29,19 +29,27 @@ const db = vi.hoisted(() => {
|
||||
|
||||
vi.mock("@/lib/db", () => ({
|
||||
prisma: db,
|
||||
toJson: <T,>(v: T) => v,
|
||||
toJson: <T>(v: T) => v,
|
||||
}));
|
||||
vi.mock("@/lib/crypto", () => ({
|
||||
encrypt: (s: string) => `enc:${s}`,
|
||||
decrypt: (s: string) => s.replace(/^enc:/, ""),
|
||||
}));
|
||||
vi.mock("@/lib/auth/session", () => ({ getSession: vi.fn() }));
|
||||
vi.mock("@/lib/auth/audit", () => ({ auditLog: vi.fn().mockResolvedValue(undefined) }));
|
||||
vi.mock("@/lib/auth/audit", () => ({
|
||||
auditLog: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
vi.mock("@/lib/logging/transports", () => ({ emitIfSampled: vi.fn() }));
|
||||
vi.mock("@/lib/db-compat", () => ({ ensureDbCompatibility: vi.fn().mockResolvedValue(undefined) }));
|
||||
vi.mock("@/lib/db-compat", () => ({
|
||||
ensureDbCompatibility: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
vi.mock("next/headers", () => ({
|
||||
headers: vi.fn(async () => ({ get: () => null })),
|
||||
cookies: vi.fn(async () => ({ get: () => undefined, set: () => {}, delete: () => {} })),
|
||||
cookies: vi.fn(async () => ({
|
||||
get: () => undefined,
|
||||
set: () => {},
|
||||
delete: () => {},
|
||||
})),
|
||||
}));
|
||||
|
||||
import { POST } from "../groups/route";
|
||||
@@ -115,7 +123,9 @@ describe("POST /api/mood/tags/groups", () => {
|
||||
describe("PATCH /api/mood/tags/groups/:key", () => {
|
||||
it("404s a seeded category key without touching the DB", async () => {
|
||||
const res = await PATCH(
|
||||
jsonReq("http://localhost/api/mood/tags/groups/feelings", "PATCH", { label: "x" }),
|
||||
jsonReq("http://localhost/api/mood/tags/groups/feelings", "PATCH", {
|
||||
label: "x",
|
||||
}),
|
||||
params("feelings"),
|
||||
);
|
||||
expect(res.status).toBe(404);
|
||||
@@ -125,7 +135,9 @@ describe("PATCH /api/mood/tags/groups/:key", () => {
|
||||
it("404s when the key is not the caller's own group", async () => {
|
||||
db.moodTagCategory.findFirst.mockResolvedValue(null);
|
||||
const res = await PATCH(
|
||||
jsonReq("http://localhost/api/mood/tags/groups/customcat:x", "PATCH", { label: "x" }),
|
||||
jsonReq("http://localhost/api/mood/tags/groups/customcat:x", "PATCH", {
|
||||
label: "x",
|
||||
}),
|
||||
params("customcat:x"),
|
||||
);
|
||||
expect(res.status).toBe(404);
|
||||
@@ -140,11 +152,15 @@ describe("PATCH /api/mood/tags/groups/:key", () => {
|
||||
labelEncrypted: "enc:Neu",
|
||||
});
|
||||
const res = await PATCH(
|
||||
jsonReq("http://localhost/api/mood/tags/groups/customcat:x", "PATCH", { label: "Neu" }),
|
||||
jsonReq("http://localhost/api/mood/tags/groups/customcat:x", "PATCH", {
|
||||
label: "Neu",
|
||||
}),
|
||||
params("customcat:x"),
|
||||
);
|
||||
expect(res.status).toBe(200);
|
||||
const body = (await res.json()) as { data: { label: string; isActive: boolean } };
|
||||
const body = (await res.json()) as {
|
||||
data: { label: string; isActive: boolean };
|
||||
};
|
||||
expect(body.data).toMatchObject({ label: "Neu", isActive: true });
|
||||
expect(db.moodTagCategory.update.mock.calls[0][0].data).toEqual({
|
||||
labelEncrypted: "enc:Neu",
|
||||
@@ -200,7 +216,9 @@ describe("DELETE /api/mood/tags/groups/:key", () => {
|
||||
|
||||
it("hard-deletes the emptied group row on ?purge=true", async () => {
|
||||
const res = await DELETE(
|
||||
new NextRequest("http://localhost/api/mood/tags/groups/customcat:x?purge=true"),
|
||||
new NextRequest(
|
||||
"http://localhost/api/mood/tags/groups/customcat:x?purge=true",
|
||||
),
|
||||
params("customcat:x"),
|
||||
);
|
||||
expect(res.status).toBe(200);
|
||||
|
||||
@@ -13,15 +13,23 @@ const db = vi.hoisted(() => ({
|
||||
|
||||
vi.mock("@/lib/db", () => ({
|
||||
prisma: db,
|
||||
toJson: <T,>(v: T) => v,
|
||||
toJson: <T>(v: T) => v,
|
||||
}));
|
||||
vi.mock("@/lib/auth/session", () => ({ getSession: vi.fn() }));
|
||||
vi.mock("@/lib/auth/audit", () => ({ auditLog: vi.fn().mockResolvedValue(undefined) }));
|
||||
vi.mock("@/lib/auth/audit", () => ({
|
||||
auditLog: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
vi.mock("@/lib/logging/transports", () => ({ emitIfSampled: vi.fn() }));
|
||||
vi.mock("@/lib/db-compat", () => ({ ensureDbCompatibility: vi.fn().mockResolvedValue(undefined) }));
|
||||
vi.mock("@/lib/db-compat", () => ({
|
||||
ensureDbCompatibility: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
vi.mock("next/headers", () => ({
|
||||
headers: vi.fn(async () => ({ get: () => null })),
|
||||
cookies: vi.fn(async () => ({ get: () => undefined, set: () => {}, delete: () => {} })),
|
||||
cookies: vi.fn(async () => ({
|
||||
get: () => undefined,
|
||||
set: () => {},
|
||||
delete: () => {},
|
||||
})),
|
||||
}));
|
||||
|
||||
import { GET, PUT } from "../layout/route";
|
||||
@@ -77,7 +85,11 @@ describe("GET /api/mood/tags/layout", () => {
|
||||
const body = (await res.json()) as {
|
||||
data: { groupOrder: string[]; placements: Record<string, string[]> };
|
||||
};
|
||||
expect(body.data.groupOrder).toEqual(["customcat:g1", "feelings", "custom"]);
|
||||
expect(body.data.groupOrder).toEqual([
|
||||
"customcat:g1",
|
||||
"feelings",
|
||||
"custom",
|
||||
]);
|
||||
expect(body.data.placements).toEqual({ "customcat:g1": ["happy"] });
|
||||
});
|
||||
});
|
||||
@@ -101,7 +113,11 @@ describe("PUT /api/mood/tags/layout", () => {
|
||||
const body = (await res.json()) as {
|
||||
data: { groupOrder: string[]; placements: Record<string, string[]> };
|
||||
};
|
||||
expect(body.data.groupOrder).toEqual(["custom", "feelings", "customcat:g1"]);
|
||||
expect(body.data.groupOrder).toEqual([
|
||||
"custom",
|
||||
"feelings",
|
||||
"customcat:g1",
|
||||
]);
|
||||
expect(body.data.placements).toEqual({ feelings: ["sad"] });
|
||||
});
|
||||
|
||||
|
||||
@@ -58,8 +58,22 @@ const SESSION_OK = {
|
||||
};
|
||||
|
||||
const CATEGORIES = [
|
||||
{ id: "c1", key: "feelings", labelKey: "mood.tagCategory.feelings", icon: "Smile", userId: null, labelEncrypted: null },
|
||||
{ id: "mtc_custom", key: "custom", labelKey: "mood.tagCategory.custom", icon: "Tag", userId: null, labelEncrypted: null },
|
||||
{
|
||||
id: "c1",
|
||||
key: "feelings",
|
||||
labelKey: "mood.tagCategory.feelings",
|
||||
icon: "Smile",
|
||||
userId: null,
|
||||
labelEncrypted: null,
|
||||
},
|
||||
{
|
||||
id: "mtc_custom",
|
||||
key: "custom",
|
||||
labelKey: "mood.tagCategory.custom",
|
||||
icon: "Tag",
|
||||
userId: null,
|
||||
labelEncrypted: null,
|
||||
},
|
||||
];
|
||||
|
||||
const OWN_GROUP = {
|
||||
@@ -72,9 +86,48 @@ const OWN_GROUP = {
|
||||
};
|
||||
|
||||
const TAGS = [
|
||||
{ id: "t_happy", categoryId: "c1", key: "happy", labelKey: "mood.tag.happy", icon: "Smile", kind: "BINARY", scaleMin: 1, scaleMax: 5, inverse: false, isActive: true, userId: null, labelEncrypted: null },
|
||||
{ id: "t_sad", categoryId: "c1", key: "sad", labelKey: "mood.tag.sad", icon: "Frown", kind: "BINARY", scaleMin: 1, scaleMax: 5, inverse: false, isActive: true, userId: null, labelEncrypted: null },
|
||||
{ id: "t_custom", categoryId: "mtc_custom", key: "custom:abc", labelKey: "custom:abc", icon: "Heart", kind: "BINARY", scaleMin: 1, scaleMax: 5, inverse: false, isActive: true, userId: "user-1", labelEncrypted: "enc:Migräne" },
|
||||
{
|
||||
id: "t_happy",
|
||||
categoryId: "c1",
|
||||
key: "happy",
|
||||
labelKey: "mood.tag.happy",
|
||||
icon: "Smile",
|
||||
kind: "BINARY",
|
||||
scaleMin: 1,
|
||||
scaleMax: 5,
|
||||
inverse: false,
|
||||
isActive: true,
|
||||
userId: null,
|
||||
labelEncrypted: null,
|
||||
},
|
||||
{
|
||||
id: "t_sad",
|
||||
categoryId: "c1",
|
||||
key: "sad",
|
||||
labelKey: "mood.tag.sad",
|
||||
icon: "Frown",
|
||||
kind: "BINARY",
|
||||
scaleMin: 1,
|
||||
scaleMax: 5,
|
||||
inverse: false,
|
||||
isActive: true,
|
||||
userId: null,
|
||||
labelEncrypted: null,
|
||||
},
|
||||
{
|
||||
id: "t_custom",
|
||||
categoryId: "mtc_custom",
|
||||
key: "custom:abc",
|
||||
labelKey: "custom:abc",
|
||||
icon: "Heart",
|
||||
kind: "BINARY",
|
||||
scaleMin: 1,
|
||||
scaleMax: 5,
|
||||
inverse: false,
|
||||
isActive: true,
|
||||
userId: "user-1",
|
||||
labelEncrypted: "enc:Migräne",
|
||||
},
|
||||
];
|
||||
|
||||
const ARCHIVED_TAG = {
|
||||
@@ -188,7 +241,14 @@ describe("GET /api/mood/tags — groups + layout + archived + usage (v1.17.0)",
|
||||
categoryFindMany.mockResolvedValue([...CATEGORIES, OWN_GROUP]);
|
||||
tagFindMany.mockResolvedValue([
|
||||
...TAGS,
|
||||
{ ...TAGS[2], id: "t_c2", categoryId: "cg1", key: "custom:ing1", labelKey: "custom:ing1", labelEncrypted: "enc:Sitzung" },
|
||||
{
|
||||
...TAGS[2],
|
||||
id: "t_c2",
|
||||
categoryId: "cg1",
|
||||
key: "custom:ing1",
|
||||
labelKey: "custom:ing1",
|
||||
labelEncrypted: "enc:Sitzung",
|
||||
},
|
||||
]);
|
||||
const res = await GET(req());
|
||||
const body = (await res.json()) as Body;
|
||||
|
||||
@@ -125,7 +125,9 @@ export const DELETE = apiHandler(
|
||||
if (layout.groupOrder !== undefined || layout.placements !== undefined) {
|
||||
await tx.user.update({
|
||||
where: { id: user.id },
|
||||
data: { moodTagLayoutJson: toJson(stripGroupFromLayout(layout, key)) },
|
||||
data: {
|
||||
moodTagLayoutJson: toJson(stripGroupFromLayout(layout, key)),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
import { NextRequest } from "next/server";
|
||||
|
||||
import { prisma, toJson } from "@/lib/db";
|
||||
import {
|
||||
apiSuccess,
|
||||
returnAllZodIssues,
|
||||
safeJson,
|
||||
} from "@/lib/api-response";
|
||||
import { apiSuccess, returnAllZodIssues, safeJson } from "@/lib/api-response";
|
||||
import { apiHandler, requireAuth } from "@/lib/api-handler";
|
||||
import { annotate } from "@/lib/logging/context";
|
||||
import {
|
||||
|
||||
@@ -165,9 +165,7 @@ export const GET = apiHandler(async (request: NextRequest) => {
|
||||
...(includeHidden && !isCustom
|
||||
? { hidden: hiddenIds.has(t.id) }
|
||||
: {}),
|
||||
...(includeArchived && isCustom
|
||||
? { archived: !t.isActive }
|
||||
: {}),
|
||||
...(includeArchived && isCustom ? { archived: !t.isActive } : {}),
|
||||
...(includeUsage
|
||||
? { usageCount: usageByTagId.get(t.id) ?? 0 }
|
||||
: {}),
|
||||
|
||||
Reference in new issue
Block a user