import { getCustomRepository } from 'typeorm'; import { AggregateProduct } from '@/entities'; import AggregateProductRepository from '../AggregateProductRepository'; describe('AggregateProductRepository', () => { let repo: AggregateProductRepository; beforeEach(async () => { repo = getCustomRepository(AggregateProductRepository); }); describe('CRUD', () => { it('should be able to create new populated aggregate product', async () => { const { aggregateProductId } = await repo.upsert({ identifiers: ['test'], data: { asin: 'asin', colorCode: 'colorCode', annotations: 'annotation', price: 100, description: 'description', dimensions: 'dimensions', discoverable: true, distributor: 'distributor', distributorSKU: 'distributor', imageUrls: ['http://test.com/test.jpg'], isAvailable: true, name: 'test', }, }); const aggregateProduct = await AggregateProduct.findOneOrFail( aggregateProductId ); expect(aggregateProduct).toMatchObject({ id: expect.any(String), identifiers: ['test'], asin: 'asin', colorCode: 'colorCode', annotations: 'annotation', price: 100, description: 'description', dimensions: 'dimensions', discoverable: true, distributor: 'distributor', distributorSKU: 'distributor', imageUrls: ['http://test.com/test.jpg'], isAvailable: true, name: 'test', }); }); it('should be able to create a sparse aggregate product', async () => { const { aggregateProductId } = await repo.upsert({ identifiers: ['test'], data: { price: 100, description: 'description', name: 'test', }, }); const aggregateProduct = await AggregateProduct.findOneOrFail( aggregateProductId ); expect(aggregateProduct).toMatchObject({ id: expect.any(String), price: 100, description: 'description', name: 'test', }); }); it('should not be able to create products without identifiers', async () => { await expect( repo.upsert({ identifiers: [], data: { price: 100, description: 'description', name: 'test', }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( `"Must provide at least one identifier"` ); }); it('should not be able to create products with mis-formed identifiers', async () => { await expect( repo.upsert({ identifiers: [''], data: { price: 100, description: 'description', name: 'test', }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( `" is not a valid identifier"` ); }); it('should be able to update products with the same identifier', async () => { const id = 'test'; const { aggregateProductId } = await repo.upsert({ identifiers: [id], data: { price: 100, description: 'description', name: 'test', }, }); const aggregateProduct = await AggregateProduct.findOneOrFail( aggregateProductId ); expect(aggregateProduct.description).toBe('description'); await repo.upsert({ identifiers: [id], data: { description: 'updated description', }, }); const updatedAggregateProduct = await AggregateProduct.findOneOrFail( aggregateProductId ); expect(updatedAggregateProduct.description).toBe('updated description'); }); }); describe('identifier resolution', () => { it('should be able to find products by single identifier', async () => { const id = 'test'; const { aggregateProductId } = await repo.upsert({ identifiers: [id], data: { price: 100, description: 'description', name: 'test', }, }); expect((await repo.findOneByIdentifiers({ identifiers: [id] }))?.id).toBe( aggregateProductId ); }); it('should be able to find products with multiple identifiers with all identifiers', async () => { const identifiers = ['test1', 'test2']; await repo.upsert({ identifiers, data: { price: 100, description: 'description', name: 'test', }, }); expect(await repo.findOneByIdentifiers({ identifiers })).toMatchObject({ id: expect.any(String), identifiers, price: 100, description: 'description', name: 'test', }); }); it('should be able to find products if there are multiple identifiers by a single identifier', async () => { const identifiers = ['test1', 'test2']; const { aggregateProductId } = await repo.upsert({ identifiers, data: { price: 100, description: 'description', name: 'test', }, }); expect( (await repo.findOneByIdentifiers({ identifiers: ['test1'] }))?.id ).toBe(aggregateProductId); }); it('should not find products with different identifier', async () => { const identifiers = ['test1', 'test2']; await repo.upsert({ identifiers, data: { price: 100, description: 'description', name: 'test', }, }); expect(await repo.findOneByIdentifiers({ identifiers: ['test3'] })).toBe( undefined ); }); it('upsert with a single matching identifier is able to add additional identifiers', async () => { const identifiers = ['test1', 'test2']; await repo.upsert({ identifiers, data: { price: 100, description: 'description', name: 'test', }, }); await repo.upsert({ identifiers: [...identifiers, 'test3'], data: {}, }); expect(await repo.findOneByIdentifiers({ identifiers })).toMatchObject({ identifiers: expect.arrayContaining([...identifiers, 'test3']), }); }); }); });