import request from 'supertest'; import app from '../src/server.js'; import { pool } from '../src/db/connection.js'; describe('API Contract Tests', () => { let authToken; let testUserId; beforeAll(async () => { // Clean up any existing test data await pool.query('DELETE FROM users WHERE email = ?', ['test@example.com']); // Register a test user const registerResponse = await request(app) .post('/auth/register') .send({ email: 'test@example.com', password: 'password123', displayName: 'Test User' }); expect(registerResponse.status).toBe(201); authToken = registerResponse.body.token; // Get the user ID const [rows] = await pool.query('SELECT id FROM users WHERE email = ?', ['test@example.com']); testUserId = rows[0].id; }); afterAll(async () => { // Clean up test data await pool.query('DELETE FROM users WHERE email = ?', ['test@example.com']); await pool.end(); }); describe('Auth Endpoints', () => { it('should register a new user', async () => { const response = await request(app) .post('/auth/register') .send({ email: 'register-test@example.com', password: 'password123', displayName: 'Register Test User' }); expect(response.status).toBe(201); expect(response.body).toHaveProperty('token'); }); it('should fail to register with invalid data', async () => { const response = await request(app) .post('/auth/register') .send({ email: 'invalid-email', password: 'short', displayName: '' }); expect(response.status).toBe(400); }); it('should login with valid credentials', async () => { const response = await request(app) .post('/auth/login') .send({ email: 'test@example.com', password: 'password123' }); expect(response.status).toBe(200); expect(response.body).toHaveProperty('token'); }); it('should fail to login with invalid credentials', async () => { const response = await request(app) .post('/auth/login') .send({ email: 'test@example.com', password: 'wrongpassword' }); expect(response.status).toBe(401); }); }); describe('Help Requests Endpoints', () => { let helpRequestId; it('should fetch all help requests', async () => { const response = await request(app) .get('/requests') .set('Authorization', `Bearer ${authToken}`); expect(response.status).toBe(200); expect(Array.isArray(response.body)).toBe(true); }); it('should create a new help request', async () => { const response = await request(app) .post('/requests') .set('Authorization', `Bearer ${authToken}`) .send({ title: 'Test Help Request', description: 'This is a test help request', valueChf: 50.0 }); expect(response.status).toBe(201); expect(response.body).toHaveProperty('id'); helpRequestId = response.body.id; }); it('should fail to create a help request with invalid data', async () => { const response = await request(app) .post('/requests') .set('Authorization', `Bearer ${authToken}`) .send({ title: 'T', description: 'Short', valueChf: -10 }); expect(response.status).toBe(400); }); it('should update a help request', async () => { const response = await request(app) .put(`/requests/${helpRequestId}`) .set('Authorization', `Bearer ${authToken}`) .send({ title: 'Updated Test Help Request', description: 'This is an updated test help request', valueChf: 75.0, status: 'in_progress' }); expect(response.status).toBe(200); }); it('should fail to update a help request with invalid data', async () => { const response = await request(app) .put(`/requests/${helpRequestId}`) .set('Authorization', `Bearer ${authToken}`) .send({ title: 'T', description: 'Short', valueChf: -10 }); expect(response.status).toBe(400); }); it('should delete a help request', async () => { const response = await request(app) .delete(`/requests/${helpRequestId}`) .set('Authorization', `Bearer ${authToken}`); expect(response.status).toBe(200); }); }); describe('Offers Endpoints', () => { let offerId; it('should fetch all offers', async () => { const response = await request(app) .get('/offers') .set('Authorization', `Bearer ${authToken}`); expect(response.status).toBe(200); expect(Array.isArray(response.body)).toBe(true); }); it('should create a new offer', async () => { // First create a help request to offer against const requestResponse = await request(app) .post('/requests') .set('Authorization', `Bearer ${authToken}`) .send({ title: 'Test Help Request for Offer', description: 'This is a test help request for an offer', valueChf: 50.0 }); const helpRequestId = requestResponse.body.id; const response = await request(app) .post('/offers') .set('Authorization', `Bearer ${authToken}`) .send({ helpRequestId, description: 'This is a test offer', valueChf: 45.0 }); expect(response.status).toBe(201); expect(response.body).toHaveProperty('id'); offerId = response.body.id; }); it('should fail to create an offer with invalid data', async () => { const response = await request(app) .post('/offers') .set('Authorization', `Bearer ${authToken}`) .send({ helpRequestId: 99999, description: 'Short', valueChf: -10 }); expect(response.status).toBe(400); }); it('should delete an offer', async () => { const response = await request(app) .delete(`/offers/${offerId}`) .set('Authorization', `Bearer ${authToken}`); expect(response.status).toBe(200); }); }); describe('Contacts Endpoints', () => { let helpRequestId; let offerId; beforeAll(async () => { // Create a help request and offer to have valid IDs for contact tests const requestResponse = await request(app) .post('/requests') .set('Authorization', `Bearer ${authToken}`) .send({ title: 'Test Help Request for Contact', description: 'This is a test help request for contacts', valueChf: 50.0 }); helpRequestId = requestResponse.body.id; const offerResponse = await request(app) .post('/offers') .set('Authorization', `Bearer ${authToken}`) .send({ helpRequestId, description: 'This is a test offer for contacts', valueChf: 45.0 }); offerId = offerResponse.body.id; }); it('should fetch all contacts', async () => { const response = await request(app) .get('/contacts') .set('Authorization', `Bearer ${authToken}`); expect(response.status).toBe(200); expect(Array.isArray(response.body)).toBe(true); }); it('should create a new contact', async () => { const response = await request(app) .post('/contacts') .set('Authorization', `Bearer ${authToken}`) .send({ name: 'Test Contact', email: 'test@example.com', phone: '123-456-7890' }); expect(response.status).toBe(201); expect(response.body).toHaveProperty('id'); }); it('should fail to create a contact with invalid data', async () => { const response = await request(app) .post('/contacts') .set('Authorization', `Bearer ${authToken}`) .send({ name: '', email: 'invalid-email', phone: '' }); expect(response.status).toBe(400); }); it('should send a contact request', async () => { const response = await request(app) .post('/contacts/request') .set('Authorization', `Bearer ${authToken}`) .send({ dealId: helpRequestId, targetUserId: testUserId }); expect(response.status).toBe(403); // Forbidden because we're not in a valid deal context }); it('should respond to a contact request', async () => { const response = await request(app) .post('/contacts/respond') .set('Authorization', `Bearer ${authToken}`) .send({ requestId: 1, accept: true }); expect(response.status).toBe(404); // Not found because we don't have a valid request ID }); it('should fetch contacts for a deal', async () => { const response = await request(app) .get(`/contacts/deal/${helpRequestId}`) .set('Authorization', `Bearer ${authToken}`); expect(response.status).toBe(403); // Forbidden because we're not in a valid deal context }); }); });