Skip to content

Commit

Permalink
Merge pull request #68 from LuisValgoi/feat-formik-refactored
Browse files Browse the repository at this point in the history
[ISSUE-9] Feature of Formik + Yup Sample
  • Loading branch information
marceloschreiber committed Oct 5, 2020
2 parents 14ba7bd + 2dab6db commit afc5278
Show file tree
Hide file tree
Showing 60 changed files with 1,000 additions and 144 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,20 @@ PS.: It is important to add the `--template ui5-webcomponents-react-seed` at the

- Multiple Scripts.

# Engine Included
# Engine & Samples Included

- Fallback Engine (`<ErrorBoundary />`, `<NotFound />` and `<Error />`);

- MockServer Engine (w/ `json-server`);

- HTTP Request Engine (w/ `Request`, `APIProvider`, `BrowserProvider`);
- API HTTP Request Engine (w/ `Request`, `APIProvider`, `BrowserProvider`);

- Permission Engine (w/ `RouteValidator` and `ComponentValidator`).

- Pagination Engine (w/ custom hook `usePaginatedGet`).

- ToDo Form Edition w/ `yup` and `formik`.

# Hooks Included

- `useRequest`: Which includes `get`, `post`, `patch`, `delete`, `put` HTTP helpers;
Expand All @@ -75,7 +77,6 @@ Following one of the several recommendations for structuring files on a React ba

The only custom change we have incremented were the Custom Components and the folder for each project containing the `tests` artefacts.


# Scripts Included

In the project directory, you can run:
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"env-cmd": "^10.1.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.4",
"formik": "^2.1.7",
"husky": "^4.2.5",
"i18next": "^19.7.0",
"i18next-browser-languagedetector": "^6.0.1",
Expand All @@ -67,7 +68,8 @@
"react-query": "^2.17.2",
"react-query-devtools": "^2.5.0",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.3"
"react-scripts": "3.4.3",
"yup": "^0.29.3"
},
"scripts": {
"build": "react-scripts build",
Expand Down
8 changes: 6 additions & 2 deletions server/data/Todo/GET_TODO_BY_ID.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
const { MemoryRouter } = require('react-router-dom');

module.exports = {
data: {
todos: {
id: 'UG9rZW1vbjowMDE=',
number: '001',
description: '001',
name: 'Task 1',
completed: false,
completed: true,
priority: 'HIGH',
type: 'PERSONAL',
},
},
};
20 changes: 10 additions & 10 deletions server/data/Todo/GET_TODO_LIST.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,61 @@ module.exports = {
content: [
{
id: 'UG9rZW1vbjowMDE=',
number: '001',
description: '001',
name: 'Task 1',
completed: false,
},
{
id: '2U9frg1Z1W1o1DE=',
number: '002',
description: '002',
name: 'Task 2',
completed: false,
},
{
id: '2Ug11Z1dv1W1og1DE=',
number: '003',
description: '003',
name: 'Task 3',
completed: false,
},
{
id: 'gxfas1cczg1ff1DE=',
number: '004',
description: '004',
name: 'Task 4',
completed: false,
},
{
id: '2Uxfg1ka1Zga1o1DE=',
number: '005',
description: '005',
name: 'Task 5',
completed: false,
},
{
id: '2z11Uxgfg1kaza1DE=',
number: '006',
description: '006',
name: 'Task 9',
completed: false,
},
{
id: '2Uxgfg1ka1Zga11DE=',
number: '007',
description: '007',
name: 'Task 7',
completed: false,
},
{
id: '2Uxfag3ka1Zga1o1DE=',
number: '008',
description: '008',
name: 'Task 8',
completed: false,
},
{
id: '2Uxfg7ka1Zga1o1DE=',
number: '009',
description: '009',
name: 'Task 9',
completed: false,
},
{
id: '2Ugg7ka1Zg31o1DE=',
number: '010',
description: '010',
name: 'Task 10',
completed: false,
},
Expand Down
2 changes: 1 addition & 1 deletion server/data/Todo/GET_TODO_LIST_PAGE_1.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module.exports = {
content: [
{
id: '5Uxfhxka1Zga1o1DE=',
number: '011',
description: '011',
name: 'Task 11',
completed: false,
},
Expand Down
4 changes: 2 additions & 2 deletions server/routes.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"*/v1/user/logged": "/GET_USER_LOGGED",
"*/v1/todo/detail/:id": "/GET_TODO_BY_ID",
"*/v1/todo/all\\?page=0": "/GET_TODO_LIST",
"*/v1/todo/all\\?page=1": "/GET_TODO_LIST_PAGE_1"
"*/v1/todo/all\\?page=1": "/GET_TODO_LIST_PAGE_1",
"*/v1/todo/:id": "/GET_TODO_BY_ID"
}
5 changes: 1 addition & 4 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import Shell from './components/Shell/Shell';
import Routes from './routes/Routes';

import './App.css';
import CenteredContent from './components/Layout/CenteredContent';

function App() {
const { t } = useTranslation();
Expand All @@ -20,9 +19,7 @@ function App() {
<Helmet title={t('helmet.title.app')} />
<Shell title={t('shell.title')} />
<ErrorBoundary>
<CenteredContent>
<Routes />
</CenteredContent>
<Routes />
</ErrorBoundary>
</BrowserRouter>
);
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import '@testing-library/jest-dom/extend-expect';
import { render, waitFor, screen, serverCustom } from '../../util/TestSetup';
import ComponentValidator from './Validator';
import APIProvider from '../../util/URL/APIProvider';
import APIProvider from '../../util/api/url/APIProvider';

describe('Validator.js Test Suite', () => {
const GET_USER_LOGGED_RESPONSE = {
Expand All @@ -25,7 +25,7 @@ describe('Validator.js Test Suite', () => {
<ComponentValidator allowedAuthorities={['canAccessDropApplication']} authorityKey="permissions">
<p>{childText}</p>
</ComponentValidator>,
{ route: '/todo/list' },
{ route: '/todo/all' },
);
const child = await waitFor(() => screen.getByText(childText));

Expand All @@ -39,22 +39,23 @@ describe('Validator.js Test Suite', () => {
<ComponentValidator allowedAuthorities={['canAccessDropApplication']} authorityKey="permissions">
<p>{childText}</p>
</ComponentValidator>,
{ route: '/todo/list' },
{ route: '/todo/all' },
);
const child = await waitFor(() => screen.getByText(childText));

expect(child).toBeInTheDocument();
});

test('should not appear in the document', async () => {
test.only('should not appear in the document', async () => {
const childText = 'inner text';

render(
<ComponentValidator allowedAuthorities={['canAccessDropApplication']} authorityKey="permissions">
<p>{childText}</p>
</ComponentValidator>,
{ route: '/todo/list' },
{ route: '/todo/all' },
);
console.log('PATHHHHHH', window.location.pathname);
const child = screen.queryByAltText(childText);

expect(child).not.toBeInTheDocument();
Expand Down
File renamed without changes.
19 changes: 19 additions & 0 deletions src/components/Form/FieldBase/FieldBase.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';

import { FlexBox, FlexBoxDirection } from '@ui5/webcomponents-react';
import Label from '../Label/Label';

const FieldBase = ({ labelText, ...props }) => {
return (
<FlexBox data-testid="fieldbase-wrapper" direction={props.direction ? props.direction : FlexBoxDirection.Column} {...props}>
{labelText && (
<Label required={props.required} for={props.for} showColon={props.showColon}>
{labelText}
</Label>
)}
{props.children}
</FlexBox>
);
};

export default FieldBase;
40 changes: 40 additions & 0 deletions src/components/Form/FieldBase/FieldBase.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react';

import '@testing-library/jest-dom/extend-expect';
import { render, screen } from '../../../util/TestSetup';

import FieldBase from '../FieldBase/FieldBase';

describe('FieldBase.js Test Suite', () => {
beforeEach(() => {
render(
<FieldBase labelText="Text Content">
<p data-testid="inner-component-wrapper">Some Inner Text</p>
</FieldBase>,
);
});

test('should match snapshot', () => {
const { asFragment } = render(
<FieldBase labelText="Text Content">
<p data-testid="inner-component-wrapper"></p>
</FieldBase>,
);

expect(asFragment()).toMatchSnapshot();
});

test('should render', () => {
const component = screen.getByTestId('fieldbase-wrapper');

expect(component).toBeInTheDocument();
});

test('should render with Inner Component with Text Content as text', () => {
const component = screen.getByTestId('fieldbase-wrapper');
const innerComponent = screen.getByTestId('inner-component-wrapper');

expect(component).toBeInTheDocument();
expect(innerComponent).toHaveTextContent('Some Inner Text');
});
});
31 changes: 31 additions & 0 deletions src/components/Form/FieldBase/__snapshots__/FieldBase.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`FieldBase.js Test Suite should match snapshot 1`] = `
<DocumentFragment>
<div
class="FlexBox-flexBox-0-2-1 FlexBox-flexBoxDirectionColumn-0-2-8 FlexBox-justifyContentStart-0-2-3 FlexBox-alignItemsStretch-0-2-15 FlexBox-flexWrapNoWrap-0-2-17"
data-testid="fieldbase-wrapper"
>
Label {
"_domRefReadyPromise": Promise {
"_deferredResolve": [Function],
},
"_firePropertyChange": false,
"_fullyConnected": false,
"_inDOM": false,
"_monitoredChildProps": Map {},
"_shouldInvalidateParent": false,
"_state": Object {
"for": "",
"required": false,
"showColon": false,
"wrap": true,
},
"_upToDate": false,
}
<p
data-testid="inner-component-wrapper"
/>
</div>
</DocumentFragment>
`;
24 changes: 24 additions & 0 deletions src/components/Form/Input/Input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';

import { spacing } from '@ui5/webcomponents-react-base';
import { Input as UI5Input, ValueState } from '@ui5/webcomponents-react';
import FieldBase from '../FieldBase/FieldBase';

const Input = ({ field, form: { touched, errors }, labelText, style, ...props }) => {
const errorMsg = touched[field.name] && errors[field.name];
const errorState = errorMsg ? ValueState.Error : ValueState.None;

const innerStyle = {
...style,
...spacing.sapUiTinyMarginBottom,
width: '100%',
};

return (
<FieldBase labelText={labelText} required={props.required} for={props.for} showColon={props.showColon}>
<UI5Input data-testid="input-wrapper" valueState={errorState} valueStateMessage={<span>{errorMsg}</span>} style={innerStyle} {...props} {...field} />
</FieldBase>
);
};

export default Input;
32 changes: 32 additions & 0 deletions src/components/Form/Input/Input.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';

import '@testing-library/jest-dom/extend-expect';
import { render, screen } from '../../../util/TestSetup';

import Input from '../Input/Input';

describe('Input.js Test Suite', () => {
test('should match snapshot', () => {
const { asFragment } = render(<Input labelText="Text Content" name="description" field={{ name: 'description' }} form={{ touched: { name: 'description' }, errors: { name: 'description' } }} />);

expect(asFragment()).toMatchSnapshot();
});

test('should have rendered with the fieldbase', () => {
render(<Input labelText="Text Content" name="description" field={{ name: 'description' }} form={{ touched: { name: 'description' }, errors: { name: 'description' } }} />);

const fieldbase = screen.getByTestId('fieldbase-wrapper');
const component = screen.getByTestId('input-wrapper');

expect(fieldbase).toBeInTheDocument();
expect(component).toBeInTheDocument();
});

test('should have attribute name as description if passed', () => {
render(<Input labelText="Text Content" name="description" field={{ name: 'description' }} form={{ touched: { name: 'description' }, errors: { name: 'description' } }} />);

const component = screen.getByTestId('input-wrapper');

expect(component).toHaveProperty('name', 'description');
});
});
Loading

0 comments on commit afc5278

Please sign in to comment.