Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/fac30/things-we-do into fea…
Browse files Browse the repository at this point in the history
…ture/ephemeral-category-creation
  • Loading branch information
JasonWarrenUK committed Dec 10, 2024
2 parents be41783 + d9aef79 commit d33ddb5
Show file tree
Hide file tree
Showing 21 changed files with 461 additions and 427 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Run Tests on Push

on:
pull_request:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"

- name: Install dependencies
run: npm install --legacy-peer-deps

- name: Run tests
run: npm run test
70 changes: 40 additions & 30 deletions __tests__/LineGraph.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,47 @@ describe("LineGraph Component", () => {
},
];

const mockStartOfRange = new Date("2023-01-01T00:00:00Z");
const mockEndOfRange = new Date("2023-12-31T23:59:59Z");

it("renders without crashing", () => {
render(<LineGraph dataArray={mockData} />);
expect(screen.getByText("day")).toBeInTheDocument();
expect(screen.getByText("week")).toBeInTheDocument();
expect(screen.getByText("month")).toBeInTheDocument();
expect(screen.getByText("year")).toBeInTheDocument();
render(
<LineGraph
dataArray={mockData}
startOfRange={mockStartOfRange}
endOfRange={mockEndOfRange}
selectedButton="day"
/>
);

const plotlyChart = screen.getByTestId("plotly-chart");
expect(plotlyChart).toBeInTheDocument();
});

it("displays a message when no data is available", () => {
render(<LineGraph dataArray={[]} />);
render(
<LineGraph
dataArray={[]}
startOfRange={mockStartOfRange}
endOfRange={mockEndOfRange}
selectedButton=""
/>
);

expect(
screen.getByText("No data available for the graph.")
).toBeInTheDocument();
});

it("correctly sets the x-axis and y-axis data", () => {
render(<LineGraph dataArray={mockData} />);
render(
<LineGraph
dataArray={mockData}
startOfRange={mockStartOfRange}
endOfRange={mockEndOfRange}
selectedButton="day"
/>
);

const plotlyChart = screen.getByTestId("plotly-chart");
const plotlyData = JSON.parse(
Expand All @@ -48,32 +72,18 @@ describe("LineGraph Component", () => {

expect(plotlyData).toHaveLength(3);

const dopamineTrace = plotlyData.find((d) => d.name === "Urgent");
const serotoninTrace = plotlyData.find((d) => d.name === "Effortful");
const adrenalineTrace = plotlyData.find((d) => d.name === "Worthwile");
const dopamineTrace = plotlyData.find(
(d: { name: string }) => d.name === "Urgent"
);
const serotoninTrace = plotlyData.find(
(d: { name: string }) => d.name === "Effortful"
);
const adrenalineTrace = plotlyData.find(
(d: { name: string }) => d.name === "Worthwile"
);

expect(dopamineTrace.y).toEqual([5]);
expect(serotoninTrace.y).toEqual([3]);
expect(adrenalineTrace.y).toEqual([7]);
});

it("updates the graph when the date range is changed", () => {
render(<LineGraph dataArray={mockData} />);

fireEvent.click(screen.getByText("week"));
const plotlyChart = screen.getByTestId("plotly-chart");
const plotlyData = JSON.parse(
plotlyChart.getAttribute("data-prop") || "[]"
);

expect(plotlyData).toHaveLength(3);
});

it("has the ToDate button already clicked on render", () => {
render(<LineGraph dataArray={mockData} />);

const toDateButton = screen.getByText("To Date");

expect(toDateButton).toHaveClass("bg-white text-black");
});
});
21 changes: 14 additions & 7 deletions __tests__/MoodsCube.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { render, screen, fireEvent } from "@testing-library/react";
import { NeurochemContext } from "@/context/NeurochemContext";
import { Cube } from "@/app/moods/components/Cube";
import { SliderBox } from "@/app/moods/components/SliderBox";
import { useState } from "react";
Expand All @@ -25,17 +24,26 @@ describe("Cube and SliderBox integration", () => {
adrenaline: 1 as Datum,
});

const handleChange = (
value: number,
chem: "dopamine" | "serotonin" | "adrenaline"
) => {
setNeuroState((prev) => ({
...prev,
[chem]: value,
}));
};

return (
<NeurochemContext.Provider value={{ neuroState, setNeuroState }}>
<Cube />
<SliderBox />
</NeurochemContext.Provider>
<>
<Cube neuroState={neuroState} />
<SliderBox handleChange={handleChange} neuroState={neuroState} />
</>
);
};

render(<Wrapper />);

// change slider values
const dopamineSlider = screen.getByLabelText(
"Step 1. How urgent does it feel?"
);
Expand All @@ -50,7 +58,6 @@ describe("Cube and SliderBox integration", () => {
fireEvent.change(serotoninSlider, { target: { value: "3" } });
fireEvent.change(adrenalineSlider, { target: { value: "7" } });

// check Plotly chart data prop gets updated
const plotlyChart = screen.getByTestId("plotly-chart");
const plotlyData = JSON.parse(
plotlyChart.getAttribute("data-prop") || "[]"
Expand Down
7 changes: 1 addition & 6 deletions __tests__/MoodsMatrixToggle.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { render, screen, fireEvent, act } from "@testing-library/react";
import { NeurochemContext } from "@/context/NeurochemContext";
import { Cube } from "@/app/moods/components/Cube";
import { useState } from "react";
import { Datum } from "plotly.js";
Expand All @@ -26,11 +25,7 @@ describe("Cube label updates on toggle", () => {
adrenaline: 1 as Datum,
});

return (
<NeurochemContext.Provider value={{ neuroState, setNeuroState }}>
<Cube />
</NeurochemContext.Provider>
);
return <Cube neuroState={neuroState} />;
};

render(<Wrapper />);
Expand Down
136 changes: 23 additions & 113 deletions __tests__/SortableItem.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,113 +19,6 @@ describe("SortableItem Component", () => {
jest.clearAllMocks();
});

it("renders without crashing", () => {
render(
<SortableItem
item={defaultItem}
handleToggle={mockHandleToggle}
handleDelete={mockHandleDelete}
/>
);

// Check the main container renders
const container = screen.getByText("Test Item").closest("div");
expect(container).toBeInTheDocument();
});

it("renders the checkbox, name, image, link, and delete button", () => {
render(
<SortableItem
item={defaultItem}
handleToggle={mockHandleToggle}
handleDelete={mockHandleDelete}
/>
);

// Check for the checkbox
const checkbox = screen.getByRole("checkbox");
expect(checkbox).toBeInTheDocument();
expect(checkbox).not.toBeChecked();

// Check for the item name
const itemName = screen.getByText("Test Item");
expect(itemName).toBeInTheDocument();

// Check for the image
const img = screen.getByRole("img", { name: /test item/i });
expect(img).toBeInTheDocument();
expect(img).toHaveAttribute("src", defaultItem.imageUrl);

// Check for the link
const link = screen.getByRole("link", { name: /go to resource/i });
expect(link).toBeInTheDocument();
expect(link).toHaveAttribute("href", defaultItem.infoUrl);

// Check for the delete button
const deleteButton = screen.getByText("Delete");
expect(deleteButton).toBeInTheDocument();
});

it("renders 'No Image' when imageUrl is invalid", () => {
const itemWithInvalidImage = { ...defaultItem, imageUrl: "" };

render(
<SortableItem
item={itemWithInvalidImage}
handleToggle={mockHandleToggle}
handleDelete={mockHandleDelete}
/>
);

// Check that "No Image" text is rendered
expect(screen.getByText("No Image")).toBeInTheDocument();
});

it("calls handleToggle when the checkbox is clicked", () => {
render(
<SortableItem
item={defaultItem}
handleToggle={mockHandleToggle}
handleDelete={mockHandleDelete}
/>
);

const checkbox = screen.getByRole("checkbox");
fireEvent.click(checkbox);

expect(mockHandleToggle).toHaveBeenCalledWith(defaultItem.id);
});

it("calls handleDelete when the delete button is clicked", () => {
render(
<SortableItem
item={defaultItem}
handleToggle={mockHandleToggle}
handleDelete={mockHandleDelete}
/>
);

const deleteButton = screen.getByText("Delete");
fireEvent.click(deleteButton);

expect(mockHandleDelete).toHaveBeenCalledWith(defaultItem.id);
});

it("applies line-through styling when the item is checked", () => {
const checkedItem = { ...defaultItem, checked: true };

render(
<SortableItem
item={checkedItem}
handleToggle={mockHandleToggle}
handleDelete={mockHandleDelete}
/>
);

const itemName = screen.getByText("Test Item");
expect(itemName).toHaveClass("line-through text-gray-400");
});

it("has the correct layout", () => {
const { container } = render(
<SortableItem
Expand All @@ -138,19 +31,36 @@ describe("SortableItem Component", () => {
const mainDiv = container.firstChild;
expect(mainDiv).toHaveClass(
"flex",
"flex-col",
"items-start",
"items-center",
"p-4",
"rounded-lg",
"shadow-lg",
"bg-twd-background"
);

// Check sub-layout
// Check the main content layout
const mainContent = screen.getByText("Test Item").closest("div");
expect(mainContent).toHaveClass(
"flex",
"items-center",
"space-x-3",
"w-full"
);

// Check sub-layout for the first row
const firstRow = screen.getByText("Test Item").closest("div");
expect(firstRow).toHaveClass("flex", "items-center", "space-x-3", "w-full");

const secondRow = screen.getByRole("link", { name: /go to resource/i }).closest("div");
expect(secondRow).toHaveClass("flex", "items-center", "justify-between", "mt-2", "pl-8", "w-full");
// Check sub-layout for the second row
const secondRow = screen
.getByRole("link", { name: /go to resource/i })
.closest("div");
expect(secondRow).toHaveClass(
"flex",
"items-center",
"justify-between",
"mt-2",
"w-full"
);
});
});
});
Loading

0 comments on commit d33ddb5

Please sign in to comment.