Skip to content

Commit

Permalink
test(transaction): add unit
Browse files Browse the repository at this point in the history
this test file will be ignored
  • Loading branch information
NedcloarBR committed Aug 17, 2024
1 parent 51d5e28 commit 017e238
Show file tree
Hide file tree
Showing 4 changed files with 364 additions and 0 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"cSpell.words": [
"Adapter",
"biomejs",
"cnpj",
"fastify",
"Fastify",
"interceptors",
Expand Down
1 change: 1 addition & 0 deletions tests/__mocks__/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./formatInput";
export * from "./userMockInput";
export * from "./transactionMockInput";
46 changes: 46 additions & 0 deletions tests/__mocks__/utils/transactionMockInput.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { $Enums } from "@prisma/client";
import type { UserEntity } from "src/modules/user";

export async function transactionMockInput() {
const cpfUser1: UserEntity = {
publicId: "0a8ee1f5-1373-4767-9389-f76abf22bf4f",
money: 100,
firstName: "Miguel",
lastName: "Alexandre Uhlein1",
email: "nedcloar1_cpf1@hotmail.com",
userType: $Enums.UserType.CPF,
document: "79148189090",
};

const cpfUser2: UserEntity = {
publicId: "5bf57a8b-1db0-4999-868d-4d34b04f3f23",
money: 100,
firstName: "Miguel",
lastName: "Alexandre Uhlein2",
email: "nedcloar1_cpf2@hotmail.com",
userType: $Enums.UserType.CPF,
document: "98772856068",
};

const cnpjUser1: UserEntity = {
publicId: "d39af869-4b78-4c36-8081-123846f41b9d",
money: 100,
firstName: "Miguel",
lastName: "Alexandre Uhlein3",
email: "nedcloar1_cnpj1@hotmail.com",
userType: $Enums.UserType.CNPJ,
document: "30347915000139",
};

const cnpjUser2: UserEntity = {
publicId: "d39af869-4b78-4c36-8081-123846f41b9d",
money: 100,
firstName: "Miguel",
lastName: "Alexandre Uhlein4",
email: "nedcloar1_cnpj2@hotmail.com",
userType: $Enums.UserType.CNPJ,
document: "52736388000197",
};

return { cpfUser1, cpfUser2, cnpjUser1, cnpjUser2 };
}
316 changes: 316 additions & 0 deletions tests/transaction.spec-ignore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,316 @@
import { Test, type TestingModule } from "@nestjs/testing";
import type { CustomPrismaService } from "nestjs-prisma";
import { UnauthorizedError } from "src/common/errors";
import { UserModule } from "src/modules";
import type { ExtendedPrismaClient } from "src/modules/database/ExtendedPrismaClient";
import {
TransactionController,
TransactionEntity,
TransactionRepository,
TransactionService,
} from "src/modules/transaction";
import { TransactionDTO } from "src/modules/transaction/transaction.dto";
import { UserEntity, UserRepository, UserService } from "src/modules/user";
import { Repositories, Services } from "src/types/constants";
import { beforeEach, describe, expect, it } from "vitest";
import type { DeepMockProxy } from "vitest-mock-extended";
import { mockPrismaProvider, transactionMockInput } from "./__mocks__";

describe("TransactionModule Tests", () => {
let transactionController: TransactionController;
let transactionService: TransactionService;
let userService: UserService;
let transactionRepository: TransactionRepository;
let prismaMock: DeepMockProxy<ExtendedPrismaClient>;

beforeEach(async () => {
const moduleRef: TestingModule = await Test.createTestingModule({
// imports: [UserModule],
controllers: [TransactionController],
providers: [
{
provide: Services.Transaction,
useClass: TransactionService,
},
{
provide: Repositories.Transaction,
useClass: TransactionRepository,
},
{
provide: Services.User,
useClass: UserService,
},
{
provide: Repositories.User,
useClass: UserRepository,
},
mockPrismaProvider,
],
}).compile();

transactionController = moduleRef.get<TransactionController>(
TransactionController,
);
transactionService = moduleRef.get<TransactionService>(
Services.Transaction,
);
userService = moduleRef.get<UserService>(Services.User);
transactionRepository = moduleRef.get<TransactionRepository>(
Repositories.Transaction,
);
prismaMock = moduleRef.get<
DeepMockProxy<CustomPrismaService<ExtendedPrismaClient>>
>(Services.Prisma).client;
});

describe("Is dependencies defined?", () => {
it("transactionController", () => {
expect(transactionController).toBeDefined();
});

it("transactionService", () => {
expect(transactionService).toBeDefined();
});

it("transactionRepository", () => {
expect(transactionRepository).toBeDefined();
});

it("userService", () => {
expect(userService).toBeDefined();
});

it("prismaMock", () => {
expect(prismaMock).toBeDefined();
});
});

it("should return the controller message", () => {
const expected = { message: "TransactionModule Controller" };

const result = transactionController.get();

expect(result).toStrictEqual(expected);
});

describe("/POST transaction", () => {
let cpfUser1: UserEntity;
let cpfUser2: UserEntity;
let cnpjUser1: UserEntity;
let cnpjUser2: UserEntity;

beforeEach(async () => {
const users = await transactionMockInput();

cpfUser1 = users.cpfUser1;
cpfUser2 = users.cpfUser2;
cnpjUser1 = users.cnpjUser1;
cnpjUser2 = users.cnpjUser2;
});

it("should create a transaction from CPF to CPF user", async () => {
prismaMock.user.findFirst.mockResolvedValue({
...cpfUser1,
id: 0,
password: "Mock",
});
const sender = await userService.findByPublicId(cpfUser1.publicId);
prismaMock.user.findFirst.mockResolvedValue({
...cpfUser2,
id: 1,
password: "Mock",
});
const receiver = await userService.findByPublicId(cpfUser2.publicId);

const data: TransactionDTO = {
senderDocument: sender.document,
receiverDocument: receiver.document,
value: 100,
};

const expected = {
id: "cd2df795-58e9-45a9-b018-31c77f74b47f",
senderId: sender.publicId,
receiverId: receiver.publicId,
timestamp: expect.any(Date),
value: 100,
};

prismaMock.transaction.create.mockResolvedValue({
id: "cd2df795-58e9-45a9-b018-31c77f74b47f",
senderId: sender.publicId,
receiverId: receiver.publicId,
timestamp: new Date(),
value: 100,
});
const transaction = await transactionController.create(data);

expect(expected).toStrictEqual(transaction);
expect(sender.money).toBe(0);
expect(receiver.money).toBe(200);
});

it("should create a transaction from CPF to CNPJ user", async () => {
prismaMock.user.findFirst.mockResolvedValue({
...cpfUser1,
id: 0,
password: "Mock",
});
const sender = await userService.findByPublicId(cpfUser1.publicId);
prismaMock.user.findFirst.mockResolvedValue({
...cnpjUser1,
id: 1,
password: "Mock",
});
const receiver = await userService.findByPublicId(cnpjUser1.publicId);

const data: TransactionDTO = {
senderDocument: sender.document,
receiverDocument: receiver.document,
value: 100,
};

const expected = {
id: "cd2df795-58e9-45a9-b018-31c77f74b47f",
senderId: sender.publicId,
receiverId: receiver.publicId,
timestamp: expect.any(Date),
value: 100,
};

prismaMock.transaction.create.mockResolvedValue({
id: "cd2df795-58e9-45a9-b018-31c77f74b47f",
senderId: sender.publicId,
receiverId: receiver.publicId,
timestamp: new Date(),
value: 100,
});
const transaction = await transactionController.create(data);

expect(expected).toStrictEqual(transaction);
expect(sender.money).toBe(0);
expect(receiver.money).toBe(200);
});

it("should not create a transaction from CNPJ to CNPJ user", async () => {
prismaMock.user.findFirst.mockResolvedValue({
...cpfUser1,
id: 0,
password: "Mock",
});
const sender = await userService.findByPublicId(cnpjUser1.publicId);
prismaMock.user.findFirst.mockResolvedValue({
...cnpjUser1,
id: 1,
password: "Mock",
});
const receiver = await userService.findByPublicId(cnpjUser2.publicId);

const data: TransactionDTO = {
senderDocument: sender.document,
receiverDocument: receiver.document,
value: 100,
};

try {
await transactionController.create(data);
} catch (error) {
expect(error).toBeInstanceOf(UnauthorizedError);
expect(error.message).toBe("CNPJ não pode enviar");
}
});

it("should not create a transaction from CNPJ to CPF user", async () => {
prismaMock.user.findFirst.mockResolvedValue({
...cpfUser1,
id: 0,
password: "Mock",
});
const sender = await userService.findByPublicId(cnpjUser1.publicId);
prismaMock.user.findFirst.mockResolvedValue({
...cnpjUser1,
id: 1,
password: "Mock",
});
const receiver = await userService.findByPublicId(cpfUser1.publicId);

const data: TransactionDTO = {
senderDocument: sender.document,
receiverDocument: receiver.document,
value: 100,
};

prismaMock.transaction.create.mockRejectedValue(
new UnauthorizedError("CNPJ não pode enviar"),
);
try {
await transactionController.create(data);
} catch (error) {
expect(error).toBeInstanceOf(UnauthorizedError);
expect(error.message).toBe("CNPJ não pode enviar");
}
});

it("should not create a transaction because user don't have the specified money amount", async () => {
prismaMock.user.findFirst.mockResolvedValue({
...cpfUser1,
id: 0,
password: "Mock",
});
const sender = await userService.findByPublicId(cpfUser1.publicId);
prismaMock.user.findFirst.mockResolvedValue({
...cpfUser2,
id: 1,
password: "Mock",
});
const receiver = await userService.findByPublicId(cpfUser2.publicId);

const data: TransactionDTO = {
senderDocument: sender.document,
receiverDocument: receiver.document,
value: 200,
};

prismaMock.transaction.create.mockRejectedValue(
new UnauthorizedError("Sender não tem dinheiro o suficiente"),
);
try {
await transactionController.create(data);
} catch (error) {
expect(error).toBeInstanceOf(UnauthorizedError);
expect(error.message).toBe("Sender não tem dinheiro o suficiente");
}
});

it("should not create a transaction because user cannot transfer to yourself", async () => {
prismaMock.user.findFirst.mockResolvedValue({
...cpfUser1,
id: 0,
password: "Mock",
});
const sender = await userService.findByPublicId(cpfUser1.publicId);
prismaMock.user.findFirst.mockResolvedValue({
...cpfUser1,
id: 1,
password: "Mock",
});
const receiver = await userService.findByPublicId(cpfUser1.publicId);

const data: TransactionDTO = {
senderDocument: sender.document,
receiverDocument: receiver.document,
value: 100,
};

prismaMock.transaction.create.mockRejectedValue(
new UnauthorizedError("Não é possível enviar para si mesmo"),
);
try {
await transactionController.create(data);
} catch (error) {
expect(error).toBeInstanceOf(UnauthorizedError);
expect(error.message).toBe("Não é possível enviar para si mesmo");
}
});
});
});

0 comments on commit 017e238

Please sign in to comment.