describe('calculateDiscount', () => {
const newUser = { id: 'u1', createdAt: daysAgo(15) };
const oldUser = { id: 'u2', createdAt: daysAgo(365) };
const regularProduct = { id: 'p1', category: 'electronics', price: 100 };
const clearanceProduct = { id: 'p2', category: 'clearance', price: 50 };
describe('descuento básico', () => {
it('aplica el descuento mayor cuando hay varios disponibles', () => {
const discounts = [
{ type: 'coupon', value: 0.15 },
{ type: 'loyalty', value: 0.20 }
];
const result = calculateDiscount(oldUser, regularProduct, discounts);
expect(result.appliedDiscount).toBe(0.20);
expect(result.finalPrice).toBe(80);
});
it('no supera el tope del 30% incluso con descuento de usuario nuevo', () => {
const discounts = [{ type: 'coupon', value: 0.25 }];
const result = calculateDiscount(newUser, regularProduct, discounts);
expect(result.appliedDiscount).toBe(0.30);
expect(result.finalPrice).toBe(70);
});
});
describe('restricciones por categoría', () => {
it('devuelve precio original para productos clearance', () => {
const discounts = [{ type: 'coupon', value: 0.20 }];
const result = calculateDiscount(oldUser, clearanceProduct, discounts);
expect(result.appliedDiscount).toBe(0);
expect(result.finalPrice).toBe(50);
});
it('ignora el descuento de usuario nuevo en clearance', () => {
const result = calculateDiscount(newUser, clearanceProduct, []);
expect(result.appliedDiscount).toBe(0);
});
});
describe('inputs inválidos', () => {
it('lanza error con descuento negativo', () => {
const discounts = [{ type: 'coupon', value: -0.1 }];
expect(() => calculateDiscount(oldUser, regularProduct, discounts))
.toThrow(InvalidDiscountError);
});
it('lanza error si el producto es null', () => {
expect(() => calculateDiscount(oldUser, null, []))
.toThrow(ArgumentNullError);
});
it('retorna precio original si no hay descuentos aplicables', () => {
const result = calculateDiscount(oldUser, regularProduct, []);
expect(result.appliedDiscount).toBe(0);
expect(result.finalPrice).toBe(100);
});
});
});