"use strict";
/**
 * Tests for UpstashRedisGenerator
 */
Object.defineProperty(exports, "__esModule", { value: true });
const upstash_redis_generator_1 = require("./upstash-redis-generator");
const workflow_engine_1 = require("../../engine/workflow-engine");
describe('UpstashRedisGenerator', () => {
    let generator;
    let mockContext;
    beforeEach(() => {
        generator = new upstash_redis_generator_1.UpstashRedisGenerator();
        // Create basic mock context with minimal stack component
        const mockWorkflow = {
            workflow: {
                id: 'test-workflow',
                version: '1.0.0',
                name: 'Test Workflow',
                description: 'Test',
                actors: [],
            },
            stack: {
                backend: {
                    type: 'backend',
                    technology: 'express',
                    endpoints: [],
                },
            },
        };
        const engine = new workflow_engine_1.WorkflowEngine();
        const executionPlan = engine.analyze(mockWorkflow);
        mockContext = {
            workflow: mockWorkflow,
            executionPlan,
            outputDirectory: '/test/output',
            options: {},
        };
    });
    describe('Generator metadata', () => {
        it('should have correct id', () => {
            expect(generator.id).toBe('upstash-redis');
        });
        it('should have descriptive name', () => {
            expect(generator.name).toBe('Upstash Redis Generator');
        });
        it('should have meaningful description', () => {
            expect(generator.description).toContain('Upstash Redis');
        });
    });
    describe('Configuration detection', () => {
        it('should return empty result when no Redis configuration found', () => {
            const result = generator.generate(mockContext);
            expect(result.files).toEqual([]);
            expect(result.warnings).toBeDefined();
            expect(result.warnings?.[0]).toContain('No Redis/cache configuration found');
        });
        it('should detect Redis in technology.cache', () => {
            const extendedWorkflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                technology: {
                    cache: {
                        provider: 'upstash-redis',
                    },
                },
            };
            const contextWithCache = {
                ...mockContext,
                extendedWorkflow,
            };
            const result = generator.generate(contextWithCache);
            expect(result.files.length).toBeGreaterThan(0);
            expect(result.warnings).toBeUndefined();
        });
        it('should detect Redis provider variations', () => {
            const providers = ['redis', 'upstash', 'upstash-redis'];
            providers.forEach((provider) => {
                const extendedWorkflow = {
                    workflow: {
                        id: 'test',
                        version: '1.0.0',
                        name: 'Test',
                        description: 'Test',
                    },
                    technology: {
                        cache: {
                            provider,
                        },
                    },
                };
                const contextWithCache = {
                    ...mockContext,
                    extendedWorkflow,
                };
                const result = generator.generate(contextWithCache);
                expect(result.files.length).toBeGreaterThan(0);
            });
        });
        it('should detect infrastructure.services with cache type', () => {
            const extendedWorkflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                infrastructure: {
                    services: [
                        {
                            id: 'cache',
                            type: 'cache',
                            provider: 'upstash',
                        },
                    ],
                },
            };
            const contextWithService = {
                ...mockContext,
                extendedWorkflow,
            };
            const result = generator.generate(contextWithService);
            expect(result.files.length).toBeGreaterThan(0);
        });
    });
    describe('File generation', () => {
        let contextWithRedis;
        beforeEach(() => {
            const extendedWorkflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                technology: {
                    backend: {
                        framework: 'express',
                        language: 'typescript',
                    },
                    cache: {
                        provider: 'upstash-redis',
                    },
                },
            };
            contextWithRedis = {
                ...mockContext,
                extendedWorkflow,
            };
        });
        it('should generate redis-client.ts', () => {
            const result = generator.generate(contextWithRedis);
            const clientFile = result.files.find((f) => f.path.endsWith('redis-client.ts'));
            expect(clientFile).toBeDefined();
            expect(clientFile?.content).toContain('initializeRedis');
            expect(clientFile?.content).toContain('getRedis');
            expect(clientFile?.content).toContain('redisHealthCheck');
            expect(clientFile?.content).toContain('@upstash/redis');
        });
        it('should generate cache-helpers.ts', () => {
            const result = generator.generate(contextWithRedis);
            const cacheFile = result.files.find((f) => f.path.endsWith('cache-helpers.ts'));
            expect(cacheFile).toBeDefined();
            expect(cacheFile?.content).toContain('CacheManager');
            expect(cacheFile?.content).toContain('getOrSet');
            expect(cacheFile?.content).toContain('@Cached');
        });
        it('should generate rate-limiter.ts', () => {
            const result = generator.generate(contextWithRedis);
            const rateLimiterFile = result.files.find((f) => f.path.endsWith('rate-limiter.ts'));
            expect(rateLimiterFile).toBeDefined();
            expect(rateLimiterFile?.content).toContain('RateLimiter');
            expect(rateLimiterFile?.content).toContain('isAllowed');
            expect(rateLimiterFile?.content).toContain('middleware');
            expect(rateLimiterFile?.content).toContain('RateLimitPresets');
        });
        it('should generate session-store.ts', () => {
            const result = generator.generate(contextWithRedis);
            const sessionFile = result.files.find((f) => f.path.endsWith('session-store.ts'));
            expect(sessionFile).toBeDefined();
            expect(sessionFile?.content).toContain('RedisSessionStore');
            expect(sessionFile?.content).toContain('express-session');
        });
        it('should generate types.ts', () => {
            const result = generator.generate(contextWithRedis);
            const typesFile = result.files.find((f) => f.path.endsWith('cache/types.ts'));
            expect(typesFile).toBeDefined();
            expect(typesFile?.content).toContain('RedisConfig');
            expect(typesFile?.content).toContain('RateLimitResult');
        });
        it('should generate package.json additions', () => {
            const result = generator.generate(contextWithRedis);
            const packageFile = result.files.find((f) => f.path.endsWith('cache-package.json'));
            expect(packageFile).toBeDefined();
            expect(packageFile?.content).toContain('@upstash/redis');
            expect(packageFile?.content).toContain('express-session');
        });
        it('should generate .env.redis.example', () => {
            const result = generator.generate(contextWithRedis);
            const envFile = result.files.find((f) => f.path.endsWith('.env.redis.example'));
            expect(envFile).toBeDefined();
            expect(envFile?.content).toContain('UPSTASH_REDIS_REST_URL');
            expect(envFile?.content).toContain('UPSTASH_REDIS_REST_TOKEN');
        });
        it('should generate README', () => {
            const result = generator.generate(contextWithRedis);
            const readmeFile = result.files.find((f) => f.path.endsWith('REDIS.md'));
            expect(readmeFile).toBeDefined();
            expect(readmeFile?.content).toContain('Upstash Redis');
            expect(readmeFile?.content).toContain('Setup');
            expect(readmeFile?.content).toContain('Usage');
        });
        it('should generate all 8 files', () => {
            const result = generator.generate(contextWithRedis);
            expect(result.files).toHaveLength(8);
        });
    });
    describe('Backend directory detection', () => {
        it('should use "backend" as default directory', () => {
            const extendedWorkflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                technology: {
                    cache: {
                        provider: 'upstash-redis',
                    },
                },
            };
            const result = generator.generate({
                ...mockContext,
                extendedWorkflow,
            });
            const clientFile = result.files.find((f) => f.path.includes('redis-client.ts'));
            expect(clientFile?.path).toContain('/backend/');
        });
        it('should use custom directory from extended workflow', () => {
            const extendedWorkflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                technology: {
                    backend: {
                        framework: 'express',
                        language: 'typescript',
                        directory: 'custom-api',
                    },
                    cache: {
                        provider: 'upstash-redis',
                    },
                },
            };
            const result = generator.generate({
                ...mockContext,
                extendedWorkflow,
            });
            const clientFile = result.files.find((f) => f.path.includes('redis-client.ts'));
            expect(clientFile?.path).toContain('/custom-api/');
        });
        it('should detect backend directory from stack components', () => {
            const workflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                    actors: [],
                },
                stack: {
                    api: {
                        type: 'backend',
                        technology: 'express',
                        directory: 'services/api',
                        endpoints: [],
                    },
                },
            };
            const extendedWorkflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                technology: {
                    cache: {
                        provider: 'upstash-redis',
                    },
                },
            };
            const engine = new workflow_engine_1.WorkflowEngine();
            const executionPlan = engine.analyze(workflow);
            const result = generator.generate({
                workflow,
                executionPlan,
                outputDirectory: '/test/output',
                extendedWorkflow,
            });
            const clientFile = result.files.find((f) => f.path.includes('redis-client.ts'));
            expect(clientFile?.path).toContain('/services/api/');
        });
    });
    describe('Code quality', () => {
        let contextWithRedis;
        beforeEach(() => {
            const extendedWorkflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                technology: {
                    cache: {
                        provider: 'upstash-redis',
                    },
                },
            };
            contextWithRedis = {
                ...mockContext,
                extendedWorkflow,
            };
        });
        it('should generate valid TypeScript code', () => {
            const result = generator.generate(contextWithRedis);
            result.files.forEach((file) => {
                if (file.path.endsWith('.ts')) {
                    // Check for basic TypeScript syntax (export at minimum)
                    expect(file.content).toContain('export');
                    // Should not have syntax errors
                    expect(file.content).not.toContain('undefined undefined');
                    expect(file.content).not.toContain('null null');
                }
            });
        });
        it('should include error handling', () => {
            const result = generator.generate(contextWithRedis);
            const clientFile = result.files.find((f) => f.path.endsWith('redis-client.ts'));
            expect(clientFile?.content).toContain('try');
            expect(clientFile?.content).toContain('catch');
            expect(clientFile?.content).toContain('throw new Error');
        });
        it('should include TypeScript types', () => {
            const result = generator.generate(contextWithRedis);
            const cacheFile = result.files.find((f) => f.path.endsWith('cache-helpers.ts'));
            expect(cacheFile?.content).toMatch(/<T>/);
            expect(cacheFile?.content).toContain('Promise<');
        });
        it('should include documentation comments', () => {
            const result = generator.generate(contextWithRedis);
            const cacheFile = result.files.find((f) => f.path.endsWith('cache-helpers.ts'));
            expect(cacheFile?.content).toContain('/**');
            expect(cacheFile?.content).toContain('*/');
        });
    });
    describe('Express middleware integration', () => {
        it('should generate Express-compatible middleware', () => {
            const extendedWorkflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                technology: {
                    backend: {
                        framework: 'express',
                        language: 'typescript',
                    },
                    cache: {
                        provider: 'upstash-redis',
                    },
                },
            };
            const result = generator.generate({
                ...mockContext,
                extendedWorkflow,
            });
            const rateLimiterFile = result.files.find((f) => f.path.endsWith('rate-limiter.ts'));
            expect(rateLimiterFile?.content).toContain('Request');
            expect(rateLimiterFile?.content).toContain('Response');
            expect(rateLimiterFile?.content).toContain('NextFunction');
            expect(rateLimiterFile?.content).toContain('middleware()');
        });
        it('should generate session store compatible with express-session', () => {
            const extendedWorkflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                technology: {
                    cache: {
                        provider: 'upstash-redis',
                    },
                },
            };
            const result = generator.generate({
                ...mockContext,
                extendedWorkflow,
            });
            const sessionFile = result.files.find((f) => f.path.endsWith('session-store.ts'));
            expect(sessionFile?.content).toContain('extends Store');
            expect(sessionFile?.content).toContain('get(');
            expect(sessionFile?.content).toContain('set(');
            expect(sessionFile?.content).toContain('destroy(');
        });
    });
    describe('Configuration options', () => {
        it('should support custom cache TTL configuration', () => {
            const extendedWorkflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                technology: {
                    cache: {
                        provider: 'upstash-redis',
                        options: {
                            defaultTTL: 3600,
                        },
                    },
                },
            };
            const result = generator.generate({
                ...mockContext,
                extendedWorkflow,
            });
            expect(result.files.length).toBeGreaterThan(0);
        });
        it('should support rate limit configuration', () => {
            const extendedWorkflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                technology: {
                    cache: {
                        provider: 'upstash-redis',
                        options: {
                            rateLimit: {
                                max: 100,
                                window: 60,
                            },
                        },
                    },
                },
            };
            const result = generator.generate({
                ...mockContext,
                extendedWorkflow,
            });
            const rateLimiterFile = result.files.find((f) => f.path.endsWith('rate-limiter.ts'));
            expect(rateLimiterFile).toBeDefined();
        });
    });
    describe('Edge cases', () => {
        it('should handle missing extended workflow', () => {
            const result = generator.generate(mockContext);
            expect(result.files).toEqual([]);
            expect(result.warnings).toBeDefined();
        });
        it('should handle empty technology section', () => {
            const extendedWorkflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                technology: {},
            };
            const result = generator.generate({
                ...mockContext,
                extendedWorkflow,
            });
            expect(result.files).toEqual([]);
        });
        it('should handle missing cache configuration', () => {
            const extendedWorkflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                technology: {
                    backend: {
                        framework: 'express',
                        language: 'typescript',
                    },
                },
            };
            const result = generator.generate({
                ...mockContext,
                extendedWorkflow,
            });
            expect(result.files).toEqual([]);
        });
        it('should handle different cache providers gracefully', () => {
            const extendedWorkflow = {
                workflow: {
                    id: 'test',
                    version: '1.0.0',
                    name: 'Test',
                    description: 'Test',
                },
                technology: {
                    cache: {
                        provider: 'memcached',
                    },
                },
            };
            const result = generator.generate({
                ...mockContext,
                extendedWorkflow,
            });
            expect(result.files).toEqual([]);
        });
    });
});
//# sourceMappingURL=upstash-redis-generator.test.js.map