feat(sync): synchronize Hiboutik data through POST /sync
POST /sync starts the full synchronization in the background (202, or 409 when one is already running). Entities are synced in dependency order: brands, categories, suppliers, products (with versions and stocks), customers. Each row is synced independently so that a failure is logged without stopping the rest. Replaces the default AppService.
This commit is contained in:
51
src/services/hiboutik/customer.hiboutik.service.spec.ts
Normal file
51
src/services/hiboutik/customer.hiboutik.service.spec.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { CustomerHiboutikService } from './customer.hiboutik.service';
|
||||
|
||||
describe('CustomerHiboutikService', () => {
|
||||
const customerHiboutikRepository = { getCustomers: jest.fn(), getCustomerById: jest.fn() };
|
||||
const customerDatabaseRepository = { upsert: jest.fn(), deleteMissing: jest.fn() };
|
||||
const customerConverter = { fromHiboutik: jest.fn() };
|
||||
let service: CustomerHiboutikService;
|
||||
|
||||
beforeAll(() => {
|
||||
jest.spyOn(Logger.prototype, 'log').mockImplementation(() => undefined);
|
||||
jest.spyOn(Logger.prototype, 'warn').mockImplementation(() => undefined);
|
||||
jest.spyOn(Logger.prototype, 'error').mockImplementation(() => undefined);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
customerHiboutikRepository.getCustomers.mockResolvedValue([]);
|
||||
customerHiboutikRepository.getCustomerById.mockResolvedValue({});
|
||||
customerDatabaseRepository.deleteMissing.mockResolvedValue(0);
|
||||
service = new CustomerHiboutikService(
|
||||
customerHiboutikRepository as never,
|
||||
customerDatabaseRepository as never,
|
||||
customerConverter as never,
|
||||
);
|
||||
});
|
||||
|
||||
it('deletes customers missing from Hiboutik', async () => {
|
||||
customerHiboutikRepository.getCustomers.mockResolvedValue([{ customers_id: 1 }, { customers_id: '2' }]);
|
||||
|
||||
await service.syncCustomers();
|
||||
|
||||
expect(customerDatabaseRepository.deleteMissing).toHaveBeenCalledWith([1, 2]);
|
||||
expect(customerDatabaseRepository.upsert).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('does not delete customers when Hiboutik returns none', async () => {
|
||||
await service.syncCustomers();
|
||||
|
||||
expect(customerDatabaseRepository.deleteMissing).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('keeps syncing the other customers when one fails', async () => {
|
||||
customerHiboutikRepository.getCustomers.mockResolvedValue([{ customers_id: 1 }, { customers_id: 2 }]);
|
||||
customerHiboutikRepository.getCustomerById.mockRejectedValueOnce(new Error('boom'));
|
||||
|
||||
await expect(service.syncCustomers()).resolves.toBeUndefined();
|
||||
|
||||
expect(customerDatabaseRepository.upsert).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user