Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
95 lines
3.2 KiB
TypeScript
95 lines
3.2 KiB
TypeScript
/**
|
|
* Unit tests for buildNormalizedCompanyPayload
|
|
* (packages/billing/src/services/companySync/companySyncNormalizer.ts).
|
|
*
|
|
* This is the data-in/data-out mapping used before pushing companies to
|
|
* accounting systems: field passthrough, null defaulting, and contact
|
|
* normalization.
|
|
*/
|
|
import { describe, expect, it } from 'vitest';
|
|
import {
|
|
buildNormalizedCompanyPayload,
|
|
type RawCompanyRecord,
|
|
} from '../../src/services/companySync/companySyncNormalizer';
|
|
|
|
describe('buildNormalizedCompanyPayload', () => {
|
|
it('maps a fully populated record through unchanged', () => {
|
|
const raw: RawCompanyRecord = {
|
|
companyId: 'co-1',
|
|
name: 'Acme Co',
|
|
primaryEmail: 'billing@acme.test',
|
|
primaryPhone: '+1-555-0100',
|
|
billingAddress: { line1: '1 Main St', city: 'Springfield', postalCode: '12345', country: 'US' },
|
|
shippingAddress: { line1: '2 Dock Rd', city: 'Springfield' },
|
|
contacts: [{ type: 'billing', name: 'Pat', email: 'pat@acme.test', phone: '+1-555-0101' }],
|
|
taxNumber: 'TAX-99',
|
|
notes: 'VIP customer',
|
|
metadata: { sourceSystem: 'crm' },
|
|
};
|
|
|
|
expect(buildNormalizedCompanyPayload(raw)).toEqual({
|
|
companyId: 'co-1',
|
|
name: 'Acme Co',
|
|
primaryEmail: 'billing@acme.test',
|
|
primaryPhone: '+1-555-0100',
|
|
billingAddress: { line1: '1 Main St', city: 'Springfield', postalCode: '12345', country: 'US' },
|
|
shippingAddress: { line1: '2 Dock Rd', city: 'Springfield' },
|
|
contacts: [{ type: 'billing', name: 'Pat', email: 'pat@acme.test', phone: '+1-555-0101' }],
|
|
taxNumber: 'TAX-99',
|
|
notes: 'VIP customer',
|
|
metadata: { sourceSystem: 'crm' },
|
|
});
|
|
});
|
|
|
|
it('defaults all optional fields to null/empty for a minimal record', () => {
|
|
const payload = buildNormalizedCompanyPayload({ companyId: 'co-2', name: 'Bare Co' });
|
|
|
|
expect(payload).toEqual({
|
|
companyId: 'co-2',
|
|
name: 'Bare Co',
|
|
primaryEmail: null,
|
|
primaryPhone: null,
|
|
billingAddress: null,
|
|
shippingAddress: null,
|
|
contacts: [],
|
|
taxNumber: null,
|
|
notes: null,
|
|
metadata: {},
|
|
});
|
|
});
|
|
|
|
it('normalizes undefined optional values to explicit nulls (stable adapter contract)', () => {
|
|
const payload = buildNormalizedCompanyPayload({
|
|
companyId: 'co-3',
|
|
name: 'Null Co',
|
|
primaryEmail: undefined,
|
|
billingAddress: null,
|
|
contacts: undefined,
|
|
metadata: undefined,
|
|
});
|
|
|
|
expect(payload.primaryEmail).toBeNull();
|
|
expect(payload.billingAddress).toBeNull();
|
|
expect(payload.contacts).toEqual([]);
|
|
expect(payload.metadata).toEqual({});
|
|
});
|
|
|
|
it('fills contact defaults: type falls back to primary, missing fields become null', () => {
|
|
const payload = buildNormalizedCompanyPayload({
|
|
companyId: 'co-4',
|
|
name: 'Contact Co',
|
|
contacts: [
|
|
{},
|
|
{ name: 'Sam' },
|
|
{ type: 'shipping', email: 'ship@co.test' },
|
|
],
|
|
});
|
|
|
|
expect(payload.contacts).toEqual([
|
|
{ type: 'primary', name: null, email: null, phone: null },
|
|
{ type: 'primary', name: 'Sam', email: null, phone: null },
|
|
{ type: 'shipping', name: null, email: 'ship@co.test', phone: null },
|
|
]);
|
|
});
|
|
});
|