Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRAFT Statviz react testing #1267

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
Draft
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { MockedResponse } from "@apollo/client/testing";
import { GraphQLError } from "graphql";
import { it, vi, expect, describe } from "vitest";
import CreatedBoxesDataContainer, { CREATED_BOXES_QUERY } from "./CreatedBoxesDataContainer";
import { render, screen, waitFor } from "../../../../tests/testUtils";
import createdBoxes from "../../../mocks/createdBoxes";

const mockCreatedBoxesBarChart = vi.fn();

describe("Created Boxes Visualizations", () => {
const mockCreatedBoxesQuery = ({
baseId = 1,
networkError = false,
graphqlError = false,
delay = 0,
mockData = {},
}): MockedResponse => {
const getResult = () => {
if (networkError) return undefined;
if (graphqlError)
return {
data: null,
errors: [new GraphQLError("Error!")],
};
return {
data: mockData,
errors: undefined,
};
};
return {
request: {
query: CREATED_BOXES_QUERY,
variables: { baseId },
},
result: getResult(),
error: networkError ? new Error() : undefined,
delay,
};
};

vi.mock("@nivo/bar", () => ({
ResponsiveSankey: (props) => {
mockCreatedBoxesBarChart(props);

return <div>BarChart</div>;
},
}));

it("x.x.x.x - user wants to see createdBoxes viz, but a network error is returned", async () => {
render(<CreatedBoxesDataContainer />, {
routePath: "/bases/:baseId/statviz",
initialUrl: "/bases/1/statviz",
mocks: [mockCreatedBoxesQuery({ networkError: true })],
});

expect(await screen.findByText(/An unexpected error happened/i)).toBeInTheDocument();
});

it("x.x.x.x - user waits for data and sees the loading spinner", async () => {
render(<CreatedBoxesDataContainer />, {
routePath: "/bases/:baseId/statviz",
initialUrl: "/bases/1/statviz",
mocks: [mockCreatedBoxesQuery({ delay: 250 })],
});

expect(await screen.findByText(/loading.../i)).toBeInTheDocument();
});

it("x.x.x.x - user sees createdBoxes viz", async () => {
render(<CreatedBoxesDataContainer />, {
routePath: "/bases/:baseId/statviz?stg=cn&boi=bc&cbg=m&to=2023-09-02&from=2023-01-30",
initialUrl: "/bases/1/statviz",
mocks: [mockCreatedBoxesQuery({ mockData: createdBoxes })],
});

await waitFor(() => expect(mockCreatedBoxesBarChart).toHaveBeenCalled());
});

it("x.x.x.x - user calls page with some filters", async () => {
render(<CreatedBoxesDataContainer />, {
routePath: "/bases/:baseId/statviz",
initialUrl: "/bases/1/statviz?stg=cn&boi=bc&cbg=m&to=2023-09-02&from=2023-01-30",
mocks: [mockCreatedBoxesQuery({ mockData: createdBoxes })],
});

// expect(await screen.findByText(/loading.../i)).toBeInTheDocument();
});

it("x.x.x.x - user selects timerange without data", async () => {
render(<CreatedBoxesDataContainer />, {
routePath: "/bases/:baseId/statviz",
initialUrl: "/bases/1/statviz?stg=cn&boi=bc&cbg=m&to=2021-09-02&from=2022-01-30",
mocks: [mockCreatedBoxesQuery({ mockData: createdBoxes })],
});

// expect(
// await screen.findByText(/No data for the selected time range or selected filters/i),
// ).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ErrorCard, { predefinedErrors } from "../../ErrorCard";
import CreatedBoxesFilterContainer from "./CreatedBoxesFilterContainer";
import { gql } from "../../../../types/generated";

const CREATED_BOXES_QUERY = gql(`
export const CREATED_BOXES_QUERY = gql(`
query createdBoxes($baseId: Int!) {
createdBoxes(baseId: $baseId) {
facts {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { MockedResponse } from "@apollo/client/testing";
import { GraphQLError } from "graphql";
import { it, expect, describe } from "vitest";
import { render, screen } from "../../../../tests/testUtils";
import DemographicDataContainer, { DEMOGRAPHIC_QUERY } from "./DemographicDataContainer";

describe("Demographic Visualizations", () => {
const mockDemographicsQuery = ({
baseId = 1,
networkError = false,
graphqlError = false,
delay = 0,
mockData = {},
}): MockedResponse => {
const getResult = () => {
if (networkError) return undefined;
if (graphqlError)
return {
data: null,
errors: [new GraphQLError("Error!")],
};
return {
data: mockData,
errors: undefined,
};
};
return {
request: {
query: DEMOGRAPHIC_QUERY,
variables: { baseId },
},
result: getResult(),
error: networkError ? new Error() : undefined,
delay,
};
};

it("x.x.x.x - user wants to see createdBoxes viz, but a network error is returned", async () => {
render(<DemographicDataContainer />, {
routePath: "/bases/:baseId/statviz",
initialUrl: "/bases/1/statviz",
mocks: [mockDemographicsQuery({ networkError: true })],
});

expect(await screen.findByText(/An unexpected error happened/i)).toBeInTheDocument();
});

it("x.x.x.x - user waits for data and sees the loading spinner", async () => {
render(<DemographicDataContainer />, {
routePath: "/bases/:baseId/statviz",
initialUrl: "/bases/1/statviz",
mocks: [mockDemographicsQuery({ delay: 250 })],
});

expect(await screen.findByText(/loading.../i)).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import DemographicFilterContainer from "./DemographicFilterContainer";
import ErrorCard, { predefinedErrors } from "../../ErrorCard";
import NoDataCard from "../../NoDataCard";

const DEMOGRAPHIC_QUERY = gql(`
export const DEMOGRAPHIC_QUERY = gql(`
query BeneficiaryDemographics($baseId: Int!) {
beneficiaryDemographics(baseId: $baseId) {
facts {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,91 @@
import { it, expect } from "vitest";
import { it, expect, vi, describe } from "vitest";
import { GraphQLError } from "graphql";
import { MockedResponse } from "@apollo/client/testing";
import MovedBoxesDataContainer, { MOVED_BOXES_QUERY } from "./MovedBoxesDataContainer";
import { render, screen } from "../../../../tests/testUtils";

const mockFailedMovedBoxesQuery = ({ baseId = "1", networkError = false }) => ({
request: {
query: MOVED_BOXES_QUERY,
variables: { baseId },
},
result: networkError
? undefined
: {
data: null,
errors: [new GraphQLError("Error!")],
import { render, screen, waitFor } from "../../../../tests/testUtils";
import movedBoxes from "../../../mocks/movedBoxes";

const mockResponsiveSankey = vi.fn();

describe("Moved Boxes Visualizations", () => {
const mockMovedBoxesQuery = ({
baseId = 1,
networkError = false,
graphqlError = false,
delay = 0,
mockData = {},
}): MockedResponse => {
const getResult = () => {
if (networkError) return undefined;
if (graphqlError)
return {
data: null,
errors: [new GraphQLError("Error!")],
};
return {
data: mockData,
errors: undefined,
};
};

return {
request: {
query: MOVED_BOXES_QUERY,
variables: { baseId },
},
error: networkError ? new Error() : undefined,
});
result: getResult(),
error: networkError ? new Error() : undefined,
delay,
};
};

vi.mock("@nivo/sankey", () => ({
ResponsiveSankey: (props) => {
mockResponsiveSankey(props);

return <div>ResponsiveSankey</div>;
},
}));

it("x.x.x.x - user scans wants to see movedBoxes viz, but a network error is returned", async () => {
render(<MovedBoxesDataContainer />, {
routePath: "/bases/:baseId/statviz",
initialUrl: "/bases/1/statviz",
mocks: [mockMovedBoxesQuery({ networkError: true })],
});

expect(await screen.findByText(/An unexpected error happened/i)).toBeInTheDocument();
});

it("x.x.x.x - user waits for data and sees the loading spinner", async () => {
render(<MovedBoxesDataContainer />, {
routePath: "/bases/:baseId/statviz",
initialUrl: "/bases/1/statviz",
mocks: [mockMovedBoxesQuery({ delay: 250 })],
});

expect(await screen.findByText(/loading.../i)).toBeInTheDocument();
});

const movedBoxesDataTests = [
{
name: "x.x.x.x - user scans wants to see movedBoxes viz, but a network error is returned",
mocks: [mockFailedMovedBoxesQuery({ networkError: true })],
alert: /An unexpected error happened/i,
},
];
it("x.x.x.x - user selects a timerange where no data is present and sees the No data view", async () => {
render(<MovedBoxesDataContainer />, {
routePath: "/bases/:baseId/statviz",
initialUrl: "/bases/1/statviz?stg=cn&boi=bc&cbg=m&to=2024-02-17&from=2023-11-17",
mocks: [mockMovedBoxesQuery({ mockData: movedBoxes })],
});

expect(
await screen.findByText(/No data for the selected time range or selected filters/i),
).toBeInTheDocument();
});

movedBoxesDataTests.forEach(({ name, mocks, alert }) => {
it(name, async () => {
it("x.x.x.x - user sees movedBoxes viz", async () => {
render(<MovedBoxesDataContainer />, {
routePath: "/bases/:baseId/",
initialUrl: "/bases/1/",
mocks,
routePath: "/bases/:baseId/statviz",
initialUrl: "/bases/1/statviz?stg=cn&boi=bc&cbg=m&to=2023-09-02&from=2023-01-30",
mocks: [mockMovedBoxesQuery({ mockData: movedBoxes })],
});

expect(await screen.findByText(alert)).toBeInTheDocument();
await waitFor(() => expect(mockResponsiveSankey).toHaveBeenCalled());
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export default function MovedBoxesDataContainer() {
variables: { baseId: parseInt(baseId!, 10) },
},
);

if (error) {
return <Box>An unexpected error happened {error.message}</Box>;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { MockedResponse } from "@apollo/client/testing";
import { GraphQLError } from "graphql";
import { it, expect, describe } from "vitest";
import { render, screen } from "../../../../tests/testUtils";
import { STOCK_QUERY, StockDataContainer } from "./StockDataContainer";

describe("Stock Overview Visualizations", () => {
const mockStockQuery = ({
baseId = 1,
networkError = false,
graphqlError = false,
delay = 0,
mockData = {},
}): MockedResponse => {
const getResult = () => {
if (networkError) return undefined;
if (graphqlError)
return {
data: null,
errors: [new GraphQLError("Error!")],
};
return {
data: mockData,
errors: undefined,
};
};
return {
request: {
query: STOCK_QUERY,
variables: { baseId },
},
result: getResult(),
error: networkError ? new Error() : undefined,
delay,
};
};

it("x.x.x.x - user wants to see the stock visualizations viz, but a network error is returned", async () => {
render(<StockDataContainer />, {
routePath: "/bases/:baseId/statviz",
initialUrl: "/bases/1/statviz",
mocks: [mockStockQuery({ networkError: true })],
});

expect(await screen.findByText(/An unexpected error happened/i)).toBeInTheDocument();
});

it("x.x.x.x - user wants to see the stock visualizations viz and waits for data", async () => {
render(<StockDataContainer />, {
routePath: "/bases/:baseId/statviz",
initialUrl: "/bases/1/statviz",
mocks: [mockStockQuery({ delay: 250 })],
});

expect(await screen.findByText(/loading.../i)).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import StockDataFilter from "./StockDataFilter";
import ErrorCard, { predefinedErrors } from "../../ErrorCard";
import { gql } from "../../../../types/generated";

const STOCK_QUERY = gql(`
export const STOCK_QUERY = gql(`
query stockOverview($baseId: Int!) {
stockOverview(baseId: $baseId) {
facts {
Expand Down Expand Up @@ -40,7 +40,7 @@ const STOCK_QUERY = gql(`
}
`);

export default function StockDataContainer() {
export function StockDataContainer() {
const { baseId } = useParams();
const { data, loading, error } = useQuery(STOCK_QUERY, {
variables: { baseId: parseInt(baseId!, 10) },
Expand Down
2 changes: 1 addition & 1 deletion shared-components/statviz/hooks/useMultiSelectFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ export default function useMultiSelectFilter<T>(
}
if (param === "") {
searchParams.delete(filterId);
setSearchParams(searchParams);
}
setSearchParams(searchParams);
}, [searchParams, filterId, values, defaultFilterValues, setSearchParams]);

const onFilterChange = (event) => {
Expand Down
Empty file.
Loading
Loading