Packages added: - @bytelyst/referral-client — referral API client + share helpers - @bytelyst/subscription-client — subscription/plan API client + cache - @bytelyst/celebrations — milestone triggers, confetti, positive messages - @bytelyst/gentle-notifications — ND-friendly messaging, forbidden phrases - @bytelyst/accessibility — VoiceOver/TalkBack label generators - @bytelyst/quick-actions — progressive disclosure, smart defaults - @bytelyst/time-references — familiar duration references - @bytelyst/org-client — org/workspace/membership/license API client - @bytelyst/marketplace-client — listing/review/install API client All packages: pure TS, ESM, globalThis.fetch, no Node.js deps. 99 Vitest tests across 9 packages, 79/79 public methods covered. Review fixes applied: - time-references: fix module-level mutable state leak + add clearCustomReferences() - accessibility: fix parameter reassignment in formatDurationForA11y/numberToWords - subscription-client: fix flaky daysRemaining test (ms boundary race)
108 lines
3.2 KiB
TypeScript
108 lines
3.2 KiB
TypeScript
import { describe, it, expect, afterEach } from 'vitest';
|
|
import {
|
|
getTimeReference,
|
|
getEpisodeComparison,
|
|
getEncouragingMessage,
|
|
registerReferences,
|
|
clearCustomReferences,
|
|
} from './client.js';
|
|
|
|
describe('getTimeReference', () => {
|
|
it('should return a reference for short duration', () => {
|
|
const ref = getTimeReference(0.1);
|
|
expect(ref.text.length).toBeGreaterThan(0);
|
|
expect(ref.emoji.length).toBeGreaterThan(0);
|
|
expect(['media', 'activity', 'travel', 'nature']).toContain(ref.category);
|
|
});
|
|
|
|
it('should return a reference for medium duration', () => {
|
|
const ref = getTimeReference(1.5);
|
|
expect(ref.text.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should return a reference for long duration', () => {
|
|
const ref = getTimeReference(16);
|
|
expect(ref.text.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should return a reference for very long duration', () => {
|
|
const ref = getTimeReference(72);
|
|
expect(ref.text.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should handle zero hours', () => {
|
|
const ref = getTimeReference(0);
|
|
expect(ref.text.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('should handle negative as zero', () => {
|
|
const ref = getTimeReference(-5);
|
|
expect(ref.text.length).toBeGreaterThan(0);
|
|
});
|
|
});
|
|
|
|
describe('getEpisodeComparison', () => {
|
|
it('should return episode count for default show', () => {
|
|
const result = getEpisodeComparison(1);
|
|
expect(result).toContain('The Office');
|
|
expect(result).toContain('episodes');
|
|
});
|
|
|
|
it('should return custom show name', () => {
|
|
const result = getEpisodeComparison(2, 'Friends', 25);
|
|
expect(result).toContain('Friends');
|
|
});
|
|
|
|
it('should handle less than one episode', () => {
|
|
const result = getEpisodeComparison(0.1);
|
|
expect(result).toContain('Less than one episode');
|
|
});
|
|
|
|
it('should handle exactly one episode', () => {
|
|
const result = getEpisodeComparison(22 / 60);
|
|
expect(result).toContain('1 episode');
|
|
});
|
|
});
|
|
|
|
describe('getEncouragingMessage', () => {
|
|
it('should return message for each time bracket', () => {
|
|
expect(getEncouragingMessage(0.5).length).toBeGreaterThan(0);
|
|
expect(getEncouragingMessage(2).length).toBeGreaterThan(0);
|
|
expect(getEncouragingMessage(6).length).toBeGreaterThan(0);
|
|
expect(getEncouragingMessage(12).length).toBeGreaterThan(0);
|
|
expect(getEncouragingMessage(20).length).toBeGreaterThan(0);
|
|
expect(getEncouragingMessage(30).length).toBeGreaterThan(0);
|
|
});
|
|
});
|
|
|
|
describe('registerReferences', () => {
|
|
afterEach(() => {
|
|
clearCustomReferences();
|
|
});
|
|
|
|
it('should allow custom references', () => {
|
|
registerReferences([
|
|
{
|
|
minHours: 0,
|
|
maxHours: 0.1,
|
|
references: [{ text: 'Custom micro reference', emoji: '⚡', category: 'activity' }],
|
|
},
|
|
]);
|
|
const ref = getTimeReference(0.05);
|
|
expect(ref.text).toBe('Custom micro reference');
|
|
});
|
|
|
|
it('should clear custom references', () => {
|
|
registerReferences([
|
|
{
|
|
minHours: 0,
|
|
maxHours: 0.1,
|
|
references: [{ text: 'Will be cleared', emoji: '🧹', category: 'activity' }],
|
|
},
|
|
]);
|
|
clearCustomReferences();
|
|
const ref = getTimeReference(0.05);
|
|
expect(ref.text).not.toBe('Will be cleared');
|
|
});
|
|
});
|