feat: předělání historie a profilu

This commit is contained in:
Ondřej Anděl committed 2026-10-07 14:48:21 +02:00
1 parent 9e72f431a1
commit 8fa7f601f2
97 files changed
+7502 -1034

No files matched your search

+80 -1
View File
@@ -1,6 +1,6 @@
import ExcelJS from 'exceljs';
import { importLuncherExport } from "../luncherImport";
import { getDay } from "../meals";
import { addMeal, getDay } from "../meals";
import { resetMemoryStorage } from "../storage/memory";
import { MealType } from "../../../types/gen/types.gen";
@@ -278,3 +278,82 @@ describe('import přehledu z Luncheru', () => {
.rejects.toThrow(/nepodařilo najít očekávané sloupce/);
});
});
describe('doplnění energie a živin z historie při importu', () => {
const svickova = {
date: '2025-02-10', mealType: MealType.OBED, name: 'Svíčková na smetaně', source: 'Sladovnická',
weight: 400, caloriesPer100g: 150, nutrientsPer100g: { protein: 8, fat: 9.5 },
};
/** Naimportovaný záznam daného dne. */
const importedOn = async (date: string) => {
await importLuncherExport(LOGIN, 'export.json', buildLuncherJson());
return (await getDay(LOGIN, date)).entries.find(entry => entry.importSource === 'luncher')!;
};
it('převezme energii, živiny i gramáž jídla stejného názvu', async () => {
await addMeal(LOGIN, svickova);
const entry = await importedOn('2025-03-03');
expect(entry).toMatchObject({
weight: 400, caloriesPer100g: 150, calories: 600, nutrientsPer100g: { protein: 8, fat: 9.5 },
});
// Cena zůstane z importu
expect(entry.price).toBe(15900);
});
it('u stejného zdroje převezme sazbu za 100 g a gramáž dopočte z nové ceny', async () => {
await addMeal(LOGIN, {
date: '2025-02-10', mealType: MealType.OBED, name: 'Kuřecí burger', source: 'Bolt Food',
price: 20000, pricePer100g: 5000, caloriesPer100g: 250,
});
const entry = await importedOn('2025-03-05');
// 249 Kč za 50 Kč/100 g = 498 g, × 250 kcal/100 g
expect(entry).toMatchObject({ pricePer100g: 5000, weight: 498, calories: 1245 });
});
it('z jiného zdroje sazbu nepřebírá a použije gramáž porce', async () => {
await addMeal(LOGIN, {
date: '2025-02-10', mealType: MealType.OBED, name: 'Kuřecí burger', source: 'Jinde',
price: 20000, pricePer100g: 5000, caloriesPer100g: 250,
});
const entry = await importedOn('2025-03-05');
expect(entry.pricePer100g).toBeUndefined();
expect(entry).toMatchObject({ weight: 400, calories: 1000 });
});
it('má přednost jídlo ze stejného zdroje, i když je starší', async () => {
await addMeal(LOGIN, svickova);
await addMeal(LOGIN, { ...svickova, date: '2025-02-20', source: 'Jinde', caloriesPer100g: 200 });
expect((await importedOn('2025-03-03')).caloriesPer100g).toBe(150);
});
it('jídlo stejného názvu bez kalorií vzorem není, vezme se starší s kaloriemi', async () => {
await addMeal(LOGIN, svickova);
await addMeal(LOGIN, { date: '2025-02-20', mealType: MealType.OBED, name: 'Svíčková na smetaně', price: 15900 });
expect((await importedOn('2025-03-03')).calories).toBe(600);
});
it('bez historie zůstane jídlo bez kalorií', async () => {
const entry = await importedOn('2025-03-03');
expect(entry.calories).toBeUndefined();
expect(entry).not.toHaveProperty('weight');
});
it('doplněné hodnoty ukáže už náhled', async () => {
await addMeal(LOGIN, svickova);
const result = await importLuncherExport(LOGIN, 'export.json', buildLuncherJson(), undefined, true);
expect(result.entries.find(entry => entry.date === '2025-03-03')?.calories).toBe(600);
});
});