diff --git a/lib/WebGUI/Asset/Wobject/Survey/ResponseJSON.pm b/lib/WebGUI/Asset/Wobject/Survey/ResponseJSON.pm index 422e423e8..d0bf30549 100644 --- a/lib/WebGUI/Asset/Wobject/Survey/ResponseJSON.pm +++ b/lib/WebGUI/Asset/Wobject/Survey/ResponseJSON.pm @@ -457,7 +457,6 @@ sub recordResponses { $gotoExpression = $section->{gotoExpression}; } - # Handle empty Section.. if ( !@questions ) { # No questions to process, so increment lastResponse and return @@ -494,6 +493,7 @@ sub recordResponses { # Pluck the values out of the responses hash that we want to record.. my $submittedAnswerResponse = $submittedResponses->{ $answer->{id} }; my $submittedAnswerComment = $submittedResponses->{ $answer->{id} . 'comment' }; + my $submittedAnswerVerbatim = $submittedResponses->{ $answer->{id} . 'verbatim' }; # Proceed if we're satisfied that the submitted answer response is valid.. if ( defined $submittedAnswerResponse && $submittedAnswerResponse =~ /\S/ ) { @@ -517,9 +517,10 @@ sub recordResponses { = $knownTypes{ $question->{questionType} } ? $submittedAnswerResponse : $answer->{recordedAnswer}; - - $self->responses->{ $answer->{id} }->{time} = time; - $self->responses->{ $answer->{id} }->{comment} = $submittedAnswerComment; + + $self->responses->{ $answer->{id} }->{verbatim} = $answer->{verbatim} ? $submittedAnswerVerbatim : undef; + $self->responses->{ $answer->{id} }->{time} = time; + $self->responses->{ $answer->{id} }->{comment} = $submittedAnswerComment; # Handle terminal Answers.. if ( $answer->{terminal} ) { @@ -694,17 +695,31 @@ sub recordedResponses{ #------------------------------------------------------------------- -=head2 responseValuesByVariableName +=head2 responseValuesByVariableName ( $options ) Returns a lookup table to question variable names and recorded response values. Only questions with a defined variable name set are included. Values come from the L hash. +=head3 options + +The following options are supported: + +=over 3 + +=item * useText + +For multiple choice questions, use the answer text instead of the recorded value +(useful for doing [[var]] text substitution + +=back + =cut sub responseValuesByVariableName { my $self = shift; + my %options = validate(@_, { useText => 0 }); my %lookup; while (my ($address, $response) = each %{$self->responses}) { @@ -722,14 +737,23 @@ sub responseValuesByVariableName { # Filter out questions without defined variable names next if !$question || !defined $question->{variable}; - #Test if question is a multiple choice type so we can use the answer text instead - my $answerText; - if($self->survey->getMultiChoiceBundle($question->{questionType})){ - $answerText = $self->survey->answer([@address])->{text}; + my $value = $response->{value}; + if ($options{useText}) { + # Test if question is a multiple choice type so we can use the answer text instead + if($self->survey->getMultiChoiceBundle($question->{questionType})){ + my $answer = $self->survey->answer([@address]); + my $answerText = $answer->{text}; + + # For verbatim mc answers, combine answer text and recorded value + if ($answer->{verbatim}) { + $answerText = "$answerText - \"$response->{verbatim}\""; + } + $value = $answerText ? $answerText : $value; + } } # Add variable => value to our hash - $lookup{$question->{variable}} = $answerText ? $answerText : $response->{value}; + $lookup{$question->{variable}} = $value; } return \%lookup; } @@ -865,7 +889,7 @@ sub nextQuestions { my $questionsPerPage = $self->survey->section( [ $self->nextResponseSectionIndex ] )->{questionsPerPage}; # Get all of the existing question responses (so that we can do Section and Question [[var]] replacements - my $responseValuesByVariableName = $self->responseValuesByVariableName(); + my $responseValuesByVariableName = $self->responseValuesByVariableName( { useText => 1 } ); # Do text replacement $section->{text} = $self->getTemplatedText($section->{text}, $responseValuesByVariableName); diff --git a/lib/WebGUI/Asset/Wobject/Survey/SurveyJSON.pm b/lib/WebGUI/Asset/Wobject/Survey/SurveyJSON.pm index 7d0ecbb59..57b6856e8 100644 --- a/lib/WebGUI/Asset/Wobject/Survey/SurveyJSON.pm +++ b/lib/WebGUI/Asset/Wobject/Survey/SurveyJSON.pm @@ -1037,10 +1037,9 @@ sub addAnswersToQuestion { # when updating answer text without causing side-effects for the caller's $address my @address_copy = @{$address}; - for my $answer_index ( 0 .. $#{$answers} ) { - + for my $answer (@$answers) { # Add a new answer to question - push @{ $self->question( \@address_copy )->{answers} }, $answers->[$answer_index]; + push @{ $self->question( \@address_copy )->{answers} }, $answer; } return; diff --git a/t/Asset/Wobject/Survey/ResponseJSON.t b/t/Asset/Wobject/Survey/ResponseJSON.t index 54535617d..83e65f06a 100644 --- a/t/Asset/Wobject/Survey/ResponseJSON.t +++ b/t/Asset/Wobject/Survey/ResponseJSON.t @@ -22,7 +22,7 @@ my $session = WebGUI::Test->session; #---------------------------------------------------------------------------- # Tests -my $tests = 74; +my $tests = 75; plan tests => $tests + 1; #---------------------------------------------------------------------------- @@ -475,6 +475,7 @@ cmp_deeply( $rJSON->recordResponses({ '1-0comment' => 'Section 1, question 0 comment', '1-0-0' => 'First answer', + '1-0-0verbatim' => 'First answer verbatim', # ignored '1-0-0comment' => 'Section 1, question 0, answer 0 comment', }), [ 1, 'question 1-0 terminal' ], @@ -494,6 +495,7 @@ cmp_deeply( comment => 'Section 1, question 0, answer 0 comment', 'time' => num(time(), 3), value => 1, # 'recordedAnswer' value used because question is multi-choice + verbatim => undef, }, '1-1' => { comment => undef, @@ -502,11 +504,42 @@ cmp_deeply( 'recordResponses: recorded responses correctly, two questions, one answer, comments, values and time' ); +# Check that raw input is recorded for verbatim mc answers +$rJSON->survey->answer([1,0,0])->{verbatim} = 1; +$rJSON->lastResponse(2); +$rJSON->responses({}); +$rJSON->questionsAnswered(-1 * $rJSON->questionsAnswered); +$rJSON->recordResponses({ + '1-0comment' => 'Section 1, question 0 comment', + '1-0-0' => 'First answer', + '1-0-0verbatim' => 'First answer verbatim', + '1-0-0comment' => 'Section 1, question 0, answer 0 comment', +}); +cmp_deeply( + $rJSON->responses, + { + '1-0' => { + comment => 'Section 1, question 0 comment', + }, + '1-0-0' => { + comment => 'Section 1, question 0, answer 0 comment', + 'time' => num(time(), 3), + value => 1, # 'recordedAnswer' value used because question is multi-choice + verbatim => 'First answer verbatim', + }, + '1-1' => { + comment => undef, + } + }, + 'recordResponses: verbatim answer recorded responses correctly' +); +$rJSON->survey->answer([1,0,0])->{verbatim} = 0; # revert change # Repeat with non multi-choice question, to check that submitted answer value is used # instead of recordedValue $rJSON->survey->question([1,0])->{questionType} = 'Text'; $rJSON->lastResponse(2); +$rJSON->responses({}); $rJSON->questionsAnswered(-1 * $rJSON->questionsAnswered); $rJSON->recordResponses({ '1-0comment' => 'Section 1, question 0 comment', @@ -523,6 +556,7 @@ cmp_deeply( comment => 'Section 1, question 0, answer 0 comment', 'time' => num(time(), 3), value => 'First answer', # submitted answer value used this time because non-mc + verbatim => undef, }, '1-1' => { comment => undef, @@ -587,12 +621,14 @@ cmp_deeply($popped, { value => 1, comment => 'Section 1, question 0, answer 0 comment', time => num(time(), 3), + verbatim => undef, }, # the second q answer '1-1-0' => { value => 0, comment => 'Section 1, question 1, answer 0 comment', time => num(time(), 3), + verbatim => undef, }, # the first question comment '1-0' => { @@ -625,6 +661,7 @@ cmp_deeply($rJSON->pop, { value => 0, comment => 'Section 1, question 1, answer 0 comment', time => num(time(), 3), + verbatim => undef, }, # the second question comment '1-1' => { @@ -637,6 +674,7 @@ cmp_deeply($rJSON->responses, { value => 1, comment => 'Section 1, question 0, answer 0 comment', time => num(time(), 3), + verbatim => undef, }, # the first question comment '1-0' => { @@ -649,6 +687,7 @@ cmp_deeply($rJSON->pop, { value => 1, comment => 'Section 1, question 0, answer 0 comment', time => num(time(), 3), + verbatim => undef, }, # the first question comment '1-0' => { diff --git a/t/Asset/Wobject/Survey/SurveyJSON.t b/t/Asset/Wobject/Survey/SurveyJSON.t index 4d368681a..513349665 100644 --- a/t/Asset/Wobject/Survey/SurveyJSON.t +++ b/t/Asset/Wobject/Survey/SurveyJSON.t @@ -22,7 +22,7 @@ my $session = WebGUI::Test->session; #---------------------------------------------------------------------------- # Tests -my $tests = 139; +my $tests = 137; plan tests => $tests + 1 + 3; #---------------------------------------------------------------------------- @@ -1384,15 +1384,15 @@ cmp_deeply( #################################################### # -# addAnswersToQuestion +# addAnswersToQuestion, getMultiChoiceBundle # #################################################### #We'll work exclusively with Question 3-0 +my $answerBundle = $surveyJSON->getMultiChoiceBundle('Yes/No'); $surveyJSON->addAnswersToQuestion( [3,0], - [ qw[ one two three ] ], - {} + $answerBundle, ); cmp_deeply( @@ -1400,85 +1400,20 @@ cmp_deeply( superhashof({ answers => [ superhashof({ - text => 'one', + text => 'Yes', verbatim => 0, recordedAnswer => 1, + value => 1, }), superhashof({ - text => 'two', + text => 'No', verbatim => 0, - recordedAnswer => 2, - }), - superhashof({ - text => 'three', - verbatim => 0, - recordedAnswer => 3, + recordedAnswer => 0, + value => 1, }), ], }), - 'addAnswersToQuestion: setup three answers, no verbatims' -); - -$surveyJSON->question([3,0])->{answers} = []; - -$surveyJSON->addAnswersToQuestion( [3,0], - [ qw[ one two three ] ], - { 1 => 1, 2 => 1 } -); - -cmp_deeply( - $surveyJSON->question([3,0]), - superhashof({ - answers => [ - superhashof({ - text => 'one', - verbatim => 0, - recordedAnswer => 1, - }), - superhashof({ - text => 'two', - verbatim => 1, - recordedAnswer => 2, - }), - superhashof({ - text => 'three', - verbatim => 1, - recordedAnswer => 3, - }), - ], - }), - 'addAnswersToQuestion: setup verbatims on two answers' -); - -$surveyJSON->question([3,0])->{answers} = []; - -$surveyJSON->addAnswersToQuestion( [3,0], - [ qw[ one two three ] ], - { 1 => 0 } -); - -cmp_deeply( - $surveyJSON->question([3,0]), - superhashof({ - answers => [ - superhashof({ - text => 'one', - verbatim => 0, - recordedAnswer => 1, - }), - superhashof({ - text => 'two', - verbatim => 0, - recordedAnswer => 2, - }), - superhashof({ - text => 'three', - verbatim => 0, - recordedAnswer => 3, - }), - ], - }), - 'addAnswersToQuestion: verbatims have to exist, and be true' + 'addAnswersToQuestion: Yes/No bundle created' ); #################################################### @@ -1507,12 +1442,12 @@ cmp_deeply( superhashof({ text => 'Male', verbatim => 0, - recordedAnswer => 1, + recordedAnswer => 0, }), superhashof({ text => 'Female', verbatim => 0, - recordedAnswer => 2, + recordedAnswer => 1, }), ], 'updateQuestionAnswers: Gender type' @@ -1530,7 +1465,7 @@ cmp_deeply( superhashof({ text => 'No', verbatim => 0, - recordedAnswer => 2, + recordedAnswer => 0, }), ], 'updateQuestionAnswers: Yes/No type' @@ -1548,10 +1483,10 @@ cmp_deeply( superhashof({ text => 'False', verbatim => 0, - recordedAnswer => 2, + recordedAnswer => 0, }), ], - 'updateQuestionAnswers: Yes/No type' + 'updateQuestionAnswers: True/False type' ); $surveyJSON->updateQuestionAnswers([3,0], 'Agree/Disagree'); @@ -1561,7 +1496,7 @@ cmp_deeply( superhashof({ text => 'Strongly disagree', verbatim => 0, - recordedAnswer => 1, + recordedAnswer => 0, }), ( superhashof({ text => '', @@ -1571,7 +1506,7 @@ cmp_deeply( superhashof({ text => 'Strongly agree', verbatim => 0, - recordedAnswer => 7, + recordedAnswer => 6, }), ], 'updateQuestionAnswers: Agree/Disagree type' @@ -1584,7 +1519,7 @@ cmp_deeply( superhashof({ text => 'Strongly oppose', verbatim => 0, - recordedAnswer => 1, + recordedAnswer => 0, }), ( superhashof({ text => '', @@ -1594,7 +1529,7 @@ cmp_deeply( superhashof({ text => 'Strongly support', verbatim => 0, - recordedAnswer => 7, + recordedAnswer => 6, }), ], 'updateQuestionAnswers: Agree/Disagree type' @@ -1607,7 +1542,7 @@ cmp_deeply( superhashof({ text => 'Not at all important', verbatim => 0, - recordedAnswer => 1, + recordedAnswer => 0, }), ( superhashof({ text => '', @@ -1617,7 +1552,7 @@ cmp_deeply( superhashof({ text => 'Extremely important', verbatim => 0, - recordedAnswer => 11, + recordedAnswer => 10, }), ], 'updateQuestionAnswers: Importance type' @@ -1630,7 +1565,7 @@ cmp_deeply( superhashof({ text => 'Not at all likely', verbatim => 0, - recordedAnswer => 1, + recordedAnswer => 0, }), ( superhashof({ text => '', @@ -1640,7 +1575,7 @@ cmp_deeply( superhashof({ text => 'Extremely likely', verbatim => 0, - recordedAnswer => 11, + recordedAnswer => 10, }), ], 'updateQuestionAnswers: Likelihood type' @@ -1653,7 +1588,7 @@ cmp_deeply( superhashof({ text => 'Not at all certain', verbatim => 0, - recordedAnswer => 1, + recordedAnswer => 0, }), ( superhashof({ text => '', @@ -1663,7 +1598,7 @@ cmp_deeply( superhashof({ text => 'Extremely certain', verbatim => 0, - recordedAnswer => 11, + recordedAnswer => 10, }), ], 'updateQuestionAnswers: Certainty type' @@ -1676,7 +1611,7 @@ cmp_deeply( superhashof({ text => 'Not at all satisfied', verbatim => 0, - recordedAnswer => 1, + recordedAnswer => 0, }), ( superhashof({ text => '', @@ -1686,7 +1621,7 @@ cmp_deeply( superhashof({ text => 'Extremely satisfied', verbatim => 0, - recordedAnswer => 11, + recordedAnswer => 10, }), ], 'updateQuestionAnswers: Satisfaction type' @@ -1699,7 +1634,7 @@ cmp_deeply( superhashof({ text => 'Not at all confident', verbatim => 0, - recordedAnswer => 1, + recordedAnswer => 0, }), ( superhashof({ text => '', @@ -1709,7 +1644,7 @@ cmp_deeply( superhashof({ text => 'Extremely confident', verbatim => 0, - recordedAnswer => 11, + recordedAnswer => 10, }), ], 'updateQuestionAnswers: Confidence type' @@ -1722,7 +1657,7 @@ cmp_deeply( superhashof({ text => 'Not at all effective', verbatim => 0, - recordedAnswer => 1, + recordedAnswer => 0, }), ( superhashof({ text => '', @@ -1732,7 +1667,7 @@ cmp_deeply( superhashof({ text => 'Extremely effective', verbatim => 0, - recordedAnswer => 11, + recordedAnswer => 10, }), ], 'updateQuestionAnswers: Effectiveness type' @@ -1745,7 +1680,7 @@ cmp_deeply( superhashof({ text => 'Not at all concerned', verbatim => 0, - recordedAnswer => 1, + recordedAnswer => 0, }), ( superhashof({ text => '', @@ -1755,7 +1690,7 @@ cmp_deeply( superhashof({ text => 'Extremely concerned', verbatim => 0, - recordedAnswer => 11, + recordedAnswer => 10, }), ], 'updateQuestionAnswers: Concern type' @@ -1768,7 +1703,7 @@ cmp_deeply( superhashof({ text => 'No risk', verbatim => 0, - recordedAnswer => 1, + recordedAnswer => 0, }), ( superhashof({ text => '', @@ -1778,7 +1713,7 @@ cmp_deeply( superhashof({ text => 'Extreme risk', verbatim => 0, - recordedAnswer => 11, + recordedAnswer => 10, }), ], 'updateQuestionAnswers: Risk type' @@ -1791,7 +1726,7 @@ cmp_deeply( superhashof({ text => 'No threat', verbatim => 0, - recordedAnswer => 1, + recordedAnswer => 0, }), ( superhashof({ text => '', @@ -1801,7 +1736,7 @@ cmp_deeply( superhashof({ text => 'Extreme threat', verbatim => 0, - recordedAnswer => 11, + recordedAnswer => 10, }), ], 'updateQuestionAnswers: Threat type' @@ -1814,7 +1749,7 @@ cmp_deeply( superhashof({ text => 'Not at all secure', verbatim => 0, - recordedAnswer => 1, + recordedAnswer => 0, }), ( superhashof({ text => '', @@ -1824,14 +1759,14 @@ cmp_deeply( superhashof({ text => 'Extremely secure', verbatim => 0, - recordedAnswer => 11, + recordedAnswer => 10, }), ], 'updateQuestionAnswers: Security type' ); $surveyJSON->updateQuestionAnswers([3,0], 'Ideology'); -my $index = 1; +my $index = 0; cmp_deeply( $surveyJSON->question([3,0])->{answers}, [ @@ -1854,14 +1789,14 @@ cmp_deeply( ); $surveyJSON->updateQuestionAnswers([3,0], 'Race'); -$index = 1; +$index = 0; cmp_deeply( $surveyJSON->question([3,0])->{answers}, [ map { superhashof({ text => $_, - verbatim => $index == 6 ? 1 : 0, + verbatim => $index == 5 ? 1 : 0, recordedAnswer => $index++, }) } 'American Indian', 'Asian', 'Black', 'Hispanic', 'White non-Hispanic', 'Something else (verbatim)', @@ -1870,14 +1805,14 @@ cmp_deeply( ); $surveyJSON->updateQuestionAnswers([3,0], 'Party'); -$index = 1; +$index = 0; cmp_deeply( $surveyJSON->question([3,0])->{answers}, [ map { superhashof({ text => $_, - verbatim => $index == 4 ? 1 : 0, + verbatim => $index == 3 ? 1 : 0, recordedAnswer => $index++, }) } 'Democratic party', 'Republican party (or GOP)', 'Independent party', 'Other party (verbatim)', @@ -1886,14 +1821,14 @@ cmp_deeply( ); $surveyJSON->updateQuestionAnswers([3,0], 'Education'); -$index = 1; +$index = 0; cmp_deeply( $surveyJSON->question([3,0])->{answers}, [ map { superhashof({ text => $_, - verbatim => $index == 8 ? 1 : 0, + verbatim => $index == 7 ? 1 : 0, recordedAnswer => $index++, }) }