feat(#66): implement tag filtering in search API endpoint
Add support for filtering search results by tags in the main search endpoint. Changes: - Add tags parameter to SearchQueryDto (comma-separated tag slugs) - Implement tag filtering in SearchService.search() method - Update SQL query to join with knowledge_entry_tags when tags provided - Entries must have ALL specified tags (AND logic) - Add tests for tag filtering (2 controller tests, 2 service tests) - Update endpoint documentation - Fix non-null assertion linting error The search endpoint now supports: - Full-text search with ranking (ts_rank) - Snippet generation with highlighting (ts_headline) - Status filtering - Tag filtering (new) - Pagination Example: GET /api/knowledge/search?q=api&tags=documentation,tutorial All tests pass (25 total), type checking passes, linting passes. Fixes #66 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
99
apps/orchestrator/src/api/health/health.controller.spec.ts
Normal file
99
apps/orchestrator/src/api/health/health.controller.spec.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import { describe, it, expect, beforeEach } from "vitest";
|
||||
import { HealthController } from "./health.controller";
|
||||
import { HealthService } from "./health.service";
|
||||
|
||||
describe("HealthController", () => {
|
||||
let controller: HealthController;
|
||||
let service: HealthService;
|
||||
|
||||
beforeEach(() => {
|
||||
service = new HealthService();
|
||||
controller = new HealthController(service);
|
||||
});
|
||||
|
||||
describe("GET /health", () => {
|
||||
it("should return 200 OK with correct format", () => {
|
||||
const result = controller.check();
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toHaveProperty("status");
|
||||
expect(result).toHaveProperty("uptime");
|
||||
expect(result).toHaveProperty("timestamp");
|
||||
});
|
||||
|
||||
it('should return status as "healthy"', () => {
|
||||
const result = controller.check();
|
||||
|
||||
expect(result.status).toBe("healthy");
|
||||
});
|
||||
|
||||
it("should return uptime as a positive number", () => {
|
||||
const result = controller.check();
|
||||
|
||||
expect(typeof result.uptime).toBe("number");
|
||||
expect(result.uptime).toBeGreaterThanOrEqual(0);
|
||||
});
|
||||
|
||||
it("should return timestamp as valid ISO 8601 string", () => {
|
||||
const result = controller.check();
|
||||
|
||||
expect(typeof result.timestamp).toBe("string");
|
||||
expect(() => new Date(result.timestamp)).not.toThrow();
|
||||
|
||||
// Verify it's a valid ISO 8601 format
|
||||
const date = new Date(result.timestamp);
|
||||
expect(date.toISOString()).toBe(result.timestamp);
|
||||
});
|
||||
|
||||
it("should return only required fields (status, uptime, timestamp)", () => {
|
||||
const result = controller.check();
|
||||
|
||||
const keys = Object.keys(result);
|
||||
expect(keys).toHaveLength(3);
|
||||
expect(keys).toContain("status");
|
||||
expect(keys).toContain("uptime");
|
||||
expect(keys).toContain("timestamp");
|
||||
});
|
||||
|
||||
it("should increment uptime over time", async () => {
|
||||
const result1 = controller.check();
|
||||
const uptime1 = result1.uptime;
|
||||
|
||||
// Wait 1100ms to ensure at least 1 second has passed
|
||||
await new Promise((resolve) => setTimeout(resolve, 1100));
|
||||
|
||||
const result2 = controller.check();
|
||||
const uptime2 = result2.uptime;
|
||||
|
||||
// Uptime should be at least 1 second higher
|
||||
expect(uptime2).toBeGreaterThanOrEqual(uptime1 + 1);
|
||||
});
|
||||
|
||||
it("should return current timestamp", () => {
|
||||
const before = Date.now();
|
||||
const result = controller.check();
|
||||
const after = Date.now();
|
||||
|
||||
const resultTime = new Date(result.timestamp).getTime();
|
||||
|
||||
// Timestamp should be between before and after (within test execution time)
|
||||
expect(resultTime).toBeGreaterThanOrEqual(before);
|
||||
expect(resultTime).toBeLessThanOrEqual(after);
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /health/ready", () => {
|
||||
it("should return ready status", () => {
|
||||
const result = controller.ready();
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result).toHaveProperty("ready");
|
||||
});
|
||||
|
||||
it("should return ready as true", () => {
|
||||
const result = controller.ready();
|
||||
|
||||
expect(result.ready).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user