feat(sync): add company details to customer addresses

Addresses with a company are completed through
GET /customers_addresses/:id (tax number, company number, legal status),
which the customer payload does not embed. Addresses without company get
these fields set to null; a failed call keeps the stored values.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MastersGame
2026-11-07 10:48:49 +01:00
parent 9e6e5162ad
commit ad8e39f63c
7 changed files with 172 additions and 23 deletions

View File

@@ -2,7 +2,7 @@ import { Logger } from '@nestjs/common';
import { CustomerHiboutikService } from './customer.hiboutik.service';
describe('CustomerHiboutikService', () => {
const customerHiboutikRepository = { getCustomers: jest.fn(), getCustomerById: jest.fn() };
const customerHiboutikRepository = { getCustomers: jest.fn(), getCustomerById: jest.fn(), getAddressById: jest.fn() };
const customerDatabaseRepository = { upsert: jest.fn(), deleteMissing: jest.fn() };
const customerConverter = { fromHiboutik: jest.fn() };
const customerAddressDatabaseRepository = { upsert: jest.fn(), deleteMissing: jest.fn() };
@@ -95,6 +95,47 @@ describe('CustomerHiboutikService', () => {
expect(customerAddressDatabaseRepository.upsert).not.toHaveBeenCalled();
});
it('fetches the company details of addresses with a company only', async () => {
customerHiboutikRepository.getCustomerById.mockResolvedValue({
customers_id: 1,
addresses: [
{ address_id: 10, company: 'ACME' },
{ address_id: 11, company: ' ' },
],
});
customerHiboutikRepository.getAddressById.mockResolvedValue({
address_id: 10,
tax_number: 'FR123',
company_number: '123',
legal_status: 'SAS',
updated_at: '2026-11-01 10:00:00',
});
await service.syncCustomers();
expect(customerHiboutikRepository.getAddressById).toHaveBeenCalledTimes(1);
expect(customerHiboutikRepository.getAddressById).toHaveBeenCalledWith(10);
expect(customerAddressConverter.fromHiboutik).toHaveBeenCalledWith({
address_id: 10,
company: 'ACME',
customers_id: 1,
tax_number: 'FR123',
company_number: '123',
legal_status: 'SAS',
updated_at: '2026-11-01 10:00:00',
});
});
it('still syncs an address whose company details cannot be fetched', async () => {
customerHiboutikRepository.getCustomerById.mockResolvedValue({ customers_id: 1, addresses: [{ address_id: 10, company: 'ACME' }] });
customerHiboutikRepository.getAddressById.mockRejectedValue(new Error('boom'));
await service.syncCustomers();
expect(customerAddressConverter.fromHiboutik).toHaveBeenCalledWith({ address_id: 10, company: 'ACME', customers_id: 1 });
expect(customerAddressDatabaseRepository.upsert).toHaveBeenCalledTimes(1);
});
it('keeps syncing the other addresses when one fails', async () => {
customerHiboutikRepository.getCustomerById.mockResolvedValue({
customers_id: 1,