From 04a6a74b4166466954fe10b4783149b9637002c6 Mon Sep 17 00:00:00 2001
From: Diego Torres
Date: Thu, 19 Jun 2025 20:25:22 -0500
Subject: [PATCH 1/3] feat: implement end-to-end test for order creation and
update order confirmation component
---
src/e2e/user-create-order.spec.ts | 57 +++++++++++++++++++++++++
src/routes/order-confirmation/index.tsx | 7 ++-
2 files changed, 63 insertions(+), 1 deletion(-)
create mode 100644 src/e2e/user-create-order.spec.ts
diff --git a/src/e2e/user-create-order.spec.ts b/src/e2e/user-create-order.spec.ts
new file mode 100644
index 0000000..8bd1454
--- /dev/null
+++ b/src/e2e/user-create-order.spec.ts
@@ -0,0 +1,57 @@
+import { test, expect } from "@playwright/test";
+
+test("User can create an order", async ({ page }) => {
+ await page.goto("http://localhost:5173/");
+
+ await page.getByRole("link", { name: "Iniciar sesión" }).click();
+
+ const loginForm = {
+ "Correo electrónico": "testino@mail.com",
+ Contraseña: "supersecret",
+ };
+
+ for (const [key, value] of Object.entries(loginForm)) {
+ const input = await page.getByRole("textbox", { name: key });
+ await input.click();
+ await input.fill(value);
+ }
+
+ await page.getByRole("button", { name: "Iniciar sesión" }).click();
+
+ // Wait for the user to be logged in
+ await expect(
+ page.getByRole("button", { name: "Cerrar sesión" })
+ ).toBeVisible();
+
+ await page.getByRole("menuitem", { name: "Polos" }).click();
+ await page.getByTestId("product-item").first().click();
+
+ await page.getByRole("button", { name: "Agregar al Carrito" }).click();
+ await page.getByRole("link", { name: "Carrito de compras" }).click();
+
+ await page.getByRole("link", { name: "Continuar Compra" }).click();
+
+ const orderForm = {
+ Nombre: "Testino",
+ Apellido: "Diprueba",
+ Compañia: "",
+ Dirección: "Calle De Prueba 123",
+ Ciudad: "Lima",
+ "Provincia/Estado": "Lima",
+ "Código Postal": "51111",
+ Teléfono: "987456321",
+ };
+
+ for (const [key, value] of Object.entries(orderForm)) {
+ const input = await page.getByRole("textbox", { name: key });
+ await input.click();
+ await input.fill(value);
+ }
+
+ await page.getByRole("combobox", { name: "País" }).selectOption("PE");
+
+ await page.getByRole("button", { name: "Confirmar Orden" }).click();
+
+ await expect(page.getByText("¡Muchas gracias por tu compra!")).toBeVisible();
+ await expect(page.getByTestId("orderId")).toBeVisible();
+});
diff --git a/src/routes/order-confirmation/index.tsx b/src/routes/order-confirmation/index.tsx
index fd01cd3..4ee3583 100644
--- a/src/routes/order-confirmation/index.tsx
+++ b/src/routes/order-confirmation/index.tsx
@@ -25,7 +25,12 @@ export default function OrderConfirmation({
Llegaremos a la puerta de tu domicilio lo antes posible
Código de seguimiento
- {orderId}
+
+ {orderId}
+
);
From 20ce53b126eac4bf1401b9d41d86b03091bd1b6b Mon Sep 17 00:00:00 2001
From: Diego Torres
Date: Thu, 19 Jun 2025 21:12:43 -0500
Subject: [PATCH 2/3] fix: add ON DELETE CASCADE to user_id reference in orders
table and enhance end-to-end test for order creation
---
src/db/migrations/initial.sql | 2 +-
src/e2e/user-create-order.spec.ts | 118 +++++++++++++++++++-----------
2 files changed, 78 insertions(+), 42 deletions(-)
diff --git a/src/db/migrations/initial.sql b/src/db/migrations/initial.sql
index 2d2bc31..0fe8b74 100644
--- a/src/db/migrations/initial.sql
+++ b/src/db/migrations/initial.sql
@@ -53,7 +53,7 @@ CREATE TABLE IF NOT EXISTS cart_items (
CREATE TABLE IF NOT EXISTS orders (
id SERIAL PRIMARY KEY,
- user_id INTEGER REFERENCES users(id),
+ user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
total_amount NUMERIC(10,2) NOT NULL,
-- Customer and shipping details
diff --git a/src/e2e/user-create-order.spec.ts b/src/e2e/user-create-order.spec.ts
index 8bd1454..20c4c55 100644
--- a/src/e2e/user-create-order.spec.ts
+++ b/src/e2e/user-create-order.spec.ts
@@ -1,57 +1,93 @@
import { test, expect } from "@playwright/test";
-test("User can create an order", async ({ page }) => {
- await page.goto("http://localhost:5173/");
+import { hashPassword } from "@/lib/security";
+import type { CreateUserDTO } from "@/models/user.model";
+import {
+ createUser,
+ deleteUser,
+ getUserByEmail,
+} from "@/repositories/user.repository";
- await page.getByRole("link", { name: "Iniciar sesión" }).click();
+test.describe("User", () => {
+ let testUserId: number;
- const loginForm = {
- "Correo electrónico": "testino@mail.com",
- Contraseña: "supersecret",
- };
+ test.beforeAll(async () => {
+ const testUser: CreateUserDTO = {
+ email: "diego@codeable.com",
+ name: null,
+ password: await hashPassword("letmein"),
+ isGuest: false,
+ };
- for (const [key, value] of Object.entries(loginForm)) {
- const input = await page.getByRole("textbox", { name: key });
- await input.click();
- await input.fill(value);
- }
+ const existingUser = await getUserByEmail(testUser.email);
- await page.getByRole("button", { name: "Iniciar sesión" }).click();
+ if (existingUser) {
+ await deleteUser(existingUser.id);
+ }
- // Wait for the user to be logged in
- await expect(
- page.getByRole("button", { name: "Cerrar sesión" })
- ).toBeVisible();
+ const user = await createUser(testUser);
+ testUserId = user.id;
+ });
- await page.getByRole("menuitem", { name: "Polos" }).click();
- await page.getByTestId("product-item").first().click();
+ test.afterAll(async () => {
+ await deleteUser(testUserId);
+ });
- await page.getByRole("button", { name: "Agregar al Carrito" }).click();
- await page.getByRole("link", { name: "Carrito de compras" }).click();
+ test("User can create an order", async ({ page }) => {
+ await page.goto("http://localhost:5173/");
- await page.getByRole("link", { name: "Continuar Compra" }).click();
+ await page.getByRole("link", { name: "Iniciar sesión" }).click();
- const orderForm = {
- Nombre: "Testino",
- Apellido: "Diprueba",
- Compañia: "",
- Dirección: "Calle De Prueba 123",
- Ciudad: "Lima",
- "Provincia/Estado": "Lima",
- "Código Postal": "51111",
- Teléfono: "987456321",
- };
+ const loginForm = {
+ "Correo electrónico": "diego@codeable.com",
+ Contraseña: "letmein",
+ };
- for (const [key, value] of Object.entries(orderForm)) {
- const input = await page.getByRole("textbox", { name: key });
- await input.click();
- await input.fill(value);
- }
+ for (const [key, value] of Object.entries(loginForm)) {
+ const input = await page.getByRole("textbox", { name: key });
+ await input.click();
+ await input.fill(value);
+ }
- await page.getByRole("combobox", { name: "País" }).selectOption("PE");
+ await page.getByRole("button", { name: "Iniciar sesión" }).click();
- await page.getByRole("button", { name: "Confirmar Orden" }).click();
+ // Wait for the user to be logged in
+ await expect(
+ page.getByRole("button", { name: "Cerrar sesión" })
+ ).toBeVisible();
- await expect(page.getByText("¡Muchas gracias por tu compra!")).toBeVisible();
- await expect(page.getByTestId("orderId")).toBeVisible();
+ await page.getByRole("menuitem", { name: "Polos" }).click();
+ await page.getByTestId("product-item").first().click();
+
+ await page.getByRole("button", { name: "Agregar al Carrito" }).click();
+ await page.getByRole("link", { name: "Carrito de compras" }).click();
+
+ await page.getByRole("link", { name: "Continuar Compra" }).click();
+
+ const orderForm = {
+ Nombre: "Testino",
+ Apellido: "Diprueba",
+ Compañia: "",
+ Dirección: "Calle De Prueba 123",
+ Ciudad: "Lima",
+ "Provincia/Estado": "Lima",
+ "Código Postal": "51111",
+ Teléfono: "987456321",
+ };
+
+ for (const [key, value] of Object.entries(orderForm)) {
+ const input = await page.getByRole("textbox", { name: key });
+ await input.click();
+ await input.fill(value);
+ }
+
+ await page.getByRole("combobox", { name: "País" }).selectOption("PE");
+
+ await page.getByRole("button", { name: "Confirmar Orden" }).click();
+
+ await expect(
+ page.getByText("¡Muchas gracias por tu compra!")
+ ).toBeVisible();
+ await expect(page.getByTestId("orderId")).toBeVisible();
+ });
});
From 41b0c9f5509cd9d482dff4ff591906bfabe28a5b Mon Sep 17 00:00:00 2001
From: Diego Torres
Date: Thu, 19 Jun 2025 21:15:30 -0500
Subject: [PATCH 3/3] chore: remove .env file and add it to .gitignore
---
.env | 12 ------------
.gitignore | 1 +
2 files changed, 1 insertion(+), 12 deletions(-)
delete mode 100644 .env
diff --git a/.env b/.env
deleted file mode 100644
index bc3c03d..0000000
--- a/.env
+++ /dev/null
@@ -1,12 +0,0 @@
-# Server
-NODE_ENV=development
-
-# Application Database
-DB_HOST=localhost
-DB_PORT=5432
-DB_NAME=fullstock
-DB_USER=diego
-DB_PASSWORD=
-
-# Admin Database (for database creation/deletion)
-ADMIN_DB_NAME=diego
diff --git a/.gitignore b/.gitignore
index 5175288..a1533a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,6 +27,7 @@ dist-ssr
.react-router/
.build/
+.env
# Playwright
/test-results/