import assert from 'assert'; import { randomUUID } from 'crypto'; import * as producer from '@spokenio/jobqueue-producer'; import { range } from 'lodash'; import request from 'supertest'; import { Product } from '@/entities'; import app from '..'; const createProduct = async (values = {}) => { return await Product.create({ firebaseId: randomUUID(), googleShoppingIDs: ['7717270608456740797'], ...values, }).save(); }; /** * Waits until `fn` does not throw. Tries every 50ms. */ const waitFor = async (fn: () => void | Promise) => { return new Promise((resolve) => { const interval = setInterval(() => { Promise.resolve(fn()) .then(() => { clearInterval(interval); resolve(); }) .catch(() => { // no-op }); }, 50); }); }; describe('PUT /update', () => { it('should not add jobs for products', async () => { // create 5 products await Promise.all( range(5).map(() => { return createProduct(); }) ); const response = await request(app()).put('/update'); expect(response.status).toBe(200); expect(response.body.status).toBe('queued'); }); it('should add jobs for products that were created a while ago', async () => { // create 5 products await Promise.all( range(5).map(() => { return createProduct({ // last scraped a year ago lastScrapedAt: new Date( new Date().getTime() - 1000 * 60 * 60 * 24 * 365 ), }); }) ); const addJobSpy = jest.spyOn(producer, 'addJob'); const response = await request(app()).put('/update'); expect(response.status).toBe(200); expect(response.body.status).toBe('queued'); await waitFor(() => { // job added expect(addJobSpy.mock.calls[0][0]).toMatchInlineSnapshot( `"UPDATE_GOOGLE_SHOPPING_OFFERS_PRICE_1"` ); assert(addJobSpy.mock.calls[0][1]); assert('googleShoppingIDs' in addJobSpy.mock.calls[0][1]); expect(addJobSpy.mock.calls[0][1]?.googleShoppingIDs).toHaveLength(1); expect(addJobSpy.mock.calls[0][1]?.googleShoppingIDs?.[0]).toBe( '7717270608456740797' ); }); }); it('should add jobs for all products if force updating', async () => { // create 5 products await Promise.all( range(5).map(() => { return createProduct(); }) ); const addJobSpy = jest.spyOn(producer, 'addJob'); const response = await request(app()).put('/update?force=1'); expect(response.status).toBe(200); expect(response.body.status).toBe('queued'); await waitFor(() => { // job added expect(addJobSpy.mock.calls[0][0]).toMatchInlineSnapshot( `"UPDATE_GOOGLE_SHOPPING_OFFERS_PRICE_1"` ); // job payload assert(addJobSpy.mock.calls[0][1]); assert('googleShoppingIDs' in addJobSpy.mock.calls[0][1]); expect(addJobSpy.mock.calls[0][1]?.googleShoppingIDs).toHaveLength(1); expect(addJobSpy.mock.calls[0][1]?.googleShoppingIDs?.[0]).toBe( '7717270608456740797' ); }); }); });