diff options
Diffstat (limited to 't')
29 files changed, 1037 insertions, 408 deletions
diff --git a/t/MapIt.pm b/t/MapIt.pm index ebef934e1..a10118013 100644 --- a/t/MapIt.pm +++ b/t/MapIt.pm @@ -24,12 +24,27 @@ sub dispatch_request { $self->json->encode($response) }; return [ 200, [ 'Content-Type' => 'application/json' ], [ $json ] ]; }, + + sub (GET + /point/**) { + my ($self, $point) = @_; + my $response = { + "63999" => {"parent_area" => 2245, "generation_high" => 25, "all_names" => {}, "id" => 63999, "codes" => {"ons" => "00HYNS", "gss" => "E05008366", "unit_id" => "44025"}, "name" => "Kington", "country" => "E", "type_name" => "Unitary Authority electoral division (UTE)", "generation_low" => 12, "country_name" => "England", "type" => "UTE"}, + "65822" => {"parent_area" => undef, "generation_high" => 25, "all_names" => {}, "id" => 65822, "codes" => {"gss" => "E14000860", "unit_id" => "24903"}, "name" => "North Wiltshire", "country" => "E", "type_name" => "UK Parliament constituency", "generation_low" => 13, "country_name" => "England", "type" => "WMC"}, + "11814" => {"parent_area" => undef, "generation_high" => 25, "all_names" => {}, "id" => 11814, "codes" => {"ons" => "09", "gss" => "E15000009", "unit_id" => "41427"}, "name" => "South West", "country" => "E", "type_name" => "European region", "generation_low" => 1, "country_name" => "England", "type" => "EUR"}, + "2245" => {"parent_area" => undef, "generation_high" => 25, "all_names" => {}, "id" => 2245, "codes" => {"ons" => "00HY", "gss" => "E06000054", "unit_id" => "43925"}, "name" => "Wiltshire Council", "country" => "E", "type_name" => "Unitary Authority", "generation_low" => 11, "country_name" => "England", "type" => "UTA"} + }; + # We must make sure we output correctly for testing purposes, we might + # be within a different locale here... + my $json = mySociety::Locale::in_gb_locale { + $self->json->encode($response) }; + return [ 200, [ 'Content-Type' => 'application/json' ], [ $json ] ]; + }, } sub postcode { my ($self, $postcode) = @_; return { - wgs84_lat => 51.5, wgs84_lon => 2.1, postcode => $postcode, + wgs84_lat => 51.5, wgs84_lon => -2.1, postcode => $postcode, coordsyst => 'G', }; } diff --git a/t/app/controller/admin.t b/t/app/controller/admin.t index 498f1cedc..e2dd5df19 100644 --- a/t/app/controller/admin.t +++ b/t/app/controller/admin.t @@ -88,7 +88,7 @@ subtest 'check summary counts' => sub { FixMyStreet::App->model('DB::Problem')->search( { bodies_str => 2489 } )->update( { bodies_str => 1 } ); my $q = FixMyStreet::App->model('DB::Questionnaire')->find_or_new( { problem => $report, }); - $q->whensent( \'ms_current_timestamp()' ); + $q->whensent( \'current_timestamp' ); $q->in_storage ? $q->update : $q->insert; my $alerts = FixMyStreet::App->model('DB::Alert')->search( { confirmed => { '>' => 0 } } ); diff --git a/t/app/controller/alert_new.t b/t/app/controller/alert_new.t index ac2ec20ac..777d733e2 100644 --- a/t/app/controller/alert_new.t +++ b/t/app/controller/alert_new.t @@ -11,7 +11,7 @@ foreach my $test ( { email => 'test@example.com', type => 'area_problems', - content => 'your alert will not be activated', + content => 'Click the link in our confirmation email to activate your alert', email_text => "confirms that you'd like to receive an email", uri => '/alert/subscribe?type=local&rznvy=test@example.com&feed=area:1000:A_Location', @@ -20,7 +20,7 @@ foreach my $test ( { email => 'test@example.com', type => 'council_problems', - content => 'your alert will not be activated', + content => 'Click the link in our confirmation email to activate your alert', email_text => "confirms that you'd like to receive an email", uri => '/alert/subscribe?type=local&rznvy=test@example.com&feed=council:1000:A_Location', @@ -30,7 +30,7 @@ foreach my $test ( { email => 'test@example.com', type => 'ward_problems', - content => 'your alert will not be activated', + content => 'Click the link in our confirmation email to activate your alert', email_text => "confirms that you'd like to receive an email", uri => '/alert/subscribe?type=local&rznvy=test@example.com&feed=ward:1000:1001:A_Location:Diff_Location', @@ -40,7 +40,7 @@ foreach my $test ( { email => 'test@example.com', type => 'local_problems', - content => 'your alert will not be activated', + content => 'Click the link in our confirmation email to activate your alert', email_text => "confirms that you'd like to receive an email", uri => '/alert/subscribe?type=local&rznvy=test@example.com&feed=local:10.2:20.1', @@ -50,7 +50,7 @@ foreach my $test ( { email => 'test@example.com', type => 'new_updates', - content => 'your alert will not be activated', + content => 'Click the link in our confirmation email to activate your alert', email_text => "confirms that you'd like to receive an email", uri => '/alert/subscribe?type=updates&rznvy=test@example.com&id=1', param1 => 1, @@ -236,7 +236,7 @@ for my $test ( { email => 'test@example.com', type => 'new_updates', - content => 'your alert will not be activated', + content => 'Click the link in our confirmation email to activate your alert', email_text => 'confirm the alert', uri => '/alert/subscribe?type=updates&rznvy=test@example.com&id=1', param1 => 1, diff --git a/t/app/controller/around.t b/t/app/controller/around.t index 03bcebf96..a70116525 100644 --- a/t/app/controller/around.t +++ b/t/app/controller/around.t @@ -1,7 +1,9 @@ use strict; use warnings; use Test::More; +use LWP::Protocol::PSGI; +use t::MapIt; use FixMyStreet::TestMech; my $mech = FixMyStreet::TestMech->new; @@ -71,8 +73,8 @@ foreach my $test ( foreach my $test ( { pc => 'SW1A 1AA', - latitude => '51.501009', - longitude => '-0.141588', + latitude => '51.5', + longitude => '-2.1', }, { pc => 'TQ 388 773', @@ -82,10 +84,12 @@ foreach my $test ( ) { subtest "check lat/lng for '$test->{pc}'" => sub { + LWP::Protocol::PSGI->register(t::MapIt->run_if_script, host => 'mapit.uk'); + $mech->get_ok('/'); FixMyStreet::override_config { ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ], - MAPIT_URL => 'http://mapit.mysociety.org/', + MAPIT_URL => 'http://mapit.uk/', }, sub { $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } }, "good location" ); diff --git a/t/app/controller/contact.t b/t/app/controller/contact.t index cf8a3161b..4ac69a9f8 100644 --- a/t/app/controller/contact.t +++ b/t/app/controller/contact.t @@ -93,7 +93,7 @@ for my $test ( user => $update_user, state => 'confirmed', text => $update_info->{text}, - confirmed => \'ms_current_timestamp()', + confirmed => \'current_timestamp', mark_fixed => 'f', anonymous => 'f', } diff --git a/t/app/controller/moderate.t b/t/app/controller/moderate.t index cd4c742bb..b79f50e73 100644 --- a/t/app/controller/moderate.t +++ b/t/app/controller/moderate.t @@ -42,10 +42,7 @@ sub create_report { latitude => '51.4129', longitude => '0.007831', user_id => $user->id, - photo => 'DUMMY DATA', # this obv fake data would not be - # accepted by front-end but is - # enough to trigger "I have a - # photo" behaviour + photo => $mech->get_photo_data, }); } my $report = create_report(); @@ -216,7 +213,7 @@ sub create_update { user => $user, name => 'Test User', anonymous => 'f', - photo => 'DUMMY DATA', # as above + photo => $mech->get_photo_data, text => 'update good good bad good', state => 'confirmed', mark_fixed => 0, @@ -283,7 +280,8 @@ subtest 'updates' => sub { $mech->get_ok($REPORT_URL); - $mech->content_contains('Photo of this report'); + $mech->content_contains('Photo of this report') + or die $mech->content; $mech->post_ok( $MODERATE_UPDATE_URL, { %update_prepopulated, diff --git a/t/app/controller/photo.t b/t/app/controller/photo.t new file mode 100644 index 000000000..6e61ebb32 --- /dev/null +++ b/t/app/controller/photo.t @@ -0,0 +1,75 @@ +use strict; +use utf8; # sign in error message has – in it +use warnings; +use feature 'say'; +use Test::More; +use utf8; + +use FixMyStreet::TestMech; +use FixMyStreet::App; +use Web::Scraper; +use Path::Tiny; +use File::Temp 'tempdir'; + +# disable info logs for this test run +FixMyStreet::App->log->disable('info'); +END { FixMyStreet::App->log->enable('info'); } + +my $mech = FixMyStreet::TestMech->new; + +my $sample_file = path(__FILE__)->parent->child("sample.jpg"); +ok $sample_file->exists, "sample file $sample_file exists"; + +my $westminster = $mech->create_body_ok(2527, 'Liverpool City Council'); + +subtest "Check multiple upload worked" => sub { + $mech->get_ok('/around'); + + my $UPLOAD_DIR = tempdir( CLEANUP => 1 ); + + # submit initial pc form + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ { fixmystreet => '.' } ], + MAPIT_URL => 'http://mapit.mysociety.org/', + UPLOAD_DIR => $UPLOAD_DIR, + }, sub { + + $mech->log_in_ok('test@example.com'); + + + # submit the main form + # can't post_ok as we lose the Content_Type header + # (TODO rewrite with HTTP::Request::Common and request_ok) + $mech->post( '/report/new', + Content_Type => 'form-data', + Content => + { + submit_problem => 1, + title => 'Test', + lat => 53.4031156, lon => -2.9840579, # in Liverpool + pc => 'L1 4LN', + detail => 'Detail', + photo1 => [ $sample_file, undef, Content_Type => 'application/octet-stream' ], + photo2 => [ $sample_file, undef, Content_Type => 'application/octet-stream' ], + photo3 => [ $sample_file, undef, Content_Type => 'application/octet-stream' ], + name => 'Bob Jones', + may_show_name => '1', + email => 'test@example.com', + phone => '', + category => 'Street lighting', + #password_sign_in => '', + #password_register => '', + #remember_me => undef, + } + ); + ok $mech->success, 'Made request with multiple photo upload'; + $mech->base_is('http://localhost/report/new'); + $mech->content_contains( + 'name="upload_fileid" value="1cdd4329ceee2234bd4e89cb33b42061a0724687,1cdd4329ceee2234bd4e89cb33b42061a0724687,1cdd4329ceee2234bd4e89cb33b42061a0724687"', + 'Returned upload_fileid contains expected hash, 3 times'); + my $image_file = path($UPLOAD_DIR, '1cdd4329ceee2234bd4e89cb33b42061a0724687.jpeg'); + ok $image_file->exists, 'File uploaded to temp'; + }; +}; + +done_testing(); diff --git a/t/app/controller/questionnaire.t b/t/app/controller/questionnaire.t index 5938acc79..2a89454d5 100644 --- a/t/app/controller/questionnaire.t +++ b/t/app/controller/questionnaire.t @@ -96,7 +96,7 @@ foreach my $test ( }, { desc => 'User goes to questionnaire URL for an already answered questionnaire', - answered => \'ms_current_timestamp()', + answered => \'current_timestamp', content => 'already answered this questionnaire', }, ) { @@ -191,6 +191,16 @@ foreach my $test ( }, }, { + desc => 'Fixed report, reopened, reported before, blank update, no further questionnaire', + problem_state => 'fixed', + fields => { + been_fixed => 'No', + reported => 'Yes', + another => 'No', + update => ' ', + }, + }, + { desc => 'Closed report, said fixed, reported before, no update, no further questionnaire', problem_state => 'closed', fields => { @@ -266,7 +276,7 @@ foreach my $test ( $questionnaire->discard_changes; is $report->state, $result eq 'unknown' ? $test->{problem_state} : $result; is $report->send_questionnaire, $another; - ok DateTime::Format::Pg->format_datetime( $report->lastupdate) gt $report_time, 'lastupdate changed' + ok (DateTime::Format::Pg->format_datetime( $report->lastupdate) gt $report_time, 'lastupdate changed') unless $test->{fields}{been_fixed} eq 'Unknown' || $test->{lastupdate_static}; is $questionnaire->old_state, $test->{problem_state}; is $questionnaire->new_state, $result; @@ -315,7 +325,7 @@ my $comment = FixMyStreet::App->model('DB::Comment')->find_or_create( ); subtest 'Check updates are shown correctly on questionnaire page' => sub { $mech->get_ok("/Q/" . $token->token); - $mech->content_contains( 'updates that have been left' ); + $mech->content_contains( 'Show all updates' ); $mech->content_contains( 'This is some update text' ); }; diff --git a/t/app/controller/report_display.t b/t/app/controller/report_display.t index 002cdc1e5..265760d86 100644 --- a/t/app/controller/report_display.t +++ b/t/app/controller/report_display.t @@ -96,19 +96,6 @@ subtest "change report to unconfirmed and check for 404 status" => sub { }; -subtest "Zurich unconfirmeds are 200" => sub { - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - }, sub { - $mech->host( 'zurich.example.com' ); - ok $report->update( { state => 'unconfirmed' } ), 'unconfirm report'; - $mech->get_ok("/report/$report_id"); - $mech->content_contains( 'Überprüfung ausstehend' ); - ok $report->update( { state => 'confirmed' } ), 'confirm report again'; - $mech->host( 'www.fixmystreet.com' ); - }; -}; - subtest "change report to hidden and check for 410 status" => sub { ok $report->update( { state => 'hidden' } ), 'hide report'; ok $mech->get("/report/$report_id"), "get '/report/$report_id'"; @@ -400,9 +387,72 @@ for my $test ( }; } +my $body_westminster = $mech->create_body_ok(2504, 'Westminster City Council'); +my $body_camden = $mech->create_body_ok(2505, 'Camden Borough Council'); + +for my $test ( + { + desc => 'no state dropdown if user not from authority', + from_body => undef, + no_state => 1, + report_body => $body_westminster->id, + }, + { + desc => 'state dropdown if user from authority', + from_body => $body_westminster->id, + no_state => 0, + report_body => $body_westminster->id, + }, + { + desc => 'no state dropdown if user not from same body as problem', + from_body => $body_camden->id, + no_state => 1, + report_body => $body_westminster->id, + }, + { + desc => 'state dropdown if user from authority and problem sent to multiple bodies', + from_body => $body_westminster->id, + no_state => 0, + report_body => $body_westminster->id . ',2506', + }, +) { + subtest $test->{desc} => sub { + $mech->log_in_ok( $user->email ); + $user->from_body( $test->{from_body} ); + $user->update; + + $report->discard_changes; + $report->bodies_str( $test->{report_body} ); + $report->update; + + $mech->get_ok("/report/$report_id"); + my $fields = $mech->visible_form_values( 'updateForm' ); + if ( $test->{no_state} ) { + ok !$fields->{state}; + } else { + ok $fields->{state}; + } + }; +} + +subtest "Zurich unconfirmeds are 200" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', + }, sub { + $mech->host( 'zurich.example.com' ); + ok $report->update( { state => 'unconfirmed' } ), 'unconfirm report'; + $mech->get_ok("/report/$report_id"); + $mech->content_contains( 'Überprüfung ausstehend' ); + ok $report->update( { state => 'confirmed' } ), 'confirm report again'; + $mech->host( 'www.fixmystreet.com' ); + }; +}; + subtest "Zurich banners are displayed correctly" => sub { FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', }, sub { $mech->host( 'zurich.example.com' ); @@ -428,8 +478,8 @@ subtest "Zurich banners are displayed correctly" => sub { { description => 'closed report', state => 'closed', - banner_id => 'fixed', - banner_text => 'Beantwortet', + banner_id => 'closed', + banner_text => _('Extern'), }, { description => 'in progress report', @@ -443,6 +493,21 @@ subtest "Zurich banners are displayed correctly" => sub { banner_id => 'progress', banner_text => 'In Bearbeitung', }, + { + description => 'planned report', + state => 'planned', + banner_id => 'progress', + banner_text => 'In Bearbeitung', + }, + { + description => 'jurisdiction unknown', + state => 'unable to fix', + banner_id => 'fixed', + # We can't use _('Jurisdiction Unknown') here because + # TestMech::extract_problem_banner decodes the HTML entities before + # the string is passed back. + banner_text => 'Zust\x{e4}ndigkeit unbekannt', + }, ) { subtest "banner for $test->{description}" => sub { $report->state( $test->{state} ); @@ -470,53 +535,6 @@ subtest "Zurich banners are displayed correctly" => sub { }; }; -my $body_westminster = $mech->create_body_ok(2504, 'Westminster City Council'); -my $body_camden = $mech->create_body_ok(2505, 'Camden Borough Council'); - -for my $test ( - { - desc => 'no state dropdown if user not from authority', - from_body => undef, - no_state => 1, - report_body => $body_westminster->id, - }, - { - desc => 'state dropdown if user from authority', - from_body => $body_westminster->id, - no_state => 0, - report_body => $body_westminster->id, - }, - { - desc => 'no state dropdown if user not from same body as problem', - from_body => $body_camden->id, - no_state => 1, - report_body => $body_westminster->id, - }, - { - desc => 'state dropdown if user from authority and problem sent to multiple bodies', - from_body => $body_westminster->id, - no_state => 0, - report_body => $body_westminster->id . ',2506', - }, -) { - subtest $test->{desc} => sub { - $mech->log_in_ok( $user->email ); - $user->from_body( $test->{from_body} ); - $user->update; - - $report->discard_changes; - $report->bodies_str( $test->{report_body} ); - $report->update; - - $mech->get_ok("/report/$report_id"); - my $fields = $mech->visible_form_values( 'updateForm' ); - if ( $test->{no_state} ) { - ok !$fields->{state}; - } else { - ok $fields->{state}; - } - }; -} END { $mech->delete_user('test@example.com'); diff --git a/t/app/controller/report_import.t b/t/app/controller/report_import.t index ff6508149..4d0f6e5d1 100644 --- a/t/app/controller/report_import.t +++ b/t/app/controller/report_import.t @@ -1,7 +1,9 @@ use strict; use warnings; use Test::More; +use LWP::Protocol::PSGI; +use t::MapIt; use FixMyStreet::TestMech; use FixMyStreet::App; use Web::Scraper; @@ -17,7 +19,7 @@ ok -e $sample_file, "sample file $sample_file exists"; FixMyStreet::App->log->disable('info'); END { FixMyStreet::App->log->enable('info'); } -my $body = $mech->create_body_ok(2504, 'Westminster City Council'); +my $body = $mech->create_body_ok(2245, 'Wiltshire Council'); $mech->create_contact_ok( body_id => $body->id, category => 'Street lighting', @@ -90,6 +92,7 @@ subtest "Test creating bad partial entries" => sub { }; subtest "Submit a correct entry" => sub { + LWP::Protocol::PSGI->register(t::MapIt->run_if_script, host => 'mapit.uk'); $mech->get_ok('/import'); @@ -120,7 +123,7 @@ subtest "Submit a correct entry" => sub { # go to the token url FixMyStreet::override_config { - MAPIT_URL => 'http://mapit.mysociety.org/', + MAPIT_URL => 'http://mapit.uk/', }, sub { $mech->get_ok($token_url); }; @@ -134,10 +137,10 @@ subtest "Submit a correct entry" => sub { FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'fixmystreet' ], - MAPIT_URL => 'http://mapit.mysociety.org/', + MAPIT_URL => 'http://mapit.uk/', }, sub { $mech->submit_form_ok( - { with_fields => { pc => 'SW1A 1AA' } }, + { with_fields => { pc => 'SN15 5NG' } }, "fill in postcode" ); }; @@ -159,15 +162,15 @@ subtest "Submit a correct entry" => sub { # Check photo present, and still there after map submission (testing bug #18) $mech->content_contains( '<img align="right" src="/photo/' ); - $mech->content_contains('latitude" value="51.501009"', 'Check latitude'); - $mech->content_contains('longitude" value="-0.141588"', 'Check longitude'); + $mech->content_contains('latitude" value="51.5"', 'Check latitude'); + $mech->content_contains('longitude" value="-2.1"', 'Check longitude'); FixMyStreet::override_config { ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ], - MAPIT_URL => 'http://mapit.mysociety.org/', + MAPIT_URL => 'http://mapit.uk/', }, sub { $mech->submit_form_ok( { - button => 'tile_32742.21793', + button => 'tile_16192.10896', x => 10, y => 10, }, @@ -175,8 +178,8 @@ subtest "Submit a correct entry" => sub { ); }; $mech->content_contains( '<img align="right" src="/photo/' ); - $mech->content_contains('latitude" value="51.50519"', 'Check latitude'); - $mech->content_contains('longitude" value="-0.142608"', 'Check longitude'); + $mech->content_contains('latitude" value="51.508475"', 'Check latitude'); + $mech->content_contains('longitude" value="-2.108946"', 'Check longitude'); # check that fields haven't changed at all is_deeply $mech->visible_form_values, @@ -194,7 +197,7 @@ subtest "Submit a correct entry" => sub { # change the details FixMyStreet::override_config { ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ], - MAPIT_URL => 'http://mapit.mysociety.org/', + MAPIT_URL => 'http://mapit.uk/', }, sub { $mech->submit_form_ok( { @@ -232,8 +235,8 @@ subtest "Submit a correct entry (with location)" => sub { { with_fields => { service => 'test-script', - lat => '51.5010096115539', # SW1A 1AA - lon => '-0.141587067110009', + lat => '51.5', + lon => '-2.1', name => 'Test User ll', email => 'test-ll@example.com', subject => 'Test report ll', @@ -318,6 +321,7 @@ subtest "Submit a correct entry (with location) to cobrand" => sub { MAPIT_URL => 'http://global.mapit.mysociety.org/', MAPIT_TYPES => [ 'O08' ], MAPIT_ID_WHITELIST => [], + MAP_TYPE => 'Zurich,OSM', }, sub { ok $mech->host("zurich.example.org"), 'change host to zurich'; @@ -361,11 +365,14 @@ subtest "Submit a correct entry (with location) to cobrand" => sub { { name => 'Test User ll', detail => 'This is a test report ll', - photo => '', + photo1 => '', + photo2 => '', + photo3 => '', phone => '', email => 'test-ll@example.com', }, - "check imported fields are shown"; + "check imported fields are shown" + or diag Dumper( $mech->visible_form_values ); use Data::Dumper; my $user = FixMyStreet::App->model('DB::User') diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t index bd0001be8..3c05adfbd 100644 --- a/t/app/controller/report_new.t +++ b/t/app/controller/report_new.t @@ -1475,7 +1475,7 @@ subtest "unresponsive body handling works" => sub { ok $mech->content_like( qr{Edinburgh.*accept reports.*/unresponsive\?body=$body_id} ); my $test_email = 'test-2@example.com'; - my $user = $mech->log_in_ok($test_email); + $mech->log_out_ok; $mech->get_ok('/around'); $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } }, "submit location" ); $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" ); @@ -1486,6 +1486,7 @@ subtest "unresponsive body handling works" => sub { detail => 'Test report details.', photo => '', name => 'Joe Bloggs', + email => $test_email, may_show_name => '1', phone => '07903 123 456', category => 'Trees', @@ -1494,10 +1495,17 @@ subtest "unresponsive body handling works" => sub { "submit good details" ); + my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); + ok $user, "test user does exist"; + my $report = $user->problems->first; ok $report, "Found the report"; is $report->bodies_str, undef, "Report not going anywhere"; + my $email = $mech->get_email; + ok $email, "got an email"; + like $email->body, qr/despite not being sent/i, "correct email sent"; + $user->problems->delete; $contact1->body->update( { send_method => $old_send } ); @@ -1517,6 +1525,7 @@ subtest "unresponsive body handling works" => sub { detail => 'Test report details.', photo => '', name => 'Joe Bloggs', + email => $test_email, may_show_name => '1', phone => '07903 123 456', category => 'Trees', diff --git a/t/app/controller/report_updates.t b/t/app/controller/report_updates.t index fa6c44292..6c6b4ca19 100644 --- a/t/app/controller/report_updates.t +++ b/t/app/controller/report_updates.t @@ -353,7 +353,7 @@ for my $test ( 'submit update' ); - $mech->content_contains('Nearly Done! Now check your email'); + $mech->content_contains('Nearly done! Now check your email'); my $email = $mech->get_email; ok $email, "got an email"; @@ -1007,7 +1007,7 @@ subtest 'submit an update for a registered user, creating update by email' => su }, }, 'submit update' ); - $mech->content_contains('Nearly Done! Now check your email'); + $mech->content_contains('Nearly done! Now check your email'); # No change to user yet. $user->discard_changes; @@ -1339,7 +1339,7 @@ foreach my $test ( { problem_id => $report_id, ever_reported => 'y', - whensent => \'ms_current_timestamp()', + whensent => \'current_timestamp', } ); @@ -1481,7 +1481,7 @@ for my $test ( { problem_id => $report_id, ever_reported => 'y', - whensent => \'ms_current_timestamp()', + whensent => \'current_timestamp', } ); diff --git a/t/app/controller/reports.t b/t/app/controller/reports.t index ecb43f447..02625fcc7 100644 --- a/t/app/controller/reports.t +++ b/t/app/controller/reports.t @@ -216,5 +216,28 @@ subtest "test fiksgatami all reports page" => sub { } }; +subtest "test greenwich all reports page" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'greenwich' ], + MAPIT_URL => 'http://mapit.mysociety.org/' + }, sub { + my $body = $mech->create_body_ok(2493, 'Royal Borough of Greenwich'); + my $deleted_contact = $mech->create_contact_ok( + body_id => $body->id, + category => 'Deleted', + email => 'deleted@example.com', + deleted => 1 + ); + ok $mech->host("greenwich.fixmystreet.com"), 'change host to greenwich'; + $mech->get_ok('/reports/Royal+Borough+of+Greenwich'); + # There should not be deleted categories in the list + my $category_select = $mech->forms()->[0]->find_input('filter_category'); + is $category_select->possible_values, 1, 'deleted categories are not shown'; + + # Clean up after the test + $deleted_contact->delete; + } +}; + done_testing(); diff --git a/t/app/controller/rss.t b/t/app/controller/rss.t index ae1c0d193..db653c094 100644 --- a/t/app/controller/rss.t +++ b/t/app/controller/rss.t @@ -127,11 +127,14 @@ $mech->content_contains( '18 North Bridge, Edinburgh' ); $report->delete(); +my $council = $mech->create_body_ok(2333, 'Hart Council'); +my $county = $mech->create_body_ok(2227, 'Hampshire Council'); + my $now = DateTime->now(); my $report_to_council = FixMyStreet::App->model('DB::Problem')->find_or_create( { postcode => 'GU51 4AE', - bodies_str => '2333', + bodies_str => $council->id, areas => ',2333,2227,', category => 'Other', title => 'council report', @@ -155,7 +158,7 @@ my $report_to_council = FixMyStreet::App->model('DB::Problem')->find_or_create( my $report_to_county_council = FixMyStreet::App->model('DB::Problem')->find_or_create( { postcode => 'GU51 4AE', - bodies_str => '2227', + bodies_str => $county->id, areas => ',2333,2227,', category => 'Other', title => 'county report', diff --git a/t/app/helpers/grey.gif b/t/app/helpers/grey.gif Binary files differnew file mode 100644 index 000000000..98eee7d12 --- /dev/null +++ b/t/app/helpers/grey.gif diff --git a/t/app/helpers/send_email.t b/t/app/helpers/send_email.t index 14c7d363b..d1609cb2f 100644 --- a/t/app/helpers/send_email.t +++ b/t/app/helpers/send_email.t @@ -9,12 +9,16 @@ BEGIN { FixMyStreet->test_mode(1); } -use Test::More tests => 5; +use Test::More; +use Test::LongString; use Catalyst::Test 'FixMyStreet::App'; use Email::Send::Test; -use Path::Class; +use Path::Tiny; + +use FixMyStreet::TestMech; +my $mech = FixMyStreet::TestMech->new; my $c = ctx_request("/"); @@ -33,16 +37,66 @@ my @emails = Email::Send::Test->emails; is scalar(@emails), 1, "caught one email"; # Get the email, check it has a date and then strip it out -my $email_as_string = $emails[0]->as_string; -ok $email_as_string =~ s{\s+Date:\s+\S.*?$}{}xms, "Found and stripped out date"; -ok $email_as_string =~ s{\s+Message-ID:\s+\S.*?$}{}xms, "Found and stripped out message ID (contains epoch)"; +my $email_as_string = $mech->get_first_email(@emails); -my $expected_email_content = file(__FILE__)->dir->file('send_email_sample.txt')->slurp; +my $expected_email_content = path(__FILE__)->parent->child('send_email_sample.txt')->slurp; my $name = FixMyStreet->config('CONTACT_NAME'); $name = "\"$name\"" if $name =~ / /; my $sender = $name . ' <' . FixMyStreet->config('DO_NOT_REPLY_EMAIL') . '>'; $expected_email_content =~ s{CONTACT_EMAIL}{$sender}; -is $email_as_string, -$expected_email_content, - "email is as expected"; +is_string $email_as_string, $expected_email_content, "email is as expected"; + +subtest 'MIME attachments' => sub { + my $data = path(__FILE__)->parent->child('grey.gif')->slurp_raw; + + Email::Send::Test->clear; + my @emails = Email::Send::Test->emails; + is scalar(@emails), 0, "reset"; + + ok $c->send_email( 'test.txt', + { to => 'test@recipient.com', + attachments => [ + { + body => $data, + attributes => { + filename => 'foo.gif', + content_type => 'image/gif', + encoding => 'quoted-printable', + name => 'foo.gif', + }, + }, + { + body => $data, + attributes => { + filename => 'bar.gif', + content_type => 'image/gif', + encoding => 'quoted-printable', + name => 'bar.gif', + }, + }, + ] + } ), "sent an email with MIME attachments"; + + @emails = $mech->get_email; + is scalar(@emails), 1, "caught one email"; + + my $email_as_string = $mech->get_first_email(@emails); + + my ($boundary) = $email_as_string =~ /boundary="([A-Za-z0-9.]*)"/ms; + my $changes = $email_as_string =~ s{$boundary}{}g; + is $changes, 5, '5 boundaries'; # header + 4 around the 3x parts (text + 2 images) + + my $expected_email_content = path(__FILE__)->parent->child('send_email_sample_mime.txt')->slurp; + $expected_email_content =~ s{CONTACT_EMAIL}{$sender}g; + + is_string $email_as_string, $expected_email_content, 'MIME email text ok' + or do { + (my $test_name = $0) =~ s{/}{_}g; + my $path = path("test-output-$test_name.tmp"); + $path->spew($email_as_string); + diag "Saved output in $path"; + }; +}; + +done_testing; diff --git a/t/app/helpers/send_email_sample_mime.txt b/t/app/helpers/send_email_sample_mime.txt new file mode 100644 index 000000000..4ce0f9520 --- /dev/null +++ b/t/app/helpers/send_email_sample_mime.txt @@ -0,0 +1,57 @@ +MIME-Version: 1.0 +Subject: test email =?utf-8?Q?=E2=98=BA?= +Content-Type: multipart/mixed; boundary="" +To: test@recipient.com +Content-Transfer-Encoding: 7bit +From: CONTACT_EMAIL + + +-- +MIME-Version: 1.0 +Subject: test email =?utf-8?Q?=E2=98=BA?= +Content-Type: text/plain; charset="utf-8" +To: test@recipient.com +Content-Transfer-Encoding: quoted-printable +From: CONTACT_EMAIL + +Hello, + +This is a test email where foo: bar. + +utf8: =E6=88=91=E4=BB=AC=E5=BA=94=E8=AF=A5=E8=83=BD=E5=A4=9F=E6=97=A0=E7=BC= +=9D=E5=A4=84=E7=90=86UTF8=E7=BC=96=E7=A0=81 + + indented_text + +long line: Lorem ipsum dolor sit amet, consectetur adipisicing elit, +sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris +nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in +reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla +pariatur. Excepteur sint occaecat cupidatat non proident, sunt in +culpa qui officia deserunt mollit anim id est laborum. + +Yours,=20=20 +FixMyStreet.=20= + + + +-- +MIME-Version: 1.0 +Content-Type: image/gif; name="foo.gif" +Content-Disposition: inline; filename="foo.gif" +Content-Transfer-Encoding: quoted-printable + +GIF89a=01=00=01=00=80=00=00=00=00=00=CC=CC=CC,=00=00=00=00=01=00=01=00=00= +=02=01L=00;= + +-- +MIME-Version: 1.0 +Content-Type: image/gif; name="bar.gif" +Content-Disposition: inline; filename="bar.gif" +Content-Transfer-Encoding: quoted-printable + +GIF89a=01=00=01=00=80=00=00=00=00=00=CC=CC=CC,=00=00=00=00=01=00=01=00=00= +=02=01L=00;= + +---- diff --git a/t/app/model/alert_type.t b/t/app/model/alert_type.t index 528c4d354..2620dd68c 100644 --- a/t/app/model/alert_type.t +++ b/t/app/model/alert_type.t @@ -87,7 +87,7 @@ my $comment2 = FixMyStreet::App->model('DB::Comment')->find_or_create( } ); -$comment->confirmed( \"ms_current_timestamp() - '3 days'::interval" ); +$comment->confirmed( \"current_timestamp - '3 days'::interval" ); $comment->update; my $alert = FixMyStreet::App->model('DB::Alert')->find_or_create( diff --git a/t/app/model/photoset.t b/t/app/model/photoset.t new file mode 100644 index 000000000..9e566f873 --- /dev/null +++ b/t/app/model/photoset.t @@ -0,0 +1,76 @@ +use strict; +use warnings; +use Test::More; +use Test::Exception; +use utf8; + +use FixMyStreet::App; +use Data::Dumper; +use DateTime; +use Path::Tiny 'path'; +use File::Temp 'tempdir'; + +my $dt = DateTime->now; + +my $c = FixMyStreet::App->new; +my $UPLOAD_DIR = tempdir( CLEANUP => 1 ); +local $c->config->{UPLOAD_DIR} = $UPLOAD_DIR; + +my $user = $c->model('DB::User')->find_or_create({ + name => 'Bob', email => 'bob@example.com', +}); + +my $image_path = path('t/app/controller/sample.jpg'); + +my $db = FixMyStreet::App->model('DB')->schema; +$db->txn_begin; + +sub make_report { + my $photo_data = shift; + return $db->resultset('Problem')->create({ + postcode => 'BR1 3SB', + bodies_str => '', + areas => ",,", + category => 'Other', + title => 'test', + detail => 'test', + used_map => 't', + name => 'Anon', + anonymous => 't', + state => 'confirmed', + confirmed => $dt, + lang => 'en-gb', + service => '', + cobrand => 'default', + cobrand_data => '', + send_questionnaire => 't', + latitude => '51.4129', + longitude => '0.007831', + user => $user, + photo => $photo_data, + }); +} + + +subtest 'Photoset with photo inline in DB' => sub { + my $report = make_report( $image_path->slurp ); + my $photoset = $report->get_photoset($c); + is $photoset->num_images, 1, 'Found just 1 image'; +}; + +$image_path->copy( path( $UPLOAD_DIR, '0123456789012345678901234567890123456789.jpeg' ) ); +subtest 'Photoset with 1 referenced photo' => sub { + my $report = make_report( '0123456789012345678901234567890123456789' ); + my $photoset = $report->get_photoset($c); + is $photoset->num_images, 1, 'Found just 1 image'; +}; + +subtest 'Photoset with 1 referenced photo' => sub { + my $report = make_report( '0123456789012345678901234567890123456789,0123456789012345678901234567890123456789,0123456789012345678901234567890123456789' ); + my $photoset = $report->get_photoset($c); + is $photoset->num_images, 3, 'Found 3 images'; +}; + +$db->txn_rollback; + +done_testing(); diff --git a/t/app/model/problem.t b/t/app/model/problem.t index ad82a62a5..82569d72a 100644 --- a/t/app/model/problem.t +++ b/t/app/model/problem.t @@ -457,7 +457,8 @@ foreach my $test ( { email_count => 1, to => qr'Gloucestershire County Council" <2226@example', dear => qr'Dear Gloucestershire County Council,', - body => $body_ids{2226} . '|' . $body_ids{2649}, + body => $body_ids{2226}, + body_missing => $body_ids{2649}, missing => qr'problem might be the responsibility of Fife.*Council'ms, }, { %common, @@ -524,14 +525,15 @@ foreach my $test ( { { whensent => undef } - )->update( { whensent => \'ms_current_timestamp()' } ); + )->update( { whensent => \'current_timestamp' } ); $problem->discard_changes; $problem->update( { bodies_str => $test->{ body }, + bodies_missing => $test->{ body_missing }, state => 'confirmed', - confirmed => \'ms_current_timestamp()', - whensent => $test->{ unset_whendef } ? undef : \'ms_current_timestamp()', + confirmed => \'current_timestamp', + whensent => $test->{ unset_whendef } ? undef : \'current_timestamp', category => $test->{ category } || 'potholes', name => $test->{ name }, cobrand => $test->{ cobrand } || 'fixmystreet', @@ -598,13 +600,13 @@ subtest 'check can set mutiple emails as a single contact' => sub { { whensent => undef } - )->update( { whensent => \'ms_current_timestamp()' } ); + )->update( { whensent => \'current_timestamp' } ); $problem->discard_changes; $problem->update( { bodies_str => $contact->{ body_id }, state => 'confirmed', - confirmed => \'ms_current_timestamp()', + confirmed => \'current_timestamp', whensent => undef, category => 'trees', name => 'Test User', @@ -632,13 +634,13 @@ subtest 'check can turn on report sent email alerts' => sub { { whensent => undef } - )->update( { whensent => \'ms_current_timestamp()' } ); + )->update( { whensent => \'current_timestamp' } ); $problem->discard_changes; $problem->update( { bodies_str => $body_ids{2651}, state => 'confirmed', - confirmed => \'ms_current_timestamp()', + confirmed => \'current_timestamp', whensent => undef, category => 'potholes', name => 'Test User', @@ -677,14 +679,14 @@ subtest 'check iOS app store test reports not sent' => sub { { whensent => undef } - )->update( { whensent => \'ms_current_timestamp()' } ); + )->update( { whensent => \'current_timestamp' } ); $problem->discard_changes; $problem->update( { bodies_str => $body_ids{2651}, title => 'App store test', state => 'confirmed', - confirmed => \'ms_current_timestamp()', + confirmed => \'current_timestamp', whensent => undef, category => 'potholes', send_fail_count => 0, @@ -706,14 +708,14 @@ subtest 'check reports from abuser not sent' => sub { { whensent => undef } - )->update( { whensent => \'ms_current_timestamp()' } ); + )->update( { whensent => \'current_timestamp' } ); $problem->discard_changes; $problem->update( { bodies_str => $body_ids{2651}, title => 'Report', state => 'confirmed', - confirmed => \'ms_current_timestamp()', + confirmed => \'current_timestamp', whensent => undef, category => 'potholes', send_fail_count => 0, @@ -728,7 +730,7 @@ subtest 'check reports from abuser not sent' => sub { $problem->update( { state => 'confirmed', - confirmed => \'ms_current_timestamp()', + confirmed => \'current_timestamp', whensent => undef, } ); diff --git a/t/app/model/questionnaire.t b/t/app/model/questionnaire.t index be5b433c1..240d6d050 100644 --- a/t/app/model/questionnaire.t +++ b/t/app/model/questionnaire.t @@ -25,8 +25,8 @@ my $problem = FixMyStreet::App->model('DB::Problem')->create( service => '', cobrand => 'default', cobrand_data => '', - confirmed => \"ms_current_timestamp() - '5 weeks'::interval", - whensent => \"ms_current_timestamp() - '5 weeks'::interval", + confirmed => \"current_timestamp - '5 weeks'::interval", + whensent => \"current_timestamp - '5 weeks'::interval", user => $user, anonymous => 0, } diff --git a/t/app/model/token.t b/t/app/model/token.t index 637477fa3..d72574bb1 100644 --- a/t/app/model/token.t +++ b/t/app/model/token.t @@ -7,17 +7,6 @@ use Test::More; use FixMyStreet; use FixMyStreet::App; -use mySociety::AuthToken; -use mySociety::DBHandle 'dbh'; - -# set things up so that code using mySociety::DBHandle is happy -FixMyStreet->configure_mysociety_dbhandle(); - -# NOTE - remember that you need to explicitly dbh()->commit after making -# database changes with the mySociety::* modules. - -# create a token using DBIC and check we can read it using AuthToken, and vice -# versa my %tests = ( nested_hash => { foo => 'bar', and => [ 'baz', 'bundy' ] }, @@ -27,76 +16,31 @@ my %tests = ( my $token_rs = FixMyStreet::App->model('DB::Token'); -# create using DBIC foreach my $test_data_name ( sort keys %tests ) { my $test_data = $tests{$test_data_name}; - pass "--- testing DBIC create using '$test_data_name'"; + pass "--- testing token creation using '$test_data_name'"; my $dbic_token = $token_rs->create( { scope => 'testing', data => $test_data } ); my $token = $dbic_token->token; ok $token, "stored token '$token'"; - is_deeply $dbic_token->data, $test_data, "data stored correctly using DBIC"; + is_deeply $dbic_token->data, $test_data, "data stored correctly"; - # read back using DBIC + # read back from database is_deeply $token_rs->find( { token => $token, scope => 'testing' } )->data, $test_data, - "data read back correctly with DBIC"; - - # read back using mySociety::AuthToken - is_deeply mySociety::AuthToken::retrieve( 'testing', $token ), - $test_data, "data read back correctly with m::AT"; + "data read back correctly"; # delete token ok $dbic_token->delete, "delete token"; is $token_rs->find( { token => $token, scope => 'testing' } ), undef, - "token gone for DBIC"; - - # read back using mySociety::AuthToken - is mySociety::AuthToken::retrieve( 'testing', $token ), - undef, "token gone with m::AT"; - -} - -# create using m::AT -foreach my $test_data_name ( sort keys %tests ) { - my $test_data = $tests{$test_data_name}; - - pass "--- testing m::AT create using '$test_data_name'"; - - my $token = mySociety::AuthToken::store( 'testing', $test_data ); - dbh->commit(); - ok $token, "stored token '$token'"; - - # read back using DBIC - is_deeply $token_rs->find( { token => $token, scope => 'testing' } )->data, - $test_data, - "data read back correctly with DBIC"; - - # read back using mySociety::AuthToken - is_deeply mySociety::AuthToken::retrieve( 'testing', $token ), - $test_data, "data read back correctly with m::AT"; - - # delete token - ok mySociety::AuthToken::destroy( 'testing', $token ), "destroy token"; - dbh->commit(); - - is $token_rs->find( { token => $token, scope => 'testing' } ), - undef, - "token gone for DBIC"; - - # read back using mySociety::AuthToken - is mySociety::AuthToken::retrieve( 'testing', $token ), - undef, "token gone with m::AT"; - + "token gone"; } - - # Test that the inflation and deflation works as expected { my $token = diff --git a/t/cobrand/fixamingata.t b/t/cobrand/fixamingata.t index 3c818474d..d181d3890 100644 --- a/t/cobrand/fixamingata.t +++ b/t/cobrand/fixamingata.t @@ -71,7 +71,7 @@ my $comment = FixMyStreet::App->model('DB::Comment')->find_or_create({ state => 'confirmed', anonymous => 'f', }); -$comment->confirmed( \"ms_current_timestamp() - '3 days'::interval" ); +$comment->confirmed( \"current_timestamp - '3 days'::interval" ); $comment->update; my $alert = FixMyStreet::App->model('DB::Alert')->find_or_create({ diff --git a/t/cobrand/two_tier.t b/t/cobrand/two_tier.t index ad664aabd..b3d6ca7db 100644 --- a/t/cobrand/two_tier.t +++ b/t/cobrand/two_tier.t @@ -6,11 +6,11 @@ use FixMyStreet; use FixMyStreet::Cobrand; my @cobrands = ( - [ hart => '%2333%' ], - [ oxfordshire => '%2237%' ], - [ eastsussex => '%2224%' ], - [ stevenage => '%2347%' ], - [ warwickshire => '%2243%' ], + [ hart => 2333 ], + [ oxfordshire => 2237 ], + [ eastsussex => 2224 ], + [ stevenage => 2347 ], + [ warwickshire => 2243 ], ); FixMyStreet::override_config { @@ -18,11 +18,10 @@ FixMyStreet::override_config { }, sub { for my $c (@cobrands) { - my ($m, $like) = @$c; + my ($m, $id) = @$c; my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($m); - my $problems_clause = $cobrand->problems_clause; - is_deeply $problems_clause, - { bodies_str => { like => $like } }, "problems_clause for $m"; + my $body_restriction = $cobrand->body_restriction; + is $body_restriction, $id, "body_restriction for $m"; } }; diff --git a/t/cobrand/zurich-logo_portal.x.jpg b/t/cobrand/zurich-logo_portal.x.jpg Binary files differnew file mode 100644 index 000000000..c0cfef240 --- /dev/null +++ b/t/cobrand/zurich-logo_portal.x.jpg diff --git a/t/cobrand/zurich.t b/t/cobrand/zurich.t index 90a92fb44..721ee547c 100644 --- a/t/cobrand/zurich.t +++ b/t/cobrand/zurich.t @@ -5,7 +5,9 @@ use strict; use warnings; use DateTime; use Test::More; +use Test::LongString; use JSON; +use Path::Tiny; # Check that you have the required locale installed - the following # should return a line with de_CH.utf8 in. If not install that locale. @@ -21,10 +23,19 @@ my $c = FixMyStreet::App->new(); my $cobrand = FixMyStreet::Cobrand::Zurich->new({ c => $c }); $c->stash->{cobrand} = $cobrand; +my $sample_file = path(__FILE__)->parent->parent->child("app/controller/sample.jpg"); +ok $sample_file->exists, "sample file $sample_file exists"; +my $sample_photo = $sample_file->slurp_raw; + # This is a helper method that will send the reports but with the config -# correctly set - notably SEND_REPORTS_ON_STAGING needs to be true. +# correctly set - notably SEND_REPORTS_ON_STAGING needs to be true, and +# zurich must be allowed cobrand if we want to be able to call cobrand +# methods on it. sub send_reports_for_zurich { - FixMyStreet::override_config { SEND_REPORTS_ON_STAGING => 1 }, sub { + FixMyStreet::override_config { + SEND_REPORTS_ON_STAGING => 1, + ALLOWED_COBRANDS => ['zurich'] + }, sub { # Actually send the report $c->model('DB::Problem')->send_reports('zurich'); }; @@ -32,15 +43,14 @@ sub send_reports_for_zurich { sub reset_report_state { my ($report, $created) = @_; $report->discard_changes; - my $extra = $report->extra; - delete $extra->{moderated_overdue}; - delete $extra->{subdiv_overdue}; - delete $extra->{closed_overdue}; - $report->update({ - extra => { %$extra }, - state => 'unconfirmed', - $created ? ( created => $created ) : (), - }); + $report->unset_extra_metadata('moderated_overdue'); + $report->unset_extra_metadata('subdiv_overdue'); + $report->unset_extra_metadata('closed_overdue'); + $report->unset_extra_metadata('closure_status'); + $report->whensent(undef); + $report->state('unconfirmed'); + $report->created($created) if $created; + $report->update; } use FixMyStreet::TestMech; @@ -64,6 +74,7 @@ $division->parent( $zurich->id ); $division->send_method( 'Zurich' ); $division->endpoint( 'division@example.org' ); $division->update; +$division->body_areas->find_or_create({ area_id => 274456 }); my $subdivision = $mech->create_body_ok( 3, 'Subdivision A' ); $subdivision->parent( $division->id ); $subdivision->send_method( 'Zurich' ); @@ -103,15 +114,18 @@ my @reports = $mech->create_problems_for_body( 1, $division->id, 'Test', { state => 'unconfirmed', confirmed => undef, cobrand => 'zurich', + photo => $sample_photo, }); my $report = $reports[0]; FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', }, sub { $mech->get_ok( '/report/' . $report->id ); }; -$mech->content_contains('Überprüfung ausstehend'); +$mech->content_contains('Überprüfung ausstehend') + or die $mech->content; # Check logging in to deal with this report FixMyStreet::override_config { @@ -136,7 +150,6 @@ $mech->content_contains( 'report_edit/' . $report->id ); $mech->content_contains( DateTime->now->strftime("%d.%m.%Y") ); $mech->content_contains( 'Erfasst' ); - subtest "changing of categories" => sub { # create a few categories (which are actually contacts) foreach my $name ( qw/Cat1 Cat2/ ) { @@ -147,6 +160,9 @@ subtest "changing of categories" => sub { ); } + # full Categories dropdown is hidden for unconfirmed reports + $report->update({ state => 'confirmed' }); + # put report into known category my $original_category = $report->category; $report->update({ category => 'Cat1' }); @@ -159,6 +175,7 @@ subtest "changing of categories" => sub { # change the category via the web interface FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', }, sub { $mech->get_ok( '/admin/report_edit/' . $report->id ); $mech->submit_form_ok( { with_fields => { category => 'Cat2' } } ); @@ -202,107 +219,112 @@ sub get_moderated_count { subtest "report_edit" => sub { - ok ( ! exists ${$report->extra}{moderated_overdue}, 'Report currently unmoderated' ); - - is get_moderated_count(), 0; - FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', }, sub { + + reset_report_state($report); + ok ( ! $report->get_extra_metadata('moderated_overdue'), 'Report currently unmoderated' ); + is get_moderated_count(), 0; + $mech->get_ok( '/admin/report_edit/' . $report->id ); $mech->content_contains( 'Unbestätigt' ); # Unconfirmed email $mech->submit_form_ok( { with_fields => { state => 'confirmed' } } ); $mech->get_ok( '/report/' . $report->id ); - }; - $mech->content_contains('Aufgenommen'); - $mech->content_contains('Test Test'); - $mech->content_lacks('photo/' . $report->id . '.jpeg'); - $mech->email_count_is(0); + $report->discard_changes(); - $report->discard_changes; + $mech->content_contains('Aufgenommen'); + $mech->content_contains('Test Test'); + $mech->content_lacks('photo/' . $report->id . '.0.jpeg'); + $mech->email_count_is(0); - is ( $report->extra->{moderated_overdue}, 0, 'Report now marked moderated' ); - is get_moderated_count(), 1; + $report->discard_changes; + is ( $report->get_extra_metadata('moderated_overdue'), 0, 'Report now marked moderated' ); + is get_moderated_count(), 1; - # Set state back to 10 days ago so that report is overdue - my $created = $report->created; - reset_report_state($report, $created->clone->subtract(days => 10)); + # Set state back to 10 days ago so that report is overdue + my $created = $report->created; + reset_report_state($report, $created->clone->subtract(days => 10)); - is get_moderated_count(), 0; + is get_moderated_count(), 0; - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - }, sub { $mech->get_ok( '/admin/report_edit/' . $report->id ); $mech->submit_form_ok( { with_fields => { state => 'confirmed' } } ); $mech->get_ok( '/report/' . $report->id ); - }; - $report->discard_changes; - is ( $report->extra->{moderated_overdue}, 1, 'moderated_overdue set correctly when overdue' ); - is get_moderated_count(), 0, 'Moderated count not increased when overdue'; - reset_report_state($report, $created); + $report->discard_changes; + is ( $report->get_extra_metadata('moderated_overdue'), 1, 'moderated_overdue set correctly when overdue' ); + is get_moderated_count(), 0, 'Moderated count not increased when overdue'; + + reset_report_state($report, $created); - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - }, sub { $mech->get_ok( '/admin/report_edit/' . $report->id ); $mech->submit_form_ok( { with_fields => { state => 'confirmed' } } ); $mech->get_ok( '/report/' . $report->id ); - }; - $report->discard_changes; - is ( $report->extra->{moderated_overdue}, 0, 'Marking confirmed sets moderated_overdue' ); - is ( $report->extra->{closed_overdue}, undef, 'Marking confirmed does NOT set closed_overdue' ); - is get_moderated_count(), 1; + $report->discard_changes; + is ( $report->get_extra_metadata('moderated_overdue'), 0, 'Marking confirmed sets moderated_overdue' ); + is ( $report->get_extra_metadata('closed_overdue'), undef, 'Marking confirmed does NOT set closed_overdue' ); + is get_moderated_count(), 1; - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - }, sub { $mech->get_ok( '/admin/report_edit/' . $report->id ); $mech->submit_form_ok( { with_fields => { state => 'hidden' } } ); $mech->get_ok( '/admin/report_edit/' . $report->id ); - }; - $report->discard_changes; - is ( $report->extra->{moderated_overdue}, 0, 'Still marked moderated_overdue' ); - is ( $report->extra->{closed_overdue}, 0, 'Marking hidden also set closed_overdue' ); - is get_moderated_count(), 1, 'Check still counted moderated' - or diag $report->get_column('extra'); - reset_report_state($report); + $report->discard_changes; + is ( $report->get_extra_metadata('moderated_overdue'), 0, 'Still marked moderated_overdue' ); + is ( $report->get_extra_metadata('closed_overdue'), undef, "Marking hidden doesn't set closed_overdue..." ); + is ( $report->state, 'planned', 'Marking hidden actually sets state to planned'); + is ( $report->get_extra_metadata('closure_status'), 'hidden', 'Marking hidden sets closure_status to hidden'); + is get_moderated_count(), 1, 'Check still counted moderated' + or diag $report->get_column('extra'); + + # publishing actually sets hidden + $mech->form_with_fields( 'status_update' ); + $mech->submit_form_ok( { button => 'publish_response' } ); + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $report->discard_changes; - is ( $report->extra->{moderated_overdue}, undef, 'Sanity check' ); - is get_moderated_count(), 0; + is ( $report->get_extra_metadata('closed_overdue'), 0, "Closing as hidden sets closed_overdue..." ); + is ( $report->state, 'hidden', 'Closing as hidden sets state to hidden'); + is ( $report->get_extra_metadata('closure_status'), undef, 'Closing as hidden unsets closure_status'); - # Check that setting to 'hidden' also triggers moderation - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - }, sub { + + reset_report_state($report); + is ( $report->get_extra_metadata('moderated_overdue'), undef, 'Sanity check' ); + is get_moderated_count(), 0; + + # Check that setting to 'hidden' also triggers moderation $mech->get_ok( '/admin/report_edit/' . $report->id ); $mech->submit_form_ok( { with_fields => { state => 'hidden' } } ); $mech->get_ok( '/admin/report_edit/' . $report->id ); - }; - $report->discard_changes; - is ( $report->extra->{moderated_overdue}, 0, 'Marking hidden from scratch sets moderated_overdue' ); - is ( $report->extra->{closed_overdue}, 0, 'Marking hidden from scratch also set closed_overdue' ); - is get_moderated_count(), 1; + $mech->form_with_fields( 'status_update' ); + $mech->submit_form_ok( { button => 'publish_response' } ); - is ($cobrand->get_or_check_overdue($report), 0, 'sanity check'); - $report->update({ created => $created->clone->subtract(days => 10) }); - is ($cobrand->get_or_check_overdue($report), 0, 'overdue call not increased'); + $report->discard_changes; + is ( $report->get_extra_metadata('moderated_overdue'), 0, 'Marking hidden from scratch sets moderated_overdue' ); + is ( $report->get_extra_metadata('closed_overdue'), 0, 'Marking hidden from scratch also set closed_overdue' ); + is get_moderated_count(), 1; - reset_report_state($report, $created); + is ($cobrand->get_or_check_overdue($report), 0, 'sanity check'); + $report->update({ created => $created->clone->subtract(days => 10) }); + is ($cobrand->get_or_check_overdue($report), 0, 'overdue call not increased'); + + reset_report_state($report, $created); + } }; FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', }, sub { # Photo publishing $mech->get_ok( '/admin/report_edit/' . $report->id ); $mech->submit_form_ok( { with_fields => { state => 'confirmed', publish_photo => 1 } } ); $mech->get_ok( '/report/' . $report->id ); - $mech->content_contains('photo/' . $report->id . '.jpeg'); + $mech->content_contains('photo/' . $report->id . '.0.jpeg'); # Internal notes $mech->get_ok( '/admin/report_edit/' . $report->id ); @@ -317,7 +339,7 @@ FixMyStreet::override_config { $mech->content_contains( 'Originaltext: “Test Test 1 for ' . $division->id . ' Detail”' ); $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->submit_form_ok( { with_fields => { body_subdivision => $subdivision->id, send_rejected_email => 1 } } ); + $mech->submit_form_ok( { with_fields => { body_subdivision => $subdivision->id } } ); $mech->get_ok( '/report/' . $report->id ); $mech->content_contains('In Bearbeitung'); @@ -332,74 +354,109 @@ $mech->clear_emails_ok; $mech->log_out_ok; -my $user = $mech->log_in_ok( 'sdm1@example.org') ; -$user->update({ from_body => undef }); -FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], -}, sub { - $mech->get_ok( '/admin' ); -}; -is $mech->uri->path, '/my', "got sent to /my"; -$user->from_body( $subdivision->id ); -$user->update; +subtest 'SDM' => sub { + my $user = $mech->log_in_ok( 'sdm1@example.org') ; + $user->update({ from_body => undef }); + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'zurich' ], + }, sub { + $mech->get_ok( '/admin' ); + }; + is $mech->uri->path, '/my', "got sent to /my"; + $user->from_body( $subdivision->id ); + $user->update; -FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], -}, sub { - $mech->get_ok( '/admin' ); -}; -is $mech->uri->path, '/admin', "am logged in"; + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'zurich' ], + }, sub { + $mech->get_ok( '/admin' ); + }; + is $mech->uri->path, '/admin', "am logged in"; -$mech->content_contains( 'report_edit/' . $report->id ); -$mech->content_contains( DateTime->now->strftime("%d.%m.%Y") ); -$mech->content_contains( 'In Bearbeitung' ); + $mech->content_contains( 'report_edit/' . $report->id ); + $mech->content_contains( DateTime->now->strftime("%d.%m.%Y") ); + $mech->content_contains( 'In Bearbeitung' ); -FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], -}, sub { - $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->content_contains( 'Initial internal note' ); + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', + }, sub { + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->content_contains( 'Initial internal note' ); - $mech->submit_form_ok( { with_fields => { status_update => 'This is an update.' } } ); - is $mech->uri->path, '/admin/report_edit/' . $report->id, "still on edit page"; - $mech->content_contains('This is an update'); - ok $mech->form_with_fields( 'status_update' ); - $mech->submit_form_ok( { button => 'no_more_updates' } ); - is $mech->uri->path, '/admin/summary', "redirected now finished with report."; + $mech->submit_form_ok( { with_fields => { status_update => 'This is an update.' } } ); + is $mech->uri->path, '/admin/report_edit/' . $report->id, "still on edit page"; + $mech->content_contains('This is an update'); + ok $mech->form_with_fields( 'status_update' ); + $mech->submit_form_ok( { button => 'no_more_updates' } ); + is $mech->uri->path, '/admin/summary', "redirected now finished with report."; - $mech->get_ok( '/report/' . $report->id ); - $mech->content_contains('In Bearbeitung'); - $mech->content_contains('Test Test'); -}; + $mech->get_ok( '/report/' . $report->id ); + $mech->content_contains('In Bearbeitung'); + $mech->content_contains('Test Test'); + }; -send_reports_for_zurich(); -$email = $mech->get_email; -like $email->header('Subject'), qr/Feedback/, 'subject looks okay'; -like $email->header('To'), qr/division\@example.org/, 'to line looks correct'; -$mech->clear_emails_ok; + send_reports_for_zurich(); + $email = $mech->get_email; + like $email->header('Subject'), qr/Feedback/, 'subject looks okay'; + like $email->header('To'), qr/division\@example.org/, 'to line looks correct'; + $mech->clear_emails_ok; -$report->discard_changes; -is $report->state, 'planned', 'Report now in planned state'; + $report->discard_changes; + is $report->state, 'planned', 'Report now in planned state'; + + subtest 'send_back' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', + }, sub { + $report->update({ bodies_str => $subdivision->id, state => 'in progress' }); + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->submit_form_ok( { form_number => 2, button => 'send_back' } ); + $report->discard_changes; + is $report->state, 'confirmed', 'Report sent back to confirmed state'; + is $report->bodies_str, $division->id, 'Report sent back to division'; + }; + }; -$mech->log_out_ok; -$user = $mech->log_in_ok( 'dm1@example.org') ; + subtest 'not contactable' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', + }, sub { + $report->update({ bodies_str => $subdivision->id, state => 'in progress' }); + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->submit_form_ok( { button => 'not_contactable', form_number => 2 } ); + $report->discard_changes; + is $report->state, 'planned', 'Report sent back to Rueckmeldung ausstehend state'; + is $report->get_extra_metadata('closure_status'), 'partial', 'Report sent back to partial (not_contactable) state'; + is $report->bodies_str, $division->id, 'Report sent back to division'; + }; + }; + + $mech->log_out_ok; +}; + +my $user = $mech->log_in_ok( 'dm1@example.org') ; FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'zurich' ], }, sub { $mech->get_ok( '/admin' ); }; +reset_report_state($report); +$report->update({ state => 'planned' }); + $mech->content_contains( 'report_edit/' . $report->id ); $mech->content_contains( DateTime->now->strftime("%d.%m.%Y") ); # User confirms their email address -my $extra = $report->extra; -$extra->{email_confirmed} = 1; -$report->extra ( { %$extra } ); +$report->set_extra_metadata(email_confirmed => 1); $report->update; FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', }, sub { $mech->get_ok( '/admin/report_edit/' . $report->id ); $mech->content_lacks( 'Unbestätigt' ); # Confirmed email @@ -419,18 +476,22 @@ like $email->header('From'), qr/division\@example.org/, 'from line looks correct like $email->body, qr/FINAL UPDATE/, 'body looks correct'; $mech->clear_emails_ok; -# Assign directly to planned, don't confirm email +# Assign planned (via confirmed), don't confirm email @reports = $mech->create_problems_for_body( 1, $division->id, 'Second', { state => 'unconfirmed', confirmed => undef, cobrand => 'zurich', + photo => $sample_photo, }); $report = $reports[0]; FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', }, sub { $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->submit_form_ok( { with_fields => { state => 'confirmed' } } ); + $mech->get_ok( '/admin/report_edit/' . $report->id ); $mech->submit_form_ok( { with_fields => { state => 'planned' } } ); $mech->get_ok( '/report/' . $report->id ); }; @@ -439,9 +500,12 @@ $mech->content_contains('Second Test'); FixMyStreet::override_config { ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', }, sub { $mech->get_ok( '/admin/report_edit/' . $report->id ); $mech->content_contains( 'Unbestätigt' ); + $report->discard_changes; + $mech->form_with_fields( 'status_update' ); $mech->submit_form_ok( { button => 'publish_response', with_fields => { status_update => 'FINAL UPDATE' } } ); $mech->get_ok( '/report/' . $report->id ); @@ -458,52 +522,155 @@ $mech->email_count_is(0); state => 'unconfirmed', confirmed => undef, cobrand => 'zurich', + photo => $sample_photo, }); $report = $reports[0]; -FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], -}, sub { - $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->submit_form_ok( { with_fields => { body_external => $external_body->id } } ); - $mech->get_ok( '/report/' . $report->id ); -}; -$mech->content_contains('Beantwortet'); -$mech->content_contains('Third Test'); -$mech->content_contains('Wir haben Ihr Anliegen an External Body weitergeleitet'); -send_reports_for_zurich(); -$email = $mech->get_email; -like $email->header('Subject'), qr/Weitergeleitete Meldung/, 'subject looks okay'; -like $email->header('To'), qr/external_body\@example.org/, 'to line looks correct'; -like $email->body, qr/External Body/, 'body has right name'; -unlike $email->body, qr/test\@example.com/, 'body does not contain email address'; -$mech->clear_emails_ok; +subtest "external report triggers email" => sub { + my $EXTERNAL_MESSAGE = 'Look Ma, no hands!'; + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', + }, sub { -# Test calling back, and third_personal boolean setting -FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], -}, sub { - $mech->get_ok( '/admin' ); - is $mech->uri->path, '/admin', "am logged in"; - $mech->content_contains( 'report_edit/' . $report->id ); - $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->submit_form_ok( { with_fields => { state => 'unconfirmed' } } ); - $mech->submit_form_ok( { with_fields => { body_external => $external_body->id, third_personal => 1 } } ); - $mech->get_ok( '/report/' . $report->id ); + # required to see body_external field + $report->state('planned'); + $report->set_extra_metadata('closure_status' => 'closed'); + # Set the public_response manually here because the default one will have line breaks that get escaped as HTML, causing the comparison to fail. + $report->set_extra_metadata('public_response' => 'Freundliche Gruesse Ihre Stadt Zuerich'); + $report->update; + + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->form_with_fields( 'publish_response' ); + $mech->submit_form_ok( { + button => 'publish_response', + with_fields => { + body_external => $external_body->id, + external_message => $EXTERNAL_MESSAGE, + } }); + $report->discard_changes; + $mech->get_ok( '/report/' . $report->id ); + }; + is ($report->state, 'closed', 'Report was closed correctly'); + $mech->content_contains('Extern') + or die $mech->content; + $mech->content_contains('Third Test'); + $mech->content_contains($report->get_extra_metadata('public_response')) or die $mech->content; + send_reports_for_zurich(); + $email = $mech->get_email; + like $email->header('Subject'), qr/Weitergeleitete Meldung/, 'subject looks okay'; + like $email->header('To'), qr/external_body\@example.org/, 'to line looks correct'; + like $email->body, qr/External Body/, 'body has right name'; + like $email->body, qr/$EXTERNAL_MESSAGE/, 'external_message was passed on'; + unlike $email->body, qr/test\@example.com/, 'body does not contain email address'; + $mech->clear_emails_ok; + + subtest "Test third_personal boolean setting" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', + }, sub { + $mech->get_ok( '/admin' ); + # required to see body_external field + $report->state('planned'); + $report->set_extra_metadata('closure_status' => 'closed'); + $report->set_extra_metadata('public_response' => 'Freundliche Gruesse Ihre Stadt Zuerich'); + $report->update; + + is $mech->uri->path, '/admin', "am logged in"; + $mech->content_contains( 'report_edit/' . $report->id ); + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->form_with_fields( 'publish_response' ); + $mech->submit_form_ok( { + button => 'publish_response', + with_fields => { + body_external => $external_body->id, + third_personal => 1, + } }); + $mech->get_ok( '/report/' . $report->id ); + }; + $mech->content_contains('Extern'); + $mech->content_contains('Third Test'); + $mech->content_contains($report->get_extra_metadata('public_response')); + send_reports_for_zurich(); + $email = $mech->get_email; + like $email->header('Subject'), qr/Weitergeleitete Meldung/, 'subject looks okay'; + like $email->header('To'), qr/external_body\@example.org/, 'to line looks correct'; + like $email->body, qr/External Body/, 'body has right name'; + like $email->body, qr/test\@example.com/, 'body does contain email address'; + $mech->clear_emails_ok; + }; + + subtest "Test external wish sending" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', + }, sub { + # set as wish + $report->discard_changes; + $report->state('planned'); + $report->set_extra_metadata('closure_status' => 'investigating'); + $report->update; + is ($report->state, 'planned', 'Sanity check') or die; + + $mech->get_ok( '/admin/report_edit/' . $report->id ); + + $mech->form_with_fields( 'publish_response' ); + $mech->submit_form_ok( { + button => 'publish_response', + with_fields => { + body_external => $external_body->id, + external_message => $EXTERNAL_MESSAGE, + } }); + }; + send_reports_for_zurich(); + $email = $mech->get_email; + like $email->header('Subject'), qr/Weitergeleitete Meldung/, 'subject looks okay'; + like $email->header('To'), qr/external_body\@example.org/, 'to line looks correct'; + like $email->body, qr/External Body/, 'body has right name'; + like $email->body, qr/$EXTERNAL_MESSAGE/, 'external_message was passed on'; + like $email->body, qr/test\@example.com/, 'body contains email address'; + $mech->clear_emails_ok; + }; + + subtest "Closure email includes public response" => sub { + my $PUBLIC_RESPONSE = "This is the public response to your report. Freundliche Gruesse."; + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', + }, sub { + # set as extern + reset_report_state($report); + $report->state('planned'); + $report->set_extra_metadata('closure_status' => 'closed'); + $report->set_extra_metadata('email_confirmed' => 1); + $report->unset_extra_metadata('public_response'); + $report->update; + is ($report->state, 'planned', 'Sanity check') or die; + + $mech->get_ok( '/admin/report_edit/' . $report->id ); + + $mech->form_with_fields( 'publish_response' ); + $mech->submit_form_ok( { + button => 'publish_response', + with_fields => { + body_external => $external_body->id, + external_message => $EXTERNAL_MESSAGE, + status_update => $PUBLIC_RESPONSE, + } }); + }; + $email = $mech->get_email; + my $report_id = $report->id; + like $email->header('Subject'), qr/Meldung #$report_id/, 'subject looks okay'; + like $email->header('To'), qr/test\@example.com/, 'to line looks correct'; + like $email->body, qr/$PUBLIC_RESPONSE/, 'public_response was passed on' or die $email->body; + $mech->clear_emails_ok; + }; + $report->comments->delete; # delete the comments, as they confuse later tests }; -$mech->content_contains('Beantwortet'); -$mech->content_contains('Third Test'); -$mech->content_contains('Wir haben Ihr Anliegen an External Body weitergeleitet'); -send_reports_for_zurich(); -$email = $mech->get_email; -like $email->header('Subject'), qr/Weitergeleitete Meldung/, 'subject looks okay'; -like $email->header('To'), qr/external_body\@example.org/, 'to line looks correct'; -like $email->body, qr/External Body/, 'body has right name'; -like $email->body, qr/test\@example.com/, 'body does contain email address'; -$mech->clear_emails_ok; -$mech->log_out_ok; -subtest "only superuser can see stats" => sub { +subtest "superuser and dm can see stats" => sub { + $mech->log_out_ok; $user = $mech->log_in_ok( 'super@example.org' ); FixMyStreet::override_config { @@ -520,7 +687,7 @@ subtest "only superuser can see stats" => sub { }, sub { $mech->get( '/admin/stats' ); }; - is $mech->res->code, 404, "only superuser should be able to see stats page"; + is $mech->res->code, 200, "dm can now also see stats page"; $mech->log_out_ok; }; @@ -556,6 +723,7 @@ subtest "phone number is mandatory" => sub { ALLOWED_COBRANDS => [ 'zurich' ], MAPIT_ID_WHITELIST => [ 274456 ], MAPIT_GENERATION => 2, + MAP_TYPE => 'Zurich,OSM', }, sub { $user = $mech->log_in_ok( 'dm1@example.org' ); $mech->get_ok( '/report/new?lat=47.381817&lon=8.529156' ); @@ -572,6 +740,7 @@ subtest "phone number is not mandatory for reports from mobile apps" => sub { ALLOWED_COBRANDS => [ 'zurich' ], MAPIT_ID_WHITELIST => [ 423017 ], MAPIT_GENERATION => 4, + MAP_TYPE => 'Zurich,OSM', }, sub { $mech->post_ok( '/report/new/mobile?lat=47.381817&lon=8.529156' , { service => 'iPhone', @@ -602,35 +771,56 @@ subtest "problems can't be assigned to deleted bodies" => sub { MAPIT_URL => 'http://global.mapit.mysociety.org/', MAPIT_TYPES => [ 'O08' ], MAPIT_ID_WHITELIST => [ 423017 ], + MAP_TYPE => 'Zurich,OSM', }, sub { $mech->get_ok( '/admin/body/' . $external_body->id ); $mech->submit_form_ok( { with_fields => { deleted => 1 } } ); $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->content_lacks( $external_body->name ); + $mech->content_lacks( $external_body->name ) + or do { + diag $mech->content; + diag $external_body->name; + die; + }; }; $user->from_body( $division->id ); $user->update; $mech->log_out_ok; }; -subtest "hidden report email are only sent when requested" => sub { - $user = $mech->log_in_ok( 'dm1@example.org') ; - $extra = $report->extra; - $extra->{email_confirmed} = 1; - $report->extra ( { %$extra } ); - $report->update; +subtest "photo must be supplied for categories that require it" => sub { + FixMyStreet::App->model('DB::Contact')->find_or_create({ + body => $division, + category => "Graffiti - photo required", + email => "graffiti\@example.org", + confirmed => 1, + deleted => 0, + editor => "editor", + whenedited => DateTime->now(), + note => "note for graffiti", + extra => { photo_required => 1 } + }); FixMyStreet::override_config { + MAPIT_TYPES => [ 'O08' ], + MAPIT_URL => 'http://global.mapit.mysociety.org/', ALLOWED_COBRANDS => [ 'zurich' ], + MAPIT_ID_WHITELIST => [ 274456 ], + MAPIT_GENERATION => 2, + MAP_TYPE => 'Zurich,OSM', }, sub { - $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->submit_form_ok( { with_fields => { state => 'hidden', send_rejected_email => 1 } } ); - $mech->email_count_is(1); - $mech->clear_emails_ok; - $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->submit_form_ok( { with_fields => { state => 'hidden', send_rejected_email => undef } } ); - $mech->email_count_is(0); - $mech->clear_emails_ok; - $mech->log_out_ok; + $mech->post_ok( '/report/new', { + detail => 'Problem-Bericht', + lat => 47.381817, + lon => 8.529156, + email => 'user@example.org', + pc => '', + name => '', + category => 'Graffiti - photo required', + photo => '', + submit_problem => 1, + }); + is $mech->res->code, 200, "missing photo shouldn't return anything but 200"; + $mech->content_contains(_("Photo is required."), 'response should contain photo error message'); }; }; @@ -643,7 +833,7 @@ subtest "test stats" => sub { $mech->get_ok( '/admin/stats' ); is $mech->res->code, 200, "superuser should be able to see stats page"; - $mech->content_contains('Innerhalb eines Arbeitstages moderiert: 2'); # now including hidden + $mech->content_contains('Innerhalb eines Arbeitstages moderiert: 3'); $mech->content_contains('Innerhalb von fünf Arbeitstagen abgeschlossen: 3'); # my @data = $mech->content =~ /(?:moderiert|abgeschlossen): \d+/g; # diag Dumper(\@data); use Data::Dumper; @@ -652,10 +842,7 @@ subtest "test stats" => sub { if (defined $export_count) { is $export_count - $EXISTING_REPORT_COUNT, 3, 'Correct number of reports'; $mech->content_contains('fixed - council'); - $mech->content_contains(',hidden,'); } - - $mech->log_out_ok; }; }; @@ -665,10 +852,118 @@ subtest "test admin_log" => sub { object_type => 'problem', object_id => $report->id, }); - is scalar @entries, 4, 'State changes logged'; - is $entries[-1]->action, 'state change to hidden', 'State change logged as expected'; + + # XXX: following is dependent on all of test up till now, rewrite to explicitly + # test which things need to be logged! + is scalar @entries, 4, 'State changes logged'; + is $entries[-1]->action, 'state change to closed', 'State change logged as expected'; }; +subtest 'email images to external partners' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', + }, sub { + reset_report_state($report); + + my $photo = path(__FILE__)->parent->child('zurich-logo_portal.x.jpg')->slurp_raw; + my $photoset = FixMyStreet::App::Model::PhotoSet->new({ + c => $c, + data_items => [ $photo ], + }); + my $fileid = $photoset->data; + + $report->set_extra_metadata('publish_photo' => 1); + # The below email comparison must not have an external message. + $report->unset_extra_metadata('external_message'); + $report->update({ + state => 'closed', + photo => $fileid, + external_body => $external_body->id, + }); + + $mech->clear_emails_ok; + send_reports_for_zurich(); + + my @emails = $mech->get_email; + my $email_as_string = $mech->get_first_email(@emails); + my ($boundary) = $email_as_string =~ /boundary="([A-Za-z0-9.]*)"/ms; + my $changes = $email_as_string =~ s{$boundary}{}g; + is $changes, 4, '4 boundaries'; # header + 3 around the 2x parts (text + 1 image) + + my $expected_email_content = path(__FILE__)->parent->child('zurich_attachments.txt')->slurp; + + my $REPORT_ID = $report->id; + $expected_email_content =~ s{REPORT_ID}{$REPORT_ID}g; + + is_string $email_as_string, $expected_email_content, 'MIME email text ok' + or do { + (my $test_name = $0) =~ s{/}{_}g; + my $path = path("test-output-$test_name.tmp"); + $path->spew($email_as_string); + diag "Saved output in $path"; + }; + }; +}; + +subtest 'Status update shown as appropriate' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', + }, sub { + # ALL closed states must hide the public_response edit, and public ones + # must show the answer in blue. + for (['planned', 1, 0, 0], + ['fixed - council', 0, 1, 0], + ['closed', 0, 1, 0], + ['hidden', 0, 0, 1]) + { + my ($state, $update, $public, $user_response) = @$_; + $report->update({ state => $state }); + $mech->get_ok( '/admin/report_edit/' . $report->id ); + contains_or_lacks($mech, $update, "<textarea name='status_update'"); + contains_or_lacks($mech, $public || $user_response, '<div class="admin-official-answer">'); + + if ($public) { + $mech->get_ok( '/report/' . $report->id ); + $mech->content_contains('Antwort</h4>'); + } + } + }; +}; + +# TODO refactor into FixMyStreet::TestMech; +sub contains_or_lacks { + my ($mech, $contains, $text) = @_; + if ($contains) { + $mech->content_contains($text); + } + else { + $mech->content_lacks($text); + } +} + +subtest 'time_spent' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'zurich' ], + MAP_TYPE => 'Zurich,OSM', + }, sub { + my $report = $reports[0]; + + is $report->get_time_spent, 0, '0 minutes spent'; + $report->update({ state => 'in progress' }); + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->form_with_fields( 'time_spent' ); + $mech->submit_form_ok( { + with_fields => { + time_spent => 10, + } }); + is $report->get_time_spent, 10, '10 minutes spent'; + }; +}; + +$mech->log_out_ok; + END { $mech->delete_body($subdivision); $mech->delete_body($division); @@ -679,3 +974,5 @@ END { ok $mech->host("www.fixmystreet.com"), "change host back"; done_testing(); } + +1; diff --git a/t/cobrand/zurich_attachments.txt b/t/cobrand/zurich_attachments.txt new file mode 100644 index 000000000..1c989c4d9 --- /dev/null +++ b/t/cobrand/zurich_attachments.txt @@ -0,0 +1,40 @@ +MIME-Version: 1.0 +Subject: =?iso-8859-1?Q?Z=FCri?= wie neu: Weitergeleitete Meldung #REPORT_ID +Content-Type: multipart/mixed; boundary="" +To: "External Body" <external_body@example.org> +Content-Transfer-Encoding: 7bit +From: FixMyStreet <division@example.org> + + +-- +MIME-Version: 1.0 +Subject: =?iso-8859-1?Q?Z=FCri?= wie neu: Weitergeleitete Meldung #REPORT_ID +Content-Type: text/plain; charset="iso-8859-1" +To: "External Body" <external_body@example.org> +Content-Transfer-Encoding: quoted-printable +From: FixMyStreet <division@example.org> + +Gr=FCezi External Body, + +=D6ffentliche URL: http://www.example.org/report/REPORT_ID + +Bei Fragen zu "Z=FCri wie neu" wenden Sie sich bitte an +gis-zentrum@zuerich.ch.= + + + +-- +MIME-Version: 1.0 +Content-Type: image/jpeg; name="REPORT_ID.0.jpeg" +Content-Disposition: inline; filename="REPORT_ID.0.jpeg" +Content-Transfer-Encoding: base64 + +/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEP +ERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4e +Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCABTAAEDAREA +AhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIIB//EAB8QAQAABAcAAAAAAAAAAAAAAAADBAbT +BxcYVVaUpf/EABcBAQEBAQAAAAAAAAAAAAAAAAAFBgT/xAAgEQEAAAQHAQAAAAAAAAAAAAAAAwQV +UgECFlNhodGx/9oADAMBAAIRAxEAPwCywAIozyxS5R58tbbujSW33j6zFRj3fGbKbjAGAgAACs9N +FCbtUfYg2mO1BM25e/V+lQeW3ISo/9k= + +---- diff --git a/t/open311/getservicerequestupdates.t b/t/open311/getservicerequestupdates.t index dac10d69b..0ab5b232d 100644 --- a/t/open311/getservicerequestupdates.t +++ b/t/open311/getservicerequestupdates.t @@ -18,6 +18,11 @@ my $user = FixMyStreet::App->model('DB::User')->find_or_create( } ); +my %bodies = ( + 2482 => FixMyStreet::App->model("DB::Body")->new({ id => 2482 }), + 2651 => FixMyStreet::App->model("DB::Body")->new({ id => 2651 }), +); + my $requests_xml = qq{<?xml version="1.0" encoding="utf-8"?> <service_requests_updates> <request_update> @@ -342,9 +347,8 @@ for my $test ( $problem->state( $test->{start_state} ); $problem->update; - my $council_details = { areas => { 2482 => 1 } }; my $update = Open311::GetServiceRequestUpdates->new( system_user => $user ); - $update->update_comments( $o, $council_details ); + $update->update_comments( $o, $bodies{2482} ); is $problem->comments->count, 1, 'comment count'; $problem->discard_changes; @@ -382,9 +386,8 @@ foreach my $test ( $problem->comments->delete; - my $council_details = { areas => { 2482 => 1 } }; my $update = Open311::GetServiceRequestUpdates->new( system_user => $user ); - $update->update_comments( $o, $council_details ); + $update->update_comments( $o, $bodies{2482} ); my $comment = $problem->comments->first; is $comment->created, $dt, 'created date set to date from XML'; @@ -451,9 +454,8 @@ for my $test ( my $o = Open311->new( jurisdiction => 'mysociety', endpoint => 'http://example.com', test_mode => 1, test_get_returns => { 'servicerequestupdates.xml' => $local_requests_xml } ); - my $council_details = { areas => { $test->{area_id} => 1 } }; my $update = Open311::GetServiceRequestUpdates->new( system_user => $user ); - $update->update_comments( $o, $council_details ); + $update->update_comments( $o, $bodies{$test->{area_id}} ); is $problem->comments->count, $test->{p1_comments}, 'comment count for first problem'; is $problem2->comments->count, $test->{p2_comments}, 'comment count for second problem'; @@ -491,8 +493,7 @@ subtest 'using start and end date' => sub { end_date => $end_dt, ); - my $council_details = { areas => { 2482 => 1 } }; - $update->update_comments( $o, $council_details ); + $update->update_comments( $o, $bodies{2482} ); my $start = $start_dt . ''; my $end = $end_dt . ''; @@ -551,18 +552,17 @@ subtest 'check that existing comments are not duplicated' => sub { system_user => $user, ); - my $council_details = { areas => { 2482 => 1 } }; - $update->update_comments( $o, $council_details ); + $update->update_comments( $o, $bodies{2482} ); $problem->discard_changes; is $problem->comments->count, 2, 'two comments after fetching updates'; - $update->update_comments( $o, $council_details ); + $update->update_comments( $o, $bodies{2482} ); $problem->discard_changes; is $problem->comments->count, 2, 're-fetching updates does not add comments'; $problem->comments->delete; - $update->update_comments( $o, $council_details ); + $update->update_comments( $o, $bodies{2482} ); $problem->discard_changes; is $problem->comments->count, 2, 'if comments are deleted then they are added'; }; @@ -612,8 +612,7 @@ foreach my $test ( { system_user => $user, ); - my $council_details = { areas => { 2482 => 1 } }; - $update->update_comments( $o, $council_details ); + $update->update_comments( $o, $bodies{2482} ); $problem->discard_changes; is $problem->comments->count, 2, 'two comments after fetching updates'; @@ -678,8 +677,7 @@ foreach my $test ( { suppress_alerts => $test->{suppress_alerts}, ); - my $council_details = { areas => { 2482 => 1 } }; - $update->update_comments( $o, $council_details ); + $update->update_comments( $o, $bodies{2482} ); $problem->discard_changes; my $alerts_sent = FixMyStreet::App->model('DB::AlertSent')->search( diff --git a/t/open311/populate-service-list.t b/t/open311/populate-service-list.t index 99663030a..1574732fb 100644 --- a/t/open311/populate-service-list.t +++ b/t/open311/populate-service-list.t @@ -55,7 +55,7 @@ subtest 'check non open311 contacts marked as deleted' => sub { confirmed => 1, deleted => 0, editor => $0, - whenedited => \'ms_current_timestamp()', + whenedited => \'current_timestamp', note => 'test contact', } ); @@ -84,7 +84,7 @@ subtest 'check email changed if matching category' => sub { confirmed => 1, deleted => 0, editor => $0, - whenedited => \'ms_current_timestamp()', + whenedited => \'current_timestamp', note => 'test contact', } ); @@ -117,7 +117,7 @@ subtest 'check category name changed if updated' => sub { confirmed => 1, deleted => 0, editor => $0, - whenedited => \'ms_current_timestamp()', + whenedited => \'current_timestamp', note => 'test contact', } ); @@ -151,7 +151,7 @@ subtest 'check conflicting contacts not changed' => sub { confirmed => 1, deleted => 0, editor => $0, - whenedited => \'ms_current_timestamp()', + whenedited => \'current_timestamp', note => 'test contact', } ); @@ -166,7 +166,7 @@ subtest 'check conflicting contacts not changed' => sub { confirmed => 1, deleted => 0, editor => $0, - whenedited => \'ms_current_timestamp()', + whenedited => \'current_timestamp', note => 'test contact', } ); @@ -223,7 +223,7 @@ subtest 'check meta data population' => sub { confirmed => 1, deleted => 0, editor => $0, - whenedited => \'ms_current_timestamp()', + whenedited => \'current_timestamp', note => 'test contact', } ); @@ -403,7 +403,7 @@ for my $test ( confirmed => 1, deleted => 0, editor => $0, - whenedited => \'ms_current_timestamp()', + whenedited => \'current_timestamp', note => 'test contact', } ); @@ -478,7 +478,7 @@ subtest 'check attribute ordering' => sub { confirmed => 1, deleted => 0, editor => $0, - whenedited => \'ms_current_timestamp()', + whenedited => \'current_timestamp', note => 'test contact', } ); @@ -580,7 +580,7 @@ subtest 'check bromely skip code' => sub { confirmed => 1, deleted => 0, editor => $0, - whenedited => \'ms_current_timestamp()', + whenedited => \'current_timestamp', note => 'test contact', } ); |