Files
website/src/lib/server/health-import.test.ts
Stan Runge 8aa689af64
All checks were successful
Deploy production / deploy (push) Successful in 2m22s
health: drop hair_progress; owner = Stan's account email only
Regenerated the (not yet deployed) health migration without hair_progress.
2026-10-24 00:22:24 +00:00

53 lines
2.2 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { amsterdamTime, cleanRow, parseCsv, toPayload, validatePayload } from './health-import';
describe('health import', () => {
it('parses CSV with quotes and semicolons', () => {
expect(parseCsv('date;kcal;notes\r\n2026-01-02;2500;"a; ""b"""\n')).toEqual([
{ date: '2026-01-02', kcal: '2500', notes: 'a; "b"' }
]);
});
it('validates and camel-cases rows', () => {
const r = cleanRow('body_measurements', {
date: '2026-01-02',
weight_kg: '80,5',
waist_cm: ''
});
expect(r).toEqual({
ok: true,
row: {
id: undefined,
values: { date: '2026-01-02', weightKg: 80.5, waistCm: null, bodyFatPct: null, notes: null }
}
});
expect(cleanRow('body_measurements', { date: '2026-01-02' }).ok).toBe(false);
expect(cleanRow('workouts', { date: '2026-01-02', exercise: 'squat', rpe: 11 }).ok).toBe(false);
expect(cleanRow('workouts', { date: '2026-01-02', exercise: 'squat', bogus: 1 }).ok).toBe(
false
);
expect(
cleanRow('vaccinations', { vaccine: 'X', date: '2026-01-02', country: 'nl' })
).toMatchObject({ ok: true, row: { values: { country: 'NL' } } });
});
it('resolves bare sleep times in Amsterdam time', () => {
const r = cleanRow('sleep', { date: '2026-07-02', bedtime: '23:30', wake_time: '07:15' });
expect(r.ok && (r.row.values.bedtime as Date).toISOString()).toBe('2026-07-01T21:30:00.000Z');
expect(r.ok && (r.row.values.wakeTime as Date).toISOString()).toBe('2026-07-02T05:15:00.000Z');
expect(amsterdamTime('2026-01-15', '12:00')?.toISOString()).toBe('2026-01-15T11:00:00.000Z');
const after = cleanRow('sleep', { date: '2026-07-02', bedtime: '00:40', wake_time: '08:00' });
expect(after.ok && (after.row.values.bedtime as Date).toISOString()).toBe(
'2026-07-01T22:40:00.000Z'
);
});
it('reports errors per row and table', () => {
const { errors } = validatePayload(
toPayload({ nutrition_daily: [{ date: 'x' }, { date: '2026-01-01', kcal: 2000 }] })
);
expect(errors).toEqual([
{ table: 'nutrition_daily', row: 1, error: expect.stringContaining('date') }
]);
expect(() => toPayload([{}])).toThrow();
expect(() => toPayload({ nope: [] })).toThrow();
});
});