feat: cover Enhancemet service by tests
This commit is contained in:
parent
ff565238da
commit
2a4ba8f4ed
|
|
@ -0,0 +1,164 @@
|
|||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { PromptEnhancementService } from '../PromptEnhancementService';
|
||||
import type { AgentResult } from '../types';
|
||||
|
||||
// Mock the agents module
|
||||
vi.mock('../agents', () => ({
|
||||
getAgent: vi.fn(() => ({
|
||||
templateType: 'general',
|
||||
enhance: vi.fn(),
|
||||
})),
|
||||
}));
|
||||
|
||||
describe('PromptEnhancementService', () => {
|
||||
let service: PromptEnhancementService;
|
||||
const mockApiKey = 'test-gemini-api-key';
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
service = new PromptEnhancementService(mockApiKey);
|
||||
});
|
||||
|
||||
describe('constructor', () => {
|
||||
it('should throw error when API key is missing', () => {
|
||||
expect(() => new PromptEnhancementService('')).toThrow('Gemini API key is required');
|
||||
});
|
||||
|
||||
it('should create instance with valid API key', () => {
|
||||
expect(service).toBeInstanceOf(PromptEnhancementService);
|
||||
});
|
||||
});
|
||||
|
||||
describe('enhancePrompt', () => {
|
||||
it('should reject empty prompts', async () => {
|
||||
const result = await service.enhancePrompt('');
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toBe('Prompt cannot be empty');
|
||||
});
|
||||
|
||||
it('should reject prompts exceeding 5000 characters', async () => {
|
||||
const longPrompt = 'a'.repeat(5001);
|
||||
const result = await service.enhancePrompt(longPrompt);
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain('exceeds maximum length');
|
||||
});
|
||||
|
||||
it('should successfully enhance valid prompt', async () => {
|
||||
const { getAgent } = await import('../agents');
|
||||
const mockAgent = {
|
||||
templateType: 'general',
|
||||
enhance: vi.fn().mockResolvedValue({
|
||||
success: true,
|
||||
enhancedPrompt: 'A beautiful sunset over the ocean with vibrant colors',
|
||||
appliedTemplate: 'general',
|
||||
enhancements: ['Added detailed descriptions'],
|
||||
} as AgentResult),
|
||||
};
|
||||
vi.mocked(getAgent).mockReturnValue(mockAgent);
|
||||
|
||||
const result = await service.enhancePrompt('sunset');
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.enhancedPrompt).toBe('A beautiful sunset over the ocean with vibrant colors');
|
||||
expect(result.appliedTemplate).toBe('general');
|
||||
});
|
||||
|
||||
it('should handle agent enhancement failure', async () => {
|
||||
const { getAgent } = await import('../agents');
|
||||
const mockAgent = {
|
||||
templateType: 'general',
|
||||
enhance: vi.fn().mockResolvedValue({
|
||||
success: false,
|
||||
error: 'Enhancement failed',
|
||||
enhancements: [],
|
||||
} as AgentResult),
|
||||
};
|
||||
vi.mocked(getAgent).mockReturnValue(mockAgent);
|
||||
|
||||
const result = await service.enhancePrompt('sunset');
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toBe('Enhancement failed');
|
||||
});
|
||||
|
||||
it('should truncate enhanced prompt exceeding 2000 characters', async () => {
|
||||
const { getAgent } = await import('../agents');
|
||||
const longEnhancedPrompt = 'enhanced '.repeat(300); // > 2000 chars
|
||||
const mockAgent = {
|
||||
templateType: 'general',
|
||||
enhance: vi.fn().mockResolvedValue({
|
||||
success: true,
|
||||
enhancedPrompt: longEnhancedPrompt,
|
||||
appliedTemplate: 'general',
|
||||
enhancements: [],
|
||||
} as AgentResult),
|
||||
};
|
||||
vi.mocked(getAgent).mockReturnValue(mockAgent);
|
||||
|
||||
const result = await service.enhancePrompt('sunset');
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.enhancedPrompt?.length).toBe(2000);
|
||||
});
|
||||
|
||||
it('should pass options to agent', async () => {
|
||||
const { getAgent } = await import('../agents');
|
||||
const mockEnhance = vi.fn().mockResolvedValue({
|
||||
success: true,
|
||||
enhancedPrompt: 'Enhanced',
|
||||
appliedTemplate: 'photorealistic',
|
||||
enhancements: [],
|
||||
} as AgentResult);
|
||||
const mockAgent = {
|
||||
templateType: 'photorealistic',
|
||||
enhance: mockEnhance,
|
||||
};
|
||||
vi.mocked(getAgent).mockReturnValue(mockAgent);
|
||||
|
||||
await service.enhancePrompt('sunset', {
|
||||
template: 'photorealistic',
|
||||
tags: ['landscape', 'nature'],
|
||||
});
|
||||
|
||||
expect(mockEnhance).toHaveBeenCalledWith('sunset', {
|
||||
template: 'photorealistic',
|
||||
tags: ['landscape', 'nature'],
|
||||
});
|
||||
});
|
||||
|
||||
it('should include detected language in result', async () => {
|
||||
const { getAgent } = await import('../agents');
|
||||
const mockAgent = {
|
||||
templateType: 'general',
|
||||
enhance: vi.fn().mockResolvedValue({
|
||||
success: true,
|
||||
enhancedPrompt: 'Enhanced prompt',
|
||||
detectedLanguage: 'Spanish',
|
||||
appliedTemplate: 'general',
|
||||
enhancements: [],
|
||||
} as AgentResult),
|
||||
};
|
||||
vi.mocked(getAgent).mockReturnValue(mockAgent);
|
||||
|
||||
const result = await service.enhancePrompt('hermosa puesta de sol');
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.detectedLanguage).toBe('Spanish');
|
||||
});
|
||||
|
||||
it('should handle exceptions gracefully', async () => {
|
||||
const { getAgent } = await import('../agents');
|
||||
const mockAgent = {
|
||||
templateType: 'general',
|
||||
enhance: vi.fn().mockRejectedValue(new Error('Network error')),
|
||||
};
|
||||
vi.mocked(getAgent).mockReturnValue(mockAgent);
|
||||
|
||||
const result = await service.enhancePrompt('sunset');
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toBe('Network error');
|
||||
});
|
||||
|
||||
it('should return original prompt in all results', async () => {
|
||||
const originalPrompt = 'test prompt';
|
||||
const result = await service.enhancePrompt(originalPrompt);
|
||||
expect(result.originalPrompt).toBe(originalPrompt);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
import { describe, it, expect } from 'vitest';
|
||||
import { getAgent } from '../agents';
|
||||
import {
|
||||
GeneralAgent,
|
||||
PhotorealisticAgent,
|
||||
IllustrationAgent,
|
||||
MinimalistAgent,
|
||||
StickerAgent,
|
||||
ProductAgent,
|
||||
ComicAgent,
|
||||
} from '../agents';
|
||||
|
||||
describe('getAgent', () => {
|
||||
const mockApiKey = 'test-api-key';
|
||||
|
||||
it('should return GeneralAgent when no template provided', () => {
|
||||
const agent = getAgent(mockApiKey);
|
||||
expect(agent).toBeInstanceOf(GeneralAgent);
|
||||
});
|
||||
|
||||
it('should return PhotorealisticAgent for photorealistic template', () => {
|
||||
const agent = getAgent(mockApiKey, 'photorealistic');
|
||||
expect(agent).toBeInstanceOf(PhotorealisticAgent);
|
||||
});
|
||||
|
||||
it('should return IllustrationAgent for illustration template', () => {
|
||||
const agent = getAgent(mockApiKey, 'illustration');
|
||||
expect(agent).toBeInstanceOf(IllustrationAgent);
|
||||
});
|
||||
|
||||
it('should return MinimalistAgent for minimalist template', () => {
|
||||
const agent = getAgent(mockApiKey, 'minimalist');
|
||||
expect(agent).toBeInstanceOf(MinimalistAgent);
|
||||
});
|
||||
|
||||
it('should return StickerAgent for sticker template', () => {
|
||||
const agent = getAgent(mockApiKey, 'sticker');
|
||||
expect(agent).toBeInstanceOf(StickerAgent);
|
||||
});
|
||||
|
||||
it('should return ProductAgent for product template', () => {
|
||||
const agent = getAgent(mockApiKey, 'product');
|
||||
expect(agent).toBeInstanceOf(ProductAgent);
|
||||
});
|
||||
|
||||
it('should return ComicAgent for comic template', () => {
|
||||
const agent = getAgent(mockApiKey, 'comic');
|
||||
expect(agent).toBeInstanceOf(ComicAgent);
|
||||
});
|
||||
|
||||
it('should return GeneralAgent for general template', () => {
|
||||
const agent = getAgent(mockApiKey, 'general');
|
||||
expect(agent).toBeInstanceOf(GeneralAgent);
|
||||
});
|
||||
|
||||
it('should fallback to GeneralAgent for unknown template', () => {
|
||||
const agent = getAgent(mockApiKey, 'unknown-template' as any);
|
||||
expect(agent).toBeInstanceOf(GeneralAgent);
|
||||
});
|
||||
|
||||
it('should return agent with correct templateType', () => {
|
||||
const agent = getAgent(mockApiKey, 'photorealistic');
|
||||
expect(agent.templateType).toBe('photorealistic');
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
import { describe, it, expect } from 'vitest';
|
||||
import { detectLanguage, detectEnhancements } from '../utils';
|
||||
|
||||
describe('detectLanguage', () => {
|
||||
it('should detect English', () => {
|
||||
expect(detectLanguage('a sunset over the ocean')).toBe('English');
|
||||
});
|
||||
|
||||
it('should detect Chinese', () => {
|
||||
expect(detectLanguage('美丽的日落')).toBe('Chinese');
|
||||
});
|
||||
|
||||
it('should detect Japanese', () => {
|
||||
expect(detectLanguage('こんにちは')).toBe('Japanese');
|
||||
});
|
||||
|
||||
it('should detect Korean', () => {
|
||||
expect(detectLanguage('아름다운 일몰')).toBe('Korean');
|
||||
});
|
||||
|
||||
it('should detect Romance Language', () => {
|
||||
expect(detectLanguage('hermosa puesta de sól')).toBe('Romance Language');
|
||||
expect(detectLanguage('beau coucher de soléil')).toBe('Romance Language');
|
||||
});
|
||||
|
||||
it('should detect Russian', () => {
|
||||
expect(detectLanguage('красивый закат')).toBe('Russian');
|
||||
});
|
||||
|
||||
it('should detect Greek', () => {
|
||||
expect(detectLanguage('όμορφο ηλιοβασίλεμα')).toBe('Greek');
|
||||
});
|
||||
|
||||
it('should detect Arabic', () => {
|
||||
expect(detectLanguage('غروب جميل')).toBe('Arabic');
|
||||
});
|
||||
|
||||
it('should detect Hebrew', () => {
|
||||
expect(detectLanguage('שקיעה יפה')).toBe('Hebrew');
|
||||
});
|
||||
|
||||
it('should default to English for unknown scripts', () => {
|
||||
expect(detectLanguage('123')).toBe('English');
|
||||
});
|
||||
});
|
||||
|
||||
describe('detectEnhancements', () => {
|
||||
it('should detect added detailed descriptions', () => {
|
||||
const original = 'sunset';
|
||||
const enhanced = 'A breathtaking sunset over the ocean with vibrant orange and pink hues';
|
||||
const enhancements = detectEnhancements(original, enhanced);
|
||||
expect(enhancements).toContain('Added detailed descriptions');
|
||||
});
|
||||
|
||||
it('should detect photography terminology', () => {
|
||||
const original = 'sunset';
|
||||
const enhanced = 'A photorealistic sunset shot with 50mm lens';
|
||||
const enhancements = detectEnhancements(original, enhanced);
|
||||
expect(enhancements).toContain('Applied photography terminology');
|
||||
});
|
||||
|
||||
it('should detect lighting descriptions', () => {
|
||||
const original = 'room';
|
||||
const enhanced = 'A room with soft lighting and warm illuminated corners';
|
||||
const enhancements = detectEnhancements(original, enhanced);
|
||||
expect(enhancements).toContain('Enhanced lighting description');
|
||||
});
|
||||
|
||||
it('should detect texture details', () => {
|
||||
const original = 'wall';
|
||||
const enhanced = 'A wall with rough texture and weathered surface';
|
||||
const enhancements = detectEnhancements(original, enhanced);
|
||||
expect(enhancements).toContain('Added texture details');
|
||||
});
|
||||
|
||||
it('should detect multiple enhancements', () => {
|
||||
const original = 'sunset';
|
||||
const enhanced =
|
||||
'A photorealistic sunset with dramatic lighting, beautiful texture in the clouds, and soft illuminated sky';
|
||||
const enhancements = detectEnhancements(original, enhanced);
|
||||
expect(enhancements.length).toBeGreaterThan(1);
|
||||
});
|
||||
|
||||
it('should return empty array when no enhancements detected', () => {
|
||||
const original = 'sunset';
|
||||
const enhanced = 'sunset';
|
||||
const enhancements = detectEnhancements(original, enhanced);
|
||||
expect(enhancements).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
import { describe, it, expect } from 'vitest';
|
||||
import { validatePromptLength } from '../validators';
|
||||
|
||||
describe('validatePromptLength', () => {
|
||||
it('should reject empty prompts', () => {
|
||||
const result = validatePromptLength('');
|
||||
expect(result.valid).toBe(false);
|
||||
expect(result.error).toBe('Prompt cannot be empty');
|
||||
});
|
||||
|
||||
it('should reject whitespace-only prompts', () => {
|
||||
const result = validatePromptLength(' ');
|
||||
expect(result.valid).toBe(false);
|
||||
expect(result.error).toBe('Prompt cannot be empty');
|
||||
});
|
||||
|
||||
it('should accept valid prompt within max length', () => {
|
||||
const result = validatePromptLength('a sunset over the ocean', 2000);
|
||||
expect(result.valid).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should reject prompts exceeding max length', () => {
|
||||
const longPrompt = 'a'.repeat(2001);
|
||||
const result = validatePromptLength(longPrompt, 2000);
|
||||
expect(result.valid).toBe(false);
|
||||
expect(result.error).toContain('exceeds maximum length');
|
||||
expect(result.error).toContain('2000');
|
||||
});
|
||||
|
||||
it('should use custom max length', () => {
|
||||
const prompt = 'a'.repeat(150);
|
||||
const result = validatePromptLength(prompt, 100);
|
||||
expect(result.valid).toBe(false);
|
||||
expect(result.error).toContain('100');
|
||||
});
|
||||
|
||||
it('should accept prompt at exact max length', () => {
|
||||
const prompt = 'a'.repeat(100);
|
||||
const result = validatePromptLength(prompt, 100);
|
||||
expect(result.valid).toBe(true);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue