Skip to content

Commit

Permalink
Implemented tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rmathis committed Jun 15, 2021
1 parent fc668d2 commit 52a5aae
Show file tree
Hide file tree
Showing 20 changed files with 436 additions and 19 deletions.
51 changes: 48 additions & 3 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"start": "react-scripts start",
"build": "GENERATE_SOURCEMAP=true react-scripts build",
"buildProd": "react-scripts build && npm run copy",
"test": "react-scripts test",
"test": "react-scripts test 00==",
"eject": "react-scripts eject",
"build:static": "sass src/static.scss ./build/unsecured/static.css",
"copy:static": "node ./build",
Expand All @@ -51,8 +51,53 @@
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx}",
"!src/test/**/*.*"
]
"!src/testing/**/*.*",
"!src/*.js"
],
"coverageThreshold": {
"global": {
"branches": 0,
"functions": 0,
"lines": 0,
"statements": 0
},
"./src/app/i18n/": {
"branches": 80,
"functions": 80,
"lines": 80,
"statements": 80
},
"./src/app/core/": {
"branches": 80,
"functions": 80,
"lines": 80,
"statements": 80
},
"./src/app/metadata/domain/": {
"branches": 80,
"functions": 80,
"lines": 80,
"statements": 80
},
"./src/app/metadata/hooks/": {
"branches": 80,
"functions": 80,
"lines": 80,
"statements": 80
},
"./src/app/metadata/contention/": {
"branches": 80,
"functions": 80,
"lines": 80,
"statements": 80
},
"./src/app/metadata/component/": {
"branches": 80,
"functions": 80,
"lines": 80,
"statements": 80
}
}
},
"eslintConfig": {
"extends": [
Expand Down
41 changes: 41 additions & 0 deletions ui/src/app/core/components/AdminRoute.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import { act, render, fireEvent, waitFor, screen } from '@testing-library/react';
import { BrowserRouter, MemoryRouter, Route } from 'react-router-dom';
import { AdminRoute } from './AdminRoute';

const mockIsAdmin = jest.fn();

jest.mock('../user/UserContext', () => ({
useIsAdmin: () => mockIsAdmin()
}));

const renderWithRouter = (ui, { route = '/' } = {}) => {
window.history.pushState({}, 'Test page', route)

return render(ui, { wrapper: BrowserRouter })
}

describe('AdminRoute user is admin', () => {
beforeEach(() => {
mockIsAdmin.mockReturnValue(true);
});

it('should render the component if user is an admin', () => {
render(<AdminRoute><React.Fragment>hi there</React.Fragment></AdminRoute>, { wrapper: MemoryRouter });
expect(screen.getByText('hi there')).toBeInTheDocument();
});
});

describe('AdminRoute user is NOT admin', () => {
beforeEach(() => {
mockIsAdmin.mockReturnValue(false);
});

it('should redirect the user to the dashboard if not admin', () => {
renderWithRouter(<React.Fragment>
<AdminRoute path="/foo"><React.Fragment>hi there</React.Fragment></AdminRoute>
<Route path="/dashboard" render={ () => 'dashboard' } />
</React.Fragment>, {route: '/foo'});
expect(screen.getByText('dashboard')).toBeInTheDocument();
});
});
4 changes: 3 additions & 1 deletion ui/src/app/core/components/Footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function FooterLink ({ link }) {
);
}

export default function Footer () {
export function Footer () {
return (
<footer>
<div className="row">
Expand Down Expand Up @@ -49,3 +49,5 @@ export default function Footer () {
</footer>
);
}

export default Footer;
12 changes: 12 additions & 0 deletions ui/src/app/core/components/Footer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { Footer } from './Footer';

jest.mock('../../i18n/hooks', () => ({
useTranslation: (value) => value
}));

it('should display the footer', () => {
render(<Footer />);
expect(screen.getByText('brand.footer.text')).toBeInTheDocument();
});
27 changes: 27 additions & 0 deletions ui/src/app/core/components/Header.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { BrowserRouter as Router } from 'react-router-dom';
import { Header } from './Header';

jest.mock('../../i18n/hooks', () => ({
useTranslator: () => (value) => value,
useTranslation: (value) => value
}));

const mockIsAdmin = jest.fn();

jest.mock('../user/UserContext', () => ({
useIsAdmin: () => mockIsAdmin()
}));

describe('header for admins', () => {
beforeEach(() => {
mockIsAdmin.mockReturnValue(true);
});

it('should display logo and navigation', () => {
render(<Router><Header /></Router>);
expect(screen.getByText('brand.logo-link-label')).toBeInTheDocument();
});
});

4 changes: 2 additions & 2 deletions ui/src/app/core/components/UserConfirmation.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Modal from 'react-bootstrap/Modal';
import Button from 'react-bootstrap/Button';
import Translate from '../../i18n/components/translate';
import { useHistory } from 'react-router-dom';

import { reload } from '../utility/window';

export function UserConfirmation({children}) {
const [confirm, setConfirm] = React.useState(false);
Expand All @@ -27,7 +27,7 @@ export function ConfirmWindow ({message, confirm, setConfirm, confirmCallback})
setConfirm(false);
confirmCallback(true);
if (history.location.pathname.includes('provider/new')) {
window.location.reload();
reload();
}
}

Expand Down
95 changes: 95 additions & 0 deletions ui/src/app/core/components/UserConfirmation.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React from 'react';
import { act, render, fireEvent, waitFor, screen } from '@testing-library/react';
import { UserConfirmation, ConfirmWindow } from './UserConfirmation';

jest.mock('../../i18n/hooks', () => ({
useTranslator: () => (value) => value,
useTranslation: (value) => value
}));

const mockReload = jest.fn();

jest.mock('../utility/window', () => ({
reload: () => mockReload()
}))

const mockIncludes = jest.fn();

jest.mock('react-router-dom', () => ({
useHistory: () => ({
location: {
pathname: {
includes: mockIncludes
}
}
})
}));

const TestWindow = ({getConfirmation, message}) => {
React.useEffect(() => getConfirmation('foo', jest.fn()), [])
return <span>{message}</span>;
}

describe('user confirmation context', () => {
it('should render its children with a function', () => {
render(<UserConfirmation>
{(message, confirm, confirmCallback, setConfirm, getConfirmation) => <p><span>hi there</span> <TestWindow message={message} getConfirmation={getConfirmation} /></p>}
</UserConfirmation>);
expect(screen.getByText('hi there')).toBeInTheDocument();
expect(screen.getByText('foo')).toBeInTheDocument();
});
});

describe('confirmation window', () => {

it('should provide buttons to confirm', async () => {

const message = 'hi there';
const confirm = true;
const confirmCallback = jest.fn();
const setConfirm = jest.fn();

render(<ConfirmWindow message={message} confirm={confirm} confirmCallback={confirmCallback} setConfirm={setConfirm} /> );
expect(screen.getByText('hi there')).toBeInTheDocument();

fireEvent.click(screen.getByText('action.discard-changes'));

expect(confirmCallback).toHaveBeenCalledWith(true);

});

it('should provide buttons to stop', async () => {

const message = 'hi there';
const confirm = true;
const confirmCallback = jest.fn();
const setConfirm = jest.fn();

render(<ConfirmWindow message={message} confirm={confirm} confirmCallback={confirmCallback} setConfirm={setConfirm} />);
expect(screen.getByText('hi there')).toBeInTheDocument();

fireEvent.click(screen.getByText('action.cancel'));

expect(confirmCallback).toHaveBeenCalledWith(false);

});

it('should redirect if on a provider', () => {
mockIncludes.mockReturnValue(true);

const message = 'hi there';
const confirm = true;
const confirmCallback = jest.fn();
const setConfirm = jest.fn();

render(<ConfirmWindow message={message} confirm={confirm} confirmCallback={confirmCallback} setConfirm={setConfirm} />);
expect(screen.getByText('hi there')).toBeInTheDocument();

fireEvent.click(screen.getByText('action.discard-changes'));

expect(confirmCallback).toHaveBeenCalledWith(true);

expect(mockReload).toHaveBeenCalled();
})
});

5 changes: 0 additions & 5 deletions ui/src/app/core/hooks/utils.js

This file was deleted.

18 changes: 18 additions & 0 deletions ui/src/app/core/user/SessionModal.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { SessionModal } from './SessionModal';

jest.mock('../../i18n/hooks', () => ({
useTranslator: () => (value) => value,
useTranslation: (value) => value
}));

describe('session modal', () => {

it('should provide buttons to confirm', async () => {

render(<SessionModal show={true} />);
expect(screen.getByText('message.session-timeout-heading')).toBeInTheDocument();

});
});
47 changes: 47 additions & 0 deletions ui/src/app/core/user/UserContext.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import { UserProvider, useIsAdmin } from './UserContext';

const getFn = jest.fn();
const okFn = jest.fn();

const mockUseFetch = {
get: getFn,
response: {}
};

Object.defineProperty(mockUseFetch.response, 'ok', {
get: okFn
});

jest.mock('use-http', () => () => mockUseFetch);

const TestAdmin = () => {
const isAdmin = useIsAdmin();
return (<>{ isAdmin ? 'yes' : 'no' }</>)
}

describe('User Context defined', () => {

beforeEach(() => {
getFn.mockReturnValue(Promise.resolve({
role: 'ROLE_ADMIN'
}));
okFn.mockReturnValueOnce(true);
});

it('should render the component children', async () => {
render(<UserProvider>
{<div>test</div>}
</UserProvider>);
await waitFor(() => expect(screen.getByText('test')).toBeInTheDocument());
});

it('should provide the user context', async () => {
render(<UserProvider>
<TestAdmin />
</UserProvider>);

await waitFor(() => expect(screen.getByText('yes')).toBeInTheDocument());
});
});
4 changes: 4 additions & 0 deletions ui/src/app/core/utility/array_move.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ it('shifts an item in an array by +1 index', () => {

it('shifts an item in an array by -1 index', () => {
expect(array_move([1, 2], 1, 0)).toEqual([2, 1]);
});

it('shifts an item in an array by +1 index if greater than length', () => {
expect(array_move([1, 2], 0, 2)).toEqual([2, undefined, 1]);
});
4 changes: 4 additions & 0 deletions ui/src/app/core/utility/is_valid_regex.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ it('should return false for a malformed regular expression', () => {

it('should return true for a well-formed regular expression', () => {
expect(isValidRegex(`[a-z0-9][a-z0-9-]{0,31}:`)).toBe(true)
});

it('should return false if no expression is provided', () => {
expect(isValidRegex(null)).toBe(false)
});
3 changes: 0 additions & 3 deletions ui/src/app/core/utility/read_file_contents.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@


export function readFileContents(file) {
return new Promise(function (resolve, reject) {
const fileReader = new FileReader();

fileReader.onload = (evt) => {
const reader = evt.target;
const txt = reader.result;
Expand Down
Loading

0 comments on commit 52a5aae

Please sign in to comment.