Skip to content

Commit

Permalink
Merge pull request #39 from indec-it/test/components
Browse files Browse the repository at this point in the history
test: add some tests
  • Loading branch information
maximilianoforlenza authored Feb 5, 2023
2 parents 46cc4c1 + 75c9a96 commit da4fb11
Show file tree
Hide file tree
Showing 13 changed files with 597 additions and 12 deletions.
14 changes: 13 additions & 1 deletion .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,16 @@ jobs:
- name: Install dependencies 🔧
run: npm ci
- name: Run eslint
run: npm run lint
run: npm run lint

tests:
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.9.1
- name: Checkout 🛎️
uses: actions/checkout@v3
- name: Install dependencies 🔧
run: npm ci
- name: Run tests
run: npm run test
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run lint
npm run validate
3 changes: 2 additions & 1 deletion src/components/Checkbox/Checkbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ function Checkbox({
</Typography>
) : (
<FormGroup row>
{options.map(option => (
{options.map((option, index) => (
<FormControlLabel
key={option.value}
control={(
<MuiCheckbox
data-testid={`option-${index}`}
checked={field.value.includes(option.value)}
onChange={e => handleChecked(e, option.value, field, form.setFieldValue)}
/>
Expand Down
149 changes: 149 additions & 0 deletions src/components/Checkbox/Checkbox.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import {
fireEvent, getByTestId, getByText, queryByText
} from '@testing-library/react';

import Checkbox from './Checkbox';

describe('<Checkbox>', () => {
let props;
const getComponent = () => render(Checkbox, props);
beforeEach(() => {
props = {
options: [
{
id: 1,
name: 'S1P1O1',
value: '1',
label: 'Option 1',
subOptions: [
{
id: 1
}
]
},
{
id: 2,
name: 'S1P1O1',
value: '2',
label: 'Option 2',
subOptions: [
{
id: 1
}
]
},
{
id: 3,
name: 'S1P1O1',
value: '3',
label: 'Option 3',
subOptions: [
{
id: 1
}
]
}
],
label: 'Select the options',
field: {value: [], name: 'test'},
form: {setFieldValue: jest.fn(), errors: {}, submitCount: 0},
readOnlyMode: false,
required: true,
warnings: {}
};
});

it('should render InputLabel component', () => {
const {container} = getComponent();
expect(getByTestId(container, 'input-label')).toBeInTheDocument();
});

describe('when `props.readOnlyMode` is `false`', () => {
beforeEach(() => {
props.readOnlyMode = false;
});

it('should display `props.options.label`', () => {
const {container} = getComponent();
props.options.forEach(option => {
expect(getByText(container, option.label)).toBeInTheDocument();
});
});

describe('when a checkbox is clicked to be mark for first time', () => {
beforeEach(() => {
const {container} = getComponent();
const firstCheckbox = getByTestId(container, 'option-0');
fireEvent.click(firstCheckbox);
});

it('should fire `props.form.setFieldValue` to set the selected value', () => {
expect(props.form.setFieldValue).toHaveBeenCalled();
expect(props.form.setFieldValue).toHaveBeenCalledWith('test', ['1']);
});

describe('when a checkbox is clicked to mark two values', () => {
beforeEach(() => {
props.field.value = ['1'];
const {container} = getComponent();
const firstCheckbox = getByTestId(container, 'option-1');
fireEvent.click(firstCheckbox);
});

it('should fire `props.form.setFieldValue` to merge selected values', () => {
expect(props.form.setFieldValue).toHaveBeenCalled();
expect(props.form.setFieldValue).toHaveBeenCalledWith('test', ['1', '2']);
});
});

describe('when a checkbox is clicked to be deselected', () => {
beforeEach(() => {
props.field.value = ['1'];
const {container} = getComponent();
const firstCheckbox = getByTestId(container, 'option-0');
fireEvent.click(firstCheckbox);
});

it('should fire `props.form.setFieldValue` to unset the selected value', () => {
expect(props.form.setFieldValue).toHaveBeenCalled();
expect(props.form.setFieldValue).toHaveBeenCalledWith('test', []);
});
});
});
});

describe('when `props.readOnlyMode` is `true`', () => {
beforeEach(() => {
props.readOnlyMode = true;
});

describe('and there are selected options', () => {
beforeEach(() => {
props.field.value = ['2', '3'];
});

it('should display the selected options', () => {
const {container} = getComponent();
expect(getByText(container, 'Option 2, Option 3')).toBeInTheDocument();
});
});

describe('and there are not selected options', () => {
beforeEach(() => {
props.field.value = [];
});

it('should display `Sin respuesta.`', () => {
const {container} = getComponent();
expect(getByText(container, 'Sin respuesta.')).toBeInTheDocument();
});
});

it('should not render the list of checkboxes', () => {
const {container} = getComponent();
props.options.forEach(option => {
expect(queryByText(container, option.label)).toBeNull();
});
});
});
});
43 changes: 43 additions & 0 deletions src/components/FieldMessage/FieldMessage.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {getByText} from '@testing-library/react';
import FieldMessage from './FieldMessage';

describe('<FieldMessage>', () => {
let props;
const getComponent = () => render(FieldMessage, props);
beforeEach(() => {
props = {
readOnly: false,
label: 'test',
field: {name: 'test'},
form: {submitCount: 0, errors: {}, touched: {test: false}},
warnings: {}
};
});

describe('when `props.readOnly` is `false` and there is an error', () => {
beforeEach(() => {
props.readOnly = false;
props.form.errors = {test: 'there is an error'};
props.form.touched = {test: true};
});

it('should display `props.form.errors` message', () => {
const {container} = getComponent();
expect(getByText(container, props.form.errors.test)).toBeInTheDocument();
});
});

describe('when `props.readOnly` is `false`, there is not an error and there is a warning', () => {
beforeEach(() => {
props.readOnly = false;
props.form.errors = {};
props.form.touched = {test: true};
props.warnings = {test: 'there is a warning'};
});

it('should display `props.warnings` message', () => {
const {container} = getComponent();
expect(getByText(container, props.warnings.test)).toBeInTheDocument();
});
});
});
6 changes: 3 additions & 3 deletions src/components/InputLabel/InputLabel.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ function InputLabel({
}) {
const {hasWarning, hasError} = hasFormikErrorsAndWarnings({form, field, warnings});
return (
<Stack direction="row" spacing={2}>
<Stack direction="row" spacing={2} data-testid="input-label">
{hasError && !readOnly && (
<Box>
<ErrorIcon color="error" />
<ErrorIcon color="error" data-testid="error-icon" />
</Box>
)}
{hasWarning && !readOnly && !hasError && (
<Box>
<WarningIcon color="warning" />
<WarningIcon color="warning" data-testid="warning-icon" />
</Box>
)}
<Box mb={0.5}>
Expand Down
46 changes: 46 additions & 0 deletions src/components/InputLabel/InputLabel.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {getByTestId, getByText} from '@testing-library/react';
import InputLabel from './InputLabel';

describe('<InputLabel>', () => {
let props;
const getComponent = () => render(InputLabel, props);
beforeEach(() => {
props = {
readOnly: false,
label: 'test',
field: {name: 'test'},
form: {submitCount: 0, errors: {}, touched: {test: false}},
required: false
};
});

it('should display `props.label`', () => {
const {container} = getComponent();
expect(getByText(container, props.label)).toBeInTheDocument();
});

describe('when there is an error and `props.readOnly` is `false`', () => {
beforeEach(() => {
props.form.errors = {test: 'there is an error'};
props.form.touched = {test: true};
});

it('should render error icon', () => {
const {container} = getComponent();
expect(getByTestId(container, 'error-icon')).toBeInTheDocument();
});
});

describe('when there is not an error, `props.readOnly` is `false` and there`s a warning', () => {
beforeEach(() => {
props.form.errors = {};
props.form.touched = {test: true};
props.warnings = {test: 'there is a warning'};
});

it('should render warning icon', () => {
const {container} = getComponent();
expect(getByTestId(container, 'warning-icon')).toBeInTheDocument();
});
});
});
14 changes: 11 additions & 3 deletions src/components/Modal/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,23 @@ function Modal({
>
<Container>
<Box sx={{display: 'flex', justifyContent: 'flex-end'}}>
<IconButton onClick={onClose}>
<IconButton data-testid="close-button-icon" onClick={onClose}>
<CancelIcon color="info" />
</IconButton>
</Box>
<Divider />
{children}
<Stack direction={{xs: 'column', sm: 'row'}} justifyContent="space-between" p={2} spacing={{xs: 1, sm: 2, md: 4}}>
<Button onClick={onClose}>{cancelButtonLabel}</Button>
{onAccept && <Button variant="contained" onClick={() => onAccept(modal)}>{acceptButtonLabel}</Button>}
<Button data-testid="close-button" onClick={onClose}>{cancelButtonLabel}</Button>
{onAccept && (
<Button
variant="contained"
data-testid="accept-button"
onClick={() => onAccept(modal)}
>
{acceptButtonLabel}
</Button>
)}
</Stack>
</Container>
</Box>
Expand Down
Loading

0 comments on commit da4fb11

Please sign in to comment.