-
Notifications
You must be signed in to change notification settings - Fork 154
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
test: add support for automated tests for frontend with Jest and tests for HomeLoggedOut and NetworkHeader components #136
Changes from 5 commits
23be268
f69d82e
ce59c1c
ca469ec
64d7ef1
d7ba09e
d4fbd8f
c1b7630
9b35150
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { render } from "@testing-library/react"; | ||
import HomeLoggedOut from "../../src/components/HomeLoggedOut"; | ||
|
||
it("renders HomeLoggedOut unchanged", () => { | ||
const { container } = render(<HomeLoggedOut />); | ||
expect(container).toMatchSnapshot(); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { render, screen } from "@testing-library/react"; | ||
import HomeLoggedOut from "../../src/components/HomeLoggedOut"; | ||
import { Router } from "react-router-dom"; | ||
import { createMemoryHistory } from "history"; | ||
import { act } from "react-dom/test-utils"; | ||
import axios from "axios"; | ||
import MockAdapter from "axios-mock-adapter"; | ||
|
||
let mock = new MockAdapter(axios); | ||
|
||
describe("HomeLoggedOut", () => { | ||
test("renders HomeLoggedOut when authentication is enabled", () => { | ||
const history = createMemoryHistory(); | ||
const goSpy = jest.spyOn(history, "go"); | ||
|
||
mock.onGet("/auth/login").reply(200, { enabled: true }); | ||
|
||
render( | ||
<Router history={history}> | ||
<HomeLoggedOut /> | ||
</Router> | ||
); | ||
|
||
const projectDescription = screen.getByRole("heading", { | ||
name: "ZeroUI - ZeroTier Controller Web UI - is a web user interface for a self-hosted ZeroTier network controller.", | ||
}); | ||
|
||
const loginMessage = screen.getByText(/Please Log In to continue/i); | ||
|
||
expect(projectDescription).toBeInTheDocument(); | ||
expect(loginMessage).toBeInTheDocument(); | ||
expect(goSpy).not.toHaveBeenCalled(); | ||
}); | ||
|
||
test("renders HomeLoggedOut when authentication is disabled", async () => { | ||
const history = createMemoryHistory(); | ||
const goSpy = jest.spyOn(history, "go"); | ||
|
||
mock.onGet("/auth/login").reply(200, { enabled: false }); | ||
|
||
await act(async () => { | ||
render( | ||
<Router history={history}> | ||
<HomeLoggedOut /> | ||
</Router> | ||
); | ||
}); | ||
|
||
const projectDescription = screen.getByRole("heading", { | ||
name: "ZeroUI - ZeroTier Controller Web UI - is a web user interface for a self-hosted ZeroTier network controller.", | ||
}); | ||
|
||
const loginMessage = screen.getByText(/Please Log In to continue/i); | ||
|
||
expect(projectDescription).toBeInTheDocument(); | ||
expect(loginMessage).toBeInTheDocument(); | ||
expect(goSpy).toHaveBeenCalled(); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { render } from "@testing-library/react"; | ||
import NetworkHeader from "../../src/components/NetworkHeader"; | ||
import { testNetwork } from "./NetworkHeader.test"; | ||
|
||
it("renders HomeLoggedOut unchanged", () => { | ||
const { container } = render(<NetworkHeader network={testNetwork} />); | ||
expect(container).toMatchSnapshot(); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import { render, screen } from "@testing-library/react"; | ||
import NetworkHeader from "../../src/components/NetworkHeader"; | ||
|
||
export const testNetwork = { | ||
id: "0d303702cd0f1fc6", | ||
clock: 1672834445703, | ||
description: "Test Network", | ||
rulesSource: | ||
"\n# This is a default rule set that allows IPv4 and IPv6 traffic but otherwise\n# behaves like a standard Ethernet switch.\n\n#\n# Allow only IPv4, IPv4 ARP, and IPv6 Ethernet frames.\n#\ndrop\n not ethertype ipv4\n and not ethertype arp\n and not ethertype ipv6\n;\n\n#\n# Uncomment to drop non-ZeroTier issued and managed IP addresses.\n#\n# This prevents IP spoofing but also blocks manual IP management at the OS level and\n# bridging unless special rules to exempt certain hosts or traffic are added before\n# this rule.\n#\n#drop\n# not chr ipauth\n#;\n\n# Accept anything else. This is required since default is 'drop'.\naccept;\n", | ||
tagsByName: {}, | ||
capabilitiesByName: {}, | ||
config: { | ||
authTokens: [null], | ||
authorizationEndpoint: "", | ||
capabilities: [], | ||
clientId: "", | ||
creationTime: 1672676611179, | ||
dns: [], | ||
enableBroadcast: true, | ||
id: "0d303702cd0f1fc6", | ||
ipAssignmentPools: [ | ||
{ | ||
ipRangeEnd: "172.30.101.254", | ||
ipRangeStart: "172.30.101.1", | ||
}, | ||
], | ||
mtu: 2800, | ||
multicastLimit: 32, | ||
name: "new-net-11166", | ||
nwid: "0d303702cd0f1fc6", | ||
private: true, | ||
routes: [ | ||
{ | ||
target: "172.30.101.0/24", | ||
via: null, | ||
}, | ||
], | ||
rules: [ | ||
{ | ||
etherType: 2048, | ||
not: true, | ||
or: false, | ||
type: "MATCH_ETHERTYPE", | ||
}, | ||
{ | ||
etherType: 2054, | ||
not: true, | ||
or: false, | ||
type: "MATCH_ETHERTYPE", | ||
}, | ||
{ | ||
etherType: 34525, | ||
not: true, | ||
or: false, | ||
type: "MATCH_ETHERTYPE", | ||
}, | ||
{ | ||
type: "ACTION_DROP", | ||
}, | ||
{ | ||
type: "ACTION_ACCEPT", | ||
}, | ||
], | ||
ssoEnabled: false, | ||
tags: [], | ||
v4AssignMode: { | ||
zt: true, | ||
}, | ||
v6AssignMode: { | ||
"6plane": false, | ||
rfc4193: false, | ||
zt: false, | ||
}, | ||
}, | ||
}; | ||
|
||
describe("NetworkHeader", () => { | ||
test("renders NetworkHeader with a test network", () => { | ||
render(<NetworkHeader network={testNetwork} />); | ||
|
||
const networkId = screen.getByRole("heading", { | ||
name: "0d303702cd0f1fc6", | ||
level: 5, | ||
}); | ||
|
||
const networkName = screen.getByRole("heading", { | ||
name: "new-net-11166", | ||
level: 6, | ||
}); | ||
|
||
const networkDescription = screen.getByText(/Test Network/); | ||
|
||
expect(networkId).toBeInTheDocument(); | ||
expect(networkName).toBeInTheDocument(); | ||
expect(networkDescription).toBeInTheDocument(); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`renders HomeLoggedOut unchanged 1`] = ` | ||
<div> | ||
<div | ||
class="MuiGrid-root MuiGrid-container MuiGrid-direction-xs-column MuiGrid-align-items-xs-center MuiGrid-justify-content-xs-center" | ||
style="min-height: 50vh;" | ||
> | ||
<div | ||
class="MuiGrid-root MuiGrid-item MuiGrid-grid-xs-10" | ||
> | ||
<h5 | ||
class="MuiTypography-root MuiTypography-h5" | ||
> | ||
<span> | ||
ZeroUI - ZeroTier Controller Web UI - is a web user interface for a self-hosted ZeroTier network controller. | ||
</span> | ||
</h5> | ||
<p | ||
class="MuiTypography-root MuiTypography-body1" | ||
> | ||
<span> | ||
Please Log In to continue | ||
</span> | ||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`renders HomeLoggedOut unchanged 1`] = ` | ||
<div> | ||
<div | ||
class="MuiGrid-root MuiGrid-item" | ||
> | ||
<h5 | ||
class="MuiTypography-root MuiTypography-h5" | ||
> | ||
<span> | ||
0d303702cd0f1fc6 | ||
</span> | ||
</h5> | ||
<h6 | ||
class="MuiTypography-root MuiTypography-h6" | ||
style="font-style: italic;" | ||
> | ||
<span> | ||
new-net-11166 | ||
</span> | ||
</h6> | ||
<span> | ||
Test Network | ||
</span> | ||
</div> | ||
</div> | ||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Add any custom config to be passed to Jest | ||
const customJestConfig = { | ||
setupFilesAfterEnv: ["<rootDir>/jest.setup.js"], | ||
moduleDirectories: ["node_modules", "<rootDir>/"], | ||
transform: { | ||
// Use babel-jest to transpile tests with the below presets | ||
// https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object | ||
"^.+\\.(js|jsx|ts|tsx)$": [ | ||
"babel-jest", | ||
{ | ||
presets: [ | ||
"@babel/preset-env", | ||
[ | ||
"@babel/preset-react", | ||
{ | ||
runtime: "automatic", | ||
}, | ||
], | ||
], | ||
}, | ||
], | ||
}, | ||
testEnvironment: "jest-environment-jsdom", | ||
moduleNameMapper: { | ||
"^uuid$": require.resolve("uuid"), | ||
"^@fontsource/roboto$": "identity-obj-proxy", | ||
"\\.(png)$": "identity-obj-proxy", | ||
}, | ||
testPathIgnorePatterns: ["<rootDir>/cypress/"], | ||
}; | ||
|
||
module.exports = customJestConfig; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// Optional: configure or set up a testing framework before each test. | ||
// If you delete this file, remove `setupFilesAfterEnv` from `jest.config.js` | ||
|
||
// Used for __tests__/testing-library.js | ||
// Learn more: https://github.com/testing-library/jest-dom | ||
import "@testing-library/jest-dom/extend-expect"; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,12 +23,17 @@ | |
"styled-components": "^5.3.5" | ||
}, | ||
"devDependencies": { | ||
"@testing-library/jest-dom": "^5.16.5", | ||
"@testing-library/react": "12.1.5", | ||
"axios-mock-adapter": "^1.21.2", | ||
"jest-transform-css": "^6.0.0", | ||
"source-map-explorer": "^2.5.2" | ||
}, | ||
"scripts": { | ||
"start": "BROWSER=none react-scripts start", | ||
"build": "react-scripts build", | ||
"analyze": "source-map-explorer 'build/static/js/*.js'" | ||
"analyze": "source-map-explorer 'build/static/js/*.js'", | ||
"test:unit": "npx jest --coverage --testPathPattern='unit'" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that it would be better to install jest in devDependencies and use it directly. ZeroUI uses the yarn package manager, so it's a bit confusing to see the npx. Thanks! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, sorry about this! I realized another package was missing too after adding Jest so I added that other package as well ( |
||
}, | ||
"homepage": "/app", | ||
"proxy": "http://127.0.0.1:4000", | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there is a better way to import the components
Please check https://stackoverflow.com/questions/71300439/how-do-i-import-from-a-relative-path-like-utils-within-my-src-folder-in-jes