diff --git a/ui/__tests__/delete-collection.test.ts b/ui/__tests__/delete-collection.test.ts new file mode 100644 index 0000000..42f5f6c --- /dev/null +++ b/ui/__tests__/delete-collection.test.ts @@ -0,0 +1,70 @@ +import handler from '@/pages/api/delete-collection'; + +import { ChromaClient } from 'chromadb'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +vi.mock('chromadb', () => ({ + ChromaClient: vi.fn(), +})); + +const deleteCollection = vi.fn(); +const ChromaClientMock = vi.mocked(ChromaClient); + +function createResponse() { + const response = { + status: vi.fn(), + json: vi.fn(), + setHeader: vi.fn(), + }; + + response.status.mockReturnValue(response); + response.json.mockReturnValue(response); + + return response; +} + +describe('delete-collection API', () => { + beforeEach(() => { + vi.clearAllMocks(); + delete process.env.CHROMA_PATH; + deleteCollection.mockResolvedValue(undefined); + ChromaClientMock.mockImplementation(((config: { path: string }) => ({ + config, + deleteCollection, + })) as any); + }); + + it('rejects non-DELETE requests without deleting the collection', async () => { + const req = { method: 'GET' }; + const res = createResponse(); + + await handler(req as any, res as any); + + expect(res.setHeader).toHaveBeenCalledWith('Allow', ['DELETE']); + expect(res.status).toHaveBeenCalledWith(405); + expect(res.json).toHaveBeenCalledWith({ + error: 'Method not allowed', + }); + expect(ChromaClientMock).not.toHaveBeenCalled(); + expect(deleteCollection).not.toHaveBeenCalled(); + }); + + it('deletes the default collection using the configured Chroma path', async () => { + process.env.CHROMA_PATH = 'http://chroma.example:8000'; + const req = { method: 'DELETE' }; + const res = createResponse(); + + await handler(req as any, res as any); + + expect(ChromaClientMock).toHaveBeenCalledWith({ + path: 'http://chroma.example:8000', + }); + expect(deleteCollection).toHaveBeenCalledWith({ + name: 'default-collection', + }); + expect(res.status).toHaveBeenCalledWith(200); + expect(res.json).toHaveBeenCalledWith({ + message: 'Deleted collection.', + }); + }); +}); diff --git a/ui/pages/api/delete-collection.ts b/ui/pages/api/delete-collection.ts index 90fb745..746468e 100644 --- a/ui/pages/api/delete-collection.ts +++ b/ui/pages/api/delete-collection.ts @@ -1,17 +1,27 @@ -import type { NextApiRequest, NextApiResponse } from "next"; -import { ChromaClient, TransformersEmbeddingFunction } from "chromadb"; +import type { NextApiRequest, NextApiResponse } from 'next'; -export default async function handler(req: NextApiRequest, res: NextApiResponse) { +import { ChromaClient } from 'chromadb'; + +const DEFAULT_COLLECTION_NAME = 'default-collection'; +const DEFAULT_CHROMA_PATH = 'http://chroma-server:8000'; + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse, +) { try { + if (req.method !== 'DELETE') { + res.setHeader('Allow', ['DELETE']); + return res.status(405).json({ error: 'Method not allowed' }); + } + const client = new ChromaClient({ - path: "http://localhost:8000", + path: process.env.CHROMA_PATH || DEFAULT_CHROMA_PATH, }); + await client.deleteCollection({ name: DEFAULT_COLLECTION_NAME }); - await client.deleteCollection({name: "default-collection"}) - - - res.status(200).json("Deleted collection."); + res.status(200).json({ message: 'Deleted collection.' }); } catch (error) { if (error instanceof Error) { console.error('Error message:', error.message); @@ -21,4 +31,4 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) } res.status(500).json({ error: 'An unexpected error occurred :(' }); } -} \ No newline at end of file +}