diff options
-rwxr-xr-x | perllib/FixMyStreet/App/Controller/Questionnaire.pm | 38 | ||||
-rw-r--r-- | t/app/controller/questionnaire.t | 278 | ||||
-rw-r--r-- | templates/web/default/questionnaire/completed.html | 10 | ||||
-rw-r--r-- | templates/web/default/questionnaire/index.html | 14 |
4 files changed, 310 insertions, 30 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Questionnaire.pm b/perllib/FixMyStreet/App/Controller/Questionnaire.pm index addbfb826..766c886f7 100755 --- a/perllib/FixMyStreet/App/Controller/Questionnaire.pm +++ b/perllib/FixMyStreet/App/Controller/Questionnaire.pm @@ -51,6 +51,14 @@ sub load_questionnaire : Private { $c->stash->{problem} = $questionnaire->problem; $c->stash->{answered_ever_reported} = $questionnaire->problem->user->answered_ever_reported; + + # EHA needs to know how many to alter display, and whether to send another or not + if ($c->cobrand->moniker eq 'emptyhomes') { + $c->stash->{num_questionnaire} = $c->model('DB::Questionnaire')->count( + { problem_id => $c->stash->{problem}->id } + ); + } + } =head2 submit @@ -141,22 +149,13 @@ sub submit_standard : Private { $c->forward( '/tokens/load_questionnaire_id', [ $c->req->params->{token} ] ); $c->forward( 'load_questionnaire' ); - - my $problem = $c->stash->{problem}; - - # EHA questionnaires done for you - if ($c->cobrand->moniker eq 'emptyhomes') { - $c->stash->{num_questionnaire} = $c->model('DB::Questionnaire')->count( - { problem_id => $problem->id } - ); - $c->stash->{another} = $c->stash->{num_questionnaire}==1 ? 'Yes' : 'No'; - } - $c->forward( 'process_questionnaire' ); + my $problem = $c->stash->{problem}; + my $old_state = $problem->state; my $new_state = ''; - $new_state = 'fixed' if $c->stash->{been_fixed} eq 'Yes' && $problem->{state} eq 'confirmed'; - $new_state = 'confirmed' if $c->stash->{been_fixed} eq 'No' && $problem->{state} eq 'fixed'; + $new_state = 'fixed' if $c->stash->{been_fixed} eq 'Yes' && $old_state eq 'confirmed'; + $new_state = 'confirmed' if $c->stash->{been_fixed} eq 'No' && $old_state eq 'fixed'; # Record state change, if there was one if ( $new_state ) { @@ -165,7 +164,7 @@ sub submit_standard : Private { } # If it's not fixed and they say it's still not been fixed, record time update - if ( $c->stash->{been_fixed} eq 'No' && $problem->state eq 'confirmed' ) { + if ( $c->stash->{been_fixed} eq 'No' && $old_state eq 'confirmed' ) { $problem->lastupdate( \'ms_current_timestamp()' ); } @@ -177,8 +176,8 @@ sub submit_standard : Private { my $q = $c->stash->{questionnaire}; $q->whenanswered( \'ms_current_timestamp()' ); $q->ever_reported( $reported ); - $q->old_state( $problem->state ); - $q->new_state( $c->stash->{been_fixed} eq 'Unknown' ? 'unknown' : ($new_state ? $new_state : $problem->state) ); + $q->old_state( $old_state ); + $q->new_state( $c->stash->{been_fixed} eq 'Unknown' ? 'unknown' : ($new_state || $old_state) ); $q->update; # Record an update if they've given one, or if there's a state change @@ -189,7 +188,7 @@ sub submit_standard : Private { problem => $problem, name => $problem->name, user => $problem->user, - text => $c->stash->{update}, + text => $update, state => 'confirmed', mark_fixed => $new_state eq 'fixed' ? 1 : 0, mark_open => $new_state eq 'confirmed' ? 1 : 0, @@ -223,6 +222,11 @@ sub process_questionnaire : Private { map { $c->stash->{$_} = $c->req->params->{$_} || '' } qw(been_fixed reported another update); + # EHA questionnaires done for you + if ($c->cobrand->moniker eq 'emptyhomes') { + $c->stash->{another} = $c->stash->{num_questionnaire}==1 ? 'Yes' : 'No'; + } + my @errors; push @errors, _('Please state whether or not the problem has been fixed') unless $c->stash->{been_fixed}; diff --git a/t/app/controller/questionnaire.t b/t/app/controller/questionnaire.t new file mode 100644 index 000000000..af14332d4 --- /dev/null +++ b/t/app/controller/questionnaire.t @@ -0,0 +1,278 @@ +use strict; +use warnings; +use Test::More; + +use FixMyStreet::TestMech; +use FixMyStreet::App::Controller::Questionnaire; + +ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' ); + +# create a test user and report +$mech->delete_user('test@example.com'); + +my $user = + FixMyStreet::App->model('DB::User') + ->find_or_create( { email => 'test@example.com', name => 'Test User' } ); +ok $user, "created test user"; + +my $report_time = '2011-03-01 12:00:00'; + +my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( + { + postcode => 'EH1 1BB', + council => '2651', + areas => ',11808,135007,14419,134935,2651,20728,', + category => 'Street lighting', + title => 'Testing', + detail => 'Testing Detail', + used_map => 1, + name => $user->name, + anonymous => 0, + state => 'confirmed', + confirmed => $report_time, + lastupdate => $report_time, + whensent => '2011-03-01 12:05:00', + lang => 'en-gb', + service => '', + cobrand => 'default', + cobrand_data => '', + send_questionnaire => 1, + latitude => '55.951963', + longitude => '-3.189944', + user_id => $user->id, + } +); +my $report_id = $report->id; +ok $report, "created test report - $report_id"; + +# FIXME Should call send-questionnaires here to test that is working okay. +# For now, just generate the questionnaire etc. manually. +# Call send-questionnaires (for normal non-EHA site) +# my $email = $mech->get_email; +# ok $email, "got an email"; +# like $email->body, qr/fill in our short questionnaire/i, "got questionnaire email"; +# my ($url) = $email->body =~ m{(http://\S+)}; +# ok $url, "extracted questionnaire url '$url'"; + +$report->send_questionnaire( 0 ); +$report->update; + +my $questionnaire = FixMyStreet::App->model('DB::Questionnaire')->find_or_create( + { + problem_id => $report->id, + whensent => '2011-04-01 12:00:00', + } +); +ok $questionnaire, 'added questionnaire'; +my $token = FixMyStreet::App->model("DB::Token")->create( + { scope => 'questionnaire', data => $questionnaire->id } +); +ok $token, 'added token for questionnaire'; + +foreach my $test ( + { + desc => 'User goes to questionnaire URL with a bad token', + token_extra => 'BAD', + content => "we couldn't validate that token", + }, + { + desc => 'User goes to questionnaire URL for a now-hidden problem', + state => 'hidden', + content => "we couldn't locate your problem", + }, + { + desc => 'User goes to questionnaire URL for an already answered questionnaire', + answered => \'ms_current_timestamp()', + content => 'already answered this questionnaire', + }, +) { + subtest $test->{desc} => sub { + $report->state( $test->{state} || 'confirmed' ); + $report->update; + $questionnaire->whenanswered( $test->{answered} ); + $questionnaire->update; + (my $token = $token->token); + $token .= $test->{token_extra} if $test->{token_extra}; + $mech->get_ok("/Q/$token"); + $mech->content_contains( $test->{content} ); + # Reset, no matter what test did + $report->state( 'confirmed' ); + $report->update; + $questionnaire->whenanswered( undef ); + $questionnaire->update; + }; +} + +$mech->get_ok("/Q/" . $token->token); +$mech->title_like( qr/Questionnaire/ ); +$mech->submit_form_ok( ); +my @errors = @{ $mech->page_errors }; +ok scalar @errors, 'displayed error messages'; +is $errors[0], "Please state whether or not the problem has been fixed", 'error message'; + +foreach my $test ( + { + desc => 'Open report, has been fixed, first time reporter, no update left', + problem_state => 'confirmed', + fields => { + been_fixed => 'Yes', + reported => 'No', + }, + comment => 'Questionnaire filled in by problem reporter', + }, + { + desc => 'Open report, has been fixed, reported before, leaves an update', + problem_state => 'confirmed', + fields => { + been_fixed => 'Yes', + reported => 'Yes', + update => 'The council fixed this really quickly, thanks!', + }, + }, + { + desc => 'Open report, has not been fixed, not reported before, no update, asks for another questionnaire', + problem_state => 'confirmed', + fields => { + been_fixed => 'No', + reported => 'No', + another => 'Yes', + }, + }, + { + desc => 'Open report, unknown fixed, reported before, update, no further questionnaire', + problem_state => 'confirmed', + fields => { + been_fixed => 'Unknown', + reported => 'Yes', + update => 'This is still going on.', + # another => 'No', Error for not setting this tested below + }, + }, + { + desc => 'Fixed report, confirmed fixed, not reported before, no update', + problem_state => 'fixed', + fields => { + been_fixed => 'Yes', + reported => 'No', + }, + lastupdate_static => 1, + }, + { + desc => 'Fixed report, unknown fixed, not reported before, no update, asks for another', + problem_state => 'fixed', + fields => { + been_fixed => 'Unknown', + reported => 'No', + another => 'Yes', + }, + }, + { + desc => 'Fixed report, reopened, reported before, no update, no further questionnaire', + problem_state => 'fixed', + fields => { + been_fixed => 'No', + reported => 'Yes', + another => 'No', + # update => 'Dummy', Error for not setting this tested below + }, + }, +) { + subtest $test->{desc} => sub { + $report->state ( $test->{problem_state} ); + $report->update; + + $mech->get_ok("/Q/" . $token->token); + $mech->title_like( qr/Questionnaire/ ); + $mech->submit_form_ok( { with_fields => $test->{fields} } ); + + # If reopening, we've just submitted without an update. Should cause an error. + if ($test->{problem_state} eq 'fixed' && $test->{fields}{been_fixed} eq 'No') { + my @errors = @{ $mech->page_errors }; + ok scalar @errors, 'displayed error messages'; + is $errors[0], "Please provide some explanation as to why you're reopening this report", 'error message'; + $test->{fields}{update} = 'This has not been fixed.'; + $mech->submit_form_ok( { with_fields => $test->{fields} } ); + } + + # We forgot to say we wanted another questionnaire or not with this test + if ($test->{problem_state} eq 'confirmed' && $test->{fields}{been_fixed} eq 'Unknown') { + my @errors = @{ $mech->page_errors }; + ok scalar @errors, 'displayed error messages'; + is $errors[0], "Please indicate whether you'd like to receive another questionnaire", 'error message'; + $test->{fields}{another} = 'No'; + $mech->submit_form_ok( { with_fields => $test->{fields} } ); + } + + my $result; + $result = 'fixed' if $test->{fields}{been_fixed} eq 'Yes'; + $result = 'confirmed' if $test->{fields}{been_fixed} eq 'No'; + $result = 'unknown' if $test->{fields}{been_fixed} eq 'Unknown'; + + my $another = 0; + $another = 1 if $test->{fields}{another} && $test->{fields}{another} eq 'Yes'; + + # Check the right HTML page has been returned + $mech->content_contains( 'glad to hear it’s been fixed' ) + if $result eq 'fixed'; + $mech->content_contains( 'get some more information about the status of your problem' ) + if $result eq 'unknown'; + $mech->content_contains( "sorry to hear that" ) + if $result eq 'confirmed'; + + # Check the database has the right information + $report->discard_changes; + $questionnaire->discard_changes; + is $report->state, $result eq 'unknown' ? $test->{problem_state} : $result; + is $report->send_questionnaire, $another; + ok DateTime::Format::Pg->format_datetime( $report->lastupdate) gt $report_time, 'lastupdate changed' + unless $test->{fields}{been_fixed} eq 'Unknown' || $test->{lastupdate_static}; + is $questionnaire->old_state, $test->{problem_state}; + is $questionnaire->new_state, $result; + is $questionnaire->ever_reported, $test->{fields}{reported} eq 'Yes' ? 1 : 0; + if ($test->{fields}{update} || $test->{comment}) { + my $c = FixMyStreet::App->model("DB::Comment")->find( + { problem_id => $report->id } + ); + is $c->text, $test->{fields}{update} || $test->{comment}; + } + + # Reset questionnaire for next test + $questionnaire->old_state( undef ); + $questionnaire->new_state( undef ); + $questionnaire->ever_reported( undef ); + $questionnaire->whenanswered( undef ); + $questionnaire->update; + $report->send_questionnaire( 0 ); + $report->lastupdate( $report_time ); + $report->comments->delete; + $report->update; + }; +} + +# EHA extra checking +ok $mech->host("reportemptyhomes.com"), 'change host to reportemptyhomes'; +$mech->get_ok("/Q/" . $token->token); +$mech->content_contains( 'should have reported what they have done' ); + +# Test already answered the ever reported question, so not shown again +my $questionnaire2 = FixMyStreet::App->model('DB::Questionnaire')->find_or_create( + { + problem_id => $report->id, + whensent => '2011-03-28 12:00:00', + ever_reported => 1, + } +); +ok $questionnaire, 'added another questionnaire'; +ok $mech->host("fixmystreet.com"), 'change host to fixmystreet'; +$mech->get_ok("/Q/" . $token->token); +$mech->title_like( qr/Questionnaire/ ); +$mech->content_contains( 'Has this problem been fixed?' ); +$mech->content_lacks( 'ever reported' ); + +# EHA extra checking +ok $mech->host("reportemptyhomes.com"), 'change host to reportemptyhomes'; +$mech->get_ok("/Q/" . $token->token); +$mech->content_contains( 'made a lot of progress' ); + +$mech->delete_user('test@example.com'); +done_testing(); diff --git a/templates/web/default/questionnaire/completed.html b/templates/web/default/questionnaire/completed.html index 0dbd2828d..afac7aa29 100644 --- a/templates/web/default/questionnaire/completed.html +++ b/templates/web/default/questionnaire/completed.html @@ -8,21 +8,21 @@ site and leave an update.</p>') %] [% ELSIF new_state == 'confirmed' OR (!new_state AND problem.state == 'confirmed') %] -[% tprintf( loc('<p style="font-size:150%%">We're sorry to hear that. We have two suggestions: why not try +[% tprintf( loc('<p style="font-size:150%%">We’re sorry to hear that. We have two suggestions: why not try <a href="%s">writing direct to your councillor(s)</a> -or, if it's a problem that could be fixed by local people working together, +or, if it’s a problem that could be fixed by local people working together, why not <a href="http://www.pledgebank.com/new">make and publicise a pledge</a>? -</p>'), c.cobrand.writetothem_url || http://www.writetothem.com %] +</p>'), c.cobrand.writetothem_url || 'http://www.writetothem.com/' ) %] [% advert_outcome = 0 %] [% ELSE %] -[% loc('<p style="font-size:150%">Thank you very much for filling in our questionnaire; glad to hear it's been fixed.</p>') %] +[% loc('<p style="font-size:150%">Thank you very much for filling in our questionnaire; glad to hear it’s been fixed.</p>') %] [% END %] [% IF advert_outcome %] - [% display_crosssell_advert( problem.user.email, problem.name, { council = problem.council } ) %] + [% display_crosssell_advert( problem.user.email, problem.name, council, problem.council ) %] [% END %] diff --git a/templates/web/default/questionnaire/index.html b/templates/web/default/questionnaire/index.html index 6d102bac9..d463ff2f9 100644 --- a/templates/web/default/questionnaire/index.html +++ b/templates/web/default/questionnaire/index.html @@ -24,28 +24,26 @@ [% c.cobrand.form_elements('questionnaireForm') %] [% IF c.cobrand.moniker == 'emptyhomes' %] -[% IF num_questionnaires == 1 %] - _(<<EOF); -<p>Getting empty homes back into use can be difficult. You shouldn't expect +[% IF num_questionnaire == 1 %] +[% loc('<p>Getting empty homes back into use can be difficult. You shouldn’t expect the property to be back into use yet. But a good council will have started work and should have reported what they have done on the website. If you are not satisfied with progress or information from the council, now is the right time to say. You may also want to try contacting some other people who may be able to help. For advice on how to do this and other useful information please go to <a href="http://www.emptyhomes.com/getinvolved/campaign.html">http://www.emptyhomes.com/getinvolved/campaign.html</a>.</p> -EOF +') %] [% ELSE %] - _(<<EOF); -<p>Getting empty homes back into use can be difficult, but by now a good council +[% loc('<p>Getting empty homes back into use can be difficult, but by now a good council will have made a lot of progress and reported what they have done on the website. Even so properties can remain empty for many months if the owner is unwilling or the property is in very poor repair. If nothing has happened or you are not satisfied with the progress the council is making, now is the right -time to say so. We think it's a good idea to contact some other people who +time to say so. We think it’s a good idea to contact some other people who may be able to help or put pressure on the council For advice on how to do this and other useful information please go to <a href="http://www.emptyhomes.com/getinvolved/campaign.html">http://www.emptyhomes.com/getinvolved/campaign.html</a>.</p> -EOF +') %] [% END %] [% END %] |