5929b935c1
DevSecOps Enterprise Pipeline / security-gate-and-deploy (pull_request) Failing after 10s
92 lines
3.8 KiB
JavaScript
92 lines
3.8 KiB
JavaScript
const request = require('supertest');
|
|
process.env.NODE_ENV = 'test';
|
|
const { app, transporter } = require('../backend/server');
|
|
const nodemailer = require('nodemailer');
|
|
|
|
// ==========================================
|
|
// MOCK EXTERNAL SERVICES
|
|
// ==========================================
|
|
jest.mock('nodemailer');
|
|
|
|
describe('Enterprise Application Flow & API Validation', () => {
|
|
|
|
beforeAll(() => {
|
|
// Configure the mock to simulate a successful SMTP response
|
|
nodemailer.createTransport.mockReturnValue({
|
|
sendMail: jest.fn().mockResolvedValue({ messageId: 'mock-id-enterprise-1234' })
|
|
});
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.clearAllMocks(); // Clear tracking between tests
|
|
});
|
|
|
|
// ==========================================
|
|
// 1. STATIC ROUTING TESTS
|
|
// ==========================================
|
|
describe('1. Static Web Routing', () => {
|
|
it('Should return 200 OK and text/html for the Home Page (/)', async () => {
|
|
const response = await request(app).get('/');
|
|
expect(response.status).toBe(200);
|
|
expect(response.headers['content-type']).toMatch(/text\/html/);
|
|
});
|
|
|
|
it('Should return 404 Not Found for an unknown endpoint', async () => {
|
|
const response = await request(app).get('/invalid-admin-route');
|
|
expect(response.status).toBe(404);
|
|
});
|
|
|
|
// OWASP ZAP (/api/search)
|
|
/* it('Should reflect the search query in the HTML response (/api/search) - Vulnerable to XSS', async () => {
|
|
const maliciousPayload = '<script>alert("ZAP")</script>';
|
|
const response = await request(app).get(`/api/search?q=${maliciousPayload}`);
|
|
|
|
expect(response.status).toBe(200);
|
|
// Verifica se o payload é refletido exatamente como entrou (confirmando a vulnerabilidade)
|
|
expect(response.text).toContain(`Resultados para: ${maliciousPayload}`);
|
|
});
|
|
});*/
|
|
|
|
// ==========================================
|
|
// 2. API BUSINESS LOGIC & VALIDATION TESTS
|
|
// ==========================================
|
|
describe('2. Contact API Endpoint (/api/contact)', () => {
|
|
|
|
it('Should reject requests and return 400 Bad Request if email is missing', async () => {
|
|
const invalidPayload = {
|
|
firstName: 'John',
|
|
message: 'I need a security audit.'
|
|
// Missing 'email' deliberately
|
|
};
|
|
|
|
const response = await request(app).post('/api/contact').send(invalidPayload);
|
|
|
|
expect(response.status).toBe(400);
|
|
|
|
// ==========================================
|
|
// CORREÇÃO DEVSECOPS: O servidor agora devolve HTML para a armadilha XSS!
|
|
// Lemos o response.text (HTML) em vez do response.body (JSON)
|
|
// ==========================================
|
|
expect(response.text).toContain('Erro de Validação');
|
|
expect(response.text).toContain('John'); // Garante que o input foi refletido na página
|
|
});
|
|
|
|
it('Should process request, return 200 OK, and invoke SMTP transporter with valid data', async () => {
|
|
const validPayload = {
|
|
firstName: 'Jane',
|
|
lastName: 'Doe',
|
|
email: 'jane.doe@example.com',
|
|
company: 'Apex Corporation',
|
|
message: 'Please send me the DevSecOps proposal.'
|
|
};
|
|
|
|
const response = await request(app).post('/api/contact').send(validPayload);
|
|
|
|
// Validate HTTP Response
|
|
expect(response.status).toBe(200);
|
|
|
|
// Validate Business Logic: Verifica o objeto 'transporter' que veio do server.js
|
|
expect(transporter.sendMail).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|
|
}); |