test(platform-service): add repository tests for settings, referrals — 336 tests, 30.64% coverage
This commit is contained in:
parent
fbb2197f7c
commit
747d89fe4d
@ -0,0 +1,159 @@
|
|||||||
|
/**
|
||||||
|
* Repository tests for referrals module — mocked Cosmos DB.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||||
|
|
||||||
|
const mockFetchAll = vi.fn();
|
||||||
|
const mockCreate = vi.fn();
|
||||||
|
const mockRead = vi.fn();
|
||||||
|
const mockReplace = vi.fn();
|
||||||
|
|
||||||
|
vi.mock('../../lib/cosmos.js', () => ({
|
||||||
|
getContainer: vi.fn(() => ({
|
||||||
|
items: {
|
||||||
|
query: () => ({ fetchAll: mockFetchAll }),
|
||||||
|
create: mockCreate,
|
||||||
|
},
|
||||||
|
item: () => ({ read: mockRead, replace: mockReplace }),
|
||||||
|
})),
|
||||||
|
}));
|
||||||
|
|
||||||
|
import {
|
||||||
|
listAll,
|
||||||
|
getByReferrer,
|
||||||
|
getByReferredEmail,
|
||||||
|
getById,
|
||||||
|
create,
|
||||||
|
update,
|
||||||
|
countReferrals,
|
||||||
|
} from './repository.js';
|
||||||
|
import type { ReferralDoc } from './types.js';
|
||||||
|
|
||||||
|
const baseReferral: ReferralDoc = {
|
||||||
|
id: 'ref_1',
|
||||||
|
productId: 'lysnrai',
|
||||||
|
referrerId: 'user_1',
|
||||||
|
referrerEmail: 'referrer@example.com',
|
||||||
|
referredUserId: null,
|
||||||
|
referredEmail: 'new@example.com',
|
||||||
|
status: 'pending',
|
||||||
|
referrerRewardTokens: 1000,
|
||||||
|
referredRewardTokens: 500,
|
||||||
|
referrerRewarded: false,
|
||||||
|
referredRewarded: false,
|
||||||
|
createdAt: '2026-02-16T00:00:00Z',
|
||||||
|
completedAt: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('referrals repository', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('listAll', () => {
|
||||||
|
it('returns referrals', async () => {
|
||||||
|
mockFetchAll.mockResolvedValue({ resources: [baseReferral] });
|
||||||
|
const result = await listAll(100, 0, 'lysnrai');
|
||||||
|
expect(result).toEqual([baseReferral]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns empty array when no referrals', async () => {
|
||||||
|
mockFetchAll.mockResolvedValue({ resources: [] });
|
||||||
|
const result = await listAll();
|
||||||
|
expect(result).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getByReferrer', () => {
|
||||||
|
it('returns referrals for referrer', async () => {
|
||||||
|
mockFetchAll.mockResolvedValue({ resources: [baseReferral] });
|
||||||
|
const result = await getByReferrer('user_1', 'lysnrai');
|
||||||
|
expect(result).toEqual([baseReferral]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getByReferredEmail', () => {
|
||||||
|
it('returns referral when found', async () => {
|
||||||
|
mockFetchAll.mockResolvedValue({ resources: [baseReferral] });
|
||||||
|
const result = await getByReferredEmail('new@example.com', 'lysnrai');
|
||||||
|
expect(result).toEqual(baseReferral);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns null when not found', async () => {
|
||||||
|
mockFetchAll.mockResolvedValue({ resources: [] });
|
||||||
|
const result = await getByReferredEmail('none@example.com', 'lysnrai');
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getById', () => {
|
||||||
|
it('returns referral when found', async () => {
|
||||||
|
mockRead.mockResolvedValue({ resource: baseReferral });
|
||||||
|
const result = await getById('ref_1', 'user_1');
|
||||||
|
expect(result).toEqual(baseReferral);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns null when not found', async () => {
|
||||||
|
mockRead.mockRejectedValue(new Error('Not found'));
|
||||||
|
const result = await getById('ref_1', 'user_1');
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns null when resource is undefined', async () => {
|
||||||
|
mockRead.mockResolvedValue({ resource: undefined });
|
||||||
|
const result = await getById('ref_1', 'user_1');
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('create', () => {
|
||||||
|
it('creates and returns referral', async () => {
|
||||||
|
mockCreate.mockResolvedValue({ resource: baseReferral });
|
||||||
|
const result = await create(baseReferral);
|
||||||
|
expect(result).toEqual(baseReferral);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('update', () => {
|
||||||
|
it('merges updates and returns referral', async () => {
|
||||||
|
mockRead.mockResolvedValue({ resource: baseReferral });
|
||||||
|
const updated = { ...baseReferral, status: 'signed_up' as const };
|
||||||
|
mockReplace.mockResolvedValue({ resource: updated });
|
||||||
|
const result = await update('ref_1', 'user_1', { status: 'signed_up' });
|
||||||
|
expect(result).toEqual(updated);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns null when not found', async () => {
|
||||||
|
mockRead.mockResolvedValue({ resource: undefined });
|
||||||
|
const result = await update('ref_1', 'user_1', { status: 'signed_up' });
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns null on error', async () => {
|
||||||
|
mockRead.mockRejectedValue(new Error('Not found'));
|
||||||
|
const result = await update('ref_1', 'user_1', { status: 'signed_up' });
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('countReferrals', () => {
|
||||||
|
it('returns counts', async () => {
|
||||||
|
mockFetchAll
|
||||||
|
.mockResolvedValueOnce({ resources: [10] })
|
||||||
|
.mockResolvedValueOnce({ resources: [5] })
|
||||||
|
.mockResolvedValueOnce({ resources: [2] });
|
||||||
|
const result = await countReferrals('lysnrai');
|
||||||
|
expect(result).toEqual({ total: 10, completed: 5, rewarded: 2 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns zeros when no data', async () => {
|
||||||
|
mockFetchAll
|
||||||
|
.mockResolvedValueOnce({ resources: [] })
|
||||||
|
.mockResolvedValueOnce({ resources: [] })
|
||||||
|
.mockResolvedValueOnce({ resources: [] });
|
||||||
|
const result = await countReferrals('lysnrai');
|
||||||
|
expect(result).toEqual({ total: 0, completed: 0, rewarded: 0 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* Repository tests for settings module — mocked Cosmos DB.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||||
|
|
||||||
|
const mockRead = vi.fn();
|
||||||
|
const mockUpsert = vi.fn();
|
||||||
|
|
||||||
|
vi.mock('../../lib/cosmos.js', () => ({
|
||||||
|
getContainer: vi.fn(() => ({
|
||||||
|
items: { upsert: mockUpsert },
|
||||||
|
item: () => ({ read: mockRead }),
|
||||||
|
})),
|
||||||
|
}));
|
||||||
|
|
||||||
|
import { getSettingsId, getByUserId, upsert } from './repository.js';
|
||||||
|
import type { UserSettingsDoc } from './types.js';
|
||||||
|
|
||||||
|
const baseSettings: UserSettingsDoc = {
|
||||||
|
id: 'set_lysnrai_user_1',
|
||||||
|
productId: 'lysnrai',
|
||||||
|
userId: 'user_1',
|
||||||
|
settings: { theme: 'dark', language: 'en' },
|
||||||
|
deviceOverrides: { dev_mac_001: { volume: 0.8 } },
|
||||||
|
createdAt: '2026-02-16T00:00:00Z',
|
||||||
|
updatedAt: '2026-02-16T00:00:00Z',
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('settings repository', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getSettingsId', () => {
|
||||||
|
it('generates correct id format', () => {
|
||||||
|
expect(getSettingsId('lysnrai', 'user_1')).toBe('set_lysnrai_user_1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles different products', () => {
|
||||||
|
expect(getSettingsId('mindlyst', 'user_2')).toBe('set_mindlyst_user_2');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getByUserId', () => {
|
||||||
|
it('returns settings when found', async () => {
|
||||||
|
mockRead.mockResolvedValue({ resource: baseSettings });
|
||||||
|
const result = await getByUserId('user_1', 'lysnrai');
|
||||||
|
expect(result).toEqual(baseSettings);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns null when not found', async () => {
|
||||||
|
mockRead.mockRejectedValue(new Error('Not found'));
|
||||||
|
const result = await getByUserId('user_1', 'lysnrai');
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns null when resource is undefined', async () => {
|
||||||
|
mockRead.mockResolvedValue({ resource: undefined });
|
||||||
|
const result = await getByUserId('user_1', 'lysnrai');
|
||||||
|
expect(result).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('upsert', () => {
|
||||||
|
it('upserts and returns settings', async () => {
|
||||||
|
mockUpsert.mockResolvedValue({ resource: baseSettings });
|
||||||
|
const result = await upsert(baseSettings);
|
||||||
|
expect(result).toEqual(baseSettings);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user