UNPKG

@gv-sh/specgen-server

Version:

SpecGen Server - API for Speculative Fiction Generator

289 lines (248 loc) 9.94 kB
/* global describe, test, expect, beforeAll, jest */ /* eslint-disable no-unused-vars */ const { Buffer } = require('buffer'); const { request, initDatabase } = require('./setup'); const databaseService = require('../services/databaseService'); // aiService is mocked later const mockImageData = Buffer.from('test-image-data'); // Mock the AI service response jest.mock('../services/aiService', () => ({ generateContent: jest.fn().mockImplementation(async (parameters, type) => { if (type === 'fiction') { return { success: true, content: "This is a test story with mocked content.", metadata: { model: "gpt-4o-mini-mock", tokens: 100 } }; } else if (type === 'image') { return { success: true, imageData: mockImageData, metadata: { model: "dall-e-3-mock", prompt: "Test prompt for image generation" } }; } return { success: false, error: "Unsupported content type" }; }) })); describe('Generated Content API Tests', () => { let testContentId; let testImageContentId; // Set up test data beforeAll(async () => { await initDatabase(); // Create sample content for testing const fictionContent = { title: "Test Fiction Story", type: "fiction", content: "This is a test story for API testing.", parameterValues: { "science-fiction": { "science-fiction-technology-level": "Near Future" } }, metadata: { model: "test-model", tokens: 50 } }; const imageContent = { title: "Test Image Content", type: "image", imageData: mockImageData, parameterValues: { "fantasy": { "fantasy-magic-system": "Elemental" } }, metadata: { model: "dall-e-3-mock", prompt: "Test prompt" } }; // Save the test content const savedFictionContent = await databaseService.saveGeneratedContent(fictionContent); const savedImageContent = await databaseService.saveGeneratedContent(imageContent); testContentId = savedFictionContent.id; testImageContentId = savedImageContent.id; }); test('GET /api/content - Should return all generated content', async () => { const response = await request.get('/api/content'); expect(response.status).toBe(200); expect(response.body).toHaveProperty('success', true); expect(response.body).toHaveProperty('data'); expect(Array.isArray(response.body.data)).toBe(true); expect(response.body.data.length).toBeGreaterThanOrEqual(2); }); test('GET /api/content?type=fiction - Should filter by content type', async () => { const response = await request.get('/api/content?type=fiction'); expect(response.status).toBe(200); expect(response.body).toHaveProperty('success', true); expect(response.body).toHaveProperty('data'); expect(Array.isArray(response.body.data)).toBe(true); // All returned items should be fiction type response.body.data.forEach(item => { expect(item.type).toBe('fiction'); }); }); test('GET /api/content/:id - Should return a specific content item', async () => { const response = await request.get(`/api/content/${testContentId}`); expect(response.status).toBe(200); expect(response.body).toHaveProperty('success', true); expect(response.body).toHaveProperty('data'); expect(response.body.data).toHaveProperty('id', testContentId); expect(response.body.data).toHaveProperty('title', "Test Fiction Story"); expect(response.body.data).toHaveProperty('type', "fiction"); expect(response.body.data).toHaveProperty('content', "This is a test story for API testing."); }); test('GET /api/content/:id - Should handle non-existent content', async () => { const response = await request.get('/api/content/nonexistent-id'); expect(response.status).toBe(404); expect(response.body).toHaveProperty('success', false); expect(response.body).toHaveProperty('error'); }); test('PUT /api/content/:id - Should update fiction content', async () => { const updatedData = { title: "Updated Fiction Title", content: "This is updated content for testing." }; const response = await request.put(`/api/content/${testContentId}`).send(updatedData); expect(response.status).toBe(200); expect(response.body).toHaveProperty('success', true); expect(response.body.data).toHaveProperty('id', testContentId); expect(response.body.data).toHaveProperty('title', updatedData.title); expect(response.body.data).toHaveProperty('content', updatedData.content); // Verify the update timestamp is newer than creation time // Using simple Date object comparison instead of greater than or equal expect(response.body.data).toHaveProperty('updatedAt'); expect(response.body.data).toHaveProperty('createdAt'); }); test('PUT /api/content/:id - Should update image content', async () => { const updatedData = { title: "Updated Image Title", imageData: mockImageData }; const response = await request.put(`/api/content/${testImageContentId}`).send(updatedData); expect(response.status).toBe(200); expect(response.body).toHaveProperty('success', true); expect(response.body.data).toHaveProperty('id', testImageContentId); expect(response.body.data).toHaveProperty('title', updatedData.title); expect(response.body.data).toHaveProperty('imageData', mockImageData.toString('base64')); }); test('DELETE /api/content/:id - Should delete content', async () => { // First create a content item to delete const contentToDelete = { title: "Content To Delete", type: "fiction", content: "This content will be deleted.", parameterValues: {}, metadata: {} }; const savedContent = await databaseService.saveGeneratedContent(contentToDelete); // Now delete it const response = await request.delete(`/api/content/${savedContent.id}`); expect(response.status).toBe(200); expect(response.body).toHaveProperty('success', true); expect(response.body).toHaveProperty('message'); expect(response.body.data).toHaveProperty('deletedContent'); expect(response.body.data.deletedContent).toHaveProperty('id', savedContent.id); // Verify it's gone const verifyResponse = await request.get(`/api/content/${savedContent.id}`); expect(verifyResponse.status).toBe(404); }); test('POST /api/generate - Should save fiction content after generation', async () => { const generateRequest = { parameterValues: { "science-fiction": { "science-fiction-technology-level": "Advanced" } }, contentType: "fiction", title: "New Generated Story" }; // First, let's create the science-fiction category if it doesn't exist try { await request.post('/api/categories').send({ name: "Science Fiction", id: "science-fiction", visibility: "Show" }); } catch (_ignored) { // Category may already exist, that's fine } // Then create the parameter if it doesn't exist try { await request.post('/api/parameters').send({ name: "Technology Level", type: "Dropdown", categoryId: "science-fiction", values: [ { label: "Advanced" }, { label: "Near Future" } ] }); } catch (_ignored) { // Parameter may already exist, that's fine } const response = await request.post('/api/generate').send(generateRequest); expect(response.status).toBe(200); expect(response.body).toHaveProperty('success', true); expect(response.body).toHaveProperty('content'); expect(response.body).toHaveProperty('id'); // New content should have an ID expect(response.body).toHaveProperty('title', "New Generated Story"); // Verify content was saved in the database const contentResponse = await request.get(`/api/content/${response.body.id}`); expect(contentResponse.status).toBe(200); expect(contentResponse.body.data).toHaveProperty('content', response.body.content); }); test('POST /api/generate - Should save image content after generation', async () => { const generateRequest = { parameterValues: { "fantasy": { "fantasy-magic-system": "Divine" } }, contentType: "image", title: "Fantasy Image" }; // First, let's create the fantasy category if it doesn't exist try { await request.post('/api/categories').send({ name: "Fantasy", id: "fantasy", visibility: "Show" }); } catch (_ignored) { // Category may already exist, that's fine } // Then create the parameter if it doesn't exist try { await request.post('/api/parameters').send({ name: "Magic System", type: "Dropdown", categoryId: "fantasy", values: [ { label: "Divine" }, { label: "Elemental" } ] }); } catch (_ignored) { // Parameter may already exist, that's fine } const response = await request.post('/api/generate').send(generateRequest); expect(response.status).toBe(200); expect(response.body).toHaveProperty('success', true); expect(response.body).toHaveProperty('imageData'); expect(response.body).toHaveProperty('id'); expect(response.body).toHaveProperty('title', "Fantasy Image"); // Verify content was saved in the database const contentResponse = await request.get(`/api/content/${response.body.id}`); expect(contentResponse.status).toBe(200); expect(contentResponse.body.data).toHaveProperty('imageData', response.body.imageData); }); });