feat(knowledge): add search service
This commit is contained in:
197
apps/api/src/knowledge/search.controller.spec.ts
Normal file
197
apps/api/src/knowledge/search.controller.spec.ts
Normal file
@@ -0,0 +1,197 @@
|
||||
import { describe, it, expect, beforeEach, vi } from "vitest";
|
||||
import { Test, TestingModule } from "@nestjs/testing";
|
||||
import { EntryStatus } from "@prisma/client";
|
||||
import { SearchController } from "./search.controller";
|
||||
import { SearchService } from "./services/search.service";
|
||||
import { AuthGuard } from "../auth/guards/auth.guard";
|
||||
import { WorkspaceGuard, PermissionGuard } from "../common/guards";
|
||||
|
||||
describe("SearchController", () => {
|
||||
let controller: SearchController;
|
||||
|
||||
const mockWorkspaceId = "550e8400-e29b-41d4-a716-446655440000";
|
||||
|
||||
const mockSearchService = {
|
||||
search: vi.fn(),
|
||||
searchByTags: vi.fn(),
|
||||
recentEntries: vi.fn(),
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [SearchController],
|
||||
providers: [
|
||||
{
|
||||
provide: SearchService,
|
||||
useValue: mockSearchService,
|
||||
},
|
||||
],
|
||||
})
|
||||
.overrideGuard(AuthGuard)
|
||||
.useValue({ canActivate: () => true })
|
||||
.overrideGuard(WorkspaceGuard)
|
||||
.useValue({ canActivate: () => true })
|
||||
.overrideGuard(PermissionGuard)
|
||||
.useValue({ canActivate: () => true })
|
||||
.compile();
|
||||
|
||||
controller = module.get<SearchController>(SearchController);
|
||||
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe("search", () => {
|
||||
it("should call searchService.search with correct parameters", async () => {
|
||||
const mockResult = {
|
||||
data: [],
|
||||
pagination: { page: 1, limit: 20, total: 0, totalPages: 0 },
|
||||
query: "test",
|
||||
};
|
||||
mockSearchService.search.mockResolvedValue(mockResult);
|
||||
|
||||
const result = await controller.search(mockWorkspaceId, {
|
||||
q: "test",
|
||||
page: 1,
|
||||
limit: 20,
|
||||
});
|
||||
|
||||
expect(mockSearchService.search).toHaveBeenCalledWith(
|
||||
"test",
|
||||
mockWorkspaceId,
|
||||
{
|
||||
status: undefined,
|
||||
page: 1,
|
||||
limit: 20,
|
||||
}
|
||||
);
|
||||
expect(result).toEqual(mockResult);
|
||||
});
|
||||
|
||||
it("should pass status filter to service", async () => {
|
||||
mockSearchService.search.mockResolvedValue({
|
||||
data: [],
|
||||
pagination: { page: 1, limit: 20, total: 0, totalPages: 0 },
|
||||
query: "test",
|
||||
});
|
||||
|
||||
await controller.search(mockWorkspaceId, {
|
||||
q: "test",
|
||||
status: EntryStatus.PUBLISHED,
|
||||
});
|
||||
|
||||
expect(mockSearchService.search).toHaveBeenCalledWith(
|
||||
"test",
|
||||
mockWorkspaceId,
|
||||
{
|
||||
status: EntryStatus.PUBLISHED,
|
||||
page: undefined,
|
||||
limit: undefined,
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("searchByTags", () => {
|
||||
it("should call searchService.searchByTags with correct parameters", async () => {
|
||||
const mockResult = {
|
||||
data: [],
|
||||
pagination: { page: 1, limit: 20, total: 0, totalPages: 0 },
|
||||
};
|
||||
mockSearchService.searchByTags.mockResolvedValue(mockResult);
|
||||
|
||||
const result = await controller.searchByTags(mockWorkspaceId, {
|
||||
tags: ["api", "documentation"],
|
||||
page: 1,
|
||||
limit: 20,
|
||||
});
|
||||
|
||||
expect(mockSearchService.searchByTags).toHaveBeenCalledWith(
|
||||
["api", "documentation"],
|
||||
mockWorkspaceId,
|
||||
{
|
||||
status: undefined,
|
||||
page: 1,
|
||||
limit: 20,
|
||||
}
|
||||
);
|
||||
expect(result).toEqual(mockResult);
|
||||
});
|
||||
|
||||
it("should pass status filter to service", async () => {
|
||||
mockSearchService.searchByTags.mockResolvedValue({
|
||||
data: [],
|
||||
pagination: { page: 1, limit: 20, total: 0, totalPages: 0 },
|
||||
});
|
||||
|
||||
await controller.searchByTags(mockWorkspaceId, {
|
||||
tags: ["api"],
|
||||
status: EntryStatus.DRAFT,
|
||||
});
|
||||
|
||||
expect(mockSearchService.searchByTags).toHaveBeenCalledWith(
|
||||
["api"],
|
||||
mockWorkspaceId,
|
||||
{
|
||||
status: EntryStatus.DRAFT,
|
||||
page: undefined,
|
||||
limit: undefined,
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("recentEntries", () => {
|
||||
it("should call searchService.recentEntries with correct parameters", async () => {
|
||||
const mockEntries = [
|
||||
{
|
||||
id: "entry-1",
|
||||
title: "Recent Entry",
|
||||
slug: "recent-entry",
|
||||
tags: [],
|
||||
},
|
||||
];
|
||||
mockSearchService.recentEntries.mockResolvedValue(mockEntries);
|
||||
|
||||
const result = await controller.recentEntries(mockWorkspaceId, {
|
||||
limit: 10,
|
||||
});
|
||||
|
||||
expect(mockSearchService.recentEntries).toHaveBeenCalledWith(
|
||||
mockWorkspaceId,
|
||||
10,
|
||||
undefined
|
||||
);
|
||||
expect(result).toEqual({
|
||||
data: mockEntries,
|
||||
count: 1,
|
||||
});
|
||||
});
|
||||
|
||||
it("should use default limit of 10", async () => {
|
||||
mockSearchService.recentEntries.mockResolvedValue([]);
|
||||
|
||||
await controller.recentEntries(mockWorkspaceId, {});
|
||||
|
||||
expect(mockSearchService.recentEntries).toHaveBeenCalledWith(
|
||||
mockWorkspaceId,
|
||||
10,
|
||||
undefined
|
||||
);
|
||||
});
|
||||
|
||||
it("should pass status filter to service", async () => {
|
||||
mockSearchService.recentEntries.mockResolvedValue([]);
|
||||
|
||||
await controller.recentEntries(mockWorkspaceId, {
|
||||
status: EntryStatus.PUBLISHED,
|
||||
limit: 5,
|
||||
});
|
||||
|
||||
expect(mockSearchService.recentEntries).toHaveBeenCalledWith(
|
||||
mockWorkspaceId,
|
||||
5,
|
||||
EntryStatus.PUBLISHED
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user