import {test} from 'node:test';
import assert from 'node:assert/strict';
import {render, screen, within} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import ShoppingCart from './main.jsx';
const products = () => screen.getByRole('list', {name: 'Products'});
const productRow = (name) => within(products()).getAllByRole('listitem').find((li) => li.textContent.startsWith(name + ' '));
const add = (user, name, label = 'Add to cart') => user.click(within(productRow(name)).getByRole('button', {name: label}));
// Each cart line's text without its buttons, e.g. "Bread × 2".
const cartLines = () => (screen.queryByRole('list', {name: 'Cart'})
? within(screen.getByRole('list', {name: 'Cart'})).getAllByRole('listitem').map((li) =>
[...li.childNodes].filter((n) => n.nodeType === 3).map((n) => n.textContent).join('').trim())
: []);
const cartRow = (name) => within(screen.getByRole('list', {name: 'Cart'})).getAllByRole('listitem').find((li) => li.textContent.startsWith(name + ' '));
const press = (user, name, label) => user.click(within(cartRow(name)).getByRole('button', {name: label}));
const total = () => screen.queryByText(/^Total:/)?.textContent ?? null;
test('Jede Zeile zeigt ihren Preis mal ihre Menge', async () => {
const user = userEvent.setup();
render(<ShoppingCart />);
await add(user, 'Bread');
await add(user, 'Bread');
await add(user, 'Apple');
assert.deepEqual(cartLines(), ['Bread × 2 €4.98', 'Apple × 1 €0.50'], 'die Zeilen des Warenkorbs lauten ' + JSON.stringify(cartLines()));
});
test('Die Summe addiert alle Zeilen', async () => {
const user = userEvent.setup();
render(<ShoppingCart />);
for (let i = 0; i < 3; i++) await add(user, 'Apple');
await add(user, 'Cheese');
assert.equal(total(), 'Total: €5.75', 'mit Apple × 3 und Cheese × 1 zeigt die Seite ' + JSON.stringify(total()));
});
test('Add 2 fügt zwei auf einmal hinzu', async () => {
const user = userEvent.setup();
render(<ShoppingCart />);
await add(user, 'Cheese', 'Add 2');
assert.deepEqual(cartLines(), ['Cheese × 2 €8.50'], 'nach einem Klick auf Add 2 lauten die Zeilen des Warenkorbs ' + JSON.stringify(cartLines()));
await add(user, 'Cheese', 'Add 2');
assert.deepEqual(cartLines(), ['Cheese × 4 €17.00'], 'nach zwei Klicks auf Add 2 lauten die Zeilen des Warenkorbs ' + JSON.stringify(cartLines()));
});
test('Ein leerer Warenkorb zeigt keine Summe', async () => {
const user = userEvent.setup();
render(<ShoppingCart />);
assert.equal(total(), null, 'der leere Warenkorb zeigt ' + JSON.stringify(total()));
await add(user, 'Apple');
await press(user, 'Apple', 'Remove');
assert.equal(total(), null, 'nach dem Entfernen des letzten Eintrags zeigt die Seite ' + JSON.stringify(total()));
assert.ok(screen.queryByText('Your cart is empty.'), 'die Meldung für den leeren Warenkorb wird nicht angezeigt');
});