eletrotupi / tcc / api/tests/users/create.test.ts master
3.3 KB Raw
import test from "ava";
import { PrismaClient } from '@prisma/client';
import { PrismaPg } from '@prisma/adapter-pg';
import request from 'supertest';
import jwt from 'jsonwebtoken';
import 'dotenv/config';
import { Express } from 'express';
import { createApp } from '../../src/createApp';

let prisma: PrismaClient;
let app: Express;

test.before(() => {
  process.env.NODE_ENV = 'test';
  process.env.JWT_SECRET = 'test-secret-key';

  const connectionString = process.env.DATABASE_URL || 'postgres://user:password@orbit_db:5432/orbit_test';
  const adapter = new PrismaPg({ connectionString });
  prisma = new PrismaClient({ adapter });

  // Create Express app with test Prisma client
  app = createApp(prisma);
});

test.beforeEach(async () => {
  // Clean database before each test
  try {
    await prisma.user.deleteMany({});
  } catch (err) {
    console.error('Error cleaning test DB:', err);
  }
});

test.after.always(async () => {
  await prisma?.$disconnect();
});

test("POST /users creates a new user and returns JWT token", async (t) => {
  const userData = {
    email: "falamansa@example.com",
    firstName: "Fala",
    lastName: "Mansa",
    password: "IscreviSeuNomeNaAreia"
  };

  const response = await request(app)
    .post('/users')
    .send(userData)
    .expect('Content-Type', /json/)
    .expect(201);

  // Should return a JWT token
  t.truthy(response.body.token);

  // Verify the token is valid
  const decoded = jwt.verify(response.body.token, process.env.JWT_SECRET!) as any;
  t.is(decoded.email, userData.email);
  t.truthy(decoded.userId);

  // Verify user was created in database
  const dbUser = await prisma.user.findUnique({
    where: { email: userData.email }
  });
  t.truthy(dbUser);
  t.is(dbUser!.email, userData.email);
  t.is(dbUser!.firstName, userData.firstName);
  t.is(dbUser!.lastName, userData.lastName);
});

test("POST /users returns 400 for missing required fields", async (t) => {
  const response = await request(app)
    .post('/users')
    .send({
      email: "invalid@example.com"
      // Missing firstName and password
    })
    .expect('Content-Type', /json/)
    .expect(400);

  t.truthy(response.body.error);
  t.is(response.body.error, "Campos faltantes"); // TODO: i18n?
  t.truthy(response.body.missing);
  t.true(response.body.missing.includes('password'));
  t.true(response.body.missing.includes('firstName'));
});

test("POST /users returns 409 for duplicate email", async (t) => {
  const email = "duplicate@example.com";

  // Create first user
  await prisma.user.create({
    data: {
      email,
      firstName: "First",
      lastName: "User",
      encryptedPassword: "$2a$10$test"
    }
  });

  // Try to create second user with same email
  const response = await request(app)
    .post('/users')
    .send({
      email,
      firstName: "Second",
      lastName: "User",
      password: "hunter2"
    })
    .expect('Content-Type', /json/)
    .expect(409);

  t.truthy(response.body.error);
});

test("createApp successfully integrates with Prisma and Express", async (t) => {
  // Test that the app factory works correctly
  const testApp = createApp(prisma);

  t.truthy(testApp);
  t.is(typeof testApp.use, 'function');
  t.is(typeof testApp.listen, 'function');

  // Verify the app has the prisma client in locals
  t.is(testApp.locals.prisma, prisma);
});