Skip to content

Commit

Permalink
Merge pull request #1502 from Avaiga/test/Metric-component
Browse files Browse the repository at this point in the history
Adding unit test for Metric component
  • Loading branch information
namnguyen20999 authored Jul 11, 2024
2 parents b2cd473 + b801b67 commit 796f4ee
Showing 1 changed file with 312 additions and 11 deletions.
323 changes: 312 additions & 11 deletions frontend/taipy-gui/src/components/Taipy/Metric.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,321 @@
*/

import React from "react";
import {render} from "@testing-library/react";
import { render, waitFor } from "@testing-library/react";
import "@testing-library/jest-dom";
import { ThemeProvider } from "@mui/material/styles";
import { createTheme } from "@mui/material/styles";

import Metric from "./Metric";

const template = {
layout: {
colorscale: {
diverging: [
[0, "#8e0152"],
[0.1, "#c51b7d"],
[0.2, "#de77ae"],
[0.3, "#f1b6da"],
[0.4, "#fde0ef"],
[0.5, "#f7f7f7"],
[0.6, "#e6f5d0"],
[0.7, "#b8e186"],
[0.8, "#7fbc41"],
[0.9, "#4d9221"],
[1, "#276419"],
],
sequential: [
[0, "#0d0887"],
[0.1111111111111111, "#46039f"],
[0.2222222222222222, "#7201a8"],
[0.3333333333333333, "#9c179e"],
[0.4444444444444444, "#bd3786"],
[0.5555555555555556, "#d8576b"],
[0.6666666666666666, "#ed7953"],
[0.7777777777777778, "#fb9f3a"],
[0.8888888888888888, "#fdca26"],
[1, "#f0f921"],
],
sequentialminus: [
[0, "#0d0887"],
[0.1111111111111111, "#46039f"],
[0.2222222222222222, "#7201a8"],
[0.3333333333333333, "#9c179e"],
[0.4444444444444444, "#bd3786"],
[0.5555555555555556, "#d8576b"],
[0.6666666666666666, "#ed7953"],
[0.7777777777777778, "#fb9f3a"],
[0.8888888888888888, "#fdca26"],
[1, "#f0f921"],
],
},
paper_bgcolor: "rgb(255,0,0)",
},
};

const colorMap = {
20: "red",
40: null,
60: "blue",
80: null,
};

const darkTemplate = {
layout: {
colorscale: {
diverging: [
[0, "#8e0152"],
[0.1, "#c51b7d"],
[0.2, "#de77ae"],
[0.3, "#f1b6da"],
[0.4, "#fde0ef"],
[0.5, "#f7f7f7"],
[0.6, "#e6f5d0"],
[0.7, "#b8e186"],
[0.8, "#7fbc41"],
[0.9, "#4d9221"],
[1, "#276419"],
],
sequential: [
[0, "#0d0887"],
[0.1111111111111111, "#46039f"],
[0.2222222222222222, "#7201a8"],
[0.3333333333333333, "#9c179e"],
[0.4444444444444444, "#bd3786"],
[0.5555555555555556, "#d8576b"],
[0.6666666666666666, "#ed7953"],
[0.7777777777777778, "#fb9f3a"],
[0.8888888888888888, "#fdca26"],
[1, "#f0f921"],
],
sequentialminus: [
[0, "#0d0887"],
[0.1111111111111111, "#46039f"],
[0.2222222222222222, "#7201a8"],
[0.3333333333333333, "#9c179e"],
[0.4444444444444444, "#bd3786"],
[0.5555555555555556, "#d8576b"],
[0.6666666666666666, "#ed7953"],
[0.7777777777777778, "#fb9f3a"],
[0.8888888888888888, "#fdca26"],
[1, "#f0f921"],
],
},
paper_bgcolor: "rgb(31,47,68)",
},
};

const lightTemplate = {
layout: {
colorscale: {
diverging: [
[0, "#053061"],
[0.1, "#2166ac"],
[0.2, "#4393c3"],
[0.3, "#92c5de"],
[0.4, "#d1e5f0"],
[0.5, "#f7f7f7"],
[0.6, "#fddbc7"],
[0.7, "#f4a582"],
[0.8, "#d6604d"],
[0.9, "#b2182b"],
[1, "#67001f"],
],
sequential: [
[0, "#f7fcf5"],
[0.1111111111111111, "#e5f5e0"],
[0.2222222222222222, "#c7e9c0"],
[0.3333333333333333, "#a1d99b"],
[0.4444444444444444, "#74c476"],
[0.5555555555555556, "#41ab5d"],
[0.6666666666666666, "#238b45"],
[0.7777777777777778, "#006d2c"],
[0.8888888888888888, "#00441b"],
[1, "#000000"],
],
sequentialminus: [
[0, "#f7fcf5"],
[0.1111111111111111, "#e5f5e0"],
[0.2222222222222222, "#c7e9c0"],
[0.3333333333333333, "#a1d99b"],
[0.4444444444444444, "#74c476"],
[0.5555555555555556, "#41ab5d"],
[0.6666666666666666, "#238b45"],
[0.7777777777777778, "#006d2c"],
[0.8888888888888888, "#00441b"],
[1, "#000000"],
],
},
paper_bgcolor: "rgb(255,255,255)",
},
};

describe("Metric Component", () => {
it("renders", async () => {
const { getByTestId } = render(<Metric testId="test-id"/>);
const elt = getByTestId("test-id");
expect(elt.tagName).toBe("DIV");
})
it("displays the right info for class", async () => {
const { getByTestId } = render(<Metric testId="test-id" className={'taipy-gauge'}/>);
const elt = getByTestId('test-id');
expect(elt).toHaveClass('taipy-gauge');
})
it("renders", async () => {
const { getByTestId } = render(<Metric testId="test-id" />);
const elt = getByTestId("test-id");
expect(elt.tagName).toBe("DIV");
});

it("displays the right info for class", async () => {
const { getByTestId } = render(<Metric testId="test-id" className={"taipy-gauge"} />);
const elt = getByTestId("test-id");
expect(elt).toHaveClass("taipy-gauge");
});

it("sets the title when provided", async () => {
const title = "Test Title";
const { container } = render(<Metric title={title} />);
await waitFor(() => {
const titleElement = container.querySelector(".gtitle");
if (!titleElement) {
throw new Error("Title element not found");
}
expect(titleElement.textContent).toContain(title);
});
});

it("logs an error when template prop is a malformed JSON string", () => {
const consoleSpy = jest.spyOn(console, "info");
const malformedJson = "{ key: 'value'";
render(<Metric template={malformedJson} />);
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error while parsing Metric.template"));
consoleSpy.mockRestore();
});

it("logs an error when colorMap prop is a malformed JSON string", () => {
const consoleSpy = jest.spyOn(console, "info");
const malformedJson = "{ key: 'value'"; // missing closing brace
render(<Metric colorMap={malformedJson} />);
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error parsing color_map value (metric)"));
consoleSpy.mockRestore();
});

it("sets the template when provided", async () => {
render(<Metric template={JSON.stringify(template)} />);
await waitFor(() => {
const elt = document.querySelector(".main-svg");
expect(elt).toHaveStyle({
backgroundColor: "rgb(255, 0, 0)",
});
});
});

it("processes colorMap prop correctly", async () => {
render(<Metric colorMap={JSON.stringify(colorMap)} />);
await waitFor(() => {
const elts = document.querySelectorAll(".bg-arc");
const redElt = Array.from(elts[1].children);
const redEltHasRedFill = redElt.some((elt) => (elt as HTMLElement).style.fill === "rgb(255, 0, 0)");
expect(redEltHasRedFill).toBeTruthy();

const blueElt = Array.from(elts[2].children);
const blueEltHasBlueFill = blueElt.some((elt) => (elt as HTMLElement).style.fill === "rgb(0, 0, 255)");
expect(blueEltHasBlueFill).toBeTruthy();
});
});

it("processes delta prop correctly when delta is defined", async () => {
render(<Metric delta={10} testId="test-id" />);
await waitFor(() => {
const elt = document.querySelector(".delta");
if (elt) {
expect(elt.textContent).toContain("10");
} else {
throw new Error("Element with class .delta not found");
}
});
});

it("processes type and threshold props correctly when type is linear", async () => {
render(<Metric type="linear" threshold={50} testId="test-id" />);
await waitFor(() => {
const elt = document.querySelector(".bullet");
expect(elt).toBeInTheDocument();
});
});

it("processes type and threshold props correctly when type is not linear", async () => {
render(<Metric type="angular" threshold={50} testId="test-id" />);
await waitFor(() => {
const elt = document.querySelector(".angular");
expect(elt).toBeInTheDocument();
});
});

it("applies style correctly when height is undefined", async () => {
render(<Metric testId="test-id" />);
await waitFor(() => {
const elt = document.querySelector(".js-plotly-plot");
expect(elt).toHaveStyle({
width: "100%",
position: "relative",
display: "inline-block",
});
});
});

it("processes type prop correctly when type is none", async () => {
render(<Metric type="none" testId="test-id" />);
await waitFor(() => {
const angularElm = document.querySelector(".angular");
const angularAxis = document.querySelector(".angularaxis");
expect(angularElm).not.toBeInTheDocument();
expect(angularAxis).not.toBeInTheDocument();
});
});

it("processes template_Dark_ prop correctly when theme is dark", async () => {
const darkTheme = createTheme({
palette: {
mode: "dark",
},
});

render(
<ThemeProvider theme={darkTheme}>
<Metric template_Dark_={JSON.stringify(darkTemplate)} testId="test-id" />
</ThemeProvider>,
);
await waitFor(() => {
const elt = document.querySelector(".main-svg");
expect(elt).toHaveStyle({
backgroundColor: "rgb(31, 47, 68)",
});
});
});

it("processes template_Light_ prop correctly when theme is not dark", async () => {
const lightTheme = createTheme({
palette: {
mode: "light",
},
});

render(
<ThemeProvider theme={lightTheme}>
<Metric template_Light_={JSON.stringify(lightTemplate)} testId="test-id" />
</ThemeProvider>,
);
await waitFor(() => {
const elt = document.querySelector(".main-svg");
expect(elt).toHaveStyle({
backgroundColor: "rgb(255, 255, 255)",
});
});
});

it.skip("logs an error when template_Dark_ prop is not a valid JSON string", () => {
const consoleSpy = jest.spyOn(console, "info");
render(<Metric template_Dark_="not a valid JSON string" testId="test-id" />);
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error while parsing Metric.template"));
consoleSpy.mockRestore();
}); // TODO: Not working at the moment, need to fix

it("logs an error when template_Light_ prop is not a valid JSON string", () => {
const consoleSpy = jest.spyOn(console, "info");
render(<Metric template_Light_="not a valid JSON string" testId="test-id" />);
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error while parsing Metric.template"));
consoleSpy.mockRestore();
});
});

0 comments on commit 796f4ee

Please sign in to comment.