- Update kill-switch-client and feature-flag-client tests to use expect.objectContaining for headers to handle x-request-id - Move React Native SDK roadmap to completed/ Total: 44 client-side package tests passing
103 lines
2.7 KiB
TypeScript
103 lines
2.7 KiB
TypeScript
import { describe, it, expect, vi, afterEach } from 'vitest';
|
|
import { createKillSwitchClient } from './index.js';
|
|
|
|
describe('createKillSwitchClient', () => {
|
|
const baseConfig = {
|
|
baseUrl: 'http://localhost:4003/api',
|
|
productId: 'testapp',
|
|
};
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it('should return disabled=false when app is not disabled', async () => {
|
|
vi.stubGlobal(
|
|
'fetch',
|
|
vi.fn().mockResolvedValue({
|
|
ok: true,
|
|
json: () => Promise.resolve({ disabled: false, message: null }),
|
|
})
|
|
);
|
|
|
|
const ks = createKillSwitchClient(baseConfig);
|
|
const result = await ks.check();
|
|
|
|
expect(result.disabled).toBe(false);
|
|
expect(result.message).toBeNull();
|
|
});
|
|
|
|
it('should return disabled=true with message when app is disabled', async () => {
|
|
vi.stubGlobal(
|
|
'fetch',
|
|
vi.fn().mockResolvedValue({
|
|
ok: true,
|
|
json: () => Promise.resolve({ disabled: true, message: 'Maintenance in progress' }),
|
|
})
|
|
);
|
|
|
|
const ks = createKillSwitchClient(baseConfig);
|
|
const result = await ks.check();
|
|
|
|
expect(result.disabled).toBe(true);
|
|
expect(result.message).toBe('Maintenance in progress');
|
|
});
|
|
|
|
it('should fail-open on network error', async () => {
|
|
vi.stubGlobal('fetch', vi.fn().mockRejectedValue(new Error('network')));
|
|
|
|
const ks = createKillSwitchClient(baseConfig);
|
|
const result = await ks.check();
|
|
|
|
expect(result.disabled).toBe(false);
|
|
expect(result.message).toBeNull();
|
|
});
|
|
|
|
it('should fail-open on non-OK response', async () => {
|
|
vi.stubGlobal(
|
|
'fetch',
|
|
vi.fn().mockResolvedValue({
|
|
ok: false,
|
|
status: 500,
|
|
})
|
|
);
|
|
|
|
const ks = createKillSwitchClient(baseConfig);
|
|
const result = await ks.check();
|
|
|
|
expect(result.disabled).toBe(false);
|
|
});
|
|
|
|
it('should send correct product-id header', async () => {
|
|
const fetchMock = vi.fn().mockResolvedValue({
|
|
ok: true,
|
|
json: () => Promise.resolve({ disabled: false }),
|
|
});
|
|
vi.stubGlobal('fetch', fetchMock);
|
|
|
|
const ks = createKillSwitchClient(baseConfig);
|
|
await ks.check();
|
|
|
|
expect(fetchMock).toHaveBeenCalledWith(
|
|
expect.stringContaining('/flags/kill-switch'),
|
|
expect.objectContaining({
|
|
headers: expect.objectContaining({ 'x-product-id': 'testapp' }),
|
|
})
|
|
);
|
|
});
|
|
|
|
it('should include platform in query string', async () => {
|
|
const fetchMock = vi.fn().mockResolvedValue({
|
|
ok: true,
|
|
json: () => Promise.resolve({ disabled: false }),
|
|
});
|
|
vi.stubGlobal('fetch', fetchMock);
|
|
|
|
const ks = createKillSwitchClient({ ...baseConfig, platform: 'ios' });
|
|
await ks.check();
|
|
|
|
const url = fetchMock.mock.calls[0][0] as string;
|
|
expect(url).toContain('platform=ios');
|
|
});
|
|
});
|