// 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); }); });