mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-26 13:48:33 +02:00
Merge pull request #116 from corinnekrych/make.strategies.default.tab
Make.strategies.default.tab
This commit is contained in:
commit
7e81ab81ed
@ -67,6 +67,8 @@
|
||||
"babel-preset-stage-0": "^6.5.0",
|
||||
"babel-preset-stage-2": "^6.13.0",
|
||||
"css-loader": "^0.28.4",
|
||||
"enzyme": "^3.3.0",
|
||||
"enzyme-adapter-react-16": "^1.1.1",
|
||||
"eslint": "^4.5.0",
|
||||
"eslint-config-finn": "^3.0.0",
|
||||
"eslint-config-finn-prettier": "^3.0.0",
|
||||
@ -92,6 +94,7 @@
|
||||
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/src/__mocks__/fileMock.js",
|
||||
"\\.(css|scss)$": "identity-obj-proxy"
|
||||
},
|
||||
"setupTestFrameworkScriptFile": "<rootDir>/src/setupTests.js",
|
||||
"setupFiles": [
|
||||
"<rootDir>/jest-setup.js"
|
||||
]
|
||||
|
2
frontend/src/__mocks__/react-mdl.js
vendored
2
frontend/src/__mocks__/react-mdl.js
vendored
@ -13,6 +13,8 @@ module.exports = {
|
||||
ListItem: 'react-mdl-ListItem',
|
||||
ListItemContent: 'react-mdl-ListItemContent',
|
||||
ListItemAction: 'react-mdl-ListItemAction',
|
||||
Menu: 'react-mdl-Menu',
|
||||
MenuItem: 'react-mdl-MenuItem',
|
||||
ProgressBar: 'react-mdl-ProgressBar',
|
||||
Switch: 'react-mdl-Switch',
|
||||
Tab: 'react-mdl-Tab',
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { connect } from 'react-redux';
|
||||
import ApplicationEdit from './application-edit-component';
|
||||
import { fetchApplication, storeApplicationMetaData } from '../../store/application/actions';
|
||||
import { fetchApplication, storeApplicationMetaData } from './../../store/application/actions';
|
||||
|
||||
const mapStateToProps = (state, props) => {
|
||||
let application = state.applications.getIn(['apps', props.appName]);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { connect } from 'react-redux';
|
||||
import ApplicationList from './application-list-component';
|
||||
import { fetchAll } from '../../store/application/actions';
|
||||
import { fetchAll } from './../../store/application/actions';
|
||||
|
||||
const mapStateToProps = state => ({ applications: state.applications.get('list').toJS() });
|
||||
|
||||
|
@ -27,6 +27,7 @@ class ArchiveList extends Component {
|
||||
))}
|
||||
</span>
|
||||
);
|
||||
|
||||
return strategiesList;
|
||||
}
|
||||
renderStrategiesInList(feature) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { connect } from 'react-redux';
|
||||
import ListComponent from './archive-list-component';
|
||||
import { fetchArchive, revive } from '../../store/archive-actions';
|
||||
import { fetchArchive, revive } from './../../store/archive-actions';
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const archive = state.archive.get('list').toArray();
|
||||
|
@ -180,3 +180,6 @@ export function calc(value, total, decimal) {
|
||||
|
||||
return (value / total * 100).toFixed(decimal);
|
||||
}
|
||||
export function getDisplayName(WrappedComponent) {
|
||||
return WrappedComponent.displayName || WrappedComponent.name || 'Component';
|
||||
}
|
||||
|
5
frontend/src/component/feature/__tests__/.eslintrc
Normal file
5
frontend/src/component/feature/__tests__/.eslintrc
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"env": {
|
||||
"jest": true
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly with one feature 1`] = `
|
||||
<react-mdl-ListItem
|
||||
twoLine={true}
|
||||
>
|
||||
<span
|
||||
className="listItemMetric"
|
||||
>
|
||||
<svg
|
||||
className="mdl-color-text--grey-300"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M17.3,18C19,16.5 20,14.4 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12C4,14.4 5,16.5 6.7,18C8.2,16.7 10,16 12,16C14,16 15.9,16.7 17.3,18M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M7,9A1,1 0 0,1 8,10A1,1 0 0,1 7,11A1,1 0 0,1 6,10A1,1 0 0,1 7,9M10,6A1,1 0 0,1 11,7A1,1 0 0,1 10,8A1,1 0 0,1 9,7A1,1 0 0,1 10,6M17,9A1,1 0 0,1 18,10A1,1 0 0,1 17,11A1,1 0 0,1 16,10A1,1 0 0,1 17,9M14.4,6.1C14.9,6.3 15.1,6.9 15,7.4L13.6,10.8C13.8,11.1 14,11.5 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12C10,11 10.7,10.1 11.7,10L13.1,6.7C13.3,6.1 13.9,5.9 14.4,6.1Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
className="listItemToggle"
|
||||
>
|
||||
<react-mdl-Switch
|
||||
checked={false}
|
||||
onChange={[Function]}
|
||||
title="Toggle Another"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
className="mdl-list__item-primary-content listItemLink"
|
||||
>
|
||||
<a
|
||||
className="listLink truncate"
|
||||
onClick={[Function]}
|
||||
style={Object {}}
|
||||
>
|
||||
Another
|
||||
<span
|
||||
className="mdl-list__item-sub-title truncate"
|
||||
>
|
||||
another's description
|
||||
</span>
|
||||
</a>
|
||||
</span>
|
||||
<span
|
||||
className="listItemStrategies hideLt920"
|
||||
>
|
||||
<react-mdl-Chip
|
||||
className="strategyChip"
|
||||
>
|
||||
gradualRolloutRandom
|
||||
</react-mdl-Chip>
|
||||
</span>
|
||||
</react-mdl-ListItem>
|
||||
`;
|
@ -0,0 +1,107 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders correctly with 0% done no fallback 1`] = `
|
||||
<svg
|
||||
viewBox="0 0 100 100"
|
||||
>
|
||||
<path
|
||||
className="trail mdl-color-text--grey-300"
|
||||
d="
|
||||
M 50,50 m 0,-42.5
|
||||
a 42.5,42.5 0 1 1 0,85
|
||||
a 42.5,42.5 0 1 1 0,-85
|
||||
"
|
||||
fillOpacity={0}
|
||||
strokeWidth={15}
|
||||
/>
|
||||
<path
|
||||
className="path mdl-color-text--primary"
|
||||
d="
|
||||
M 50,50 m 0,-42.5
|
||||
a 42.5,42.5 0 1 1 0,85
|
||||
a 42.5,42.5 0 1 1 0,-85
|
||||
"
|
||||
fillOpacity={0}
|
||||
strokeWidth={15}
|
||||
style={
|
||||
Object {
|
||||
"strokeDasharray": "267.0353755551324px 267.0353755551324px",
|
||||
"strokeDashoffset": "267.0353755551324px",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<text
|
||||
className="text"
|
||||
x={50}
|
||||
y={50}
|
||||
>
|
||||
0
|
||||
%
|
||||
</text>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`renders correctly with 0% done with fallback 1`] = `
|
||||
<svg
|
||||
className="mdl-color-text--grey-300"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M17.3,18C19,16.5 20,14.4 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12C4,14.4 5,16.5 6.7,18C8.2,16.7 10,16 12,16C14,16 15.9,16.7 17.3,18M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M7,9A1,1 0 0,1 8,10A1,1 0 0,1 7,11A1,1 0 0,1 6,10A1,1 0 0,1 7,9M10,6A1,1 0 0,1 11,7A1,1 0 0,1 10,8A1,1 0 0,1 9,7A1,1 0 0,1 10,6M17,9A1,1 0 0,1 18,10A1,1 0 0,1 17,11A1,1 0 0,1 16,10A1,1 0 0,1 17,9M14.4,6.1C14.9,6.3 15.1,6.9 15,7.4L13.6,10.8C13.8,11.1 14,11.5 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12C10,11 10.7,10.1 11.7,10L13.1,6.7C13.3,6.1 13.9,5.9 14.4,6.1Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`renders correctly with 15% done no fallback 1`] = `
|
||||
<svg
|
||||
viewBox="0 0 100 100"
|
||||
>
|
||||
<path
|
||||
className="trail mdl-color-text--grey-300"
|
||||
d="
|
||||
M 50,50 m 0,-42.5
|
||||
a 42.5,42.5 0 1 1 0,85
|
||||
a 42.5,42.5 0 1 1 0,-85
|
||||
"
|
||||
fillOpacity={0}
|
||||
strokeWidth={15}
|
||||
/>
|
||||
<path
|
||||
className="path mdl-color-text--primary"
|
||||
d="
|
||||
M 50,50 m 0,-42.5
|
||||
a 42.5,42.5 0 1 1 0,85
|
||||
a 42.5,42.5 0 1 1 0,-85
|
||||
"
|
||||
fillOpacity={0}
|
||||
strokeWidth={15}
|
||||
style={
|
||||
Object {
|
||||
"strokeDasharray": "267.0353755551324px 267.0353755551324px",
|
||||
"strokeDashoffset": "226.98006922186255px",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<text
|
||||
className="text"
|
||||
x={50}
|
||||
y={50}
|
||||
>
|
||||
15
|
||||
%
|
||||
</text>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
exports[`renders correctly with 15% done with fallback 1`] = `
|
||||
<svg
|
||||
className="mdl-color-text--grey-300"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M17.3,18C19,16.5 20,14.4 20,12A8,8 0 0,0 12,4A8,8 0 0,0 4,12C4,14.4 5,16.5 6.7,18C8.2,16.7 10,16 12,16C14,16 15.9,16.7 17.3,18M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M7,9A1,1 0 0,1 8,10A1,1 0 0,1 7,11A1,1 0 0,1 6,10A1,1 0 0,1 7,9M10,6A1,1 0 0,1 11,7A1,1 0 0,1 10,8A1,1 0 0,1 9,7A1,1 0 0,1 10,6M17,9A1,1 0 0,1 18,10A1,1 0 0,1 17,11A1,1 0 0,1 16,10A1,1 0 0,1 17,9M14.4,6.1C14.9,6.3 15.1,6.9 15,7.4L13.6,10.8C13.8,11.1 14,11.5 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12C10,11 10.7,10.1 11.7,10L13.1,6.7C13.3,6.1 13.9,5.9 14.4,6.1Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
`;
|
@ -0,0 +1,37 @@
|
||||
import React from 'react';
|
||||
|
||||
import Feature from './../feature-list-item-component';
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
jest.mock('react-mdl');
|
||||
|
||||
test('renders correctly with one feature', () => {
|
||||
const feature = {
|
||||
name: 'Another',
|
||||
description: "another's description",
|
||||
enabled: false,
|
||||
strategies: [
|
||||
{
|
||||
name: 'gradualRolloutRandom',
|
||||
parameters: {
|
||||
percentage: 50,
|
||||
},
|
||||
},
|
||||
],
|
||||
createdAt: '2018-02-04T20:27:52.127Z',
|
||||
};
|
||||
const featureMetrics = { lastHour: {}, lastMinute: {}, seenApps: {} };
|
||||
const settings = { sort: 'name' };
|
||||
const tree = renderer.create(
|
||||
<Feature
|
||||
key={0}
|
||||
settings={settings}
|
||||
metricsLastHour={featureMetrics.lastHour[feature.name]}
|
||||
metricsLastMinute={featureMetrics.lastMinute[feature.name]}
|
||||
feature={feature}
|
||||
toggleFeature={jest.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
34
frontend/src/component/feature/__tests__/progress-test.jsx
Normal file
34
frontend/src/component/feature/__tests__/progress-test.jsx
Normal file
@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
|
||||
import Progress from './../progress';
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
jest.mock('react-mdl');
|
||||
|
||||
test('renders correctly with 15% done no fallback', () => {
|
||||
const percent = 15;
|
||||
const tree = renderer.create(<Progress strokeWidth={15} percentage={percent} isFallback={false} />);
|
||||
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('renders correctly with 0% done no fallback', () => {
|
||||
const percent = 0;
|
||||
const tree = renderer.create(<Progress strokeWidth={15} percentage={percent} isFallback={false} />);
|
||||
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('renders correctly with 15% done with fallback', () => {
|
||||
const percent = 15;
|
||||
const tree = renderer.create(<Progress strokeWidth={15} percentage={percent} isFallback />);
|
||||
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('renders correctly with 0% done with fallback', () => {
|
||||
const percent = 0;
|
||||
const tree = renderer.create(<Progress strokeWidth={15} percentage={percent} isFallback />);
|
||||
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
@ -52,7 +52,7 @@ const Feature = ({
|
||||
</span>
|
||||
<span className={['mdl-list__item-primary-content', styles.listItemLink].join(' ')}>
|
||||
<Link
|
||||
to={`/features/view/${name}`}
|
||||
to={`/features/strategies/${name}`}
|
||||
className={[commonStyles.listLink, commonStyles.truncate].join(' ')}
|
||||
>
|
||||
{name}
|
||||
|
@ -1,19 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Card, CardTitle } from 'react-mdl';
|
||||
|
||||
import FormComponent from './form';
|
||||
import { styles as commonStyles } from '../common';
|
||||
|
||||
const FormAddComponent = ({ title, ...formProps }) => (
|
||||
<Card className={commonStyles.fullwidth} style={{ overflow: 'visible' }}>
|
||||
<CardTitle style={{ paddingTop: '24px' }}>{title}</CardTitle>
|
||||
<FormComponent {...formProps} />
|
||||
</Card>
|
||||
);
|
||||
|
||||
FormAddComponent.propTypes = {
|
||||
title: PropTypes.string,
|
||||
};
|
||||
|
||||
export default FormAddComponent;
|
5
frontend/src/component/feature/form/__tests__/.eslintrc
Normal file
5
frontend/src/component/feature/form/__tests__/.eslintrc
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"env": {
|
||||
"jest": true
|
||||
}
|
||||
}
|
@ -0,0 +1,555 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`render the create feature page 1`] = `
|
||||
ShallowWrapper {
|
||||
"length": 1,
|
||||
Symbol(enzyme.__root__): [Circular],
|
||||
Symbol(enzyme.__unrendered__): <AddFeatureComponent
|
||||
addStrategy={[MockFunction]}
|
||||
initCallRequired={false}
|
||||
input={
|
||||
Object {
|
||||
"description": "Description",
|
||||
"enabled": false,
|
||||
"name": "feature",
|
||||
"nameError": Object {},
|
||||
}
|
||||
}
|
||||
moveStrategy={[MockFunction]}
|
||||
onCancel={[MockFunction]}
|
||||
onSubmit={
|
||||
[MockFunction] {
|
||||
"calls": Array [
|
||||
Array [
|
||||
Object {
|
||||
"description": "Description",
|
||||
"enabled": false,
|
||||
"name": "feature",
|
||||
"nameError": Object {},
|
||||
},
|
||||
],
|
||||
],
|
||||
}
|
||||
}
|
||||
removeStrategy={[MockFunction]}
|
||||
setValue={[MockFunction]}
|
||||
title="title"
|
||||
updateStrategy={[MockFunction]}
|
||||
validateName={[MockFunction]}
|
||||
/>,
|
||||
Symbol(enzyme.__renderer__): Object {
|
||||
"batchedUpdates": [Function],
|
||||
"getNode": [Function],
|
||||
"render": [Function],
|
||||
"simulateEvent": [Function],
|
||||
"unmount": [Function],
|
||||
},
|
||||
Symbol(enzyme.__node__): Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": <section
|
||||
style={
|
||||
Object {
|
||||
"padding": "16px",
|
||||
}
|
||||
}
|
||||
>
|
||||
<react-mdl-Textfield
|
||||
error={Object {}}
|
||||
floatingLabel={true}
|
||||
label="Name"
|
||||
name="name"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
required={true}
|
||||
value="feature"
|
||||
/>
|
||||
<react-mdl-Textfield
|
||||
floatingLabel={true}
|
||||
label="Description"
|
||||
onChange={[Function]}
|
||||
required={true}
|
||||
rows={1}
|
||||
style={
|
||||
Object {
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
value="Description"
|
||||
/>
|
||||
<div>
|
||||
<br />
|
||||
<react-mdl-Switch
|
||||
checked={false}
|
||||
onChange={[Function]}
|
||||
>
|
||||
Enabled
|
||||
</react-mdl-Switch>
|
||||
<hr />
|
||||
</div>
|
||||
<StrategiesSection
|
||||
addStrategy={[MockFunction]}
|
||||
configuredStrategies={Array []}
|
||||
moveStrategy={[MockFunction]}
|
||||
removeStrategy={[MockFunction]}
|
||||
updateStrategy={[MockFunction]}
|
||||
/>
|
||||
<br />
|
||||
<FormButtons
|
||||
onCancel={[MockFunction]}
|
||||
submitText="Create"
|
||||
/>
|
||||
</section>,
|
||||
"onSubmit": undefined,
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": Array [
|
||||
<react-mdl-Textfield
|
||||
error={Object {}}
|
||||
floatingLabel={true}
|
||||
label="Name"
|
||||
name="name"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
required={true}
|
||||
value="feature"
|
||||
/>,
|
||||
<react-mdl-Textfield
|
||||
floatingLabel={true}
|
||||
label="Description"
|
||||
onChange={[Function]}
|
||||
required={true}
|
||||
rows={1}
|
||||
style={
|
||||
Object {
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
value="Description"
|
||||
/>,
|
||||
<div>
|
||||
<br />
|
||||
<react-mdl-Switch
|
||||
checked={false}
|
||||
onChange={[Function]}
|
||||
>
|
||||
Enabled
|
||||
</react-mdl-Switch>
|
||||
<hr />
|
||||
</div>,
|
||||
<StrategiesSection
|
||||
addStrategy={[MockFunction]}
|
||||
configuredStrategies={Array []}
|
||||
moveStrategy={[MockFunction]}
|
||||
removeStrategy={[MockFunction]}
|
||||
updateStrategy={[MockFunction]}
|
||||
/>,
|
||||
<br />,
|
||||
<FormButtons
|
||||
onCancel={[MockFunction]}
|
||||
submitText="Create"
|
||||
/>,
|
||||
],
|
||||
"style": Object {
|
||||
"padding": "16px",
|
||||
},
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"error": Object {},
|
||||
"floatingLabel": true,
|
||||
"label": "Name",
|
||||
"name": "name",
|
||||
"onBlur": [Function],
|
||||
"onChange": [Function],
|
||||
"required": true,
|
||||
"value": "feature",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "react-mdl-Textfield",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"floatingLabel": true,
|
||||
"label": "Description",
|
||||
"onChange": [Function],
|
||||
"required": true,
|
||||
"rows": 1,
|
||||
"style": Object {
|
||||
"width": "100%",
|
||||
},
|
||||
"value": "Description",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "react-mdl-Textfield",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": Array [
|
||||
<br />,
|
||||
<react-mdl-Switch
|
||||
checked={false}
|
||||
onChange={[Function]}
|
||||
>
|
||||
Enabled
|
||||
</react-mdl-Switch>,
|
||||
<hr />,
|
||||
],
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "br",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"checked": false,
|
||||
"children": "Enabled",
|
||||
"onChange": [Function],
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": "Enabled",
|
||||
"type": "react-mdl-Switch",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "hr",
|
||||
},
|
||||
],
|
||||
"type": "div",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"addStrategy": [MockFunction],
|
||||
"configuredStrategies": Array [],
|
||||
"moveStrategy": [MockFunction],
|
||||
"removeStrategy": [MockFunction],
|
||||
"updateStrategy": [MockFunction],
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "StrategiesSection",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "br",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "function",
|
||||
"props": Object {
|
||||
"onCancel": [MockFunction],
|
||||
"submitText": "Create",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": [Function],
|
||||
},
|
||||
],
|
||||
"type": "section",
|
||||
},
|
||||
"type": "form",
|
||||
},
|
||||
Symbol(enzyme.__nodes__): Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": <section
|
||||
style={
|
||||
Object {
|
||||
"padding": "16px",
|
||||
}
|
||||
}
|
||||
>
|
||||
<react-mdl-Textfield
|
||||
error={Object {}}
|
||||
floatingLabel={true}
|
||||
label="Name"
|
||||
name="name"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
required={true}
|
||||
value="feature"
|
||||
/>
|
||||
<react-mdl-Textfield
|
||||
floatingLabel={true}
|
||||
label="Description"
|
||||
onChange={[Function]}
|
||||
required={true}
|
||||
rows={1}
|
||||
style={
|
||||
Object {
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
value="Description"
|
||||
/>
|
||||
<div>
|
||||
<br />
|
||||
<react-mdl-Switch
|
||||
checked={false}
|
||||
onChange={[Function]}
|
||||
>
|
||||
Enabled
|
||||
</react-mdl-Switch>
|
||||
<hr />
|
||||
</div>
|
||||
<StrategiesSection
|
||||
addStrategy={[MockFunction]}
|
||||
configuredStrategies={Array []}
|
||||
moveStrategy={[MockFunction]}
|
||||
removeStrategy={[MockFunction]}
|
||||
updateStrategy={[MockFunction]}
|
||||
/>
|
||||
<br />
|
||||
<FormButtons
|
||||
onCancel={[MockFunction]}
|
||||
submitText="Create"
|
||||
/>
|
||||
</section>,
|
||||
"onSubmit": undefined,
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": Array [
|
||||
<react-mdl-Textfield
|
||||
error={Object {}}
|
||||
floatingLabel={true}
|
||||
label="Name"
|
||||
name="name"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
required={true}
|
||||
value="feature"
|
||||
/>,
|
||||
<react-mdl-Textfield
|
||||
floatingLabel={true}
|
||||
label="Description"
|
||||
onChange={[Function]}
|
||||
required={true}
|
||||
rows={1}
|
||||
style={
|
||||
Object {
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
value="Description"
|
||||
/>,
|
||||
<div>
|
||||
<br />
|
||||
<react-mdl-Switch
|
||||
checked={false}
|
||||
onChange={[Function]}
|
||||
>
|
||||
Enabled
|
||||
</react-mdl-Switch>
|
||||
<hr />
|
||||
</div>,
|
||||
<StrategiesSection
|
||||
addStrategy={[MockFunction]}
|
||||
configuredStrategies={Array []}
|
||||
moveStrategy={[MockFunction]}
|
||||
removeStrategy={[MockFunction]}
|
||||
updateStrategy={[MockFunction]}
|
||||
/>,
|
||||
<br />,
|
||||
<FormButtons
|
||||
onCancel={[MockFunction]}
|
||||
submitText="Create"
|
||||
/>,
|
||||
],
|
||||
"style": Object {
|
||||
"padding": "16px",
|
||||
},
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"error": Object {},
|
||||
"floatingLabel": true,
|
||||
"label": "Name",
|
||||
"name": "name",
|
||||
"onBlur": [Function],
|
||||
"onChange": [Function],
|
||||
"required": true,
|
||||
"value": "feature",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "react-mdl-Textfield",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"floatingLabel": true,
|
||||
"label": "Description",
|
||||
"onChange": [Function],
|
||||
"required": true,
|
||||
"rows": 1,
|
||||
"style": Object {
|
||||
"width": "100%",
|
||||
},
|
||||
"value": "Description",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "react-mdl-Textfield",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": Array [
|
||||
<br />,
|
||||
<react-mdl-Switch
|
||||
checked={false}
|
||||
onChange={[Function]}
|
||||
>
|
||||
Enabled
|
||||
</react-mdl-Switch>,
|
||||
<hr />,
|
||||
],
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "br",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"checked": false,
|
||||
"children": "Enabled",
|
||||
"onChange": [Function],
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": "Enabled",
|
||||
"type": "react-mdl-Switch",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "hr",
|
||||
},
|
||||
],
|
||||
"type": "div",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"addStrategy": [MockFunction],
|
||||
"configuredStrategies": Array [],
|
||||
"moveStrategy": [MockFunction],
|
||||
"removeStrategy": [MockFunction],
|
||||
"updateStrategy": [MockFunction],
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "StrategiesSection",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "br",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "function",
|
||||
"props": Object {
|
||||
"onCancel": [MockFunction],
|
||||
"submitText": "Create",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": [Function],
|
||||
},
|
||||
],
|
||||
"type": "section",
|
||||
},
|
||||
"type": "form",
|
||||
},
|
||||
],
|
||||
Symbol(enzyme.__options__): Object {
|
||||
"adapter": ReactSixteenAdapter {
|
||||
"options": Object {
|
||||
"enableComponentDidUpdateOnSetState": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
@ -0,0 +1,245 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`render the create feature page 1`] = `
|
||||
ShallowWrapper {
|
||||
"length": 1,
|
||||
Symbol(enzyme.__root__): [Circular],
|
||||
Symbol(enzyme.__unrendered__): <UpdateFeatureComponent
|
||||
addStrategy={[MockFunction]}
|
||||
initCallRequired={false}
|
||||
input={
|
||||
Object {
|
||||
"description": "Description",
|
||||
"enabled": false,
|
||||
"name": "feature",
|
||||
"nameError": Object {},
|
||||
}
|
||||
}
|
||||
moveStrategy={[MockFunction]}
|
||||
onCancel={[MockFunction]}
|
||||
onSubmit={
|
||||
[MockFunction] {
|
||||
"calls": Array [
|
||||
Array [
|
||||
Object {
|
||||
"description": "Description",
|
||||
"enabled": false,
|
||||
"name": "feature",
|
||||
"nameError": Object {},
|
||||
},
|
||||
],
|
||||
],
|
||||
}
|
||||
}
|
||||
removeStrategy={[MockFunction]}
|
||||
setValue={[MockFunction]}
|
||||
title="title"
|
||||
updateStrategy={[MockFunction]}
|
||||
validateName={[MockFunction]}
|
||||
/>,
|
||||
Symbol(enzyme.__renderer__): Object {
|
||||
"batchedUpdates": [Function],
|
||||
"getNode": [Function],
|
||||
"render": [Function],
|
||||
"simulateEvent": [Function],
|
||||
"unmount": [Function],
|
||||
},
|
||||
Symbol(enzyme.__node__): Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": <section
|
||||
style={
|
||||
Object {
|
||||
"padding": "16px",
|
||||
}
|
||||
}
|
||||
>
|
||||
<StrategiesSection
|
||||
addStrategy={[MockFunction]}
|
||||
configuredStrategies={Array []}
|
||||
moveStrategy={[MockFunction]}
|
||||
removeStrategy={[MockFunction]}
|
||||
updateStrategy={[MockFunction]}
|
||||
/>
|
||||
<br />
|
||||
<FormButtons
|
||||
onCancel={[MockFunction]}
|
||||
submitText="Update"
|
||||
/>
|
||||
</section>,
|
||||
"onSubmit": undefined,
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": Array [
|
||||
<StrategiesSection
|
||||
addStrategy={[MockFunction]}
|
||||
configuredStrategies={Array []}
|
||||
moveStrategy={[MockFunction]}
|
||||
removeStrategy={[MockFunction]}
|
||||
updateStrategy={[MockFunction]}
|
||||
/>,
|
||||
<br />,
|
||||
<FormButtons
|
||||
onCancel={[MockFunction]}
|
||||
submitText="Update"
|
||||
/>,
|
||||
],
|
||||
"style": Object {
|
||||
"padding": "16px",
|
||||
},
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"addStrategy": [MockFunction],
|
||||
"configuredStrategies": Array [],
|
||||
"moveStrategy": [MockFunction],
|
||||
"removeStrategy": [MockFunction],
|
||||
"updateStrategy": [MockFunction],
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "StrategiesSection",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "br",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "function",
|
||||
"props": Object {
|
||||
"onCancel": [MockFunction],
|
||||
"submitText": "Update",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": [Function],
|
||||
},
|
||||
],
|
||||
"type": "section",
|
||||
},
|
||||
"type": "form",
|
||||
},
|
||||
Symbol(enzyme.__nodes__): Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": <section
|
||||
style={
|
||||
Object {
|
||||
"padding": "16px",
|
||||
}
|
||||
}
|
||||
>
|
||||
<StrategiesSection
|
||||
addStrategy={[MockFunction]}
|
||||
configuredStrategies={Array []}
|
||||
moveStrategy={[MockFunction]}
|
||||
removeStrategy={[MockFunction]}
|
||||
updateStrategy={[MockFunction]}
|
||||
/>
|
||||
<br />
|
||||
<FormButtons
|
||||
onCancel={[MockFunction]}
|
||||
submitText="Update"
|
||||
/>
|
||||
</section>,
|
||||
"onSubmit": undefined,
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": Array [
|
||||
<StrategiesSection
|
||||
addStrategy={[MockFunction]}
|
||||
configuredStrategies={Array []}
|
||||
moveStrategy={[MockFunction]}
|
||||
removeStrategy={[MockFunction]}
|
||||
updateStrategy={[MockFunction]}
|
||||
/>,
|
||||
<br />,
|
||||
<FormButtons
|
||||
onCancel={[MockFunction]}
|
||||
submitText="Update"
|
||||
/>,
|
||||
],
|
||||
"style": Object {
|
||||
"padding": "16px",
|
||||
},
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"addStrategy": [MockFunction],
|
||||
"configuredStrategies": Array [],
|
||||
"moveStrategy": [MockFunction],
|
||||
"removeStrategy": [MockFunction],
|
||||
"updateStrategy": [MockFunction],
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "StrategiesSection",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "br",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "function",
|
||||
"props": Object {
|
||||
"onCancel": [MockFunction],
|
||||
"submitText": "Update",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": [Function],
|
||||
},
|
||||
],
|
||||
"type": "section",
|
||||
},
|
||||
"type": "form",
|
||||
},
|
||||
],
|
||||
Symbol(enzyme.__options__): Object {
|
||||
"adapter": ReactSixteenAdapter {
|
||||
"options": Object {
|
||||
"enableComponentDidUpdateOnSetState": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
@ -0,0 +1,296 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders add strategy form with a list of available strategies 1`] = `
|
||||
ShallowWrapper {
|
||||
"length": 1,
|
||||
Symbol(enzyme.__root__): [Circular],
|
||||
Symbol(enzyme.__unrendered__): <AddStrategy
|
||||
addStrategy={[MockFunction]}
|
||||
fetchStrategies={[MockFunction]}
|
||||
strategies={
|
||||
Array [
|
||||
Object {
|
||||
"description": "Default on/off strategy.",
|
||||
"editable": false,
|
||||
"name": "default",
|
||||
"parameters": Array [
|
||||
"t",
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
/>,
|
||||
Symbol(enzyme.__renderer__): Object {
|
||||
"batchedUpdates": [Function],
|
||||
"getNode": [Function],
|
||||
"render": [Function],
|
||||
"simulateEvent": [Function],
|
||||
"unmount": [Function],
|
||||
},
|
||||
Symbol(enzyme.__node__): Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": Array [
|
||||
<react-mdl-IconButton
|
||||
accent={true}
|
||||
id="strategies-add"
|
||||
name="add"
|
||||
onClick={[Function]}
|
||||
raised={true}
|
||||
title="Add Strategy"
|
||||
/>,
|
||||
<react-mdl-Menu
|
||||
align="right"
|
||||
ripple={true}
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "rgb(247, 248, 255)",
|
||||
"maxHeight": "300px",
|
||||
"overflowY": "auto",
|
||||
}
|
||||
}
|
||||
target="strategies-add"
|
||||
valign="bottom"
|
||||
>
|
||||
<react-mdl-MenuItem
|
||||
disabled={true}
|
||||
>
|
||||
Add Strategy:
|
||||
</react-mdl-MenuItem>
|
||||
<react-mdl-MenuItem
|
||||
onClick={[Function]}
|
||||
title="Default on/off strategy."
|
||||
>
|
||||
default
|
||||
</react-mdl-MenuItem>
|
||||
</react-mdl-Menu>,
|
||||
],
|
||||
"style": Object {
|
||||
"display": "inline-block",
|
||||
"height": "25px",
|
||||
"position": "relative",
|
||||
"width": "25px",
|
||||
},
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"accent": true,
|
||||
"id": "strategies-add",
|
||||
"name": "add",
|
||||
"onClick": [Function],
|
||||
"raised": true,
|
||||
"title": "Add Strategy",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "react-mdl-IconButton",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"align": "right",
|
||||
"children": Array [
|
||||
<react-mdl-MenuItem
|
||||
disabled={true}
|
||||
>
|
||||
Add Strategy:
|
||||
</react-mdl-MenuItem>,
|
||||
Array [
|
||||
<react-mdl-MenuItem
|
||||
onClick={[Function]}
|
||||
title="Default on/off strategy."
|
||||
>
|
||||
default
|
||||
</react-mdl-MenuItem>,
|
||||
],
|
||||
],
|
||||
"ripple": true,
|
||||
"style": Object {
|
||||
"backgroundColor": "rgb(247, 248, 255)",
|
||||
"maxHeight": "300px",
|
||||
"overflowY": "auto",
|
||||
},
|
||||
"target": "strategies-add",
|
||||
"valign": "bottom",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": "Add Strategy:",
|
||||
"disabled": true,
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": "Add Strategy:",
|
||||
"type": "react-mdl-MenuItem",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": "default",
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": "default",
|
||||
"onClick": [Function],
|
||||
"title": "Default on/off strategy.",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": "default",
|
||||
"type": "react-mdl-MenuItem",
|
||||
},
|
||||
],
|
||||
"type": "react-mdl-Menu",
|
||||
},
|
||||
],
|
||||
"type": "div",
|
||||
},
|
||||
Symbol(enzyme.__nodes__): Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": Array [
|
||||
<react-mdl-IconButton
|
||||
accent={true}
|
||||
id="strategies-add"
|
||||
name="add"
|
||||
onClick={[Function]}
|
||||
raised={true}
|
||||
title="Add Strategy"
|
||||
/>,
|
||||
<react-mdl-Menu
|
||||
align="right"
|
||||
ripple={true}
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "rgb(247, 248, 255)",
|
||||
"maxHeight": "300px",
|
||||
"overflowY": "auto",
|
||||
}
|
||||
}
|
||||
target="strategies-add"
|
||||
valign="bottom"
|
||||
>
|
||||
<react-mdl-MenuItem
|
||||
disabled={true}
|
||||
>
|
||||
Add Strategy:
|
||||
</react-mdl-MenuItem>
|
||||
<react-mdl-MenuItem
|
||||
onClick={[Function]}
|
||||
title="Default on/off strategy."
|
||||
>
|
||||
default
|
||||
</react-mdl-MenuItem>
|
||||
</react-mdl-Menu>,
|
||||
],
|
||||
"style": Object {
|
||||
"display": "inline-block",
|
||||
"height": "25px",
|
||||
"position": "relative",
|
||||
"width": "25px",
|
||||
},
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"accent": true,
|
||||
"id": "strategies-add",
|
||||
"name": "add",
|
||||
"onClick": [Function],
|
||||
"raised": true,
|
||||
"title": "Add Strategy",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": null,
|
||||
"type": "react-mdl-IconButton",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"align": "right",
|
||||
"children": Array [
|
||||
<react-mdl-MenuItem
|
||||
disabled={true}
|
||||
>
|
||||
Add Strategy:
|
||||
</react-mdl-MenuItem>,
|
||||
Array [
|
||||
<react-mdl-MenuItem
|
||||
onClick={[Function]}
|
||||
title="Default on/off strategy."
|
||||
>
|
||||
default
|
||||
</react-mdl-MenuItem>,
|
||||
],
|
||||
],
|
||||
"ripple": true,
|
||||
"style": Object {
|
||||
"backgroundColor": "rgb(247, 248, 255)",
|
||||
"maxHeight": "300px",
|
||||
"overflowY": "auto",
|
||||
},
|
||||
"target": "strategies-add",
|
||||
"valign": "bottom",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": Array [
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": undefined,
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": "Add Strategy:",
|
||||
"disabled": true,
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": "Add Strategy:",
|
||||
"type": "react-mdl-MenuItem",
|
||||
},
|
||||
Object {
|
||||
"instance": null,
|
||||
"key": "default",
|
||||
"nodeType": "host",
|
||||
"props": Object {
|
||||
"children": "default",
|
||||
"onClick": [Function],
|
||||
"title": "Default on/off strategy.",
|
||||
},
|
||||
"ref": null,
|
||||
"rendered": "default",
|
||||
"type": "react-mdl-MenuItem",
|
||||
},
|
||||
],
|
||||
"type": "react-mdl-Menu",
|
||||
},
|
||||
],
|
||||
"type": "div",
|
||||
},
|
||||
],
|
||||
Symbol(enzyme.__options__): Object {
|
||||
"adapter": ReactSixteenAdapter {
|
||||
"options": Object {
|
||||
"enableComponentDidUpdateOnSetState": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`;
|
@ -0,0 +1,103 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders strategy with empty list as param 1`] = `
|
||||
<div>
|
||||
<p>
|
||||
featureName
|
||||
</p>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"display": "flex",
|
||||
}
|
||||
}
|
||||
>
|
||||
<react-mdl-Textfield
|
||||
floatingLabel={true}
|
||||
label="Add list entry"
|
||||
name="featureName_input"
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"flex": 1,
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<react-mdl-IconButton
|
||||
name="add"
|
||||
onClick={[Function]}
|
||||
raised={true}
|
||||
style={
|
||||
Object {
|
||||
"flex": 1,
|
||||
"flexGrow": 0,
|
||||
"margin": "20px 0 0 10px",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders strategy with list as param 1`] = `
|
||||
<div>
|
||||
<p>
|
||||
featureName
|
||||
</p>
|
||||
<react-mdl-Chip
|
||||
onClose={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"marginRight": "3px",
|
||||
}
|
||||
}
|
||||
>
|
||||
item1
|
||||
</react-mdl-Chip>
|
||||
<react-mdl-Chip
|
||||
onClose={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"marginRight": "3px",
|
||||
}
|
||||
}
|
||||
>
|
||||
item2
|
||||
</react-mdl-Chip>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"display": "flex",
|
||||
}
|
||||
}
|
||||
>
|
||||
<react-mdl-Textfield
|
||||
floatingLabel={true}
|
||||
label="Add list entry"
|
||||
name="featureName_input"
|
||||
onBlur={[Function]}
|
||||
onFocus={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"flex": 1,
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<react-mdl-IconButton
|
||||
name="add"
|
||||
onClick={[Function]}
|
||||
raised={true}
|
||||
style={
|
||||
Object {
|
||||
"flex": 1,
|
||||
"flexGrow": 0,
|
||||
"margin": "20px 0 0 10px",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
@ -0,0 +1,124 @@
|
||||
import React from 'react';
|
||||
import AddFeatureComponent from './../form-add-feature-component';
|
||||
import { shallow } from 'enzyme/build/index';
|
||||
|
||||
jest.mock('react-mdl');
|
||||
jest.mock('../strategies-section-container', () => 'StrategiesSection');
|
||||
|
||||
it('render the create feature page', () => {
|
||||
let input = {
|
||||
name: 'feature',
|
||||
nameError: {},
|
||||
description: 'Description',
|
||||
enabled: false,
|
||||
};
|
||||
const tree = shallow(
|
||||
<AddFeatureComponent
|
||||
input={input}
|
||||
onSubmit={jest.fn()}
|
||||
setValue={jest.fn()}
|
||||
addStrategy={jest.fn()}
|
||||
removeStrategy={jest.fn()}
|
||||
moveStrategy={jest.fn()}
|
||||
onCancel={jest.fn()}
|
||||
updateStrategy={jest.fn()}
|
||||
validateName={jest.fn()}
|
||||
initCallRequired={false}
|
||||
title="title"
|
||||
/>
|
||||
);
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
|
||||
let input = {
|
||||
name: 'feature',
|
||||
nameError: {},
|
||||
description: 'Description',
|
||||
enabled: false,
|
||||
};
|
||||
|
||||
let validateName = jest.fn();
|
||||
let setValue = jest.fn();
|
||||
let onSubmit = jest.fn();
|
||||
let addStrategy = jest.fn();
|
||||
let removeStrategy = jest.fn();
|
||||
let moveStrategy = jest.fn();
|
||||
let onCancel = jest.fn();
|
||||
let updateStratgy = jest.fn();
|
||||
let init = jest.fn();
|
||||
let eventMock = {
|
||||
preventDefault: () => {},
|
||||
stopPropagation: () => {},
|
||||
target: {
|
||||
name: 'NAME',
|
||||
},
|
||||
};
|
||||
const buildComponent = (setValue, validateName) => (
|
||||
<AddFeatureComponent
|
||||
input={input}
|
||||
onSubmit={onSubmit}
|
||||
setValue={setValue}
|
||||
addStrategy={addStrategy}
|
||||
removeStrategy={removeStrategy}
|
||||
moveStrategy={moveStrategy}
|
||||
onCancel={onCancel}
|
||||
updateStrategy={updateStratgy}
|
||||
validateName={validateName}
|
||||
initCallRequired
|
||||
title="title"
|
||||
init={init}
|
||||
/>
|
||||
);
|
||||
|
||||
it('add a feature name with validation', () => {
|
||||
let called = false;
|
||||
validateName = () => {
|
||||
called = true;
|
||||
};
|
||||
const wrapper = shallow(buildComponent(setValue, validateName));
|
||||
wrapper
|
||||
.find('react-mdl-Textfield')
|
||||
.first()
|
||||
.simulate('blur', eventMock);
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
|
||||
it('set a value for feature name', () => {
|
||||
let called = false;
|
||||
setValue = () => {
|
||||
called = true;
|
||||
};
|
||||
let wrapper = shallow(buildComponent(setValue, validateName));
|
||||
wrapper
|
||||
.find('react-mdl-Textfield')
|
||||
.first()
|
||||
.simulate('change', eventMock);
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
|
||||
it('set a description for feature name', () => {
|
||||
let called = false;
|
||||
setValue = () => {
|
||||
called = true;
|
||||
};
|
||||
let wrapper = shallow(buildComponent(setValue, validateName));
|
||||
wrapper
|
||||
.find('react-mdl-Textfield')
|
||||
.last()
|
||||
.simulate('change', eventMock);
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
|
||||
it('switch the toggle', () => {
|
||||
let called = false;
|
||||
setValue = () => {
|
||||
called = true;
|
||||
};
|
||||
let wrapper = shallow(buildComponent(setValue, validateName));
|
||||
eventMock.target.enabled = false;
|
||||
wrapper
|
||||
.find('react-mdl-Switch')
|
||||
.last()
|
||||
.simulate('change', eventMock);
|
||||
expect(called).toBe(true);
|
||||
});
|
@ -0,0 +1,31 @@
|
||||
import React from 'react';
|
||||
import UpdateFeatureComponent from './../form-update-feature-component';
|
||||
import { shallow } from 'enzyme/build/index';
|
||||
|
||||
jest.mock('react-mdl');
|
||||
jest.mock('../strategies-section-container', () => 'StrategiesSection');
|
||||
|
||||
it('render the create feature page', () => {
|
||||
let input = {
|
||||
name: 'feature',
|
||||
nameError: {},
|
||||
description: 'Description',
|
||||
enabled: false,
|
||||
};
|
||||
const tree = shallow(
|
||||
<UpdateFeatureComponent
|
||||
input={input}
|
||||
onSubmit={jest.fn()}
|
||||
setValue={jest.fn()}
|
||||
addStrategy={jest.fn()}
|
||||
removeStrategy={jest.fn()}
|
||||
moveStrategy={jest.fn()}
|
||||
onCancel={jest.fn()}
|
||||
updateStrategy={jest.fn()}
|
||||
validateName={jest.fn()}
|
||||
initCallRequired={false}
|
||||
title="title"
|
||||
/>
|
||||
);
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import AddStrategy from './../strategies-add';
|
||||
import { shallow } from 'enzyme/build/index';
|
||||
|
||||
jest.mock('react-mdl');
|
||||
|
||||
const strategies = [
|
||||
{
|
||||
name: 'default',
|
||||
editable: false,
|
||||
description: 'Default on/off strategy.',
|
||||
parameters: ['t'],
|
||||
},
|
||||
];
|
||||
let addStrategy = jest.fn();
|
||||
let fetchStrategies = jest.fn();
|
||||
let eventMock = {
|
||||
preventDefault: () => {},
|
||||
stopPropagation: () => {},
|
||||
target: {
|
||||
name: 'default',
|
||||
},
|
||||
};
|
||||
const buildComponent = (addStrategy, fetchStrategies, strategies) => (
|
||||
<AddStrategy addStrategy={addStrategy} fetchStrategies={fetchStrategies} strategies={strategies} />
|
||||
);
|
||||
|
||||
it('renders add strategy form with a list of available strategies', () => {
|
||||
const tree = shallow(buildComponent(addStrategy, fetchStrategies, strategies));
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('add a strategy', () => {
|
||||
let called = false;
|
||||
addStrategy = () => {
|
||||
called = true;
|
||||
};
|
||||
const addStrategyProto = jest.spyOn(AddStrategy.prototype, 'addStrategy');
|
||||
const wrapper = shallow(buildComponent(addStrategy, fetchStrategies, strategies));
|
||||
wrapper
|
||||
.find('react-mdl-MenuItem')
|
||||
.last()
|
||||
.simulate('click', eventMock);
|
||||
expect(called).toBe(true);
|
||||
expect(addStrategyProto).toHaveBeenCalled();
|
||||
});
|
@ -0,0 +1,81 @@
|
||||
import React from 'react';
|
||||
import InputList from './../strategy-input-list';
|
||||
import renderer from 'react-test-renderer';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
it('renders strategy with list as param', () => {
|
||||
const list = ['item1', 'item2'];
|
||||
const name = 'featureName';
|
||||
const tree = renderer.create(<InputList list={list} name={name} setConfig={jest.fn()} />);
|
||||
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders strategy with empty list as param', () => {
|
||||
const list = [];
|
||||
const name = 'featureName';
|
||||
const tree = renderer.create(<InputList list={list} name={name} setConfig={jest.fn()} />);
|
||||
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders an item as chip', () => {
|
||||
let list = ['item1'];
|
||||
const name = 'featureName';
|
||||
let wrapper = shallow(<InputList list={list} name={name} setConfig={jest.fn()} />);
|
||||
expect(wrapper.find('react-mdl-Chip').length).toEqual(1);
|
||||
expect(wrapper.find('react-mdl-Chip').text()).toEqual('item1');
|
||||
});
|
||||
|
||||
it('go inside onFocus', () => {
|
||||
let list = ['item1'];
|
||||
const name = 'featureName';
|
||||
const wrapper = shallow(<InputList list={list} name={name} setConfig={jest.fn()} />);
|
||||
let focusMock = {
|
||||
preventDefault: () => {},
|
||||
stopPropagation: () => {},
|
||||
key: 'e',
|
||||
};
|
||||
wrapper.find('react-mdl-Textfield').simulate('focus', focusMock);
|
||||
});
|
||||
|
||||
// https://github.com/airbnb/enzyme/issues/944
|
||||
it('spy onFocus', () => {
|
||||
let list = ['item1'];
|
||||
const name = 'featureName';
|
||||
const onFocus = jest.spyOn(InputList.prototype, 'onFocus');
|
||||
let focusMock = {
|
||||
preventDefault: () => {},
|
||||
stopPropagation: () => {},
|
||||
key: 'e',
|
||||
};
|
||||
const wrapper = shallow(<InputList list={list} name={name} setConfig={jest.fn()} />);
|
||||
wrapper.find('react-mdl-Textfield').simulate('focus', focusMock);
|
||||
expect(onFocus).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('spy onBlur', () => {
|
||||
let list = ['item1'];
|
||||
const name = 'featureName';
|
||||
const onFocus = jest.spyOn(InputList.prototype, 'onBlur');
|
||||
let focusMock = {
|
||||
preventDefault: () => {},
|
||||
stopPropagation: () => {},
|
||||
};
|
||||
const wrapper = shallow(<InputList list={list} name={name} setConfig={jest.fn()} />);
|
||||
wrapper.find('react-mdl-Textfield').simulate('blur', focusMock);
|
||||
expect(onFocus).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('spy onClose', () => {
|
||||
let list = ['item1'];
|
||||
const name = 'featureName';
|
||||
const onClose = jest.spyOn(InputList.prototype, 'onClose');
|
||||
let closeMock = {
|
||||
preventDefault: () => {},
|
||||
stopPropagation: () => {},
|
||||
};
|
||||
const wrapper = shallow(<InputList list={list} name={name} setConfig={jest.fn()} />);
|
||||
wrapper.find('react-mdl-Chip').simulate('close', closeMock);
|
||||
expect(onClose).toHaveBeenCalled();
|
||||
});
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
||||
import { Textfield, Switch } from 'react-mdl';
|
||||
import StrategiesSection from './strategies-section-container';
|
||||
|
||||
import { FormButtons } from '../../common';
|
||||
import { FormButtons } from './../../common';
|
||||
|
||||
const trim = value => {
|
||||
if (value && value.trim) {
|
||||
@ -13,7 +13,8 @@ const trim = value => {
|
||||
}
|
||||
};
|
||||
|
||||
class AddFeatureToggleComponent extends Component {
|
||||
class AddFeatureComponent extends Component {
|
||||
// static displayName = `AddFeatureComponent-${getDisplayName(Component)}`;
|
||||
componentWillMount() {
|
||||
// TODO unwind this stuff
|
||||
if (this.props.initCallRequired === true) {
|
||||
@ -32,7 +33,6 @@ class AddFeatureToggleComponent extends Component {
|
||||
moveStrategy,
|
||||
onSubmit,
|
||||
onCancel,
|
||||
editmode = false,
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
@ -50,14 +50,12 @@ class AddFeatureToggleComponent extends Component {
|
||||
floatingLabel
|
||||
label="Name"
|
||||
name="name"
|
||||
disabled={editmode}
|
||||
required
|
||||
value={name}
|
||||
error={nameError}
|
||||
onBlur={v => validateName(v.target.value)}
|
||||
onChange={v => setValue('name', trim(v.target.value))}
|
||||
/>
|
||||
<br />
|
||||
<Textfield
|
||||
floatingLabel
|
||||
style={{ width: '100%' }}
|
||||
@ -67,21 +65,19 @@ class AddFeatureToggleComponent extends Component {
|
||||
value={description}
|
||||
onChange={v => setValue('description', v.target.value)}
|
||||
/>
|
||||
<div>
|
||||
<br />
|
||||
<Switch
|
||||
checked={enabled}
|
||||
onChange={() => {
|
||||
setValue('enabled', !enabled);
|
||||
}}
|
||||
>
|
||||
Enabled
|
||||
</Switch>
|
||||
<hr />
|
||||
</div>
|
||||
|
||||
{!editmode && (
|
||||
<div>
|
||||
<br />
|
||||
<Switch
|
||||
checked={enabled}
|
||||
onChange={() => {
|
||||
setValue('enabled', !enabled);
|
||||
}}
|
||||
>
|
||||
Enabled
|
||||
</Switch>
|
||||
<hr />
|
||||
</div>
|
||||
)}
|
||||
<StrategiesSection
|
||||
configuredStrategies={configuredStrategies}
|
||||
addStrategy={addStrategy}
|
||||
@ -91,14 +87,14 @@ class AddFeatureToggleComponent extends Component {
|
||||
/>
|
||||
|
||||
<br />
|
||||
<FormButtons submitText={editmode ? 'Update' : 'Create'} onCancel={onCancel} />
|
||||
<FormButtons submitText={'Create'} onCancel={onCancel} />
|
||||
</section>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AddFeatureToggleComponent.propTypes = {
|
||||
AddFeatureComponent.propTypes = {
|
||||
input: PropTypes.object,
|
||||
setValue: PropTypes.func.isRequired,
|
||||
addStrategy: PropTypes.func.isRequired,
|
||||
@ -108,9 +104,8 @@ AddFeatureToggleComponent.propTypes = {
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
onCancel: PropTypes.func.isRequired,
|
||||
validateName: PropTypes.func.isRequired,
|
||||
editmode: PropTypes.bool,
|
||||
initCallRequired: PropTypes.bool,
|
||||
init: PropTypes.func,
|
||||
};
|
||||
|
||||
export default AddFeatureToggleComponent;
|
||||
export default AddFeatureComponent;
|
@ -1,8 +1,8 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { hashHistory } from 'react-router';
|
||||
import { createFeatureToggles, validateName } from '../../store/feature-actions';
|
||||
import { createMapper, createActions } from '../input-helpers';
|
||||
import FormAddComponent from './form-add-component';
|
||||
import { createFeatureToggles, validateName } from './../../../store/feature-actions';
|
||||
import { createMapper, createActions } from './../../input-helpers';
|
||||
import AddFeatureComponent from './form-add-feature-component';
|
||||
|
||||
const ID = 'add-feature-toggle';
|
||||
const mapStateToProps = createMapper({
|
||||
@ -31,7 +31,7 @@ const prepare = (methods, dispatch) => {
|
||||
|
||||
createFeatureToggles(input)(dispatch)
|
||||
.then(() => methods.clear())
|
||||
.then(() => hashHistory.push(`/features/edit/${input.name}`));
|
||||
.then(() => hashHistory.push(`/features/strategies/${input.name}`));
|
||||
};
|
||||
|
||||
methods.onCancel = evt => {
|
||||
@ -67,6 +67,6 @@ const prepare = (methods, dispatch) => {
|
||||
};
|
||||
const actions = createActions({ id: ID, prepare });
|
||||
|
||||
const FormAddContainer = connect(mapStateToProps, actions)(FormAddComponent);
|
||||
const FormAddContainer = connect(mapStateToProps, actions)(AddFeatureComponent);
|
||||
|
||||
export default FormAddContainer;
|
@ -0,0 +1,57 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import StrategiesSection from './strategies-section-container';
|
||||
|
||||
import { FormButtons } from './../../common';
|
||||
|
||||
class UpdateFeatureComponent extends Component {
|
||||
// static displayName = `UpdateFeatureComponent-{getDisplayName(Component)}`;
|
||||
componentWillMount() {
|
||||
// TODO unwind this stuff
|
||||
if (this.props.initCallRequired === true) {
|
||||
this.props.init(this.props.input);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { input, addStrategy, removeStrategy, updateStrategy, moveStrategy, onSubmit, onCancel } = this.props;
|
||||
|
||||
const {
|
||||
name, // eslint-disable-line
|
||||
} = input;
|
||||
const configuredStrategies = input.strategies || [];
|
||||
|
||||
return (
|
||||
<form onSubmit={onSubmit(input)}>
|
||||
<section style={{ padding: '16px' }}>
|
||||
<StrategiesSection
|
||||
configuredStrategies={configuredStrategies}
|
||||
addStrategy={addStrategy}
|
||||
updateStrategy={updateStrategy}
|
||||
moveStrategy={moveStrategy}
|
||||
removeStrategy={removeStrategy}
|
||||
/>
|
||||
|
||||
<br />
|
||||
<FormButtons submitText={'Update'} onCancel={onCancel} />
|
||||
</section>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateFeatureComponent.propTypes = {
|
||||
input: PropTypes.object,
|
||||
setValue: PropTypes.func.isRequired,
|
||||
addStrategy: PropTypes.func.isRequired,
|
||||
removeStrategy: PropTypes.func.isRequired,
|
||||
moveStrategy: PropTypes.func.isRequired,
|
||||
updateStrategy: PropTypes.func.isRequired,
|
||||
onSubmit: PropTypes.func.isRequired,
|
||||
onCancel: PropTypes.func.isRequired,
|
||||
validateName: PropTypes.func.isRequired,
|
||||
initCallRequired: PropTypes.bool,
|
||||
init: PropTypes.func,
|
||||
};
|
||||
|
||||
export default UpdateFeatureComponent;
|
@ -1,9 +1,9 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { hashHistory } from 'react-router';
|
||||
|
||||
import { requestUpdateFeatureToggle } from '../../store/feature-actions';
|
||||
import { createMapper, createActions } from '../input-helpers';
|
||||
import FormComponent from './form';
|
||||
import { requestUpdateFeatureToggle } from '../../../store/feature-actions';
|
||||
import { createMapper, createActions } from '../../input-helpers';
|
||||
import UpdateFeatureToggleComponent from './form-update-feature-component';
|
||||
|
||||
const ID = 'edit-feature-toggle';
|
||||
function getId(props) {
|
||||
@ -34,10 +34,12 @@ const prepare = (methods, dispatch) => {
|
||||
delete s.id;
|
||||
});
|
||||
}
|
||||
delete input.description;
|
||||
|
||||
// TODO: should add error handling
|
||||
requestUpdateFeatureToggle(input)(dispatch)
|
||||
.then(() => methods.clear())
|
||||
.then(() => hashHistory.push(`/features/view/${input.name}`));
|
||||
.then(() => hashHistory.push(`/features`));
|
||||
};
|
||||
|
||||
methods.onCancel = evt => {
|
||||
@ -73,4 +75,4 @@ const actions = createActions({
|
||||
prepare,
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, actions)(FormComponent);
|
||||
export default connect(mapStateToProps, actions)(UpdateFeatureToggleComponent);
|
@ -9,7 +9,7 @@ class AddStrategy extends React.Component {
|
||||
fetchStrategies: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
addStrategy = strategyName => {
|
||||
addStrategy(strategyName) {
|
||||
const selectedStrategy = this.props.strategies.find(s => s.name === strategyName);
|
||||
const parameters = {};
|
||||
|
||||
@ -21,7 +21,7 @@ class AddStrategy extends React.Component {
|
||||
name: selectedStrategy.name,
|
||||
parameters,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
stopPropagation(e) {
|
||||
e.stopPropagation();
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { connect } from 'react-redux';
|
||||
import StrategiesSection from './strategies-section';
|
||||
import StrategiesSectionComponent from './strategies-section';
|
||||
import { fetchStrategies } from '../../../store/strategy/actions';
|
||||
|
||||
export default connect(
|
||||
const StrategiesSection = connect(
|
||||
state => ({
|
||||
strategies: state.strategies.get('list').toArray(),
|
||||
}),
|
||||
{ fetchStrategies }
|
||||
)(StrategiesSection);
|
||||
)(StrategiesSectionComponent);
|
||||
export default StrategiesSection;
|
||||
|
@ -5,7 +5,7 @@ import StrategiesList from './strategies-list';
|
||||
import AddStrategy from './strategies-add';
|
||||
import { HeaderTitle } from '../../common';
|
||||
|
||||
class StrategiesSection extends React.Component {
|
||||
class StrategiesSectionComponent extends React.Component {
|
||||
static propTypes = {
|
||||
strategies: PropTypes.array.isRequired,
|
||||
addStrategy: PropTypes.func.isRequired,
|
||||
@ -32,4 +32,4 @@ class StrategiesSection extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default StrategiesSection;
|
||||
export default StrategiesSectionComponent;
|
||||
|
@ -9,16 +9,16 @@ export default class InputList extends Component {
|
||||
setConfig: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
onBlur = e => {
|
||||
onBlur(e) {
|
||||
this.setValue(e);
|
||||
window.removeEventListener('keydown', this.onKeyHandler, false);
|
||||
};
|
||||
}
|
||||
|
||||
onFocus = e => {
|
||||
onFocus(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
window.addEventListener('keydown', this.onKeyHandler, false);
|
||||
};
|
||||
}
|
||||
|
||||
onKeyHandler = e => {
|
||||
if (e.key === 'Enter') {
|
||||
@ -35,10 +35,9 @@ export default class InputList extends Component {
|
||||
}
|
||||
|
||||
const { name, list, setConfig } = this.props;
|
||||
const inputValue = this.refs.input.inputRef;
|
||||
if (inputValue && inputValue.value) {
|
||||
list.push(inputValue.value);
|
||||
inputValue.value = '';
|
||||
if (this.textInput && this.textInput.inputRef && this.textInput.inputRef.value) {
|
||||
list.push(this.textInput.inputRef.value);
|
||||
this.textInput.inputRef.value = '';
|
||||
setConfig(name, list.join(','));
|
||||
}
|
||||
};
|
||||
@ -66,9 +65,11 @@ export default class InputList extends Component {
|
||||
style={{ width: '100%', flex: 1 }}
|
||||
floatingLabel
|
||||
label="Add list entry"
|
||||
onFocus={this.onFocus}
|
||||
onBlur={this.onBlur}
|
||||
ref="input"
|
||||
onFocus={this.onFocus.bind(this)}
|
||||
onBlur={this.onBlur.bind(this)}
|
||||
ref={input => {
|
||||
this.textInput = input;
|
||||
}}
|
||||
/>
|
||||
<IconButton
|
||||
name="add"
|
||||
|
@ -1,16 +1,16 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Tabs, Tab, ProgressBar, Button, Card, CardTitle, CardText, CardActions, Switch } from 'react-mdl';
|
||||
import { Tabs, Tab, ProgressBar, Button, Card, CardText, CardTitle, CardActions, Textfield, Switch } from 'react-mdl';
|
||||
import { hashHistory, Link } from 'react-router';
|
||||
|
||||
import HistoryComponent from '../history/history-list-toggle-container';
|
||||
import MetricComponent from './metric-container';
|
||||
import EditFeatureToggle from './form-edit-container.jsx';
|
||||
import EditFeatureToggle from './form/form-update-feature-container';
|
||||
import { styles as commonStyles } from '../common';
|
||||
|
||||
const TABS = {
|
||||
view: 0,
|
||||
edit: 1,
|
||||
strategies: 0,
|
||||
view: 1,
|
||||
history: 2,
|
||||
};
|
||||
|
||||
@ -26,6 +26,7 @@ export default class ViewFeatureToggleComponent extends React.Component {
|
||||
toggleFeature: PropTypes.func.isRequired,
|
||||
removeFeatureToggle: PropTypes.func.isRequired,
|
||||
fetchFeatureToggles: PropTypes.func.isRequired,
|
||||
editFeatureToggle: PropTypes.func.isRequired,
|
||||
featureToggle: PropTypes.object,
|
||||
};
|
||||
|
||||
@ -40,7 +41,7 @@ export default class ViewFeatureToggleComponent extends React.Component {
|
||||
|
||||
if (TABS[activeTab] === TABS.history) {
|
||||
return <HistoryComponent toggleName={featureToggleName} />;
|
||||
} else if (TABS[activeTab] === TABS.edit) {
|
||||
} else if (TABS[activeTab] === TABS.strategies) {
|
||||
return <EditFeatureToggle featureToggle={featureToggle} />;
|
||||
} else {
|
||||
return <MetricComponent featureToggle={featureToggle} />;
|
||||
@ -56,6 +57,7 @@ export default class ViewFeatureToggleComponent extends React.Component {
|
||||
featureToggle,
|
||||
features,
|
||||
activeTab,
|
||||
// setValue,
|
||||
featureToggleName,
|
||||
toggleFeature,
|
||||
removeFeatureToggle,
|
||||
@ -80,7 +82,7 @@ export default class ViewFeatureToggleComponent extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
const activeTabId = TABS[this.props.activeTab] ? TABS[this.props.activeTab] : TABS.view;
|
||||
const activeTabId = TABS[this.props.activeTab] ? TABS[this.props.activeTab] : TABS.strategies;
|
||||
const tabContent = this.getTabContent(activeTab);
|
||||
|
||||
const removeToggle = () => {
|
||||
@ -92,11 +94,37 @@ export default class ViewFeatureToggleComponent extends React.Component {
|
||||
hashHistory.push('/features');
|
||||
}
|
||||
};
|
||||
const updateFeatureToggle = () => {
|
||||
let feature = { ...featureToggle };
|
||||
if (Array.isArray(feature.strategies)) {
|
||||
feature.strategies.forEach(s => {
|
||||
delete s.id;
|
||||
});
|
||||
}
|
||||
|
||||
this.props.editFeatureToggle(feature);
|
||||
};
|
||||
const setValue = (v, event) => {
|
||||
featureToggle[v] = event.target.value;
|
||||
this.forceUpdate();
|
||||
};
|
||||
|
||||
return (
|
||||
<Card shadow={0} className={commonStyles.fullwidth} style={{ overflow: 'visible' }}>
|
||||
<CardTitle style={{ paddingTop: '24px', wordBreak: 'break-all' }}>{featureToggle.name}</CardTitle>
|
||||
<CardText>{featureToggle.description}</CardText>
|
||||
<CardText>
|
||||
<Textfield
|
||||
floatingLabel
|
||||
style={{ width: '100%' }}
|
||||
rows={1}
|
||||
label="Description"
|
||||
required
|
||||
value={featureToggle.description}
|
||||
onChange={v => setValue('description', v)}
|
||||
onBlur={updateFeatureToggle}
|
||||
/>
|
||||
</CardText>
|
||||
|
||||
<CardActions
|
||||
border
|
||||
style={{
|
||||
@ -125,8 +153,8 @@ export default class ViewFeatureToggleComponent extends React.Component {
|
||||
tabBarProps={{ style: { width: '100%' } }}
|
||||
className="mdl-color--grey-100"
|
||||
>
|
||||
<Tab onClick={() => this.goToTab('strategies', featureToggleName)}>Strategies</Tab>
|
||||
<Tab onClick={() => this.goToTab('view', featureToggleName)}>Metrics</Tab>
|
||||
<Tab onClick={() => this.goToTab('edit', featureToggleName)}>Edit</Tab>
|
||||
<Tab onClick={() => this.goToTab('history', featureToggleName)}>History</Tab>
|
||||
</Tabs>
|
||||
{tabContent}
|
||||
|
@ -1,6 +1,11 @@
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { fetchFeatureToggles, toggleFeature, removeFeatureToggle } from '../../store/feature-actions';
|
||||
import {
|
||||
fetchFeatureToggles,
|
||||
toggleFeature,
|
||||
removeFeatureToggle,
|
||||
editFeatureToggle,
|
||||
} from './../../store/feature-actions';
|
||||
|
||||
import ViewToggleComponent from './view-component';
|
||||
|
||||
@ -14,5 +19,6 @@ export default connect(
|
||||
fetchFeatureToggles,
|
||||
toggleFeature,
|
||||
removeFeatureToggle,
|
||||
editFeatureToggle,
|
||||
}
|
||||
)(ViewToggleComponent);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { connect } from 'react-redux';
|
||||
import HistoryComponent from './history-component';
|
||||
import { fetchHistory } from '../../store/history-actions';
|
||||
import { fetchHistory } from './../../store/history-actions';
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const history = state.history.get('list').toArray();
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { createMapper, createActions } from '../input-helpers';
|
||||
import { createStrategy } from '../../store/strategy/actions';
|
||||
import { createMapper, createActions } from './../input-helpers';
|
||||
import { createStrategy } from './../../store/strategy/actions';
|
||||
|
||||
import AddStrategy from './add-strategy';
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { connect } from 'react-redux';
|
||||
import StrategiesListComponent from './list-component.jsx';
|
||||
import { fetchStrategies, removeStrategy } from '../../store/strategy/actions';
|
||||
import { fetchStrategies, removeStrategy } from './../../store/strategy/actions';
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const list = state.strategies.get('list').toArray();
|
||||
|
@ -54,7 +54,7 @@ export default class StrategyDetails extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const activeTabId = TABS[this.props.activeTab] ? TABS[this.props.activeTab] : TABS.view;
|
||||
const activeTabId = TABS[this.props.activeTab] ? TABS[this.props.activeTab] : TABS.strategies;
|
||||
const strategy = this.props.strategy;
|
||||
if (!strategy) {
|
||||
return <ProgressBar indeterminate />;
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { connect } from 'react-redux';
|
||||
import ShowStrategy from './strategy-details-component';
|
||||
import { fetchStrategies } from '../../store/strategy/actions';
|
||||
import { fetchAll } from '../../store/application/actions';
|
||||
import { fetchFeatureToggles } from '../../store/feature-actions';
|
||||
import { fetchStrategies } from './../../store/strategy/actions';
|
||||
import { fetchAll } from './../../store/application/actions';
|
||||
import { fetchFeatureToggles } from './../../store/feature-actions';
|
||||
|
||||
const mapStateToProps = (state, props) => {
|
||||
let strategy = state.strategies.get('list').find(n => n.name === props.strategyName);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import AddFeatureToggleForm from '../../component/feature/form-add-container';
|
||||
import AddFeatureToggleForm from '../../component/feature/form/form-add-feature-container';
|
||||
|
||||
const render = () => <AddFeatureToggleForm title="Create feature toggle" />;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import FeatureListContainer from '../../component/feature/list-container';
|
||||
import FeatureListContainer from './../../component/feature/list-container';
|
||||
|
||||
const render = () => <FeatureListContainer />;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ViewFeatureToggle from '../../component/feature/view-container';
|
||||
import ViewFeatureToggle from './../../component/feature/view-container';
|
||||
|
||||
export default class Features extends PureComponent {
|
||||
static propTypes = {
|
||||
|
4
frontend/src/setupTests.js
Normal file
4
frontend/src/setupTests.js
Normal file
@ -0,0 +1,4 @@
|
||||
import { configure } from 'enzyme';
|
||||
import Adapter from 'enzyme-adapter-react-16';
|
||||
|
||||
configure({ adapter: new Adapter() });
|
Loading…
Reference in New Issue
Block a user