From 2d5d4f9c1a260803e26b9425957d78485fbe9086 Mon Sep 17 00:00:00 2001 From: Jean-Luc Makiola Date: Sun, 5 Apr 2026 13:05:02 +0200 Subject: [PATCH] test(18-03): add failing tests for profile service and setup isPublic - Profile CRUD tests: updateProfile, getPublicProfile, getPublicSetupWithItems - Setup service isPublic tests: create with isPublic, toggle, list includes isPublic --- tests/services/profile.service.test.ts | 197 +++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 tests/services/profile.service.test.ts diff --git a/tests/services/profile.service.test.ts b/tests/services/profile.service.test.ts new file mode 100644 index 0000000..52f9278 --- /dev/null +++ b/tests/services/profile.service.test.ts @@ -0,0 +1,197 @@ +import { beforeEach, describe, expect, it } from "bun:test"; +import { eq } from "drizzle-orm"; +import * as schema from "../../src/db/schema.ts"; +import { + getPublicProfile, + getPublicSetupWithItems, + updateProfile, +} from "../../src/server/services/profile.service.ts"; +import { + createSetup, + getAllSetups, + getSetupWithItems, + updateSetup, +} from "../../src/server/services/setup.service.ts"; +import { createSecondTestUser, createTestDb } from "../helpers/db.ts"; + +type Db = Awaited>["db"]; + +describe("Profile Service", () => { + let db: Db; + let userId: number; + + beforeEach(async () => { + const testData = await createTestDb(); + db = testData.db; + userId = testData.userId; + }); + + describe("updateProfile", () => { + it("updates displayName and returns updated user", async () => { + const result = await updateProfile(db, userId, { + displayName: "Alice", + }); + expect(result).not.toBeNull(); + expect(result!.displayName).toBe("Alice"); + }); + + it("updates bio only, leaves other fields untouched", async () => { + await updateProfile(db, userId, { displayName: "Alice" }); + const result = await updateProfile(db, userId, { bio: "Bikepacker" }); + expect(result).not.toBeNull(); + expect(result!.bio).toBe("Bikepacker"); + expect(result!.displayName).toBe("Alice"); + }); + + it("handles empty update without error", async () => { + const result = await updateProfile(db, userId, {}); + expect(result).not.toBeNull(); + expect(result!.id).toBe(userId); + }); + + it("returns null for non-existent user", async () => { + const result = await updateProfile(db, 99999, { + displayName: "Ghost", + }); + expect(result).toBeNull(); + }); + }); + + describe("getPublicProfile", () => { + it("returns user profile with empty setups when none exist", async () => { + await updateProfile(db, userId, { + displayName: "Alice", + bio: "Bikepacker", + }); + const profile = await getPublicProfile(db, userId); + expect(profile).not.toBeNull(); + expect(profile!.displayName).toBe("Alice"); + expect(profile!.bio).toBe("Bikepacker"); + expect(profile!.setups).toEqual([]); + }); + + it("returns only public setups, not private ones", async () => { + // Create one public and one private setup + const pub = await createSetup(db, userId, { name: "Public Setup", isPublic: true }); + const priv = await createSetup(db, userId, { name: "Private Setup" }); + + const profile = await getPublicProfile(db, userId); + expect(profile).not.toBeNull(); + expect(profile!.setups).toHaveLength(1); + expect(profile!.setups[0].name).toBe("Public Setup"); + }); + + it("returns null for non-existent user", async () => { + const profile = await getPublicProfile(db, 99999); + expect(profile).toBeNull(); + }); + }); + + describe("getPublicSetupWithItems", () => { + it("returns setup with items when isPublic is true", async () => { + const setup = await createSetup(db, userId, { + name: "Public Setup", + isPublic: true, + }); + + // Create an item and add to setup + const [cat] = await db + .select() + .from(schema.categories) + .where(eq(schema.categories.userId, userId)); + const [item] = await db + .insert(schema.items) + .values({ + name: "Tent", + categoryId: cat.id, + userId, + weightGrams: 1200, + priceCents: 30000, + }) + .returning(); + + await db.insert(schema.setupItems).values({ + setupId: setup.id, + itemId: item.id, + }); + + const result = await getPublicSetupWithItems(db, setup.id); + expect(result).not.toBeNull(); + expect(result!.name).toBe("Public Setup"); + expect(result!.items).toHaveLength(1); + expect(result!.items[0].name).toBe("Tent"); + }); + + it("returns null when isPublic is false", async () => { + const setup = await createSetup(db, userId, { + name: "Private Setup", + }); + const result = await getPublicSetupWithItems(db, setup.id); + expect(result).toBeNull(); + }); + + it("returns null for non-existent setup", async () => { + const result = await getPublicSetupWithItems(db, 99999); + expect(result).toBeNull(); + }); + }); +}); + +describe("Setup Service - isPublic", () => { + let db: Db; + let userId: number; + + beforeEach(async () => { + const testData = await createTestDb(); + db = testData.db; + userId = testData.userId; + }); + + it("createSetup persists isPublic when true", async () => { + const setup = await createSetup(db, userId, { + name: "Public", + isPublic: true, + }); + expect(setup.isPublic).toBe(true); + }); + + it("createSetup defaults isPublic to false", async () => { + const setup = await createSetup(db, userId, { name: "Private" }); + expect(setup.isPublic).toBe(false); + }); + + it("updateSetup can toggle isPublic", async () => { + const setup = await createSetup(db, userId, { name: "Test" }); + expect(setup.isPublic).toBe(false); + + const updated = await updateSetup(db, userId, setup.id, { + name: "Test", + isPublic: true, + }); + expect(updated).not.toBeNull(); + expect(updated!.isPublic).toBe(true); + }); + + it("getAllSetups includes isPublic in response", async () => { + await createSetup(db, userId, { name: "Public", isPublic: true }); + await createSetup(db, userId, { name: "Private" }); + + const setups = await getAllSetups(db, userId); + expect(setups).toHaveLength(2); + + const pub = setups.find((s) => s.name === "Public"); + const priv = setups.find((s) => s.name === "Private"); + expect(pub!.isPublic).toBe(true); + expect(priv!.isPublic).toBe(false); + }); + + it("getSetupWithItems includes isPublic", async () => { + const setup = await createSetup(db, userId, { + name: "Test", + isPublic: true, + }); + const result = await getSetupWithItems(db, userId, setup.id); + expect(result).not.toBeNull(); + expect(result!.isPublic).toBe(true); + }); +});