test(catalog): cover global availability behavior
This commit is contained in:
59
src/app/core/services/catalog/catalog-availability.spec.ts
Normal file
59
src/app/core/services/catalog/catalog-availability.spec.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
|
import { CatalogAvailability } from './catalog.interface';
|
||||||
|
import {
|
||||||
|
allowsCatalogAction,
|
||||||
|
combineCatalogAvailability,
|
||||||
|
createCatalogAvailability,
|
||||||
|
maximumCatalogQuantity,
|
||||||
|
} from './catalog-availability';
|
||||||
|
|
||||||
|
describe('catalog availability', () => {
|
||||||
|
it('represents hidden items without irrelevant actions or quantities', () => {
|
||||||
|
const availability = createCatalogAvailability(0);
|
||||||
|
|
||||||
|
expect(availability).toEqual({
|
||||||
|
state: 'hidden',
|
||||||
|
reasons: [
|
||||||
|
{
|
||||||
|
code: 'out_of_stock',
|
||||||
|
message: 'Este producto no tiene stock disponible.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
expect(allowsCatalogAction(availability, 'buy_now')).toBe(false);
|
||||||
|
expect(maximumCatalogQuantity(availability)).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('intersects product and variant actions and quantities', () => {
|
||||||
|
const product: CatalogAvailability = {
|
||||||
|
state: 'visible',
|
||||||
|
maximum_quantity: 3,
|
||||||
|
allowed_actions: ['select_variant', 'change_quantity'],
|
||||||
|
reasons: [{ code: 'limited', message: 'Corregí la selección.' }],
|
||||||
|
};
|
||||||
|
const variant: CatalogAvailability = {
|
||||||
|
state: 'visible',
|
||||||
|
maximum_quantity: 2,
|
||||||
|
allowed_actions: ['change_quantity', 'add_to_cart'],
|
||||||
|
reasons: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(combineCatalogAvailability(product, variant)).toEqual({
|
||||||
|
state: 'visible',
|
||||||
|
maximum_quantity: 2,
|
||||||
|
allowed_actions: ['change_quantity'],
|
||||||
|
reasons: [{ code: 'limited', message: 'Corregí la selección.' }],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('lets a hidden decision win composition', () => {
|
||||||
|
const availability = combineCatalogAvailability(
|
||||||
|
createCatalogAvailability(5),
|
||||||
|
createCatalogAvailability(0),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(availability.state).toBe('hidden');
|
||||||
|
expect(allowsCatalogAction(availability, 'add_to_cart')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -193,6 +193,21 @@ describe('ProductDetailPageComponent', () => {
|
|||||||
expect(fixture.componentInstance['selectedVariantMax']()).toBe(4);
|
expect(fixture.componentInstance['selectedVariantMax']()).toBe(4);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('stops presenting a product that becomes hidden during an availability refresh', async () => {
|
||||||
|
catalogServiceStub.getCatalogItem.mockReturnValue(
|
||||||
|
throwError(() => new HttpErrorResponse({ status: 404 })),
|
||||||
|
);
|
||||||
|
await configureTestingModule();
|
||||||
|
const fixture = TestBed.createComponent(ProductDetailPageComponent);
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
TestBed.inject(CatalogAvailabilityService).notifyAvailabilityChanged();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(fixture.componentInstance['product']()).toBeNull();
|
||||||
|
expect(fixture.nativeElement.textContent).toContain('Este producto ya no está disponible.');
|
||||||
|
});
|
||||||
|
|
||||||
it('shows error message if the resolver cannot load the product', async () => {
|
it('shows error message if the resolver cannot load the product', async () => {
|
||||||
resolveProductError(PRODUCT_DETAIL_ERROR_MESSAGE);
|
resolveProductError(PRODUCT_DETAIL_ERROR_MESSAGE);
|
||||||
await configureTestingModule();
|
await configureTestingModule();
|
||||||
|
|||||||
@@ -59,6 +59,20 @@ describe('ProductListComponent', () => {
|
|||||||
) {
|
) {
|
||||||
const getVariantOptions = vi.fn().mockReturnValue(
|
const getVariantOptions = vi.fn().mockReturnValue(
|
||||||
of({
|
of({
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
id: 401,
|
||||||
|
precio: '10000.00',
|
||||||
|
availability: createCatalogAvailability(1),
|
||||||
|
values: { tipo: '1', sector: '2', fila: '3', asiento: '4' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 402,
|
||||||
|
precio: '12000.00',
|
||||||
|
availability: createCatalogAvailability(1),
|
||||||
|
values: { tipo: '1', sector: '2', fila: '3', asiento: '5' },
|
||||||
|
},
|
||||||
|
],
|
||||||
selectors: ['tipo', 'sector', 'fila', 'asiento'].map((key, index) => ({
|
selectors: ['tipo', 'sector', 'fila', 'asiento'].map((key, index) => ({
|
||||||
key,
|
key,
|
||||||
label: key,
|
label: key,
|
||||||
@@ -76,7 +90,12 @@ describe('ProductListComponent', () => {
|
|||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
imports: [ProductListComponent],
|
imports: [ProductListComponent],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: CatalogService, useValue: { getVariantOptions } },
|
{
|
||||||
|
provide: CatalogService,
|
||||||
|
useValue: {
|
||||||
|
withoutLoading: () => ({ getVariantOptions }),
|
||||||
|
},
|
||||||
|
},
|
||||||
{ provide: CartService, useValue: {} },
|
{ provide: CartService, useValue: {} },
|
||||||
],
|
],
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
|
|||||||
@@ -59,21 +59,15 @@ describe('ProductVerticalWithCartCardComponent', () => {
|
|||||||
it('shows the backend availability message with the reusable tooltip', async () => {
|
it('shows the backend availability message with the reusable tooltip', async () => {
|
||||||
const fixture = await createComponent();
|
const fixture = await createComponent();
|
||||||
fixture.componentRef.setInput('availability', {
|
fixture.componentRef.setInput('availability', {
|
||||||
subject: 'product',
|
state: 'visible',
|
||||||
maximum_quantity: 0,
|
maximum_quantity: 0,
|
||||||
restrictions: [
|
reasons: [
|
||||||
{
|
{
|
||||||
code: 'user_quota_reached',
|
code: 'user_quota_reached',
|
||||||
message: 'Alcanzaste el cupo máximo permitido para este producto.',
|
message: 'Alcanzaste el cupo máximo permitido para este producto.',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
capabilities: {
|
allowed_actions: [],
|
||||||
display: true,
|
|
||||||
select_variant: false,
|
|
||||||
change_quantity: false,
|
|
||||||
add_to_cart: false,
|
|
||||||
buy_now: false,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ describe('VariantSelectorComponent', () => {
|
|||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
values: { talle: 'M' },
|
values: { talle: 'M' },
|
||||||
availability: { capabilities: { display: true, select_variant: false } },
|
availability: { state: 'visible', maximum_quantity: 0, allowed_actions: [], reasons: [] },
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|||||||
Reference in New Issue
Block a user