diff --git a/src/App.test.tsx b/src/App.test.tsx index fa71d96..6eb6e28 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -3,11 +3,8 @@ import userEvent from "@testing-library/user-event"; import { describe, expect, it } from "vitest"; import { App } from "./App"; import { budgetsDB, calcHistDB, optionsDB } from "./db"; -import { - budgetContextSpy, - testBudget, - testEmptyBudgetContext, -} from "./setupTests"; +import { budgetContextSpy, testEmptyBudgetContext } from "./setupTests"; +import { BudgetMother } from "./guitos/domain/budget.mother"; describe("App", () => { const comp = ; @@ -29,11 +26,11 @@ describe("App", () => { expect(calcHistDB.config("name")).toBe("guitos"); expect(calcHistDB.config("storeName")).toBe("calcHistDB"); await expect( - budgetsDB.getItem(testBudget.id.toString()), + budgetsDB.getItem(BudgetMother.testBudget().id.toString()), ).resolves.toBeNull(); }); - it.skip("shows new budget when clicking new button", async () => { + it("shows new budget when clicking new button", async () => { render(comp); const newButton = screen.getAllByRole("button", { name: "new budget" }); await act(async () => { @@ -44,17 +41,17 @@ describe("App", () => { expect(await screen.findByText("Statistics")).toBeInTheDocument(); expect(await screen.findByText("Revenue")).toBeInTheDocument(); expect(await screen.findByText("Expenses")).toBeInTheDocument(); - await expect(budgetsDB.getItem(testBudget.id.toString())).resolves.toEqual( - testBudget, - ); + await expect( + budgetsDB.getItem(BudgetMother.testBudget().id.toString()), + ).resolves.toEqual(BudgetMother.testBudget()); }); - it.skip("deletes budget when clicking delete button", async () => { + it("deletes budget when clicking delete button", async () => { render(comp); await act(async () => { await expect( - budgetsDB.getItem(testBudget.id.toString()), - ).resolves.toEqual(testBudget); + budgetsDB.getItem(BudgetMother.testBudget().id.toString()), + ).resolves.toEqual(BudgetMother.testBudget()); }); const newButton = await screen.findAllByRole("button", { @@ -73,7 +70,7 @@ describe("App", () => { await act(async () => { await expect( - budgetsDB.getItem(testBudget.id.toString()), + budgetsDB.getItem(BudgetMother.testBudget().id.toString()), ).resolves.toBeNull(); }); }); diff --git a/src/components/Budget/BudgetPage.test.tsx b/src/components/Budget/BudgetPage.test.tsx index 5db5b45..c042545 100644 --- a/src/components/Budget/BudgetPage.test.tsx +++ b/src/components/Budget/BudgetPage.test.tsx @@ -9,12 +9,11 @@ import { redoMock, setBudgetMock, setNotificationsMock, - testBudget, - testBudgetClone, testBudgetContext, undoMock, } from "../../setupTests"; import { BudgetPage } from "./BudgetPage"; +import { BudgetMother } from "../../guitos/domain/budget.mother"; describe("BudgetPage", () => { const comp = ( @@ -53,7 +52,7 @@ describe("BudgetPage", () => { await screen.findByRole("button", { name: "confirm budget deletion" }), ); await expect( - budgetsDB.getItem(testBudget.id.toString()), + budgetsDB.getItem(BudgetMother.testBudget().id.toString()), ).resolves.toBeNull(); }); @@ -68,7 +67,10 @@ describe("BudgetPage", () => { name: "clone budget", }); await userEvent.click(cloneButton[0]); - expect(setBudgetMock).toHaveBeenCalledWith(testBudgetClone, true); + expect(setBudgetMock).toHaveBeenCalledWith( + BudgetMother.testBudgetClone(), + true, + ); }); it.skip("responds to clone budget keyboard shortcut", async () => { @@ -79,7 +81,10 @@ describe("BudgetPage", () => { await userEvent.click(newButton[0]); await userEvent.type(await screen.findByTestId("header"), "c"); - expect(setBudgetMock).toHaveBeenCalledWith(testBudgetClone, true); + expect(setBudgetMock).toHaveBeenCalledWith( + BudgetMother.testBudgetClone(), + true, + ); }); it("responds to undo change keyboard shortcut", async () => { diff --git a/src/components/CalculateButton/CalculateButton.test.tsx b/src/components/CalculateButton/CalculateButton.test.tsx index 7aa8dfa..a8ca00e 100644 --- a/src/components/CalculateButton/CalculateButton.test.tsx +++ b/src/components/CalculateButton/CalculateButton.test.tsx @@ -3,15 +3,15 @@ import userEvent from "@testing-library/user-event"; import { BrowserRouter } from "react-router-dom"; import { vi } from "vitest"; import { describe, expect, it } from "vitest"; -import { itemForm1 } from "../../setupTests"; import { CalculateButton } from "./CalculateButton"; +import { BudgetItemsMother } from "../../guitos/domain/budgetItem.mother"; describe("CalculateButton", () => { const onCalculate = vi.fn(); const comp = ( diff --git a/src/components/Chart/Chart.test.tsx b/src/components/Chart/Chart.test.tsx index e1f7234..831b1f3 100644 --- a/src/components/Chart/Chart.test.tsx +++ b/src/components/Chart/Chart.test.tsx @@ -1,9 +1,8 @@ import { render, screen } from "@testing-library/react"; import { vi } from "vitest"; import { afterEach, beforeEach, describe, expect, it } from "vitest"; -import type { Budget } from "../../guitos/domain/budget"; -import { testBudgetList } from "../../setupTests"; import { Chart } from "./Chart"; +import { BudgetMother } from "../../guitos/domain/budget.mother"; describe("Chart", () => { const comp = ( @@ -14,7 +13,7 @@ describe("Chart", () => { areaStroke1={"highlight"} areaFill1={"highlight"} legend1={"median revenue"} - legendValues1={testBudgetList.map((b: Budget) => { + legendValues1={BudgetMother.testBudgetList().map((b) => { return b.incomes.total; })} /> diff --git a/src/components/ItemForm/ItemFormGroup.test.tsx b/src/components/ItemForm/ItemFormGroup.test.tsx index 8fc1755..286eae2 100644 --- a/src/components/ItemForm/ItemFormGroup.test.tsx +++ b/src/components/ItemForm/ItemFormGroup.test.tsx @@ -5,19 +5,19 @@ import { BrowserRouter } from "react-router-dom"; import { describe, expect, it } from "vitest"; import { configContextSpy, - itemForm1, setBudgetMock, - testBudget, testSpanishConfigContext, } from "../../setupTests"; import { ItemFormGroup } from "./ItemFormGroup"; +import { BudgetMother } from "../../guitos/domain/budget.mother"; +import { BudgetItemsMother } from "../../guitos/domain/budgetItem.mother"; describe("ItemFormGroup", () => { const ref = createRef(); const comp = ( { expect(screen.getByDisplayValue("name1change name")).toBeInTheDocument(); expect(setBudgetMock).toHaveBeenCalledWith( { - ...testBudget, + ...BudgetMother.testBudget(), expenses: { items: [{ id: 1, name: "name1change name", value: 10 }], total: 10, @@ -60,13 +60,13 @@ describe("ItemFormGroup", () => { expect(screen.getByDisplayValue("$123")).toBeInTheDocument(); expect(setBudgetMock).toHaveBeenCalledWith( { - ...testBudget, + ...BudgetMother.testBudget(), expenses: { items: [{ id: 1, name: "expense1", value: 123 }], total: 123, }, stats: { - ...testBudget.stats, + ...BudgetMother.testBudget().stats, available: -23, withGoal: -33, }, @@ -87,10 +87,10 @@ describe("ItemFormGroup", () => { expect(setBudgetMock).toHaveBeenCalledWith( { - ...testBudget, + ...BudgetMother.testBudget(), expenses: { items: [], total: 0 }, stats: { - ...testBudget.stats, + ...BudgetMother.testBudget().stats, available: 100, withGoal: 90, }, @@ -126,7 +126,7 @@ describe("ItemFormGroup", () => { render( { const comp = ( @@ -49,7 +49,7 @@ describe("LandingPage", () => { const uploadEl = screen.getByTestId("import-form-control-landing-page"); await userEvent.upload( uploadEl, - new File([JSON.stringify(testBudget)], "test"), + new File([JSON.stringify(BudgetMother.testBudget())], "test"), ); expect((uploadEl as HTMLInputElement).files).toHaveLength(1); }); diff --git a/src/components/NavBar/NavBar.test.tsx b/src/components/NavBar/NavBar.test.tsx index 3ff53fa..80a7a9c 100644 --- a/src/components/NavBar/NavBar.test.tsx +++ b/src/components/NavBar/NavBar.test.tsx @@ -5,11 +5,10 @@ import { describe, expect, it } from "vitest"; import { budgetContextSpy, setBudgetMock, - testBudget, - testBudgetClone, testEmptyBudgetContext, } from "../../setupTests"; import { NavBar } from "./NavBar"; +import { BudgetMother } from "../../guitos/domain/budget.mother"; describe("NavBar", () => { const comp = ( @@ -57,7 +56,10 @@ describe("NavBar", () => { render(comp); setBudgetMock.mockClear(); await userEvent.click(screen.getByLabelText("clone budget")); - expect(setBudgetMock).toHaveBeenCalledWith(testBudgetClone, true); + expect(setBudgetMock).toHaveBeenCalledWith( + BudgetMother.testBudgetClone(), + true, + ); }); it("triggers event when import button is pressed", async () => { @@ -66,7 +68,7 @@ describe("NavBar", () => { const uploadEl = screen.getByTestId("import-form-control"); await userEvent.upload( uploadEl, - new File([JSON.stringify(testBudget)], "budget", { + new File([JSON.stringify(BudgetMother.testBudget())], "budget", { type: "application/json", }), ); @@ -114,7 +116,7 @@ describe("NavBar", () => { expect(screen.getByDisplayValue("2023-03change name")).toBeInTheDocument(); expect(setBudgetMock).toHaveBeenCalledWith( - { ...testBudget, name: "2023-03change name" }, + { ...BudgetMother.testBudget(), name: "2023-03change name" }, false, ); }); diff --git a/src/components/StatCard/StatCard.test.tsx b/src/components/StatCard/StatCard.test.tsx index da0d859..d3783ee 100644 --- a/src/components/StatCard/StatCard.test.tsx +++ b/src/components/StatCard/StatCard.test.tsx @@ -2,8 +2,9 @@ import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { vi } from "vitest"; import { describe, expect, it } from "vitest"; -import { setBudgetMock, testBudget } from "../../setupTests"; +import { setBudgetMock } from "../../setupTests"; import { StatCard } from "./StatCard"; +import { BudgetMother } from "../../guitos/domain/budget.mother"; describe("StatCard", () => { const onShowGraphs = vi.fn(); @@ -29,7 +30,10 @@ describe("StatCard", () => { await userEvent.type(screen.getByLabelText("reserves"), "2"); expect(setBudgetMock).toHaveBeenCalledWith( - { ...testBudget, stats: { ...testBudget.stats, reserves: 2 } }, + { + ...BudgetMother.testBudget(), + stats: { ...BudgetMother.testBudget().stats, reserves: 2 }, + }, false, ); expect(screen.getByDisplayValue("$2")).toBeInTheDocument(); @@ -38,8 +42,13 @@ describe("StatCard", () => { await userEvent.type(screen.getByTestId("goal-input"), "95"); expect(setBudgetMock).toHaveBeenCalledWith( { - ...testBudget, - stats: { ...testBudget.stats, goal: 95, saved: 95, withGoal: -5 }, + ...BudgetMother.testBudget(), + stats: { + ...BudgetMother.testBudget().stats, + goal: 95, + saved: 95, + withGoal: -5, + }, }, false, ); @@ -55,8 +64,13 @@ describe("StatCard", () => { ); expect(setBudgetMock).toHaveBeenCalledWith( { - ...testBudget, - stats: { ...testBudget.stats, goal: 90, saved: 90, withGoal: 0 }, + ...BudgetMother.testBudget(), + stats: { + ...BudgetMother.testBudget().stats, + goal: 90, + saved: 90, + withGoal: 0, + }, }, true, ); diff --git a/src/components/TableCard/TableCard.test.tsx b/src/components/TableCard/TableCard.test.tsx index 50a5c3e..9370473 100644 --- a/src/components/TableCard/TableCard.test.tsx +++ b/src/components/TableCard/TableCard.test.tsx @@ -2,8 +2,9 @@ import { cleanup, render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { BrowserRouter } from "react-router-dom"; import { describe, expect, it } from "vitest"; -import { setBudgetMock, testBudget } from "../../setupTests"; +import { setBudgetMock } from "../../setupTests"; import TableCard from "./TableCard"; +import { BudgetMother } from "../../guitos/domain/budget.mother"; describe("TableCard", () => { const comp = ( @@ -39,7 +40,7 @@ describe("TableCard", () => { expect(setBudgetMock).toHaveBeenCalledWith( { - ...testBudget, + ...BudgetMother.testBudget(), expenses: { items: [{ id: 1, name: "expense1change name", value: 10 }], total: 10, @@ -54,13 +55,13 @@ describe("TableCard", () => { expect(screen.getByDisplayValue("$123")).toBeInTheDocument(); expect(setBudgetMock).toHaveBeenCalledWith( { - ...testBudget, + ...BudgetMother.testBudget(), expenses: { items: [{ id: 1, name: "expense1", value: 123 }], total: 123, }, stats: { - ...testBudget.stats, + ...BudgetMother.testBudget().stats, available: -23, withGoal: -33, }, @@ -77,9 +78,12 @@ describe("TableCard", () => { expect(screen.getByDisplayValue("$10")).toBeInTheDocument(); expect(setBudgetMock).toHaveBeenCalledWith( { - ...testBudget, + ...BudgetMother.testBudget(), expenses: { - items: [...testBudget.expenses.items, { id: 2, name: "", value: 0 }], + items: [ + ...BudgetMother.testBudget().expenses.items, + { id: 2, name: "", value: 0 }, + ], total: 10, }, }, @@ -100,9 +104,12 @@ describe("TableCard", () => { expect(screen.getByDisplayValue("$100")).toBeInTheDocument(); expect(setBudgetMock).toHaveBeenCalledWith( { - ...testBudget, + ...BudgetMother.testBudget(), incomes: { - items: [...testBudget.incomes.items, { id: 3, name: "", value: 0 }], + items: [ + ...BudgetMother.testBudget().incomes.items, + { id: 3, name: "", value: 0 }, + ], total: 100, }, }, @@ -120,13 +127,13 @@ describe("TableCard", () => { ); expect(setBudgetMock).toHaveBeenCalledWith( { - ...testBudget, + ...BudgetMother.testBudget(), expenses: { items: [], total: 0, }, stats: { - ...testBudget.stats, + ...BudgetMother.testBudget().stats, available: 100, withGoal: 90, }, diff --git a/src/context/BudgetContext.test.tsx b/src/context/BudgetContext.test.tsx index c1bbc3e..b3aebcc 100644 --- a/src/context/BudgetContext.test.tsx +++ b/src/context/BudgetContext.test.tsx @@ -1,7 +1,7 @@ import { render, screen } from "@testing-library/react"; import { describe, expect, it } from "vitest"; -import { testBudget, testBudgetList } from "../setupTests"; import { BudgetProvider, useBudget } from "./BudgetContext"; +import { BudgetMother } from "../guitos/domain/budget.mother"; function TestComponent() { const { budget, budgetList } = useBudget(); @@ -21,10 +21,10 @@ describe("BudgetProvider", () => { , ); expect(screen.getByLabelText("budget").textContent).toEqual( - JSON.stringify(testBudget), + JSON.stringify(BudgetMother.testBudget()), ); expect(screen.getByLabelText("budgetList").textContent).toEqual( - JSON.stringify(testBudgetList), + JSON.stringify(BudgetMother.testBudgetList()), ); }); }); diff --git a/src/guitos/domain/budget.mother.ts b/src/guitos/domain/budget.mother.ts new file mode 100644 index 0000000..9651d12 --- /dev/null +++ b/src/guitos/domain/budget.mother.ts @@ -0,0 +1,178 @@ +import { BudgetItem } from "./budgetItem"; +import { Uuid } from "./uuid"; +import { Budget } from "./budget"; + +// biome-ignore lint/complexity/noStaticOnlyClass: +export class BudgetMother { + static testBudget() { + return { + id: Uuid.random().value as unknown as Uuid, + name: "2023-03", + expenses: { + items: [{ id: 1, name: "expense1", value: 10 }], + total: 10, + }, + incomes: { + items: [{ id: 2, name: "income1", value: 100 }], + total: 100, + }, + stats: { + available: 90, + withGoal: 80, + saved: 10, + goal: 10, + reserves: 200, + }, + }; + } + + static testBudgetClone() { + return { + ...BudgetMother.testBudget(), + name: "2023-03-clone", + }; + } + + static testBudget2() { + return { + ...Budget.create(), + id: Uuid.random().value as unknown as Uuid, + name: "2023-04", + expenses: { + items: [{ id: 1, name: "name", value: 50 }], + total: 50, + }, + incomes: { + items: [{ id: 2, name: "name2", value: 200 }], + total: 200, + }, + stats: { + available: 150, + withGoal: 130, + saved: 20, + goal: 35, + reserves: 30, + }, + }; + } + + static testBigBudget() { + return { + ...Budget.create(), + name: "2023-03", + expenses: { + items: [ + { id: 1, name: "name", value: 11378.64 }, + { id: 4, name: "name2", value: 11378.64 }, + ], + total: 22757.28, + }, + incomes: { + items: [ + { id: 2, name: "name", value: 100.03 }, + { id: 3, name: "name2", value: 342783.83 }, + ], + total: 342883.86, + }, + stats: { + available: 320126.58, + withGoal: 148684.65, + saved: 171441.93, + goal: 50, + reserves: 200, + }, + }; + } + + static testBudgetCsv() { + return { + ...Budget.create(), + name: "2023-03", + expenses: { + items: [ + new BudgetItem(0, "rent", 1000), + new BudgetItem(1, "food", 200), + ], + total: 1200, + }, + incomes: { + items: [ + new BudgetItem(2, "salary", 2000), + new BudgetItem(3, "sale", 100), + ], + total: 2100, + }, + stats: { + available: 900, + withGoal: 690, + saved: 210, + goal: 10, + reserves: 0, + }, + }; + } + + static testBudgetList() { + return [ + BudgetMother.testBudget(), + BudgetMother.testBudget2(), + BudgetMother.testBigBudget(), + ]; + } + + static testBudgetNameList() { + return [ + { + id: BudgetMother.testBudget().id, + item: "", + name: BudgetMother.testBudget().name, + }, + { + id: BudgetMother.testBudget2().id, + item: "", + name: BudgetMother.testBudget2().name, + }, + ]; + } + + static testJSONErrorBudget() { + return `{ + id: "03123AAA5c2de4-00a4-403c-8f0e-f81339be9a4e", + na2me: "2023-03", + expens3es: { + items: [{ id: "infinity", name: -1, value: "r" }], + total: 10, + }, + stats: { + available: 0, + withGoal: 0, + saved: 0, + goal: 10, + reserves: 0, + }, +}`; + } + + static testCsv() { + return `type,name,value +expense,rent,1000.00 +expense,food,200.00 +income,salary,2000.00 +income,sale,100 +goal,goal,10 +reserves,reserves,0 +`; + } + + static testCsvError() { + return `type,name,value +expe2nse,rent,1000.00 +expense,food,200.00,123,4 +incomae,salary,2000.00 +income,sale,100 +goal,123,goal +goal,,goal,,, +reservaes,reserves,0 +`; + } +} diff --git a/src/guitos/domain/budget.test.ts b/src/guitos/domain/budget.test.ts new file mode 100644 index 0000000..7959bb8 --- /dev/null +++ b/src/guitos/domain/budget.test.ts @@ -0,0 +1,94 @@ +import Big from "big.js"; +import Papa from "papaparse"; +import { expect, test, describe } from "vitest"; +import { Budget } from "./budget"; +import { BudgetMother } from "./budget.mother"; +import { BudgetItem } from "./budgetItem"; +import { BudgetItemsMother } from "./budgetItem.mother"; + +describe("Budget", () => { + test("itemsTotal", () => { + expect( + Budget.itemsTotal([ + BudgetItemsMother.itemForm1(), + BudgetItemsMother.itemForm2(), + ]), + ).toEqual(Big(110)); + expect(Budget.itemsTotal([])).toEqual(Big(0)); + }); + + test("percentage", () => { + expect( + BudgetItem.percentage( + BudgetItemsMother.itemForm1().value, + BudgetMother.testBudget().incomes.total, + ), + ).eq(10); + expect( + BudgetItem.percentage( + BudgetItemsMother.itemForm2().value, + BudgetMother.testBudget().incomes.total, + ), + ).eq(100); + expect( + BudgetItem.percentage( + BudgetItemsMother.itemForm1().value, + BudgetMother.testBudget().expenses.total, + ), + ).eq(100); + expect( + BudgetItem.percentage( + BudgetItemsMother.itemForm2().value, + BudgetMother.testBudget().expenses.total, + ), + ).eq(1000); + expect(BudgetItem.percentage(0, 0)).eq(0); + expect( + BudgetItem.percentage(0, BudgetMother.testBudget().incomes.total), + ).eq(0); + expect( + BudgetItem.percentage(0, BudgetMother.testBudget().expenses.total), + ).eq(0); + }); + + test("available", () => { + expect(Budget.available(BudgetMother.testBudget() as Budget)).toEqual( + Big(90), + ); + expect(Budget.available(undefined)).toEqual(Big(0)); + }); + + test("availableWithGoal", () => { + expect(Budget.availableWithGoal(BudgetMother.testBudget() as Budget)).eq( + 80, + ); + }); + + test("saved", () => { + expect(Budget.saved(BudgetMother.testBudget() as Budget)).eq(10); + }); + + test("automaticGoal", () => { + expect(Budget.automaticGoal(BudgetMother.testBigBudget())).eq(93.36298); + }); + + test("fromCsv", () => { + const csvObject = Papa.parse(BudgetMother.testCsv() as string, { + header: true, + skipEmptyLines: "greedy", + }); + expect(Budget.fromCsv(csvObject.data as string[], "2023-03")).toEqual( + BudgetMother.testBudgetCsv(), + ); + }); + + test("toCsv", () => { + expect(Budget.toCsv(BudgetMother.testBigBudget())).eq(`type,name,value +expense,name,11378.64 +expense,name2,11378.64 +income,name,100.03 +income,name2,342783.83 +goal,goal,50 +reserves,reserves,200`); + }); +}); diff --git a/src/guitos/domain/budgetItem.mother.ts b/src/guitos/domain/budgetItem.mother.ts index 9cdede5..055db13 100644 --- a/src/guitos/domain/budgetItem.mother.ts +++ b/src/guitos/domain/budgetItem.mother.ts @@ -25,4 +25,12 @@ export class BudgetItemsMother { return faker.helpers.arrayElements(list); } + + static itemForm1() { + return new BudgetItem(1, "name1", 10); + } + + static itemForm2() { + return new BudgetItem(2, "name2", 100); + } } diff --git a/src/guitos/domain/calculationHistoryItem.mother.ts b/src/guitos/domain/calculationHistoryItem.mother.ts new file mode 100644 index 0000000..dce8ec5 --- /dev/null +++ b/src/guitos/domain/calculationHistoryItem.mother.ts @@ -0,0 +1,26 @@ +import { BudgetMother } from "./budget.mother"; +import { BudgetItemsMother } from "./budgetItem.mother"; + +// biome-ignore lint/complexity/noStaticOnlyClass: +export class CalculationHistoryItemMother { + static testCalcHist() { + return [ + { + id: `${BudgetMother.testBudget().id}-Expenses-1`, + itemForm: BudgetItemsMother.itemForm1(), + changeValue: 123, + operation: "add", + }, + { + id: `${BudgetMother.testBudget().id}-Expenses-1`, + itemForm: { + id: 1, + name: BudgetItemsMother.itemForm1().name, + value: 133, + }, + changeValue: 3, + operation: "add", + }, + ]; + } +} diff --git a/src/setupTests.ts b/src/setupTests.ts index 8461b43..9bfc068 100644 --- a/src/setupTests.ts +++ b/src/setupTests.ts @@ -11,9 +11,7 @@ import { afterEach, beforeEach, expect, vi } from "vitest"; import * as AppBudgetContext from "./context/BudgetContext"; import * as AppConfigContext from "./context/ConfigContext"; import * as AppGeneralContext from "./context/GeneralContext"; -import { Budget } from "./guitos/domain/budget"; -import { BudgetItem } from "./guitos/domain/budgetItem"; -import { Uuid } from "./guitos/domain/uuid"; +import { BudgetMother } from "./guitos/domain/budget.mother"; window.crypto.randomUUID = randomUUID; global.URL.createObjectURL = vi.fn(); @@ -66,191 +64,9 @@ Object.defineProperty(window, "matchMedia", { dispatchEvent: vi.fn(), })), }); - -export const testBudget = { - ...Budget.create(), - id: Uuid.random().value as unknown as Uuid, - name: "2023-03", - expenses: { - items: [{ id: 1, name: "expense1", value: 10 }], - total: 10, - }, - incomes: { - items: [{ id: 2, name: "income1", value: 100 }], - total: 100, - }, - stats: { - available: 90, - withGoal: 80, - saved: 10, - goal: 10, - reserves: 200, - }, -}; - -export const testBudgetClone = { - ...testBudget, - name: "2023-03-clone", -}; - -export const testBudget2: Budget = { - ...Budget.create(), - id: Uuid.random().value as unknown as Uuid, - name: "2023-04", - expenses: { - items: [{ id: 1, name: "name", value: 50 }], - total: 50, - }, - incomes: { - items: [{ id: 2, name: "name2", value: 200 }], - total: 200, - }, - stats: { - available: 150, - withGoal: 130, - saved: 20, - goal: 35, - reserves: 30, - }, -}; - -export const testBigBudget: Budget = { - ...Budget.create(), - name: "2023-03", - expenses: { - items: [ - { id: 1, name: "name", value: 11378.64 }, - { id: 4, name: "name2", value: 11378.64 }, - ], - total: 22757.28, - }, - incomes: { - items: [ - { id: 2, name: "name", value: 100.03 }, - { id: 3, name: "name2", value: 342783.83 }, - ], - total: 342883.86, - }, - stats: { - available: 320126.58, - withGoal: 148684.65, - saved: 171441.93, - goal: 50, - reserves: 200, - }, -}; - -export const testJSONErrorBudget = `{ - id: "03123AAA5c2de4-00a4-403c-8f0e-f81339be9a4e", - na2me: "2023-03", - expens3es: { - items: [{ id: "infinity", name: -1, value: "r" }], - total: 10, - }, - stats: { - available: 0, - withGoal: 0, - saved: 0, - goal: 10, - reserves: 0, - }, -}`; - -export const testCsv = `type,name,value -expense,rent,1000.00 -expense,food,200.00 -income,salary,2000.00 -income,sale,100 -goal,goal,10 -reserves,reserves,0 -`; - -export const testCsvError = `type,name,value -expe2nse,rent,1000.00 -expense,food,200.00,123,4 -incomae,salary,2000.00 -income,sale,100 -goal,123,goal -goal,,goal,,, -reservaes,reserves,0 -`; - -export const testBudgetCsv: Budget = { - ...Budget.create(), - name: "2023-03", - expenses: { - items: [new BudgetItem(0, "rent", 1000), new BudgetItem(1, "food", 200)], - total: 1200, - }, - incomes: { - items: [new BudgetItem(2, "salary", 2000), new BudgetItem(3, "sale", 100)], - total: 2100, - }, - stats: { - available: 900, - withGoal: 690, - saved: 210, - goal: 10, - reserves: 0, - }, -}; - -export const budgetNameList = [ - { - id: "035c2de4-01a4-403c-8f0e-f81340be9a4e", - name: "2023-03", - }, - { - id: "035c2de4-00a4-403c-8f0e-f81339be9a4e", - name: "2023-04", - }, - { - id: "036c2de4-00a4-402c-8f0e-f81339be9a4e", - name: "2023-05", - }, -]; - -export const itemForm1 = new BudgetItem(1, "name1", 10); - -export const itemForm2 = new BudgetItem(2, "name2", 100); - -export const testCalcHist = [ - { - id: `${testBudget.id}-Expenses-1`, - itemForm: itemForm1, - changeValue: 123, - operation: "add", - }, - { - id: `${testBudget.id}-Expenses-1`, - itemForm: { - id: 1, - name: itemForm1.name, - value: 133, - }, - changeValue: 3, - operation: "add", - }, -]; - export const testIntlConfig = { locale: "en-US", currency: "USD" }; export const testSpanishIntlConfig = { locale: "es-ES", currency: "EUR" }; -export const testBudgetList = [testBudget, testBudget2, testBigBudget]; - -export const testBudgetNameList = [ - { - id: testBudget.id, - item: "", - name: testBudget.name, - }, - { - id: testBudget2.id, - item: "", - name: testBudget2.name, - }, -]; - export const setIntlConfigMock = vi.fn(); export const handleCurrencyMock = vi.fn(); export const testConfigContext = { @@ -293,13 +109,13 @@ export const testEmptyBudgetContext = { }; export const testBudgetContext = { - budget: testBudget, + budget: BudgetMother.testBudget(), setBudget: setBudgetMock, - budgetList: testBudgetList, + budgetList: BudgetMother.testBudgetList(), setBudgetList: setBudgetListMock, - budgetNameList: testBudgetNameList, + budgetNameList: BudgetMother.testBudgetNameList(), setBudgetNameList: setBudgetNameListMock, revenuePercentage: 10, diff --git a/src/utils.test.ts b/src/utils.test.ts index 1bc2606..7c0ddbf 100644 --- a/src/utils.test.ts +++ b/src/utils.test.ts @@ -1,24 +1,12 @@ import Big from "big.js"; -import Papa from "papaparse"; import { expect, test } from "vitest"; import type { FilteredItem } from "./components/ChartsPage/ChartsPage"; -import { Budget } from "./guitos/domain/budget"; -import { BudgetItem } from "./guitos/domain/budgetItem"; +import type { Budget } from "./guitos/domain/budget"; import type { ItemOperation } from "./guitos/domain/calculationHistoryItem"; import { Uuid } from "./guitos/domain/uuid"; import { chromeLocalesList } from "./lists/chromeLocalesList"; import { currenciesMap } from "./lists/currenciesMap"; import { firefoxLocalesList } from "./lists/firefoxLocalesList"; -import { - itemForm1, - itemForm2, - testBigBudget, - testBudget, - testBudget2, - testBudgetCsv, - testBudgetList, - testCsv, -} from "./setupTests"; import { calc, createBudgetNameList, @@ -33,6 +21,7 @@ import { parseLocaleNumber, roundBig, } from "./utils"; +import { BudgetMother } from "./guitos/domain/budget.mother"; test("round", () => { expect(roundBig(Big(123.123123123), 5)).eq(123.12312); @@ -44,56 +33,6 @@ test("round", () => { expect(roundBig(Big(123.126), 0)).eq(123); }); -test("calcTotal", () => { - expect(Budget.itemsTotal([itemForm1, itemForm2])).toEqual(Big(110)); - expect(Budget.itemsTotal([])).toEqual(Big(0)); -}); - -test("BudgetItem.percentage", () => { - expect(BudgetItem.percentage(itemForm1.value, testBudget.incomes.total)).eq( - 10, - ); - expect(BudgetItem.percentage(itemForm2.value, testBudget.incomes.total)).eq( - 100, - ); - expect(BudgetItem.percentage(itemForm1.value, testBudget.expenses.total)).eq( - 100, - ); - expect(BudgetItem.percentage(itemForm2.value, testBudget.expenses.total)).eq( - 1000, - ); - expect(BudgetItem.percentage(0, 0)).eq(0); - expect(BudgetItem.percentage(0, testBudget.incomes.total)).eq(0); - expect(BudgetItem.percentage(0, testBudget.expenses.total)).eq(0); -}); - -test("Budget.available", () => { - expect(Budget.available(testBudget)).toEqual(Big(90)); - expect(Budget.available(undefined)).toEqual(Big(0)); -}); - -test("Budget.availableWithGoal", () => { - expect(Budget.availableWithGoal(testBudget)).eq(80); -}); - -test("Budget.saved", () => { - expect(Budget.saved(testBudget)).eq(10); -}); - -test("Budget.automaticGoal", () => { - expect(Budget.automaticGoal(testBigBudget)).eq(93.36298); -}); - -test("Budget.fromCsv", () => { - const csvObject = Papa.parse(testCsv as string, { - header: true, - skipEmptyLines: "greedy", - }); - expect(Budget.fromCsv(csvObject.data as string[], "2023-03")).toEqual( - testBudgetCsv, - ); -}); - test("createBudgetNameList", () => { const expectedResult = [ { @@ -107,9 +46,12 @@ test("createBudgetNameList", () => { name: "2023-04", }, ]; - expect(createBudgetNameList([testBudget, testBudget2])).toEqual( - expectedResult, - ); + expect( + createBudgetNameList([ + BudgetMother.testBudget() as Budget, + BudgetMother.testBudget2() as Budget, + ]), + ).toEqual(expectedResult); expect(createBudgetNameList([])).toEqual([]); }); @@ -148,16 +90,6 @@ test("parseLocaleNumber", () => { expect(parseLocaleNumber("1,20,54,100.55", "en-IN")).eq(12054100.55); }); -test("Budget.toCsv", () => { - expect(Budget.toCsv(testBigBudget)).eq(`type,name,value -expense,name,11378.64 -expense,name2,11378.64 -income,name,100.03 -income,name2,342783.83 -goal,goal,50 -reserves,reserves,200`); -}); - test("calc", () => { expect(calc(123.45, 100, "add")).eq(223.45); expect(calc(123.45, 100, "subtract")).eq(23.45); @@ -181,22 +113,24 @@ test("median", () => { }); test("getNestedProperty", () => { - expect(getNestedProperty(testBudget, "expenses", "total")).eq(10); - expect(getNestedProperty(testBudget, "incomes", "items")).eq( - testBudget.incomes.items, + expect(getNestedProperty(BudgetMother.testBudget(), "expenses", "total")).eq( + 10, ); + expect( + getNestedProperty(BudgetMother.testBudget(), "incomes", "items"), + ).toEqual(BudgetMother.testBudget().incomes.items); }); test("getNestedValues", () => { - const expected = testBudgetList.map((i) => i.expenses.total); - const expected2 = testBudgetList.map((i) => i.incomes.items); - - expect(getNestedValues(testBudgetList, "expenses", "total")).toEqual( - expected, - ); - expect(getNestedValues(testBudgetList, "incomes", "items")).toEqual( - expected2, - ); + const expected = BudgetMother.testBudgetList().map((i) => i.expenses.total); + const expected2 = BudgetMother.testBudgetList().map((i) => i.incomes.items); + + expect( + getNestedValues(BudgetMother.testBudgetList(), "expenses", "total"), + ).toEqual(expected); + expect( + getNestedValues(BudgetMother.testBudgetList(), "incomes", "items"), + ).toEqual(expected2); }); test("getLabelKey", () => {