diff --git a/packages/marketing-pages/src/interface-adapters/controllers/pages.controller.test.ts b/packages/marketing-pages/src/interface-adapters/controllers/pages.controller.test.ts new file mode 100644 index 0000000..481a294 --- /dev/null +++ b/packages/marketing-pages/src/interface-adapters/controllers/pages.controller.test.ts @@ -0,0 +1,49 @@ +import { beforeEach, describe, expect, it } from "vitest"; +import { marketingPagesContainer } from "@/di/container"; +import { MARKETING_PAGES_SYMBOLS } from "@/di/symbols"; +import { MockPagesRepository } from "@/infrastructure/repositories/mock-pages.repository"; +import { MockSiteSettingsRepository } from "@/infrastructure/repositories/mock-site-settings.repository"; +import type { IPagesRepository } from "@/application/repositories/pages-repository.interface"; +import type { ISiteSettingsRepository } from "@/application/repositories/site-settings-repository.interface"; +import { InputParseError } from "@/entities/errors"; +import { + getPageBySlugController, + getSiteSettingsController, +} from "./pages.controller"; + +describe("pages controller", () => { + beforeEach(() => { + if (marketingPagesContainer.isBound(MARKETING_PAGES_SYMBOLS.IPagesRepository)) { + marketingPagesContainer.unbind(MARKETING_PAGES_SYMBOLS.IPagesRepository); + } + if (marketingPagesContainer.isBound(MARKETING_PAGES_SYMBOLS.ISiteSettingsRepository)) { + marketingPagesContainer.unbind(MARKETING_PAGES_SYMBOLS.ISiteSettingsRepository); + } + marketingPagesContainer + .bind(MARKETING_PAGES_SYMBOLS.IPagesRepository) + .toConstantValue(new MockPagesRepository()); + marketingPagesContainer + .bind(MARKETING_PAGES_SYMBOLS.ISiteSettingsRepository) + .toConstantValue(new MockSiteSettingsRepository()); + }); + + describe("getPageBySlugController", () => { + it("returns the page when found", async () => { + const result = await getPageBySlugController({ slug: "about" }); + expect(result?.slug).toBe("about"); + }); + + it("throws InputParseError on missing slug", async () => { + await expect( + getPageBySlugController({} as { slug: string }), + ).rejects.toBeInstanceOf(InputParseError); + }); + }); + + describe("getSiteSettingsController", () => { + it("returns site settings", async () => { + const result = await getSiteSettingsController(); + expect(result.siteName).toBe("My App"); + }); + }); +}); diff --git a/packages/marketing-pages/src/interface-adapters/controllers/pages.controller.ts b/packages/marketing-pages/src/interface-adapters/controllers/pages.controller.ts new file mode 100644 index 0000000..6b89eb8 --- /dev/null +++ b/packages/marketing-pages/src/interface-adapters/controllers/pages.controller.ts @@ -0,0 +1,27 @@ +import { z } from "zod"; + +import { InputParseError } from "../../entities/errors"; +import type { Page } from "../../entities/page"; +import type { SiteSettings } from "../../entities/site-settings"; +import { getPageBySlugUseCase } from "../../application/use-cases/get-page-by-slug.use-case"; +import { getSiteSettingsUseCase } from "../../application/use-cases/get-site-settings.use-case"; + +const getBySlugInputSchema = z.object({ + slug: z.string().min(1), +}); + +export async function getPageBySlugController(input: { + slug: string; +}): Promise { + const parsed = getBySlugInputSchema.safeParse(input); + if (!parsed.success) { + throw new InputParseError("Invalid get-page-by-slug input", { + cause: parsed.error, + }); + } + return getPageBySlugUseCase(parsed.data.slug); +} + +export async function getSiteSettingsController(): Promise { + return getSiteSettingsUseCase(); +}