mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 14:38:12 +00:00
195 lines
5.5 KiB
TypeScript
195 lines
5.5 KiB
TypeScript
import { Test, TestingModule } from "@nestjs/testing";
|
|
import { INestApplication, ValidationPipe } from "@nestjs/common";
|
|
import request from "supertest";
|
|
import { AppModule } from "../../app.module";
|
|
import { PrismaService } from "../../common/prisma.service";
|
|
|
|
describe("Payments E2E", () => {
|
|
let app: INestApplication;
|
|
let prisma: PrismaService;
|
|
let authToken: string;
|
|
let bookingId: string;
|
|
|
|
beforeAll(async () => {
|
|
const moduleFixture: TestingModule = await Test.createTestingModule({
|
|
imports: [AppModule],
|
|
}).compile();
|
|
|
|
app = moduleFixture.createNestApplication();
|
|
app.useGlobalPipes(
|
|
new ValidationPipe({ transform: true, whitelist: true }),
|
|
);
|
|
await app.init();
|
|
|
|
prisma = app.get<PrismaService>(PrismaService);
|
|
|
|
const passenger = await prisma.passenger.create({ data: { iamUserId: 'test-iam-payments-user' } });
|
|
|
|
await prisma.walletAccount.create({
|
|
data: {
|
|
passengerId: passenger.id,
|
|
balanceMinor: 100000,
|
|
currency: "ETB",
|
|
},
|
|
});
|
|
|
|
authToken = "mock-jwt-token";
|
|
|
|
const station1 = await prisma.station.create({
|
|
data: {
|
|
code: "TST1",
|
|
name: "Test Station 1",
|
|
city: "Test City",
|
|
lat: 9.0,
|
|
lng: 38.0,
|
|
},
|
|
});
|
|
const station2 = await prisma.station.create({
|
|
data: {
|
|
code: "TST2",
|
|
name: "Test Station 2",
|
|
city: "Test City 2",
|
|
lat: 9.5,
|
|
lng: 38.5,
|
|
},
|
|
});
|
|
|
|
const train = await prisma.train.create({
|
|
data: { number: "TEST-001", name: "Test Train" },
|
|
});
|
|
|
|
const schedule = await prisma.trainSchedule.create({
|
|
data: {
|
|
trainId: train.id,
|
|
originStationId: station1.id,
|
|
destinationStationId: station2.id,
|
|
departureAt: new Date(Date.now() + 86400000),
|
|
arrivalAt: new Date(Date.now() + 90000000),
|
|
durationMinutes: 60,
|
|
},
|
|
});
|
|
|
|
const coachType = await prisma.coachType.create({
|
|
data: { name: "Standard", code: "STD" },
|
|
});
|
|
|
|
const seatClass = await prisma.seatClass.create({
|
|
data: {
|
|
name: "Economy Regular",
|
|
description: "Standard economy seating",
|
|
baseFareMinor: 45000,
|
|
isActive: true,
|
|
coachTypeId: coachType.id,
|
|
},
|
|
});
|
|
|
|
const coach = await prisma.coach.create({
|
|
data: {
|
|
coachTypeId: coachType.id,
|
|
number: "TEST-C1",
|
|
arrangement: "2+2",
|
|
capacity: 10,
|
|
status: "ACTIVE",
|
|
},
|
|
});
|
|
|
|
const seat = await prisma.seat.create({
|
|
data: {
|
|
coachId: coach.id,
|
|
row: 1,
|
|
col: "A",
|
|
seatNumber: "1A",
|
|
status: "AVAILABLE",
|
|
},
|
|
});
|
|
|
|
const booking = await prisma.booking.create({
|
|
data: {
|
|
bookingRef: "TEST-BOOK-001",
|
|
passengerId: passenger.id,
|
|
scheduleId: schedule.id,
|
|
status: "PENDING_PAYMENT",
|
|
totalMinor: 50000,
|
|
currency: "ETB",
|
|
},
|
|
});
|
|
|
|
await prisma.bookingSeat.create({
|
|
data: {
|
|
bookingId: booking.id,
|
|
seatId: seat.id,
|
|
scheduleId: schedule.id,
|
|
passengerName: "Test Passenger",
|
|
},
|
|
});
|
|
|
|
bookingId = booking.id;
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await prisma.$transaction([
|
|
prisma.bookingSeat.deleteMany(),
|
|
prisma.paymentIntent.deleteMany(),
|
|
prisma.booking.deleteMany(),
|
|
prisma.coachAssignment.deleteMany(),
|
|
prisma.seat.deleteMany(),
|
|
prisma.coach.deleteMany(),
|
|
prisma.trainSchedule.deleteMany(),
|
|
prisma.train.deleteMany(),
|
|
prisma.station.deleteMany({ where: { code: { in: ["TST1", "TST2"] } } }),
|
|
prisma.walletLedgerEntry.deleteMany(),
|
|
prisma.walletAccount.deleteMany(),
|
|
prisma.passenger.deleteMany(),
|
|
]);
|
|
await app.close();
|
|
});
|
|
|
|
describe("POST /payments/initiate", () => {
|
|
it("should initiate wallet payment successfully", async () => {
|
|
const response = await request(app.getHttpServer())
|
|
.post("/payments/initiate")
|
|
.set("Authorization", `Bearer ${authToken}`)
|
|
.send({ bookingId, method: "WALLET" })
|
|
.expect(201);
|
|
expect(response.body.intentId).toBeDefined();
|
|
expect(response.body.status).toBe("SUCCEEDED");
|
|
});
|
|
|
|
it("should return 400 for invalid payment method", async () => {
|
|
await request(app.getHttpServer())
|
|
.post("/payments/initiate")
|
|
.set("Authorization", `Bearer ${authToken}`)
|
|
.send({ bookingId, method: "INVALID_METHOD" })
|
|
.expect(400);
|
|
});
|
|
|
|
it("should return 404 for non-existent booking", async () => {
|
|
await request(app.getHttpServer())
|
|
.post("/payments/initiate")
|
|
.set("Authorization", `Bearer ${authToken}`)
|
|
.send({ bookingId: "non-existent-id", method: "WALLET" })
|
|
.expect(404);
|
|
});
|
|
});
|
|
|
|
describe("GET /payments/intents/:bookingId", () => {
|
|
it("should get payment intent status", async () => {
|
|
const response = await request(app.getHttpServer())
|
|
.get(`/payments/intents/${bookingId}`)
|
|
.set("Authorization", `Bearer ${authToken}`)
|
|
.expect(200);
|
|
expect(response.body.intentId).toBeDefined();
|
|
expect(response.body.status).toBeDefined();
|
|
});
|
|
|
|
it("should return 404 for non-existent intent", async () => {
|
|
await request(app.getHttpServer())
|
|
.get("/payments/intents/non-existent-booking")
|
|
.set("Authorization", `Bearer ${authToken}`)
|
|
.expect(404);
|
|
});
|
|
});
|
|
|
|
// Provider webhooks moved to the payment microservice (apps/edr-payment-api /webhooks/*).
|
|
});
|