weegschaal-app/tests/database.test.ts
eddy 4c34dff629 fix: sync refactor — fix 6 bugs + cache refresh na sync
- setDeletedAt update nu ook updatedAt (bug 2)
- getAllMeasurements filtert deletedAt IS NULL, nieuwe getAllMeasurementsForSync voor sync
- mergeMeasurements detecteert server deleted:true → deletedAt (bug 1)
- syncAll: pull-push split met remoteUpdatedMap, geen double-push (bug 3)
- hard delete alleen na API-succes (bug 4)
- DashboardScreen: refreshCache() na syncAll zodat UI niet op Laden blijft hangen
- deleteMeasurement() dead code verwijderd (bug 5)
- tests: 3 nieuwe testcases voor deleted → deletedAt mapping, 15/15 pass
2026-07-25 15:33:22 +02:00

95 lines
2.9 KiB
TypeScript

import { Measurement } from '../src/types'
import * as SQLite from 'expo-sqlite'
jest.mock('expo-sqlite', () => ({
openDatabaseAsync: jest.fn(),
}))
const mockMeasurement: Measurement = {
id: '550e8400-e29b-41d4-a716-446655440000',
weight: 75.5,
bmi: 22.3,
bodyFatPercentage: 15.2,
fatMass: 11.5,
musclePercentage: 40.1,
muscleMass: 30.3,
visceralFat: 8,
bmr: 1650,
measuredAt: '2024-01-01T08:00:00.000Z',
createdAt: '2024-01-01T08:00:00.000Z',
updatedAt: '2024-01-01T08:00:00.000Z',
}
describe('database', () => {
let db: any
let initDatabase: any
let insertMeasurement: any
let getAllMeasurements: any
let getLatestMeasurement: any
let setDeletedAt: any
beforeEach(async () => {
jest.resetModules()
jest.doMock('expo-sqlite', () => ({
openDatabaseAsync: jest.fn(),
}))
db = {
execAsync: jest.fn(),
runAsync: jest.fn(),
getAllAsync: jest.fn(),
}
const sqlite = require('expo-sqlite')
;(sqlite.openDatabaseAsync as jest.Mock).mockResolvedValue(db)
const mod = require('../src/database/db')
initDatabase = mod.initDatabase
insertMeasurement = mod.insertMeasurement
getAllMeasurements = mod.getAllMeasurements
getLatestMeasurement = mod.getLatestMeasurement
setDeletedAt = mod.setDeletedAt
})
it('initDatabase creates the measurements table', async () => {
await initDatabase()
expect(db.execAsync).toHaveBeenCalledWith(
expect.stringContaining('CREATE TABLE IF NOT EXISTS measurements')
)
})
it('insertMeasurement inserts a row', async () => {
db.runAsync.mockResolvedValue(undefined)
await initDatabase()
await insertMeasurement(mockMeasurement)
expect(db.runAsync).toHaveBeenCalledWith(
expect.stringContaining('INSERT INTO measurements'),
expect.arrayContaining([mockMeasurement.id])
)
})
it('getAllMeasurements returns all measurements ordered by measuredAt desc', async () => {
db.getAllAsync.mockResolvedValue([{ ...mockMeasurement }])
await initDatabase()
const result = await getAllMeasurements()
expect(result).toHaveLength(1)
expect(result[0].id).toBe(mockMeasurement.id)
})
it('getLatestMeasurement returns the most recent', async () => {
db.getAllAsync.mockResolvedValue([{ ...mockMeasurement }])
await initDatabase()
const result = await getLatestMeasurement()
expect(result).not.toBeNull()
expect(result!.id).toBe(mockMeasurement.id)
})
it('setDeletedAt sets both deletedAt and updatedAt timestamps', async () => {
db.runAsync.mockResolvedValue(undefined)
await initDatabase()
await setDeletedAt(mockMeasurement.id)
expect(db.runAsync).toHaveBeenCalledWith(
expect.stringContaining('UPDATE measurements SET deletedAt'),
expect.arrayContaining([mockMeasurement.id])
)
const args = (db.runAsync as jest.Mock).mock.calls.slice(-1)[0]
expect(args[1][0]).toBe(args[1][1])
})
})