Skip to content

Commit 76a170b

Browse files
committed
Added a simple UI cypress test, improvements to ui menu
1 parent 4fbb354 commit 76a170b

File tree

7 files changed

+151
-95
lines changed

7 files changed

+151
-95
lines changed

frontend/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"styled-components": "5.3.0",
4848
"tabler-icons-react": "^1.35.0",
4949
"tabler-react": "^2.0.0-alpha.1",
50-
"tabler-react-typescript": "^0.0.4",
50+
"tabler-react-typescript": "0.0.5",
5151
"typescript": "^4.3.5"
5252
},
5353
"scripts": {
@@ -83,10 +83,10 @@
8383
],
8484
"coverageThreshold": {
8585
"global": {
86-
"branches": 1,
87-
"functions": 1,
88-
"lines": 1,
89-
"statements": 1
86+
"branches": 0,
87+
"functions": 0,
88+
"lines": 0,
89+
"statements": 0
9090
}
9191
}
9292
}

frontend/src/components/NavMenu.tsx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import React from "react";
2+
3+
import {
4+
Book,
5+
DeviceDesktop,
6+
Home,
7+
Lock,
8+
Settings,
9+
Shield,
10+
Users,
11+
} from "tabler-icons-react";
12+
import { Navigation } from "tabler-react-typescript";
13+
14+
function NavMenu() {
15+
return (
16+
<Navigation.Menu
17+
theme="light"
18+
className="mb-3"
19+
items={[
20+
{
21+
title: "Home",
22+
icon: <Home />,
23+
to: "/",
24+
},
25+
{
26+
title: "Hosts",
27+
icon: <DeviceDesktop />,
28+
to: "/hosts",
29+
},
30+
{
31+
title: "Access Lists",
32+
icon: <Lock />,
33+
to: "/access-lists",
34+
},
35+
{
36+
title: "Certificates",
37+
icon: <Shield />,
38+
to: "/certificates",
39+
},
40+
{
41+
title: "Users",
42+
icon: <Users />,
43+
to: "/users",
44+
},
45+
{
46+
title: "Audit Log",
47+
icon: <Book />,
48+
to: "/audit-log",
49+
},
50+
{
51+
title: "Settings",
52+
icon: <Settings />,
53+
to: "/settings",
54+
},
55+
]}
56+
/>
57+
);
58+
}
59+
60+
export { NavMenu };

frontend/src/components/SiteWrapper.tsx

Lines changed: 4 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,10 @@ import React, { ReactNode } from "react";
33
import { Footer } from "components";
44
import { useAuthState, useUserState } from "context";
55
import styled from "styled-components";
6-
import {
7-
Book,
8-
DeviceDesktop,
9-
Home,
10-
Lock,
11-
Settings,
12-
Shield,
13-
Users,
14-
} from "tabler-icons-react";
156
import { Avatar, Dropdown, Navigation } from "tabler-react-typescript";
167

8+
import { NavMenu } from "./NavMenu";
9+
1710
const StyledContainer = styled.div`
1811
padding-bottom: 30px;
1912
`;
@@ -45,52 +38,14 @@ function SiteWrapper({ children }: Props) {
4538
user.roles.includes("admin") ? "Administrator" : "Standard User"
4639
}
4740
profileItems={[
48-
<Dropdown.Item key="m1-1">Set status</Dropdown.Item>,
49-
<Dropdown.Item key="m1-2">Profile &amp; account</Dropdown.Item>,
50-
<Dropdown.Item key="m1-3">Feedback</Dropdown.Item>,
41+
<Dropdown.Item key="m1-2">Profile settings</Dropdown.Item>,
5142
<Dropdown.Item divider key="m1-4" />,
52-
<Dropdown.Item key="m1-5">Settings</Dropdown.Item>,
5343
<Dropdown.Item key="m1-6" onClick={logout}>
5444
Logout
5545
</Dropdown.Item>,
5646
]}
5747
/>
58-
<Navigation.Menu
59-
theme="light"
60-
className="mb-3"
61-
items={[
62-
{
63-
title: "Home",
64-
icon: <Home />,
65-
active: true,
66-
},
67-
{
68-
title: "Hosts",
69-
icon: <DeviceDesktop />,
70-
},
71-
{
72-
title: "Access Lists",
73-
icon: <Lock />,
74-
},
75-
{
76-
title: "Certificates",
77-
icon: <Shield />,
78-
},
79-
{
80-
title: "Users",
81-
icon: <Users />,
82-
},
83-
{
84-
title: "Audit Log",
85-
icon: <Book />,
86-
},
87-
{
88-
title: "Settings",
89-
icon: <Settings />,
90-
},
91-
]}
92-
/>
93-
48+
<NavMenu />
9449
<div className="content">
9550
<div className="container-xl">
9651
<StyledContainer>{children}</StyledContainer>

frontend/yarn.lock

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1829,13 +1829,6 @@
18291829
dependencies:
18301830
"@babel/types" "^7.3.0"
18311831

1832-
"@types/classnames@^2.2.11":
1833-
version "2.3.1"
1834-
resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.3.1.tgz#3c2467aa0f1a93f1f021e3b9bcf938bd5dfdc0dd"
1835-
integrity sha512-zeOWb0JGBoVmlQoznvqXbE0tEC/HONsnoUNH19Hc96NFsTAwTXbTqb8FMYkru1F/iqp7a18Ws3nWJvtA1sHD1A==
1836-
dependencies:
1837-
classnames "*"
1838-
18391832
"@types/eslint@^7.2.6":
18401833
version "7.2.6"
18411834
resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.6.tgz#5e9aff555a975596c03a98b59ecd103decc70c3c"
@@ -3646,7 +3639,7 @@ class-utils@^0.3.5:
36463639
isobject "^3.0.0"
36473640
static-extend "^0.1.1"
36483641

3649-
classnames@*, classnames@^2.2.6:
3642+
classnames@^2.2.6:
36503643
version "2.3.1"
36513644
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
36523645
integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
@@ -11784,13 +11777,13 @@ tabler-icons-react@^1.35.0:
1178411777
resolved "https://registry.yarnpkg.com/tabler-icons-react/-/tabler-icons-react-1.35.0.tgz#b4e7f8da632314d002aa5e34931f2f824395b77c"
1178511778
integrity sha512-WiJ+dYQ71HCsxKAQpCfPrFVwSfqE6CByYFjq9Gzikmp2RijJBsNpj0sE/T5G0H+nERS9odjAWJoSryvr4FymFg==
1178611779

11787-
tabler-react-typescript@^0.0.4:
11788-
version "0.0.4"
11789-
resolved "https://registry.yarnpkg.com/tabler-react-typescript/-/tabler-react-typescript-0.0.4.tgz#b40ee7faef743f5d5af6cdf098d3376cdb71989e"
11790-
integrity sha512-l/OoB4zQ3+u4xVxARw+1HqaHO13wDYlQIvjFyvs6Sdk7Vdys0sAc/EzN9hxWg5ywRNM+mGwt5+fVHXiuYAcD7g==
11780+
11781+
version "0.0.5"
11782+
resolved "https://registry.yarnpkg.com/tabler-react-typescript/-/tabler-react-typescript-0.0.5.tgz#ab14ebada6f0524e13e3c6e60d2739a0f34f617d"
11783+
integrity sha512-PIov0LMSZWQzQ0OnlyITTzVdgBOKuc6HzgNLttP6Uz3/evGDBFl/Owl7wcP6niy7varzx4SttzFNXfJyhC3zcg==
1179111784
dependencies:
11792-
"@types/classnames" "^2.2.11"
1179311785
classnames "^2.2.6"
11786+
react-router-dom "^5.2.0"
1179411787

1179511788
tabler-react@^2.0.0-alpha.1:
1179611789
version "2.0.0-alpha.1"

test/cypress/integration/api/SetupPhase.spec.js

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,15 @@
33
describe('Setup Phase', () => {
44

55
before(() => {
6-
cy.task('backendApiDelete', {
7-
path: '/api/users'
8-
}).then((data) => {
9-
expect(data).to.have.property('result', true);
10-
});
6+
cy.resetUsers();
117
});
128

13-
it('Should not be able to get a token', function() {
9+
it('Should NOT be able to get a token', function() {
1410
cy.task('backendApiPost', {
1511
path: '/api/tokens',
1612
data: {
1713
type: 'password',
18-
identity: 'jc@jc21.com',
14+
identity: 'cypress@example.com',
1915
secret: 'changeme'
2016
},
2117
returnOnError: true
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/// <reference types="Cypress" />
2+
3+
describe('UI Setup and Login', () => {
4+
5+
// Clear the users before runing this test
6+
before(() => {
7+
cy.resetUsers();
8+
});
9+
10+
it('Should be able to setup a new user', function() {
11+
cy.visit('/');
12+
cy.get('input[name="name"]').type('Cypress McGee');
13+
cy.get('input[name="nickname"]').type('Cypress');
14+
cy.get('input[name="email"]').type('[email protected]');
15+
cy.get('input[name="password"]').type('changeme');
16+
cy.get('form button:first').click();
17+
cy.get('.navbar-nav .avatar').should('be.visible');
18+
});
19+
20+
});

test/cypress/support/commands.js

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,18 @@ Cypress.Commands.add('validateSwaggerSchema', (method, code, path, data) => {
2828
}).should('equal', null);
2929
});
3030

31-
Cypress.Commands.add('getToken', () => {
31+
/**
32+
* @param {object} defaultUser
33+
* @param {object} defaultAuth
34+
*/
35+
Cypress.Commands.add('getToken', (defaultUser, defaultAuth) => {
36+
if (typeof defaultAuth === 'object' && defaultAuth) {
37+
if (!defaultUser) {
38+
defaultUser = {};
39+
}
40+
defaultUser.auth = defaultAuth;
41+
}
42+
3243
cy.task('backendApiGet', {
3344
path: '/api/',
3445
}).then((data) => {
@@ -38,40 +49,52 @@ Cypress.Commands.add('getToken', () => {
3849
if (!data.result.setup) {
3950
cy.log('Setup = false');
4051
// create a new user
41-
cy.createInitialUser().then(() => {
42-
return cy.getToken();
52+
cy.createInitialUser(defaultUser).then(() => {
53+
return cy.getToken(defaultUser);
4354
});
4455
} else {
56+
let auth = {
57+
type: 'password',
58+
identity: '[email protected]',
59+
secret: 'changeme',
60+
};
61+
62+
if (typeof defaultUser === 'object' && defaultUser && typeof defaultUser.auth === 'object' && defaultUser.auth) {
63+
auth = Object.assign({}, auth, defaultUser.auth);
64+
}
65+
4566
cy.log('Setup = true');
4667
// login with existing user
4768
cy.task('backendApiPost', {
4869
path: '/api/tokens',
49-
data: {
50-
type: 'password',
51-
identity: '[email protected]',
52-
secret: 'changeme'
53-
}
54-
}).then(res => {
70+
data: auth,
71+
}).then((res) => {
5572
cy.wrap(res.result.token);
5673
});
5774
}
5875
});
5976
});
6077

61-
Cypress.Commands.add('createInitialUser', () => {
78+
Cypress.Commands.add('createInitialUser', (defaultUser) => {
79+
let user = {
80+
name: 'Cypress McGee',
81+
nickname: 'Cypress',
82+
83+
roles: [],
84+
is_disabled: false,
85+
auth: {
86+
type: 'password',
87+
secret: 'changeme'
88+
}
89+
};
90+
91+
if (typeof defaultUser === 'object' && defaultUser) {
92+
user = Object.assign({}, user, defaultUser);
93+
}
94+
6295
return cy.task('backendApiPost', {
6396
path: '/api/users',
64-
data: {
65-
name: 'Jamie Curnow',
66-
nickname: 'James',
67-
68-
roles: [],
69-
is_disabled: false,
70-
auth: {
71-
type: 'password',
72-
secret: 'changeme'
73-
}
74-
}
97+
data: user,
7598
}).then((data) => {
7699
// Check the swagger schema:
77100
cy.validateSwaggerSchema('post', 201, '/users', data);
@@ -80,3 +103,12 @@ Cypress.Commands.add('createInitialUser', () => {
80103
cy.wrap(data.result);
81104
});
82105
});
106+
107+
Cypress.Commands.add('resetUsers', () => {
108+
cy.task('backendApiDelete', {
109+
path: '/api/users'
110+
}).then((data) => {
111+
expect(data).to.have.property('result', true);
112+
cy.wrap(data.result);
113+
});
114+
});

0 commit comments

Comments
 (0)