wulf-pulse/lib/services/mimecast-client.test.ts
lorentz 12250c1e1d test(260716-n46): add coverage for getMimecastClientForTenant
Covers the already-implemented per-tenant factory: returns a MimecastClient
instance, builds a new independent instance per call (never the cached
global), doesn't affect getMimecastClient()'s singleton, and defaults
base_url when omitted. Uses fake credentials only.
2026-07-16 16:44:54 -04:00

105 lines
3.7 KiB
TypeScript

/**
* mimecast-client.ts — isMimecastConfigured()/getMimecastClient() factory tests.
*
* Mirrors pax8-factory.test.ts's beforeEach env-var-delete + reset seam
* pattern. Does not test MimecastClient's other 20+ methods — out of scope
* for this phase (Phase 17, Plan 01, Task 1).
*/
import { describe, it, expect, beforeEach } from 'vitest';
import {
isMimecastConfigured,
getMimecastClient,
getMimecastClientForTenant,
_resetMimecastClient,
} from './mimecast-client';
beforeEach(() => {
delete process.env.MIMECAST_CLIENT_ID;
delete process.env.MIMECAST_CLIENT_SECRET;
_resetMimecastClient();
});
describe('isMimecastConfigured', () => {
it('returns false when neither env var is set', () => {
expect(isMimecastConfigured()).toBe(false);
});
it('returns false when only MIMECAST_CLIENT_ID is set', () => {
process.env.MIMECAST_CLIENT_ID = 'id1';
expect(isMimecastConfigured()).toBe(false);
});
it('returns false when only MIMECAST_CLIENT_SECRET is set', () => {
process.env.MIMECAST_CLIENT_SECRET = 'secret1';
expect(isMimecastConfigured()).toBe(false);
});
it('returns true when both env vars are set', () => {
process.env.MIMECAST_CLIENT_ID = 'id1';
process.env.MIMECAST_CLIENT_SECRET = 'secret1';
expect(isMimecastConfigured()).toBe(true);
});
});
describe('getMimecastClient', () => {
it('throws the exact configuration error when not configured', () => {
expect(() => getMimecastClient()).toThrow(
'MIMECAST_CLIENT_ID and MIMECAST_CLIENT_SECRET must be set'
);
});
it('returns the same cached instance on repeated calls', () => {
process.env.MIMECAST_CLIENT_ID = 'id1';
process.env.MIMECAST_CLIENT_SECRET = 'secret1';
const first = getMimecastClient();
const second = getMimecastClient();
expect(second).toBe(first);
});
it('rebuilds a new instance after _resetMimecastClient()', () => {
process.env.MIMECAST_CLIENT_ID = 'id1';
process.env.MIMECAST_CLIENT_SECRET = 'secret1';
const first = getMimecastClient();
_resetMimecastClient();
const second = getMimecastClient();
expect(second).not.toBe(first);
});
});
describe('getMimecastClientForTenant', () => {
// Fake credentials only — never real mimecast_tenants values.
const FAKE_TENANT = { client_id: 'tid', client_secret: 'tsecret', base_url: 'https://tenant.example' };
it('returns a MimecastClient instance exposing the fan-out methods', () => {
const client = getMimecastClientForTenant(FAKE_TENANT);
expect(client).toBeTruthy();
expect(typeof client.searchDeliveredMessages).toBe('function');
expect(typeof client.getHeldMessages).toBe('function');
expect(typeof client.getThreatEvents).toBe('function');
});
it('returns a NEW instance on each call — never the cached global', () => {
const first = getMimecastClientForTenant(FAKE_TENANT);
const second = getMimecastClientForTenant(FAKE_TENANT);
expect(second).not.toBe(first);
});
it('does not populate or replace the cached global getMimecastClient() instance', () => {
process.env.MIMECAST_CLIENT_ID = 'id1';
process.env.MIMECAST_CLIENT_SECRET = 'secret1';
getMimecastClientForTenant(FAKE_TENANT);
const global1 = getMimecastClient();
const global2 = getMimecastClient();
// The global singleton is unaffected by tenant-client construction —
// still cached and independent of the tenant instance.
expect(global2).toBe(global1);
expect(global1).not.toBe(getMimecastClientForTenant(FAKE_TENANT));
});
it('does not throw when base_url is omitted (defaults to the Mimecast API host)', () => {
expect(() => getMimecastClientForTenant({ client_id: 'tid', client_secret: 'tsecret' })).not.toThrow();
});
});