Merge pull request #12038 from keithjgrant/survey-array

Add array support to survey multiple choice questions
This commit is contained in:
Sarah Akus
2022-04-13 15:00:49 -04:00
committed by GitHub
5 changed files with 195 additions and 33 deletions

View File

@@ -19,17 +19,14 @@ export default function SurveyQuestionAdd({ survey, updateSurvey }) {
); );
return; return;
} }
let choices = '';
let defaultAnswers = '';
if ( if (
formData.type === 'multiselect' || formData.type === 'multiselect' ||
formData.type === 'multiplechoice' formData.type === 'multiplechoice'
) { ) {
const choices = [];
let defaultAnswers = '';
formData.formattedChoices.forEach(({ choice, isDefault }, i) => { formData.formattedChoices.forEach(({ choice, isDefault }, i) => {
choices = choices.push(choice);
i === formData.formattedChoices.length - 1
? choices.concat(`${choice}`)
: choices.concat(`${choice}\n`);
if (isDefault) { if (isDefault) {
defaultAnswers = defaultAnswers =
i === formData.formattedChoices.length - 1 i === formData.formattedChoices.length - 1
@@ -38,7 +35,7 @@ export default function SurveyQuestionAdd({ survey, updateSurvey }) {
} }
}); });
formData.default = defaultAnswers.trim(); formData.default = defaultAnswers.trim();
formData.choices = choices.trim(); formData.choices = choices;
} }
delete formData.formattedChoices; delete formData.formattedChoices;
const newSpec = survey?.spec ? survey.spec.concat(formData) : [formData]; const newSpec = survey?.spec ? survey.spec.concat(formData) : [formData];

View File

@@ -58,17 +58,14 @@ export default function SurveyQuestionEdit({ survey, updateSurvey }) {
if (questionIndex === -1) { if (questionIndex === -1) {
throw new Error('Question not found in spec'); throw new Error('Question not found in spec');
} }
let choices = '';
let defaultAnswers = '';
if ( if (
submittedData.type === 'multiselect' || submittedData.type === 'multiselect' ||
submittedData.type === 'multiplechoice' submittedData.type === 'multiplechoice'
) { ) {
const choices = [];
let defaultAnswers = '';
submittedData.formattedChoices.forEach(({ choice, isDefault }, i) => { submittedData.formattedChoices.forEach(({ choice, isDefault }, i) => {
choices = choices.push(choice);
i === submittedData.formattedChoices.length - 1
? choices.concat(`${choice}`)
: choices.concat(`${choice}\n`);
if (isDefault) { if (isDefault) {
defaultAnswers = defaultAnswers =
i === submittedData.formattedChoices.length - 1 i === submittedData.formattedChoices.length - 1
@@ -77,8 +74,9 @@ export default function SurveyQuestionEdit({ survey, updateSurvey }) {
} }
}); });
submittedData.default = defaultAnswers.trim(); submittedData.default = defaultAnswers.trim();
submittedData.choices = choices.trim(); submittedData.choices = choices;
} }
delete submittedData.formattedChoices;
await updateSurvey([ await updateSurvey([
...survey.spec.slice(0, questionIndex), ...survey.spec.slice(0, questionIndex),

View File

@@ -41,18 +41,16 @@ describe('<SurveyQuestionEdit />', () => {
], ],
}); });
updateSurvey = jest.fn(); updateSurvey = jest.fn();
act(() => { wrapper = mountWithContexts(
wrapper = mountWithContexts( <Switch>
<Switch> <Route path="/templates/:templateType/:id/survey/edit">
<Route path="/templates/:templateType/:id/survey/edit"> <SurveyQuestionEdit survey={survey} updateSurvey={updateSurvey} />
<SurveyQuestionEdit survey={survey} updateSurvey={updateSurvey} /> </Route>
</Route> </Switch>,
</Switch>, {
{ context: { router: { history } },
context: { router: { history } }, }
} );
);
});
}); });
test('should render form', () => { test('should render form', () => {
@@ -147,4 +145,164 @@ describe('<SurveyQuestionEdit />', () => {
); );
}); });
}); });
test('should handle multiplechoice as array', () => {
const survey = {
spec: [
{
question_name: 'What is the foo?',
question_description: 'more about the foo',
variable: 'foo',
required: true,
type: 'multiplechoice',
choices: ['one', 'two', 'three'],
default: '',
min: 0,
max: 1024,
},
],
};
history = createMemoryHistory({
initialEntries: [
'/templates/job_templates/1/survey/edit?question_variable=foo',
],
});
updateSurvey = jest.fn();
wrapper = mountWithContexts(
<Switch>
<Route path="/templates/:templateType/:id/survey/edit">
<SurveyQuestionEdit survey={survey} updateSurvey={updateSurvey} />
</Route>
</Switch>,
{
context: { router: { history } },
}
);
const inputs = wrapper.find('MultipleChoiceField TextInput');
expect(inputs).toHaveLength(3);
expect(inputs.at(0).prop('value')).toEqual('one');
expect(inputs.at(1).prop('value')).toEqual('two');
expect(inputs.at(2).prop('value')).toEqual('three');
});
test('should handle multiplechoice as string', () => {
const survey = {
spec: [
{
question_name: 'What is the foo?',
question_description: 'more about the foo',
variable: 'foo',
required: true,
type: 'multiplechoice',
choices: 'one\ntwo\nthree',
default: '',
min: 0,
max: 1024,
},
],
};
history = createMemoryHistory({
initialEntries: [
'/templates/job_templates/1/survey/edit?question_variable=foo',
],
});
updateSurvey = jest.fn();
wrapper = mountWithContexts(
<Switch>
<Route path="/templates/:templateType/:id/survey/edit">
<SurveyQuestionEdit survey={survey} updateSurvey={updateSurvey} />
</Route>
</Switch>,
{
context: { router: { history } },
}
);
const inputs = wrapper.find('MultipleChoiceField TextInput');
expect(inputs).toHaveLength(3);
expect(inputs.at(0).prop('value')).toEqual('one');
expect(inputs.at(1).prop('value')).toEqual('two');
expect(inputs.at(2).prop('value')).toEqual('three');
});
test('should handle multiselect as array', () => {
const survey = {
spec: [
{
question_name: 'What is the foo?',
question_description: 'more about the foo',
variable: 'foo',
required: true,
type: 'multiselect',
choices: ['one', 'two', 'three'],
default: '',
min: 0,
max: 1024,
},
],
};
history = createMemoryHistory({
initialEntries: [
'/templates/job_templates/1/survey/edit?question_variable=foo',
],
});
updateSurvey = jest.fn();
wrapper = mountWithContexts(
<Switch>
<Route path="/templates/:templateType/:id/survey/edit">
<SurveyQuestionEdit survey={survey} updateSurvey={updateSurvey} />
</Route>
</Switch>,
{
context: { router: { history } },
}
);
const inputs = wrapper.find('MultipleChoiceField TextInput');
expect(inputs).toHaveLength(3);
expect(inputs.at(0).prop('value')).toEqual('one');
expect(inputs.at(1).prop('value')).toEqual('two');
expect(inputs.at(2).prop('value')).toEqual('three');
});
test('should handle multiselect as string', () => {
const survey = {
spec: [
{
question_name: 'What is the foo?',
question_description: 'more about the foo',
variable: 'foo',
required: true,
type: 'multiselect',
choices: 'one\ntwo\nthree',
default: '',
min: 0,
max: 1024,
},
],
};
history = createMemoryHistory({
initialEntries: [
'/templates/job_templates/1/survey/edit?question_variable=foo',
],
});
updateSurvey = jest.fn();
wrapper = mountWithContexts(
<Switch>
<Route path="/templates/:templateType/:id/survey/edit">
<SurveyQuestionEdit survey={survey} updateSurvey={updateSurvey} />
</Route>
</Switch>,
{
context: { router: { history } },
}
);
const inputs = wrapper.find('MultipleChoiceField TextInput');
expect(inputs).toHaveLength(3);
expect(inputs.at(0).prop('value')).toEqual('one');
expect(inputs.at(1).prop('value')).toEqual('two');
expect(inputs.at(2).prop('value')).toEqual('three');
});
}); });

View File

@@ -120,8 +120,14 @@ function SurveyQuestionForm({
new_question: !question, new_question: !question,
}; };
if (question?.type === 'multiselect' || question?.type === 'multiplechoice') { if (question?.type === 'multiselect' || question?.type === 'multiplechoice') {
const newQuestions = question.choices.split('\n').map((c, i) => { const choices = Array.isArray(question.choices)
if (question.default.split('\n').includes(c)) { ? question.choices
: question.choices.split('\n');
const defaults = Array.isArray(question.default)
? question.default
: question.default.split('\n');
const formattedChoices = choices.map((c, i) => {
if (defaults.includes(c)) {
return { choice: c, isDefault: true, id: i }; return { choice: c, isDefault: true, id: i };
} }
@@ -136,7 +142,7 @@ function SurveyQuestionForm({
variable: question?.variable || '', variable: question?.variable || '',
min: question?.min || 0, min: question?.min || 0,
max: question?.max || 1024, max: question?.max || 1024,
formattedChoices: newQuestions, formattedChoices,
new_question: !question, new_question: !question,
}; };
} }

View File

@@ -115,6 +115,9 @@ function SurveyReorderModal({
const defaultAnswer = (q) => { const defaultAnswer = (q) => {
let component = null; let component = null;
const choices = Array.isArray(q.choices)
? q.choices
: (q.choices || '').split('\n');
switch (q.type) { switch (q.type) {
case 'password': case 'password':
component = ( component = (
@@ -162,10 +165,10 @@ function SurveyReorderModal({
ouiaId={`survey-preview-multiSelect-${q.variable}`} ouiaId={`survey-preview-multiSelect-${q.variable}`}
noResultsFoundText={t`No results found`} noResultsFoundText={t`No results found`}
> >
{q.choices.length > 0 && {choices.length > 0 &&
q.choices choices.map((option) => (
.split('\n') <SelectOption key={option} value={option} />
.map((option) => <SelectOption key={option} value={option} />)} ))}
</Select> </Select>
); );
break; break;