Skip to content

Commit

Permalink
Merge pull request #29 from samvera-labs/24-react-testing-library-switch
Browse files Browse the repository at this point in the history
Add Testing Library setup and some boilerplate tests for current comp…
  • Loading branch information
jrgriffiniii authored Feb 19, 2020
2 parents f4698dd + 74b028f commit 453982f
Show file tree
Hide file tree
Showing 16 changed files with 560 additions and 181 deletions.
13 changes: 13 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// jest.config.js
module.exports = {
collectCoverageFrom: ['src/**/*.{js,jsx}'],
coveragePathIgnorePatterns: [
'/node_modules/',
'src/serviceWorker.js',
'src/configureStore.js',
'src/bees.js',
'src/index.js',
'src/tests/*.{js,jsx}',
'src/__tests__/testing-helpers.js'
]
}
17 changes: 3 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"test": "react-scripts test --testPathIgnorePatterns=src/__tests__/testing-helpers.js --env=jsdom",
"test:coverage": "react-scripts test --coverage --watchAll=false",
"eject": "react-scripts eject",
"lint": "eslint './src/**/*.{js,jsx}'",
Expand All @@ -24,19 +24,6 @@
"eslintConfig": {
"extends": "react-app"
},
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx}"
],
"coveragePathIgnorePatterns": [
"/node_modules/",
"src/serviceWorker.js",
"src/configureStore.js",
"src/bees.js",
"src/index.js",
"src/tests/*.{js,jsx}"
]
},
"browserslist": {
"production": [
">0.2%",
Expand All @@ -50,6 +37,8 @@
]
},
"devDependencies": {
"@testing-library/jest-dom": "^5.1.1",
"@testing-library/react": "^9.4.0",
"babel-loader": "^8.0.6",
"cross-fetch": "^3.0.4",
"eslint": "^6.4.0",
Expand Down
9 changes: 3 additions & 6 deletions src/__tests__/App.test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import React from 'react'
import ReactDOM from 'react-dom'
import App from '../containers/App'
import { renderWithRedux } from './testing-helpers'

/**
* This needs to be implemented to handle working with the Redux Store
*/
it('renders the component on the DOM', () => {
// To be implemented
it('renders without crashing', () => {
expect(renderWithRedux(<App />))
})
23 changes: 16 additions & 7 deletions src/__tests__/AuthButton.test.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
import React from 'react'
import ReactDOM from 'react-dom'
import AuthButton from '../containers/AuthButton'
import { render } from '@testing-library/react'

describe('<AuthButton />', () => {
let defaultProps = {
handleClick: () => {},
authorizationUrl: 'http://cloud.org/authorize'
}

it('renders without crashing', () => {
expect(render(<AuthButton {...defaultProps} />))
})

it('renders the auth button', () => {
const { getByTestId, debug } = render(<AuthButton {...defaultProps} />)
expect(getByTestId('auth-button')).toBeInTheDocument()
})

it('renders the Sign in', () => {
// const wrapper = mount(<AuthButton {...defaultProps} />);
// expect(wrapper).toBeTruthy;
// expect(wrapper.text()).toEqual('Sign In');
const { getByTestId, debug } = render(<AuthButton {...defaultProps} />)
expect(getByTestId('auth-button')).toHaveTextContent(/sign in/i)
})

it('renders the Authorized', () => {
// const wrapper = mount(<AuthButton disabled={true} {...defaultProps} />);
// expect(wrapper).toBeTruthy;
// expect(wrapper.text()).toEqual('Authorized');
const { getByTestId, debug } = render(
<AuthButton {...defaultProps} disabled={true} />
)
expect(getByTestId('auth-button')).toHaveTextContent(/authorized/i)
})
})
25 changes: 23 additions & 2 deletions src/__tests__/ResourceNode.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
import React from 'react'
import ReactDOM from 'react-dom'
import ResourceNode from '../containers/ResourceNode'
import { render } from '@testing-library/react'

it('renders the component on the DOM', () => {})
const mockDispatch = jest.fn()

const defaultProps = {
selected: false,
label: 'Ima label',
bytestream: { foo: 'bar ' },
dispatch: mockDispatch
}

it('renders without crashing', () => {
expect(render(<ResourceNode {...defaultProps} />))
})

it('renders the resource node checkbox', () => {
const { getByTestId } = render(<ResourceNode {...defaultProps} />)
expect(getByTestId('resource-node-checkbox')).toBeInTheDocument()
})

it('renders expand/collapse button', () => {
const { getByTestId } = render(<ResourceNode {...defaultProps} />)
expect(getByTestId('expand-collapse-button')).toBeInTheDocument()
})
34 changes: 32 additions & 2 deletions src/__tests__/ResourceTree.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
import React from 'react'
import ReactDOM from 'react-dom'
import ResourceTree from '../containers/ResourceTree'
import { render } from '@testing-library/react'

it('renders the component on the DOM', () => {})
const mockDispatch = jest.fn()

const defaultProps = {
selected: false,
root: false,
label: 'Ima label',
dispatch: mockDispatch,
container: { foo: 'bar' }
}

it('renders without crashing', () => {
expect(render(<ResourceTree {...defaultProps} />))
})

it('renders resource tree wrapper element', () => {
const { getByTestId } = render(<ResourceTree {...defaultProps} />)
expect(getByTestId('resource-tree-wrapper')).toBeInTheDocument()
})

it('renders primary checkbox', () => {
const { getByTestId } = render(<ResourceTree {...defaultProps} />)
expect(getByTestId('primary-checkbox')).toBeInTheDocument()
})

it('renders expand/collapse button', () => {
const { getByTestId } = render(<ResourceTree {...defaultProps} />)
expect(getByTestId('expand-collapse-button')).toBeInTheDocument()
})

// Not really sure yet how to test <StyledChildResourceTree /> and
// < ResourceNode /> presence in this component
24 changes: 22 additions & 2 deletions src/__tests__/SelectProvider.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
import React from 'react'
import ReactDOM from 'react-dom'
import SelectProvider from '../containers/SelectProvider'
import { render } from '@testing-library/react'

it('renders the component on the DOM', () => {})
const mockFn = jest.fn()

const defaultProps = {
selectedProvider: { foo: 'bar' },
providers: { items: [], id: 'ABC123', name: 'Ima provider 1' },
handleChange: mockFn
}

it('renders without crashing', () => {
expect(render(<SelectProvider {...defaultProps} />))
})

it('renders the select provider form control', () => {
const { getByTestId } = render(<SelectProvider {...defaultProps} />)
expect(getByTestId('select-provider-wrapper')).toBeInTheDocument()
})

it('renders the select element', () => {
const { getByTestId } = render(<SelectProvider {...defaultProps} />)
expect(getByTestId('select-provider')).toBeInTheDocument()
})
40 changes: 38 additions & 2 deletions src/__tests__/UploadForm.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,41 @@
import React from 'react'
import ReactDOM from 'react-dom'
import UploadForm from '../containers/UploadForm'
import { render } from '@testing-library/react'

it('renders the component on the DOM', () => {})
const mockOnUpload = jest.fn()
const mockDispatch = jest.fn()

const defaultProps = {
selectedProvider: { foo: 'bar' },
providers: { items: [], id: 'ABC123', name: 'Ima provider 1' },
currentAuthToken: { foo: 'bar ' },
currentSession: {},
rootContainer: {},
currentUpload: {},
dispatch: mockDispatch,
onUpload: mockOnUpload
}

it('renders without crashing', () => {
expect(render(<UploadForm {...defaultProps} />))
})

it('renders the form', () => {
const { getByTestId } = render(<UploadForm {...defaultProps} />)
expect(getByTestId('upload-form')).toBeInTheDocument()
})

it('renders the Select Providers section', () => {
const { getByTestId } = render(<UploadForm {...defaultProps} />)
expect(getByTestId('select-provider-wrapper')).toBeInTheDocument()
})

it('renders the resource tree section', () => {
const { getByTestId } = render(<UploadForm {...defaultProps} />)
expect(getByTestId('resource-tree-wrapper')).toBeInTheDocument()
})

it('renders the submit button', () => {
const { getByTestId } = render(<UploadForm {...defaultProps} />)
expect(getByTestId('upload-submit-button')).toBeInTheDocument()
})
21 changes: 21 additions & 0 deletions src/__tests__/testing-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'
import { Provider } from 'react-redux'
import { render } from '@testing-library/react'
import reducer from '../reducers'
import configureStore from '../configureStore'

// this is a handy function that I normally make available for all my tests
// that deal with connected components.
// you can provide initialState for the entire store that the ui is rendered with
export function renderWithRedux(
ui,
{ initialState, store = configureStore(initialState) } = {}
) {
return {
...render(<Provider store={store}>{ui}</Provider>),
// adding `store` to the returned utilities to allow us
// to reference it in our tests (just try to avoid using
// this to test implementation details).
store
}
}
55 changes: 28 additions & 27 deletions src/containers/AuthButton.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
import React from 'react';
import PropTypes from 'prop-types';
import React from 'react'
import PropTypes from 'prop-types'
import Button from '@material-ui/core/Button'
import { makeStyles } from '@material-ui/core/styles'

import Button from '@material-ui/core/Button';
import { withStyles } from '@material-ui/core/styles';

class AuthButton extends React.Component {
render() {
const textContent = this.props.disabled ? 'Authorized' : 'Sign In';
return (
<Button
variant="contained"
color="secondary"
className={this.props.classes.root}
onClick={this.props.handleClick}
href={this.props.authorizationUrl}
disabled={this.props.disabled}>{textContent}
</Button>
);
const useStyles = makeStyles({
root: {
alignSelf: 'center'
}
})

const AuthButton = ({ handleClick, authorizationUrl, disabled }) => {
const classes = useStyles
const textContent = disabled ? 'Authorized' : 'Sign In'

return (
<Button
data-testid="auth-button"
variant="contained"
color="secondary"
className={classes.root}
onClick={handleClick}
href={authorizationUrl}
disabled={disabled}
>
{textContent}
</Button>
)
}

AuthButton.propTypes = {
classes: PropTypes.object.isRequired,
handleClick: PropTypes.func.isRequired,
authorizationUrl: PropTypes.string.isRequired,
disabled: PropTypes.bool
};

const styles = {
root: {
alignSelf: 'center'
}
};
}

export default withStyles(styles)(AuthButton);
export default AuthButton
8 changes: 6 additions & 2 deletions src/containers/ResourceNode.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react'
import PropTypes from 'prop-types'

import Checkbox from '@material-ui/core/Checkbox'
import IconButton from '@material-ui/core/IconButton'
import InsertDriveFileIcon from '@material-ui/icons/InsertDriveFile'
Expand Down Expand Up @@ -35,6 +34,7 @@ class ResourceNode extends React.Component {
return (
<div className={this.props.classes.root}>
<Checkbox
data-testid="resource-node-checkbox"
checked={this.state.selected}
onChange={this.handleChecked}
value="selected"
Expand All @@ -43,7 +43,11 @@ class ResourceNode extends React.Component {
}}
/>

<IconButton aria-label="expand or collapse" size="small">
<IconButton
data-testid="expand-collapse-button"
aria-label="expand or collapse"
size="small"
>
<InsertDriveFileIcon />
</IconButton>

Expand Down
9 changes: 6 additions & 3 deletions src/containers/ResourceTree.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import React from 'react'
import PropTypes from 'prop-types'

import Checkbox from '@material-ui/core/Checkbox'
import FolderIcon from '@material-ui/icons/Folder'
import FolderOpenIcon from '@material-ui/icons/FolderOpen'
import IconButton from '@material-ui/core/IconButton'
import { withStyles } from '@material-ui/core/styles'

import {
getContainer,
selectContainerForUpload,
Expand Down Expand Up @@ -52,11 +50,15 @@ class ResourceTree extends React.Component {

render() {
return (
<div className={this.props.classes.root}>
<div
className={this.props.classes.root}
data-testid="resource-tree-wrapper"
>
<div>
{!this.props.root && (
<span>
<Checkbox
data-testid="primary-checkbox"
checked={this.state.selected}
onChange={this.handleChecked}
value="selected"
Expand All @@ -65,6 +67,7 @@ class ResourceTree extends React.Component {
}}
/>
<IconButton
data-testid="expand-collapse-button"
aria-label="expand or collapse"
size="small"
onClick={
Expand Down
Loading

0 comments on commit 453982f

Please sign in to comment.