diff --git a/caravel/assets/javascripts/explorev2/actions/exploreActions.js b/caravel/assets/javascripts/explorev2/actions/exploreActions.js index 6b4bad7d3e13b..d836dd864bb44 100644 --- a/caravel/assets/javascripts/explorev2/actions/exploreActions.js +++ b/caravel/assets/javascripts/explorev2/actions/exploreActions.js @@ -17,7 +17,7 @@ export const CHANGE_FILTER_VALUE = 'CHANGE_FILTER_VALUE'; export const RESET_FORM_DATA = 'RESET_FORM_DATA'; export const CLEAR_ALL_OPTS = 'CLEAR_ALL_OPTS'; export const SET_DATASOURCE_TYPE = 'SET_DATASOURCE_TYPE'; -export const SET_FORM_DATA = 'SET_FORM_DATA'; +export const SET_FIELD_VALUE = 'SET_FIELD_VALUE'; export function setTimeColumnOpts(timeColumnOpts) { return { type: SET_TIME_COLUMN_OPTS, timeColumnOpts }; @@ -47,19 +47,10 @@ export function setFilterColumnOpts(filterColumnOpts) { return { type: SET_FILTER_COLUMN_OPTS, filterColumnOpts }; } -export function resetFormData() { - // Clear all form data when switching datasource - return { type: RESET_FORM_DATA }; -} - export function clearAllOpts() { return { type: CLEAR_ALL_OPTS }; } -export function setDatasourceType(datasourceType) { - return { type: SET_DATASOURCE_TYPE, datasourceType }; -} - export function setFormOpts(datasourceId, datasourceType) { return function (dispatch) { const timeColumnOpts = []; @@ -114,15 +105,6 @@ export function setFormOpts(datasourceId, datasourceType) { } }; } - -export function setDatasource(datasourceId) { - return { type: SET_DATASOURCE, datasourceId }; -} - -export function toggleSearchBox(searchBox) { - return { type: TOGGLE_SEARCHBOX, searchBox }; -} - export function addFilter(filter) { return { type: ADD_FILTER, filter }; } @@ -143,6 +125,6 @@ export function changeFilterValue(filter, value) { return { type: CHANGE_FILTER_VALUE, filter, value }; } -export function setFormData(key, value) { - return { type: SET_FORM_DATA, key, value }; +export function setFieldValue(key, value) { + return { type: SET_FIELD_VALUE, key, value }; } diff --git a/caravel/assets/javascripts/explorev2/components/ChartContainer.jsx b/caravel/assets/javascripts/explorev2/components/ChartContainer.jsx index 887738d2b803a..287836bffd0a8 100644 --- a/caravel/assets/javascripts/explorev2/components/ChartContainer.jsx +++ b/caravel/assets/javascripts/explorev2/components/ChartContainer.jsx @@ -6,12 +6,12 @@ import visMap from '../../../visualizations/main'; import { d3format } from '../../modules/utils'; const propTypes = { - sliceName: PropTypes.string.isRequired, - vizType: PropTypes.string.isRequired, + slice_name: PropTypes.string.isRequired, + viz_type: PropTypes.string.isRequired, height: PropTypes.string.isRequired, containerId: PropTypes.string.isRequired, - jsonEndpoint: PropTypes.string.isRequired, - columnFormats: PropTypes.object, + json_endpoint: PropTypes.string.isRequired, + column_formats: PropTypes.object, }; class ChartContainer extends React.Component { @@ -33,8 +33,7 @@ class ChartContainer extends React.Component { getMockedSliceObject() { return { containerId: this.props.containerId, - - jsonEndpoint: () => this.props.jsonEndpoint, + jsonEndpoint: () => this.props.json_endpoint, container: { html: (data) => { @@ -104,7 +103,7 @@ class ChartContainer extends React.Component { d3format: (col, number) => { // mock d3format function in Slice object in caravel.js - const format = this.props.columnFormats[col]; + const format = this.props.column_formats[col]; return d3format(format, number); }, }; @@ -112,7 +111,7 @@ class ChartContainer extends React.Component { renderVis() { const slice = this.getMockedSliceObject(); - visMap[this.props.vizType](slice).render(); + visMap[this.props.viz_type](slice).render(); } render() { @@ -125,14 +124,14 @@ class ChartContainer extends React.Component { id="slice-header" className="panel-title" > - {this.props.sliceName} + {this.props.slice_name} } >
{ this.chartContainerRef = ref; }} - className={this.props.vizType} + className={this.props.viz_type} />
@@ -144,11 +143,11 @@ ChartContainer.propTypes = propTypes; function mapStateToProps(state) { return { - sliceName: state.sliceName, - vizType: state.viz.formData.vizType, - containerId: `slice-container-${state.viz.formData.sliceId}`, - jsonEndpoint: state.viz.jsonEndPoint, - columnFormats: state.viz.columnFormats, + containerId: `slice-container-${state.viz.form_data.slice_id}`, + slice_name: state.viz.form_data.slice_name, + viz_type: state.viz.form_data.viz_type, + json_endpoint: state.viz.json_endpoint, + column_formats: state.viz.column_formats, }; } diff --git a/caravel/assets/javascripts/explorev2/components/CheckboxField.jsx b/caravel/assets/javascripts/explorev2/components/CheckboxField.jsx index 6398b6443b276..0996b90396c5e 100644 --- a/caravel/assets/javascripts/explorev2/components/CheckboxField.jsx +++ b/caravel/assets/javascripts/explorev2/components/CheckboxField.jsx @@ -3,21 +3,29 @@ import { Checkbox } from 'react-bootstrap'; import ControlLabelWithTooltip from './ControlLabelWithTooltip'; const propTypes = { + name: PropTypes.string.isRequired, label: PropTypes.string, description: PropTypes.string, + onChange: PropTypes.func, }; const defaultProps = { label: null, description: null, + onChange: () => {}, }; -export default function CheckboxField({ label, description }) { - return ( - - - - ); +export default class CheckboxField extends React.Component { + onToggle() { + this.props.onChange(this.props.name); + } + render() { + return ( + + + + ); + } } CheckboxField.propTypes = propTypes; diff --git a/caravel/assets/javascripts/explorev2/components/ControlPanelsContainer.jsx b/caravel/assets/javascripts/explorev2/components/ControlPanelsContainer.jsx index 04f25f9b2ea0e..7b2a8de9dc5a4 100644 --- a/caravel/assets/javascripts/explorev2/components/ControlPanelsContainer.jsx +++ b/caravel/assets/javascripts/explorev2/components/ControlPanelsContainer.jsx @@ -1,3 +1,4 @@ +/* eslint camelcase: 0 */ import React, { PropTypes } from 'react'; import { bindActionCreators } from 'redux'; import * as actions from '../actions/exploreActions'; @@ -8,26 +9,30 @@ import ControlPanelSection from './ControlPanelSection'; import FieldSetRow from './FieldSetRow'; const propTypes = { - vizType: PropTypes.string, - datasourceId: PropTypes.number.isRequired, - datasourceType: PropTypes.string.isRequired, + viz_type: PropTypes.string, + datasource_id: PropTypes.number.isRequired, + datasource_type: PropTypes.string.isRequired, actions: PropTypes.object.isRequired, }; const defaultProps = { - vizType: null, + viz_type: null, }; class ControlPanelsContainer extends React.Component { componentWillMount() { - const { datasourceId, datasourceType } = this.props; - if (datasourceId) { - this.props.actions.setFormOpts(datasourceId, datasourceType); + const { datasource_id, datasource_type } = this.props; + if (datasource_id) { + this.props.actions.setFormOpts(datasource_id, datasource_type); } } + onChange(name, value) { + this.props.actions.setFieldValue(name, value); + } + sectionsToRender() { - const viz = visTypes[this.props.vizType]; + const viz = visTypes[this.props.viz_type]; const { datasourceAndVizType, sqlClause } = commonControlPanelSections; const sectionsToRender = [datasourceAndVizType].concat(viz.controlPanelSections, sqlClause); @@ -35,7 +40,7 @@ class ControlPanelsContainer extends React.Component { } fieldOverrides() { - const viz = visTypes[this.props.vizType]; + const viz = visTypes[this.props.viz_type]; return viz.fieldOverrides; } @@ -55,6 +60,7 @@ class ControlPanelsContainer extends React.Component { key={`${section.label}-fieldSetRow-${i}`} fieldSets={fieldSets} fieldOverrides={this.fieldOverrides()} + onChange={this.onChange.bind(this)} /> ))} @@ -72,9 +78,9 @@ ControlPanelsContainer.defaultProps = defaultProps; function mapStateToProps(state) { return { - datasourceId: state.datasourceId, - datasourceType: state.datasourceType, - vizType: state.viz.formData.vizType, + datasource_id: state.datasource_id, + datasource_type: state.datasource_type, + viz_type: state.viz.form_data.viz_type, }; } diff --git a/caravel/assets/javascripts/explorev2/components/FieldSet.jsx b/caravel/assets/javascripts/explorev2/components/FieldSet.jsx index ef6f5659b32cd..0fbfdbfdc0795 100644 --- a/caravel/assets/javascripts/explorev2/components/FieldSet.jsx +++ b/caravel/assets/javascripts/explorev2/components/FieldSet.jsx @@ -6,12 +6,14 @@ import SelectField from './SelectField'; import { fieldTypes } from '../stores/store'; const propTypes = { + name: PropTypes.string.isRequired, type: PropTypes.oneOf(fieldTypes).isRequired, label: PropTypes.string.isRequired, choices: PropTypes.arrayOf(PropTypes.array), description: PropTypes.string, places: PropTypes.number, validators: PropTypes.any, + onChange: React.PropTypes.func, }; const defaultProps = { @@ -19,23 +21,36 @@ const defaultProps = { description: null, places: null, validators: null, + onChange: () => {}, }; export default class FieldSet extends React.Component { renderCheckBoxField() { - return ; + return ( + ); } renderTextAreaField() { - return ; + return ( + ); } renderSelectField() { - return ; + return ( + ); } renderTextField() { - return ; + return ( + ); } render() { diff --git a/caravel/assets/javascripts/explorev2/components/FieldSetRow.jsx b/caravel/assets/javascripts/explorev2/components/FieldSetRow.jsx index b699b0301b50e..8ab8b877db445 100644 --- a/caravel/assets/javascripts/explorev2/components/FieldSetRow.jsx +++ b/caravel/assets/javascripts/explorev2/components/FieldSetRow.jsx @@ -5,10 +5,12 @@ import { fields } from '../stores/store'; const propTypes = { fieldSets: PropTypes.array.isRequired, fieldOverrides: PropTypes.object, + onChange: PropTypes.func, }; const defaultProps = { fieldOverrides: {}, + onChange: () => {}, }; function getFieldData(fs, fieldOverrides) { @@ -20,12 +22,15 @@ function getFieldData(fs, fieldOverrides) { return fieldData; } -export default function FieldSetRow({ fieldSets, fieldOverrides }) { +export default function FieldSetRow({ fieldSets, fieldOverrides, onChange }) { return (
    {fieldSets.map((fs) => { const fieldData = getFieldData(fs, fieldOverrides); - return
  • ; + return ( +
  • +
    +
  • ); })}
); diff --git a/caravel/assets/javascripts/explorev2/components/SelectField.jsx b/caravel/assets/javascripts/explorev2/components/SelectField.jsx index 6cbd09ac7792d..c50e0cdf59fad 100644 --- a/caravel/assets/javascripts/explorev2/components/SelectField.jsx +++ b/caravel/assets/javascripts/explorev2/components/SelectField.jsx @@ -4,25 +4,40 @@ import ControlLabelWithTooltip from './ControlLabelWithTooltip'; import { slugify } from '../../modules/utils'; const propTypes = { + name: PropTypes.string.isRequired, label: PropTypes.string, description: PropTypes.string, + onChange: PropTypes.func, }; const defaultProps = { label: null, description: null, + onChange: () => {}, }; -export default function SelectField({ label, description }) { - return ( - - - - - - - - ); +export default class SelectField extends React.Component { + onChange(opt) { + this.props.onChange(this.props.name, opt.target.value); + } + render() { + return ( + + + + + + + + ); + } } SelectField.propTypes = propTypes; diff --git a/caravel/assets/javascripts/explorev2/components/TextAreaField.jsx b/caravel/assets/javascripts/explorev2/components/TextAreaField.jsx index 42c8a0089cc35..761ab70f47071 100644 --- a/caravel/assets/javascripts/explorev2/components/TextAreaField.jsx +++ b/caravel/assets/javascripts/explorev2/components/TextAreaField.jsx @@ -3,22 +3,34 @@ import { FormGroup, FormControl } from 'react-bootstrap'; import ControlLabelWithTooltip from './ControlLabelWithTooltip'; const propTypes = { + name: PropTypes.string.isRequired, label: PropTypes.string, description: PropTypes.string, + onChange: PropTypes.func, }; const defaultProps = { label: null, description: null, + onChange: () => {}, }; -export default function TextAreaField({ label, description }) { - return ( - - - - - ); +export default class TextAreaField extends React.Component { + onChange(event) { + this.props.onChange(this.props.name, event.target.value); + } + render() { + return ( + + + + + ); + } } TextAreaField.propTypes = propTypes; diff --git a/caravel/assets/javascripts/explorev2/components/TextField.jsx b/caravel/assets/javascripts/explorev2/components/TextField.jsx index b562f622f8117..65f44f4c67e62 100644 --- a/caravel/assets/javascripts/explorev2/components/TextField.jsx +++ b/caravel/assets/javascripts/explorev2/components/TextField.jsx @@ -3,22 +3,33 @@ import { FormGroup, FormControl } from 'react-bootstrap'; import ControlLabelWithTooltip from './ControlLabelWithTooltip'; const propTypes = { + name: PropTypes.string.isRequired, label: PropTypes.string, description: PropTypes.string, + onChange: PropTypes.func, }; const defaultProps = { label: null, description: null, + onChange: () => {}, }; -export default function TextField({ label, description }) { - return ( - - - - - ); +export default class TextField extends React.Component { + onChange(event) { + this.props.onChange(this.props.name, event.target.value); + } + render() { + return ( + + + + + ); + } } TextField.propTypes = propTypes; diff --git a/caravel/assets/javascripts/explorev2/index.jsx b/caravel/assets/javascripts/explorev2/index.jsx index b26857bb22fcf..73fef9878f541 100644 --- a/caravel/assets/javascripts/explorev2/index.jsx +++ b/caravel/assets/javascripts/explorev2/index.jsx @@ -14,27 +14,9 @@ import { exploreReducer } from './reducers/exploreReducer'; const bootstrappedState = Object.assign(initialState, { datasources: bootstrapData.datasources, - datasourceId: parseInt(bootstrapData.datasource_id, 10), - datasourceType: bootstrapData.datasource_type, - sliceName: bootstrapData.viz.form_data.slice_name, - viz: { - jsonEndPoint: bootstrapData.viz.json_endpoint, - data: bootstrapData.viz.data, - columnFormats: bootstrapData.viz.column_formats, - formData: { - sliceId: bootstrapData.viz.form_data.slice_id, - vizType: bootstrapData.viz.form_data.viz_type, - timeColumn: bootstrapData.viz.form_data.granularity_sqla, - timeGrain: bootstrapData.viz.form_data.time_grain_sqla, - metrics: [bootstrapData.viz.form_data.metrics].map((m) => ({ value: m, label: m })), - since: bootstrapData.viz.form_data.since, - until: bootstrapData.viz.form_data.until, - having: bootstrapData.viz.form_data.having, - where: bootstrapData.viz.form_data.where, - rowLimit: bootstrapData.viz.form_data.row_limit, - timeStampFormat: bootstrapData.viz.form_data.table_timestamp_format, - }, - }, + datasource_id: parseInt(bootstrapData.datasource_id, 10), + datasource_type: bootstrapData.datasource_type, + viz: bootstrapData.viz, }); const store = createStore(exploreReducer, bootstrappedState, compose(applyMiddleware(thunk)) diff --git a/caravel/assets/javascripts/explorev2/reducers/exploreReducer.js b/caravel/assets/javascripts/explorev2/reducers/exploreReducer.js index 8ff9b361cb681..93d7fe5f09bb6 100644 --- a/caravel/assets/javascripts/explorev2/reducers/exploreReducer.js +++ b/caravel/assets/javascripts/explorev2/reducers/exploreReducer.js @@ -1,31 +1,9 @@ -import { defaultFormData, defaultOpts } from '../stores/store'; +import { defaultOpts } from '../stores/store'; import * as actions from '../actions/exploreActions'; import { addToArr, removeFromArr, alterInArr } from '../../../utils/reducerUtils'; -const setFormInViz = function (state, action) { - const newFormData = Object.assign({}, state); - newFormData[action.key] = action.value; - return newFormData; -}; - -const setVizInState = function (state, action) { - switch (action.type) { - case actions.SET_FORM_DATA: - return Object.assign( - {}, - state, - { formData: setFormInViz(state.formData, action) } - ); - default: - return state; - } -}; - export const exploreReducer = function (state, action) { const actionHandlers = { - [actions.SET_DATASOURCE]() { - return Object.assign({}, state, { datasourceId: action.datasourceId }); - }, [actions.SET_TIME_COLUMN_OPTS]() { return Object.assign({}, state, { timeColumnOpts: action.timeColumnOpts }); }, @@ -44,9 +22,6 @@ export const exploreReducer = function (state, action) { [actions.SET_ORDERING_OPTS]() { return Object.assign({}, state, { orderingOpts: action.orderingOpts }); }, - [actions.TOGGLE_SEARCHBOX]() { - return Object.assign({}, state, { searchBox: action.searchBox }); - }, [actions.SET_FILTER_COLUMN_OPTS]() { return Object.assign({}, state, { filterColumnOpts: action.filterColumnOpts }); }, @@ -65,21 +40,14 @@ export const exploreReducer = function (state, action) { [actions.CHANGE_FILTER_VALUE]() { return alterInArr(state, 'filters', action.filter, { value: action.value }); }, - [actions.RESET_FORM_DATA]() { - return Object.assign({}, state, defaultFormData); - }, [actions.CLEAR_ALL_OPTS]() { return Object.assign({}, state, defaultOpts); }, - [actions.SET_DATASOURCE_TYPE]() { - return Object.assign({}, state, { datasourceType: action.datasourceType }); - }, - [actions.SET_FORM_DATA]() { - return Object.assign( - {}, - state, - { viz: setVizInState(state.viz, action) } - ); + [actions.SET_FIELD_VALUE]() { + const newState = Object.assign({}, state); + newState.viz.form_data[action.key] = + action.value ? action.value : (!state.viz.form_data[action.key]); + return newState; }, }; if (action.type in actionHandlers) { diff --git a/caravel/assets/javascripts/explorev2/stores/store.js b/caravel/assets/javascripts/explorev2/stores/store.js index 14b6fbbbe4cfb..d5db2f9c17fe9 100644 --- a/caravel/assets/javascripts/explorev2/stores/store.js +++ b/caravel/assets/javascripts/explorev2/stores/store.js @@ -11,60 +11,6 @@ export const fieldTypes = [ 'TextField', ]; -// TODO: add datasource_type here after druid support is added -export const defaultFormData = { - sliceId: null, - vizType: null, - timeColumn: null, - timeGrain: null, - groupByColumns: [], - metrics: [], - since: null, - until: null, - having: null, - where: null, - columns: [], - orderings: [], - timeStampFormat: 'smart_date', - rowLimit: 50000, - searchBox: false, - whereClause: '', - havingClause: '', - filters: [], -}; - -export const initialState = { - datasources: null, - datasourceId: null, - datasourceType: null, - timeColumnOpts: [], - timeGrainOpts: [], - timeGrain: null, - groupByColumnOpts: [], - metricsOpts: [], - columnOpts: [], - orderingOpts: [], - searchBox: false, - whereClause: '', - havingClause: '', - filters: [], - filterColumnOpts: [], - viz: { - columnFormats: {}, - formData: defaultFormData, - }, -}; - -export const defaultOpts = { - timeColumnOpts: [], - timeGrainOpts: [], - groupByColumnOpts: [], - metricsOpts: [], - filterColumnOpts: [], - columnOpts: [], - orderingOpts: [], -}; - const D3_FORMAT_DOCS = 'D3 format syntax: https://github.com/d3/d3-format'; // input choices & options @@ -1082,7 +1028,7 @@ export const fields = { choices: [['granularity_sqla', 'granularity_sqla']], description: 'The time column for the visualization. Note that you ' + 'can define arbitrary expression that return a DATETIME ' + - 'column in the table editor. Also note that the ' + + 'column in the table or. Also note that the ' + 'filter below is applied against this column or ' + 'expression', }, @@ -1679,3 +1625,46 @@ export const fields = { description: 'The color for points and clusters in RGB', }, }; + +const defaultFormData = {}; +defaultFormData.slice_name = null; +defaultFormData.slice_id = null; +Object.keys(fields).forEach((k) => { defaultFormData[k] = fields[k].default; }); + +export const defaultViz = { + cached_key: null, + cached_timeout: null, + cached_dttm: null, + column_formats: null, + csv_endpoint: null, + is_cached: false, + data: [], + form_data: defaultFormData, + json_endpoint: null, + query: null, + standalone_endpoint: null, +}; + +export const initialState = { + datasources: null, + datasource_id: null, + datasource_type: null, + timeColumnOpts: [], + timeGrainOpts: [], + groupByColumnOpts: [], + metricsOpts: [], + columnOpts: [], + orderingOpts: [], + filterColumnOpts: [], + viz: defaultViz, +}; + +export const defaultOpts = { + timeColumnOpts: [], + timeGrainOpts: [], + groupByColumnOpts: [], + metricsOpts: [], + filterColumnOpts: [], + columnOpts: [], + orderingOpts: [], +}; diff --git a/caravel/assets/spec/javascripts/explore/components/actions_spec.js b/caravel/assets/spec/javascripts/explore/components/actions_spec.js deleted file mode 100644 index 808822c3b8bf3..0000000000000 --- a/caravel/assets/spec/javascripts/explore/components/actions_spec.js +++ /dev/null @@ -1,50 +0,0 @@ -import { it, describe } from 'mocha'; -import { expect } from 'chai'; -import shortid from 'shortid'; -import * as actions from '../../../../javascripts/explorev2/actions/exploreActions'; -import { initialState } from '../../../../javascripts/explorev2/stores/store'; -import { exploreReducer } from '../../../../javascripts/explorev2/reducers/exploreReducer'; - -describe('reducers', () => { - it('should return new state with datasource id', () => { - const newState = exploreReducer(initialState, actions.setDatasource(1)); - expect(newState.datasourceId).to.equal(1); - }); - - it('should return new state with search box toggled', () => { - const newState = exploreReducer(initialState, actions.toggleSearchBox(true)); - expect(newState.searchBox).to.equal(true); - }); - - it('should return new state with added filter', () => { - const newFilter = { - id: shortid.generate(), - eq: 'value', - op: 'in', - col: 'vals', - }; - const newState = exploreReducer(initialState, actions.addFilter(newFilter)); - expect(newState.filters).to.deep.equal([newFilter]); - }); - - it('should return new state with removed filter', () => { - const filter1 = { - id: shortid.generate(), - eq: 'value', - op: 'in', - col: 'vals1', - }; - const filter2 = { - id: shortid.generate(), - eq: 'value', - op: 'not in', - col: 'vals2', - }; - const testState = { - initialState, - filters: [filter1, filter2], - }; - const newState = exploreReducer(testState, actions.removeFilter(filter1)); - expect(newState.filters).to.deep.equal([filter2]); - }); -}); diff --git a/caravel/assets/spec/javascripts/explorev2/actions_spec.js b/caravel/assets/spec/javascripts/explorev2/actions_spec.js new file mode 100644 index 0000000000000..c674fdf519948 --- /dev/null +++ b/caravel/assets/spec/javascripts/explorev2/actions_spec.js @@ -0,0 +1,16 @@ +import { it, describe } from 'mocha'; +import { expect } from 'chai'; +import * as actions from '../../../javascripts/explorev2/actions/exploreActions'; +import { initialState } from '../../../javascripts/explorev2/stores/store'; +import { exploreReducer } from '../../../javascripts/explorev2/reducers/exploreReducer'; + +describe('reducers', () => { + it('sets correct field value given a key and value', () => { + const newState = exploreReducer(initialState, actions.setFieldValue('x_axis_label', 'x')); + expect(newState.viz.form_data.x_axis_label).to.equal('x'); + }); + it('toggles a boolean field value given only a key', () => { + const newState = exploreReducer(initialState, actions.setFieldValue('show_legend')); + expect(newState.viz.form_data.show_legend).to.equal(false); + }); +}); diff --git a/caravel/assets/spec/javascripts/explorev2/components/CheckboxField_spec.js b/caravel/assets/spec/javascripts/explorev2/components/CheckboxField_spec.js new file mode 100644 index 0000000000000..18a2ff9159a94 --- /dev/null +++ b/caravel/assets/spec/javascripts/explorev2/components/CheckboxField_spec.js @@ -0,0 +1,31 @@ +/* eslint-disable no-unused-expressions */ +import React from 'react'; +import { Checkbox } from 'react-bootstrap'; +import sinon from 'sinon'; +import { expect } from 'chai'; +import { describe, it, beforeEach } from 'mocha'; +import { shallow } from 'enzyme'; +import CheckboxField from '../../../../javascripts/explorev2/components/CheckboxField'; + +const defaultProps = { + name: 'show_legend', + onChange: sinon.spy(), +}; + +describe('CheckboxField', () => { + let wrapper; + + beforeEach(() => { + wrapper = shallow(); + }); + + it('renders a Checkbox', () => { + expect(wrapper.find(Checkbox)).to.have.lengthOf(1); + }); + + it('calls onChange when toggled', () => { + const checkbox = wrapper.find(Checkbox); + checkbox.simulate('change', { value: true }); + expect(defaultProps.onChange.calledWith('show_legend')).to.be.true; + }); +}); diff --git a/caravel/assets/spec/javascripts/explorev2/components/ControlPanelsContainer_spec.js b/caravel/assets/spec/javascripts/explorev2/components/ControlPanelsContainer_spec.js index 74eb50de34a01..924fb42b468b8 100644 --- a/caravel/assets/spec/javascripts/explorev2/components/ControlPanelsContainer_spec.js +++ b/caravel/assets/spec/javascripts/explorev2/components/ControlPanelsContainer_spec.js @@ -9,9 +9,9 @@ import { } from '../../../../javascripts/explorev2/components/ControlPanelsContainer'; const defaultProps = { - vizType: 'dist_bar', - datasourceId: 1, - datasourceType: 'type', + viz_type: 'dist_bar', + datasource_id: 1, + datasource_type: 'type', actions: { setFormOpts: () => { // noop diff --git a/caravel/assets/spec/javascripts/explorev2/components/SelectField_spec.js b/caravel/assets/spec/javascripts/explorev2/components/SelectField_spec.js new file mode 100644 index 0000000000000..7b22cf010f72b --- /dev/null +++ b/caravel/assets/spec/javascripts/explorev2/components/SelectField_spec.js @@ -0,0 +1,32 @@ +/* eslint-disable no-unused-expressions */ +import React from 'react'; +import { FormControl } from 'react-bootstrap'; +import sinon from 'sinon'; +import { expect } from 'chai'; +import { describe, it, beforeEach } from 'mocha'; +import { shallow } from 'enzyme'; +import SelectField from '../../../../javascripts/explorev2/components/SelectField'; + +const defaultProps = { + name: 'row_limit', + label: 'Row Limit', + onChange: sinon.spy(), +}; + +describe('SelectField', () => { + let wrapper; + + beforeEach(() => { + wrapper = shallow(); + }); + + it('renders a FormControl', () => { + expect(wrapper.find(FormControl)).to.have.lengthOf(1); + }); + + it('calls onChange when toggled', () => { + const select = wrapper.find(FormControl); + select.simulate('change', { target: { value: 50 } }); + expect(defaultProps.onChange.calledWith('row_limit', 50)).to.be.true; + }); +}); diff --git a/caravel/assets/spec/javascripts/explorev2/components/TextArea_spec.js b/caravel/assets/spec/javascripts/explorev2/components/TextArea_spec.js new file mode 100644 index 0000000000000..eb337ddd5ddc7 --- /dev/null +++ b/caravel/assets/spec/javascripts/explorev2/components/TextArea_spec.js @@ -0,0 +1,32 @@ +/* eslint-disable no-unused-expressions */ +import React from 'react'; +import { FormControl } from 'react-bootstrap'; +import sinon from 'sinon'; +import { expect } from 'chai'; +import { describe, it, beforeEach } from 'mocha'; +import { shallow } from 'enzyme'; +import TextAreaField from '../../../../javascripts/explorev2/components/TextAreaField'; + +const defaultProps = { + name: 'x_axis_label', + label: 'X Axis Label', + onChange: sinon.spy(), +}; + +describe('SelectField', () => { + let wrapper; + + beforeEach(() => { + wrapper = shallow(); + }); + + it('renders a FormControl', () => { + expect(wrapper.find(FormControl)).to.have.lengthOf(1); + }); + + it('calls onChange when toggled', () => { + const select = wrapper.find(FormControl); + select.simulate('change', { target: { value: 'x' } }); + expect(defaultProps.onChange.calledWith('x_axis_label', 'x')).to.be.true; + }); +});