import { startCase } from 'lodash'; import { getCustomRepository } from 'typeorm'; import { AggregateProduct, AggregateProductVariant, RawRetailerProduct, RetailerProduct, RetailerProductVariant, } from '@/entities'; import { RetailerProductSource } from '@/entities/types'; import { RetailerProductRepository } from '@/repositories'; import { RetailerProductVariantRepository } from '@/repositories/RetailerProductVariantRepository'; import { RetailerKind } from '@/types'; import * as algoliaUtils from '@/utils/algolia'; import RawRetailerProductRepository from '../RawRetailerProductRepository'; describe('RawRetailerProductRepository', () => { let repo: RawRetailerProductRepository; let productRepo: RetailerProductRepository; let retailerProductVariantRepo: RetailerProductVariantRepository; beforeEach(async () => { repo = getCustomRepository(RawRetailerProductRepository); productRepo = getCustomRepository(RetailerProductRepository); retailerProductVariantRepo = getCustomRepository( RetailerProductVariantRepository ); }); describe.each([ { url: 'https://www.amazon.com/Haussmann-Twist-Stool-High-Walnut/dp/B00KRY0SY2', expected: { retailer: RetailerKind.AMAZON, identifiers: ['amazonid:B00KRY0SY2'], variantIdentifiers: ['amazonid:B00KRY0SY2'], }, }, { url: 'https://www.allmodern.com/bedding/pdp/casper-sleep-element-mattress-a001045038.html?piid=1352782263', expected: { retailer: RetailerKind.ALL_MODERN, identifiers: ['all_modern-sku:a001045038'], variantIdentifiers: ['piid:1352782263'], }, }, { url: 'https://www.wayfair.com/furniture/pdp/mercury-row-osteen-40-h-x-36-w-steel-etagere-bookcase-w005504125.html?piid=330188248', expected: { retailer: RetailerKind.WAYFAIR, identifiers: ['wayfair-sku:w005504125'], variantIdentifiers: ['piid:330188248'], }, }, { url: 'https://www.luluandgeorgia.com/products/cylia-counter-stool?variant=39490236842083', expected: { retailer: RetailerKind.LULU_AND_GEORGIA, identifiers: ['lag:cylia-counter-stool'], variantIdentifiers: ['variant:39490236842083'], }, }, ])( 'should create RetailerProduct with correct data', ({ url, expected: { retailer, identifiers, variantIdentifiers } }) => { it(`should create a ${startCase( retailer.toLowerCase().replace('_', ' ').trim() )} retailer product from ${url} with correctly identified data`, async () => { const raw = await repo.createFromData({ data: { price: 100, annotations: 'annotations', colorCode: 'blue', description: 'Blue couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, name: 'Couch', url, category: 'couch', }, ingestionID: 'test12', }); expect(raw).toMatchObject({ retailer, rawData: { price: 100, annotations: 'annotations', colorCode: 'blue', description: 'Blue couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, name: 'Couch', url, category: 'couch', }, }); const product = await productRepo.findOneByIdentifiersOrFail({ identifiers, retailer, }); expect(product).toMatchObject({ identifiers: expect.arrayContaining(identifiers), price: 100, annotations: 'annotations', colorCode: 'blue', description: 'Blue couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, name: 'Couch', url, category: 'couch', }); const retailerProductVariant = await retailerProductVariantRepo.findOneByIdentifiersOrFail({ retailer, retailerProductId: product.id, identifiers: variantIdentifiers, }); expect(retailerProductVariant).toMatchObject({ identifiers: expect.arrayContaining(variantIdentifiers), price: 100, annotations: 'annotations', colorCode: 'blue', description: 'Blue couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, name: 'Couch', url, category: 'couch', }); }); } ); it('handles upserting data all the way up to aggregate product', async () => { const url = 'https://www.luluandgeorgia.com/products/cylia-counter-stool?variant=39490236842083'; const retailer = RetailerKind.LULU_AND_GEORGIA; const raw = await repo.createFromData({ data: { price: 100, annotations: 'annotations', colorCode: 'blue', description: 'Blue couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, name: 'Couch', url, }, ingestionID: 'test12', }); expect(raw).toMatchObject({ retailer, rawData: { price: 100, annotations: 'annotations', colorCode: 'blue', description: 'Blue couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, name: 'Couch', url, }, }); const aggregateProduct = await AggregateProduct.findOneOrFail(); expect(aggregateProduct).toEqual({ annotations: 'annotations', colorCode: 'blue', description: 'Blue couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, featured: false, name: 'Couch', asin: null, category: null, createdAt: expect.any(Date), deletedAt: null, discoverable: null, id: expect.any(String), identifiers: ['lag:cylia-counter-stool'], price: 100, updatedAt: expect.any(Date), }); const variant = await AggregateProductVariant.findOneOrFail(); expect(variant).toEqual({ annotations: 'annotations', colorCode: 'blue', description: 'Blue couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, featured: false, name: 'Couch', asin: null, category: null, createdAt: expect.any(Date), deletedAt: null, discoverable: null, id: expect.any(String), identifiers: ['ingestionid:test12', 'variant:39490236842083'], price: 100, productId: aggregateProduct.id, updatedAt: expect.any(Date), }); const retailerProduct = await RetailerProduct.findOneOrFail(); expect(retailerProduct).toEqual({ annotations: 'annotations', colorCode: 'blue', description: 'Blue couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, featured: false, name: 'Couch', asin: null, aggregateProductId: aggregateProduct.id, category: null, createdAt: expect.any(Date), deletedAt: null, discoverable: null, id: retailerProduct.id, identifiers: ['lag:cylia-counter-stool'], price: 100, retailer, source: RetailerProductSource.RETAILER_LULU_AND_GEORGIA, updatedAt: expect.any(Date), url, }); const retailerProductVariant = await RetailerProductVariant.findOneOrFail(); expect(retailerProductVariant).toEqual({ annotations: 'annotations', colorCode: 'blue', description: 'Blue couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, featured: false, name: 'Couch', asin: null, productId: retailerProduct.id, variantId: variant.id, category: null, createdAt: expect.any(Date), deletedAt: null, discoverable: null, id: expect.any(String), identifiers: ['ingestionid:test12', 'variant:39490236842083'], price: 100, retailer, source: RetailerProductSource.RETAILER_LULU_AND_GEORGIA, updatedAt: expect.any(Date), url, }); }); it('handles adding new variant', async () => { const spy = jest.spyOn(algoliaUtils, 'syncProductsToAlgolia'); // first variant await repo.createFromData({ data: { price: 100, annotations: 'annotations', colorCode: 'blue', description: 'Blue couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, featured: false, name: 'Couch', url: 'https://www.luluandgeorgia.com/products/cylia-counter-stool?variant=39490236842083', }, ingestionID: 'test12', }); // first variant duplicated await repo.createFromData({ data: { price: 100, annotations: 'annotations', colorCode: 'blue', description: 'Blue couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, featured: false, name: 'Couch', url: 'https://www.luluandgeorgia.com/products/cylia-counter-stool?variant=39490236842083', }, ingestionID: 'test12', }); // second variant await repo.createFromData({ data: { price: 100, annotations: 'annotations', colorCode: 'green', description: 'Green couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, name: 'Couch', url: 'https://www.luluandgeorgia.com/products/cylia-counter-stool?variant=39490236842083555', }, ingestionID: 'test123', }); // make sure counts are consistent expect(await RawRetailerProduct.count()).toBe(3); expect(await RetailerProductVariant.count()).toBe(2); expect(await RetailerProduct.count()).toBe(1); expect(await AggregateProductVariant.count()).toBe(2); expect(await AggregateProduct.count()).toBe(1); const retailerProductVariants = await RetailerProductVariant.find(); expect(retailerProductVariants).toContainEqual({ annotations: 'annotations', colorCode: 'blue', description: 'Blue couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, featured: false, name: 'Couch', asin: null, productId: expect.any(String), variantId: expect.any(String), category: null, createdAt: expect.any(Date), deletedAt: null, discoverable: null, id: expect.any(String), identifiers: ['ingestionid:test12', 'variant:39490236842083'], price: 100, retailer: RetailerKind.LULU_AND_GEORGIA, source: RetailerProductSource.RETAILER_LULU_AND_GEORGIA, updatedAt: expect.any(Date), url: 'https://www.luluandgeorgia.com/products/cylia-counter-stool?variant=39490236842083', }); expect(retailerProductVariants).toContainEqual({ annotations: 'annotations', colorCode: 'green', description: 'Green couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, name: 'Couch', featured: false, asin: null, productId: expect.any(String), variantId: expect.any(String), category: null, createdAt: expect.any(Date), deletedAt: null, discoverable: null, id: expect.any(String), identifiers: ['ingestionid:test123', 'variant:39490236842083555'], price: 100, retailer: RetailerKind.LULU_AND_GEORGIA, source: RetailerProductSource.RETAILER_LULU_AND_GEORGIA, updatedAt: expect.any(Date), url: 'https://www.luluandgeorgia.com/products/cylia-counter-stool?variant=39490236842083555', }); const retailerProducts = await RetailerProduct.find(); expect(retailerProducts).toContainEqual({ annotations: 'annotations', colorCode: 'green', description: 'Green couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, name: 'Couch', asin: null, featured: false, aggregateProductId: expect.any(String), category: null, createdAt: expect.any(Date), deletedAt: null, discoverable: null, id: expect.any(String), identifiers: ['lag:cylia-counter-stool'], price: 100, retailer: RetailerKind.LULU_AND_GEORGIA, source: RetailerProductSource.RETAILER_LULU_AND_GEORGIA, updatedAt: expect.any(Date), url: 'https://www.luluandgeorgia.com/products/cylia-counter-stool?variant=39490236842083555', }); const aggregateProductVariants = await AggregateProductVariant.find(); expect(aggregateProductVariants).toContainEqual({ annotations: 'annotations', colorCode: 'blue', description: 'Blue couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', featured: false, imageUrls: [], isAvailable: true, name: 'Couch', asin: null, category: null, createdAt: expect.any(Date), deletedAt: null, discoverable: null, id: expect.any(String), identifiers: ['ingestionid:test12', 'variant:39490236842083'], price: 100, productId: expect.any(String), updatedAt: expect.any(Date), }); expect(aggregateProductVariants).toContainEqual({ annotations: 'annotations', colorCode: 'green', description: 'Green couch', dimensions: '100"x100"', distributor: 'CostCo', distributorSKU: '1290-12', imageUrls: [], isAvailable: true, name: 'Couch', asin: null, featured: false, category: null, createdAt: expect.any(Date), deletedAt: null, discoverable: null, id: expect.any(String), identifiers: ['ingestionid:test123', 'variant:39490236842083555'], price: 100, productId: expect.any(String), updatedAt: expect.any(Date), }); const aggregateProducts = await AggregateProduct.find(); expect(aggregateProducts[0]).toEqual({ annotations: 'annotations', asin: null, category: null, colorCode: 'green', createdAt: expect.any(Date), deletedAt: null, description: 'Green couch', dimensions: '100"x100"', featured: false, discoverable: null, distributor: 'CostCo', distributorSKU: '1290-12', id: expect.any(String), identifiers: ['lag:cylia-counter-stool'], imageUrls: [], isAvailable: true, name: 'Couch', price: 100, updatedAt: expect.any(Date), }); expect(spy).toHaveBeenCalledTimes(3); expect(spy).toHaveBeenNthCalledWith(1, [aggregateProducts[0].id]); expect(spy).toHaveBeenNthCalledWith(2, [aggregateProducts[0].id]); expect(spy).toHaveBeenNthCalledWith(3, [aggregateProducts[0].id]); spy.mockClear(); }); });