83 lines
3.2 KiB
JavaScript
83 lines
3.2 KiB
JavaScript
import { test } from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import { mergeEditedDays } from '#tofu/tools/planning/mergeEditedDays.js'
|
|
|
|
function buildPlanning(days) {
|
|
return { weekId: '2026-W40', days }
|
|
}
|
|
|
|
const LOADED = buildPlanning([
|
|
{ date: '2026-09-28', dish: 'Gratin dauphinois', ingredients: 'pommes de terre, crème' },
|
|
{ date: '2026-09-29', dish: 'Quiche lorraine', ingredients: 'lardons, œufs' },
|
|
])
|
|
|
|
test('returns the loaded planning untouched when nothing was edited', () => {
|
|
const local = buildPlanning([
|
|
{ date: '2026-09-28', dish: '', ingredients: '' },
|
|
{ date: '2026-09-29', dish: '', ingredients: '' },
|
|
])
|
|
assert.equal(mergeEditedDays(LOADED, local, new Set()), LOADED)
|
|
})
|
|
|
|
test('keeps the edited cell and the loaded days that were not touched', () => {
|
|
const local = buildPlanning([
|
|
{ date: '2026-09-28', dish: 'Pizza', ingredients: '' },
|
|
{ date: '2026-09-29', dish: '', ingredients: '' },
|
|
])
|
|
const merged = mergeEditedDays(LOADED, local, new Set(['2026-09-28:dish']))
|
|
|
|
assert.equal(merged.days[0].dish, 'Pizza', 'the typed dish survives the load')
|
|
assert.equal(
|
|
merged.days[0].ingredients,
|
|
'pommes de terre, crème',
|
|
'the untouched ingredient line of the same day still comes from the store',
|
|
)
|
|
assert.deepEqual(merged.days[1], LOADED.days[1], 'the other days are the loaded ones')
|
|
})
|
|
|
|
test('an edited empty cell wins over the loaded value', () => {
|
|
// Clearing a field is an edit like any other: it must not be undone by the load.
|
|
const local = buildPlanning([
|
|
{ date: '2026-09-28', dish: '', ingredients: 'pommes de terre, crème' },
|
|
{ date: '2026-09-29', dish: 'Quiche lorraine', ingredients: 'lardons, œufs' },
|
|
])
|
|
const merged = mergeEditedDays(LOADED, local, new Set(['2026-09-28:dish']))
|
|
assert.equal(merged.days[0].dish, '')
|
|
})
|
|
|
|
test('merges several cells across several days', () => {
|
|
const local = buildPlanning([
|
|
{ date: '2026-09-28', dish: 'Pizza', ingredients: 'pâte, tomate' },
|
|
{ date: '2026-09-29', dish: 'Soupe', ingredients: '' },
|
|
])
|
|
const merged = mergeEditedDays(
|
|
LOADED,
|
|
local,
|
|
new Set(['2026-09-28:ingredients', '2026-09-29:dish']),
|
|
)
|
|
|
|
assert.equal(merged.days[0].dish, 'Gratin dauphinois', 'untouched cell keeps the loaded value')
|
|
assert.equal(merged.days[0].ingredients, 'pâte, tomate')
|
|
assert.equal(merged.days[1].dish, 'Soupe')
|
|
assert.equal(merged.days[1].ingredients, 'lardons, œufs')
|
|
})
|
|
|
|
test('does not mutate the loaded planning', () => {
|
|
const local = buildPlanning([
|
|
{ date: '2026-09-28', dish: 'Pizza', ingredients: '' },
|
|
{ date: '2026-09-29', dish: '', ingredients: '' },
|
|
])
|
|
const snapshot = structuredClone(LOADED)
|
|
mergeEditedDays(LOADED, local, new Set(['2026-09-28:dish']))
|
|
assert.deepEqual(LOADED, snapshot)
|
|
})
|
|
|
|
test('ignores an edited day that the loaded planning does not contain', () => {
|
|
const local = buildPlanning([{ date: '2026-10-05', dish: 'Pizza', ingredients: '' }])
|
|
const merged = mergeEditedDays(LOADED, local, new Set(['2026-10-05:dish']))
|
|
assert.deepEqual(merged, LOADED)
|
|
})
|
|
|
|
test('falls back to the loaded planning when the local one is unusable', () => {
|
|
assert.equal(mergeEditedDays(LOADED, null, new Set(['2026-09-28:dish'])), LOADED)
|
|
})
|