testing web access view

This commit is contained in:
Roland Osborne 2023-01-12 15:31:35 -08:00
parent 0cf94193a2
commit eb96fe2664
9 changed files with 139 additions and 47 deletions

View File

@ -11,7 +11,7 @@
"**/test/**"
],
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/test/fileMock.js",
"\\.(css|less|scss|sass)$": "identity-obj-proxy"
}
},

View File

@ -1,7 +1,4 @@
import React, { useContext, useEffect } from 'react';
import { useNavigate } from "react-router-dom";
import { AppContext } from 'context/AppContext';
import { ViewportContext } from 'context/ViewportContext';
import { useAccess } from './useAccess.hook';
import { AccessWrapper } from './Access.styled';
import { Login } from './login/Login';
import { CreateAccount } from './createAccount/CreateAccount';
@ -10,26 +7,16 @@ import login from 'images/login.png'
export function Access({ mode }) {
const navigate = useNavigate();
const app = useContext(AppContext);
const viewport = useContext(ViewportContext);
useEffect(() => {
if (app.state) {
if (app.state.access) {
navigate('/session');
}
}
}, [app, navigate]);
const { state } = useAccess();
return (
<AccessWrapper>
{ (viewport.state.display === 'large' || viewport.state.display === 'xlarge') && (
<div class="split-layout">
<div class="left">
<img class="splash" src={login} alt="Databag Splash" />
{ (state.display === 'large' || state.display === 'xlarge') && (
<div className="split-layout">
<div className="left">
<img className="splash" src={login} alt="Databag Splash" />
</div>
<div class="right">
<div className="right">
{ mode === 'login' && (
<Login />
)}
@ -39,9 +26,9 @@ export function Access({ mode }) {
</div>
</div>
)}
{ (viewport.state.display === 'medium' || viewport.state.display === 'small') && (
<div class="full-layout">
<div class="center">
{ (state.display === 'medium' || state.display === 'small') && (
<div className="full-layout">
<div className="center">
{ mode === 'login' && (
<Login />
)}

View File

@ -27,35 +27,35 @@ export function CreateAccount() {
return (
<CreateAccountWrapper>
<div class="app-title">
<div className="app-title">
<span>Databag</span>
<div class="settings" onClick={() => actions.onSettings()}>
<div className="settings" onClick={() => actions.onSettings()}>
<SettingOutlined />
</div>
</div>
<div class="form-title">Create Account</div>
<div class="form-form">
<div className="form-title">Create Account</div>
<div className="form-form">
<Form name="basic" wrapperCol={{ span: 24, }}>
<Form.Item name="username" validateStatus={state.validateStatus} help={state.help}>
<Input placeholder="Username" spellCheck="false" onChange={(e) => actions.setUsername(e.target.value)}
autocomplete="username" autocapitalize="none" onKeyDown={(e) => keyDown(e)} prefix={<UserOutlined />} size="large" />
autoComplete="username" autoCapitalize="none" onKeyDown={(e) => keyDown(e)} prefix={<UserOutlined />} size="large" />
</Form.Item>
<div class="form-space"></div>
<div className="form-space"></div>
<Form.Item name="password">
<Input.Password placeholder="Password" spellCheck="false" onChange={(e) => actions.setPassword(e.target.value)}
autocomplete="new-password" onKeyDown={(e) => keyDown(e)} prefix={<LockOutlined />} size="large" />
autoComplete="new-password" onKeyDown={(e) => keyDown(e)} prefix={<LockOutlined />} size="large" />
</Form.Item>
<Form.Item name="confirm">
<Input.Password placeholder="Confirm Password" spellCheck="false" onChange={(e) => actions.setConfirm(e.target.value)}
autocomplete="new-password" onKeyDown={(e) => keyDown(e)} prefix={<LockOutlined />} size="large" />
autoComplete="new-password" onKeyDown={(e) => keyDown(e)} prefix={<LockOutlined />} size="large" />
</Form.Item>
<div class="form-button">
<div class="form-create">
<div className="form-button">
<div className="form-create">
<Button type="primary" block onClick={create} disabled={ actions.isDisabled()}
loading={state.busy} size="middle">
Create Account
@ -63,8 +63,8 @@ export function CreateAccount() {
</div>
</div>
<div class="form-button">
<div class="form-login">
<div className="form-button">
<div className="form-login">
<Button type="link" block onClick={(e) => actions.onLogin()}>
Account Login
</Button>

View File

@ -38,7 +38,6 @@ export const CreateAccountWrapper = styled.div`
.form-form {
flex: 2;
flex-grow: 1;
.form-space {
height: 8px;

View File

@ -27,28 +27,28 @@ export function Login() {
return (
<LoginWrapper>
<div class="app-title">
<div className="app-title">
<span>Databag</span>
<div class="settings" onClick={() => actions.onSettings()}>
<div className="settings" onClick={() => actions.onSettings()}>
<SettingOutlined />
</div>
</div>
<div class="form-title">Login</div>
<div class="form-form">
<div className="form-title">Login</div>
<div className="form-form">
<Form name="basic" wrapperCol={{ span: 24, }}>
<Form.Item name="username">
<Input placeholder="Username" spellCheck="false" onChange={(e) => actions.setUsername(e.target.value)}
autocomplete="username" autocapitalize="none" onKeyDown={(e) => keyDown(e)} prefix={<UserOutlined />} size="large" />
autoComplete="username" autoCapitalize="none" onKeyDown={(e) => keyDown(e)} prefix={<UserOutlined />} size="large" />
</Form.Item>
<Form.Item name="password">
<Input.Password placeholder="Password" spellCheck="false" onChange={(e) => actions.setPassword(e.target.value)}
autocomplete="current-password" onKeyDown={(e) => keyDown(e)} prefix={<LockOutlined />} size="large" />
autoComplete="current-password" onKeyDown={(e) => keyDown(e)} prefix={<LockOutlined />} size="large" />
</Form.Item>
<div class="form-button">
<div class="form-login">
<div className="form-button">
<div className="form-login">
<Button type="primary" block onClick={login} disabled={ actions.isDisabled()}
size="middle" loading={state.busy}>
Login
@ -56,7 +56,7 @@ export function Login() {
</div>
</div>
<div class="form-button">
<div className="form-button">
<Button type="link" block disabled={ !state.available } onClick={(e) => actions.onCreate()}>
Create Account
</Button>

View File

@ -77,6 +77,10 @@ export function useLogin() {
access();
}
}
// eslint-disable-next-line
}, [app.state, navigate, search]);
useEffect(() => {
const count = async () => {
try {
const available = await getAvailable()
@ -88,7 +92,7 @@ export function useLogin() {
}
count();
// eslint-disable-next-line
}, [app.state, navigate, search])
}, [])
return { state, actions };
}

View File

@ -0,0 +1,35 @@
import { useContext, useState, useEffect } from 'react';
import { useNavigate } from "react-router-dom";
import { AppContext } from 'context/AppContext';
import { ViewportContext } from 'context/ViewportContext';
export function useAccess() {
const [state, setState] = useState({
display: null,
});
const navigate = useNavigate();
const app = useContext(AppContext);
const viewport = useContext(ViewportContext);
const updateState = (value) => {
setState((s) => ({ ...s, ...value }));
}
useEffect(() => {
if (app.state.status) {
navigate('/session');
}
}, [app.state, navigate]);
useEffect(() => {
const { display } = viewport.state;
updateState({ display });
}, [viewport.state]);
const actions = {};
return { state, actions };
}

View File

@ -0,0 +1,65 @@
import React, { useState, useEffect, useContext } from 'react';
import {render, act, screen, waitFor, fireEvent} from '@testing-library/react'
import { HashRouter as Router, Routes, Route } from "react-router-dom";
import { ViewportContextProvider } from 'context/ViewportContext';
import { AppContextProvider } from 'context/AppContext';
import { Access } from 'access/Access';
import * as fetchUtil from 'api/fetchUtil';
function AccessTestApp() {
return (
<ViewportContextProvider>
<AppContextProvider>
<Router>
<Routes>
<Route path="/" element={ <Access mode="login" /> } />
<Route path="/login" element={ <Access mode="login" /> } />
<Route path="/create" element={ <Access mode="create" /> } />
</Routes>
</Router>
</AppContextProvider>
</ViewportContextProvider>
);
}
beforeAll(() => {
Object.defineProperty(window, "matchMedia", {
writable: true,
value: jest.fn().mockImplementation(query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // Deprecated
removeListener: jest.fn(), // Deprecated
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
}))
});
});
const realFetchWithTimeout = fetchUtil.fetchWithTimeout;
const realFetchWithCustomTimeout = fetchUtil.fetchWithCustomTimeout;
beforeEach(() => {
const mockFetch = jest.fn().mockImplementation((url, options) => {
return Promise.resolve({
json: () => Promise.resolve([])
});
});
fetchUtil.fetchWithTimeout = mockFetch;
fetchUtil.fetchWithCustomTimeout = mockFetch;
});
afterEach(() => {
fetchUtil.fetchWithTimeout = realFetchWithTimeout;
fetchUtil.fetchWithCustomTimeout = realFetchWithCustomTimeout;
});
test('login and create', async () => {
await act(async () => {
render(<AccessTestApp />);
});
});

2
net/web/test/fileMock.js Normal file
View File

@ -0,0 +1,2 @@
module.exports = '';