// Feature-level test: exercises the full slice // use case factory chain → mock repo // Tests the full dependency chain via direct injection (no container rebinding). import { describe, expect, it } from "vitest"; import { MockArticlesRepository } from "../src/infrastructure/repositories/articles.repository.mock"; import { getArticlesUseCase } from "../src/application/use-cases/get-articles.use-case"; import { createArticleUseCase } from "../src/application/use-cases/create-article.use-case"; import { getArticleBySlugUseCase } from "../src/application/use-cases/get-article-by-slug.use-case"; import { getArticlesController } from "../src/interface-adapters/controllers/get-articles.controller"; import { createArticleController } from "../src/interface-adapters/controllers/create-article.controller"; import { getArticleBySlugController } from "../src/interface-adapters/controllers/get-article-by-slug.controller"; import { ArticleNotFoundError } from "../src/entities/errors/article"; describe("blog feature: article end-to-end via direct injection", () => { function buildChain() { const repo = new MockArticlesRepository(); const createUseCase = createArticleUseCase(repo); const getArticlesUC = getArticlesUseCase(repo); const getBySlugUC = getArticleBySlugUseCase(repo); const createCtrl = createArticleController(createUseCase); const listCtrl = getArticlesController(getArticlesUC); const bySlugCtrl = getArticleBySlugController(getBySlugUC); return { createCtrl, listCtrl, bySlugCtrl }; } it("creates an article via controller, then fetches it back by slug", async () => { const { createCtrl, bySlugCtrl } = buildChain(); const created = await createCtrl({ 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 bySlugCtrl({ slug: "vertical-refactor" }); expect(fetched.id).toBe(created.id); expect(fetched.title).toBe("The Vertical Refactor"); }); it("listArticles filters by status", async () => { const { createCtrl, listCtrl } = buildChain(); await createCtrl({ title: "Draft One", content: null, authorId: "u1", }); const draftOnly = await listCtrl({ status: "draft" }); expect(draftOnly).toHaveLength(1); const publishedOnly = await listCtrl({ status: "published" }); expect(publishedOnly).toHaveLength(0); }); it("getArticleBySlugController throws ArticleNotFoundError for missing article", async () => { const { bySlugCtrl } = buildChain(); await expect(bySlugCtrl({ slug: "missing-slug" })).rejects.toBeInstanceOf(ArticleNotFoundError); }); });