diff options
Diffstat (limited to 't')
-rw-r--r-- | t/app/controller/admin.t | 352 | ||||
-rw-r--r-- | t/app/controller/alert.t | 2 | ||||
-rw-r--r-- | t/app/controller/alert_new.t | 210 | ||||
-rw-r--r-- | t/app/controller/around.t | 31 | ||||
-rw-r--r-- | t/app/controller/index.t | 19 | ||||
-rw-r--r-- | t/app/controller/questionnaire.t | 26 | ||||
-rw-r--r-- | t/app/controller/report_display.t | 31 | ||||
-rw-r--r-- | t/app/controller/report_interest_count.t | 143 | ||||
-rw-r--r-- | t/app/controller/report_new.t | 385 | ||||
-rw-r--r-- | t/app/controller/report_new_open311.t | 2 | ||||
-rw-r--r-- | t/app/controller/report_updates.t | 43 | ||||
-rw-r--r-- | t/app/controller/reports.t | 42 | ||||
-rw-r--r-- | t/app/helpers/send_email.t | 2 | ||||
-rw-r--r-- | t/app/model/alert_type.t | 47 | ||||
-rw-r--r-- | t/app/model/problem.t | 55 | ||||
-rw-r--r-- | t/cobrand/councils.t | 18 | ||||
-rw-r--r-- | t/cobrand/get_council_sender.t | 8 | ||||
-rw-r--r-- | t/i18n.t | 11 | ||||
-rw-r--r-- | t/open311.t | 79 | ||||
-rw-r--r-- | t/open311/getservicerequestupdates.t | 57 | ||||
-rw-r--r-- | t/open311/populate-service-list.t | 178 |
21 files changed, 1464 insertions, 277 deletions
diff --git a/t/app/controller/admin.t b/t/app/controller/admin.t index 09d99cfdf..9ec15ec21 100644 --- a/t/app/controller/admin.t +++ b/t/app/controller/admin.t @@ -163,19 +163,32 @@ subtest 'check contact creation' => sub { $mech->get_ok('/admin/council_contacts/2650'); $mech->submit_form_ok( { with_fields => { - category => 'test category', - email => 'test@example.com', - note => 'test note', + category => 'test category', + email => 'test@example.com', + note => 'test note', + non_public => undef, } } ); $mech->content_contains( 'test category' ); $mech->content_contains( '<td>test@example.com' ); $mech->content_contains( '<td>test note' ); + $mech->content_contains( '<td>Public' ); + + $mech->submit_form_ok( { with_fields => { + category => 'private category', + email => 'test@example.com', + note => 'test note', + non_public => 'on', + } } ); + + $mech->content_contains( 'private category' ); + $mech->content_contains( '<td>Non Public' ); $mech->submit_form_ok( { with_fields => { category => 'test/category', email => 'test@example.com', note => 'test/note', + non_public => 'on', } } ); $mech->get_ok('/admin/council_edit/2650/test/category'); @@ -187,11 +200,21 @@ subtest 'check contact editing' => sub { $mech->submit_form_ok( { with_fields => { email => 'test2@example.com', note => 'test2 note', + non_public => undef, } } ); $mech->content_contains( 'test category' ); $mech->content_contains( '<td>test2@example.com' ); $mech->content_contains( '<td>test2 note' ); + $mech->content_contains( '<td>Public' ); + + $mech->submit_form_ok( { with_fields => { + email => 'test2@example.com', + note => 'test2 note', + non_public => 'on', + } } ); + + $mech->content_contains( '<td>Non Public' ); $mech->get_ok('/admin/council_edit/2650/test%20category'); $mech->content_contains( '<td><strong>test2@example.com' ); @@ -293,206 +316,229 @@ ok $report, "created test report - $report_id"; foreach my $test ( { description => 'edit report title', - fields => { - title => 'Report to Edit', - detail => 'Detail for Report to Edit', - state => 'confirmed', - name => 'Test User', - email => $user->email, - anonymous => 0, - flagged => undef, - }, - changes => { - title => 'Edited Report', + fields => { + title => 'Report to Edit', + detail => 'Detail for Report to Edit', + state => 'confirmed', + name => 'Test User', + email => $user->email, + anonymous => 0, + flagged => undef, + non_public => undef, }, - log_count => 1, - log_entries => [ qw/edit/ ], - resend => 0, + changes => { title => 'Edited Report', }, + log_count => 1, + log_entries => [qw/edit/], + resend => 0, }, { description => 'edit report description', - fields => { - title => 'Edited Report', - detail => 'Detail for Report to Edit', - state => 'confirmed', - name => 'Test User', - email => $user->email, - anonymous => 0, - flagged => undef, - }, - changes => { - detail => 'Edited Detail', + fields => { + title => 'Edited Report', + detail => 'Detail for Report to Edit', + state => 'confirmed', + name => 'Test User', + email => $user->email, + anonymous => 0, + flagged => undef, + non_public => undef, }, - log_count => 2, - log_entries => [ qw/edit edit/ ], - resend => 0, + changes => { detail => 'Edited Detail', }, + log_count => 2, + log_entries => [qw/edit edit/], + resend => 0, }, { description => 'edit report user name', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'confirmed', - name => 'Test User', - email => $user->email, - anonymous => 0, - flagged => undef, - }, - changes => { - name => 'Edited User', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Test User', + email => $user->email, + anonymous => 0, + flagged => undef, + non_public => undef, }, - log_count => 3, - log_entries => [ qw/edit edit edit/ ], - resend => 0, - user => $user, + changes => { name => 'Edited User', }, + log_count => 3, + log_entries => [qw/edit edit edit/], + resend => 0, + user => $user, }, { description => 'edit report set flagged true', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'confirmed', - name => 'Edited User', - email => $user->email, - anonymous => 0, - flagged => undef, + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Edited User', + email => $user->email, + anonymous => 0, + flagged => undef, + non_public => undef, }, changes => { - flagged => 'on', + flagged => 'on', }, - log_count => 4, - log_entries => [ qw/edit edit edit edit/ ], - resend => 0, - user => $user, + log_count => 4, + log_entries => [qw/edit edit edit edit/], + resend => 0, + user => $user, }, { description => 'edit report user email', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'confirmed', - name => 'Edited User', - email => $user->email, - anonymous => 0, - flagged => 'on', - }, - changes => { - email => $user2->email, + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Edited User', + email => $user->email, + anonymous => 0, + flagged => 'on', + non_public => undef, }, - log_count => 5, - log_entries => [ qw/edit edit edit edit edit/ ], - resend => 0, - user => $user2, + changes => { email => $user2->email, }, + log_count => 5, + log_entries => [qw/edit edit edit edit edit/], + resend => 0, + user => $user2, }, { description => 'change state to unconfirmed', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'confirmed', - name => 'Edited User', - email => $user2->email, - anonymous => 0, - flagged => 'on', - }, - changes => { - state => 'unconfirmed' + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Edited User', + email => $user2->email, + anonymous => 0, + flagged => 'on', + non_public => undef, }, + changes => { state => 'unconfirmed' }, log_count => 6, - log_entries => [ qw/state_change edit edit edit edit edit/ ], - resend => 0, + log_entries => [qw/state_change edit edit edit edit edit/], + resend => 0, }, { description => 'change state to confirmed', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'unconfirmed', - name => 'Edited User', - email => $user2->email, - anonymous => 0, - flagged => 'on', - }, - changes => { - state => 'confirmed' + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'unconfirmed', + name => 'Edited User', + email => $user2->email, + anonymous => 0, + flagged => 'on', + non_public => undef, }, + changes => { state => 'confirmed' }, log_count => 7, - log_entries => [ qw/state_change state_change edit edit edit edit edit/ ], - resend => 0, + log_entries => [qw/state_change state_change edit edit edit edit edit/], + resend => 0, }, { description => 'change state to fixed', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'confirmed', - name => 'Edited User', - email => $user2->email, - anonymous => 0, - flagged => 'on', - }, - changes => { - state => 'fixed' + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Edited User', + email => $user2->email, + anonymous => 0, + flagged => 'on', + non_public => undef, }, + changes => { state => 'fixed' }, log_count => 8, - log_entries => [ qw/state_change state_change state_change edit edit edit edit edit/ ], + log_entries => + [qw/state_change state_change state_change edit edit edit edit edit/], resend => 0, }, { description => 'change state to hidden', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'fixed', - name => 'Edited User', - email => $user2->email, - anonymous => 0, - flagged => 'on', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'fixed', + name => 'Edited User', + email => $user2->email, + anonymous => 0, + flagged => 'on', + non_public => undef, }, - changes => { - state => 'hidden' - }, - log_count => 9, - log_entries => [ qw/state_change state_change state_change state_change edit edit edit edit edit/ ], + changes => { state => 'hidden' }, + log_count => 9, + log_entries => [ + qw/state_change state_change state_change state_change edit edit edit edit edit/ + ], resend => 0, }, { description => 'edit and change state', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'hidden', - name => 'Edited User', - email => $user2->email, - anonymous => 0, - flagged => 'on', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'hidden', + name => 'Edited User', + email => $user2->email, + anonymous => 0, + flagged => 'on', + non_public => undef, }, changes => { - state => 'confirmed', + state => 'confirmed', anonymous => 1, }, - log_count => 11, - log_entries => [ qw/edit state_change state_change state_change state_change state_change edit edit edit edit edit/ ], + log_count => 11, + log_entries => [ + qw/edit state_change state_change state_change state_change state_change edit edit edit edit edit/ + ], resend => 0, }, { description => 'resend', - fields => { - title => 'Edited Report', - detail => 'Edited Detail', - state => 'confirmed', - name => 'Edited User', - email => $user2->email, - anonymous => 1, - flagged => 'on', - }, - changes => { + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Edited User', + email => $user2->email, + anonymous => 1, + flagged => 'on', + non_public => undef, }, - log_count => 12, - log_entries => [ qw/resend edit state_change state_change state_change state_change state_change edit edit edit edit edit/ ], + changes => {}, + log_count => 12, + log_entries => [ + qw/resend edit state_change state_change state_change state_change state_change edit edit edit edit edit/ + ], resend => 1, }, -) { + { + description => 'non public', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Edited User', + email => $user2->email, + anonymous => 1, + flagged => 'on', + non_public => undef, + }, + changes => { + non_public => 'on', + }, + log_count => 13, + log_entries => [ + qw/edit resend edit state_change state_change state_change state_change state_change edit edit edit edit edit/ + ], + resend => 0, + }, + ) +{ subtest $test->{description} => sub { $log_entries->reset; $mech->get_ok("/admin/report_edit/$report_id"); @@ -523,6 +569,8 @@ foreach my $test ( } $test->{changes}->{flagged} = 1 if $test->{changes}->{flagged}; + $test->{changes}->{non_public} = 1 if $test->{changes}->{non_public}; + is $report->$_, $test->{changes}->{$_}, "$_ updated" for grep { $_ ne 'email' } keys %{ $test->{changes} }; if ( $test->{user} ) { @@ -547,6 +595,7 @@ subtest 'change email to new user' => sub { email => $report->user->email, anonymous => 1, flagged => 'on', + non_public => 'on', }; is_deeply( $mech->visible_form_values(), $fields, 'initial form values' ); @@ -1017,9 +1066,8 @@ subtest 'report search' => sub { }; subtest 'search abuse' => sub { - $mech->get_ok( '/admin/search_abuse?search=example' ); - - $mech->content_contains('test4@example.com'); + $mech->get_ok( '/admin/search_users?search=example' ); + $mech->content_like(qr/test4\@example.com.*\n.*\n.*Email in abuse table/); }; subtest 'show flagged entries' => sub { diff --git a/t/app/controller/alert.t b/t/app/controller/alert.t index e1ebbecb6..3d95bef6d 100644 --- a/t/app/controller/alert.t +++ b/t/app/controller/alert.t @@ -40,7 +40,7 @@ $mech->get_ok('/alert/list?pc=High Street'); $mech->content_contains('We found more than one match for that location'); $mech->get_ok('/alert/list?pc='); -$mech->content_contains('hat location does not appear to be covered by a council'); +$mech->content_contains('To find out what local alerts we have for you'); $mech->get_ok('/alert/list?pc=GL502PR'); $mech->content_contains('Problems within the boundary of'); diff --git a/t/app/controller/alert_new.t b/t/app/controller/alert_new.t index d66590c57..c849b9485 100644 --- a/t/app/controller/alert_new.t +++ b/t/app/controller/alert_new.t @@ -330,7 +330,7 @@ subtest "Test two-tier council alerts" => sub { feed => $alert->{feed}, } } ); - is $mech->uri->path, $alert->{result}; + is $mech->uri->path, $alert->{result}, 'Redirected to right RSS feed'; } }; @@ -390,7 +390,7 @@ subtest "Test normal alert signups and that alerts are sent" => sub { used_map => 1, name => $user1->name, anonymous => 0, - state => 'confirmed', + state => 'fixed - user', confirmed => $dt, lastupdate => $dt, whensent => $dt->clone->add( minutes => 5 ), @@ -430,7 +430,7 @@ subtest "Test normal alert signups and that alerts are sent" => sub { problem_id => $report_id, user_id => $user2->id, name => 'Anonymous User', - mark_fixed => 'false', + mark_fixed => 'true', text => 'This is some more update text', state => 'confirmed', confirmed => $dt->clone->add( hours => 8 ), @@ -450,13 +450,23 @@ subtest "Test normal alert signups and that alerts are sent" => sub { $count++ if $_->body =~ /The following nearby problems have been added:/; $count++ if $_->body =~ /\s+-\s+Testing/; } - is $count, 5, 'Five emails with the right things in them'; + is $count, 5, 'Three emails, with five matching lines in them'; my $email = $emails[0]; like $email->body, qr/Other User/, 'Update name given'; unlike $email->body, qr/Anonymous User/, 'Update name not given'; - my ( $url, $url_token ) = $emails[0]->body =~ m{http://\S+(/A/(\S+))}; + # The update alert was to the problem reporter, so has a login update URL + $mech->get_ok( "/report/$report_id" ); + $mech->content_lacks( 'has not been fixed' ); + my ($url) = $email->body =~ m{(http://\S+/M/\S+)}; + ok $url, "extracted update url '$url'"; + $mech->get_ok( $url ); + is $mech->uri->path, "/report/" . $report_id, "redirected to report page"; + $mech->content_contains( 'has not been fixed' ); + $mech->logged_in_ok; + + ($url) = $emails[0]->body =~ m{http://\S+(/A/\S+)}; $mech->get_ok( $url ); $mech->content_contains('successfully deleted'); @@ -464,4 +474,194 @@ subtest "Test normal alert signups and that alerts are sent" => sub { $mech->delete_user($user2); }; +for my $test ( + { + desc => 'check non public reports are not included in council problems alerts', + alert_params => { + alert_type => 'council_problems', + parameter => '2651', + parameter2 => '2651', + } + }, + { + desc => 'check non public reports are not included in ward problems alerts', + alert_params => { + alert_type => 'ward_problems', + parameter => '2651', + parameter2 => '20728', + } + }, + { + desc => 'check non public reports are not included in local problems alerts', + alert_params => { + alert_type => 'local_problems', + parameter => '-3.189944', + parameter2 => '55.951963', + } + }, + { + desc => 'check non public reports are not included in area problems alerts', + alert_params => { + alert_type => 'area_problems', + parameter => '20728', + parameter2 => '20728', + } + }, +) { + subtest $test->{desc} => sub { + my $user1 = FixMyStreet::App->model('DB::User') + ->find_or_create( { email => 'reporter@example.com', name => 'Reporter User' } ); + ok $user1, "created test user"; + $user1->alerts->delete; + + my $user2 = FixMyStreet::App->model('DB::User') + ->find_or_create( { email => 'alerts@example.com', name => 'Alert User' } ); + ok $user2, "created test user"; + $user2->alerts->delete; + + my $dt = DateTime->now->add( minutes => -30 ); + my $r_dt = $dt->clone->add( minutes => 20 ); + + my $alert_params = $test->{alert_params}; + $alert_params->{user} = $user1; + $alert_params->{whensubscribed} = $dt; + $alert_params->{confirmed} = 1; + + my $alert_user1 = FixMyStreet::App->model('DB::Alert')->create( $alert_params ); + ok $alert_user1, "alert created"; + + 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 => 'Alert test for non public reports', + detail => 'Testing Detail', + used_map => 1, + name => $user2->name, + anonymous => 0, + state => 'confirmed', + confirmed => $r_dt, + lastupdate => $r_dt, + whensent => $r_dt->clone->add( minutes => 5 ), + lang => 'en-gb', + service => '', + cobrand => 'default', + cobrand_data => '', + send_questionnaire => 1, + latitude => '55.951963', + longitude => '-3.189944', + user_id => $user2->id, + non_public => 1, + } ); + + $mech->clear_emails_ok; + FixMyStreet::App->model('DB::AlertType')->email_alerts(); + $mech->email_count_is(0); + + $report->update( { non_public => 0 } ); + FixMyStreet::App->model('DB::AlertType')->email_alerts(); + $mech->email_count_is(1); + my $email = $mech->get_email; + like $email->body, qr/Alert\s+test\s+for\s+non\s+public\s+reports/, 'alert contains public report'; + + $mech->delete_user( $user1 ); + $mech->delete_user( $user2 ); + }; +} + +subtest 'check new updates alerts for non public reports only go to report owner' => sub { + my $user1 = FixMyStreet::App->model('DB::User') + ->find_or_create( { email => 'reporter@example.com', name => 'Reporter User' } ); + ok $user1, "created test user"; + $user1->alerts->delete; + + my $user2 = FixMyStreet::App->model('DB::User') + ->find_or_create( { email => 'alerts@example.com', name => 'Alert User' } ); + ok $user2, "created test user"; + $user2->alerts->delete; + + my $user3 = FixMyStreet::App->model('DB::User') + ->find_or_create( { email => 'updates@example.com', name => 'Update User' } ); + ok $user3, "created test user"; + + my $dt = DateTime->now->add( minutes => -30 ); + my $r_dt = $dt->clone->add( minutes => 20 ); + + 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 => 'Alert test for non public reports', + detail => 'Testing Detail', + used_map => 1, + name => $user2->name, + anonymous => 0, + state => 'confirmed', + confirmed => $r_dt, + lastupdate => $r_dt, + whensent => $r_dt->clone->add( minutes => 5 ), + lang => 'en-gb', + service => '', + cobrand => 'default', + cobrand_data => '', + send_questionnaire => 1, + latitude => '55.951963', + longitude => '-3.189944', + user_id => $user2->id, + non_public => 1, + } ); + + my $update = FixMyStreet::App->model('DB::Comment')->create( { + problem_id => $report->id, + user_id => $user3->id, + name => 'Anonymous User', + mark_fixed => 'false', + text => 'This is some more update text', + state => 'confirmed', + confirmed => $r_dt->clone->add( minutes => 8 ), + anonymous => 't', + } ); + + my $alert_user1 = FixMyStreet::App->model('DB::Alert')->create( { + user => $user1, + alert_type => 'new_updates', + parameter => $report->id, + confirmed => 1, + whensubscribed => $dt, + } ); + ok $alert_user1, "alert created"; + + + $mech->clear_emails_ok; + FixMyStreet::App->model('DB::AlertType')->email_alerts(); + $mech->email_count_is(0); + + my $alert_user2 = FixMyStreet::App->model('DB::Alert')->create( { + user => $user2, + alert_type => 'new_updates', + parameter => $report->id, + confirmed => 1, + whensubscribed => $dt, + } ); + ok $alert_user2, "alert created"; + + FixMyStreet::App->model('DB::AlertType')->email_alerts(); + $mech->email_count_is(1); + my $email = $mech->get_email; + like $email->body, qr/This is some more update text/, 'alert contains update text'; + + $mech->clear_emails_ok; + $report->update( { non_public => 0 } ); + FixMyStreet::App->model('DB::AlertType')->email_alerts(); + $mech->email_count_is(1); + $email = $mech->get_email; + like $email->body, qr/This is some more update text/, 'alert contains update text'; + + $mech->delete_user( $user1 ); + $mech->delete_user( $user2 ); + $mech->delete_user( $user3 ); +}; + done_testing(); diff --git a/t/app/controller/around.t b/t/app/controller/around.t index db03e00f4..d973543ce 100644 --- a/t/app/controller/around.t +++ b/t/app/controller/around.t @@ -66,6 +66,11 @@ foreach my $test ( latitude => '51.50101', longitude => '-0.141587', }, + { + pc => 'TQ 388 773', + latitude => '51.478074', + longitude => '-0.001966', + }, ) { subtest "check lat/lng for '$test->{pc}'" => sub { @@ -78,4 +83,30 @@ foreach my $test ( }; } +subtest 'check non public reports are not displayed on around page' => sub { + my $params = { + postcode => 'EH99 1SP', + latitude => 55.9519637512, + longitude => -3.17492254484, + }; + my @edinburgh_problems = + $mech->create_problems_for_council( 5, 2651, 'Around page', $params ); + + $mech->get_ok('/'); + $mech->submit_form_ok( { with_fields => { pc => 'EH99 1SP' } }, + "good location" ); + $mech->content_contains( 'Around page Test 3 for 2651', + 'problem to be marked non public visible' ); + + my $private = $edinburgh_problems[2]; + ok $private->update( { non_public => 1 } ), 'problem marked non public'; + + $mech->get_ok('/'); + $mech->submit_form_ok( { with_fields => { pc => 'EH99 1SP' } }, + "good location" ); + $mech->content_lacks( 'Around page Test 3 for 2651', + 'problem marked non public is not visible' ); +}; + + done_testing(); diff --git a/t/app/controller/index.t b/t/app/controller/index.t index bf9124ee0..462b21064 100644 --- a/t/app/controller/index.t +++ b/t/app/controller/index.t @@ -55,4 +55,23 @@ subtest "does pc, (x,y), (e,n) or (lat,lon) go to /around" => sub { } }; +$mech->delete_problems_for_council( 2651 ); + +my $problem_rs = FixMyStreet::App->model('DB::Problem'); +my $num = $problem_rs->count; + +my @edinburgh_problems = $mech->create_problems_for_council(5, 2651, 'Front page'); +is scalar @edinburgh_problems, 5, 'correct number of edinburgh problems created'; + +$mech->get_ok('/report/' . $edinburgh_problems[2]->id); +$mech->content_contains('Front page Test 3 for 2651', 'problem to be marked non public visible'); +is $problem_rs->count, $num+5; + +my $private = $edinburgh_problems[2]; +ok $private->update( { non_public => 1 } ), 'problem marked non public'; + +ok $mech->get('/report/' . $edinburgh_problems[2]->id); +is $mech->res->code, 403, 'page forbidden'; +is $problem_rs->count, $num+5; + done_testing(); diff --git a/t/app/controller/questionnaire.t b/t/app/controller/questionnaire.t index 872a1733c..d8d1eb4f3 100644 --- a/t/app/controller/questionnaire.t +++ b/t/app/controller/questionnaire.t @@ -190,6 +190,25 @@ foreach my $test ( # update => 'Dummy', Error for not setting this tested below }, }, + { + desc => 'Closed report, said fixed, reported before, no update, no further questionnaire', + problem_state => 'closed', + fields => { + been_fixed => 'Yes', + reported => 'Yes', + another => 'No', + }, + }, + { + desc => 'Closed report, said not fixed, reported before, no update, no further questionnaire', + problem_state => 'closed', + fields => { + been_fixed => 'No', + reported => 'Yes', + another => 'No', + }, + lastupdate_static => 1, + }, ) { subtest $test->{desc} => sub { $report->state ( $test->{problem_state} ); @@ -224,7 +243,8 @@ foreach my $test ( $result = 'fixed' if $test->{fields}{been_fixed} eq 'Yes' && $test->{problem_state} eq 'fixed'; - $result = 'confirmed' if $test->{fields}{been_fixed} eq 'No'; + $result = 'confirmed' if $test->{fields}{been_fixed} eq 'No' && $test->{problem_state} ne 'closed'; + $result = 'closed' if $test->{fields}{been_fixed} eq 'No' && $test->{problem_state} eq 'closed'; $result = 'unknown' if $test->{fields}{been_fixed} eq 'Unknown'; my $another = 0; @@ -234,10 +254,12 @@ foreach my $test ( $mech->content_like( qr/<title>[^<]*Questionnaire/m ); $mech->content_contains( 'glad to hear it’s been fixed' ) if $result =~ /fixed/; + $mech->content_lacks( 'glad to hear it’s been fixed' ) + if $result !~ /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'; + if $result eq 'confirmed' || $result eq 'closed'; # Check the database has the right information $report->discard_changes; diff --git a/t/app/controller/report_display.t b/t/app/controller/report_display.t index fde52860a..82c98dc5c 100644 --- a/t/app/controller/report_display.t +++ b/t/app/controller/report_display.t @@ -16,6 +16,11 @@ my $user = ->find_or_create( { email => 'test@example.com', name => 'Test User' } ); ok $user, "created test user"; +my $user2 = + FixMyStreet::App->model('DB::User') + ->find_or_create( { email => 'test2@example.com', name => 'Other User' } ); +ok $user2, "created test user"; + my $dt = DateTime->new( year => 2011, month => 04, @@ -98,6 +103,32 @@ subtest "change report to hidden and check for 410 status" => sub { ok $report->update( { state => 'confirmed' } ), 'confirm report again'; }; +subtest "change report to non_public and check for 403 status" => sub { + ok $report->update( { non_public => 1 } ), 'make report non public'; + ok $mech->get("/report/$report_id"), "get '/report/$report_id'"; + is $mech->res->code, 403, "access denied"; + is $mech->uri->path, "/report/$report_id", "at /report/$report_id"; + $mech->content_contains('That report cannot be viewed on FixMyStreet.'); + ok $report->update( { non_public => 0 } ), 'make report public'; +}; + +subtest "check owner of report can view non public reports" => sub { + ok $report->update( { non_public => 1 } ), 'make report non public'; + $mech->log_in_ok( $report->user->email ); + ok $mech->get("/report/$report_id"), "get '/report/$report_id'"; + is $mech->res->code, 200, "report can be viewed"; + is $mech->uri->path, "/report/$report_id", "at /report/$report_id"; + $mech->log_out_ok; + + $mech->log_in_ok( $user2->email ); + ok $mech->get("/report/$report_id"), "get '/report/$report_id'"; + is $mech->res->code, 403, "access denied to user who is not report creator"; + is $mech->uri->path, "/report/$report_id", "at /report/$report_id"; + $mech->content_contains('That report cannot be viewed on FixMyStreet.'); + $mech->log_out_ok; + ok $report->update( { non_public => 0 } ), 'make report public'; +}; + subtest "test a good report" => sub { $mech->get_ok("/report/$report_id"); is $mech->uri->path, "/report/$report_id", "at /report/$report_id"; diff --git a/t/app/controller/report_interest_count.t b/t/app/controller/report_interest_count.t new file mode 100644 index 000000000..dd44a83d4 --- /dev/null +++ b/t/app/controller/report_interest_count.t @@ -0,0 +1,143 @@ +use strict; +use warnings; +use Test::More; + +use FixMyStreet::TestMech; +use Web::Scraper; +use Path::Class; +use DateTime; + +my $mech = FixMyStreet::TestMech->new; + +# 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 $user2 = + FixMyStreet::App->model('DB::User') + ->find_or_create( { email => 'test2@example.com', name => 'Other User' } ); +ok $user2, "created test user"; + +my $dt = DateTime->new( + year => 2011, + month => 04, + day => 16, + hour => 15, + minute => 47, + second => 23 +); + +my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( + { + postcode => 'SW1A 1AA', + council => '2504', + areas => ',105255,11806,11828,2247,2504,', + category => 'Other', + title => 'Test 2', + detail => 'Test 2 Detail', + used_map => 't', + name => 'Test User', + anonymous => 'f', + state => 'confirmed', + confirmed => $dt->ymd . ' ' . $dt->hms, + lang => 'en-gb', + service => '', + cobrand => 'default', + cobrand_data => '', + send_questionnaire => 't', + latitude => '51.5016605453401', + longitude => '-0.142497580865087', + user_id => $user->id, + } +); +my $report_id = $report->id; +ok $report, "created test report - $report_id"; + +SKIP: { + skip( "Need 'fixmybarangay' in ALLOWED_COBRANDS config", 29 ) + unless FixMyStreet::Cobrand->exists('fixmybarangay'); + for my $test ( + { + desc => 'if not from council then no supporter button', + from_council => 0, + support_string => 'No supporters', + }, + { + desc => 'from council user can increment supported count', + from_council => 2504, + support_string => 'No supporters', + updated_support => '1 supporter' + }, + { + desc => 'correct grammar for more than one supporter', + from_council => 2504, + support_string => '1 supporter', + updated_support => '2 supporters' + }, + ) { + subtest $test->{desc} => sub { + ok $mech->host('fixmybarangay.com'), 'changed to fixmybarangay'; + $mech->log_in_ok( $user->email ); + $user->from_council( $test->{from_council} ); + $user->update; + + $report->discard_changes; + $report->council( $test->{report_council} ); + $report->update; + + $mech->get_ok("/report/$report_id"); + $mech->content_contains( $test->{support_string} ); + + if ( $test->{from_council} ) { + $mech->content_contains('Add support'); + $mech->submit_form_ok( { form_number => 1 } ); + + is $mech->uri, "http://fixmybarangay.com/report/$report_id", 'add support redirects to report page'; + + $mech->content_contains($test->{updated_support}); + } else { + $mech->content_lacks( 'Add support' ); + } + }; + } + + subtest 'check non council user cannot increment support count' => sub { + ok $mech->host('fixmybarangay.com'), 'changed to fixmybarangay'; + $report->discard_changes; + $report->interest_count(1); + ok $report->update(), 'updated interest count'; + + $report->discard_changes; + is $report->interest_count, 1, 'correct interest count'; + + $mech->get_ok("/report/$report_id"); + $mech->content_contains( '1 supporter' ); + + $mech->post_ok("/report/support", { id => $report_id } ); + + is $mech->uri, "http://fixmybarangay.com/report/$report_id", 'add support redirects to report page'; + + $mech->content_contains( '1 supporter' ); + }; +}; + +subtest 'check support details not shown if not enabled in cobrand' => sub { + ok $mech->host('fixmystreet.com'), 'changed to fixmystreet'; + + $report->interest_count(1); + ok $report->update, 'updated interest count'; + + $mech->get_ok("/report/$report_id"); + $mech->content_lacks( '1 supporter' ); +}; + +$report->discard_changes; +$report->council( 2504 ); +$report->update; + +# tidy up +$mech->delete_user('test@example.com'); +done_testing(); diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t index 65bd71af2..6cfa67116 100644 --- a/t/app/controller/report_new.t +++ b/t/app/controller/report_new.t @@ -788,6 +788,74 @@ foreach my $test ( } +subtest "test report creation for a category that is non public" => sub { + $mech->log_out_ok; + $mech->clear_emails_ok; + + # check that the user does not exist + my $test_email = 'test-2@example.com'; + + my $user = FixMyStreet::App->model('DB::User')->find_or_create( { email => $test_email } ); + ok $user, "test user does exist"; + + $contact1->update( { non_public => 1 } ); + + # submit initial pc form + $mech->get_ok('/around'); + $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } }, + "submit location" ); + + # click through to the report page + $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, + "follow 'skip this step' link" ); + + $mech->submit_form_ok( + { + button => 'submit_register', + with_fields => { + title => 'Test Report', + detail => 'Test report details.', + photo => '', + email => 'test-2@example.com', + name => 'Joe Bloggs', + category => 'Street lighting', + } + }, + "submit good details" + ); + + # find the report + my $report = $user->problems->first; + ok $report, "Found the report"; + + # Check the report is not public + ok $report->non_public, 'report is not public'; + + my $email = $mech->get_email; + ok $email, "got an email"; + like $email->body, qr/confirm the problem/i, "confirm the problem"; + + my ($url) = $email->body =~ m{(http://\S+)}; + ok $url, "extracted confirm url '$url'"; + + # confirm token + $mech->get_ok($url); + $report->discard_changes; + + is $report->state, 'confirmed', "Report is now confirmed"; + + $mech->logged_in_ok; + $mech->get_ok( '/report/' . $report->id, 'user can see own report' ); + + $mech->log_out_ok; + ok $mech->get("/report/" . $report->id), "fetched report"; + is $mech->res->code, 403, "access denied to report"; + + # cleanup + $mech->delete_user($user); + $contact1->update( { non_public => 0 } ); +}; + $contact2->category( "Pothol\xc3\xa9s" ); $contact2->update; $mech->get_ok( '/report/new/ajax?latitude=' . $saved_lat . '&longitude=' . $saved_lon ); @@ -960,71 +1028,288 @@ for my $test ( }; } +subtest 'user title not reset if no user title in submission' => sub { + $mech->log_out_ok; + $mech->host( 'http://fixmystreet.com' ); + + my $user = $mech->log_in_ok( 'userwithtitle@example.com' ); + + ok $user->update( + { + name => 'Has Title', + phone => '0789 654321', + title => 'MR', + } + ), + "set users details"; + + + my $submission_fields = { + title => "Test Report", + detail => 'Test report details.', + photo => '', + name => 'Has Title', + may_show_name => '1', + phone => '07903 123 456', + category => 'Trees', + }; + + $mech->get_ok('/'); + $mech->submit_form_ok( { with_fields => { pc => 'EH99 1SP', } }, + "submit location" ); + $mech->follow_link_ok( + { text_regex => qr/skip this step/i, }, + "follow 'skip this step' link" + ); + + my $fields = $mech->visible_form_values('mapSkippedForm'); + ok !exists( $fields->{fms_extra_title} ), 'user title field not displayed'; + + $mech->submit_form_ok( { with_fields => $submission_fields }, + "submit good details" ); + + $user->discard_changes; + my $report = $user->problems->first; + ok $report, "Found report"; + is $report->title, "Test Report", "Report title correct"; + is $user->title, 'MR', 'User title unchanged'; +}; + SKIP: { skip( "Need 'lichfielddc' in ALLOWED_COBRANDS config", 100 ) unless FixMyStreet::Cobrand->exists('lichfielddc'); - my $test_email = 'test-22@example.com'; - $mech->host( 'http://lichfielddc.fixmystreet.com/' ); - $mech->clear_emails_ok; - $mech->log_out_ok; - - $mech->get_ok('/around'); - $mech->content_contains( "Lichfield District Council FixMyStreet" ); - $mech->submit_form_ok( { with_fields => { pc => 'WS13 7RD' } }, "submit location" ); - $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" ); - $mech->submit_form_ok( + for my $test ( { - button => 'submit_register', - with_fields => { - title => 'Test Report', - detail => 'Test report details.', - photo => '', - name => 'Joe Bloggs', - may_show_name => '1', - email => $test_email, - phone => '07903 123 456', - category => 'Street lighting', - } + desc => 'confirm link for cobrand council in two tier cobrand links to cobrand site', + category => 'Trees', + council => 2434, + link_base => 'http://lichfielddc.localhost/', + national => 0, + button => 'submit_register', }, - "submit good details" - ); - is_deeply $mech->page_errors, [], "check there were no errors"; + { + desc => 'confirm link for non cobrand council in two tier cobrand links to national site', + category => 'Street Lighting', + council => 2240, + link_base => 'http://localhost/', + national => 1, + button => 'submit_register', + }, + { + desc => 'confirm redirect for cobrand council in two tier cobrand redirects to cobrand site', + category => 'Trees', + council => 2434, + link_base => 'lichfielddc.localhost', + national => 0, + redirect => 1, + }, + { + desc => 'confirm redirect for non cobrand council in two tier cobrand redirect to national site', + category => 'Street Lighting', + council => 2240, + link_base => 'localhost', + national => 1, + redirect => 1, + }, + ) { + subtest $test->{ desc } => sub { + my $test_email = 'test-22@example.com'; + $mech->host( 'http://lichfielddc.fixmystreet.com/' ); + $mech->clear_emails_ok; + $mech->log_out_ok; + + my $user = $mech->log_in_ok($test_email) if $test->{redirect}; + + $mech->get_ok('/around'); + $mech->content_contains( "Lichfield District Council FixMyStreet" ); + $mech->submit_form_ok( { with_fields => { pc => 'WS13 7RD' } }, "submit location" ); + $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" ); + my %optional_fields = $test->{redirect} ? () : + ( email => $test_email, phone => '07903 123 456' ); + + # we do this as otherwise test::www::mechanize::catalyst + # goes to the value set in ->host above irregardless and + # that is a 404. It works but it is not pleasant. + $mech->clear_host if $test->{redirect} && $test->{national}; + $mech->submit_form_ok( + { + button => $test->{button}, + with_fields => { + title => 'Test Report', + detail => 'Test report details.', + photo => '', + name => 'Joe Bloggs', + may_show_name => '1', + category => $test->{category}, + %optional_fields + } + }, + "submit good details" + ); + is_deeply $mech->page_errors, [], "check there were no errors"; + + # check that the user has been created/ not changed + $user = + FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); + ok $user, "user found"; + + # find the report + my $report = $user->problems->first; + ok $report, "Found the report"; + + # Check the report has been assigned appropriately + is $report->council, $test->{council}; + + if ( $test->{redirect} ) { + is $mech->uri->path, "/report/" . $report->id, "redirected to report page"; + is $mech->uri->host, $test->{link_base}, 'redirected to correct site'; + } else { + # receive token + my $email = $mech->get_email; + ok $email, "got an email"; + like $email->body, qr/confirm the problem/i, "confirm the problem"; + + my ($url) = $email->body =~ m{(http://\S+)}; + ok $url, "extracted confirm url '$url'"; + + # confirm token + $mech->get_ok($url); + + $mech->content_contains( $test->{link_base} . 'report/' . + $report->id, 'confirm page links to correct site' ); + + if ( $test->{national} ) { + # Shouldn't be found, as it was a county problem + is $mech->get( '/report/' . $report->id )->code, 404, "report not found"; + + # But should be on the main site + $mech->host( 'www.fixmystreet.com' ); + } + $mech->get_ok( '/report/' . $report->id ); + } - # check that the user has been created/ not changed - my $user = - FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); - ok $user, "user found"; + $report->discard_changes; + is $report->state, 'confirmed', "Report is now confirmed"; - # find the report - my $report = $user->problems->first; - ok $report, "Found the report"; + is $report->name, 'Joe Bloggs', 'name updated correctly'; - # Check the report has been assigned appropriately - is $report->council, 2240; + $mech->delete_user($user); + }; + } +} - # receive token - my $email = $mech->get_email; - ok $email, "got an email"; - like $email->body, qr/confirm the problem/i, "confirm the problem"; +SKIP: { + skip( "Need 'seesomething' in ALLOWED_COBRANDS config", 100 ) + unless FixMyStreet::Cobrand->exists('seesomething'); - my ($url) = $email->body =~ m{(http://\S+)}; - ok $url, "extracted confirm url '$url'"; + $mech->host('seesomething.fixmystreet.com'); + $mech->clear_emails_ok; + $mech->log_out_ok; - # confirm token - $mech->get_ok($url); - $report->discard_changes; - is $report->state, 'confirmed', "Report is now confirmed"; + my $cobrand = FixMyStreet::Cobrand::SeeSomething->new(); - # Shouldn't be found, as it was a county problem - is $mech->get( '/report/' . $report->id )->code, 404, "report not found"; + my $bus_contact = FixMyStreet::App->model('DB::Contact')->find_or_create( { + %contact_params, + area_id => 2535, + category => 'Bus', + email => 'bus@example.com', + non_public => 1, + } ); - # But should be on the main site - $mech->host( 'www.fixmystreet.com' ); - $mech->get_ok( '/report/' . $report->id ); - is $report->name, 'Joe Bloggs', 'name updated correctly'; + for my $test ( { + desc => 'report with no user details works', + pc => 'WS1 4NH', + fields => { + detail => 'Test report details', + category => 'Bus', + subcategory => 'Smoking', + }, + email => $cobrand->anonymous_account->{email}, + }, + { + desc => 'report with user details works', + pc => 'WS1 4NH', + fields => { + detail => 'Test report details', + category => 'Bus', + subcategory => 'Smoking', + email => 'non_anon_user@example.com', + name => 'Non Anon', + }, + email => 'non_anon_user@example.com', + }, + { + desc => 'report with public category', + pc => 'WS1 4NH', + fields => { + detail => 'Test report details', + category => 'Bus', + subcategory => 'Smoking', + }, + email => $cobrand->anonymous_account->{email}, + public => 1, + } + ) { + subtest $test->{desc} => sub { + $mech->clear_emails_ok; + my $user = + FixMyStreet::App->model('DB::User')->find( { email => $test->{email} } ); + + if ( $user ) { + $user->alerts->delete; + $user->problems->delete; + $user->delete; + } - $mech->delete_user($user); + if ( $test->{public} ) { + $bus_contact->non_public(0); + $bus_contact->update; + } else { + $bus_contact->non_public(1); + $bus_contact->update; + } + + $mech->get_ok( '/around' ); + $mech->submit_form_ok( + { + with_fields => { + pc => $test->{pc}, + }, + }, + 'submit around form', + ); + $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" ); + + $mech->submit_form_ok( + { + with_fields => $test->{fields}, + }, + 'Submit form details with no user details', + ); + is_deeply $mech->page_errors, [], "check there were no errors"; + + $user = + FixMyStreet::App->model('DB::User')->find( { email => $test->{email} } ); + ok $user, "user found"; + + my $report = $user->problems->first; + ok $report, "Found the report"; + + $mech->email_count_is(0); + + ok $report->confirmed, 'Report is confirmed automatically'; + + if ( $test->{public} ) { + is $mech->uri->path, '/report/' . $report->id, 'redirects to report page'; + } else { + is $mech->uri->path, '/report/new', 'stays on report/new page'; + $mech->content_contains( 'Your report has been sent', 'use report created template' ); + } + }; + } + + $bus_contact->delete; } $contact1->delete; diff --git a/t/app/controller/report_new_open311.t b/t/app/controller/report_new_open311.t index 863571ad0..55c5a92e8 100644 --- a/t/app/controller/report_new_open311.t +++ b/t/app/controller/report_new_open311.t @@ -29,7 +29,7 @@ my $contact1 = FixMyStreet::App->model('DB::Contact')->find_or_create( { email => '100', extra => [ { description => 'Lamppost number', code => 'number', required => 'True' }, { description => 'Lamppost type', code => 'type', required => 'False', values => - { value => { Yellow => { key => 'modern' }, 'Gas' => { key => 'old' } } } + { value => [ { name => ['Gas'], key => ['old'] }, { name => [ 'Yellow' ], key => [ 'modern' ] } ] } } ], } ); diff --git a/t/app/controller/report_updates.t b/t/app/controller/report_updates.t index 6f139fc4e..2204a9d99 100644 --- a/t/app/controller/report_updates.t +++ b/t/app/controller/report_updates.t @@ -618,11 +618,52 @@ for my $test ( }; } +subtest 'check meta correct for comments marked confirmed but not marked open' => sub { + $report->comments->delete; + my $comment = FixMyStreet::App->model('DB::Comment')->create( + { + user => $user, + problem_id => $report->id, + text => 'update text', + confirmed => DateTime->now, + problem_state => 'confirmed', + anonymous => 0, + mark_open => 0, + mark_fixed => 0, + state => 'confirmed', + } + ); + + $mech->get_ok( "/report/" . $report->id ); + my $update_meta = $mech->extract_update_metas; + like $update_meta->[0], qr/reopened$/, + 'update meta does not say reopened'; + + $comment->update( { mark_open => 1, problem_state => undef } ); + $mech->get_ok( "/report/" . $report->id ); + $update_meta = $mech->extract_update_metas; + + unlike $update_meta->[0], qr/marked as open$/, + 'update meta does not says marked as open'; + like $update_meta->[0], qr/reopened$/, 'update meta does say reopened'; + + $comment->update( { mark_open => 0, problem_state => undef } ); + $mech->get_ok( "/report/" . $report->id ); + $update_meta = $mech->extract_update_metas; + + unlike $update_meta->[0], qr/marked as open$/, + 'update meta does not says marked as open'; + unlike $update_meta->[0], qr/reopened$/, 'update meta does not say reopened'; + }; + subtest "check comment with no status change has not status in meta" => sub { $mech->log_in_ok( $user->email ); $user->from_council( 0 ); $user->update; + my $comment = $report->comments->first; + $comment->update( { mark_fixed => 1, problem_state => 'fixed - council' } ); + $mech->get_ok("/report/$report_id"); $mech->submit_form_ok( @@ -642,6 +683,8 @@ subtest "check comment with no status change has not status in meta" => sub { my @updates = $report->comments->all; is scalar @updates, 2, 'correct number of updates'; + warn $updates[0]->problem_state; + warn $updates[1]->problem_state; my $update = pop @updates; is $report->state, 'fixed - council', 'correct report state'; diff --git a/t/app/controller/reports.t b/t/app/controller/reports.t index 801dbeddb..a4dab6597 100644 --- a/t/app/controller/reports.t +++ b/t/app/controller/reports.t @@ -1,10 +1,21 @@ use strict; use warnings; use Test::More; -use Test::WWW::Mechanize::Catalyst 'FixMyStreet::App'; +use FixMyStreet::TestMech; use mySociety::MaPit; +use FixMyStreet::App; +use DateTime; -ok( my $mech = Test::WWW::Mechanize::Catalyst->new, 'Created mech object' ); +ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' ); + +$mech->delete_problems_for_council( 2504 ); +$mech->delete_problems_for_council( 2651 ); + +my @edinburgh_problems = $mech->create_problems_for_council(3, 2651, 'All reports'); +my @westminster_problems = $mech->create_problems_for_council(5, 2504, 'All reports'); + +is scalar @westminster_problems, 5, 'correct number of westminster problems created'; +is scalar @edinburgh_problems, 3, 'correct number of edinburgh problems created'; # Run the cron script that makes the data for /reports so we don't get an error. system( "bin/cron-wrapper update-all-reports" ); @@ -13,8 +24,35 @@ system( "bin/cron-wrapper update-all-reports" ); $mech->get_ok('/reports'); $mech->title_like(qr{Summary reports}); $mech->content_contains('Birmingham'); + +my $stats = $mech->extract_report_stats; + +is $stats->{'City of Edinburgh Council'}->[1], 3, 'correct number of reports for Edinburgh'; +is $stats->{'Westminster City Council'}->[1], 5, 'correct number of reports for Westminster'; + $mech->follow_link_ok( { text_regex => qr/Birmingham/ } ); +$mech->get_ok('/reports/Westminster'); +$mech->title_like(qr/Westminster City Council/); +$mech->content_contains('Westminster City Council'); +$mech->content_contains('All reports Test 3 for 2504', 'problem to be marked non public visible'); + +my $problems = $mech->extract_problem_list; +is scalar @$problems, 5, 'correct number of problems displayed'; + +my $private = $westminster_problems[2]; +ok $private->update( { non_public => 1 } ), 'problem marked non public'; + +$mech->get_ok('/reports/Westminster'); +$problems = $mech->extract_problem_list; +is scalar @$problems, 4, 'only public problems are displayed'; + +$mech->content_lacks('All reports Test 3 for 2504', 'non public problem is not visible'); + +$mech->get_ok('/reports'); +$stats = $mech->extract_report_stats; +is $stats->{'Westminster City Council'}->[1], 5, 'non public reports included in stats'; + SKIP: { skip( "Need 'emptyhomes' in ALLOWED_COBRANDS config", 8 ) unless FixMyStreet::Cobrand->exists('emptyhomes'); diff --git a/t/app/helpers/send_email.t b/t/app/helpers/send_email.t index 8c043f701..3067d90f3 100644 --- a/t/app/helpers/send_email.t +++ b/t/app/helpers/send_email.t @@ -49,7 +49,7 @@ ok $email_as_string =~ s{\s+Message-ID:\s+\S.*?$}{}xms, "Found and stripped out my $expected_email_content = file(__FILE__)->dir->file('send_email_sample.txt')->slurp; my $name = FixMyStreet->config('CONTACT_NAME'); $name = "\"$name\"" if $name =~ / /; -my $sender = $name . ' <' . FixMyStreet->config('CONTACT_EMAIL') . '>'; +my $sender = $name . ' <' . FixMyStreet->config('DO_NOT_REPLY_EMAIL') . '>'; $expected_email_content =~ s{CONTACT_EMAIL}{$sender}; is $email_as_string, diff --git a/t/app/model/alert_type.t b/t/app/model/alert_type.t index 7df4c44c0..c592e9d3f 100644 --- a/t/app/model/alert_type.t +++ b/t/app/model/alert_type.t @@ -22,6 +22,10 @@ my $user2 = ->find_or_create( { email => 'commenter@example.com', name => 'Commenter' } ); ok $user2, "created comment user"; +my $user3 = + FixMyStreet::App->model('DB::User') + ->find_or_create( { email => 'bystander@example.com', name => 'Bystander' } ); +ok $user3, "created bystander"; my $dt = DateTime->new( year => 2011, @@ -96,6 +100,16 @@ my $alert = FixMyStreet::App->model('DB::Alert')->find_or_create( } ); +my $alert3 = FixMyStreet::App->model('DB::Alert')->find_or_create( + { + user => $user3, + parameter => $report_id, + alert_type => 'new_updates', + whensubscribed => $dt->ymd . ' ' . $dt->hms, + confirmed => 1, + } +); + for my $test ( { state => 'closed', @@ -115,7 +129,7 @@ for my $test ( my $sent = FixMyStreet::App->model('DB::AlertSent')->search( { - alert_id => $alert->id, + alert_id => [ $alert->id, $alert3->id ], parameter => $comment->id, } )->delete; @@ -125,18 +139,25 @@ for my $test ( FixMyStreet::App->model('DB::AlertType')->email_alerts(); - $mech->email_count_is( 1 ); - my $email = $mech->get_email; + $mech->email_count_is( 2 ); + my @emails = $mech->get_email; my $msg = $test->{msg}; - my $body = $email->body; - - like $body, qr/$msg/, 'email says problem is ' . $test->{state}; - like $body, qr{report/$report_id}, 'contains problem url'; - like $body, qr/This is some update text/, 'contains update text'; - unlike $body, qr/This is other update text/, 'does not contains other update text'; + for my $email (@emails) { + my $body = $email->body; + my $to = $email->header('To'); + + like $body, qr/$msg/, 'email says problem is ' . $test->{state}; + if ($to eq $user->email) { + like $body, qr{/M/}, 'contains problem login url'; + } elsif ($to eq $user3->email) { + like $body, qr{/report/$report_id}, 'contains problem url'; + } + like $body, qr/This is some update text/, 'contains update text'; + unlike $body, qr/This is other update text/, 'does not contains other update text'; - my $comments = $body =~ s/(------)//gs; - is $comments, 1, 'only 1 update'; + my $comments = $body =~ s/(------)//gs; + is $comments, 1, 'only 1 update'; + } }; } @@ -166,7 +187,6 @@ subtest "correct text for title after URL" => sub { )->delete; FixMyStreet::App->model('DB::AlertType')->email_alerts(); - $mech->email_count_is( 1 ); my $email = $mech->get_email; (my $title = $report->title) =~ s/ /\\s+/; my $body = $email->body; @@ -300,7 +320,6 @@ foreach my $test ( FixMyStreet::App->model('DB::AlertType')->email_alerts(); - $mech->email_count_is( 1 ); my $email = $mech->get_email; my $body = $email->body; @@ -406,7 +425,6 @@ subtest "check alerts from cobrand send main site url for alerts for different c FixMyStreet::App->model('DB::AlertType')->email_alerts(); - $mech->email_count_is( 1 ); my $email = $mech->get_email; my $body = $email->body; @@ -444,7 +462,6 @@ subtest "check local alerts from cobrand send main site url for alerts for diffe FixMyStreet::App->model('DB::AlertType')->email_alerts(); - $mech->email_count_is( 1 ); my $email = $mech->get_email; my $body = $email->body; diff --git a/t/app/model/problem.t b/t/app/model/problem.t index c3913b79e..040790184 100644 --- a/t/app/model/problem.t +++ b/t/app/model/problem.t @@ -511,6 +511,10 @@ foreach my $test ( { }, ) { subtest $test->{ desc } => sub { + if ( $test->{cobrand} && $test->{cobrand} =~ /lichfielddc/ && !FixMyStreet::Cobrand->exists('lichfielddc') ) { + plan skip_all => 'Skipping Lichfield tests without Lichfield cobrand'; + } + $mech->clear_emails_ok; FixMyStreet::App->model('DB::Problem')->search( @@ -519,10 +523,6 @@ foreach my $test ( { } )->update( { whensent => \'ms_current_timestamp()' } ); - if ( $test->{cobrand} && $test->{cobrand} =~ /lichfielddc/ && !FixMyStreet::Cobrand->exists('lichfielddc') ) { - plan skip_all => 'Skipping Lichfield tests without Lichfield cobrand'; - } - $problem->discard_changes; $problem->update( { council => $test->{ council }, @@ -568,6 +568,53 @@ foreach my $test ( { }; } +subtest 'check can turn on report sent email alerts' => sub { + eval 'use Test::MockModule; 1' or + plan skip_all => 'Skipping tests that rely on Test::MockModule'; + + $mech->clear_emails_ok; + + FixMyStreet::App->model('DB::Problem')->search( + { + whensent => undef + } + )->update( { whensent => \'ms_current_timestamp()' } ); + + $problem->discard_changes; + $problem->update( { + council => 2651, + state => 'confirmed', + confirmed => \'ms_current_timestamp()', + whensent => undef, + category => 'potholes', + name => 'Test User', + cobrand => 'fixmystreet', + } ); + + my $m = new Test::MockModule( + 'FixMyStreet::Cobrand::FixMyStreet' ); + $m->mock( report_sent_confirmation_email => 1 ); + FixMyStreet::App->model('DB::Problem')->send_reports(); + + $mech->email_count_is( 2 ); + my @emails = $mech->get_email; + my $email = $emails[0]; + + like $email->header('To'),qr/City of Edinburgh Council/, 'to line looks correct'; + is $email->header('From'), '"Test User" <system_user@example.com>', 'from line looks correct'; + like $email->header('Subject'), qr/A Title/, 'subject line looks correct'; + like $email->body, qr/A user of FixMyStreet/, 'email body looks a bit like a report'; + like $email->body, qr/Subject: A Title/, 'more email body checking'; + like $email->body, qr/Dear City of Edinburgh Council/, 'Salutation looks correct'; + + $problem->discard_changes; + ok defined( $problem->whensent ), 'whensent set'; + + $email = $emails[1]; + like $email->header('Subject'), qr/Problem Report Sent/, 'report sent email title correct'; + like $email->body, qr/Your report about/, 'report sent body correct'; +}; + $problem->comments->delete; $problem->delete; $user->delete; diff --git a/t/cobrand/councils.t b/t/cobrand/councils.t new file mode 100644 index 000000000..8fb10cfbe --- /dev/null +++ b/t/cobrand/councils.t @@ -0,0 +1,18 @@ +use strict; +use warnings; +use Test::More; + +use FixMyStreet::TestMech; +my $mech = FixMyStreet::TestMech->new; + +foreach my $council (qw/southampton reading bromley/) { + SKIP: { + skip( "Need '$council' in ALLOWED_COBRANDS config", 3 ) + unless FixMyStreet::Cobrand->exists($council); + ok $mech->host("$council.fixmystreet.com"), "change host to $council"; + $mech->get_ok('/'); + $mech->content_like( qr/$council/i ); + } +} + +done_testing(); diff --git a/t/cobrand/get_council_sender.t b/t/cobrand/get_council_sender.t index 9004a47f5..e61f36370 100644 --- a/t/cobrand/get_council_sender.t +++ b/t/cobrand/get_council_sender.t @@ -13,8 +13,8 @@ mySociety::Locale::gettext_domain( 'FixMyStreet' ); my $c = FixMyStreet::Cobrand::FixMyStreet->new(); -is $c->get_council_sender( '1000', { type => 'DIS' } ), 'Email', 'defaults to email'; -is $c->get_council_sender( '1000', { type => 'LBO' } ), 'London', 'returns london report it if London borough'; +is_deeply $c->get_council_sender( '1000', { type => 'DIS' } ), { method => 'Email' }, 'defaults to email'; +is_deeply $c->get_council_sender( '1000', { type => 'LBO' } ), { method=> 'London' }, 'returns london report it if London borough'; my $conf = FixMyStreet::App->model('DB::Open311Conf')->find_or_create( area_id => 1000, @@ -22,8 +22,8 @@ my $conf = FixMyStreet::App->model('DB::Open311Conf')->find_or_create( send_method => 'TestMethod' ); -is $c->get_council_sender( '1000', { type => 'LBO' } ), 'TestMethod', 'uses send_method in preference to London'; -is $c->get_council_sender( '1000', { type => 'DIS' } ), 'TestMethod', 'uses send_method in preference to Email'; +is $c->get_council_sender( '1000', { type => 'LBO' } )->{ method }, 'TestMethod', 'uses send_method in preference to London'; +is $c->get_council_sender( '1000', { type => 'DIS' } )->{ method }, 'TestMethod', 'uses send_method in preference to Email'; $conf->delete; @@ -7,6 +7,7 @@ use FixMyStreet; use mySociety::Locale; use Encode; use Data::Dumper; +use HTTP::Headers; use Sort::Key qw(keysort); use POSIX 'strcoll'; local $Data::Dumper::Sortkeys = 1; @@ -18,6 +19,16 @@ die "You need to run 'commonlib/bin/gettext-makemo --quiet FixMyStreet' " unless -e FixMyStreet->path_to( 'locale/cy_GB.UTF-8/LC_MESSAGES/FixMyStreet-EmptyHomes.mo'); +# Test the language negotiation works +my $lang = mySociety::Locale::negotiate_language( + 'en-gb,English,en_GB|cy,Cymraeg,cy_GB|es,Spanish,es_ES', + undef, + HTTP::Headers->new( + Accept_Language => 'es,en-gb;q=0.6,en;q=0.4' + ) +); +is $lang, 'es', 'Language negotiation works okay'; + # Example strings my $english = "Please enter a valid email"; my $welsh = "Cofnodwch gyfeiriad e-bost dilys"; diff --git a/t/open311.t b/t/open311.t index f9315982d..4c451d55e 100644 --- a/t/open311.t +++ b/t/open311.t @@ -37,9 +37,10 @@ my $p = FixMyStreet::App->model('DB::Problem')->new( { title => 'title', detail => 'detail', user => $u, + id => 1, } ); -my $expected_error = qr{.*request failed: 500 Can.t connect to 192.168.50.1:80 \([^)]*\).*}; +my $expected_error = qr{Failed to submit problem 1 over Open311}ism; warning_like {$o2->send_service_request( $p, { url => 'http://example.com/' }, 1 )} $expected_error, 'warning generated on failed call'; @@ -105,7 +106,7 @@ subtest 'posting service request with basic_description' => sub { $extra, $problem->category, '<?xml version="1.0" encoding="utf-8"?><service_requests><request><service_request_id>248</service_request_id></request></service_requests>', - { basic_description => 1 }, + { extended_description => 0 }, ); is $results->{ res }, 248, 'got request id'; @@ -207,6 +208,26 @@ subtest 'basic request update post parameters' => sub { is $c->param('description'), 'this is a comment', 'email correct'; is $c->param('email'), 'test@example.com', 'email correct'; is $c->param('status'), 'OPEN', 'status correct'; + is $c->param('service_request_id'), 81, 'request id correct'; + is $c->param('updated_datetime'), DateTime::Format::W3CDTF->format_datetime($dt), 'correct date'; + is $c->param('title'), 'Mr', 'correct title'; + is $c->param('last_name'), 'User', 'correct first name'; + is $c->param('first_name'), 'Test', 'correct second name'; + is $c->param('media_url'), undef, 'no media url'; +}; + +subtest 'extended request update post parameters' => sub { + my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>', { extended_updates => 1 } ); + + is $results->{ res }, 248, 'got update id'; + + my $req = $o->test_req_used; + + my $c = CGI::Simple->new( $results->{ req }->content ); + + is $c->param('description'), 'this is a comment', 'email correct'; + is $c->param('email'), 'test@example.com', 'email correct'; + is $c->param('status'), 'OPEN', 'status correct'; is $c->param('service_request_id_ext'), 80, 'external request id correct'; is $c->param('service_request_id'), 81, 'request id correct'; is $c->param('public_anonymity_required'), 'FALSE', 'anon status correct'; @@ -237,21 +258,18 @@ foreach my $test ( { desc => 'comment with fixed state sends status of CLOSED', state => 'fixed', - anon => 0, status => 'CLOSED', extended => 'FIXED', }, { desc => 'comment with fixed - user state sends status of CLOSED', state => 'fixed - user', - anon => 0, status => 'CLOSED', extended => 'FIXED', }, { desc => 'comment with fixed - council state sends status of CLOSED', state => 'fixed - council', - anon => 0, status => 'CLOSED', extended => 'FIXED', }, @@ -279,20 +297,17 @@ foreach my $test ( { desc => 'comment with closed state sends status of CLOSED', state => 'closed', - anon => 0, status => 'CLOSED', }, { desc => 'comment with investigating state sends status of OPEN', state => 'investigating', - anon => 0, status => 'OPEN', extended => 'INVESTIGATING', }, { desc => 'comment with planned state sends status of OPEN', state => 'planned', - anon => 0, status => 'OPEN', extended => 'ACTION_SCHEDULED', }, @@ -306,6 +321,27 @@ foreach my $test ( { desc => 'comment with in progress state sends status of OPEN', state => 'in progress', + status => 'OPEN', + }, + { + state => 'confirmed', + status => 'OPEN', + }, +) { + subtest $test->{desc} => sub { + $comment->problem->state( $test->{state} ); + + my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>' ); + + my $c = CGI::Simple->new( $results->{ req }->content ); + is $c->param('status'), $test->{status}, 'correct status'; + }; +} + +for my $test ( + { + desc => 'public comment sets public_anonymity_required to false', + state => 'confirmed', anon => 0, status => 'OPEN', extended => 'IN_PROGRESS', @@ -322,10 +358,9 @@ foreach my $test ( $comment->problem->state( $test->{state} ); $comment->anonymous( $test->{anon} ); - my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>' ); + my $results = make_update_req( $comment, '<?xml version="1.0" encoding="utf-8"?><service_request_updates><request_update><update_id>248</update_id></request_update></service_request_updates>', { extended_updates => 1 } ); my $c = CGI::Simple->new( $results->{ req }->content ); - is $c->param('status'), $test->{status}, 'correct status'; is $c->param('public_anonymity_required'), $test->{anon} ? 'TRUE' : 'FALSE', 'correct anonymity'; if ( $test->{extended} ) { @@ -597,19 +632,19 @@ for my $test ( done_testing(); sub make_update_req { - my $comment = shift; - my $xml = shift; - my $open311_args = shift || {}; + my $comment = shift; + my $xml = shift; + my $open311conf = shift || {}; + + my $params = { + object => $comment, + xml => $xml, + method => 'post_service_request_update', + path => 'servicerequestupdates.xml', + open311_conf => $open311_args, + }; - return make_req( - { - object => $comment, - xml => $xml, - method => 'post_service_request_update', - path => 'update.xml', - open311_conf => $open311_args, - } - ); + return make_req( $params ); } sub make_service_req { diff --git a/t/open311/getservicerequestupdates.t b/t/open311/getservicerequestupdates.t index 9852e53b6..3f9c35c32 100644 --- a/t/open311/getservicerequestupdates.t +++ b/t/open311/getservicerequestupdates.t @@ -26,7 +26,6 @@ my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> <request_update> <update_id>638344</update_id> <service_request_id>1</service_request_id> -<service_request_id_ext>1</service_request_id_ext> <status>open</status> <description>This is a note</description> UPDATED_DATETIME @@ -42,25 +41,25 @@ for my $test ( { desc => 'basic parsing - element missing', updated_datetime => '', - res => { update_id => 638344, service_request_id => 1, service_request_id_ext => 1, + res => { update_id => 638344, service_request_id => 1, status => 'open', description => 'This is a note' }, }, { desc => 'basic parsing - empty element', updated_datetime => '<updated_datetime />', - res => { update_id => 638344, service_request_id => 1, service_request_id_ext => 1, + res => { update_id => 638344, service_request_id => 1, status => 'open', description => 'This is a note', updated_datetime => {} } , }, { desc => 'basic parsing - element with no content', updated_datetime => '<updated_datetime></updated_datetime>', - res => { update_id => 638344, service_request_id => 1, service_request_id_ext => 1, + res => { update_id => 638344, service_request_id => 1, status => 'open', description => 'This is a note', updated_datetime => {} } , }, { desc => 'basic parsing - element with content', updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), - res => { update_id => 638344, service_request_id => 1, service_request_id_ext => 1, + res => { update_id => 638344, service_request_id => 1, status => 'open', description => 'This is a note', updated_datetime => $dt } , }, ) { @@ -68,7 +67,7 @@ for my $test ( my $local_requests_xml = $requests_xml; $local_requests_xml =~ s/UPDATED_DATETIME/$test->{updated_datetime}/; - my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'update.xml' => $local_requests_xml } ); + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); my $res = $o->get_service_request_updates; is_deeply $res->[0], $test->{ res }, 'result looks correct'; @@ -76,6 +75,33 @@ for my $test ( }; } +subtest 'check extended request parsed correctly' => sub { + my $extended_requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> + <service_requests_updates> + <request_update> + <update_id>638344</update_id> + <service_request_id_ext>120384</service_request_id_ext> + <service_request_id>1</service_request_id> + <status>open</status> + <description>This is a note</description> + UPDATED_DATETIME + </request_update> + </service_requests_updates> + }; + + my $updated_datetime = sprintf( '<updated_datetime>%s</updated_datetime>', $dt ); + my $expected_res = { update_id => 638344, service_request_id => 1, service_request_id_ext => 120384, + status => 'open', description => 'This is a note', updated_datetime => $dt }; + + $extended_requests_xml =~ s/UPDATED_DATETIME/$updated_datetime/; + + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $extended_requests_xml } ); + + my $res = $o->get_service_request_updates; + is_deeply $res->[0], $expected_res, 'result looks correct'; + +}; + my $problem_rs = FixMyStreet::App->model('DB::Problem'); my $problem = $problem_rs->new( { @@ -305,7 +331,7 @@ for my $test ( $local_requests_xml =~ s#<service_request_id_ext>\d+</service_request_id_ext>#<service_request_id_ext>@{[$problem->id]}</service_request_id_ext>#; $local_requests_xml =~ s#<status>\w+</status>#<status>$test->{comment_status}</status># if $test->{comment_status}; - my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'update.xml' => $local_requests_xml } ); + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); $problem->comments->delete; $problem->lastupdate( DateTime->now()->subtract( days => 1 ) ); @@ -347,7 +373,7 @@ foreach my $test ( $local_requests_xml =~ s#<service_request_id>\d+</service_request_id>#<service_request_id>@{[$problem->external_id]}</service_request_id>#; $local_requests_xml =~ s#<service_request_id_ext>\d+</service_request_id_ext>#<service_request_id_ext>@{[$problem->id]}</service_request_id_ext>#; - my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'update.xml' => $local_requests_xml } ); + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); $problem->comments->delete; @@ -417,7 +443,7 @@ for my $test ( $local_requests_xml =~ s#<service_request_id>\d+</service_request_id>#<service_request_id>$test->{request_id}</service_request_id>#; $local_requests_xml =~ s#<service_request_id_ext>\d+</service_request_id_ext>#<service_request_id_ext>$test->{request_id_ext}</service_request_id_ext>#; - my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'update.xml' => $local_requests_xml } ); + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); my $council_details = { areaid => $test->{area_id} }; @@ -431,7 +457,7 @@ for my $test ( subtest 'using start and end date' => sub { my $local_requests_xml = $requests_xml; - my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'update.xml' => $local_requests_xml } ); + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); my $start_dt = DateTime->now(); $start_dt->subtract( days => 1 ); @@ -479,7 +505,6 @@ subtest 'check that existing comments are not duplicated' => sub { <request_update> <update_id>638344</update_id> <service_request_id>@{[ $problem->external_id ]}</service_request_id> - <service_request_id_ext>@{[ $problem->id ]}</service_request_id_ext> <status>open</status> <description>This is a note</description> <updated_datetime>UPDATED_DATETIME</updated_datetime> @@ -487,7 +512,6 @@ subtest 'check that existing comments are not duplicated' => sub { <request_update> <update_id>638354</update_id> <service_request_id>@{[ $problem->external_id ]}</service_request_id> - <service_request_id_ext>@{[ $problem->id ]}</service_request_id_ext> <status>open</status> <description>This is a different note</description> <updated_datetime>UPDATED_DATETIME2</updated_datetime> @@ -516,7 +540,7 @@ subtest 'check that existing comments are not duplicated' => sub { $requests_xml =~ s/UPDATED_DATETIME2/$dt/; $requests_xml =~ s/UPDATED_DATETIME/@{[ $comment->confirmed ]}/; - my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'update.xml' => $requests_xml } ); + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $requests_xml } ); my $update = Open311::GetServiceRequestUpdates->new( system_user => $user, @@ -555,7 +579,6 @@ foreach my $test ( { <request_update> <update_id>638344</update_id> <service_request_id>@{[ $problem->external_id ]}</service_request_id> - <service_request_id_ext>@{[ $problem->id ]}</service_request_id_ext> <status>closed</status> <description>This is a note</description> <updated_datetime>UPDATED_DATETIME</updated_datetime> @@ -563,7 +586,6 @@ foreach my $test ( { <request_update> <update_id>638354</update_id> <service_request_id>@{[ $problem->external_id ]}</service_request_id> - <service_request_id_ext>@{[ $problem->id ]}</service_request_id_ext> <status>open</status> <description>This is a different note</description> <updated_datetime>UPDATED_DATETIME2</updated_datetime> @@ -579,7 +601,7 @@ foreach my $test ( { $requests_xml =~ s/UPDATED_DATETIME/$test->{dt1}/; $requests_xml =~ s/UPDATED_DATETIME2/$test->{dt2}/; - my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'update.xml' => $requests_xml } ); + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $requests_xml } ); my $update = Open311::GetServiceRequestUpdates->new( system_user => $user, @@ -609,7 +631,6 @@ foreach my $test ( { <request_update> <update_id>638344</update_id> <service_request_id>@{[ $problem->external_id ]}</service_request_id> - <service_request_id_ext>@{[ $problem->id ]}</service_request_id_ext> <status>closed</status> <description>This is a note</description> <updated_datetime>UPDATED_DATETIME</updated_datetime> @@ -631,7 +652,7 @@ foreach my $test ( { $requests_xml =~ s/UPDATED_DATETIME/$dt/; - my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'update.xml' => $requests_xml } ); + my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $requests_xml } ); my $update = Open311::GetServiceRequestUpdates->new( system_user => $user, diff --git a/t/open311/populate-service-list.t b/t/open311/populate-service-list.t index fbd729f3a..00026cd9f 100644 --- a/t/open311/populate-service-list.t +++ b/t/open311/populate-service-list.t @@ -269,6 +269,184 @@ subtest 'check meta data population' => sub { is_deeply $contact->extra, $extra, 'meta data saved'; }; +for my $test ( + { + desc => 'check meta data added to existing contact', + has_meta => 1, + orig_meta => undef, + end_meta => [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Type of bin', + order => 1, + description => 'Type of bin' + + } ], + meta_xml => '<?xml version="1.0" encoding="utf-8"?> + <service_definition> + <service_code>100</service_code> + <attributes> + <attribute> + <variable>true</variable> + <code>type</code> + <datatype>string</datatype> + <required>true</required> + <datatype_description>Type of bin</datatype_description> + <order>1</order> + <description>Type of bin</description> + </attribute> + </attributes> + </service_definition> + ', + }, + { + desc => 'check meta data updated', + has_meta => 1, + orig_meta => [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Type of bin', + order => 1, + description => 'Type of bin' + + } ], + end_meta => [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Colour of bin', + order => 1, + description => 'Colour of bin' + + } ], + meta_xml => '<?xml version="1.0" encoding="utf-8"?> + <service_definition> + <service_code>100</service_code> + <attributes> + <attribute> + <variable>true</variable> + <code>type</code> + <datatype>string</datatype> + <required>true</required> + <datatype_description>Colour of bin</datatype_description> + <order>1</order> + <description>Colour of bin</description> + </attribute> + </attributes> + </service_definition> + ', + }, + { + desc => 'check meta data removed', + has_meta => 0, + end_meta => undef, + orig_meta => [ { + variable => 'true', + code => 'type', + datatype => 'string', + required => 'true', + datatype_description => 'Type of bin', + order => 1, + description => 'Type of bin' + + } ], + meta_xml => '<?xml version="1.0" encoding="utf-8"?> + <service_definition> + <service_code>100</service_code> + <attributes> + <attribute> + <variable>true</variable> + <code>type</code> + <datatype>string</datatype> + <required>true</required> + <datatype_description>Type of bin</datatype_description> + <order>1</order> + <description>Type of bin</description> + </attribute> + </attributes> + </service_definition> + ', + }, + { + desc => 'check empty meta data handled', + has_meta => 1, + orig_meta => undef, + end_meta => undef, + meta_xml => '<?xml version="1.0" encoding="utf-8"?> + <service_definition> + <service_code>100</service_code> + <attributes> + </attributes> + </service_definition> + ', + }, +) { + subtest $test->{desc} => sub { + my $processor = Open311::PopulateServiceList->new( council_list => [] ); + + my $services_xml = '<?xml version="1.0" encoding="utf-8"?> + <services> + <service> + <service_code>100</service_code> + <service_name>Cans left out 24x7</service_name> + <description>Garbage or recycling cans that have been left out for more than 24 hours after collection. Violators will be cited.</description> + <metadata>false</metadata> + <type>realtime</type> + <keywords>lorem, ipsum, dolor</keywords> + <group>sanitation</group> + </service> + </services> + '; + + if ( $test->{has_meta} ) { + $services_xml =~ s/metadata>false/metadata>true/ms; + } + + my $contact = FixMyStreet::App->model('DB::Contact')->find_or_create( + { + area_id => 1, + email => '100', + category => 'Cans left out 24x7', + confirmed => 1, + deleted => 0, + editor => $0, + whenedited => \'ms_current_timestamp()', + note => 'test contact', + } + ); + + $contact->update( { extra => $test->{orig_meta} } ); + + my $o = Open311->new( + jurisdiction => 'mysociety', + endpoint => 'http://example.com', + test_mode => 1, + test_get_returns => { 'services.xml' => $services_xml, 'services/100.xml' => $test->{meta_xml} } + ); + + my $service_list = get_xml_simple_object( $services_xml ); + $service_list = { service => [ $service_list->{ service } ] }; + + my $council = FixMyStreet::App->model('DB::Open311conf')->new( { + area_id => 1 + } ); + + $processor->_current_open311( $o ); + $processor->_current_council( $council ); + + $processor->process_services( $service_list ); + + $contact->discard_changes; + + is_deeply $contact->extra, $test->{end_meta}, 'meta data saved'; + }; +} + subtest 'check attribute ordering' => sub { my $processor = Open311::PopulateServiceList->new( council_list => [] ); |