Bug-ul
Un magazin online de mobilă importă prețurile din fișierul furnizorului. Fișierul folosește formatul românesc, cu punct la mii și virgulă la zecimale, așa că o canapea apare ca 1.299,00. Scriptul de import transformă acest text în număr cu parseFloat din JavaScript, care citește de la stânga și se oprește la primul caracter pe care nu-l poate folosi. În JavaScript, punctul e separatorul zecimal, așa că îl acceptă, se oprește la virgulă și întoarce 1.299: un leu și ceva, adică 1,299 lei în scrierea noastră. Rotunjit la două zecimale, canapeaua costă 1,30 lei.
Cum se vede
Importul se termină fără nicio eroare, iar fiecare produs de 1.000 de lei sau mai mult se vinde acum cu a mia parte din preț. Și produsele mai ieftine se strică, mai discret: 999,99 iese 999, pentru că parseFloat se oprește la virgulă și pierde zecimalele. Number("1.299,00") ar fi întors NaN și ar fi picat zgomotos; parseFloat pică în tăcere. Primii care observă sunt clienții care găsesc o canapea la 1,30 lei și o comandă.
Cum îl găsește un test
Dai importului exact prețurile care păcălesc un parser îngăduitor și verifici valorile exacte care ies. O valoare de o mie de ori prea mică, sau una care și-a pierdut zecimalele, înseamnă test picat. Oricine poate verifica asta în consola browserului: parseFloat("1.299,00") întoarce 1.299.
Reparația
Prețurile se parsează cu reguli explicite: se scot punctele de la mii, virgula zecimală devine punct, apoi se face conversia. Orice valoare care nu respectă formatul e respinsă și oprește importul. Un filtru ține pe loc importurile care mută un preț peste un procent stabilit, până le aprobă cineva.
Testul care îl prinde
Teste de import cu 1.299,00, 999,99 și 12.345,50, care așteaptă exact 1299.00, 999.99 și 12345.50 (adică 1.299,00, 999,99 și 12.345,50 lei), plus un test că o schimbare de preț peste prag așteaptă aprobare. Rulează la fiecare modificare a scriptului de import.
import { test, expect } from "@playwright/test";
import { importPrices, parsePrice } from "../src/import";
const fixtures: [text: string, lei: number][] = [
["1.299,00", 1299.0],
["999,99", 999.99],
["12.345,50", 12345.5],
];
for (const [text, lei] of fixtures) {
test(`reads ${text} as ${lei} lei`, () => {
expect(parsePrice(text)).toBe(lei);
});
}
test("a value that doesn't match the format stops the import", () => {
expect(() => parsePrice("1.299")).toThrow();
});
test("a large price change waits for approval", async () => {
const result = await importPrices([{ sku: "SOFA-3", price: "1,30" }], {
current: { "SOFA-3": 1299 },
});
expect(result.held).toEqual(["SOFA-3"]);
});
Ce pune în pericol
Cel mai scump stoc, vândut pe nimic până observă cineva. Apoi vin anulările, rambursările și clienții care se simt păcăliți.
