Skip to content
This repository has been archived by the owner on Aug 3, 2022. It is now read-only.

Commit

Permalink
[#900] Fix merge of multiple choice options
Browse files Browse the repository at this point in the history
Fix merge of default options with options provided by an answer
(props.value passed to the component).
  • Loading branch information
brew committed Jan 20, 2017
1 parent 9da911d commit 55de449
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 11 deletions.
27 changes: 20 additions & 7 deletions census/ui_app/QuestionFields.jsx
Expand Up @@ -440,14 +440,14 @@ const QuestionFieldMultipleChoiceOther = props => {
let QuestionFieldMultipleChoice = React.createClass({
getDefaultOptionValuesForOptionList(optionList) {
return _.map(optionList, option => {
return {description: option, checked: false};
return {checked: false, description: option};
});
},

componentWillMount() {
// Set the defaultOptions collection, either from a list of
// `options` in the Question's config, or from the context using a key
// defined in the Question's config (`optionsContextKey`).
// Set the defaultOptions collection, either from a list of `options` in
// the Question's config, or from the context using a key defined in the
// Question's config (`optionsContextKey`).
let defaultOptions = [];
if (_.has(this.props.config, 'optionsContextKey')) {
// Config directs to get the value from the context for the key set in
Expand All @@ -462,9 +462,22 @@ let QuestionFieldMultipleChoice = React.createClass({
defaultOptions =
this.getDefaultOptionValuesForOptionList(this.props.config.options);
}
// Merge the defaultOptions with those from the value in props to
// get the value store we'll use for the render.
this.optionValues = _.assign(defaultOptions, this.props.value);
// Merge the defaultOptions with those from the value in props to get the
// value store we'll use for the render.
this.optionValues = defaultOptions;
if (this.props.value.length) {
// upsert optionValues with the provided props.values based on
// `description` key
_.each(this.props.value, o => {
const match = _.find(this.optionValues, {description: o.description});
if (match) {
const i = _.indexOf(this.optionValues, match);
this.optionValues.splice(i, 1, o);
} else {
this.optionValues.push(o);
}
});
}
this.orderOptions = _.get(this.props.config, 'orderOptions', false);
},

Expand Down
91 changes: 87 additions & 4 deletions tests/question_form.js
Expand Up @@ -20,13 +20,13 @@ describe('<QuestionForm />', () => {
required: true,
visible: true
},
id: 'yesno_question',
id: 'base_question',
position: 1
}
];
this.baseQuestions = [
{
id: 'yesno_question',
id: 'base_question',
text: 'Is this a yesno question?',
type: 'yesno'
}
Expand Down Expand Up @@ -88,18 +88,101 @@ describe('<QuestionForm />', () => {
let question = {
type: 'multiple',
config: {
optionsContextKey: 'characteristics'
optionsContextKey: 'myContextOptions'
}
};
let context = {
characteristics: ['txt', 'json', 'xml']
myContextOptions: ['txt', 'json', 'xml']
};
this.baseQuestions[0] = _.assign(this.baseQuestions[0], question);
this.wrapper =
mount(<QuestionForm questions={this.baseQuestions} qsSchema={this.baseQSSchema} context={context} answers={[]} />);
expect(this.wrapper.find('QuestionFieldMultipleChoice')).to.have.length(1);
expect(this.wrapper.find('QuestionFieldMultipleChoiceOption')).to.have.length(3);
});
it('renders QuestionFieldMultipleChoice type in correct order with no answer', function() {
let question = {
type: 'multiple',
config: {
optionsContextKey: 'myContextOptions'
}
};
let context = {
myContextOptions: ['txt', 'json', 'xml']
};
let answers = [];
this.baseQuestions[0] = _.assign(this.baseQuestions[0], question);
this.wrapper =
mount(<QuestionForm questions={this.baseQuestions} qsSchema={this.baseQSSchema} context={context} answers={answers} />);
expect(this.wrapper.find('QuestionFieldMultipleChoice')).to.have.length(1);
expect(this.wrapper.find('QuestionFieldMultipleChoiceOption')).to.have.length(3);
let lastOption = this.wrapper.find('QuestionFieldMultipleChoiceOption .description').last().text();
let firstOption = this.wrapper.find('QuestionFieldMultipleChoiceOption .description').first().text();
expect(firstOption).to.equal('txt');
expect(lastOption).to.equal('xml');
});
it('renders QuestionFieldMultipleChoice type in correct order with answer', function() {
let question = {
type: 'multiple',
config: {
optionsContextKey: 'myContextOptions'
}
};
let context = {
myContextOptions: ['txt', 'json', 'xml']
};
let answers = [{
id: 'base_question',
value: [
{
checked: true,
description: 'xml'
}
],
commentValue: '',
currentValue: ''
}];
this.baseQuestions[0] = _.assign(this.baseQuestions[0], question);
this.wrapper =
mount(<QuestionForm questions={this.baseQuestions} qsSchema={this.baseQSSchema} context={context} answers={answers} />);
expect(this.wrapper.find('QuestionFieldMultipleChoice')).to.have.length(1);
expect(this.wrapper.find('QuestionFieldMultipleChoiceOption')).to.have.length(3);
let lastOption = this.wrapper.find('QuestionFieldMultipleChoiceOption .description').last().text();
let firstOption = this.wrapper.find('QuestionFieldMultipleChoiceOption .description').first().text();
expect(firstOption).to.equal('txt');
expect(lastOption).to.equal('xml');
});
it('renders QuestionFieldMultipleChoice wth added option provided by answer', function() {
let question = {
type: 'multiple',
config: {
optionsContextKey: 'myContextOptions'
}
};
let context = {
myContextOptions: ['txt', 'json', 'xml']
};
let answers = [{
id: 'base_question',
value: [
{
checked: true,
description: 'html'
}
],
commentValue: '',
currentValue: ''
}];
this.baseQuestions[0] = _.assign(this.baseQuestions[0], question);
this.wrapper =
mount(<QuestionForm questions={this.baseQuestions} qsSchema={this.baseQSSchema} context={context} answers={answers} />);
expect(this.wrapper.find('QuestionFieldMultipleChoice')).to.have.length(1);
expect(this.wrapper.find('QuestionFieldMultipleChoiceOption')).to.have.length(4);
let lastOption = this.wrapper.find('QuestionFieldMultipleChoiceOption .description').last().text();
let firstOption = this.wrapper.find('QuestionFieldMultipleChoiceOption .description').first().text();
expect(firstOption).to.equal('txt');
expect(lastOption).to.equal('html');
});
});

let qsSchema = [
Expand Down

0 comments on commit 55de449

Please sign in to comment.