Skip to content

Commit

Permalink
Merge branch 'develop' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
juanfabrega authored Jul 10, 2020
2 parents 3324e2e + 96ad059 commit 81ebf61
Show file tree
Hide file tree
Showing 10 changed files with 218 additions and 42 deletions.
67 changes: 67 additions & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# This is a basic workflow to help you get started with Actions

name: Pull Request

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
pull_request:
types: [opened, synchronize, reopened]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
lint:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/cache@v1
with:
path: ~/.cache/yarn
key: ${{ runner.os }}-yarn-${{ hashFiles(format('{0}{1}', github.workspace, '/yarn.lock')) }}
restore-keys: |
${{ runner.os }}-yarn-
- name: install dependencies
run: yarn install
- name: lint
run: yarn lint
unit-tests:
name: unit tests
runs-on: ubuntu-latest
env:
CI: true
steps:
- uses: actions/checkout@v2
- uses: actions/cache@v1
with:
path: ~/.cache/yarn
key: ${{ runner.os }}-yarn-${{ hashFiles(format('{0}{1}', github.workspace, '/yarn.lock')) }}
restore-keys: |
${{ runner.os }}-yarn-
- name: install dependencies
run: yarn install
- name: unit test
run: |
yarn test
visual-tests:
name: visual regression tests
runs-on: ubuntu-latest
env:
CI: true
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0 # Required to retrieve git history
- uses: actions/cache@v1
with:
path: ~/.cache/yarn
key: ${{ runner.os }}-yarn-${{ hashFiles(format('{0}{1}', github.workspace, '/yarn.lock')) }}
restore-keys: |
${{ runner.os }}-yarn-
- name: install dependencies
run: yarn install
- uses: chromaui/action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}

7 changes: 2 additions & 5 deletions src/components/Button/Button.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { v4 as uuid } from 'uuid';
import './Button.scss';
import { ReactComponent as LoadingIndicator } from '../../images/loading.svg';

Expand All @@ -18,8 +17,6 @@ const Button = ({
onFocus,
onBlur,
}) => {
const inputId = id || uuid();

const disabled = isLoading || isDisabled;

const buttonClasses = classNames('Palmetto-Button', className, {
Expand Down Expand Up @@ -52,9 +49,9 @@ const Button = ({

return (
<button
disabled={disabled}
id={inputId}
id={id}
type={type} // eslint-disable-line react/button-has-type
disabled={disabled}
className={buttonClasses}
onClick={handleClick}
onFocus={handleFocus}
Expand Down
14 changes: 0 additions & 14 deletions src/components/Button/Button.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
screen,
} from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import validateUuid from '../../lib/validateUuid';
import Button from './Button';

describe('Button', () => {
Expand Down Expand Up @@ -51,19 +50,6 @@ describe('Button', () => {
});
});

describe('Automatic ID Generator', () => {
test('Button correctly generates a uuid if none is provided', () => {
render(
<Button>
Button!
</Button>,
);
const buttonElement = screen.getByText('Button!').closest('button');

expect(validateUuid(buttonElement.id)).toBe(true);
});
});

describe('States', () => {
describe('Default', () => {
test('it renders the button with simple text', () => {
Expand Down
14 changes: 7 additions & 7 deletions src/components/CheckboxInput/CheckboxInput.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { v4 as uuid } from 'uuid';
import InputValidationMessage from '../InputValidationMessage/InputValidationMessage';
import FormLabel from '../FormLabel/FormLabel';
import './CheckboxInput.scss';

/**
* Used to allow users to make a range of selections (zero, one or many).
*/

const CheckboxInput = ({
id,
className,
Expand All @@ -16,8 +19,6 @@ const CheckboxInput = ({
onChange,
label,
}) => {
const inputId = id || uuid();

const handleChange = e => {
onChange(e.target.checked);
};
Expand All @@ -29,7 +30,7 @@ const CheckboxInput = ({

const labelProps = {
isFieldRequired: isRequired,
inputId,
inputId: id,
labelText: label,
hasError: !!error,
};
Expand All @@ -39,7 +40,7 @@ const CheckboxInput = ({
<div className={classNames('Palmetto-CheckboxInput', className, { isDisabled })}>
<input
aria-invalid={!!error}
id={inputId}
id={id}
checked={isChecked}
disabled={isDisabled}
onChange={handleChange}
Expand All @@ -54,7 +55,6 @@ const CheckboxInput = ({
};

CheckboxInput.defaultProps = {
id: undefined,
className: '',
error: false,
isChecked: false,
Expand All @@ -66,7 +66,7 @@ CheckboxInput.propTypes = {
/**
* The id attribute of the input
*/
id: PropTypes.string,
id: PropTypes.string.isRequired,
/**
* Additional classes to add
*/
Expand Down
8 changes: 8 additions & 0 deletions src/components/CheckboxInput/CheckboxInput.stories.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ export const All = () => {
<>
<div style={{ marginBottom: '1rem' }}>
<CheckboxInput
id="defaultStateIsUnchecked"
label="Default state is unchecked"
isChecked={state.default}
onChange={value => handleChange(value, 'default')}
/>
</div>
<div style={{ marginBottom: '1rem' }}>
<CheckboxInput
id="requiredCheckboxIsUnchecked"
isRequired
label="Required checkbox is unchecked"
isChecked={state.required}
Expand All @@ -48,13 +50,15 @@ export const All = () => {
</div>
<div style={{ marginBottom: '1rem' }}>
<CheckboxInput
id="initialStateChecked"
isChecked={state.initialChecked}
label="Initial state can be set to checked."
onChange={value => handleChange(value, 'initialChecked')}
/>
</div>
<div style={{ marginBottom: '1rem' }}>
<CheckboxInput
id="customLabel"
label={(
<>
<span style={{ color: '#5620c5' }}>
Expand All @@ -71,6 +75,7 @@ export const All = () => {
</div>
<div style={{ marginBottom: '1rem' }}>
<CheckboxInput
id="disabledAndUnchecked"
isDisabled
label="Disabled, and unchecked."
isChecked={state.disabledUnchecked}
Expand All @@ -79,6 +84,7 @@ export const All = () => {
</div>
<div style={{ marginBottom: '1rem' }}>
<CheckboxInput
id="disabledAndChecked"
label="Disabled, and checked."
isDisabled
isChecked={state.disabledChecked}
Expand All @@ -87,6 +93,7 @@ export const All = () => {
</div>
<div style={{ marginBottom: '1rem' }}>
<CheckboxInput
id="invalidCheckbox"
error="You must accept the Terms and Conditions"
label="Invalid checkbox"
isChecked={state.withError}
Expand All @@ -95,6 +102,7 @@ export const All = () => {
</div>
<div style={{ marginBottom: '1rem' }}>
<CheckboxInput
id="requiredInvalidCheckbox"
isRequired
error="You must accept the Terms and Conditions"
label="Required Invalid checkbox"
Expand Down
116 changes: 116 additions & 0 deletions src/components/CheckboxInput/CheckboxInput.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import React from 'react';
import {
render,
fireEvent,
} from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import CheckboxInput from './CheckboxInput';

describe('CheckboxInput', () => {
test('not disabled, checked, or invalid by default', () => {
const { getByLabelText } = render(
<CheckboxInput
id="testCheckbox"
label="test checkbox"
value="hello"
onChange={() => null}
/>,
);
const checkbox = getByLabelText('test checkbox');

expect(checkbox.checked).toBe(false);
expect(checkbox.disabled).toBe(false);
expect(checkbox.getAttribute('aria-invalid')).toBe('false');
});

test('it renders the label if provided', () => {
const { getByLabelText } = render(
<CheckboxInput
id="testCheckbox"
label="test checkbox"
value="hello"
onChange={() => null}
/>,
);
expect(getByLabelText('test checkbox')).toBeDefined();
});

test('input is checked when isChecked is true', () => {
const { getByLabelText } = render(
<CheckboxInput
id="testCheckbox"
label="test checkbox"
value="hello"
onChange={() => null}
isChecked
/>,
);
const checkbox = getByLabelText('test checkbox');
expect(checkbox.checked).toEqual(true);
});

test('input is not checked when isChecked is false', () => {
const { getByLabelText } = render(
<CheckboxInput
id="testCheckbox"
label="test checkbox"
value="hello"
onChange={() => null}
isChecked={false}
/>,
);
const checkbox = getByLabelText('test checkbox');
expect(checkbox.checked).toEqual(false);
});

describe('onChange', () => {
test('onChange event fires callback function', () => {
const mockedHandleChange = jest.fn(() => null);

const { getByLabelText } = render(
<CheckboxInput
id="testCheckbox"
label="test checkbox"
value="hello"
onChange={mockedHandleChange}
/>,
);
const checkbox = getByLabelText('test checkbox');
fireEvent.click(checkbox);
expect(mockedHandleChange).toHaveBeenCalledTimes(1);
});

test('calls onChange with true when isCheck is false', () => {
const mockedHandleChange = jest.fn(() => null);

const { getByLabelText } = render(
<CheckboxInput
id="testCheckbox"
label="test checkbox"
value="hello"
onChange={mockedHandleChange}
/>,
);
const checkbox = getByLabelText('test checkbox');
fireEvent.click(checkbox);
expect(mockedHandleChange).toHaveBeenCalledWith(true);
});

test('calls onChange with false when isChecked when true', () => {
const mockedHandleChange = jest.fn(() => null);

const { getByLabelText } = render(
<CheckboxInput
id="testCheckbox"
label="test checkbox"
value="hello"
onChange={mockedHandleChange}
isChecked
/>,
);
const checkbox = getByLabelText('test checkbox');
fireEvent.click(checkbox);
expect(mockedHandleChange).toHaveBeenCalledWith(false);
});
});
});
Loading

0 comments on commit 81ebf61

Please sign in to comment.