Merge pull request #172 from jlmitch5/moveTestContext

PR for moving tests to using new mountWithContext helper
This commit is contained in:
Michael Abashian
2019-04-23 09:58:15 -04:00
committed by GitHub
35 changed files with 792 additions and 1254 deletions

View File

@@ -1,50 +1,36 @@
import React from 'react'; import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { I18nProvider } from '@lingui/react';
import { mount } from 'enzyme'; import { mountWithContexts } from './enzymeHelpers';
import { asyncFlush } from '../jest.setup'; import { asyncFlush } from '../jest.setup';
import { ConfigProvider } from '../src/contexts/Config'; import App from '../src/App';
import { NetworkProvider } from '../src/contexts/Network';
import App, { _App } from '../src/App';
const networkProviderValue = { api: {}, handleHttpError: () => {} };
describe('<App />', () => { describe('<App />', () => {
test('expected content is rendered', () => { test('expected content is rendered', () => {
const appWrapper = mount( const appWrapper = mountWithContexts(
<MemoryRouter> <App
<I18nProvider> routeGroups={[
<NetworkProvider value={networkProviderValue}> {
<ConfigProvider> groupTitle: 'Group One',
<App groupId: 'group_one',
routeGroups={[ routes: [
{ { title: 'Foo', path: '/foo' },
groupTitle: 'Group One', { title: 'Bar', path: '/bar' },
groupId: 'group_one', ],
routes: [ },
{ title: 'Foo', path: '/foo' }, {
{ title: 'Bar', path: '/bar' }, groupTitle: 'Group Two',
], groupId: 'group_two',
}, routes: [
{ { title: 'Fiz', path: '/fiz' },
groupTitle: 'Group Two', ]
groupId: 'group_two', }
routes: [ ]}
{ title: 'Fiz', path: '/fiz' }, render={({ routeGroups }) => (
] routeGroups.map(({ groupId }) => (<div key={groupId} id={groupId} />))
} )}
]} />
render={({ routeGroups }) => (
routeGroups.map(({ groupId }) => (<div key={groupId} id={groupId} />))
)}
/>
</ConfigProvider>
</NetworkProvider>
</I18nProvider>
</MemoryRouter>
); );
// page components // page components
@@ -69,17 +55,7 @@ describe('<App />', () => {
const config = { ansible_version, version }; const config = { ansible_version, version };
const wrapper = mount( const wrapper = mountWithContexts(<App />, { context: { config } });
<MemoryRouter>
<I18nProvider>
<NetworkProvider value={networkProviderValue}>
<ConfigProvider value={config}>
<App />
</ConfigProvider>
</NetworkProvider>
</I18nProvider>
</MemoryRouter>
);
// open about modal // open about modal
const aboutDropdown = 'Dropdown QuestionCircleIcon'; const aboutDropdown = 'Dropdown QuestionCircleIcon';
@@ -106,19 +82,8 @@ describe('<App />', () => {
}); });
test('onNavToggle sets state.isNavOpen to opposite', () => { test('onNavToggle sets state.isNavOpen to opposite', () => {
const appWrapper = mount( const appWrapper = mountWithContexts(<App />).find('App');
<MemoryRouter>
<I18nProvider>
<NetworkProvider value={networkProviderValue}>
<ConfigProvider>
<App />
</ConfigProvider>
</NetworkProvider>
</I18nProvider>
</MemoryRouter>
).find('App');
const { onNavToggle } = appWrapper.instance(); const { onNavToggle } = appWrapper.instance();
[true, false, true, false, true].forEach(expected => { [true, false, true, false, true].forEach(expected => {
expect(appWrapper.state().isNavOpen).toBe(expected); expect(appWrapper.state().isNavOpen).toBe(expected);
onNavToggle(); onNavToggle();
@@ -128,17 +93,9 @@ describe('<App />', () => {
test('onLogout makes expected call to api client', async (done) => { test('onLogout makes expected call to api client', async (done) => {
const logout = jest.fn(() => Promise.resolve()); const logout = jest.fn(() => Promise.resolve());
const appWrapper = mount( const appWrapper = mountWithContexts(<App />, {
<MemoryRouter> context: { network: { api: { logout }, handleHttpError: () => {} } }
<I18nProvider> }).find('App');
<NetworkProvider value={networkProviderValue}>
<ConfigProvider>
<_App api={{ logout }} handleHttpError={() => {}} />
</ConfigProvider>
</NetworkProvider>
</I18nProvider>
</MemoryRouter>
).find('App');
appWrapper.instance().onLogout(); appWrapper.instance().onLogout();
await asyncFlush(); await asyncFlush();

View File

@@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mountWithContexts } from '../enzymeHelpers';
import { I18nProvider } from '@lingui/react';
import About from '../../src/components/About'; import About from '../../src/components/About';
describe('<About />', () => { describe('<About />', () => {
@@ -8,20 +7,16 @@ describe('<About />', () => {
let closeButton; let closeButton;
const onClose = jest.fn(); const onClose = jest.fn();
test('initially renders without crashing', () => { test('initially renders without crashing', () => {
aboutWrapper = mount( aboutWrapper = mountWithContexts(
<I18nProvider> <About isOpen onClose={onClose} />
<About isOpen onClose={onClose} />
</I18nProvider>
); );
expect(aboutWrapper.length).toBe(1); expect(aboutWrapper.length).toBe(1);
aboutWrapper.unmount(); aboutWrapper.unmount();
}); });
test('close button calls onClose handler', () => { test('close button calls onClose handler', () => {
aboutWrapper = mount( aboutWrapper = mountWithContexts(
<I18nProvider> <About isOpen onClose={onClose} />
<About isOpen onClose={onClose} />
</I18nProvider>
); );
closeButton = aboutWrapper.find('AboutModalBoxCloseButton Button'); closeButton = aboutWrapper.find('AboutModalBoxCloseButton Button');
closeButton.simulate('click'); closeButton.simulate('click');

View File

@@ -1,37 +1,32 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mountWithContexts } from '../enzymeHelpers';
import { I18nProvider } from '@lingui/react';
import AnsibleSelect from '../../src/components/AnsibleSelect'; import AnsibleSelect from '../../src/components/AnsibleSelect';
const label = 'test select'; const label = 'test select';
const mockData = ['/venv/baz/', '/venv/ansible/']; const mockData = ['/venv/baz/', '/venv/ansible/'];
describe('<AnsibleSelect />', () => { describe('<AnsibleSelect />', () => {
test('initially renders succesfully', async () => { test('initially renders succesfully', async () => {
mount( mountWithContexts(
<I18nProvider> <AnsibleSelect
<AnsibleSelect value="foo"
value="foo" name="bar"
name="bar" onChange={() => { }}
onChange={() => { }} label={label}
label={label} data={mockData}
data={mockData} />
/>
</I18nProvider>
); );
}); });
test('calls "onSelectChange" on dropdown select change', () => { test('calls "onSelectChange" on dropdown select change', () => {
const spy = jest.spyOn(AnsibleSelect.prototype, 'onSelectChange'); const spy = jest.spyOn(AnsibleSelect.prototype, 'onSelectChange');
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <AnsibleSelect
<AnsibleSelect value="foo"
value="foo" name="bar"
name="bar" onChange={() => { }}
onChange={() => { }} label={label}
label={label} data={mockData}
data={mockData} />
/>
</I18nProvider>
); );
expect(spy).not.toHaveBeenCalled(); expect(spy).not.toHaveBeenCalled();
wrapper.find('select').simulate('change'); wrapper.find('select').simulate('change');
@@ -39,17 +34,15 @@ describe('<AnsibleSelect />', () => {
}); });
test('Returns correct select options if defaultSelected props is passed', () => { test('Returns correct select options if defaultSelected props is passed', () => {
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <AnsibleSelect
<AnsibleSelect value="foo"
value="foo" name="bar"
name="bar" onChange={() => { }}
onChange={() => { }} label={label}
label={label} data={mockData}
data={mockData} defaultSelected={mockData[1]}
defaultSelected={mockData[1]} />
/>
</I18nProvider>
); );
expect(wrapper.find('FormSelect')).toHaveLength(1); expect(wrapper.find('FormSelect')).toHaveLength(1);
}); });

View File

@@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mountWithContexts } from '../enzymeHelpers';
import { I18nProvider } from '@lingui/react';
import DataListToolbar from '../../src/components/DataListToolbar'; import DataListToolbar from '../../src/components/DataListToolbar';
describe('<DataListToolbar />', () => { describe('<DataListToolbar />', () => {
@@ -25,20 +24,18 @@ describe('<DataListToolbar />', () => {
const onSort = jest.fn(); const onSort = jest.fn();
const onSelectAll = jest.fn(); const onSelectAll = jest.fn();
toolbar = mount( toolbar = mountWithContexts(
<I18nProvider> <DataListToolbar
<DataListToolbar isAllSelected={false}
isAllSelected={false} showExpandCollapse
showExpandCollapse sortedColumnKey="name"
sortedColumnKey="name" sortOrder="ascending"
sortOrder="ascending" columns={columns}
columns={columns} onSearch={onSearch}
onSearch={onSearch} onSort={onSort}
onSort={onSort} onSelectAll={onSelectAll}
onSelectAll={onSelectAll} showSelectAll
showSelectAll />
/>
</I18nProvider>
); );
toolbar.find(sort).simulate('click'); toolbar.find(sort).simulate('click');
@@ -76,18 +73,16 @@ describe('<DataListToolbar />', () => {
const onSort = jest.fn(); const onSort = jest.fn();
const onSelectAll = jest.fn(); const onSelectAll = jest.fn();
toolbar = mount( toolbar = mountWithContexts(
<I18nProvider> <DataListToolbar
<DataListToolbar isAllSelected={false}
isAllSelected={false} sortedColumnKey="foo"
sortedColumnKey="foo" sortOrder="ascending"
sortOrder="ascending" columns={multipleColumns}
columns={multipleColumns} onSearch={onSearch}
onSearch={onSearch} onSort={onSort}
onSort={onSort} onSelectAll={onSelectAll}
onSelectAll={onSelectAll} />
/>
</I18nProvider>
); );
const sortDropdownToggle = toolbar.find(sortDropdownToggleSelector); const sortDropdownToggle = toolbar.find(sortDropdownToggleSelector);
expect(sortDropdownToggle.length).toBe(2); expect(sortDropdownToggle.length).toBe(2);
@@ -100,18 +95,16 @@ describe('<DataListToolbar />', () => {
const mockedSortEvent = { target: { innerText: 'Bar' } }; const mockedSortEvent = { target: { innerText: 'Bar' } };
sortDropdownItems.at(0).simulate('click', mockedSortEvent); sortDropdownItems.at(0).simulate('click', mockedSortEvent);
toolbar = mount( toolbar = mountWithContexts(
<I18nProvider> <DataListToolbar
<DataListToolbar isAllSelected={false}
isAllSelected={false} sortedColumnKey="foo"
sortedColumnKey="foo" sortOrder="descending"
sortOrder="descending" columns={multipleColumns}
columns={multipleColumns} onSearch={onSearch}
onSearch={onSearch} onSort={onSort}
onSort={onSort} onSelectAll={onSelectAll}
onSelectAll={onSelectAll} />
/>
</I18nProvider>
); );
toolbar.update(); toolbar.update();
@@ -152,70 +145,62 @@ describe('<DataListToolbar />', () => {
const onSort = jest.fn(); const onSort = jest.fn();
const onSelectAll = jest.fn(); const onSelectAll = jest.fn();
toolbar = mount( toolbar = mountWithContexts(
<I18nProvider> <DataListToolbar
<DataListToolbar isAllSelected={false}
isAllSelected={false} sortedColumnKey="id"
sortedColumnKey="id" sortOrder="descending"
sortOrder="descending" columns={numericColumns}
columns={numericColumns} onSearch={onSearch}
onSearch={onSearch} onSort={onSort}
onSort={onSort} onSelectAll={onSelectAll}
onSelectAll={onSelectAll} showDelete
showDelete />
/>
</I18nProvider>
); );
const downNumericIcon = toolbar.find(downNumericIconSelector); const downNumericIcon = toolbar.find(downNumericIconSelector);
expect(downNumericIcon.length).toBe(1); expect(downNumericIcon.length).toBe(1);
toolbar = mount( toolbar = mountWithContexts(
<I18nProvider> <DataListToolbar
<DataListToolbar isAllSelected={false}
isAllSelected={false} sortedColumnKey="id"
sortedColumnKey="id" sortOrder="ascending"
sortOrder="ascending" columns={numericColumns}
columns={numericColumns} onSearch={onSearch}
onSearch={onSearch} onSort={onSort}
onSort={onSort} onSelectAll={onSelectAll}
onSelectAll={onSelectAll} />
/>
</I18nProvider>
); );
const upNumericIcon = toolbar.find(upNumericIconSelector); const upNumericIcon = toolbar.find(upNumericIconSelector);
expect(upNumericIcon.length).toBe(1); expect(upNumericIcon.length).toBe(1);
toolbar = mount( toolbar = mountWithContexts(
<I18nProvider> <DataListToolbar
<DataListToolbar isAllSelected={false}
isAllSelected={false} sortedColumnKey="name"
sortedColumnKey="name" sortOrder="descending"
sortOrder="descending" columns={alphaColumns}
columns={alphaColumns} onSearch={onSearch}
onSearch={onSearch} onSort={onSort}
onSort={onSort} onSelectAll={onSelectAll}
onSelectAll={onSelectAll} />
/>
</I18nProvider>
); );
const downAlphaIcon = toolbar.find(downAlphaIconSelector); const downAlphaIcon = toolbar.find(downAlphaIconSelector);
expect(downAlphaIcon.length).toBe(1); expect(downAlphaIcon.length).toBe(1);
toolbar = mount( toolbar = mountWithContexts(
<I18nProvider> <DataListToolbar
<DataListToolbar isAllSelected={false}
isAllSelected={false} sortedColumnKey="name"
sortedColumnKey="name" sortOrder="ascending"
sortOrder="ascending" columns={alphaColumns}
columns={alphaColumns} onSearch={onSearch}
onSearch={onSearch} onSort={onSort}
onSort={onSort} onSelectAll={onSelectAll}
onSelectAll={onSelectAll} />
/>
</I18nProvider>
); );
const upAlphaIcon = toolbar.find(upAlphaIconSelector); const upAlphaIcon = toolbar.find(upAlphaIconSelector);
@@ -232,22 +217,20 @@ describe('<DataListToolbar />', () => {
const showDelete = true; const showDelete = true;
const disableTrashCanIcon = false; const disableTrashCanIcon = false;
toolbar = mount( toolbar = mountWithContexts(
<I18nProvider> <DataListToolbar
<DataListToolbar isAllSelected={false}
isAllSelected={false} selected={() => [1, 2, 3, 4]}
selected={() => [1, 2, 3, 4]} sortedColumnKey="name"
sortedColumnKey="name" sortOrder="ascending"
sortOrder="ascending" columns={columns}
columns={columns} onSearch={onSearch}
onSearch={onSearch} onSort={onSort}
onSort={onSort} onSelectAll={onSelectAll}
onSelectAll={onSelectAll} onOpenDeleteModal={onOpenDeleteModal}
onOpenDeleteModal={onOpenDeleteModal} showDelete={showDelete}
showDelete={showDelete} disableTrashCanIcon={disableTrashCanIcon}
disableTrashCanIcon={disableTrashCanIcon} />
/>
</I18nProvider>
); );
toolbar.find(openDeleteModalButton).simulate('click'); toolbar.find(openDeleteModalButton).simulate('click');

View File

@@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mountWithContexts } from '../enzymeHelpers';
import { I18nProvider } from '@lingui/react';
import ExpandCollapse from '../../src/components/ExpandCollapse'; import ExpandCollapse from '../../src/components/ExpandCollapse';
describe('<ExpandCollapse />', () => { describe('<ExpandCollapse />', () => {
@@ -8,14 +7,12 @@ describe('<ExpandCollapse />', () => {
const onExpand = jest.fn(); const onExpand = jest.fn();
const isCompact = false; const isCompact = false;
test('initially renders without crashing', () => { test('initially renders without crashing', () => {
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <ExpandCollapse
<ExpandCollapse onCompact={onCompact}
onCompact={onCompact} onExpand={onExpand}
onExpand={onExpand} isCompact={isCompact}
isCompact={isCompact} />
/>
</I18nProvider>
); );
expect(wrapper.length).toBe(1); expect(wrapper.length).toBe(1);
wrapper.unmount(); wrapper.unmount();

View File

@@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mountWithContexts } from '../enzymeHelpers';
import { I18nProvider } from '@lingui/react';
import Lookup from '../../src/components/Lookup'; import Lookup from '../../src/components/Lookup';
import { _Lookup } from '../../src/components/Lookup/Lookup'; import { _Lookup } from '../../src/components/Lookup/Lookup';
@@ -10,36 +9,32 @@ const mockColumns = [
]; ];
describe('<Lookup />', () => { describe('<Lookup />', () => {
test('initially renders succesfully', () => { test('initially renders succesfully', () => {
mount( mountWithContexts(
<I18nProvider> <_Lookup
<_Lookup lookup_header="Foo Bar"
lookup_header="Foo Bar" name="fooBar"
name="fooBar" value={mockData}
value={mockData} onLookupSave={() => { }}
onLookupSave={() => { }} getItems={() => { }}
getItems={() => { }} columns={mockColumns}
columns={mockColumns} sortedColumnKey="name"
sortedColumnKey="name" handleHttpError={() => {}}
handleHttpError={() => {}} />
/>
</I18nProvider>
); );
}); });
test('API response is formatted properly', (done) => { test('API response is formatted properly', (done) => {
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <_Lookup
<_Lookup lookup_header="Foo Bar"
lookup_header="Foo Bar" name="fooBar"
name="fooBar" value={mockData}
value={mockData} onLookupSave={() => { }}
onLookupSave={() => { }} getItems={() => ({ data: { results: [{ name: 'test instance', id: 1 }] } })}
getItems={() => ({ data: { results: [{ name: 'test instance', id: 1 }] } })} columns={mockColumns}
columns={mockColumns} sortedColumnKey="name"
sortedColumnKey="name" handleHttpError={() => {}}
handleHttpError={() => {}} />
/>
</I18nProvider>
).find('Lookup'); ).find('Lookup');
setImmediate(() => { setImmediate(() => {
@@ -51,20 +46,18 @@ describe('<Lookup />', () => {
test('Opens modal when search icon is clicked', () => { test('Opens modal when search icon is clicked', () => {
const spy = jest.spyOn(_Lookup.prototype, 'handleModalToggle'); const spy = jest.spyOn(_Lookup.prototype, 'handleModalToggle');
const mockSelected = [{ name: 'foo', id: 1 }]; const mockSelected = [{ name: 'foo', id: 1 }];
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <_Lookup
<_Lookup id="search"
id="search" lookup_header="Foo Bar"
lookup_header="Foo Bar" name="fooBar"
name="fooBar" value={mockSelected}
value={mockSelected} onLookupSave={() => { }}
onLookupSave={() => { }} getItems={() => { }}
getItems={() => { }} columns={mockColumns}
columns={mockColumns} sortedColumnKey="name"
sortedColumnKey="name" handleHttpError={() => {}}
handleHttpError={() => {}} />
/>
</I18nProvider>
).find('Lookup'); ).find('Lookup');
expect(spy).not.toHaveBeenCalled(); expect(spy).not.toHaveBeenCalled();
expect(wrapper.state('lookupSelectedItems')).toEqual(mockSelected); expect(wrapper.state('lookupSelectedItems')).toEqual(mockSelected);
@@ -81,20 +74,18 @@ describe('<Lookup />', () => {
test('calls "toggleSelected" when a user changes a checkbox', (done) => { test('calls "toggleSelected" when a user changes a checkbox', (done) => {
const spy = jest.spyOn(_Lookup.prototype, 'toggleSelected'); const spy = jest.spyOn(_Lookup.prototype, 'toggleSelected');
const mockSelected = [{ name: 'foo', id: 1 }]; const mockSelected = [{ name: 'foo', id: 1 }];
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <_Lookup
<_Lookup id="search"
id="search" lookup_header="Foo Bar"
lookup_header="Foo Bar" name="fooBar"
name="fooBar" value={mockSelected}
value={mockSelected} onLookupSave={() => { }}
onLookupSave={() => { }} getItems={() => ({ data: { results: [{ name: 'test instance', id: 1 }] } })}
getItems={() => ({ data: { results: [{ name: 'test instance', id: 1 }] } })} columns={mockColumns}
columns={mockColumns} sortedColumnKey="name"
sortedColumnKey="name" handleHttpError={() => {}}
handleHttpError={() => {}} />
/>
</I18nProvider>
); );
setImmediate(() => { setImmediate(() => {
const searchItem = wrapper.find('button[aria-label="Search"]'); const searchItem = wrapper.find('button[aria-label="Search"]');
@@ -108,20 +99,18 @@ describe('<Lookup />', () => {
test('calls "toggleSelected" when remove icon is clicked', () => { test('calls "toggleSelected" when remove icon is clicked', () => {
const spy = jest.spyOn(_Lookup.prototype, 'toggleSelected'); const spy = jest.spyOn(_Lookup.prototype, 'toggleSelected');
mockData = [{ name: 'foo', id: 1 }, { name: 'bar', id: 2 }]; mockData = [{ name: 'foo', id: 1 }, { name: 'bar', id: 2 }];
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <_Lookup
<_Lookup id="search"
id="search" lookup_header="Foo Bar"
lookup_header="Foo Bar" name="fooBar"
name="fooBar" value={mockData}
value={mockData} onLookupSave={() => { }}
onLookupSave={() => { }} getItems={() => { }}
getItems={() => { }} columns={mockColumns}
columns={mockColumns} sortedColumnKey="name"
sortedColumnKey="name" handleHttpError={() => {}}
handleHttpError={() => {}} />
/>
</I18nProvider>
); );
const removeIcon = wrapper.find('button[aria-label="close"]').first(); const removeIcon = wrapper.find('button[aria-label="close"]').first();
removeIcon.simulate('click'); removeIcon.simulate('click');
@@ -130,19 +119,16 @@ describe('<Lookup />', () => {
test('renders chips from prop value', () => { test('renders chips from prop value', () => {
mockData = [{ name: 'foo', id: 0 }, { name: 'bar', id: 1 }]; mockData = [{ name: 'foo', id: 0 }, { name: 'bar', id: 1 }];
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <Lookup
<Lookup lookup_header="Foo Bar"
lookup_header="Foo Bar" onLookupSave={() => { }}
onLookupSave={() => { }} value={mockData}
value={mockData} selected={[]}
selected={[]} getItems={() => { }}
getItems={() => { }} columns={mockColumns}
columns={mockColumns} sortedColumnKey="name"
sortedColumnKey="name" />
handleHttpError={() => {}}
/>
</I18nProvider>
).find('Lookup'); ).find('Lookup');
const chip = wrapper.find('li.pf-c-chip'); const chip = wrapper.find('li.pf-c-chip');
expect(chip).toHaveLength(2); expect(chip).toHaveLength(2);
@@ -150,18 +136,15 @@ describe('<Lookup />', () => {
test('toggleSelected successfully adds/removes row from lookupSelectedItems state', () => { test('toggleSelected successfully adds/removes row from lookupSelectedItems state', () => {
mockData = []; mockData = [];
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <Lookup
<Lookup lookup_header="Foo Bar"
lookup_header="Foo Bar" onLookupSave={() => { }}
onLookupSave={() => { }} value={mockData}
value={mockData} getItems={() => { }}
getItems={() => { }} columns={mockColumns}
columns={mockColumns} sortedColumnKey="name"
sortedColumnKey="name" />
handleHttpError={() => {}}
/>
</I18nProvider>
).find('Lookup'); ).find('Lookup');
wrapper.instance().toggleSelected({ wrapper.instance().toggleSelected({
id: 1, id: 1,
@@ -181,17 +164,14 @@ describe('<Lookup />', () => {
test('saveModal calls callback with selected items', () => { test('saveModal calls callback with selected items', () => {
mockData = []; mockData = [];
const onLookupSaveFn = jest.fn(); const onLookupSaveFn = jest.fn();
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <Lookup
<Lookup lookup_header="Foo Bar"
lookup_header="Foo Bar" name="fooBar"
name="fooBar" value={mockData}
value={mockData} onLookupSave={onLookupSaveFn}
onLookupSave={onLookupSaveFn} getItems={() => { }}
getItems={() => { }} />
handleHttpError={() => {}}
/>
</I18nProvider>
).find('Lookup'); ).find('Lookup');
wrapper.instance().toggleSelected({ wrapper.instance().toggleSelected({
id: 1, id: 1,
@@ -210,19 +190,17 @@ describe('<Lookup />', () => {
test('onSort sets state and calls getData ', () => { test('onSort sets state and calls getData ', () => {
const spy = jest.spyOn(_Lookup.prototype, 'getData'); const spy = jest.spyOn(_Lookup.prototype, 'getData');
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <_Lookup
<_Lookup lookup_header="Foo Bar"
lookup_header="Foo Bar" onLookupSave={() => { }}
onLookupSave={() => { }} value={mockData}
value={mockData} selected={[]}
selected={[]} columns={mockColumns}
columns={mockColumns} sortedColumnKey="name"
sortedColumnKey="name" getItems={() => { }}
getItems={() => { }} handleHttpError={() => {}}
handleHttpError={() => {}} />
/>
</I18nProvider>
).find('Lookup'); ).find('Lookup');
wrapper.instance().onSort('id', 'descending'); wrapper.instance().onSort('id', 'descending');
expect(wrapper.state('sortedColumnKey')).toEqual('id'); expect(wrapper.state('sortedColumnKey')).toEqual('id');
@@ -232,19 +210,17 @@ describe('<Lookup />', () => {
test('onSearch calls getData (through calling onSort)', () => { test('onSearch calls getData (through calling onSort)', () => {
const spy = jest.spyOn(_Lookup.prototype, 'getData'); const spy = jest.spyOn(_Lookup.prototype, 'getData');
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <_Lookup
<_Lookup lookup_header="Foo Bar"
lookup_header="Foo Bar" onLookupSave={() => { }}
onLookupSave={() => { }} value={mockData}
value={mockData} selected={[]}
selected={[]} columns={mockColumns}
columns={mockColumns} sortedColumnKey="name"
sortedColumnKey="name" getItems={() => { }}
getItems={() => { }} handleHttpError={() => {}}
handleHttpError={() => {}} />
/>
</I18nProvider>
).find('Lookup'); ).find('Lookup');
wrapper.instance().onSearch(); wrapper.instance().onSearch();
expect(spy).toHaveBeenCalled(); expect(spy).toHaveBeenCalled();
@@ -252,19 +228,17 @@ describe('<Lookup />', () => {
test('onSetPage sets state and calls getData ', () => { test('onSetPage sets state and calls getData ', () => {
const spy = jest.spyOn(_Lookup.prototype, 'getData'); const spy = jest.spyOn(_Lookup.prototype, 'getData');
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <_Lookup
<_Lookup lookup_header="Foo Bar"
lookup_header="Foo Bar" onLookupSave={() => { }}
onLookupSave={() => { }} value={mockData}
value={mockData} selected={[]}
selected={[]} columns={mockColumns}
columns={mockColumns} sortedColumnKey="name"
sortedColumnKey="name" getItems={() => { }}
getItems={() => { }} handleHttpError={() => {}}
handleHttpError={() => {}} />
/>
</I18nProvider>
).find('Lookup'); ).find('Lookup');
wrapper.instance().onSetPage(2, 10); wrapper.instance().onSetPage(2, 10);
expect(wrapper.state('page')).toEqual(2); expect(wrapper.state('page')).toEqual(2);

View File

@@ -39,7 +39,7 @@ describe('NavExpandableGroup', () => {
]; ];
params.forEach(([location, path, expected]) => { params.forEach(([location, path, expected]) => {
test(`when location is ${location}', isActivePath('${path}') returns ${expected} `, () => { test(`when location is ${location}, isActivePath('${path}') returns ${expected} `, () => {
const component = mount( const component = mount(
<MemoryRouter initialEntries={[location]}> <MemoryRouter initialEntries={[location]}>
<Nav aria-label="Test Navigation"> <Nav aria-label="Test Navigation">

View File

@@ -1,139 +1,107 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mountWithContexts } from '../enzymeHelpers';
import { MemoryRouter } from 'react-router-dom';
import { I18nProvider } from '@lingui/react';
import Notifications, { _Notifications } from '../../src/components/NotificationsList/Notifications.list'; import Notifications, { _Notifications } from '../../src/components/NotificationsList/Notifications.list';
describe('<Notifications />', () => { describe('<Notifications />', () => {
test('initially renders succesfully', () => { test('initially renders succesfully', () => {
mount( mountWithContexts(
<MemoryRouter> <Notifications
<I18nProvider> onReadError={() => {}}
<Notifications onReadNotifications={() => {}}
match={{ path: '/organizations/:id/?tab=notifications', url: '/organizations/:id/?tab=notifications' }} onReadSuccess={() => {}}
location={{ search: '', pathname: '/organizations/:id/?tab=notifications' }} onCreateError={() => {}}
onReadError={jest.fn()} onCreateSuccess={() => {}}
onReadNotifications={jest.fn()} />
onReadSuccess={jest.fn()}
onCreateError={jest.fn()}
onCreateSuccess={jest.fn()}
handleHttpError={() => {}}
/>
</I18nProvider>
</MemoryRouter>
); );
}); });
test('fetches notifications on mount', () => { test('fetches notifications on mount', () => {
const spy = jest.spyOn(_Notifications.prototype, 'readNotifications'); const spy = jest.spyOn(_Notifications.prototype, 'readNotifications');
mount( mountWithContexts(
<I18nProvider> <Notifications
<_Notifications onReadError={() => {}}
match={{ path: '/organizations/:id/?tab=notifications', url: '/organizations/:id/?tab=notifications' }} onReadNotifications={() => {}}
location={{ search: '', pathname: '/organizations/:id/?tab=notifications' }} onReadSuccess={() => {}}
onReadError={jest.fn()} onCreateError={() => {}}
onReadNotifications={jest.fn()} onCreateSuccess={() => {}}
onReadSuccess={jest.fn()} />
onCreateError={jest.fn()}
onCreateSuccess={jest.fn()}
handleHttpError={() => {}}
/>
</I18nProvider>
); );
expect(spy).toHaveBeenCalled(); expect(spy).toHaveBeenCalled();
}); });
test('toggle success calls post', () => { test('toggle success calls post', () => {
const spy = jest.spyOn(_Notifications.prototype, 'createSuccess'); const spy = jest.spyOn(_Notifications.prototype, 'createSuccess');
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <Notifications
<_Notifications onReadError={() => {}}
match={{ path: '/organizations/:id/?tab=notifications', url: '/organizations/:id/?tab=notifications' }} onReadNotifications={() => {}}
location={{ search: '', pathname: '/organizations/:id/?tab=notifications' }} onReadSuccess={() => {}}
onReadError={jest.fn()} onCreateError={() => {}}
onReadNotifications={jest.fn()} onCreateSuccess={() => {}}
onReadSuccess={jest.fn()} />
onCreateError={jest.fn()}
onCreateSuccess={jest.fn()}
handleHttpError={() => {}}
/>
</I18nProvider>
).find('Notifications'); ).find('Notifications');
wrapper.instance().toggleNotification(1, true, 'success'); wrapper.instance().toggleNotification(1, true, 'success');
expect(spy).toHaveBeenCalledWith(1, true); expect(spy).toHaveBeenCalledWith(1, true);
}); });
test('post success makes request and updates state properly', async () => { test('post success makes request and updates state properly', async () => {
const createSuccess = jest.fn(); const onCreateSuccess = jest.fn();
const wrapper = mount( const wrapper = mountWithContexts(
<MemoryRouter> <_Notifications
<I18nProvider> match={{ path: '/organizations/:id/?tab=notifications', url: '/organizations/:id/?tab=notifications', params: { id: 1 } }}
<Notifications location={{ search: '', pathname: '/organizations/:id/?tab=notifications' }}
match={{ path: '/organizations/:id/?tab=notifications', url: '/organizations/:id/?tab=notifications', params: { id: 1 } }} handleHttpError={() => {}}
location={{ search: '', pathname: '/organizations/:id/?tab=notifications' }} onReadError={() => {}}
onReadError={jest.fn()} onReadNotifications={() => {}}
onReadNotifications={jest.fn()} onReadSuccess={() => {}}
onReadSuccess={jest.fn()} onCreateError={() => {}}
onCreateError={jest.fn()} onCreateSuccess={onCreateSuccess}
onCreateSuccess={createSuccess} />
handleHttpError={() => {}}
/>
</I18nProvider>
</MemoryRouter>
).find('Notifications'); ).find('Notifications');
wrapper.setState({ successTemplateIds: [44] }); wrapper.setState({ successTemplateIds: [44] });
await wrapper.instance().createSuccess(44, true); await wrapper.instance().createSuccess(44, true);
expect(createSuccess).toHaveBeenCalledWith(1, { id: 44, disassociate: true }); expect(onCreateSuccess).toHaveBeenCalledWith(1, { id: 44, disassociate: true });
expect(wrapper.state('successTemplateIds')).not.toContain(44); expect(wrapper.state('successTemplateIds')).not.toContain(44);
await wrapper.instance().createSuccess(44, false); await wrapper.instance().createSuccess(44, false);
expect(createSuccess).toHaveBeenCalledWith(1, { id: 44 }); expect(onCreateSuccess).toHaveBeenCalledWith(1, { id: 44 });
expect(wrapper.state('successTemplateIds')).toContain(44); expect(wrapper.state('successTemplateIds')).toContain(44);
}); });
test('toggle error calls post', () => { test('toggle error calls post', () => {
const spy = jest.spyOn(_Notifications.prototype, 'createError'); const spy = jest.spyOn(_Notifications.prototype, 'createError');
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <Notifications
<_Notifications onReadError={() => {}}
match={{ path: '/organizations/:id/?tab=notifications', url: '/organizations/:id/?tab=notifications' }} onReadNotifications={() => {}}
location={{ search: '', pathname: '/organizations/:id/?tab=notifications' }} onReadSuccess={() => {}}
onReadError={jest.fn()} onCreateError={() => {}}
onReadNotifications={jest.fn()} onCreateSuccess={() => {}}
onReadSuccess={jest.fn()} />
onCreateError={jest.fn()}
onCreateSuccess={jest.fn()}
handleHttpError={() => {}}
/>
</I18nProvider>
).find('Notifications'); ).find('Notifications');
wrapper.instance().toggleNotification(1, true, 'error'); wrapper.instance().toggleNotification(1, true, 'error');
expect(spy).toHaveBeenCalledWith(1, true); expect(spy).toHaveBeenCalledWith(1, true);
}); });
test('post error makes request and updates state properly', async () => { test('post error makes request and updates state properly', async () => {
const createError = jest.fn(); const onCreateError = jest.fn();
const wrapper = mount( const wrapper = mountWithContexts(
<MemoryRouter> <_Notifications
<I18nProvider> match={{ path: '/organizations/:id/?tab=notifications', url: '/organizations/:id/?tab=notifications', params: { id: 1 } }}
<Notifications location={{ search: '', pathname: '/organizations/:id/?tab=notifications' }}
match={{ path: '/organizations/:id/?tab=notifications', url: '/organizations/:id/?tab=notifications', params: { id: 1 } }} handleHttpError={() => {}}
location={{ search: '', pathname: '/organizations/:id/?tab=notifications' }} onReadError={() => {}}
onReadError={jest.fn()} onReadNotifications={() => {}}
onReadNotifications={jest.fn()} onReadSuccess={() => {}}
onReadSuccess={jest.fn()} onCreateError={onCreateError}
onCreateError={createError} onCreateSuccess={() => {}}
onCreateSuccess={jest.fn()} />
handleHttpError={() => {}}
/>
</I18nProvider>
</MemoryRouter>
).find('Notifications'); ).find('Notifications');
wrapper.setState({ errorTemplateIds: [44] }); wrapper.setState({ errorTemplateIds: [44] });
await wrapper.instance().createError(44, true); await wrapper.instance().createError(44, true);
expect(createError).toHaveBeenCalledWith(1, { id: 44, disassociate: true }); expect(onCreateError).toHaveBeenCalledWith(1, { id: 44, disassociate: true });
expect(wrapper.state('errorTemplateIds')).not.toContain(44); expect(wrapper.state('errorTemplateIds')).not.toContain(44);
await wrapper.instance().createError(44, false); await wrapper.instance().createError(44, false);
expect(createError).toHaveBeenCalledWith(1, { id: 44 }); expect(onCreateError).toHaveBeenCalledWith(1, { id: 44 });
expect(wrapper.state('errorTemplateIds')).toContain(44); expect(wrapper.state('errorTemplateIds')).toContain(44);
}); });
@@ -159,28 +127,24 @@ describe('<Notifications />', () => {
] ]
} }
}); });
const readError = jest.fn().mockResolvedValue({ const onReadError = jest.fn().mockResolvedValue({
data: { data: {
results: [ results: [
{ id: 2 } { id: 2 }
] ]
} }
}); });
const wrapper = mount( const wrapper = mountWithContexts(
<MemoryRouter> <_Notifications
<I18nProvider> match={{ path: '/organizations/:id/?tab=notifications', url: '/organizations/:id/?tab=notifications', params: { id: 1 } }}
<Notifications location={{ search: '', pathname: '/organizations/:id/?tab=notifications' }}
match={{ path: '/organizations/:id/?tab=notifications', url: '/organizations/:id/?tab=notifications', params: { id: 1 } }} handleHttpError={() => {}}
location={{ search: '', pathname: '/organizations/:id/?tab=notifications' }} onReadError={onReadError}
onReadNotifications={onReadNotifications} onReadNotifications={onReadNotifications}
onReadSuccess={onReadSuccess} onReadSuccess={onReadSuccess}
onReadError={readError} onCreateError={() => {}}
onCreateError={jest.fn()} onCreateSuccess={() => {}}
onCreateSuccess={jest.fn()} />
handleHttpError={() => {}}
/>
</I18nProvider>
</MemoryRouter>
).find('Notifications'); ).find('Notifications');
wrapper.instance().updateUrl = jest.fn(); wrapper.instance().updateUrl = jest.fn();
await wrapper.instance().readNotifications(mockQueryParams); await wrapper.instance().readNotifications(mockQueryParams);
@@ -188,7 +152,7 @@ describe('<Notifications />', () => {
expect(onReadSuccess).toHaveBeenCalledWith(1, { expect(onReadSuccess).toHaveBeenCalledWith(1, {
id__in: '1,2,3' id__in: '1,2,3'
}); });
expect(readError).toHaveBeenCalledWith(1, { expect(onReadError).toHaveBeenCalledWith(1, {
id__in: '1,2,3' id__in: '1,2,3'
}); });
expect(wrapper.state('successTemplateIds')).toContain(1); expect(wrapper.state('successTemplateIds')).toContain(1);

View File

@@ -1,7 +1,5 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mountWithContexts } from '../enzymeHelpers';
import { MemoryRouter } from 'react-router-dom';
import { I18nProvider } from '@lingui/react';
import NotificationListItem from '../../src/components/NotificationsList/NotificationListItem'; import NotificationListItem from '../../src/components/NotificationsList/NotificationListItem';
describe('<NotificationListItem />', () => { describe('<NotificationListItem />', () => {
@@ -16,88 +14,68 @@ describe('<NotificationListItem />', () => {
}); });
test('initially renders succesfully', () => { test('initially renders succesfully', () => {
wrapper = mount( wrapper = mountWithContexts(
<I18nProvider> <NotificationListItem
<MemoryRouter> itemId={9000}
<NotificationListItem toggleNotification={toggleNotification}
itemId={9000} detailUrl="/foo"
toggleNotification={toggleNotification} notificationType="slack"
detailUrl="/foo" />
notificationType="slack"
/>
</MemoryRouter>
</I18nProvider>
); );
expect(wrapper.length).toBe(1); expect(wrapper.length).toBe(1);
}); });
test('handles success click when toggle is on', () => { test('handles success click when toggle is on', () => {
wrapper = mount( wrapper = mountWithContexts(
<I18nProvider> <NotificationListItem
<MemoryRouter> itemId={9000}
<NotificationListItem successTurnedOn
itemId={9000} toggleNotification={toggleNotification}
successTurnedOn detailUrl="/foo"
toggleNotification={toggleNotification} notificationType="slack"
detailUrl="/foo" />
notificationType="slack"
/>
</MemoryRouter>
</I18nProvider>
); );
wrapper.find('Switch').first().find('input').simulate('change'); wrapper.find('Switch').first().find('input').simulate('change');
expect(toggleNotification).toHaveBeenCalledWith(9000, true, 'success'); expect(toggleNotification).toHaveBeenCalledWith(9000, true, 'success');
}); });
test('handles success click when toggle is off', () => { test('handles success click when toggle is off', () => {
wrapper = mount( wrapper = mountWithContexts(
<I18nProvider> <NotificationListItem
<MemoryRouter> itemId={9000}
<NotificationListItem successTurnedOn={false}
itemId={9000} toggleNotification={toggleNotification}
successTurnedOn={false} detailUrl="/foo"
toggleNotification={toggleNotification} notificationType="slack"
detailUrl="/foo" />
notificationType="slack"
/>
</MemoryRouter>
</I18nProvider>
); );
wrapper.find('Switch').first().find('input').simulate('change'); wrapper.find('Switch').first().find('input').simulate('change');
expect(toggleNotification).toHaveBeenCalledWith(9000, false, 'success'); expect(toggleNotification).toHaveBeenCalledWith(9000, false, 'success');
}); });
test('handles error click when toggle is on', () => { test('handles error click when toggle is on', () => {
wrapper = mount( wrapper = mountWithContexts(
<I18nProvider> <NotificationListItem
<MemoryRouter> itemId={9000}
<NotificationListItem errorTurnedOn
itemId={9000} toggleNotification={toggleNotification}
errorTurnedOn detailUrl="/foo"
toggleNotification={toggleNotification} notificationType="slack"
detailUrl="/foo" />
notificationType="slack"
/>
</MemoryRouter>
</I18nProvider>
); );
wrapper.find('Switch').at(1).find('input').simulate('change'); wrapper.find('Switch').at(1).find('input').simulate('change');
expect(toggleNotification).toHaveBeenCalledWith(9000, true, 'error'); expect(toggleNotification).toHaveBeenCalledWith(9000, true, 'error');
}); });
test('handles error click when toggle is off', () => { test('handles error click when toggle is off', () => {
wrapper = mount( wrapper = mountWithContexts(
<I18nProvider> <NotificationListItem
<MemoryRouter> itemId={9000}
<NotificationListItem errorTurnedOn={false}
itemId={9000} toggleNotification={toggleNotification}
errorTurnedOn={false} detailUrl="/foo"
toggleNotification={toggleNotification} notificationType="slack"
detailUrl="/foo" />
notificationType="slack"
/>
</MemoryRouter>
</I18nProvider>
); );
wrapper.find('Switch').at(1).find('input').simulate('change'); wrapper.find('Switch').at(1).find('input').simulate('change');
expect(toggleNotification).toHaveBeenCalledWith(9000, false, 'error'); expect(toggleNotification).toHaveBeenCalledWith(9000, false, 'error');

View File

@@ -1,24 +1,17 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mountWithContexts } from '../enzymeHelpers';
import { MemoryRouter } from 'react-router-dom';
import { I18nProvider } from '@lingui/react';
import { _NotifyAndRedirect } from '../../src/components/NotifyAndRedirect'; import { _NotifyAndRedirect } from '../../src/components/NotifyAndRedirect';
describe('<NotifyAndRedirect />', () => { describe('<NotifyAndRedirect />', () => {
test('initially renders succesfully and calls setRootDialogMessage', () => { test('initially renders succesfully and calls setRootDialogMessage', () => {
const setRootDialogMessage = jest.fn(); const setRootDialogMessage = jest.fn();
mount( mountWithContexts(
<MemoryRouter> <_NotifyAndRedirect
<I18nProvider> to="foo"
<_NotifyAndRedirect setRootDialogMessage={setRootDialogMessage}
to="foo" location={{ pathname: 'foo' }}
setRootDialogMessage={setRootDialogMessage} />
location={{ pathname: 'foo' }}
/>
</I18nProvider>
</MemoryRouter>
); );
expect(setRootDialogMessage).toHaveBeenCalled(); expect(setRootDialogMessage).toHaveBeenCalled();
}); });

View File

@@ -1,8 +1,5 @@
import React from 'react'; import React from 'react';
import { MemoryRouter } from 'react-router-dom'; import { mountWithContexts } from '../enzymeHelpers';
import { mount } from 'enzyme';
import { I18nProvider } from '@lingui/react';
import PageHeaderToolbar from '../../src/components/PageHeaderToolbar'; import PageHeaderToolbar from '../../src/components/PageHeaderToolbar';
describe('PageHeaderToolbar', () => { describe('PageHeaderToolbar', () => {
@@ -12,13 +9,11 @@ describe('PageHeaderToolbar', () => {
const onLogoutClick = jest.fn(); const onLogoutClick = jest.fn();
test('expected content is rendered on initialization', () => { test('expected content is rendered on initialization', () => {
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <PageHeaderToolbar
<PageHeaderToolbar onAboutClick={onAboutClick}
onAboutClick={onAboutClick} onLogoutClick={onLogoutClick}
onLogoutClick={onLogoutClick} />
/>
</I18nProvider>
); );
expect(wrapper.find(pageHelpDropdownSelector)).toHaveLength(1); expect(wrapper.find(pageHelpDropdownSelector)).toHaveLength(1);
@@ -26,15 +21,11 @@ describe('PageHeaderToolbar', () => {
}); });
test('dropdowns have expected items and callbacks', () => { test('dropdowns have expected items and callbacks', () => {
const wrapper = mount( const wrapper = mountWithContexts(
<MemoryRouter> <PageHeaderToolbar
<I18nProvider> onAboutClick={onAboutClick}
<PageHeaderToolbar onLogoutClick={onLogoutClick}
onAboutClick={onAboutClick} />
onLogoutClick={onLogoutClick}
/>
</I18nProvider>
</MemoryRouter>
); );
expect(wrapper.find('DropdownItem')).toHaveLength(0); expect(wrapper.find('DropdownItem')).toHaveLength(0);
wrapper.find(pageHelpDropdownSelector).simulate('click'); wrapper.find(pageHelpDropdownSelector).simulate('click');

View File

@@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mountWithContexts } from '../enzymeHelpers';
import { I18nProvider } from '@lingui/react';
import Search from '../../src/components/Search'; import Search from '../../src/components/Search';
describe('<Search />', () => { describe('<Search />', () => {
@@ -8,7 +7,6 @@ describe('<Search />', () => {
afterEach(() => { afterEach(() => {
if (search) { if (search) {
search.unmount();
search = null; search = null;
} }
}); });
@@ -21,14 +19,12 @@ describe('<Search />', () => {
const onSearch = jest.fn(); const onSearch = jest.fn();
search = mount( search = mountWithContexts(
<I18nProvider> <Search
<Search sortedColumnKey="name"
sortedColumnKey="name" columns={columns}
columns={columns} onSearch={onSearch}
onSearch={onSearch} />
/>
</I18nProvider>
); );
search.find(searchTextInput).instance().value = 'test-321'; search.find(searchTextInput).instance().value = 'test-321';
@@ -42,14 +38,12 @@ describe('<Search />', () => {
test('handleDropdownToggle properly updates state', async () => { test('handleDropdownToggle properly updates state', async () => {
const columns = [{ name: 'Name', key: 'name', isSortable: true }]; const columns = [{ name: 'Name', key: 'name', isSortable: true }];
const onSearch = jest.fn(); const onSearch = jest.fn();
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <Search
<Search sortedColumnKey="name"
sortedColumnKey="name" columns={columns}
columns={columns} onSearch={onSearch}
onSearch={onSearch} />
/>
</I18nProvider>
).find('Search'); ).find('Search');
expect(wrapper.state('isSearchDropdownOpen')).toEqual(false); expect(wrapper.state('isSearchDropdownOpen')).toEqual(false);
wrapper.instance().handleDropdownToggle(true); wrapper.instance().handleDropdownToggle(true);
@@ -62,14 +56,12 @@ describe('<Search />', () => {
{ name: 'Description', key: 'description', isSortable: true } { name: 'Description', key: 'description', isSortable: true }
]; ];
const onSearch = jest.fn(); const onSearch = jest.fn();
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <Search
<Search sortedColumnKey="name"
sortedColumnKey="name" columns={columns}
columns={columns} onSearch={onSearch}
onSearch={onSearch} />
/>
</I18nProvider>
).find('Search'); ).find('Search');
expect(wrapper.state('searchKey')).toEqual('name'); expect(wrapper.state('searchKey')).toEqual('name');
wrapper.instance().handleDropdownSelect({ target: { innerText: 'Description' } }); wrapper.instance().handleDropdownSelect({ target: { innerText: 'Description' } });

View File

@@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mountWithContexts } from '../enzymeHelpers';
import { I18nProvider } from '@lingui/react';
import Sort from '../../src/components/Sort'; import Sort from '../../src/components/Sort';
describe('<Sort />', () => { describe('<Sort />', () => {
@@ -8,7 +7,6 @@ describe('<Sort />', () => {
afterEach(() => { afterEach(() => {
if (sort) { if (sort) {
sort.unmount();
sort = null; sort = null;
} }
}); });
@@ -20,15 +18,13 @@ describe('<Sort />', () => {
const onSort = jest.fn(); const onSort = jest.fn();
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <Sort
<Sort sortedColumnKey="name"
sortedColumnKey="name" sortOrder="ascending"
sortOrder="ascending" columns={columns}
columns={columns} onSort={onSort}
onSort={onSort} />
/>
</I18nProvider>
).find('Sort'); ).find('Sort');
wrapper.find(sortBtn).simulate('click'); wrapper.find(sortBtn).simulate('click');
@@ -47,15 +43,13 @@ describe('<Sort />', () => {
const onSort = jest.fn(); const onSort = jest.fn();
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <Sort
<Sort sortedColumnKey="foo"
sortedColumnKey="foo" sortOrder="ascending"
sortOrder="ascending" columns={multipleColumns}
columns={multipleColumns} onSort={onSort}
onSort={onSort} />
/>
</I18nProvider>
).find('Sort'); ).find('Sort');
const sortDropdownToggle = wrapper.find('Button'); const sortDropdownToggle = wrapper.find('Button');
expect(sortDropdownToggle.length).toBe(1); expect(sortDropdownToggle.length).toBe(1);
@@ -73,15 +67,13 @@ describe('<Sort />', () => {
const onSort = jest.fn(); const onSort = jest.fn();
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <Sort
<Sort sortedColumnKey="foo"
sortedColumnKey="foo" sortOrder="descending"
sortOrder="descending" columns={multipleColumns}
columns={multipleColumns} onSort={onSort}
onSort={onSort} />
/>
</I18nProvider>
).find('Sort'); ).find('Sort');
const sortDropdownToggle = wrapper.find('Button'); const sortDropdownToggle = wrapper.find('Button');
expect(sortDropdownToggle.length).toBe(1); expect(sortDropdownToggle.length).toBe(1);
@@ -99,15 +91,13 @@ describe('<Sort />', () => {
const onSort = jest.fn(); const onSort = jest.fn();
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <Sort
<Sort sortedColumnKey="foo"
sortedColumnKey="foo" sortOrder="ascending"
sortOrder="ascending" columns={multipleColumns}
columns={multipleColumns} onSort={onSort}
onSort={onSort} />
/>
</I18nProvider>
).find('Sort'); ).find('Sort');
wrapper.instance().handleDropdownSelect({ target: { innerText: 'Bar' } }); wrapper.instance().handleDropdownSelect({ target: { innerText: 'Bar' } });
@@ -124,15 +114,13 @@ describe('<Sort />', () => {
const onSort = jest.fn(); const onSort = jest.fn();
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <Sort
<Sort sortedColumnKey="foo"
sortedColumnKey="foo" sortOrder="ascending"
sortOrder="ascending" columns={multipleColumns}
columns={multipleColumns} onSort={onSort}
onSort={onSort} />
/>
</I18nProvider>
).find('Sort'); ).find('Sort');
expect(wrapper.state('isSortDropdownOpen')).toEqual(false); expect(wrapper.state('isSortDropdownOpen')).toEqual(false);
wrapper.instance().handleDropdownToggle(true); wrapper.instance().handleDropdownToggle(true);
@@ -149,57 +137,49 @@ describe('<Sort />', () => {
const alphaColumns = [{ name: 'Name', key: 'name', isSortable: true, isNumeric: false }]; const alphaColumns = [{ name: 'Name', key: 'name', isSortable: true, isNumeric: false }];
const onSort = jest.fn(); const onSort = jest.fn();
sort = mount( sort = mountWithContexts(
<I18nProvider> <Sort
<Sort sortedColumnKey="id"
sortedColumnKey="id" sortOrder="descending"
sortOrder="descending" columns={numericColumns}
columns={numericColumns} onSort={onSort}
onSort={onSort} />
/>
</I18nProvider>
); );
const downNumericIcon = sort.find(downNumericIconSelector); const downNumericIcon = sort.find(downNumericIconSelector);
expect(downNumericIcon.length).toBe(1); expect(downNumericIcon.length).toBe(1);
sort = mount( sort = mountWithContexts(
<I18nProvider> <Sort
<Sort sortedColumnKey="id"
sortedColumnKey="id" sortOrder="ascending"
sortOrder="ascending" columns={numericColumns}
columns={numericColumns} onSort={onSort}
onSort={onSort} />
/>
</I18nProvider>
); );
const upNumericIcon = sort.find(upNumericIconSelector); const upNumericIcon = sort.find(upNumericIconSelector);
expect(upNumericIcon.length).toBe(1); expect(upNumericIcon.length).toBe(1);
sort = mount( sort = mountWithContexts(
<I18nProvider> <Sort
<Sort sortedColumnKey="name"
sortedColumnKey="name" sortOrder="descending"
sortOrder="descending" columns={alphaColumns}
columns={alphaColumns} onSort={onSort}
onSort={onSort} />
/>
</I18nProvider>
); );
const downAlphaIcon = sort.find(downAlphaIconSelector); const downAlphaIcon = sort.find(downAlphaIconSelector);
expect(downAlphaIcon.length).toBe(1); expect(downAlphaIcon.length).toBe(1);
sort = mount( sort = mountWithContexts(
<I18nProvider> <Sort
<Sort sortedColumnKey="name"
sortedColumnKey="name" sortOrder="ascending"
sortOrder="ascending" columns={alphaColumns}
columns={alphaColumns} onSort={onSort}
onSort={onSort} />
/>
</I18nProvider>
); );
const upAlphaIcon = sort.find(upAlphaIconSelector); const upAlphaIcon = sort.find(upAlphaIconSelector);

View File

@@ -1,7 +1,6 @@
import React from 'react'; import React from 'react';
import { MemoryRouter } from 'react-router-dom'; import { createMemoryHistory } from 'history';
import { mount } from 'enzyme'; import { mountWithContexts } from '../enzymeHelpers';
import { I18nProvider } from '@lingui/react';
import TowerLogo from '../../src/components/TowerLogo'; import TowerLogo from '../../src/components/TowerLogo';
let logoWrapper; let logoWrapper;
@@ -15,12 +14,8 @@ const findChildren = () => {
describe('<TowerLogo />', () => { describe('<TowerLogo />', () => {
test('initially renders without crashing', () => { test('initially renders without crashing', () => {
logoWrapper = mount( logoWrapper = mountWithContexts(
<MemoryRouter> <TowerLogo />
<I18nProvider>
<TowerLogo />
</I18nProvider>
</MemoryRouter>
); );
findChildren(); findChildren();
expect(logoWrapper.length).toBe(1); expect(logoWrapper.length).toBe(1);
@@ -29,12 +24,12 @@ describe('<TowerLogo />', () => {
}); });
test('adds navigation to route history on click', () => { test('adds navigation to route history on click', () => {
logoWrapper = mount( const history = createMemoryHistory({
<MemoryRouter> initialEntries: ['/organizations/1/teams'],
<I18nProvider> });
<TowerLogo linkTo="/" />
</I18nProvider> logoWrapper = mountWithContexts(
</MemoryRouter> <TowerLogo linkTo="/" />, { context: { router: { history } } }
); );
findChildren(); findChildren();
expect(towerLogoElem.props().history.length).toBe(1); expect(towerLogoElem.props().history.length).toBe(1);
@@ -42,27 +37,9 @@ describe('<TowerLogo />', () => {
expect(towerLogoElem.props().history.length).toBe(2); expect(towerLogoElem.props().history.length).toBe(2);
}); });
test('linkTo prop is optional', () => {
logoWrapper = mount(
<MemoryRouter>
<I18nProvider>
<TowerLogo />
</I18nProvider>
</MemoryRouter>
);
findChildren();
expect(towerLogoElem.props().history.length).toBe(1);
logoWrapper.simulate('click');
expect(towerLogoElem.props().history.length).toBe(1);
});
test('handles mouse over and out state.hover changes', () => { test('handles mouse over and out state.hover changes', () => {
logoWrapper = mount( logoWrapper = mountWithContexts(
<MemoryRouter> <TowerLogo />
<I18nProvider>
<TowerLogo />
</I18nProvider>
</MemoryRouter>
); );
findChildren(); findChildren();
findChildren(); findChildren();

View File

@@ -45,6 +45,12 @@ const defaultContexts = {
push: () => {}, push: () => {},
replace: () => {}, replace: () => {},
createHref: () => {}, createHref: () => {},
location: {
hash: '',
pathname: '',
search: '',
state: '',
}
}, },
route: { route: {
location: { location: {
@@ -58,7 +64,7 @@ const defaultContexts = {
isExact: false, isExact: false,
path: '', path: '',
url: '', url: '',
}, }
}, },
toJSON: () => '/router/', toJSON: () => '/router/',
}, },

View File

@@ -1,8 +1,6 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme';
import { MemoryRouter } from 'react-router-dom';
import { I18nProvider } from '@lingui/react';
import { mountWithContexts } from '../../../enzymeHelpers';
import OrganizationAccessList, { _OrganizationAccessList } from '../../../../src/pages/Organizations/components/OrganizationAccessList'; import OrganizationAccessList, { _OrganizationAccessList } from '../../../../src/pages/Organizations/components/OrganizationAccessList';
const mockData = [ const mockData = [
@@ -31,32 +29,20 @@ describe('<OrganizationAccessList />', () => {
}); });
test('initially renders succesfully', () => { test('initially renders succesfully', () => {
mount( mountWithContexts(
<I18nProvider> <OrganizationAccessList
<MemoryRouter> getAccessList={() => {}}
<OrganizationAccessList removeRole={() => {}}
match={{ path: '/organizations/:id', url: '/organizations/1', params: { id: '1' } }} />
location={{ search: '', pathname: '/organizations/1/access' }}
getAccessList={() => {}}
removeRole={() => {}}
/>
</MemoryRouter>
</I18nProvider>
); );
}); });
test('api response data passed to component gets set to state properly', (done) => { test('api response data passed to component gets set to state properly', (done) => {
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <OrganizationAccessList
<MemoryRouter> getAccessList={() => ({ data: { count: 1, results: mockData } })}
<OrganizationAccessList removeRole={() => {}}
match={{ path: '/organizations/:id', url: '/organizations/1', params: { id: '0' } }} />
location={{ search: '', pathname: '/organizations/1/access' }}
getAccessList={() => ({ data: { count: 1, results: mockData } })}
removeRole={() => {}}
/>
</MemoryRouter>
</I18nProvider>
).find('OrganizationAccessList'); ).find('OrganizationAccessList');
setImmediate(() => { setImmediate(() => {
@@ -67,18 +53,11 @@ describe('<OrganizationAccessList />', () => {
test('onSort being passed properly to DataListToolbar component', async (done) => { test('onSort being passed properly to DataListToolbar component', async (done) => {
const onSort = jest.spyOn(_OrganizationAccessList.prototype, 'onSort'); const onSort = jest.spyOn(_OrganizationAccessList.prototype, 'onSort');
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <OrganizationAccessList
<MemoryRouter> getAccessList={() => ({ data: { count: 1, results: mockData } })}
<_OrganizationAccessList removeRole={() => {}}
match={{ path: '/organizations/:id', url: '/organizations/1', params: { id: '0' } }} />
location={{ search: '', pathname: '/organizations/1/access' }}
getAccessList={() => ({ data: { count: 1, results: mockData } })}
removeRole={() => {}}
handleHttpError={() => {}}
/>
</MemoryRouter>
</I18nProvider>
).find('OrganizationAccessList'); ).find('OrganizationAccessList');
expect(onSort).not.toHaveBeenCalled(); expect(onSort).not.toHaveBeenCalled();
@@ -91,17 +70,11 @@ describe('<OrganizationAccessList />', () => {
}); });
test('getTeamRoles returns empty array if dataset is missing team_id attribute', (done) => { test('getTeamRoles returns empty array if dataset is missing team_id attribute', (done) => {
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <OrganizationAccessList
<MemoryRouter> getAccessList={() => ({ data: { count: 1, results: mockData } })}
<OrganizationAccessList removeRole={() => {}}
match={{ path: '/organizations/:id', url: '/organizations/1', params: { id: '0' } }} />
location={{ search: '', pathname: '/organizations/1/access' }}
getAccessList={() => ({ data: { count: 1, results: mockData } })}
removeRole={() => {}}
/>
</MemoryRouter>
</I18nProvider>
).find('OrganizationAccessList'); ).find('OrganizationAccessList');
setImmediate(() => { setImmediate(() => {
@@ -117,18 +90,11 @@ describe('<OrganizationAccessList />', () => {
const handleWarning = jest.spyOn(_OrganizationAccessList.prototype, 'handleWarning'); const handleWarning = jest.spyOn(_OrganizationAccessList.prototype, 'handleWarning');
const confirmDelete = jest.spyOn(_OrganizationAccessList.prototype, 'confirmDelete'); const confirmDelete = jest.spyOn(_OrganizationAccessList.prototype, 'confirmDelete');
const removeRole = jest.spyOn(_OrganizationAccessList.prototype, 'removeAccessRole'); const removeRole = jest.spyOn(_OrganizationAccessList.prototype, 'removeAccessRole');
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <OrganizationAccessList
<MemoryRouter> getAccessList={() => ({ data: { count: 1, results: mockData } })}
<_OrganizationAccessList removeRole={() => {}}
match={{ path: '/organizations/:id', url: '/organizations/1', params: { id: '0' } }} />
location={{ search: '', pathname: '/organizations/1/access' }}
getAccessList={() => ({ data: { count: 1, results: mockData } })}
removeRole={() => {}}
handleHttpError={() => {}}
/>
</MemoryRouter>
</I18nProvider>
).find('OrganizationAccessList'); ).find('OrganizationAccessList');
expect(handleWarning).not.toHaveBeenCalled(); expect(handleWarning).not.toHaveBeenCalled();
expect(confirmDelete).not.toHaveBeenCalled(); expect(confirmDelete).not.toHaveBeenCalled();
@@ -147,17 +113,11 @@ describe('<OrganizationAccessList />', () => {
}); });
test('state is set appropriately when a user tries deleting a role', (done) => { test('state is set appropriately when a user tries deleting a role', (done) => {
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <OrganizationAccessList
<MemoryRouter> getAccessList={() => ({ data: { count: 1, results: mockData } })}
<_OrganizationAccessList removeRole={() => {}}
match={{ path: '/organizations/:id', url: '/organizations/1', params: { id: '0' } }} />
location={{ search: '', pathname: '/organizations/1/access' }}
getAccessList={() => ({ data: { count: 1, results: mockData } })}
removeRole={() => {}}
/>
</MemoryRouter>
</I18nProvider>
).find('OrganizationAccessList'); ).find('OrganizationAccessList');
setImmediate(() => { setImmediate(() => {

View File

@@ -1,12 +1,12 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme';
import { MemoryRouter } from 'react-router-dom'; import { MemoryRouter } from 'react-router-dom';
import { I18nProvider } from '@lingui/react'; import { I18nProvider } from '@lingui/react';
import { mountWithContexts } from '../../../enzymeHelpers';
import OrganizationListItem from '../../../../src/pages/Organizations/components/OrganizationListItem'; import OrganizationListItem from '../../../../src/pages/Organizations/components/OrganizationListItem';
describe('<OrganizationListItem />', () => { describe('<OrganizationListItem />', () => {
test('initially renders succesfully', () => { test('initially renders succesfully', () => {
mount( mountWithContexts(
<I18nProvider> <I18nProvider>
<MemoryRouter initialEntries={['/organizations']} initialIndex={0}> <MemoryRouter initialEntries={['/organizations']} initialIndex={0}>
<OrganizationListItem /> <OrganizationListItem />

View File

@@ -1,8 +1,6 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme';
import { MemoryRouter, Router } from 'react-router-dom';
import { createMemoryHistory } from 'history'; import { createMemoryHistory } from 'history';
import { I18nProvider } from '@lingui/react'; import { mountWithContexts } from '../../../enzymeHelpers';
import { sleep } from '../../../testUtils'; import { sleep } from '../../../testUtils';
import OrganizationTeamsList from '../../../../src/pages/Organizations/components/OrganizationTeamsList'; import OrganizationTeamsList from '../../../../src/pages/Organizations/components/OrganizationTeamsList';
@@ -20,20 +18,16 @@ describe('<OrganizationTeamsList />', () => {
}); });
test('initially renders succesfully', () => { test('initially renders succesfully', () => {
mount( mountWithContexts(
<I18nProvider> <OrganizationTeamsList
<MemoryRouter> teams={mockData}
<OrganizationTeamsList itemCount={7}
teams={mockData} queryParams={{
itemCount={7} page: 1,
queryParams={{ page_size: 5,
page: 1, order_by: 'name',
page_size: 5, }}
order_by: 'name', />
}}
/>
</MemoryRouter>
</I18nProvider>
); );
}); });
@@ -42,20 +36,16 @@ describe('<OrganizationTeamsList />', () => {
const history = createMemoryHistory({ const history = createMemoryHistory({
initialEntries: ['/organizations/1/teams'], initialEntries: ['/organizations/1/teams'],
}); });
const wrapper = mount( const wrapper = mountWithContexts(
<Router history={history}> <OrganizationTeamsList
<I18nProvider> teams={mockData}
<OrganizationTeamsList itemCount={7}
teams={mockData} queryParams={{
itemCount={7} page: 1,
queryParams={{ page_size: 5,
page: 1, order_by: 'name',
page_size: 5, }}
order_by: 'name', />, { context: { router: { history } } }
}}
/>
</I18nProvider>
</Router>
); );
const toolbar = wrapper.find('DataListToolbar'); const toolbar = wrapper.find('DataListToolbar');
@@ -78,20 +68,16 @@ describe('<OrganizationTeamsList />', () => {
const history = createMemoryHistory({ const history = createMemoryHistory({
initialEntries: ['/organizations/1/teams'], initialEntries: ['/organizations/1/teams'],
}); });
const wrapper = mount( const wrapper = mountWithContexts(
<Router history={history}> <OrganizationTeamsList
<I18nProvider> teams={mockData}
<OrganizationTeamsList itemCount={7}
teams={mockData} queryParams={{
itemCount={7} page: 1,
queryParams={{ page_size: 5,
page: 1, order_by: 'name',
page_size: 5, }}
order_by: 'name', />, { context: { router: { history } } }
}}
/>
</I18nProvider>
</Router>
); );
const pagination = wrapper.find('Pagination'); const pagination = wrapper.find('Pagination');

View File

@@ -1,21 +1,9 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mountWithContexts } from '../../../../enzymeHelpers';
import { MemoryRouter } from 'react-router-dom';
import { I18nProvider } from '@lingui/react';
import Organization from '../../../../../src/pages/Organizations/screens/Organization/Organization'; import Organization from '../../../../../src/pages/Organizations/screens/Organization/Organization';
describe('<OrganizationView />', () => { describe('<OrganizationView />', () => {
test('initially renders succesfully', () => { test('initially renders succesfully', () => {
mount( mountWithContexts(<Organization />);
<I18nProvider>
<MemoryRouter initialEntries={['/organizations/1']} initialIndex={0}>
<Organization
match={{ path: '/organizations/:id', url: '/organizations/1' }}
location={{ search: '', pathname: '/organizations/1' }}
/>
</MemoryRouter>
</I18nProvider>
);
}); });
}); });

View File

@@ -1,51 +1,26 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mountWithContexts } from '../../../../enzymeHelpers';
import { MemoryRouter } from 'react-router-dom';
import OrganizationAccess from '../../../../../src/pages/Organizations/screens/Organization/OrganizationAccess'; import OrganizationAccess from '../../../../../src/pages/Organizations/screens/Organization/OrganizationAccess';
const mockAPIAccessList = {
foo: 'bar',
};
const mockGetOrganizationAccessList = () => Promise.resolve(mockAPIAccessList);
const mockResponse = {
status: 'success',
};
const mockRemoveRole = () => Promise.resolve(mockResponse);
describe('<OrganizationAccess />', () => { describe('<OrganizationAccess />', () => {
test('initially renders succesfully', () => { test('initially renders succesfully', () => {
mount( mountWithContexts(<OrganizationAccess />);
<MemoryRouter initialEntries={['/organizations/1']} initialIndex={0}>
<OrganizationAccess
match={{ path: '/organizations/:id/access', url: '/organizations/1/access', params: { id: 1 } }}
location={{ search: '', pathname: '/organizations/1/access' }}
params={{}}
api={{
getOrganizationAccessList: jest.fn(),
}}
/>
</MemoryRouter>
);
}); });
test('passed methods as props are called appropriately', async () => { test('passed methods as props are called appropriately', async () => {
const wrapper = mount( const mockAPIAccessList = {
<MemoryRouter initialEntries={['/organizations/1']} initialIndex={0}> foo: 'bar',
<OrganizationAccess };
match={{ path: '/organizations/:id/access', url: '/organizations/1/access', params: { id: 1 } }} const mockResponse = {
location={{ search: '', pathname: '/organizations/1/access' }} status: 'success',
params={{}} };
api={{ const wrapper = mountWithContexts(<OrganizationAccess />, { context: { network: {
getOrganizationAccessList: mockGetOrganizationAccessList, api: {
disassociate: mockRemoveRole getOrganizationAccessList: () => Promise.resolve(mockAPIAccessList),
}} disassociate: () => Promise.resolve(mockResponse)
/> },
</MemoryRouter> handleHttpError: () => {}
).find('OrganizationAccess'); } } }).find('OrganizationAccess');
const accessList = await wrapper.instance().getOrgAccessList(); const accessList = await wrapper.instance().getOrgAccessList();
expect(accessList).toEqual(mockAPIAccessList); expect(accessList).toEqual(mockAPIAccessList);
const resp = await wrapper.instance().removeRole(2, 3, 'users'); const resp = await wrapper.instance().removeRole(2, 3, 'users');

View File

@@ -1,7 +1,5 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mountWithContexts } from '../../../../enzymeHelpers';
import { MemoryRouter } from 'react-router-dom';
import { I18nProvider } from '@lingui/react';
import OrganizationDetail from '../../../../../src/pages/Organizations/screens/Organization/OrganizationDetail'; import OrganizationDetail from '../../../../../src/pages/Organizations/screens/Organization/OrganizationDetail';
describe('<OrganizationDetail />', () => { describe('<OrganizationDetail />', () => {
@@ -14,33 +12,21 @@ describe('<OrganizationDetail />', () => {
}; };
test('initially renders succesfully', () => { test('initially renders succesfully', () => {
mount( mountWithContexts(
<I18nProvider> <OrganizationDetail
<MemoryRouter initialEntries={['/organizations/1']} initialIndex={0}> organization={mockDetails}
<OrganizationDetail />
match={{ params: { id: '1' } }}
organization={mockDetails}
/>
</MemoryRouter>
</I18nProvider>
); );
}); });
test('should request instance groups from api', () => { test('should request instance groups from api', () => {
const getOrganizationInstanceGroups = jest.fn(); const getOrganizationInstanceGroups = jest.fn();
mount( mountWithContexts(
<I18nProvider> <OrganizationDetail
<MemoryRouter initialEntries={['/organizations/1']} initialIndex={0}> organization={mockDetails}
<OrganizationDetail />, { context: {
match={{ params: { id: '1' } }} network: { api: { getOrganizationInstanceGroups }, handleHttpError: () => {} }
api={{ } }
getOrganizationInstanceGroups
}}
handleHttpError={() => {}}
organization={mockDetails}
/>
</MemoryRouter>
</I18nProvider>
).find('OrganizationDetail'); ).find('OrganizationDetail');
expect(getOrganizationInstanceGroups).toHaveBeenCalledTimes(1); expect(getOrganizationInstanceGroups).toHaveBeenCalledTimes(1);
@@ -54,23 +40,12 @@ describe('<OrganizationDetail />', () => {
const getOrganizationInstanceGroups = jest.fn(() => ( const getOrganizationInstanceGroups = jest.fn(() => (
Promise.resolve({ data: { results: mockInstanceGroups } }) Promise.resolve({ data: { results: mockInstanceGroups } })
)); ));
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <OrganizationDetail
<MemoryRouter initialEntries={['/organizations/1']} initialIndex={0}> organization={mockDetails}
<OrganizationDetail />, { context: {
match={{ network: { api: { getOrganizationInstanceGroups }, handleHttpError: () => {} }
path: '/organizations/:id', } }
url: '/organizations/1',
params: { id: '1' }
}}
organization={mockDetails}
handleHttpError={() => {}}
api={{
getOrganizationInstanceGroups
}}
/>
</MemoryRouter>
</I18nProvider>
).find('OrganizationDetail'); ).find('OrganizationDetail');
await getOrganizationInstanceGroups(); await getOrganizationInstanceGroups();
@@ -78,19 +53,10 @@ describe('<OrganizationDetail />', () => {
}); });
test('should render Details', async () => { test('should render Details', async () => {
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <OrganizationDetail
<MemoryRouter initialEntries={['/organizations/1']} initialIndex={0}> organization={mockDetails}
<OrganizationDetail />
match={{
path: '/organizations/:id',
url: '/organizations/1',
params: { id: '1' }
}}
organization={mockDetails}
/>
</MemoryRouter>
</I18nProvider>
); );
const detailWrapper = wrapper.find('Detail'); const detailWrapper = wrapper.find('Detail');

View File

@@ -1,17 +1,12 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mountWithContexts } from '../../../../enzymeHelpers';
import { MemoryRouter } from 'react-router-dom';
import { I18nProvider } from '@lingui/react';
import { NetworkProvider } from '../../../../../src/contexts/Network'; import OrganizationEdit from '../../../../../src/pages/Organizations/screens/Organization/OrganizationEdit';
import { _OrganizationEdit } from '../../../../../src/pages/Organizations/screens/Organization/OrganizationEdit';
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms)); const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
describe('<OrganizationEdit />', () => { describe('<OrganizationEdit />', () => {
let api; let api;
let networkProviderValue;
const mockData = { const mockData = {
name: 'Foo', name: 'Foo',
@@ -30,26 +25,16 @@ describe('<OrganizationEdit />', () => {
associateInstanceGroup: jest.fn(), associateInstanceGroup: jest.fn(),
disassociate: jest.fn(), disassociate: jest.fn(),
}; };
networkProviderValue = {
api,
handleHttpError: () => {}
};
}); });
test('handleSubmit should call api update', () => { test('handleSubmit should call api update', () => {
const wrapper = mount( const wrapper = mountWithContexts(
<MemoryRouter> <OrganizationEdit
<I18nProvider> organization={mockData}
<NetworkProvider value={networkProviderValue}> />, { context: { network: {
<_OrganizationEdit api,
organization={mockData} handleHttpError: () => {}
api={api} } } }
handleHttpError={() => {}}
/>
</NetworkProvider>
</I18nProvider>
</MemoryRouter>
); );
const updatedOrgData = { const updatedOrgData = {
@@ -66,18 +51,13 @@ describe('<OrganizationEdit />', () => {
}); });
test('handleSubmit associates and disassociates instance groups', async () => { test('handleSubmit associates and disassociates instance groups', async () => {
const wrapper = mount( const wrapper = mountWithContexts(
<MemoryRouter> <OrganizationEdit
<I18nProvider> organization={mockData}
<NetworkProvider value={networkProviderValue}> />, { context: { network: {
<_OrganizationEdit api,
organization={mockData} handleHttpError: () => {}
api={api} } } }
handleHttpError={() => {}}
/>
</NetworkProvider>
</I18nProvider>
</MemoryRouter>
); );
const updatedOrgData = { const updatedOrgData = {
@@ -106,19 +86,16 @@ describe('<OrganizationEdit />', () => {
const history = { const history = {
push: jest.fn(), push: jest.fn(),
}; };
const wrapper = mount( const wrapper = mountWithContexts(
<MemoryRouter> <OrganizationEdit
<I18nProvider> organization={mockData}
<NetworkProvider value={networkProviderValue}> />, { context: {
<_OrganizationEdit network: {
organization={mockData} api: { api },
api={api} handleHttpError: () => {}
handleHttpError={() => {}} },
history={history} router: { history }
/> } }
</NetworkProvider>
</I18nProvider>
</MemoryRouter>
); );
expect(history.push).not.toHaveBeenCalled(); expect(history.push).not.toHaveBeenCalled();

View File

@@ -1,60 +1,45 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mountWithContexts } from '../../../../enzymeHelpers';
import { MemoryRouter } from 'react-router-dom';
import { _OrganizationNotifications } from '../../../../../src/pages/Organizations/screens/Organization/OrganizationNotifications'; import OrganizationNotifications from '../../../../../src/pages/Organizations/screens/Organization/OrganizationNotifications';
describe('<OrganizationNotifications />', () => { describe('<OrganizationNotifications />', () => {
let api;
beforeEach(() => {
api = {
getOrganizationNotifications: jest.fn(),
getOrganizationNotificationSuccess: jest.fn(),
getOrganizationNotificationError: jest.fn(),
createOrganizationNotificationSuccess: jest.fn(),
createOrganizationNotificationError: jest.fn()
};
});
test('initially renders succesfully', () => { test('initially renders succesfully', () => {
mount( mountWithContexts(
<MemoryRouter initialEntries={['/organizations/1']} initialIndex={0}> <OrganizationNotifications />, { context: { network: {
<_OrganizationNotifications api,
match={{ path: '/organizations/:id/notifications', url: '/organizations/1/notifications' }} handleHttpError: () => {}
location={{ search: '', pathname: '/organizations/1/notifications' }} } } }
params={{}}
api={{
getOrganizationNotifications: jest.fn(),
getOrganizationNotificationSuccess: jest.fn(),
getOrganizationNotificationError: jest.fn(),
createOrganizationNotificationSuccess: jest.fn(),
createOrganizationNotificationError: jest.fn()
}}
handleHttpError={() => {}}
/>
</MemoryRouter>
); );
}); });
test('handles api requests', () => { test('handles api requests', () => {
const getOrganizationNotifications = jest.fn(); const wrapper = mountWithContexts(
const getOrganizationNotificationSuccess = jest.fn(); <OrganizationNotifications />, { context: { network: {
const getOrganizationNotificationError = jest.fn(); api,
const createOrganizationNotificationSuccess = jest.fn(); handleHttpError: () => {}
const createOrganizationNotificationError = jest.fn(); } } }
const wrapper = mount(
<MemoryRouter initialEntries={['/organizations/1']} initialIndex={0}>
<_OrganizationNotifications
match={{ path: '/organizations/:id/notifications', url: '/organizations/1/notifications' }}
location={{ search: '', pathname: '/organizations/1/notifications' }}
params={{}}
api={{
getOrganizationNotifications,
getOrganizationNotificationSuccess,
getOrganizationNotificationError,
createOrganizationNotificationSuccess,
createOrganizationNotificationError
}}
handleHttpError={() => {}}
/>
</MemoryRouter>
).find('OrganizationNotifications'); ).find('OrganizationNotifications');
wrapper.instance().readOrgNotifications(1, { foo: 'bar' }); wrapper.instance().readOrgNotifications(1, { foo: 'bar' });
expect(getOrganizationNotifications).toHaveBeenCalledWith(1, { foo: 'bar' }); expect(api.getOrganizationNotifications).toHaveBeenCalledWith(1, { foo: 'bar' });
wrapper.instance().readOrgNotificationSuccess(1, { foo: 'bar' }); wrapper.instance().readOrgNotificationSuccess(1, { foo: 'bar' });
expect(getOrganizationNotificationSuccess).toHaveBeenCalledWith(1, { foo: 'bar' }); expect(api.getOrganizationNotificationSuccess).toHaveBeenCalledWith(1, { foo: 'bar' });
wrapper.instance().readOrgNotificationError(1, { foo: 'bar' }); wrapper.instance().readOrgNotificationError(1, { foo: 'bar' });
expect(getOrganizationNotificationError).toHaveBeenCalledWith(1, { foo: 'bar' }); expect(api.getOrganizationNotificationError).toHaveBeenCalledWith(1, { foo: 'bar' });
wrapper.instance().createOrgNotificationSuccess(1, { id: 2 }); wrapper.instance().createOrgNotificationSuccess(1, { id: 2 });
expect(createOrganizationNotificationSuccess).toHaveBeenCalledWith(1, { id: 2 }); expect(api.createOrganizationNotificationSuccess).toHaveBeenCalledWith(1, { id: 2 });
wrapper.instance().createOrgNotificationError(1, { id: 2 }); wrapper.instance().createOrgNotificationError(1, { id: 2 });
expect(createOrganizationNotificationError).toHaveBeenCalledWith(1, { id: 2 }); expect(api.createOrganizationNotificationError).toHaveBeenCalledWith(1, { id: 2 });
}); });
}); });

View File

@@ -1,12 +1,11 @@
import React from 'react'; import React from 'react';
import { mount, shallow } from 'enzyme'; import { shallow } from 'enzyme';
import { MemoryRouter, Router } from 'react-router-dom'; import { Router } from 'react-router-dom';
import { I18nProvider } from '@lingui/react';
import { createMemoryHistory } from 'history'; import { createMemoryHistory } from 'history';
import { mountWithContexts } from '../../../../enzymeHelpers';
import { sleep } from '../../../../testUtils'; import { sleep } from '../../../../testUtils';
import OrganizationTeams, { _OrganizationTeams } from '../../../../../src/pages/Organizations/screens/Organization/OrganizationTeams'; import OrganizationTeams, { _OrganizationTeams } from '../../../../../src/pages/Organizations/screens/Organization/OrganizationTeams';
import OrganizationTeamsList from '../../../../../src/pages/Organizations/components/OrganizationTeamsList'; import OrganizationTeamsList from '../../../../../src/pages/Organizations/components/OrganizationTeamsList';
import { NetworkProvider } from '../../../../../src/contexts/Network';
const listData = { const listData = {
data: { data: {
@@ -38,19 +37,13 @@ describe('<OrganizationTeams />', () => {
test('should load teams on mount', () => { test('should load teams on mount', () => {
const readOrganizationTeamsList = jest.fn(() => Promise.resolve(listData)); const readOrganizationTeamsList = jest.fn(() => Promise.resolve(listData));
mount( mountWithContexts(
<I18nProvider> <OrganizationTeams
<MemoryRouter initialEntries={['/organizations/1']} initialIndex={0}> id={1}
<NetworkProvider searchString=""
value={{ api: { readOrganizationTeamsList }, handleHttpError: () => {} }} />, { context: {
> network: { api: { readOrganizationTeamsList }, handleHttpError: () => {} } }
<OrganizationTeams }
id={1}
searchString=""
/>
</NetworkProvider>
</MemoryRouter>
</I18nProvider>
).find('OrganizationTeams'); ).find('OrganizationTeams');
expect(readOrganizationTeamsList).toHaveBeenCalledWith(1, { expect(readOrganizationTeamsList).toHaveBeenCalledWith(1, {
page: 1, page: 1,
@@ -61,19 +54,13 @@ describe('<OrganizationTeams />', () => {
test('should pass fetched teams to list component', async () => { test('should pass fetched teams to list component', async () => {
const readOrganizationTeamsList = jest.fn(() => Promise.resolve(listData)); const readOrganizationTeamsList = jest.fn(() => Promise.resolve(listData));
const wrapper = mount( const wrapper = mountWithContexts(
<I18nProvider> <OrganizationTeams
<MemoryRouter> id={1}
<NetworkProvider searchString=""
value={{ api: { readOrganizationTeamsList }, handleHttpError: () => {} }} />, { context: {
> network: { api: { readOrganizationTeamsList }, handleHttpError: () => {} } }
<OrganizationTeams }
id={1}
searchString=""
/>
</NetworkProvider>
</MemoryRouter>
</I18nProvider>
); );
await sleep(0); await sleep(0);
@@ -105,19 +92,20 @@ describe('<OrganizationTeams />', () => {
const history = createMemoryHistory({ const history = createMemoryHistory({
initialEntries: ['/organizations/1/teams'], initialEntries: ['/organizations/1/teams'],
}); });
const wrapper = mount( const wrapper = mountWithContexts(
<Router history={history}> <Router history={history}>
<I18nProvider> <OrganizationTeams
<NetworkProvider id={1}
value={{ api: { readOrganizationTeamsList }, handleHttpError: () => {} }} searchString=""
> />
<OrganizationTeams </Router>,
id={1} { context: {
searchString="" network: {
/> api: { readOrganizationTeamsList },
</NetworkProvider> handleHttpError: () => {}
</I18nProvider> },
</Router> router: false,
} }
); );
await sleep(0); await sleep(0);
@@ -132,7 +120,6 @@ describe('<OrganizationTeams />', () => {
readOrganizationTeamsList.mockReturnValueOnce(page2Data); readOrganizationTeamsList.mockReturnValueOnce(page2Data);
history.push('/organizations/1/teams?page=2'); history.push('/organizations/1/teams?page=2');
wrapper.setProps({ history });
await sleep(0); await sleep(0);
wrapper.update(); wrapper.update();

View File

@@ -1,12 +1,8 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme';
import { MemoryRouter } from 'react-router-dom';
import { I18nProvider } from '@lingui/react';
import { ConfigProvider } from '../../../../src/contexts/Config'; import { mountWithContexts } from '../../../enzymeHelpers';
import { NetworkProvider } from '../../../../src/contexts/Network';
import { _OrganizationAdd } from '../../../../src/pages/Organizations/screens/OrganizationAdd'; import OrganizationAdd from '../../../../src/pages/Organizations/screens/OrganizationAdd';
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms)); const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
@@ -29,25 +25,15 @@ describe('<OrganizationAdd />', () => {
}); });
test('handleSubmit should post to api', () => { test('handleSubmit should post to api', () => {
const wrapper = mount( const wrapper = mountWithContexts(<OrganizationAdd />, {
<MemoryRouter> context: { network: networkProviderValue }
<I18nProvider> });
<NetworkProvider value={networkProviderValue}>
<ConfigProvider>
<_OrganizationAdd api={api} />
</ConfigProvider>
</NetworkProvider>
</I18nProvider>
</MemoryRouter>
);
const updatedOrgData = { const updatedOrgData = {
name: 'new name', name: 'new name',
description: 'new description', description: 'new description',
custom_virtualenv: 'Buzz', custom_virtualenv: 'Buzz',
}; };
wrapper.find('OrganizationForm').prop('handleSubmit')(updatedOrgData, [], []); wrapper.find('OrganizationForm').prop('handleSubmit')(updatedOrgData, [], []);
expect(api.createOrganization).toHaveBeenCalledWith(updatedOrgData); expect(api.createOrganization).toHaveBeenCalledWith(updatedOrgData);
}); });
@@ -55,21 +41,11 @@ describe('<OrganizationAdd />', () => {
const history = { const history = {
push: jest.fn(), push: jest.fn(),
}; };
const wrapper = mount( const wrapper = mountWithContexts(<OrganizationAdd />, {
<MemoryRouter> context: { router: { history } }
<I18nProvider> });
<NetworkProvider value={networkProviderValue}>
<ConfigProvider>
<_OrganizationAdd api={api} history={history} />
</ConfigProvider>
</NetworkProvider>
</I18nProvider>
</MemoryRouter>
);
expect(history.push).not.toHaveBeenCalled(); expect(history.push).not.toHaveBeenCalled();
wrapper.find('button[aria-label="Cancel"]').prop('onClick')(); wrapper.find('button[aria-label="Cancel"]').prop('onClick')();
expect(history.push).toHaveBeenCalledWith('/organizations'); expect(history.push).toHaveBeenCalledWith('/organizations');
}); });
@@ -77,21 +53,11 @@ describe('<OrganizationAdd />', () => {
const history = { const history = {
push: jest.fn(), push: jest.fn(),
}; };
const wrapper = mount( const wrapper = mountWithContexts(<OrganizationAdd />, {
<MemoryRouter> context: { router: { history } }
<I18nProvider> });
<NetworkProvider value={networkProviderValue}>
<ConfigProvider>
<_OrganizationAdd api={api} history={history} />
</ConfigProvider>
</NetworkProvider>
</I18nProvider>
</MemoryRouter>
);
expect(history.push).not.toHaveBeenCalled(); expect(history.push).not.toHaveBeenCalled();
wrapper.find('button[aria-label="Close"]').prop('onClick')(); wrapper.find('button[aria-label="Close"]').prop('onClick')();
expect(history.push).toHaveBeenCalledWith('/organizations'); expect(history.push).toHaveBeenCalledWith('/organizations');
}); });
@@ -113,37 +79,18 @@ describe('<OrganizationAdd />', () => {
...orgData, ...orgData,
} }
}); });
const wrapper = mount( const wrapper = mountWithContexts(<OrganizationAdd />, {
<MemoryRouter> context: { router: { history }, network: networkProviderValue }
<I18nProvider> });
<NetworkProvider value={networkProviderValue}>
<ConfigProvider>
<_OrganizationAdd api={api} history={history} />
</ConfigProvider>
</NetworkProvider>
</I18nProvider>
</MemoryRouter>
);
wrapper.find('OrganizationForm').prop('handleSubmit')(orgData, [], []); wrapper.find('OrganizationForm').prop('handleSubmit')(orgData, [], []);
await sleep(0); await sleep(0);
expect(history.push).toHaveBeenCalledWith('/organizations/5'); expect(history.push).toHaveBeenCalledWith('/organizations/5');
}); });
test('handleSubmit should post instance groups', async () => { test('handleSubmit should post instance groups', async () => {
const wrapper = mount( const wrapper = mountWithContexts(<OrganizationAdd />, {
<MemoryRouter> context: { network: networkProviderValue }
<I18nProvider> });
<NetworkProvider value={networkProviderValue}>
<ConfigProvider>
<_OrganizationAdd api={api} />
</ConfigProvider>
</NetworkProvider>
</I18nProvider>
</MemoryRouter>
);
const orgData = { const orgData = {
name: 'new name', name: 'new name',
description: 'new description', description: 'new description',
@@ -160,7 +107,6 @@ describe('<OrganizationAdd />', () => {
}); });
wrapper.find('OrganizationForm').prop('handleSubmit')(orgData, [3], []); wrapper.find('OrganizationForm').prop('handleSubmit')(orgData, [3], []);
await sleep(0); await sleep(0);
expect(api.associateInstanceGroup) expect(api.associateInstanceGroup)
.toHaveBeenCalledWith('/api/v2/organizations/5/instance_groups', 3); .toHaveBeenCalledWith('/api/v2/organizations/5/instance_groups', 3);
}); });
@@ -169,17 +115,9 @@ describe('<OrganizationAdd />', () => {
const config = { const config = {
custom_virtualenvs: ['foo', 'bar'], custom_virtualenvs: ['foo', 'bar'],
}; };
const wrapper = mount( const wrapper = mountWithContexts(<OrganizationAdd />, {
<MemoryRouter> context: { network: networkProviderValue, config }
<I18nProvider> }).find('AnsibleSelect');
<NetworkProvider value={networkProviderValue}>
<ConfigProvider value={config}>
<_OrganizationAdd api={api} />
</ConfigProvider>
</NetworkProvider>
</I18nProvider>
</MemoryRouter>
).find('OrganizationAdd').find('AnsibleSelect');
expect(wrapper.find('FormSelect')).toHaveLength(1); expect(wrapper.find('FormSelect')).toHaveLength(1);
expect(wrapper.find('FormSelectOption')).toHaveLength(2); expect(wrapper.find('FormSelectOption')).toHaveLength(2);
}); });
@@ -188,17 +126,9 @@ describe('<OrganizationAdd />', () => {
const config = { const config = {
custom_virtualenvs: [], custom_virtualenvs: [],
}; };
const wrapper = mount( const wrapper = mountWithContexts(<OrganizationAdd />, {
<MemoryRouter> context: { network: networkProviderValue, config }
<I18nProvider> }).find('AnsibleSelect');
<NetworkProvider value={networkProviderValue}>
<ConfigProvider value={config}>
<_OrganizationAdd api={api} />
</ConfigProvider>
</NetworkProvider>
</I18nProvider>
</MemoryRouter>
).find('OrganizationAdd').find('AnsibleSelect');
expect(wrapper.find('FormSelect')).toHaveLength(0); expect(wrapper.find('FormSelect')).toHaveLength(0);
}); });
}); });

67
package-lock.json generated
View File

@@ -2143,6 +2143,7 @@
"version": "2.13.2", "version": "2.13.2",
"resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.13.2.tgz", "resolved": "https://registry.npmjs.org/airbnb-prop-types/-/airbnb-prop-types-2.13.2.tgz",
"integrity": "sha512-2FN6DlHr6JCSxPPi25EnqGaXC4OC3/B3k1lCd6MMYrZ51/Gf/1qDfaR+JElzWa+Tl7cY2aYOlsYJGFeQyVHIeQ==", "integrity": "sha512-2FN6DlHr6JCSxPPi25EnqGaXC4OC3/B3k1lCd6MMYrZ51/Gf/1qDfaR+JElzWa+Tl7cY2aYOlsYJGFeQyVHIeQ==",
"dev": true,
"requires": { "requires": {
"array.prototype.find": "^2.0.4", "array.prototype.find": "^2.0.4",
"function.prototype.name": "^1.1.0", "function.prototype.name": "^1.1.0",
@@ -2160,6 +2161,7 @@
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz",
"integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==",
"dev": true,
"requires": { "requires": {
"define-properties": "^1.1.3", "define-properties": "^1.1.3",
"es-abstract": "^1.12.0", "es-abstract": "^1.12.0",
@@ -2171,6 +2173,7 @@
"version": "15.7.2", "version": "15.7.2",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
"dev": true,
"requires": { "requires": {
"loose-envify": "^1.4.0", "loose-envify": "^1.4.0",
"object-assign": "^4.1.1", "object-assign": "^4.1.1",
@@ -2180,7 +2183,8 @@
"react-is": { "react-is": {
"version": "16.8.6", "version": "16.8.6",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz",
"integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==",
"dev": true
} }
} }
}, },
@@ -2736,6 +2740,7 @@
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.0.4.tgz", "resolved": "https://registry.npmjs.org/array.prototype.find/-/array.prototype.find-2.0.4.tgz",
"integrity": "sha1-VWpcU2LAhkgyPdrrnenRS8GGTJA=", "integrity": "sha1-VWpcU2LAhkgyPdrrnenRS8GGTJA=",
"dev": true,
"requires": { "requires": {
"define-properties": "^1.1.2", "define-properties": "^1.1.2",
"es-abstract": "^1.7.0" "es-abstract": "^1.7.0"
@@ -5155,6 +5160,7 @@
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
"dev": true,
"requires": { "requires": {
"object-keys": "^1.0.12" "object-keys": "^1.0.12"
}, },
@@ -5162,7 +5168,8 @@
"object-keys": { "object-keys": {
"version": "1.0.12", "version": "1.0.12",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
"integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
"dev": true
} }
} }
}, },
@@ -5618,6 +5625,7 @@
"version": "1.12.1", "version": "1.12.1",
"resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.12.1.tgz", "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.12.1.tgz",
"integrity": "sha512-GB61gvY97XvrA6qljExGY+lgI6BBwz+ASLaRKct9VQ3ozu0EraqcNn3CcrUckSGIqFGa1+CxO5gj5is5t3lwrw==", "integrity": "sha512-GB61gvY97XvrA6qljExGY+lgI6BBwz+ASLaRKct9VQ3ozu0EraqcNn3CcrUckSGIqFGa1+CxO5gj5is5t3lwrw==",
"dev": true,
"requires": { "requires": {
"enzyme-adapter-utils": "^1.11.0", "enzyme-adapter-utils": "^1.11.0",
"object.assign": "^4.1.0", "object.assign": "^4.1.0",
@@ -5632,6 +5640,7 @@
"version": "15.7.2", "version": "15.7.2",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
"dev": true,
"requires": { "requires": {
"loose-envify": "^1.4.0", "loose-envify": "^1.4.0",
"object-assign": "^4.1.1", "object-assign": "^4.1.1",
@@ -5641,7 +5650,8 @@
"react-is": { "react-is": {
"version": "16.8.6", "version": "16.8.6",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz",
"integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==",
"dev": true
} }
} }
}, },
@@ -5649,6 +5659,7 @@
"version": "1.11.0", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.11.0.tgz", "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.11.0.tgz",
"integrity": "sha512-0VZeoE9MNx+QjTfsjmO1Mo+lMfunucYB4wt5ficU85WB/LoetTJrbuujmHP3PJx6pSoaAuLA+Mq877x4LoxdNg==", "integrity": "sha512-0VZeoE9MNx+QjTfsjmO1Mo+lMfunucYB4wt5ficU85WB/LoetTJrbuujmHP3PJx6pSoaAuLA+Mq877x4LoxdNg==",
"dev": true,
"requires": { "requires": {
"airbnb-prop-types": "^2.12.0", "airbnb-prop-types": "^2.12.0",
"function.prototype.name": "^1.1.0", "function.prototype.name": "^1.1.0",
@@ -5662,6 +5673,7 @@
"version": "15.7.2", "version": "15.7.2",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
"integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
"dev": true,
"requires": { "requires": {
"loose-envify": "^1.4.0", "loose-envify": "^1.4.0",
"object-assign": "^4.1.1", "object-assign": "^4.1.1",
@@ -5671,7 +5683,8 @@
"react-is": { "react-is": {
"version": "16.8.6", "version": "16.8.6",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz",
"integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==",
"dev": true
} }
} }
}, },
@@ -5705,6 +5718,7 @@
"version": "1.12.0", "version": "1.12.0",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz",
"integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==",
"dev": true,
"requires": { "requires": {
"es-to-primitive": "^1.1.1", "es-to-primitive": "^1.1.1",
"function-bind": "^1.1.1", "function-bind": "^1.1.1",
@@ -5717,6 +5731,7 @@
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
"integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
"dev": true,
"requires": { "requires": {
"is-callable": "^1.1.4", "is-callable": "^1.1.4",
"is-date-object": "^1.0.1", "is-date-object": "^1.0.1",
@@ -7555,12 +7570,14 @@
"function-bind": { "function-bind": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
}, },
"function.prototype.name": { "function.prototype.name": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.0.tgz", "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.0.tgz",
"integrity": "sha512-Bs0VRrTz4ghD8pTmbJQD1mZ8A/mN0ur/jGz+A6FBxPDUPkm1tNfF6bhTYPA7i7aF4lZJVr+OXTNNrnnIl58Wfg==", "integrity": "sha512-Bs0VRrTz4ghD8pTmbJQD1mZ8A/mN0ur/jGz+A6FBxPDUPkm1tNfF6bhTYPA7i7aF4lZJVr+OXTNNrnnIl58Wfg==",
"dev": true,
"requires": { "requires": {
"define-properties": "^1.1.2", "define-properties": "^1.1.2",
"function-bind": "^1.1.1", "function-bind": "^1.1.1",
@@ -7770,6 +7787,7 @@
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"requires": { "requires": {
"function-bind": "^1.1.1" "function-bind": "^1.1.1"
} }
@@ -7791,7 +7809,8 @@
"has-symbols": { "has-symbols": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
"dev": true
}, },
"has-unicode": { "has-unicode": {
"version": "2.0.1", "version": "2.0.1",
@@ -8753,7 +8772,8 @@
"is-callable": { "is-callable": {
"version": "1.1.4", "version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
"dev": true
}, },
"is-ci": { "is-ci": {
"version": "2.0.0", "version": "2.0.0",
@@ -8787,7 +8807,8 @@
"is-date-object": { "is-date-object": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
"dev": true
}, },
"is-decimal": { "is-decimal": {
"version": "1.0.2", "version": "1.0.2",
@@ -8922,6 +8943,7 @@
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
"dev": true,
"requires": { "requires": {
"has": "^1.0.1" "has": "^1.0.1"
} }
@@ -8953,6 +8975,7 @@
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
"integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
"dev": true,
"requires": { "requires": {
"has-symbols": "^1.0.0" "has-symbols": "^1.0.0"
} }
@@ -11792,7 +11815,8 @@
"object-is": { "object-is": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz", "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz",
"integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=" "integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=",
"dev": true
}, },
"object-keys": { "object-keys": {
"version": "0.4.0", "version": "0.4.0",
@@ -11820,6 +11844,7 @@
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
"integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
"dev": true,
"requires": { "requires": {
"define-properties": "^1.1.2", "define-properties": "^1.1.2",
"function-bind": "^1.1.1", "function-bind": "^1.1.1",
@@ -11830,7 +11855,8 @@
"object-keys": { "object-keys": {
"version": "1.0.12", "version": "1.0.12",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
"integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
"dev": true
} }
} }
}, },
@@ -11850,6 +11876,7 @@
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz",
"integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==",
"dev": true,
"requires": { "requires": {
"define-properties": "^1.1.2", "define-properties": "^1.1.2",
"es-abstract": "^1.11.0", "es-abstract": "^1.11.0",
@@ -11888,6 +11915,7 @@
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz",
"integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==",
"dev": true,
"requires": { "requires": {
"define-properties": "^1.1.3", "define-properties": "^1.1.3",
"es-abstract": "^1.12.0", "es-abstract": "^1.12.0",
@@ -12718,6 +12746,7 @@
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/prop-types-exact/-/prop-types-exact-1.2.0.tgz", "resolved": "https://registry.npmjs.org/prop-types-exact/-/prop-types-exact-1.2.0.tgz",
"integrity": "sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==", "integrity": "sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA==",
"dev": true,
"requires": { "requires": {
"has": "^1.0.3", "has": "^1.0.3",
"object.assign": "^4.1.0", "object.assign": "^4.1.0",
@@ -13006,6 +13035,7 @@
"version": "16.8.6", "version": "16.8.6",
"resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.8.6.tgz", "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.8.6.tgz",
"integrity": "sha512-H2srzU5IWYT6cZXof6AhUcx/wEyJddQ8l7cLM/F7gDXYyPr4oq+vCIxJYXVGhId1J706sqziAjuOEjyNkfgoEw==", "integrity": "sha512-H2srzU5IWYT6cZXof6AhUcx/wEyJddQ8l7cLM/F7gDXYyPr4oq+vCIxJYXVGhId1J706sqziAjuOEjyNkfgoEw==",
"dev": true,
"requires": { "requires": {
"object-assign": "^4.1.1", "object-assign": "^4.1.1",
"prop-types": "^15.6.2", "prop-types": "^15.6.2",
@@ -13016,12 +13046,14 @@
"react-is": { "react-is": {
"version": "16.8.6", "version": "16.8.6",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz",
"integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==",
"dev": true
}, },
"scheduler": { "scheduler": {
"version": "0.13.6", "version": "0.13.6",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz",
"integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==",
"dev": true,
"requires": { "requires": {
"loose-envify": "^1.1.0", "loose-envify": "^1.1.0",
"object-assign": "^4.1.1" "object-assign": "^4.1.1"
@@ -13442,7 +13474,8 @@
"reflect.ownkeys": { "reflect.ownkeys": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz", "resolved": "https://registry.npmjs.org/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz",
"integrity": "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=" "integrity": "sha1-dJrO7H8/34tj+SegSAnpDFwLNGA=",
"dev": true
}, },
"regenerate": { "regenerate": {
"version": "1.4.0", "version": "1.4.0",
@@ -13953,16 +13986,6 @@
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
}, },
"scheduler": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.10.0.tgz",
"integrity": "sha512-+TSTVTCBAA3h8Anei3haDc1IRwMeDmtI/y/o3iBe3Mjl2vwYF9DtPDt929HyRmV/e7au7CLu8sc4C4W0VOs29w==",
"dev": true,
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
}
},
"schema-utils": { "schema-utils": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",

View File

@@ -3,6 +3,7 @@ import React, {
Fragment Fragment
} from 'react'; } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import { Title, EmptyState, EmptyStateIcon, EmptyStateBody } from '@patternfly/react-core'; import { Title, EmptyState, EmptyStateIcon, EmptyStateBody } from '@patternfly/react-core';
import { CubesIcon } from '@patternfly/react-icons'; import { CubesIcon } from '@patternfly/react-icons';
import { I18n, i18nMark } from '@lingui/react'; import { I18n, i18nMark } from '@lingui/react';
@@ -344,4 +345,4 @@ Notifications.propTypes = {
}; };
export { Notifications as _Notifications }; export { Notifications as _Notifications };
export default withNetwork(Notifications); export default withRouter(withNetwork(Notifications));

View File

@@ -15,7 +15,8 @@ class Provider extends Component {
custom_virtualenvs: null, custom_virtualenvs: null,
version: null, version: null,
custom_logo: null, custom_logo: null,
custom_login_info: null custom_login_info: null,
...props.value
} }
}; };
@@ -23,7 +24,10 @@ class Provider extends Component {
} }
componentDidMount () { componentDidMount () {
this.fetchConfig(); const { value } = this.props;
if (!value) {
this.fetchConfig();
}
} }
async fetchConfig () { async fetchConfig () {
@@ -66,14 +70,12 @@ class Provider extends Component {
} }
render () { render () {
const { const { value } = this.state;
value: stateValue
} = this.state;
const { value: propsValue, children } = this.props; const { children } = this.props;
return ( return (
<ConfigContext.Provider value={propsValue || stateValue}> <ConfigContext.Provider value={value}>
{children} {children}
</ConfigContext.Provider> </ConfigContext.Provider>
); );

View File

@@ -26,7 +26,8 @@ class Provider extends Component {
this.handle404(); this.handle404();
} }
return (err.response.status === 401 || err.response.status === 404); return (err.response.status === 401 || err.response.status === 404);
} },
...props.value
} }
}; };
} }
@@ -58,14 +59,12 @@ class Provider extends Component {
} }
render () { render () {
const { const { value } = this.state;
value: stateValue
} = this.state;
const { value: propsValue, children } = this.props; const { children } = this.props;
return ( return (
<NetworkContext.Provider value={propsValue || stateValue}> <NetworkContext.Provider value={value}>
{children} {children}
</NetworkContext.Provider> </NetworkContext.Provider>
); );

View File

@@ -17,7 +17,7 @@ export class RootDialogProvider extends Component {
const { value } = this.state; const { value } = this.state;
this.setState({ value: { ...value, title: null, bodyText: null, variant: null } }); this.setState({ value: { ...value, title: null, bodyText: null, variant: null } });
}, },
...props.value, ...props.value
} }
}; };
} }

View File

@@ -10,7 +10,8 @@ import { I18n, i18nMark } from '@lingui/react';
import { t, Trans } from '@lingui/macro'; import { t, Trans } from '@lingui/macro';
import { import {
Link Link,
withRouter
} from 'react-router-dom'; } from 'react-router-dom';
import { withNetwork } from '../../../contexts/Network'; import { withNetwork } from '../../../contexts/Network';
@@ -160,8 +161,8 @@ class OrganizationAccessList extends React.Component {
} }
getQueryParams (overrides = {}) { getQueryParams (overrides = {}) {
const { location } = this.props; const { history } = this.props;
const { search } = location; const { search } = history.location;
const searchParams = parseQueryString(search.substring(1)); const searchParams = parseQueryString(search.substring(1));
@@ -422,4 +423,4 @@ OrganizationAccessList.propTypes = {
}; };
export { OrganizationAccessList as _OrganizationAccessList }; export { OrganizationAccessList as _OrganizationAccessList };
export default withNetwork(OrganizationAccessList); export default withRouter(withNetwork(OrganizationAccessList));

View File

@@ -158,11 +158,7 @@ class Organization extends Component {
<Route <Route
path="/organizations/:id/access" path="/organizations/:id/access"
render={() => ( render={() => (
<OrganizationAccess <OrganizationAccess />
match={match}
location={location}
history={history}
/>
)} )}
/> />
<Route <Route

View File

@@ -23,19 +23,10 @@ class OrganizationAccess extends React.Component {
} }
render () { render () {
const {
location,
match,
history,
} = this.props;
return ( return (
<OrganizationAccessList <OrganizationAccessList
getAccessList={this.getOrgAccessList} getAccessList={this.getOrgAccessList}
removeRole={this.removeRole} removeRole={this.removeRole}
match={match}
location={location}
history={history}
/> />
); );
} }

View File

@@ -1,5 +1,5 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { Link } from 'react-router-dom'; import { Link, withRouter } from 'react-router-dom';
import { I18n } from '@lingui/react'; import { I18n } from '@lingui/react';
import { Trans, t } from '@lingui/macro'; import { Trans, t } from '@lingui/macro';
@@ -178,4 +178,4 @@ class OrganizationDetail extends Component {
} }
} }
export default withNetwork(OrganizationDetail); export default withRouter(withNetwork(OrganizationDetail));

View File

@@ -41,12 +41,6 @@ class OrganizationNotifications extends Component {
} }
render () { render () {
const {
location,
match,
history
} = this.props;
return ( return (
<NotificationsList <NotificationsList
onReadNotifications={this.readOrgNotifications} onReadNotifications={this.readOrgNotifications}
@@ -54,9 +48,6 @@ class OrganizationNotifications extends Component {
onReadError={this.readOrgNotificationError} onReadError={this.readOrgNotificationError}
onCreateSuccess={this.createOrgNotificationSuccess} onCreateSuccess={this.createOrgNotificationSuccess}
onCreateError={this.createOrgNotificationError} onCreateError={this.createOrgNotificationError}
match={match}
location={location}
history={history}
/> />
); );
} }