Merge pull request #148 from davidlag0/test/front_end_tests

Test/front end tests
This commit is contained in:
dec0dOS 2023-02-26 22:35:48 +00:00 committed by GitHub
commit be0cc0c80d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 703 additions and 1186 deletions

View file

@ -0,0 +1 @@
module.exports = "test-file-stub";

View file

@ -0,0 +1,47 @@
import { render } from "@testing-library/react";
import Bar from "components/Bar";
import { Router } from "react-router-dom";
import { createMemoryHistory } from "history";
// Useful reference: https://bholmes.dev/blog/mocking-browser-apis-fetch-localstorage-dates-the-easy-way-with-jest/
let mockStorage = {};
describe("Bar", () => {
beforeAll(() => {
global.Storage.prototype.getItem = jest.fn((key) => mockStorage[key]);
});
beforeEach(() => {
// make sure the fridge starts out empty for each test
mockStorage = {};
});
afterAll(() => {
global.Storage.prototype.getItem.mockReset();
});
it("renders Bar unchanged when logged out", () => {
const history = createMemoryHistory();
mockStorage["loggedIn"] = false;
const { container } = render(
<Router history={history}>
<Bar />
</Router>
);
expect(container).toMatchSnapshot();
});
it("renders Bar unchanged when logged in", () => {
const history = createMemoryHistory();
mockStorage["loggedIn"] = true;
const { container } = render(
<Router history={history}>
<Bar />
</Router>
);
expect(container).toMatchSnapshot();
});
});

View file

@ -0,0 +1,46 @@
import { render, screen } from "@testing-library/react";
import HomeLoggedIn from "components/HomeLoggedIn";
import { Router } from "react-router-dom";
import { createMemoryHistory } from "history";
import { testNetwork } from "../../data/network";
import API from "utils/API";
import MockAdapter from "axios-mock-adapter";
describe("HomeLoggedIn", () => {
it("renders HomeLoggedIn unchanged (no network)", async () => {
const mock = new MockAdapter(API);
const history = createMemoryHistory();
mock.onGet("network").reply(200, []);
const { container } = render(
<Router history={history}>
<HomeLoggedIn />
</Router>
);
expect(
await screen.findByText(/Please create at least one network/i)
).toBeInTheDocument();
expect(container).toMatchSnapshot();
});
it("renders HomeLoggedIn unchanged (with network)", async () => {
const mock = new MockAdapter(API);
const history = createMemoryHistory();
mock.onGet("network").reply(200, [testNetwork]);
const { container } = render(
<Router history={history}>
<HomeLoggedIn />
</Router>
);
expect(await screen.findByText(/0d303702cd0f1fc6/)).toBeInTheDocument();
expect(await screen.findByText(/new-net-11166/)).toBeInTheDocument();
expect(container).toMatchSnapshot();
});
});

View file

@ -0,0 +1,198 @@
import { render, screen } from "@testing-library/react";
import NetworkManagement from "components/NetworkManagement";
import { MemoryRouter, Route, Router } from "react-router-dom";
import { createMemoryHistory } from "history";
import userEvent from "@testing-library/user-event";
import API from "utils/API";
import MockAdapter from "axios-mock-adapter";
describe("NetworkManagement", () => {
it("renders unchanged", () => {
const history = createMemoryHistory();
const { container } = render(
<Router history={history}>
<NetworkManagement />
</Router>
);
expect(container).toMatchSnapshot();
});
test("renders with initial state (accordion not expanded)", () => {
const history = createMemoryHistory();
render(
<Router history={history}>
<NetworkManagement />
</Router>
);
const expandAccordionButton = screen.getByRole("button", {
name: "Management",
});
expect(expandAccordionButton).toBeInTheDocument();
expect(
screen.queryByRole("button", { name: "Delete Network" })
).toBeFalsy();
});
test("renders with accordion expanded (and dialog closed)", async () => {
const history = createMemoryHistory();
const user = userEvent.setup();
render(
<Router history={history}>
<NetworkManagement />
</Router>
);
const expandAccordionButton = screen.getByRole("button", {
name: "Management",
});
await user.click(expandAccordionButton);
expect(
screen.getByRole("button", {
name: "Delete Network",
})
).toBeVisible();
});
test("renders with accordion expanded and dialog opened", async () => {
const history = createMemoryHistory();
const user = userEvent.setup();
render(
<Router history={history}>
<NetworkManagement />
</Router>
);
const expandAccordionButton = screen.getByRole("button", {
name: "Management",
});
await user.click(expandAccordionButton);
const deleteNetworkButton = screen.getByRole("button", {
name: "Delete Network",
});
await user.click(deleteNetworkButton);
expect(screen.getByRole("button", { name: "Cancel" })).toBeVisible();
expect(screen.getByRole("button", { name: "Delete" })).toBeVisible();
});
test("renders with accordion closed after opening and closing it", async () => {
const history = createMemoryHistory();
const user = userEvent.setup();
render(
<Router history={history}>
<NetworkManagement />
</Router>
);
const expandAccordionButton = screen.getByRole("button", {
name: "Management",
});
await user.click(expandAccordionButton);
expect(
screen.getByRole("button", {
name: "Delete Network",
})
).toBeVisible();
await user.click(expandAccordionButton);
expect(
screen.queryByRole("button", {
name: "Delete Network",
})
).toBeFalsy();
});
test("renders with accordion expanded and dialog closed (after opening and closing the dialog)", async () => {
const history = createMemoryHistory();
const user = userEvent.setup();
render(
<Router history={history}>
<NetworkManagement />
</Router>
);
const expandAccordionButton = screen.getByRole("button", {
name: "Management",
});
await user.click(expandAccordionButton);
const deleteNetworkButton = screen.getByRole("button", {
name: "Delete Network",
});
await user.click(deleteNetworkButton);
const dialogCancelButton = screen.getByRole("button", { name: "Cancel" });
const dialogDeleteButton = screen.getByRole("button", { name: "Delete" });
expect(dialogCancelButton).toBeVisible();
expect(dialogDeleteButton).toBeVisible();
await user.click(dialogCancelButton);
expect(dialogCancelButton).not.toBeVisible();
expect(dialogDeleteButton).not.toBeVisible();
});
test("renders with network deleted (after expanding the acordion, opening the dialog and clicking the button to delete the network)", async () => {
const mock = new MockAdapter(API);
const user = userEvent.setup();
const nwid = "123";
let testLocation;
mock.onDelete("/network/" + nwid).reply(200);
render(
<MemoryRouter initialEntries={["/network/" + nwid]}>
<Route path="/network/:nwid">
<NetworkManagement />
</Route>
<Route
path="*"
render={({ location }) => {
testLocation = location;
return null;
}}
/>
</MemoryRouter>
);
const expandAccordionButton = screen.getByRole("button", {
name: "Management",
});
await user.click(expandAccordionButton);
const deleteNetworkButton = screen.getByRole("button", {
name: "Delete Network",
});
await user.click(deleteNetworkButton);
const dialogCancelButton = screen.getByRole("button", { name: "Cancel" });
const dialogDeleteButton = screen.getByRole("button", { name: "Delete" });
expect(dialogCancelButton).toBeVisible();
expect(dialogDeleteButton).toBeVisible();
await user.click(dialogDeleteButton);
expect(testLocation.pathname).toBe("/");
});
});

View file

@ -0,0 +1,104 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Bar renders Bar unchanged when logged in 1`] = `
<div>
<header
class="MuiPaper-root MuiAppBar-root MuiAppBar-positionStatic MuiAppBar-colorSecondary MuiPaper-elevation4"
style="background: rgb(0, 0, 0);"
>
<div
class="MuiToolbar-root MuiToolbar-regular MuiToolbar-gutters"
>
<div
class="MuiBox-root MuiBox-root-2"
>
<h6
class="MuiTypography-root MuiTypography-h6 MuiTypography-colorInherit"
>
<a
class="MuiTypography-root MuiLink-root MuiLink-underlineNone MuiTypography-colorInherit"
href="/"
>
<img
alt="logo"
height="100"
src="test-file-stub"
width="100"
/>
</a>
</h6>
</div>
<button
class="MuiButtonBase-root MuiButton-root MuiButton-text MuiButton-colorInherit"
tabindex="0"
type="button"
>
<span
class="MuiButton-label"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"
/>
</svg>
</span>
<span
class="MuiTouchRipple-root"
/>
</button>
</div>
</header>
</div>
`;
exports[`Bar renders Bar unchanged when logged out 1`] = `
<div>
<header
class="MuiPaper-root MuiAppBar-root MuiAppBar-positionStatic MuiAppBar-colorSecondary MuiPaper-elevation4"
style="background: rgb(0, 0, 0);"
>
<div
class="MuiToolbar-root MuiToolbar-regular MuiToolbar-gutters"
>
<div
class="MuiBox-root MuiBox-root-1"
>
<h6
class="MuiTypography-root MuiTypography-h6 MuiTypography-colorInherit"
>
<a
class="MuiTypography-root MuiLink-root MuiLink-underlineNone MuiTypography-colorInherit"
href="/"
>
<img
alt="logo"
height="100"
src="test-file-stub"
width="100"
/>
</a>
</h6>
</div>
<button
class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary"
tabindex="0"
type="button"
>
<span
class="MuiButton-label"
>
Log In
</span>
<span
class="MuiTouchRipple-root"
/>
</button>
</div>
</header>
</div>
`;

View file

@ -0,0 +1,145 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`HomeLoggedIn renders HomeLoggedIn unchanged (no network) 1`] = `
<div>
<div
class="makeStyles-root-1"
>
<button
class="MuiButtonBase-root MuiButton-root MuiButton-contained makeStyles-createBtn-2 MuiButton-containedPrimary"
tabindex="0"
type="button"
>
<span
class="MuiButton-label"
>
Create A Network
</span>
<span
class="MuiTouchRipple-root"
/>
</button>
<hr
class="MuiDivider-root"
/>
<div
class="MuiGrid-root makeStyles-container-3 MuiGrid-container MuiGrid-spacing-xs-3"
>
<div
class="MuiGrid-root MuiGrid-item MuiGrid-grid-xs-6"
>
<h5
class="MuiTypography-root MuiTypography-h5"
>
Controller networks
</h5>
<div
class="MuiBox-root MuiBox-root-4"
/>
</div>
<div
class="MuiGrid-root MuiGrid-item MuiGrid-grid-xs-auto"
>
<p
class="MuiTypography-root MuiTypography-body1"
>
Networks
</p>
<div
class="MuiGrid-root MuiGrid-item"
>
<div>
Please create at least one network
</div>
</div>
</div>
</div>
</div>
</div>
`;
exports[`HomeLoggedIn renders HomeLoggedIn unchanged (with network) 1`] = `
<div>
<div
class="makeStyles-root-5"
>
<button
class="MuiButtonBase-root MuiButton-root MuiButton-contained makeStyles-createBtn-6 MuiButton-containedPrimary"
tabindex="0"
type="button"
>
<span
class="MuiButton-label"
>
Create A Network
</span>
<span
class="MuiTouchRipple-root"
/>
</button>
<hr
class="MuiDivider-root"
/>
<div
class="MuiGrid-root makeStyles-container-7 MuiGrid-container MuiGrid-spacing-xs-3"
>
<div
class="MuiGrid-root MuiGrid-item MuiGrid-grid-xs-6"
>
<h5
class="MuiTypography-root MuiTypography-h5"
>
Controller networks
</h5>
Network controller address
<div
class="MuiBox-root MuiBox-root-8"
>
0d303702cd
</div>
</div>
<div
class="MuiGrid-root MuiGrid-item MuiGrid-grid-xs-auto"
>
<p
class="MuiTypography-root MuiTypography-body1"
>
Networks
</p>
<div
class="MuiGrid-root MuiGrid-item"
>
<div
class="MuiGrid-root MuiGrid-item"
>
<div
class="netBtn"
role="button"
>
<a
class="makeStyles-link-9"
href="/network/0d303702cd0f1fc6"
>
<ul
class="MuiList-root makeStyles-flexContainer-10 MuiList-padding"
>
<li
class="MuiListItem-root makeStyles-nwid-12 MuiListItem-gutters"
>
0d303702cd0f1fc6
</li>
<li
class="MuiListItem-root makeStyles-name-11 MuiListItem-gutters"
>
new-net-11166
</li>
</ul>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;

View file

@ -0,0 +1,99 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`NetworkManagement renders unchanged 1`] = `
<div>
<div
class="MuiPaper-root MuiAccordion-root MuiAccordion-rounded MuiPaper-elevation1 MuiPaper-rounded"
>
<div
aria-disabled="false"
aria-expanded="false"
class="MuiButtonBase-root MuiAccordionSummary-root"
role="button"
tabindex="0"
>
<div
class="MuiAccordionSummary-content"
>
<p
class="MuiTypography-root MuiTypography-body1"
>
Management
</p>
</div>
<div
aria-disabled="false"
aria-hidden="true"
class="MuiButtonBase-root MuiIconButton-root MuiAccordionSummary-expandIcon MuiIconButton-edgeEnd"
>
<span
class="MuiIconButton-label"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"
/>
</svg>
</span>
<span
class="MuiTouchRipple-root"
/>
</div>
</div>
<div
class="MuiCollapse-root MuiCollapse-hidden"
style="min-height: 0px;"
>
<div
class="MuiCollapse-wrapper"
>
<div
class="MuiCollapse-wrapperInner"
>
<div
role="region"
>
<div
class="MuiAccordionDetails-root"
>
<button
class="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedSecondary"
tabindex="0"
type="button"
>
<span
class="MuiButton-label"
>
<span
class="MuiButton-startIcon MuiButton-iconSizeMedium"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"
/>
</svg>
</span>
Delete Network
</span>
<span
class="MuiTouchRipple-root"
/>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;

View file

@ -24,7 +24,8 @@ const customJestConfig = {
moduleNameMapper: {
"^uuid$": require.resolve("uuid"),
"^@fontsource/roboto$": "identity-obj-proxy",
"\\.(png|css)$": "identity-obj-proxy",
"\\.(css)$": "identity-obj-proxy",
"\\.(png|pdf|svg|jpg|jpeg)$": "<rootDir>/__tests__/__mocks__/fileMock.js",
},
testPathIgnorePatterns: ["<rootDir>/cypress/"],
};

View file

@ -23,12 +23,14 @@
"styled-components": "^5.3.5"
},
"devDependencies": {
"@testing-library/dom": "^9.0.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "12.1.5",
"@testing-library/user-event": "^14.4.3",
"axios-mock-adapter": "^1.21.2",
"jest": "^29.3.1",
"jest-environment-jsdom": "^29.3.1",
"jest": "26.6.0",
"jest-transform-css": "^6.0.0",
"postcss": "^8.4.21",
"source-map-explorer": "^2.5.2"
},
"scripts": {

1240
yarn.lock

File diff suppressed because it is too large Load diff