feat(core): add content use cases with tests (create-article, get-articles)
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
import type { Article } from "@/entities/models/article.js";
|
||||
import { getInjection } from "@/di/container.js";
|
||||
|
||||
function generateSlug(title: string): string {
|
||||
return title
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9]+/g, "-")
|
||||
.replace(/^-|-$/g, "");
|
||||
}
|
||||
|
||||
export async function createArticleUseCase(input: {
|
||||
title: string;
|
||||
content: string;
|
||||
authorId: string;
|
||||
slug?: string;
|
||||
}): Promise<Article> {
|
||||
const articlesRepository = getInjection("IArticlesRepository");
|
||||
|
||||
const now = new Date();
|
||||
const article: Article = {
|
||||
id: crypto.randomUUID(),
|
||||
title: input.title,
|
||||
slug: input.slug ?? generateSlug(input.title),
|
||||
content: input.content,
|
||||
status: "draft",
|
||||
authorId: input.authorId,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
|
||||
return await articlesRepository.createArticle(article);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import type { Article } from "@/entities/models/article.js";
|
||||
import { getInjection } from "@/di/container.js";
|
||||
|
||||
export async function getArticlesUseCase(options?: {
|
||||
status?: string;
|
||||
authorId?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}): Promise<Article[]> {
|
||||
const articlesRepository = getInjection("IArticlesRepository");
|
||||
return await articlesRepository.getArticles(options);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import "reflect-metadata";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
destroyContainer,
|
||||
initializeContainer,
|
||||
} from "@/di/container.js";
|
||||
import { createArticleUseCase } from "@/application/use-cases/content/create-article.use-case.js";
|
||||
|
||||
beforeEach(() => {
|
||||
initializeContainer();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
destroyContainer();
|
||||
});
|
||||
|
||||
describe("createArticleUseCase", () => {
|
||||
it("creates an article with generated slug and draft status", async () => {
|
||||
const result = await createArticleUseCase({
|
||||
title: "My First Article",
|
||||
content: "Hello world",
|
||||
authorId: "1",
|
||||
});
|
||||
expect(result.title).toBe("My First Article");
|
||||
expect(result.slug).toBe("my-first-article");
|
||||
expect(result.status).toBe("draft");
|
||||
expect(result.authorId).toBe("1");
|
||||
expect(result.id).toBeDefined();
|
||||
});
|
||||
|
||||
it("uses provided slug if given", async () => {
|
||||
const result = await createArticleUseCase({
|
||||
title: "Another Article",
|
||||
content: "Content here",
|
||||
authorId: "1",
|
||||
slug: "custom-slug",
|
||||
});
|
||||
expect(result.slug).toBe("custom-slug");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
import "reflect-metadata";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
destroyContainer,
|
||||
initializeContainer,
|
||||
} from "@/di/container.js";
|
||||
import { createArticleUseCase } from "@/application/use-cases/content/create-article.use-case.js";
|
||||
import { getArticlesUseCase } from "@/application/use-cases/content/get-articles.use-case.js";
|
||||
|
||||
beforeEach(() => {
|
||||
initializeContainer();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
destroyContainer();
|
||||
});
|
||||
|
||||
describe("getArticlesUseCase", () => {
|
||||
it("returns empty array when no articles exist", async () => {
|
||||
const result = await getArticlesUseCase();
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it("returns created articles", async () => {
|
||||
await createArticleUseCase({
|
||||
title: "Article One",
|
||||
content: "Content one",
|
||||
authorId: "1",
|
||||
});
|
||||
await createArticleUseCase({
|
||||
title: "Article Two",
|
||||
content: "Content two",
|
||||
authorId: "1",
|
||||
});
|
||||
|
||||
const result = await getArticlesUseCase();
|
||||
expect(result).toHaveLength(2);
|
||||
});
|
||||
|
||||
it("filters by status", async () => {
|
||||
await createArticleUseCase({
|
||||
title: "Draft Article",
|
||||
content: "Draft",
|
||||
authorId: "1",
|
||||
});
|
||||
|
||||
const result = await getArticlesUseCase({ status: "published" });
|
||||
expect(result).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user