diff options
Diffstat (limited to 't')
-rw-r--r-- | t/app/controller/dashboard.t | 54 | ||||
-rw-r--r-- | t/app/controller/questionnaire.t | 16 | ||||
-rw-r--r-- | t/app/controller/report_display.t | 42 | ||||
-rw-r--r-- | t/app/controller/report_new.t | 272 | ||||
-rw-r--r-- | t/app/controller/report_updates.t | 491 | ||||
-rw-r--r-- | t/app/controller/rss.t | 5 | ||||
-rw-r--r-- | t/app/helpers/send_email.t | 2 | ||||
-rw-r--r-- | t/app/model/problem.t | 77 | ||||
-rw-r--r-- | t/app/model/questionnaire.t | 16 | ||||
-rw-r--r-- | t/app/sendreport/email.t | 1 | ||||
-rw-r--r-- | t/map/tilma/original.t | 16 | ||||
-rw-r--r-- | t/open311.t | 125 | ||||
-rw-r--r-- | t/open311/getservicerequestupdates.t | 174 |
13 files changed, 1169 insertions, 122 deletions
diff --git a/t/app/controller/dashboard.t b/t/app/controller/dashboard.t index 5a8465edc..091335040 100644 --- a/t/app/controller/dashboard.t +++ b/t/app/controller/dashboard.t @@ -80,7 +80,7 @@ my $categories = scraper { process "tr[id=fixed_user] > td", 'user[]' => 'TEXT', process "tr[id=total_fixed] > td", 'total_fixed[]' => 'TEXT', process "tr[id=in_progress] > td", 'in_progress[]' => 'TEXT', - process "tr[id=planned] > td", 'planned[]' => 'TEXT', + process "tr[id=action_scheduled] > td", 'action_scheduled[]' => 'TEXT', process "tr[id=investigating] > td", 'investigating[]' => 'TEXT', process "tr[id=marked] > td", 'marked[]' => 'TEXT', process "tr[id=avg_marked] > td", 'avg_marked[]' => 'TEXT', @@ -214,10 +214,10 @@ foreach my $test ( } }, { - desc => 'marked as planned today', + desc => 'marked as action scheduled today', confirm_dt => DateTime->now->subtract( days => 1 ), mark_dt => DateTime->now, - state => 'planned', + state => 'action scheduled', counts => { totals => $is_monday ? [ 0,5,5,5] : [5,5,5,5], user => [1,1,1,1], @@ -226,15 +226,15 @@ foreach my $test ( avg_marked => [1,1,1,1], investigating => [1,1,1,1], in_progress => [1,1,1,1], - planned => [1,1,1,1], + action_scheduled => [1,1,1,1], marked => [3,3,3,3] } }, { - desc => 'marked as planned today, confirmed a week ago', + desc => 'marked as action scheduled today, confirmed a week ago', confirm_dt => DateTime->now->subtract( days => 8 ), mark_dt => DateTime->now, - state => 'planned', + state => 'action scheduled', counts => { totals => $is_monday ? [0,5,6,6] : [5,5,6,6], user => [1,1,1,1], @@ -243,7 +243,7 @@ foreach my $test ( avg_marked => [3,3,3,3], investigating => [1,1,1,1], in_progress => [1,1,1,1], - planned => [2,2,2,2], + action_scheduled => [2,2,2,2], marked => [4,4,4,4] } }, @@ -261,7 +261,7 @@ foreach my $test ( avg_marked => [3,3,3,3], investigating => [1,1,1,1], in_progress => [1,1,1,1], - planned => [2,2,2,2], + action_scheduled => [2,2,2,2], marked => [4,4,4,4] } }, @@ -279,7 +279,7 @@ foreach my $test ( avg_marked => [3,3,3,3], investigating => [1,1,1,1], in_progress => [1,1,1,1], - planned => [2,2,2,2], + action_scheduled => [2,2,2,2], marked => [4,4,4,4] } }, @@ -297,7 +297,7 @@ foreach my $test ( avg_marked => [3,3,3,3], investigating => [1,1,1,1], in_progress => [1,1,1,1], - planned => [2,2,2,2], + action_scheduled => [2,2,2,2], marked => [4,4,4,4] } }, @@ -315,11 +315,30 @@ foreach my $test ( avg_marked => [2,2,2,2], investigating => [1,1,1,1], in_progress => [1,1,1,1], - planned => [2,2,2,2], + action_scheduled => [2,2,2,2], closed => [1,1,1,1], marked => [5,5,5,5] } }, + { + desc => 'marked as planned', + confirm_dt => DateTime->now->subtract( days => 1 ), + mark_dt => DateTime->now, + state => 'planned', + counts => { + totals => $is_monday ? [0,7,10,11] : [7,7,10,11], + user => [1,1,1,2], + council => [2,2,3,3], + total_fixed => [3,3,4,5], + avg_fixed => [5,5,7,7], + avg_marked => [2,2,2,2], + investigating => [1,1,1,1], + in_progress => [1,1,1,1], + action_scheduled => [3,3,3,3], + closed => [1,1,1,1], + marked => [6,6,6,6] + } + }, ) { subtest $test->{desc} => sub { make_problem( @@ -530,6 +549,17 @@ for my $test ( report_counts_after => [1,0,0], }, { + desc => 'planned counted as action scheduled', + p1 => { + state => 'planned', + conf_dt => DateTime->now(), + category => 'Potholes', + }, + state => 'action scheduled', + report_counts => [3,0,0], + report_counts_after => [1,0,0], + }, + { desc => 'All fixed states count as fixed', p1 => { state => 'fixed - council', @@ -542,7 +572,7 @@ for my $test ( category => 'Potholes', }, state => 'fixed', - report_counts => [4,0,0], + report_counts => [5,0,0], report_counts_after => [3,0,0], }, ) { diff --git a/t/app/controller/questionnaire.t b/t/app/controller/questionnaire.t index a99f4c645..5c81a43d1 100644 --- a/t/app/controller/questionnaire.t +++ b/t/app/controller/questionnaire.t @@ -329,6 +329,10 @@ for my $test ( fixed => 0 }, { + state => 'action scheduled', + fixed => 0 + }, + { state => 'in progress', fixed => 0 }, @@ -337,6 +341,18 @@ for my $test ( fixed => 0 }, { + state => 'duplicate', + fixed => 0 + }, + { + state => 'not responsible', + fixed => 0 + }, + { + state => 'unable to fix', + fixed => 0 + }, + { state => 'closed', fixed => 0 }, diff --git a/t/app/controller/report_display.t b/t/app/controller/report_display.t index 10ef3dfd9..a3c4edfc7 100644 --- a/t/app/controller/report_display.t +++ b/t/app/controller/report_display.t @@ -297,6 +297,38 @@ for my $test ( fixed => 1 }, { + description => 'duplicate report', + date => DateTime->now, + state => 'duplicate', + banner_id => 'closed', + banner_text => 'closed', + fixed => 0 + }, + { + description => 'not responsible report', + date => DateTime->now, + state => 'not responsible', + banner_id => 'closed', + banner_text => 'closed', + fixed => 0 + }, + { + description => 'unable to fix report', + date => DateTime->now, + state => 'unable to fix', + banner_id => 'closed', + banner_text => 'closed', + fixed => 0 + }, + { + description => 'internal referral report', + date => DateTime->now, + state => 'internal referral', + banner_id => 'closed', + banner_text => 'closed', + fixed => 0 + }, + { description => 'closed report', date => DateTime->now, state => 'closed', @@ -313,6 +345,14 @@ for my $test ( fixed => 0 }, { + description => 'action scheduled report', + date => DateTime->now, + state => 'action scheduled', + banner_id => 'progress', + banner_text => 'progress', + fixed => 0 + }, + { description => 'planned report', date => DateTime->now, state => 'planned', @@ -321,7 +361,7 @@ for my $test ( fixed => 0 }, { - description => 'in progressreport', + description => 'in progress report', date => DateTime->now, state => 'in progress', banner_id => 'progress', diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t index 783f3fb01..868977953 100644 --- a/t/app/controller/report_new.t +++ b/t/app/controller/report_new.t @@ -1142,67 +1142,239 @@ 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, + 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, + national => 1, + button => 'submit_register', + }, + { + desc => 'confirm redirect for cobrand council in two tier cobrand redirects to cobrand site', + category => 'Trees', + council => 2434, + national => 0, + redirect => 1, + }, + { + desc => 'confirm redirect for non cobrand council in two tier cobrand redirect to national site', + category => 'Street Lighting', + council => 2240, + 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->bodies_str, $test->{council}; + + if ( $test->{redirect} ) { + is $mech->uri->path, "/report/" . $report->id, "redirected to report page"; + my $base = FixMyStreet->config('BASE_URL'); + $base =~ s{http://}{}; + $base = "lichfielddc.$base" unless $test->{national}; + is $mech->uri->host, $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); + + my $base = FixMyStreet->config('BASE_URL'); + $base =~ s{http://}{http://lichfielddc.} unless $test->{national}; + $mech->content_contains( $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->bodies_str, 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"; + $mech->create_body_ok(2535, 'Sandwell Borough Council'); + my $bus_contact = FixMyStreet::App->model('DB::Contact')->find_or_create( { + %contact_params, + body_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_updates.t b/t/app/controller/report_updates.t index 5accb9ce4..2765ed246 100644 --- a/t/app/controller/report_updates.t +++ b/t/app/controller/report_updates.t @@ -479,64 +479,103 @@ for my $test ( state => 'investigating', }, { - desc => 'from authority user marks report as planned', + desc => 'from authority user marks report as in progress', fields => { name => $user->name, may_show_name => 1, add_alert => undef, photo => '', - update => 'Set state to planned', - state => 'planned', + update => 'Set state to in progress', + state => 'in progress', }, - state => 'planned', + state => 'in progress', }, { - desc => 'from authority user marks report as in progress', + desc => 'from authority user marks report as fixed', fields => { name => $user->name, may_show_name => 1, add_alert => undef, photo => '', - update => 'Set state to in progress', - state => 'in progress', + update => 'Set state to fixed', + state => 'fixed', }, - state => 'in progress', + state => 'fixed - council', }, { - desc => 'from authority user marks report as closed', + desc => 'from authority user marks report as action scheduled', fields => { name => $user->name, may_show_name => 1, add_alert => undef, photo => '', - update => 'Set state to closed', - state => 'closed', + update => 'Set state to action scheduled', + state => 'action scheduled', }, - state => 'closed', + state => 'action scheduled', }, { - desc => 'from authority user marks report as fixed', + desc => 'from authority user marks report as unable to fix', fields => { name => $user->name, may_show_name => 1, add_alert => undef, photo => '', - update => 'Set state to fixed', - state => 'fixed', + update => 'Set state to unable to fix', + state => 'unable to fix', }, - state => 'fixed - council', + state => 'unable to fix', + }, + { + desc => 'from authority user marks report as internal referral', + fields => { + name => $user->name, + may_show_name => 1, + add_alert => undef, + photo => '', + update => 'Set state to internal referral', + state => 'internal referral', + }, + state => 'internal referral', + }, + { + desc => 'from authority user marks report as not responsible', + fields => { + name => $user->name, + may_show_name => 1, + add_alert => undef, + photo => '', + update => 'Set state to not responsible', + state => 'not responsible', + }, + state => 'not responsible', + meta => "not the council's responsibility" + }, + { + desc => 'from authority user marks report as duplicate', + fields => { + name => $user->name, + may_show_name => 1, + add_alert => undef, + photo => '', + update => 'Set state to duplicate', + state => 'duplicate', + }, + state => 'duplicate', + meta => 'duplicate report', }, { - desc => 'from authority user marks report as confirmed', + desc => 'from authority user marks report as internal referral', fields => { name => $user->name, may_show_name => 1, add_alert => undef, photo => '', - update => 'Set state to confirmed', - state => 'confirmed', + update => 'Set state to internal referral', + state => 'internal referral', }, - state => 'confirmed', + state => 'internal referral', + meta => 'internal referral', }, { desc => 'from authority user marks report sent to two councils as fixed', @@ -579,11 +618,11 @@ for my $test ( is $update->problem_state, $test->{state}, 'problem state set'; my $update_meta = $mech->extract_update_metas; - # setting it to confirmed shouldn't say anything - if ( $test->{fields}->{state} ne 'confirmed' ) { - like $update_meta->[0], qr/marked as $test->{fields}->{state}$/, 'update meta includes state change'; + my $meta_state = $test->{meta} || $test->{fields}->{state}; + if ( $test->{reopened} ) { + like $update_meta->[0], qr/reopened$/, 'update meta says reopened'; } else { - like $update_meta->[0], qr/reopened$/, 'update meta includes state change'; + like $update_meta->[0], qr/marked as $meta_state$/, 'update meta includes state change'; } like $update_meta->[0], qr{Test User \(Westminster City Council\)}, 'update meta includes council name'; $mech->content_contains( 'Test User (<strong>Westminster City Council</strong>)', 'council name in bold'); @@ -611,7 +650,7 @@ subtest 'check meta correct for comments marked confirmed but not marked open' = $mech->get_ok( "/report/" . $report->id ); my $update_meta = $mech->extract_update_metas; - like $update_meta->[0], qr/reopened$/, + unlike $update_meta->[0], qr/reopened$/, 'update meta does not say reopened'; $comment->update( { mark_open => 1, problem_state => undef } ); @@ -629,7 +668,159 @@ subtest 'check meta correct for comments marked confirmed but not marked open' = 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 first comment with no status change has no status in meta" => sub { + $mech->log_in_ok( $user->email ); + $user->from_body( undef ); + $user->update; + + my $comment = $report->comments->first; + $comment->update( { mark_fixed => 0, problem_state => 'confirmed' } ); + + $mech->get_ok("/report/$report_id"); + + my $update_meta = $mech->extract_update_metas; + unlike $update_meta->[0], qr/marked as|reopened/, 'update meta does not include state change'; +}; + +subtest "check comment with no status change has not status in meta" => sub { + $mech->log_in_ok( $user->email ); + $user->from_body( undef ); + $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( + { + with_fields => { + name => $user->name, + may_show_name => 1, + add_alert => undef, + photo => '', + update => 'Comment that does not change state', + }, + }, + 'submit update' + ); + + $report->discard_changes; + 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'; + is $update->problem_state, 'fixed - council', 'corect update state'; + my $update_meta = $mech->extract_update_metas; + unlike $update_meta->[1], qr/marked as/, 'update meta does not include state change'; + + $user->from_body( 2504 ); + $user->update; + + $mech->get_ok("/report/$report_id"); + + $mech->submit_form_ok( + { + with_fields => { + name => $user->name, + may_show_name => 1, + add_alert => undef, + photo => '', + update => 'Comment that sets state to investigating', + state => 'investigating', + }, + }, + 'submit update' + ); + + $report->discard_changes; + @updates = $report->comments->all; + is scalar @updates, 3, 'correct number of updates'; + + $update = pop @updates; + + is $report->state, 'investigating', 'correct report state'; + is $update->problem_state, 'investigating', 'corect update state'; + $update_meta = $mech->extract_update_metas; + like $update_meta->[0], qr/marked as fixed/, 'first update meta says fixed'; + unlike $update_meta->[1], qr/marked as/, 'second update meta does not include state change'; + like $update_meta->[2], qr/marked as investigating/, 'third update meta says investigating'; + + my $dt = DateTime->now->add( seconds => 1 ); + $comment = FixMyStreet::App->model('DB::Comment')->find_or_create( + { + problem_id => $report_id, + user_id => $user->id, + name => 'Other User', + mark_fixed => 'false', + text => 'This is some update text', + state => 'confirmed', + confirmed => $dt->ymd . ' ' . $dt->hms, + anonymous => 'f', + } + ); + + $mech->get_ok("/report/$report_id"); + + $report->discard_changes; + @updates = $report->comments->all; + is scalar @updates, 4, 'correct number of updates'; + + $update = pop @updates; + + is $report->state, 'investigating', 'correct report state'; + is $update->problem_state, undef, 'no update state'; + $update_meta = $mech->extract_update_metas; + like $update_meta->[0], qr/marked as fixed/, 'first update meta says fixed'; + unlike $update_meta->[1], qr/marked as/, 'second update meta does not include state change'; + like $update_meta->[2], qr/marked as investigating/, 'third update meta says investigating'; + unlike $update_meta->[3], qr/marked as/, 'fourth update meta has no state change'; +}; + +subtest 'check meta correct for second comment marking as reopened' => 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 => 'fixed - user', + anonymous => 0, + mark_open => 0, + mark_fixed => 1, + state => 'confirmed', + } + ); + + $mech->get_ok( "/report/" . $report->id ); + my $update_meta = $mech->extract_update_metas; + like $update_meta->[0], qr/fixed$/, 'update meta says fixed'; + + $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 ); + $update_meta = $mech->extract_update_metas; + like $update_meta->[1], qr/reopened$/, 'update meta says reopened'; +}; $user->from_body(undef); $user->update; @@ -1288,6 +1479,254 @@ for my $test ( }; } +for my $test ( + { + desc => 'update confirmed without marking as fixed leaves state unchanged', + initial_state => 'confirmed', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 0, + }, + end_state => 'confirmed', + }, + { + desc => 'update investigating without marking as fixed leaves state unchanged', + initial_state => 'investigating', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 0, + }, + end_state => 'investigating', + }, + { + desc => 'update in progress without marking as fixed leaves state unchanged', + initial_state => 'in progress', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 0, + }, + end_state => 'in progress', + }, + { + desc => 'update action scheduled without marking as fixed leaves state unchanged', + initial_state => 'action scheduled', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 0, + }, + end_state => 'action scheduled', + }, + { + desc => 'update fixed without marking as open leaves state unchanged', + initial_state => 'fixed', + expected_form_fields => { + reopen => undef, + }, + submitted_form_fields => { + reopen => 0, + }, + end_state => 'fixed', + }, + { + desc => 'update unable to fix without marking as fixed leaves state unchanged', + initial_state => 'unable to fix', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 0, + }, + end_state => 'unable to fix', + }, + { + desc => 'update internal referral without marking as fixed leaves state unchanged', + initial_state => 'internal referral', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 0, + }, + end_state => 'internal referral', + }, + { + desc => 'update not responsible without marking as fixed leaves state unchanged', + initial_state => 'not responsible', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 0, + }, + end_state => 'not responsible', + }, + { + desc => 'update duplicate without marking as fixed leaves state unchanged', + initial_state => 'duplicate', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 0, + }, + end_state => 'duplicate', + }, + { + desc => 'can mark confirmed as fixed', + initial_state => 'confirmed', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 1, + }, + end_state => 'fixed - user', + }, + { + desc => 'can mark investigating as fixed', + initial_state => 'investigating', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 1, + }, + end_state => 'fixed - user', + }, + { + desc => 'can mark in progress as fixed', + initial_state => 'in progress', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 1, + }, + end_state => 'fixed - user', + }, + { + desc => 'can mark action scheduled as fixed', + initial_state => 'action scheduled', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 1, + }, + end_state => 'fixed - user', + }, + { + desc => 'cannot mark fixed as fixed, can mark as not fixed', + initial_state => 'fixed', + expected_form_fields => { + reopen => undef, + }, + submitted_form_fields => { + reopen => 1, + }, + end_state => 'confirmed', + }, + { + desc => 'can mark unable to fix as fixed, cannot mark not closed', + initial_state => 'unable to fix', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 1, + }, + end_state => 'fixed - user', + }, + { + desc => 'can mark internal referral as fixed, cannot mark not closed', + initial_state => 'internal referral', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 1, + }, + end_state => 'fixed - user', + }, + { + desc => 'can mark not responsible as fixed, cannot mark not closed', + initial_state => 'not responsible', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 1, + }, + end_state => 'fixed - user', + }, + { + desc => 'can mark duplicate as fixed, cannot mark not closed', + initial_state => 'duplicate', + expected_form_fields => { + fixed => undef, + }, + submitted_form_fields => { + fixed => 1, + }, + end_state => 'fixed - user', + }, +) { + subtest $test->{desc} => sub { + $mech->log_in_ok( $report->user->email ); + + my %standard_fields = ( + name => $report->user->name, + update => 'update text', + photo => '', + may_show_name => 1, + add_alert => 1, + ); + + my %expected_fields = ( + %standard_fields, + %{ $test->{expected_form_fields} }, + update => '', + ); + + my %submitted_fields = ( + %standard_fields, + %{ $test->{submitted_form_fields} }, + ); + + # clear out comments for this problem to make + # checking details easier later + ok( $_->delete, 'deleted comment ' . $_->id ) for $report->comments; + + $report->discard_changes; + $report->state($test->{initial_state}); + $report->update; + + $mech->get_ok("/report/$report_id"); + + my $values = $mech->visible_form_values('updateForm'); + is_deeply $values, \%expected_fields, 'correct form fields present'; + + if ( $test->{submitted_form_fields} ) { + $mech->submit_form_ok( { + with_fields => \%submitted_fields + }, + 'submit update' + ); + + $report->discard_changes; + is $report->state, $test->{end_state}, 'update sets correct report state'; + } + }; +} + subtest 'check have to be logged in for creator fixed questionnaire' => sub { $mech->log_out_ok(); diff --git a/t/app/controller/rss.t b/t/app/controller/rss.t index 002d63d67..f04a17151 100644 --- a/t/app/controller/rss.t +++ b/t/app/controller/rss.t @@ -13,7 +13,7 @@ my $dt = DateTime->new( ); my $user1 = FixMyStreet::App->model('DB::User') - ->find_or_create( { email => 'reporter@example.com', name => 'Reporter User' } ); + ->find_or_create( { email => 'reporter-rss@example.com', name => 'Reporter User' } ); my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( { postcode => 'eh1 1BB', @@ -175,7 +175,6 @@ subtest "check RSS feeds on cobrand have correct URLs for non-cobrand reports" = $mech->content_contains($expected2, 'cobrand area report point to cobrand url'); }; -$user1->problems->delete(); -$user1->delete(); +$mech->delete_user( $user1 ); done_testing(); 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/problem.t b/t/app/model/problem.t index b2243fcf5..a92e3b079 100644 --- a/t/app/model/problem.t +++ b/t/app/model/problem.t @@ -302,6 +302,13 @@ for my $test ( is_closed => 0, }, { + state => 'action scheduled', + is_visible => 1, + is_fixed => 0, + is_open => 1, + is_closed => 0, + }, + { state => 'in progress', is_visible => 1, is_fixed => 0, @@ -309,6 +316,27 @@ for my $test ( is_closed => 0, }, { + state => 'duplicate', + is_visible => 1, + is_fixed => 0, + is_open => 0, + is_closed => 1, + }, + { + state => 'not responsible', + is_visible => 1, + is_fixed => 0, + is_open => 0, + is_closed => 1, + }, + { + state => 'unable to fix', + is_visible => 1, + is_fixed => 0, + is_open => 0, + is_closed => 1, + }, + { state => 'fixed', is_visible => 1, is_fixed => 1, @@ -554,9 +582,56 @@ 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; +$mech->delete_user( $user ); foreach (@contacts) { $_->delete; diff --git a/t/app/model/questionnaire.t b/t/app/model/questionnaire.t index 60b52043a..86af51c42 100644 --- a/t/app/model/questionnaire.t +++ b/t/app/model/questionnaire.t @@ -62,6 +62,10 @@ for my $test ( send_email => 1, }, { + state => 'action scheduled', + send_email => 1, + }, + { state => 'in progress', send_email => 1, }, @@ -78,6 +82,18 @@ for my $test ( send_email => 1, }, { + state => 'duplicate', + send_email => 1, + }, + { + state => 'unable to fix', + send_email => 1, + }, + { + state => 'not responsible', + send_email => 1, + }, + { state => 'closed', send_email => 1, }, diff --git a/t/app/sendreport/email.t b/t/app/sendreport/email.t index 106a31c42..8063c928f 100644 --- a/t/app/sendreport/email.t +++ b/t/app/sendreport/email.t @@ -33,6 +33,7 @@ my $contact = FixMyStreet::App->model('DB::Contact')->find_or_create( my $row = FixMyStreet::App->model('DB::Problem')->new( { bodies_str => '1000', category => 'category', + cobrand => '', } ); ok $e; diff --git a/t/map/tilma/original.t b/t/map/tilma/original.t index cd3bc623e..72cde5f9f 100644 --- a/t/map/tilma/original.t +++ b/t/map/tilma/original.t @@ -71,10 +71,26 @@ for my $test ( colour => 'yellow', }, { + state => 'duplicate', + colour => 'yellow', + }, + { + state => 'unable to fix', + colour => 'yellow', + }, + { + state => 'not responsible', + colour => 'yellow', + }, + { state => 'investigating', colour => 'yellow', }, { + state => 'action scheduled', + colour => 'yellow', + }, + { state => 'planned', colour => 'yellow', }, diff --git a/t/open311.t b/t/open311.t index 2371c53bc..71a87325c 100644 --- a/t/open311.t +++ b/t/open311.t @@ -106,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'; @@ -192,6 +192,7 @@ my $comment = FixMyStreet::App->model('DB::Comment')->new( { anonymous => 0, text => 'this is a comment', confirmed => $dt, + problem_state => 'confirmed', extra => { title => 'Mr', email_alerts_requested => 0 }, } ); @@ -216,7 +217,7 @@ subtest 'basic request update post parameters' => sub { }; 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>', 1 ); + 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>', { use_extended_updates => 1 } ); is $results->{ res }, 248, 'got update id'; @@ -258,16 +259,47 @@ foreach my $test ( desc => 'comment with fixed state sends status of CLOSED', state => 'fixed', status => 'CLOSED', + extended => 'FIXED', }, { desc => 'comment with fixed - user state sends status of CLOSED', state => 'fixed - user', status => 'CLOSED', + extended => 'FIXED', }, { desc => 'comment with fixed - council state sends status of CLOSED', state => 'fixed - council', status => 'CLOSED', + extended => 'FIXED', + }, + { + desc => 'comment with duplicate state sends status of CLOSED', + state => 'duplicate', + anon => 0, + status => 'CLOSED', + extended => 'DUPLICATE', + }, + { + desc => 'comment with not reponsible state sends status of CLOSED', + state => 'not responsible', + anon => 0, + status => 'CLOSED', + extended => 'NOT_COUNCILS_RESPONSIBILITY', + }, + { + desc => 'comment with unable to fix state sends status of CLOSED', + state => 'unable to fix', + anon => 0, + status => 'CLOSED', + extended => 'NO_FURTHER_ACTION', + }, + { + desc => 'comment with internal referral state sends status of CLOSED', + state => 'internal referral', + anon => 0, + status => 'CLOSED', + extended => 'INTERNAL_REFERRAL', }, { desc => 'comment with closed state sends status of CLOSED', @@ -278,29 +310,42 @@ foreach my $test ( desc => 'comment with investigating state sends status of OPEN', state => 'investigating', status => 'OPEN', + extended => 'INVESTIGATING', }, { desc => 'comment with planned state sends status of OPEN', state => 'planned', status => 'OPEN', + extended => 'ACTION_SCHEDULED', }, { - desc => 'comment with in progress state sends status of OPEN', - state => 'in progress', + desc => 'comment with action scheduled state sends status of OPEN', + state => 'action scheduled', + anon => 0, status => 'OPEN', + extended => 'ACTION_SCHEDULED', }, { - state => 'confirmed', + desc => 'comment with in progress state sends status of OPEN', + state => 'in progress', status => 'OPEN', + extended => 'IN_PROGRESS', }, ) { subtest $test->{desc} => sub { + $comment->problem_state( $test->{state} ); $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'; + + if ( $test->{extended} ) { + 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_statuses => 1 } ); + my $c = CGI::Simple->new( $results->{ req }->content ); + is $c->param('status'), $test->{extended}, 'correct extended status'; + } }; } @@ -319,16 +364,70 @@ for my $test ( }, ) { subtest $test->{desc} => sub { + $comment->problem_state( $test->{state} ); $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>', 1 ); + 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>', { use_extended_updates => 1 } ); my $c = CGI::Simple->new( $results->{ req }->content ); is $c->param('public_anonymity_required'), $test->{anon} ? 'TRUE' : 'FALSE', 'correct anonymity'; }; } +my $dt2 = $dt->clone; +$dt2->add( 'minutes' => 1 ); + +my $comment2 = FixMyStreet::App->model('DB::Comment')->new( { + id => 38363, + user => $user, + problem => $problem, + anonymous => 0, + text => 'this is a comment', + confirmed => $dt, + problem_state => 'confirmed', + extra => { title => 'Mr', email_alerts_requested => 0 }, +} ); + +for my $test ( + { + desc => 'comment with fixed - council state sends status of CLOSED even if problem is open', + state => 'fixed - council', + problem_state => 'confirmed', + status => 'CLOSED', + extended => 'FIXED', + }, + { + desc => 'comment marked open sends status of OPEN even if problem is closed', + state => 'confirmed', + problem_state => 'fixed - council', + status => 'OPEN', + extended => 'OPEN', + }, + { + desc => 'comment with no problem state falls back to report state', + state => '', + problem_state => 'fixed - council', + status => 'CLOSED', + extended => 'FIXED', + }, +) { + subtest $test->{desc} => sub { + $comment->problem_state( $test->{state} ); + $comment->problem->state( $test->{problem_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'; + + if ( $test->{extended} ) { + 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_statuses => 1 } ); + my $c = CGI::Simple->new( $results->{ req }->content ); + is $c->param('status'), $test->{extended}, 'correct extended status'; + } + }; +} + for my $test ( { @@ -539,18 +638,16 @@ done_testing(); sub make_update_req { my $comment = shift; my $xml = shift; - my $extended = shift; + my $open311_args = shift || {}; my $params = { - object => $comment, - xml => $xml, - method => 'post_service_request_update', - path => 'servicerequestupdates.xml', + object => $comment, + xml => $xml, + method => 'post_service_request_update', + path => 'servicerequestupdates.xml', + open311_conf => $open311_args, }; - if ( $extended ) { - $params->{ open311_conf } = { use_extended_updates => 1 }; - } return make_req( $params ); } diff --git a/t/open311/getservicerequestupdates.t b/t/open311/getservicerequestupdates.t index da23c944e..36ed13615 100644 --- a/t/open311/getservicerequestupdates.t +++ b/t/open311/getservicerequestupdates.t @@ -131,63 +131,209 @@ $problem->insert; for my $test ( { - desc => 'element with content', + desc => 'OPEN status for confirmed problem does not change state', updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), description => 'This is a note', external_id => 638344, start_state => 'confirmed', - close_comment => 0, + comment_status => 'OPEN', mark_fixed=> 0, mark_open => 0, problem_state => undef, end_state => 'confirmed', }, { - desc => 'comment closes report', + desc => 'bad state does not update states but does create update', updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), description => 'This is a note', external_id => 638344, start_state => 'confirmed', - close_comment => 1, + comment_status => 'INVALID_STATE', + mark_fixed=> 0, + mark_open => 0, + problem_state => undef, + end_state => 'confirmed', + }, + + { + desc => 'investigating status changes problem status', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'confirmed', + comment_status => 'INVESTIGATING', + mark_fixed=> 0, + mark_open => 0, + problem_state => 'investigating', + end_state => 'investigating', + }, + { + desc => 'in progress status changes problem status', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'confirmed', + comment_status => 'IN_PROGRESS', + mark_fixed=> 0, + mark_open => 0, + problem_state => 'in progress', + end_state => 'in progress', + }, + { + desc => 'action scheduled status changes problem status', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'confirmed', + comment_status => 'ACTION_SCHEDULED', + mark_fixed=> 0, + mark_open => 0, + problem_state => 'action scheduled', + end_state => 'action scheduled', + }, + { + desc => 'not responsible status changes problem status', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'confirmed', + comment_status => 'NOT_COUNCILS_RESPONSIBILITY', + mark_fixed=> 0, + mark_open => 0, + problem_state => 'not responsible', + end_state => 'not responsible', + }, + { + desc => 'internal referral status changes problem status', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'confirmed', + comment_status => 'INTERNAL_REFERRAL', + mark_fixed=> 0, + mark_open => 0, + problem_state => 'internal referral', + end_state => 'internal referral', + }, + { + desc => 'duplicate status changes problem status', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'confirmed', + comment_status => 'DUPLICATE', + mark_fixed=> 0, + mark_open => 0, + problem_state => 'duplicate', + end_state => 'duplicate', + }, + { + desc => 'fixed status marks report as fixed - council', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'confirmed', + comment_status => 'FIXED', + mark_fixed=> 0, + mark_open => 0, + problem_state => 'fixed - council', + end_state => 'fixed - council', + }, + { + desc => 'status of CLOSED marks report as fixed - council', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'confirmed', + comment_status => 'CLOSED', mark_fixed=> 0, mark_open => 0, problem_state => 'fixed - council', end_state => 'fixed - council', }, { - desc => 'comment re-opens fixed report', + desc => 'status of OPEN re-opens fixed report', updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), description => 'This is a note', external_id => 638344, start_state => 'fixed - user', - close_comment => 0, + comment_status => 'OPEN', mark_fixed => 0, mark_open => 0, problem_state => 'confirmed', end_state => 'confirmed', }, { - desc => 'comment re-opens closed report', + desc => 'action sheduled re-opens fixed report as action scheduled', updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), description => 'This is a note', external_id => 638344, - start_state => 'closed', - close_comment => 0, + start_state => 'fixed - user', + comment_status => 'ACTION_SCHEDULED', + mark_fixed => 0, + mark_open => 0, + problem_state => 'action scheduled', + end_state => 'action scheduled', + }, + { + desc => 'open status re-opens closed report', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'not responsible', + comment_status => 'OPEN', mark_fixed => 0, mark_open => 0, problem_state => 'confirmed', end_state => 'confirmed', }, { - desc => 'comment leaves report closed', + desc => 'fixed status leaves fixed - user report as fixed - user', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'fixed - user', + comment_status => 'FIXED', + mark_fixed => 0, + mark_open => 0, + problem_state => undef, + end_state => 'fixed - user', + }, + { + desc => 'closed status updates fixed report', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'fixed - user', + comment_status => 'NO_FURTHER_ACTION', + mark_fixed => 0, + mark_open => 0, + problem_state => 'unable to fix', + end_state => 'unable to fix', + }, + { + desc => 'no futher action status closes report', updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), description => 'This is a note', external_id => 638344, - start_state => 'closed', - close_comment => 1, + start_state => 'confirmed', + comment_status => 'NO_FURTHER_ACTION', mark_fixed => 0, mark_open => 0, - end_state => 'closed', + problem_state => 'unable to fix', + end_state => 'unable to fix', + }, + { + desc => 'fixed status sets closed report as fixed', + updated_datetime => sprintf( '<updated_datetime>%s</updated_datetime>', $dt ), + description => 'This is a note', + external_id => 638344, + start_state => 'unable to fix', + comment_status => 'FIXED', + mark_fixed => 0, + mark_open => 0, + problem_state => 'fixed - council', + end_state => 'fixed - council', }, ) { subtest $test->{desc} => sub { @@ -195,7 +341,7 @@ for my $test ( $local_requests_xml =~ s/UPDATED_DATETIME/$test->{updated_datetime}/; $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>#; - $local_requests_xml =~ s#<status>\w+</status>#<status>closed</status># if $test->{close_comment}; + $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 => { 'servicerequestupdates.xml' => $local_requests_xml } ); |