Skip to content

Commit 5190a07

Browse files
authored
Merge pull request #138 from davidlag0/test/front_end_tests
Add tests for NetworkButton component
2 parents 13b9cbb + 04c3f26 commit 5190a07

12 files changed

+264
-47
lines changed

frontend/__tests__/unit/NetworkHeader.test.jsx renamed to frontend/__tests__/data/network.jsx

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import { render, screen } from "@testing-library/react";
2-
import NetworkHeader from "components/NetworkHeader";
3-
41
export const testNetwork = {
52
id: "0d303702cd0f1fc6",
63
clock: 1672834445703,
@@ -73,25 +70,3 @@ export const testNetwork = {
7370
},
7471
},
7572
};
76-
77-
describe("NetworkHeader", () => {
78-
test("renders NetworkHeader with a test network", () => {
79-
render(<NetworkHeader network={testNetwork} />);
80-
81-
const networkId = screen.getByRole("heading", {
82-
name: "0d303702cd0f1fc6",
83-
level: 5,
84-
});
85-
86-
const networkName = screen.getByRole("heading", {
87-
name: "new-net-11166",
88-
level: 6,
89-
});
90-
91-
const networkDescription = screen.getByText(/Test Network/);
92-
93-
expect(networkId).toBeInTheDocument();
94-
expect(networkName).toBeInTheDocument();
95-
expect(networkDescription).toBeInTheDocument();
96-
});
97-
});

frontend/__tests__/unit/HomeLoggedOut.snapshot.jsx

Lines changed: 0 additions & 7 deletions
This file was deleted.

frontend/__tests__/unit/NetworkHeader.snapshot.jsx

Lines changed: 0 additions & 8 deletions
This file was deleted.

frontend/__tests__/unit/HomeLoggedOut.test.jsx renamed to frontend/__tests__/unit/components/HomeLoggedOut.test.jsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,15 @@ import { act } from "react-dom/test-utils";
66
import axios from "axios";
77
import MockAdapter from "axios-mock-adapter";
88

9-
let mock = new MockAdapter(axios);
10-
119
describe("HomeLoggedOut", () => {
10+
it("renders HomeLoggedOut unchanged", () => {
11+
const { container } = render(<HomeLoggedOut />);
12+
expect(container).toMatchSnapshot();
13+
});
14+
1215
test("renders HomeLoggedOut when authentication is enabled", () => {
16+
let mock = new MockAdapter(axios);
17+
1318
const history = createMemoryHistory();
1419
const goSpy = jest.spyOn(history, "go");
1520

@@ -33,6 +38,8 @@ describe("HomeLoggedOut", () => {
3338
});
3439

3540
test("renders HomeLoggedOut when authentication is disabled", async () => {
41+
let mock = new MockAdapter(axios);
42+
3643
const history = createMemoryHistory();
3744
const goSpy = jest.spyOn(history, "go");
3845

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { render, screen } from "@testing-library/react";
2+
import NetworkButton from "components/HomeLoggedIn/components/NetworkButton";
3+
import { testNetwork } from "../../data/network";
4+
import { Router } from "react-router-dom";
5+
import { createMemoryHistory } from "history";
6+
7+
describe("NetworkHeader", () => {
8+
it("renders NetworkButton unchanged", () => {
9+
const history = createMemoryHistory();
10+
11+
const { container } = render(
12+
<Router history={history}>
13+
<NetworkButton network={testNetwork} />
14+
</Router>
15+
);
16+
expect(container).toMatchSnapshot();
17+
});
18+
19+
test("renders NetworkHeader with a test network", () => {
20+
const history = createMemoryHistory();
21+
22+
render(
23+
<Router history={history}>
24+
<NetworkButton network={testNetwork} />
25+
</Router>
26+
);
27+
28+
const networkButton = screen.getByRole("button", {
29+
name: "0d303702cd0f1fc6 new-net-11166",
30+
});
31+
32+
const networkLink = screen.getByRole("link", {
33+
name: "0d303702cd0f1fc6 new-net-11166",
34+
});
35+
36+
expect(networkButton).toBeInTheDocument();
37+
expect(networkLink).toBeInTheDocument();
38+
});
39+
});
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { render, screen } from "@testing-library/react";
2+
import NetworkHeader from "components/NetworkHeader";
3+
import { testNetwork } from "../../data/network";
4+
5+
describe("NetworkHeader", () => {
6+
it("renders NetworkHeader unchanged", () => {
7+
const { container } = render(<NetworkHeader network={testNetwork} />);
8+
expect(container).toMatchSnapshot();
9+
});
10+
11+
test("renders NetworkHeader with a test network", () => {
12+
render(<NetworkHeader network={testNetwork} />);
13+
14+
const networkId = screen.getByRole("heading", {
15+
name: "0d303702cd0f1fc6",
16+
level: 5,
17+
});
18+
19+
const networkName = screen.getByRole("heading", {
20+
name: "new-net-11166",
21+
level: 6,
22+
});
23+
24+
const networkDescription = screen.getByText(/Test Network/);
25+
26+
expect(networkId).toBeInTheDocument();
27+
expect(networkName).toBeInTheDocument();
28+
expect(networkDescription).toBeInTheDocument();
29+
});
30+
});

frontend/__tests__/unit/__snapshots__/HomeLoggedOut.snapshot.jsx.snap renamed to frontend/__tests__/unit/components/__snapshots__/HomeLoggedOut.test.jsx.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`renders HomeLoggedOut unchanged 1`] = `
3+
exports[`HomeLoggedOut renders HomeLoggedOut unchanged 1`] = `
44
<div>
55
<div
66
class="MuiGrid-root MuiGrid-container MuiGrid-direction-xs-column MuiGrid-align-items-xs-center MuiGrid-justify-content-xs-center"
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`NetworkHeader renders NetworkButton unchanged 1`] = `
4+
<div>
5+
<div
6+
class="netBtn"
7+
role="button"
8+
>
9+
<a
10+
class="makeStyles-link-1"
11+
href="/network/0d303702cd0f1fc6"
12+
>
13+
<ul
14+
class="MuiList-root makeStyles-flexContainer-2 MuiList-padding"
15+
>
16+
<li
17+
class="MuiListItem-root makeStyles-nwid-4 MuiListItem-gutters"
18+
>
19+
0d303702cd0f1fc6
20+
</li>
21+
<li
22+
class="MuiListItem-root makeStyles-name-3 MuiListItem-gutters"
23+
>
24+
new-net-11166
25+
</li>
26+
</ul>
27+
</a>
28+
</div>
29+
</div>
30+
`;

frontend/__tests__/unit/__snapshots__/NetworkHeader.snapshot.jsx.snap renamed to frontend/__tests__/unit/components/__snapshots__/NetworkHeader.test.jsx.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`renders HomeLoggedOut unchanged 1`] = `
3+
exports[`NetworkHeader renders NetworkHeader unchanged 1`] = `
44
<div>
55
<div
66
class="MuiGrid-root MuiGrid-item"
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import * as IP from "utils/IP";
2+
3+
describe("IP", () => {
4+
describe("getCIDRAddress()", () => {
5+
test("throws and error if start parameter is not a valid IPv4", () => {
6+
expect(() => {
7+
IP.getCIDRAddress(1, "1.1.1.1");
8+
}).toThrow("ipaddr: the address has neither IPv6 nor IPv4 format");
9+
});
10+
11+
test("throws and error if end parameter is not a valid IPv4", () => {
12+
expect(() => {
13+
IP.getCIDRAddress("1.1.1.1", 1);
14+
}).toThrow("ipaddr: the address has neither IPv6 nor IPv4 format");
15+
});
16+
17+
test("returns /32 if both IPv4 addresses are the same", () => {
18+
expect(IP.getCIDRAddress("1.1.1.1", "1.1.1.1")).toBe("1.1.1.0/32");
19+
});
20+
21+
test("returns different values depending on how many bits are different between start and end IPv4 addresses", () => {
22+
expect(IP.getCIDRAddress("1.1.1.1", "1.1.1.0")).toBe("1.1.1.0/31");
23+
expect(IP.getCIDRAddress("1.1.1.1", "1.1.1.2")).toBe("1.1.1.0/30");
24+
expect(IP.getCIDRAddress("1.1.1.1", "1.1.1.4")).toBe("1.1.1.0/29");
25+
expect(IP.getCIDRAddress("1.1.1.1", "1.1.1.8")).toBe("1.1.1.0/28");
26+
expect(IP.getCIDRAddress("1.1.1.1", "1.1.2.1")).toBe("1.1.1.0/22");
27+
});
28+
29+
test("returns '<start with last character changed to 0>/32' no matter what valid IPv6 addresses are provided for start and end", () => {
30+
expect(IP.getCIDRAddress("2001:db8:1234::1", "2001:db8:1234::1")).toBe(
31+
"2001:db8:1234::0/32"
32+
);
33+
expect(IP.getCIDRAddress("2001:db8:1234::32", "2001:db8:1234::1")).toBe(
34+
"2001:db8:1234::30/32"
35+
);
36+
expect(IP.getCIDRAddress("2001:db8:1234::3000", "2001:db8:1234::1")).toBe(
37+
"2001:db8:1234::3000/32"
38+
);
39+
expect(IP.getCIDRAddress("2002:db8:1234::1", "2001:db8:1234::1")).toBe(
40+
"2002:db8:1234::0/32"
41+
);
42+
});
43+
});
44+
45+
describe("getCIDR()", () => {
46+
test("throws and error if start parameter is not a valid IPv4", () => {
47+
expect(() => {
48+
IP.getCIDR(1, "1.1.1.1");
49+
}).toThrow("ipaddr: the address has neither IPv6 nor IPv4 format");
50+
});
51+
52+
test("throws and error if end parameter is not a valid IPv4", () => {
53+
expect(() => {
54+
IP.getCIDR("1.1.1.1", 1);
55+
}).toThrow("ipaddr: the address has neither IPv6 nor IPv4 format");
56+
});
57+
58+
test("returns 32 if both IPv4 addresses are the same", () => {
59+
expect(IP.getCIDR("1.1.1.1", "1.1.1.1")).toBe(32);
60+
});
61+
62+
test("returns different values depending on how many bits are different between start and end IPv4 addresses", () => {
63+
expect(IP.getCIDR("1.1.1.1", "1.1.1.0")).toBe(31);
64+
expect(IP.getCIDR("1.1.1.1", "1.1.1.2")).toBe(30);
65+
expect(IP.getCIDR("1.1.1.1", "1.1.1.4")).toBe(29);
66+
expect(IP.getCIDR("1.1.1.1", "1.1.1.8")).toBe(28);
67+
});
68+
69+
test("returns 32 no matter what valid IPv6 addresses are provided for start and end", () => {
70+
expect(IP.getCIDR("2001:db8:1234::1", "2001:db8:1234::1")).toBe(32);
71+
expect(IP.getCIDR("2001:db8:1234::1", "2001:db8:1234::0")).toBe(32);
72+
expect(IP.getCIDR("2001:db8:1234::1", "2001:db8:1234::2")).toBe(32);
73+
expect(IP.getCIDR("2001:db8:1234::1", "2001:db8:1235::1")).toBe(32);
74+
expect(IP.getCIDR("2002:db8:1234::1", "2001:db8:1234::1")).toBe(32);
75+
});
76+
});
77+
78+
describe("toInt()", () => {
79+
test("returns an IP in integer format when given a valid IPv4", () => {
80+
expect(IP.toInt("1.1.1.1")).toBe(16843009);
81+
});
82+
83+
test("throw an error if a string that is not an IP is provided as input", () => {
84+
expect(() => {
85+
IP.toInt("some string that is not an IPv4 or IPv6");
86+
}).toThrow("ipaddr: the address has neither IPv6 nor IPv4 format");
87+
});
88+
89+
test("throw an error if addr is undefined", () => {
90+
expect(IP.toInt).toThrow(
91+
"ipaddr: the address has neither IPv6 nor IPv4 format"
92+
);
93+
});
94+
95+
test("returns 0 when given a valid IPv6", () => {
96+
expect(IP.toInt("2001:db8:1234::1")).toBe(0);
97+
});
98+
});
99+
100+
describe("validateIP()", () => {
101+
test("returns true if the provided string is a valid IPv4 address", () => {
102+
expect(IP.validateIP("1.1.1.1")).toBe(true);
103+
});
104+
105+
test("returns true if the provided string is a valid IPv6 address", () => {
106+
expect(IP.validateIP("2001:db8:1234::1")).toBe(true);
107+
});
108+
109+
test("returns false if the provided string is not a valid IPv4 or IPv6 address", () => {
110+
expect(
111+
IP.validateIP("some string that is not an IPv4 or IPv6 address")
112+
).toBe(false);
113+
});
114+
});
115+
116+
describe("normilizeIP()", () => {
117+
test("returns an IPv4 address with no leading 0's for each octet", () => {
118+
expect(IP.normilizeIP("01.01.01.01")).toBe("1.1.1.1");
119+
});
120+
121+
test("returns an IPv6 address with explicit 0's octets (if any) and no leading 0's (if any)", () => {
122+
expect(IP.normilizeIP("2001:0db8:1234::0001")).toBe(
123+
"2001:db8:1234:0:0:0:0:1"
124+
);
125+
});
126+
127+
test("throw an error if a string that is not an IP is provided as input", () => {
128+
expect(() => {
129+
IP.normilizeIP("some string that is not an IPv4 or IPv6");
130+
}).toThrow("ipaddr: the address has neither IPv6 nor IPv4 format");
131+
});
132+
});
133+
134+
describe("validateCIDR()", () => {
135+
test("returns true if provided a valid IPv4 CIDR address", () => {
136+
expect(IP.validateCIDR("1.1.1.0/24")).toBe(true);
137+
});
138+
139+
test("returns true if provided a valid IPv6 CIDR address", () => {
140+
expect(IP.validateCIDR("2001:0db8:1234::/64")).toBe(true);
141+
});
142+
143+
test("throw an error if a string that is not an IPv4 or IPv6 CIDR is provided as input", () => {
144+
expect(
145+
IP.validateCIDR("some string that is not an IPv4 or IPv6 CIDR address")
146+
).toBe(false);
147+
});
148+
});
149+
});

frontend/jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const customJestConfig = {
2424
moduleNameMapper: {
2525
"^uuid$": require.resolve("uuid"),
2626
"^@fontsource/roboto$": "identity-obj-proxy",
27-
"\\.(png)$": "identity-obj-proxy",
27+
"\\.(png|css)$": "identity-obj-proxy",
2828
},
2929
testPathIgnorePatterns: ["<rootDir>/cypress/"],
3030
};

frontend/src/utils/IP.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,23 @@ export function getCIDRAddress(start, end) {
55
return start.replace(/.$/, 0) + "/" + cidr;
66
}
77

8-
function getCIDR(start, end) {
8+
export function getCIDR(start, end) {
99
const startInt = toInt(start);
1010
const endInt = toInt(end);
1111
const binaryXOR = startInt ^ endInt;
1212
if (binaryXOR === 0) {
1313
return 32;
1414
} else {
1515
const binaryStr = binaryXOR.toString(2);
16+
// TODO: Both types of bits are counted here so using the
17+
// length of binaryStr would simplify the code.
1618
const zeroCount = binaryStr.split("0").length - 1;
1719
const oneCount = binaryStr.split("1").length - 1;
1820
return 32 - (zeroCount + oneCount);
1921
}
2022
}
2123

22-
function toInt(addr) {
24+
export function toInt(addr) {
2325
const ip = ipaddr.parse(addr);
2426
const arr = ip.octets;
2527
let ipInt = 0;

0 commit comments

Comments
 (0)