Skip to content

Commit 8e73418

Browse files
committed
feat: update product service test
1 parent 3d0babc commit 8e73418

File tree

2 files changed

+62
-51
lines changed

2 files changed

+62
-51
lines changed

src/lib/utils.tests.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ import { vi } from "vitest";
22

33
import type { Category } from "@/models/category.model";
44
import type { Order, OrderDetails, OrderItem } from "@/models/order.model";
5-
import type { Product } from "@/models/product.model";
5+
import type { ProductVariantValue } from "@/models/product.model";
66
import type { User } from "@/models/user.model";
77

88
import type {
99
OrderItem as PrismaOrderItem,
1010
Order as PrismaOrder,
1111
Product as PrismaProduct,
12+
VariantAttributeValue as PrismaVariantAttributeValue,
13+
1214
} from "@/../generated/prisma/client";
1315
import type { Session } from "react-router";
1416

@@ -53,38 +55,40 @@ export const createMockSession = (userId: number | null): Session => ({
5355
unset: vi.fn(),
5456
});
5557

56-
export const createTestProduct = (overrides?: Partial<Product>): Product => ({
58+
export const createTestDBProduct = (
59+
overrides?: Partial<PrismaProduct> & { variantAttributeValues?: PrismaVariantAttributeValue[] }
60+
): PrismaProduct & { variantAttributeValues: PrismaVariantAttributeValue[] } => ({
5761
id: 1,
5862
title: "Test Product",
5963
imgSrc: "/test-image.jpg",
6064
alt: "Test alt text",
61-
price: 100,
6265
description: "Test description",
6366
categoryId: 1,
6467
isOnSale: false,
6568
features: ["Feature 1", "Feature 2"],
6669
createdAt: new Date(),
6770
updatedAt: new Date(),
71+
variantAttributeValues: overrides?.variantAttributeValues ?? [createTestDBVariantAttributeValue()],
6872
...overrides,
6973
});
7074

71-
export const createTestDBProduct = (
72-
overrides?: Partial<PrismaProduct>
73-
): PrismaProduct => ({
75+
// --- FRONTEND PRODUCT ---
76+
export const createTestProduct = (overrides?: Partial<ProductVariantValue>): ProductVariantValue => ({
7477
id: 1,
7578
title: "Test Product",
7679
imgSrc: "/test-image.jpg",
7780
alt: "Test alt text",
78-
price: new Decimal(100),
7981
description: "Test description",
8082
categoryId: 1,
8183
isOnSale: false,
8284
features: ["Feature 1", "Feature 2"],
8385
createdAt: new Date(),
8486
updatedAt: new Date(),
87+
variantAttributeValues: [createTestDBVariantAttributeValue()],
8588
...overrides,
8689
});
8790

91+
8892
export const createTestCategory = (
8993
overrides?: Partial<Category>
9094
): Category => ({
@@ -99,6 +103,19 @@ export const createTestCategory = (
99103
...overrides,
100104
});
101105

106+
export const createTestDBVariantAttributeValue = (
107+
overrides?: Partial<PrismaVariantAttributeValue>
108+
): PrismaVariantAttributeValue => ({
109+
id: 1,
110+
attributeId: 1,
111+
productId: 1,
112+
value: "Default",
113+
price: new Decimal(100),
114+
createdAt: new Date(),
115+
updatedAt: new Date(),
116+
...overrides,
117+
});
118+
102119
export const createTestOrderDetails = (
103120
overrides: Partial<OrderDetails> = {}
104121
): OrderDetails => ({

src/services/product.service.test.ts

Lines changed: 38 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1-
import { beforeEach, describe, expect, it, vi } from "vitest";
1+
import { vi, describe, it, expect, beforeEach } from "vitest";
2+
23

34
import { prisma as mockPrisma } from "@/db/prisma";
4-
import { createTestCategory, createTestDBProduct } from "@/lib/utils.tests";
5-
import type { Category } from "@/models/category.model";
5+
import {
6+
createTestCategory,
7+
createTestDBProduct,
8+
createTestDBVariantAttributeValue,
9+
} from "@/lib/utils.tests";
610

711
import { getCategoryBySlug } from "./category.service";
8-
import { getProductById, getProductsByCategorySlug } from "./product.service";
12+
import { getProductsByCategorySlug, getProductById } from "./product.service";
13+
14+
import type { Category } from "generated/prisma/client";
915

10-
import type { Product as PrismaProduct } from "@/../generated/prisma/client";
16+
import { Decimal } from "@/../generated/prisma/internal/prismaNamespace";
1117

1218
vi.mock("@/db/prisma", () => ({
1319
prisma: {
@@ -18,7 +24,6 @@ vi.mock("@/db/prisma", () => ({
1824
},
1925
}));
2026

21-
// Mock category service
2227
vi.mock("./category.service");
2328

2429
describe("Product Service", () => {
@@ -27,93 +32,82 @@ describe("Product Service", () => {
2732
});
2833

2934
describe("getProductsByCategorySlug", () => {
30-
it("should return products for a valid category slug", async () => {
31-
// Step 1: Setup - Create test data with valid category and products
35+
it("should return products for a valid category slug with prices as numbers", async () => {
3236
const testCategory = createTestCategory();
33-
const mockedProducts: PrismaProduct[] = [
37+
38+
const mockedProducts = [
3439
createTestDBProduct({ id: 1, categoryId: testCategory.id }),
35-
createTestDBProduct({
36-
id: 2,
37-
title: "Test Product 2",
38-
categoryId: testCategory.id,
39-
}),
40+
createTestDBProduct({ id: 2, categoryId: testCategory.id }),
4041
];
4142

42-
// Step 2: Mock - Configure responses
4343
vi.mocked(getCategoryBySlug).mockResolvedValue(testCategory);
44-
4544
vi.mocked(mockPrisma.product.findMany).mockResolvedValue(mockedProducts);
4645

47-
// Step 3: Call service function
4846
const products = await getProductsByCategorySlug(testCategory.slug);
4947

50-
// Step 4: Verify expected behavior
5148
expect(getCategoryBySlug).toHaveBeenCalledWith(testCategory.slug);
5249
expect(mockPrisma.product.findMany).toHaveBeenCalledWith({
5350
where: { categoryId: testCategory.id },
51+
include: { variantAttributeValues: true },
5452
});
53+
54+
// Comprobamos que los precios se transforman a number
5555
expect(products).toEqual(
5656
mockedProducts.map((product) => ({
5757
...product,
58-
price: product.price.toNumber(),
58+
price: product.variantAttributeValues[0].price.toNumber(),
5959
}))
6060
);
6161
});
62-
6362
it("should throw error when category slug does not exist", async () => {
64-
// Step 1: Setup - Create test data for non-existent category
6563
const invalidSlug = "invalid-slug";
66-
67-
// Step 2: Mock - Configure error response
6864
const errorMessage = `Category with slug "${invalidSlug}" not found`;
69-
vi.mocked(getCategoryBySlug).mockRejectedValue(new Error(errorMessage));
7065

71-
// Step 3: Call service function
72-
const getProducts = getProductsByCategorySlug(
73-
invalidSlug as Category["slug"]
74-
);
66+
vi.mocked(getCategoryBySlug).mockRejectedValue(new Error(errorMessage));
7567

76-
// Step 4: Verify expected behavior
77-
await expect(getProducts).rejects.toThrow(errorMessage);
68+
await expect(getProductsByCategorySlug(invalidSlug as Category["slug"])).rejects.toThrow(errorMessage);
7869
expect(mockPrisma.product.findMany).not.toHaveBeenCalled();
7970
});
8071
});
8172

8273
describe("getProductById", () => {
83-
it("should return product for valid ID", async () => {
84-
// Step 1: Setup - Create test data for existing product
85-
const testProduct = createTestDBProduct();
74+
it("should return product for valid ID with prices as numbers", async () => {
75+
const testProduct = createTestDBProduct({
76+
id: 1,
77+
variantAttributeValues: [
78+
createTestDBVariantAttributeValue({ price: new Decimal(120) }),
79+
createTestDBVariantAttributeValue({ id: 2, price: new Decimal(150) }),
80+
],
81+
});
8682

87-
// Step 2: Mock - Configure Prisma response
8883
vi.mocked(mockPrisma.product.findUnique).mockResolvedValue(testProduct);
8984

90-
// Step 3: Call service function
9185
const result = await getProductById(testProduct.id);
9286

93-
// Step 4: Verify expected behavior
9487
expect(mockPrisma.product.findUnique).toHaveBeenCalledWith({
9588
where: { id: testProduct.id },
89+
include: { variantAttributeValues: { include: { variantAttribute: true } } },
9690
});
91+
92+
// Se espera que el producto devuelto tenga minPrice y maxPrice correctamente calculados
9793
expect(result).toEqual({
9894
...testProduct,
99-
price: testProduct.price.toNumber(),
95+
variantAttributeValues: testProduct.variantAttributeValues.map((v) => ({
96+
...v,
97+
price: v.price.toNumber(),
98+
})),
10099
});
101100
});
102101

103102
it("should throw error when product does not exist", async () => {
104-
// Step 1: Setup - Configure ID for non-existent product
105103
const nonExistentId = 999;
106104

107-
// Step 2: Mock - Configure null response from Prisma
108105
vi.mocked(mockPrisma.product.findUnique).mockResolvedValue(null);
109106

110-
// Step 3: Call service function
111-
const productPromise = getProductById(nonExistentId);
112-
113-
// Step 4: Verify expected behavior
114-
await expect(productPromise).rejects.toThrow("Product not found");
107+
await expect(getProductById(nonExistentId)).rejects.toThrow("Product not found");
115108
expect(mockPrisma.product.findUnique).toHaveBeenCalledWith({
116109
where: { id: nonExistentId },
110+
include: { variantAttributeValues: { include: { variantAttribute: true } } },
117111
});
118112
});
119113
});

0 commit comments

Comments
 (0)