diff --git a/packages/blog/tests/articles.feature.test.ts b/packages/blog/tests/articles.feature.test.ts new file mode 100644 index 0000000..b9c0066 --- /dev/null +++ b/packages/blog/tests/articles.feature.test.ts @@ -0,0 +1,56 @@ +// Feature-level test: exercises the full slice +// tRPC procedure -> controller -> use-case -> mock repo +// without going through a network or the actual Payload Local API. +// Verifies that the layers are correctly wired through the per-feature DI container. + +import { beforeEach, describe, expect, it } from "vitest"; +import { blogContainer } from "../src/di/container"; +import { BLOG_SYMBOLS } from "../src/di/symbols"; +import { MockArticlesRepository } from "../src/infrastructure/repositories/mock-articles.repository"; +import type { IArticlesRepository } from "../src/application/repositories/articles-repository.interface"; +import { blogRouter } from "../src/integrations/api/router"; + +describe("blog feature: article-by-slug end-to-end", () => { + let repo: MockArticlesRepository; + + beforeEach(() => { + if (blogContainer.isBound(BLOG_SYMBOLS.IArticlesRepository)) { + blogContainer.unbind(BLOG_SYMBOLS.IArticlesRepository); + } + repo = new MockArticlesRepository(); + blogContainer + .bind(BLOG_SYMBOLS.IArticlesRepository) + .toConstantValue(repo); + }); + + it("creates an article via tRPC, then fetches it back by slug", async () => { + const caller = blogRouter.createCaller({}); + + const created = await caller.createArticle({ + title: "The Vertical Refactor", + content: { type: "doc", children: [] }, + authorId: "u1", + slug: "vertical-refactor", + }); + expect(created.id).toBeTruthy(); + expect(created.slug).toBe("vertical-refactor"); + + const fetched = await caller.articleBySlug({ slug: "vertical-refactor" }); + expect(fetched?.id).toBe(created.id); + expect(fetched?.title).toBe("The Vertical Refactor"); + }); + + it("listArticles filters by status", async () => { + const caller = blogRouter.createCaller({}); + await caller.createArticle({ + title: "Draft One", + content: null, + authorId: "u1", + }); + const draftOnly = await caller.listArticles({ status: "draft" }); + expect(draftOnly).toHaveLength(1); + + const publishedOnly = await caller.listArticles({ status: "published" }); + expect(publishedOnly).toHaveLength(0); + }); +});