// Mock Next.js server components jest.mock('next/server', () => ({ NextResponse: { json: (data: any, init?: ResponseInit) => ({ json: async () => data, ...init }) } })); // Mock confluence module jest.mock('../src/server/confluence', () => ({ fetchFromConfluence: jest.fn() })); import { GET } from '../app/api/filaments/route'; import { fetchFromConfluence } from '../src/server/confluence'; describe('API Security Tests', () => { const originalEnv = process.env; beforeEach(() => { jest.resetModules(); process.env = { ...originalEnv }; }); afterEach(() => { process.env = originalEnv; }); it('should not expose credentials in error responses', async () => { // Simulate missing environment variables delete process.env.CONFLUENCE_TOKEN; const response = await GET(); const data = await response.json(); // Check that response doesn't contain sensitive information expect(JSON.stringify(data)).not.toContain('ATATT'); expect(JSON.stringify(data)).not.toContain('token'); expect(JSON.stringify(data)).not.toContain('password'); expect(data.error).toBe('Server configuration error'); }); it('should not expose internal error details', async () => { // Set valid environment process.env.CONFLUENCE_API_URL = 'https://test.atlassian.net'; process.env.CONFLUENCE_TOKEN = 'test-token'; process.env.CONFLUENCE_PAGE_ID = 'test-page'; // Mock fetchFromConfluence to throw an error const mockFetchFromConfluence = fetchFromConfluence as jest.MockedFunction; mockFetchFromConfluence.mockRejectedValueOnce(new Error('Internal database error with sensitive details')); const response = await GET(); const data = await response.json(); // Should get generic error, not specific details expect(data.error).toBe('Failed to fetch filaments'); expect(data).not.toHaveProperty('stack'); expect(data).not.toHaveProperty('message'); expect(JSON.stringify(data)).not.toContain('Internal database error'); expect(JSON.stringify(data)).not.toContain('sensitive details'); }); });