import { INestApplication } from '@nestjs/common'; import * as request from 'supertest'; import { createTestApp, createTestUser, generateTokensForUser, cleanupTestData } from './test-utils'; import { v4 as uuidv4 } from 'uuid'; describe('UsersController (e2e)', () => { let app: INestApplication; let accessToken: string; let testUser: any; let testUserId: string; beforeAll(async () => { app = await createTestApp(); // Create a test user and generate tokens testUser = await createTestUser(app); testUserId = testUser.id; const tokens = await generateTokensForUser(app, testUserId); accessToken = tokens.accessToken; }); afterAll(async () => { // Clean up test data await cleanupTestData(app, testUserId); await app.close(); }); describe('GET /api/users', () => { it('should return a list of users when authenticated', () => { return request(app.getHttpServer()) .get('/api/users') .set('Authorization', `Bearer ${accessToken}`) .expect(200) .expect((res) => { expect(Array.isArray(res.body)).toBe(true); expect(res.body.length).toBeGreaterThan(0); expect(res.body.some(user => user.id === testUserId)).toBe(true); }); }); it('should return 401 when not authenticated', () => { return request(app.getHttpServer()) .get('/api/users') .expect(401); }); }); describe('GET /api/users/:id', () => { it('should return a user by ID when authenticated', () => { return request(app.getHttpServer()) .get(`/api/users/${testUserId}`) .set('Authorization', `Bearer ${accessToken}`) .expect(200) .expect((res) => { expect(res.body).toHaveProperty('id', testUserId); expect(res.body.name).toBe(testUser.name); expect(res.body.githubId).toBe(testUser.githubId); }); }); it('should return 401 when not authenticated', () => { return request(app.getHttpServer()) .get(`/api/users/${testUserId}`) .expect(401); }); it('should return 404 for non-existent user', () => { const nonExistentId = uuidv4(); return request(app.getHttpServer()) .get(`/api/users/${nonExistentId}`) .set('Authorization', `Bearer ${accessToken}`) .expect(404); }); }); describe('PATCH /api/users/:id', () => { it('should update a user when authenticated', () => { const updateData = { name: `Updated Test User ${uuidv4().substring(0, 8)}` }; return request(app.getHttpServer()) .patch(`/api/users/${testUserId}`) .set('Authorization', `Bearer ${accessToken}`) .send(updateData) .expect(200) .expect((res) => { expect(res.body).toHaveProperty('id', testUserId); expect(res.body.name).toBe(updateData.name); }); }); it('should return 401 when not authenticated', () => { return request(app.getHttpServer()) .patch(`/api/users/${testUserId}`) .send({ name: 'Updated Name' }) .expect(401); }); }); describe('POST /api/users/:id/gdpr-consent', () => { it('should update GDPR consent timestamp when authenticated', () => { return request(app.getHttpServer()) .post(`/api/users/${testUserId}/gdpr-consent`) .set('Authorization', `Bearer ${accessToken}`) .expect(200) .expect((res) => { expect(res.body).toHaveProperty('id', testUserId); expect(res.body).toHaveProperty('gdprConsentDate'); expect(new Date(res.body.gdprConsentDate).getTime()).toBeGreaterThan(0); }); }); it('should return 401 when not authenticated', () => { return request(app.getHttpServer()) .post(`/api/users/${testUserId}/gdpr-consent`) .expect(401); }); }); describe('GET /api/users/:id/export-data', () => { it('should export user data when authenticated', () => { return request(app.getHttpServer()) .get(`/api/users/${testUserId}/export-data`) .set('Authorization', `Bearer ${accessToken}`) .expect(200) .expect((res) => { expect(res.body).toHaveProperty('user'); expect(res.body.user).toHaveProperty('id', testUserId); expect(res.body).toHaveProperty('projects'); expect(res.body).toHaveProperty('groups'); expect(res.body).toHaveProperty('persons'); }); }); it('should return 401 when not authenticated', () => { return request(app.getHttpServer()) .get(`/api/users/${testUserId}/export-data`) .expect(401); }); }); // Note: We're not testing the DELETE endpoint to avoid complications with test user cleanup });