175 lines
8.1 KiB
TypeScript
175 lines
8.1 KiB
TypeScript
process.env.CALORIE_PROVIDER = 'none';
|
|
|
|
import { addMeal, getDay } from "../meals";
|
|
import { fillMealGroup, getMealGroups, renameMealGroup } from "../mealGroups";
|
|
import { searchCalories } from "../calories";
|
|
import { resetMemoryStorage } from "../storage/memory";
|
|
import { MealType } from "../../../types/gen/types.gen";
|
|
|
|
const LOGIN = 'tester';
|
|
|
|
beforeEach(() => resetMemoryStorage());
|
|
|
|
const cina = { mealType: MealType.OBED, name: 'Čína', source: 'Chefie' };
|
|
|
|
describe('skupiny jídel podle názvu a zdroje', () => {
|
|
|
|
it('seskupí jídla podle názvu i zdroje a spočítá chybějící údaje', async () => {
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-01', price: 13900 });
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-02', name: 'cina', price: 14900 });
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-03', price: 14900, weight: 400, caloriesPer100g: 150 });
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-04', source: 'doma' });
|
|
|
|
const groups = await getMealGroups(LOGIN);
|
|
|
|
expect(groups).toHaveLength(2);
|
|
expect(groups[0]).toMatchObject({
|
|
name: 'Čína', source: 'Chefie', count: 3, lastDate: '2025-03-03',
|
|
missingCaloriesCount: 2, missingWeightCount: 2, missingNutrientsCount: 3,
|
|
values: { weight: 400, caloriesPer100g: 150 },
|
|
days: [
|
|
{ date: '2025-03-03', incomplete: true },
|
|
{ date: '2025-03-02', incomplete: true },
|
|
{ date: '2025-03-01', incomplete: true },
|
|
],
|
|
});
|
|
expect(groups[1]).toMatchObject({ source: 'doma', count: 1 });
|
|
});
|
|
|
|
it('u dnů skupiny označí ty, kde jídlu něco chybí', async () => {
|
|
await addMeal(LOGIN, {
|
|
...cina, date: '2025-03-01', weight: 400, caloriesPer100g: 150, nutrientsPer100g: { protein: 8 },
|
|
});
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-02', price: 13900 });
|
|
|
|
const [group] = await getMealGroups(LOGIN);
|
|
|
|
expect(group.days).toEqual([
|
|
{ date: '2025-03-02', incomplete: true },
|
|
{ date: '2025-03-01', incomplete: false },
|
|
]);
|
|
});
|
|
|
|
it('energii a živiny předvyplní i z jídla stejného názvu odjinud, sazbu ne', async () => {
|
|
await addMeal(LOGIN, {
|
|
...cina, date: '2025-03-01', source: 'doma', pricePer100g: 2000, caloriesPer100g: 140,
|
|
nutrientsPer100g: { protein: 8 },
|
|
});
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-02', price: 13900 });
|
|
|
|
const group = (await getMealGroups(LOGIN)).find(item => item.source === 'Chefie');
|
|
|
|
expect(group?.values).toEqual({ caloriesPer100g: 140, nutrientsPer100g: { protein: 8 } });
|
|
});
|
|
});
|
|
|
|
describe('hromadné doplnění údajů do skupiny', () => {
|
|
|
|
it('doplní jen chybějící hodnoty a kalorie dopočte z gramáže', async () => {
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-01', price: 13900 });
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-02', price: 14900, weight: 300 });
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-03', price: 14900, calories: 700 });
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-04', source: 'doma' });
|
|
|
|
const result = await fillMealGroup(LOGIN, 'cina', 'chefie', {
|
|
weight: 400, caloriesPer100g: 150, nutrientsPer100g: { protein: 8 },
|
|
});
|
|
|
|
expect(result).toEqual({ count: 3, dates: ['2025-03-01', '2025-03-02', '2025-03-03'] });
|
|
expect((await getDay(LOGIN, '2025-03-01')).entries[0]).toMatchObject({ weight: 400, calories: 600, price: 13900 });
|
|
expect((await getDay(LOGIN, '2025-03-02')).entries[0]).toMatchObject({ weight: 300, calories: 450 });
|
|
// Ručně zadané kalorie zůstanou, energie na 100 g by je přepočítala
|
|
const third = (await getDay(LOGIN, '2025-03-03')).entries[0];
|
|
expect(third).toMatchObject({ weight: 400, calories: 700, nutrientsPer100g: { protein: 8 } });
|
|
expect(third.caloriesPer100g).toBeUndefined();
|
|
expect((await getDay(LOGIN, '2025-03-04')).entries[0].calories).toBeUndefined();
|
|
});
|
|
|
|
it('gramáž dopočte z vlastní ceny jídla, když přibude sazba', async () => {
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-01', price: 13200 });
|
|
|
|
await fillMealGroup(LOGIN, 'Čína', 'Chefie', { pricePer100g: 4400, weight: 400, caloriesPer100g: 150 });
|
|
|
|
expect((await getDay(LOGIN, '2025-03-01')).entries[0]).toMatchObject({ weight: 300, calories: 450 });
|
|
});
|
|
|
|
it('vyplněné živiny nepřepíše, chybějící doplní', async () => {
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-01', nutrientsPer100g: { protein: 5 } });
|
|
|
|
await fillMealGroup(LOGIN, 'Čína', 'Chefie', { nutrientsPer100g: { protein: 8, fat: 4 } });
|
|
|
|
expect((await getDay(LOGIN, '2025-03-01')).entries[0].nutrientsPer100g).toEqual({ protein: 5, fat: 4 });
|
|
});
|
|
|
|
it('jídla, kterým nic nechybí, nepočítá', async () => {
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-01', weight: 300, caloriesPer100g: 150 });
|
|
|
|
const result = await fillMealGroup(LOGIN, 'Čína', 'Chefie', { weight: 400, caloriesPer100g: 200 });
|
|
|
|
expect(result).toEqual({ count: 0, dates: [] });
|
|
expect((await getDay(LOGIN, '2025-03-01')).entries[0].calories).toBe(450);
|
|
});
|
|
|
|
it('bez zdroje doplní jen jídla bez zdroje', async () => {
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-01', source: undefined });
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-02' });
|
|
|
|
const result = await fillMealGroup(LOGIN, 'Čína', undefined, { calories: 600 });
|
|
|
|
expect(result.dates).toEqual(['2025-03-01']);
|
|
expect((await getDay(LOGIN, '2025-03-02')).entries[0].calories).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('přejmenování skupiny jídel', () => {
|
|
|
|
it('přejmenuje a přesune do jiného zdroje všechna jídla skupiny', async () => {
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-01', price: 13900 });
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-02', name: 'cina' });
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-02', source: 'doma' });
|
|
|
|
const result = await renameMealGroup(LOGIN, 'Čína', 'Chefie', 'Kuře kung-pao', 'Everest');
|
|
|
|
expect(result).toEqual({ count: 2, dates: ['2025-03-01', '2025-03-02'] });
|
|
expect((await getDay(LOGIN, '2025-03-01')).entries[0])
|
|
.toMatchObject({ name: 'Kuře kung-pao', source: 'Everest', price: 13900 });
|
|
const second = (await getDay(LOGIN, '2025-03-02')).entries;
|
|
expect(second.map(entry => `${entry.name}|${entry.source}`).sort())
|
|
.toEqual(['Kuře kung-pao|Everest', 'Čína|doma']);
|
|
});
|
|
|
|
it('prázdný zdroj zdroj odebere a jídla se sloučí se skupinou bez zdroje', async () => {
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-01' });
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-02', source: undefined });
|
|
|
|
await renameMealGroup(LOGIN, 'Čína', 'Chefie', 'Čína', undefined);
|
|
|
|
const groups = await getMealGroups(LOGIN);
|
|
expect(groups).toHaveLength(1);
|
|
expect(groups[0].count).toBe(2);
|
|
expect((await getDay(LOGIN, '2025-03-01')).entries[0]).not.toHaveProperty('source');
|
|
});
|
|
|
|
it('jídla se shodným zápisem nepočítá', async () => {
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-01' });
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-02', name: 'čína' });
|
|
|
|
const result = await renameMealGroup(LOGIN, 'Čína', 'Chefie', 'Čína', 'Chefie');
|
|
|
|
expect(result).toEqual({ count: 1, dates: ['2025-03-02'] });
|
|
});
|
|
|
|
it('energii na 100 g si knihovna zapamatuje i pod novým názvem', async () => {
|
|
await addMeal(LOGIN, { ...cina, date: '2025-03-01', weight: 400, caloriesPer100g: 150 });
|
|
|
|
await renameMealGroup(LOGIN, 'Čína', 'Chefie', 'Kuře kung-pao', 'Chefie');
|
|
|
|
const { suggestions } = await searchCalories(LOGIN, 'Kuře kung-pao');
|
|
expect(suggestions[0]).toMatchObject({ name: 'Kuře kung-pao', caloriesPer100g: 150 });
|
|
});
|
|
|
|
it('odmítne prázdný nový název', async () => {
|
|
await expect(renameMealGroup(LOGIN, 'Čína', 'Chefie', ' ', 'Chefie')).rejects.toThrow(/nový název/);
|
|
});
|
|
});
|