diff options
27 files changed, 724 insertions, 759 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin/Bodies.pm b/perllib/FixMyStreet/App/Controller/Admin/Bodies.pm index 67177fcbd..8ca6bbc22 100644 --- a/perllib/FixMyStreet/App/Controller/Admin/Bodies.pm +++ b/perllib/FixMyStreet/App/Controller/Admin/Bodies.pm @@ -380,9 +380,13 @@ sub body_params : Private { ); my %params = map { $_ => $c->get_param($_) || $defaults{$_} } keys %defaults; $c->forward('check_body_params', [ \%params ]); + my @extras = qw/fetch_all_problems/; + my $cobrand_extras = $c->cobrand->call_hook('body_extra_fields'); + push @extras, @$cobrand_extras if $cobrand_extras; + %defaults = map { $_ => '' } @extras; - my %extras = map { $_ => $c->get_param($_) || $defaults{$_} } @extras; + my %extras = map { $_ => $c->get_param("extra[$_]") || $defaults{$_} } @extras; return { params => \%params, extras => \%extras }; } diff --git a/perllib/FixMyStreet/App/Controller/Reports.pm b/perllib/FixMyStreet/App/Controller/Reports.pm index 8e167a70d..741cbb60f 100644 --- a/perllib/FixMyStreet/App/Controller/Reports.pm +++ b/perllib/FixMyStreet/App/Controller/Reports.pm @@ -705,8 +705,9 @@ sub stash_report_filter_status : Private { my @status = $c->get_param_list('status', 1); @status = ($c->stash->{page} eq 'my' ? 'all' : $c->cobrand->on_map_default_status) unless @status; - my %status = map { $_ => 1 } @status; + $c->cobrand->call_hook(hook_report_filter_status => \@status); + my %status = map { $_ => 1 } @status; my %filter_problem_states; my %filter_status; diff --git a/perllib/FixMyStreet/Cobrand/Zurich.pm b/perllib/FixMyStreet/Cobrand/Zurich.pm index 5fea9a03f..9cf1030f0 100644 --- a/perllib/FixMyStreet/Cobrand/Zurich.pm +++ b/perllib/FixMyStreet/Cobrand/Zurich.pm @@ -9,6 +9,8 @@ use Scalar::Util 'blessed'; use DateTime::Format::Pg; use Try::Tiny; +use FixMyStreet::Geocode::Zurich; + use strict; use warnings; use utf8; @@ -141,7 +143,7 @@ sub problem_as_hashref { $hashref->{title} = _('This report is awaiting moderation.'); $hashref->{banner_id} = 'closed'; } else { - if ( $problem->state eq 'confirmed' || $problem->state eq 'external' ) { + if ( $problem->state eq 'confirmed' ) { $hashref->{banner_id} = 'closed'; } elsif ( $problem->is_fixed || $problem->is_closed ) { $hashref->{banner_id} = 'fixed'; @@ -152,7 +154,7 @@ sub problem_as_hashref { if ( $problem->state eq 'confirmed' ) { $hashref->{state} = 'open'; $hashref->{state_t} = _('Open'); - } elsif ( $problem->state eq 'wish' ) { + } elsif ( $problem->state eq 'wish' || $problem->state eq 'external' ) { $hashref->{state_t} = _('Closed'); } elsif ( $problem->is_fixed ) { $hashref->{state} = 'closed'; @@ -329,6 +331,14 @@ sub report_page_data { $c->detach('ajax', [ 'reports/_problem-list.html' ]); } + my @categories = $c->model('DB::Contact')->not_deleted->search(undef, { + columns => [ 'category', 'extra' ], + order_by => [ 'category' ], + distinct => 1 + })->all; + $c->stash->{filter_categories} = \@categories; + $c->stash->{filter_category} = { map { $_ => 1 } $c->get_param_list('filter_category', 1) }; + my $pins = $c->stash->{pins}; FixMyStreet::Map::display_map( $c, @@ -522,12 +532,16 @@ sub admin { } sub category_options { - my ($self, $c) = @_; + my $self = shift; + my $c = $self->{c}; my @categories = $c->model('DB::Contact')->not_deleted->all; - $c->stash->{category_options} = [ map { { - category => $_->category, category_display => $_->category, + @categories = map { { + category => $_->category, + category_display => $_->get_extra_metadata('admin_label') || $_->category, abbreviation => $_->get_extra_metadata('abbreviation'), - } } @categories ]; + } } @categories; + @categories = sort { $a->{category_display} cmp $b->{category_display} } @categories; + $c->stash->{category_options} = \@categories; } sub admin_report_edit { @@ -553,21 +567,39 @@ sub admin_report_edit { $c->stash->{bodies} = \@bodies; # Can change category to any other - $self->category_options($c); + $self->category_options; } elsif ($type eq 'dm') { # Can assign to: my @bodies = $c->model('DB::Body')->search( [ - { 'me.parent' => $body->parent->id }, # Other DMs on the same level { 'me.parent' => $body->id }, # Their subdivisions { 'me.parent' => undef, 'bodies.id' => undef }, # External bodies - ], { join => 'bodies', distinct => 1 } ); - @bodies = sort { strcoll($a->name, $b->name) } @bodies; + ], { join => 'bodies', distinct => 1 } )->all; + @bodies = grep { + my $cat = $_->get_extra_metadata('category'); + if ($cat) { + $cat = $c->model('DB::Contact')->not_deleted->search({ category => $cat })->first; + } + !$cat || $cat->body_id == $body->id; + } @bodies; + @bodies = sort { + my $a_cat = $a->get_extra_metadata('category'); + my $b_cat = $b->get_extra_metadata('category'); + if ($a_cat && $b_cat) { + strcoll($a->name, $b->name) + } elsif ($a_cat) { + -1; + } elsif ($b_cat) { + 1; + } else { + strcoll($a->name, $b->name) + } + } @bodies; $c->stash->{bodies} = \@bodies; # Can change category to any other - $self->category_options($c); + $self->category_options; } @@ -927,6 +959,11 @@ sub admin_report_edit { } +sub admin_district_lookup { + my ($self, $row) = @_; + FixMyStreet::Geocode::Zurich::admin_district($row->local_coords); +} + sub stash_states { my ($self, $problem) = @_; my $c = $self->{c}; @@ -1135,7 +1172,7 @@ sub admin_stats { } # Can change category to any other - $self->category_options($c); + $self->category_options; # Total reports (non-hidden) my $total = $c->model('DB::Problem')->search( \%params )->count; @@ -1305,7 +1342,9 @@ sub reports_per_page { return 20; } sub singleton_bodies_str { 1 } -sub contact_extra_fields { [ 'abbreviation' ] }; +sub body_extra_fields { [ 'category' ] }; + +sub contact_extra_fields { [ 'abbreviation', 'admin_label' ] }; sub default_problem_state { 'submitted' } @@ -1343,4 +1382,11 @@ sub db_state_migration { } } +sub hook_report_filter_status { + my ($self, $status) = @_; + @$status = map { + $_ eq 'closed' ? ('closed', 'fixed') : $_ + } @$status; +} + 1; diff --git a/perllib/FixMyStreet/Geocode/Zurich.pm b/perllib/FixMyStreet/Geocode/Zurich.pm index 38df431c9..0b85ab7b2 100644 --- a/perllib/FixMyStreet/Geocode/Zurich.pm +++ b/perllib/FixMyStreet/Geocode/Zurich.pm @@ -24,6 +24,8 @@ sub setup_soap { # Variables for the SOAP web service my $geocoder = FixMyStreet->config('GEOCODER'); + return unless ref $geocoder eq 'HASH'; + my $url = $geocoder->{url}; my $username = $geocoder->{username}; my $password = $geocoder->{password}; @@ -49,6 +51,34 @@ sub setup_soap { $method = SOAP::Data->name('getLocation95')->attr({ xmlns => $attr }); } +sub admin_district { + my ($e, $n) = @_; + + setup_soap(); + return unless $soap; + + my $attr = 'http://ch/geoz/fixmyzuerich/service'; + my $bo = 'http://ch/geoz/fixmyzuerich/bo'; + my $method = SOAP::Data->name('getInfoByLocation')->attr({ xmlns => $attr }); + my $location = SOAP::Data->name( + 'location' => \SOAP::Data->value( + SOAP::Data->name('bo:easting', $e), + SOAP::Data->name('bo:northing', $n), + ) + )->attr({ 'xmlns:bo' => $bo }); + my $search = SOAP::Data->value($location); + my $result; + eval { + $result = $soap->call($method, $security, $search); + }; + if ($@) { + warn $@ if FixMyStreet->config('STAGING_SITE'); + return 'The geocoder appears to be down.'; + } + $result = $result->result; + return $result; +} + # string STRING CONTEXT # Looks up on Zurich web service a user-inputted location. # Returns array of (LAT, LON, ERROR), where ERROR is either undef, a string, or diff --git a/perllib/FixMyStreet/SendReport/Email.pm b/perllib/FixMyStreet/SendReport/Email.pm index 6cd9afccd..09847cf5f 100644 --- a/perllib/FixMyStreet/SendReport/Email.pm +++ b/perllib/FixMyStreet/SendReport/Email.pm @@ -53,6 +53,15 @@ sub send_from { return [ $row->user->email, $row->name ]; } +sub envelope_sender { + my ($self, $row) = @_; + + if ($row->user->email && $row->user->email_verified) { + return FixMyStreet::Email::unique_verp_id('report', $row->id); + } + return FixMyStreet->config('DO_NOT_REPLY_EMAIL'); +} + sub send { my $self = shift; my ( $row, $h ) = @_; @@ -82,12 +91,10 @@ sub send { $params->{Bcc} = $self->bcc if @{$self->bcc}; - my $sender; + my $sender = $self->envelope_sender($row); if ($row->user->email && $row->user->email_verified) { - $sender = FixMyStreet::Email::unique_verp_id('report', $row->id); $params->{From} = $self->send_from( $row ); } else { - $sender = FixMyStreet->config('DO_NOT_REPLY_EMAIL'); my $name = sprintf(_("On behalf of %s"), @{ $self->send_from($row) }[1]); $params->{From} = [ $sender, $name ]; } diff --git a/perllib/FixMyStreet/TestMech.pm b/perllib/FixMyStreet/TestMech.pm index 16871d0f2..927e4556c 100644 --- a/perllib/FixMyStreet/TestMech.pm +++ b/perllib/FixMyStreet/TestMech.pm @@ -229,6 +229,17 @@ sub get_email { return $emails[0]; } +sub get_email_envelope { + my $mech = shift; + my @emails = FixMyStreet::Email::Sender->default_transport->deliveries; + @emails = map { $_->{envelope} } @emails; + + return @emails if wantarray; + + $mech->email_count_is(1) || return undef; + return $emails[0]; +} + sub get_text_body_from_email { my ($mech, $email, $obj) = @_; unless ($email) { diff --git a/t/app/controller/admin/bodies.t b/t/app/controller/admin/bodies.t index 6fb13f0ff..a07f19494 100644 --- a/t/app/controller/admin/bodies.t +++ b/t/app/controller/admin/bodies.t @@ -162,7 +162,7 @@ subtest 'check open311 configuring' => sub { jurisdiction => 'open311', send_comments => 0, send_method => 'Open311', - fetch_all_problems => 1, + 'extra[fetch_all_problems]' => 1, } } ); @@ -181,7 +181,7 @@ subtest 'check open311 configuring' => sub { jurisdiction => 'open311', send_comments => 0, send_method => 'Open311', - fetch_all_problems => 0, + 'extra[fetch_all_problems]' => 0, can_be_devolved => 1, # for next test } } diff --git a/t/cobrand/zurich.t b/t/cobrand/zurich.t index 0bfdd8351..a08eb431e 100644 --- a/t/cobrand/zurich.t +++ b/t/cobrand/zurich.t @@ -6,6 +6,7 @@ use Email::MIME; use File::Temp; use LWP::Protocol::PSGI; use Test::LongString; +use Test::MockModule; use Path::Tiny; use t::Mock::MapItZurich; use FixMyStreet::Script::Reports; @@ -28,18 +29,8 @@ $cobrand->db_state_migration; my $sample_file = path(__FILE__)->parent->parent->child("app/controller/sample.jpg"); ok $sample_file->exists, "sample file $sample_file exists"; -# This is a helper method that will send the reports but with the config -# correctly set - notably STAGING_FLAGS send_reports 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 { - STAGING_FLAGS => { send_reports => 1 }, - ALLOWED_COBRANDS => ['zurich'] - }, sub { - # Actually send the report - FixMyStreet::Script::Reports::send('zurich'); - }; + FixMyStreet::Script::Reports::send('zurich'); } sub reset_report_state { my ($report, $created) = @_; @@ -51,45 +42,45 @@ sub reset_report_state { $report->whensent(undef); $report->state('submitted'); $report->created($created) if $created; + $report->category('Other'); $report->update; } -# Front page test -ok $mech->host("zurich.example.com"), "change host to Zurich"; +my $UPLOAD_DIR = File::Temp->newdir(); FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], + STAGING_FLAGS => { send_reports => 1 }, + ALLOWED_COBRANDS => 'zurich', + MAPIT_URL => 'http://mapit.zurich/', + MAPIT_TYPES => [ 'O08' ], + MAPIT_ID_WHITELIST => [ 423017 ], + MAP_TYPE => 'Zurich,OSM', + PHOTO_STORAGE_BACKEND => 'FileSystem', + PHOTO_STORAGE_OPTIONS => { + UPLOAD_DIR => $UPLOAD_DIR, + }, }, sub { - $mech->get_ok('/'); -}; + +# Front page test +ok $mech->host("zurich.example.com"), "change host to Zurich"; +$mech->get_ok('/'); $mech->content_like( qr/zurich/i ); # Set up bodies my $zurich = $mech->create_body_ok( 1, 'Zurich' ); -$zurich->parent( undef ); -$zurich->update; -my $division = $mech->create_body_ok( 2, 'Division 1' ); -$division->parent( $zurich->id ); -$division->send_method( 'Zurich' ); -$division->endpoint( 'division@example.org' ); -$division->update; -$division->body_areas->find_or_create({ area_id => 423017 }); -my $subdivision = $mech->create_body_ok( 3, 'Subdivision A' ); -$subdivision->parent( $division->id ); -$subdivision->send_method( 'Zurich' ); -$subdivision->endpoint( 'subdivision@example.org' ); -$subdivision->update; -my $external_body = $mech->create_body_ok( 4, 'External Body' ); -$external_body->send_method( 'Zurich' ); -$external_body->endpoint( 'external_body@example.net' ); -$external_body->update; +my $division = $mech->create_body_ok( 423017, 'Division 1', { + parent => $zurich->id, send_method => 'Zurich', endpoint => 'division@example.org' } ); +my $division2 = $mech->create_body_ok( 423017, 'Division 2', { + parent => $zurich->id, send_method => 'Zurich', endpoint => 'division2@example.org' } ); +my $subdivision = $mech->create_body_ok( 3, 'Subdivision A', + { parent => $division->id, send_method => 'Zurich', endpoint => 'subdivision@example.org' } ); +my $external_body = $mech->create_body_ok( 4, 'External Body', + { send_method => 'Zurich', endpoint => 'external_body@example.net' } ); +my $external_body2 = $mech->create_body_ok( 4, 'Another Body External', + { send_method => 'Zurich', endpoint => 'external_body2@example.net' } ); sub get_export_rows_count { my $mech = shift; - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - }, sub { - $mech->get_ok( '/admin/stats?export=1' ); - }; + $mech->get_ok( '/admin/stats?export=1' ); is $mech->res->code, 200, 'csv retrieved ok'; is $mech->content_type, 'text/csv', 'content_type correct' and do { my @lines = split /\n/, $mech->content; @@ -117,29 +108,15 @@ my @reports = $mech->create_problems_for_body( 1, $division->id, 'Test', { }); my $report = $reports[0]; -FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - MAP_TYPE => 'Zurich,OSM', -}, sub { - $mech->get_ok( '/report/' . $report->id ); -}; +$mech->get_ok( '/report/' . $report->id ); $mech->content_contains('Überprüfung ausstehend') or die $mech->content; -FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - MAP_TYPE => 'Zurich,OSM', -}, sub { - my $json = $mech->get_ok_json( '/report/ajax/' . $report->id ); - is $json->{report}->{title}, "Überprüfung ausstehend", "correct title"; - is $json->{report}->{state}, "submitted", "correct state"; -}; +my $json = $mech->get_ok_json( '/report/ajax/' . $report->id ); +is $json->{report}->{title}, "Überprüfung ausstehend", "correct title"; +is $json->{report}->{state}, "submitted", "correct state"; subtest "Banners are displayed correctly" => sub { - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - MAP_TYPE => 'Zurich,OSM', - }, sub { for my $test ( { description => 'new report', @@ -162,8 +139,8 @@ subtest "Banners are displayed correctly" => sub { { description => 'closed report', state => 'external', - banner_id => 'closed', - banner_text => 'Extern', + banner_id => 'fixed', + banner_text => 'Beantwortet', }, { description => 'in progress report', @@ -211,17 +188,14 @@ subtest "Banners are displayed correctly" => sub { }; } $report->update({ state => 'submitted' }); - }; }; -# Check logging in to deal with this report -FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], -}, sub { +my $user; +subtest 'check logging in to deal with this report' => sub { $mech->get_ok( '/admin' ); is $mech->uri->path, '/auth', "got sent to the sign in page"; - my $user = $mech->log_in_ok( 'dm1@example.org') ; + $user = $mech->log_in_ok( 'dm1@example.org') ; $user->from_body( undef ); $user->update; ok $mech->get( '/admin' ); @@ -230,12 +204,12 @@ FixMyStreet::override_config { $user->update; $mech->get_ok( '/admin' ); -}; -is $mech->uri->path, '/admin', "am logged in"; + 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( 'Erfasst' ); + $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) @@ -260,13 +234,8 @@ subtest "changing of categories" => sub { ok ( !$comments_rs->first, "There are no comments yet" ); # 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' } } ); - }; + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->submit_form_ok( { with_fields => { category => 'Cat2' } } ); # check changes correctly saved $report->discard_changes(); @@ -280,6 +249,38 @@ subtest "changing of categories" => sub { $report->update({category => $original_category }); }; +subtest "private categories" => sub { + $mech->log_in_ok( 'super@example.org' ); + $mech->get_ok('/admin/bodies'); + $mech->follow_link_ok({ text => 'Division 1' }); + $mech->submit_form_ok({ with_fields => { + category => 'Allgemein', + state => 'inactive', + email => 'allgemein@example.org', + 'extra[admin_label]' => 'StadtPeople', + 'extra[abbreviation]' => 'STA', + note => 'New', + }}); + $mech->follow_link_ok({ text => 'Allgemein' }); + $mech->content_contains('<option value="inactive" selected>'); + $mech->content_like(qr/admin_label.*?StadtPeople/); + + $mech->get_ok( '/around?lat=47.381817&lon=8.529156' ); + $mech->content_lacks('StadtPeople'); + $mech->content_contains('Allgemein'); + $mech->get_ok( '/report/new?lat=47.381817&lon=8.529156' ); + $mech->content_lacks('StadtPeople'); + $mech->content_lacks('Allgemein'); + + $report->update({ category => 'Allgemein' }); + $mech->get_ok('/report/' . $report->id); + $mech->content_lacks('StadtPeople'); + $mech->content_contains('Allgemein'); + + $mech->get_ok('/admin/report_edit/' . $report->id); + $mech->content_contains('<option value="Allgemein">StadtPeople (STA)</option>'); +}; + sub get_moderated_count { # my %date_params = ( ); # my $moderated = FixMyStreet::DB->resultset('Problem')->search({ @@ -288,17 +289,12 @@ sub get_moderated_count { # use a separate mech to avoid stomping on test state my $mech = FixMyStreet::TestMech->new; - my $user = $mech->log_in_ok( 'super@example.org' ); + $mech->log_in_ok( 'super@example.org' ); - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - }, sub { - $mech->get( '/admin/stats' ); - }; + $mech->get( '/admin/stats' ); if ($mech->content =~/Innerhalb eines Arbeitstages moderiert: (\d+)/) { return $1; - } - else { + } else { fail sprintf "Could not get moderation results (%d)", $mech->status; return undef; } @@ -306,127 +302,112 @@ sub get_moderated_count { subtest "report_edit" => sub { - 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; - 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->log_in_ok( 'dm1@example.org') ; + $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 ); - $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); + $mech->content_contains('Aufgenommen'); + $mech->content_contains('Test Test'); + $mech->content_lacks('photo/' . $report->id . '.0.jpeg'); + $mech->email_count_is(0); - $report->discard_changes; + $report->discard_changes; - is ( $report->get_extra_metadata('moderated_overdue'), 0, 'Report now marked moderated' ); - is get_moderated_count(), 1; + 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; - $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->submit_form_ok( { with_fields => { state => 'confirmed' } } ); - $mech->get_ok( '/report/' . $report->id ); + $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->get_extra_metadata('moderated_overdue'), 1, 'moderated_overdue set correctly when overdue' ); - is get_moderated_count(), 0, 'Moderated count not increased when overdue'; + $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); + reset_report_state($report, $created); - $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->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; + $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->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; - $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->submit_form_ok( { with_fields => { state => 'hidden' } } ); - $mech->get_ok( '/report/' . $report->id, 'still visible as response not published yet' ); + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->submit_form_ok( { with_fields => { state => 'hidden' } } ); + $mech->get_ok( '/report/' . $report->id, 'still visible as response not published yet' ); - $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, 'feedback pending', 'Marking hidden actually sets state to feedback pending'); - 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->get_ok( '/admin/report_edit/' . $report->id ); - $mech->form_with_fields( 'status_update' ); - $mech->submit_form_ok( { button => 'publish_response' } ); - $mech->get_ok( '/admin/report_edit/' . $report->id ); - $report->discard_changes; + $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, 'feedback pending', 'Marking hidden actually sets state to feedback pending'); + 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->get_ok( '/admin/report_edit/' . $report->id ); + $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->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'); + 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'); - $mech->submit_form_ok( { with_fields => { new_internal_note => 'Initial internal note.' } } ); - $report->discard_changes; - is ( $report->state, 'hidden', 'Another internal note does not reopen'); + $mech->submit_form_ok( { with_fields => { new_internal_note => 'Initial internal note.' } } ); + $report->discard_changes; + is ( $report->state, 'hidden', 'Another internal note does not reopen'); - $mech->get( '/report/' . $report->id); - is $mech->res->code, 410; + $mech->get( '/report/' . $report->id); + is $mech->res->code, 410; - reset_report_state($report); - is ( $report->get_extra_metadata('moderated_overdue'), undef, 'Sanity check' ); - is get_moderated_count(), 0; + 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 ); - $mech->form_with_fields( 'status_update' ); - $mech->submit_form_ok( { button => 'publish_response' } ); + # 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 ); + $mech->form_with_fields( 'status_update' ); + $mech->submit_form_ok( { button => 'publish_response' } ); - $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; + $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; - 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'); + 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); - } + reset_report_state($report, $created); }; # Give the report three photos -my $UPLOAD_DIR = File::Temp->newdir(); my @files = map { $_ x 40 . ".jpeg" } (1..3); $sample_file->copy(path($UPLOAD_DIR, $_)) for @files; $report->photo(join(',', @files)); $report->update; -FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - MAPIT_URL => 'http://mapit.zurich/', - MAP_TYPE => 'Zurich,OSM', - PHOTO_STORAGE_BACKEND => 'FileSystem', - PHOTO_STORAGE_OPTIONS => { - UPLOAD_DIR => $UPLOAD_DIR, - }, -}, sub { - # Photo publishing +subtest 'Photo publishing' => sub { $mech->get_ok( '/admin/report_edit/' . $report->id ); $mech->submit_form_ok( { with_fields => { state => 'confirmed', publish_photo_1 => 1 } } ); $mech->get_ok( '/around?lat=' . $report->latitude . ';lon=' . $report->longitude); @@ -469,50 +450,37 @@ $mech->log_out_ok; subtest 'SDM' => sub { my $user = $mech->log_in_ok( 'sdm1@example.org') ; $user->update({ from_body => undef }); - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - }, sub { - ok $mech->get( '/admin' ); - }; + ok $mech->get( '/admin' ); is $mech->res->code, 403, 'Got 403'; $user->from_body( $subdivision->id ); $user->update; - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - }, sub { - $mech->get_ok( '/admin' ); - }; + $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' ); - 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->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."; - # Can still view the edit page but can't change anything - $mech->get_ok( '/admin/report_edit/' . $report->id ); - $mech->content_contains('<input disabled'); - $mech->submit_form_ok( { with_fields => { status_update => 'This is a disallowed update.' } } ); - $mech->content_lacks('This is a disallowed update'); + # Can still view the edit page but can't change anything + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->content_contains('<input disabled'); + $mech->submit_form_ok( { with_fields => { status_update => 'This is a disallowed update.' } } ); + $mech->content_lacks('This is a disallowed update'); - $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; @@ -524,106 +492,86 @@ subtest 'SDM' => sub { is $report->state, 'feedback pending', 'Report now in feedback pending 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'; - }; + $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'; }; 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, 'feedback pending', 'Report sent back to Rueckmeldung ausstehend state'; - is $report->get_extra_metadata('closure_status'), 'not contactable', 'Report sent back to not_contactable state'; - is $report->bodies_str, $division->id, 'Report sent back to division'; - }; + $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, 'feedback pending', 'Report sent back to Rueckmeldung ausstehend state'; + is $report->get_extra_metadata('closure_status'), 'not contactable', 'Report sent back to 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 { +subtest 'Test publishing of final update by DM' => sub { + $user = $mech->log_in_ok( 'dm1@example.org'); $mech->get_ok( '/admin' ); -}; -reset_report_state($report); -$report->update({ state => 'feedback pending' }); + reset_report_state($report); + $report->update({ state => 'feedback pending' }); -$mech->content_contains( 'report_edit/' . $report->id ); -$mech->content_contains( DateTime->now->strftime("%d.%m.%Y") ); + $mech->content_contains( 'report_edit/' . $report->id ); + $mech->content_contains( DateTime->now->strftime("%d.%m.%Y") ); -# User confirms their email address -$report->set_extra_metadata(email_confirmed => 1); -$report->confirmed(DateTime->now); -$report->update; + # User confirms their email address + $report->set_extra_metadata(email_confirmed => 1); + $report->confirmed(DateTime->now); + $report->update; -FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - MAP_TYPE => 'Zurich,OSM', -}, sub { # Quick RSS check here, while we have a report $mech->get_ok('/rss/problems'); + my $module = Test::MockModule->new('FixMyStreet::Geocode::Zurich'); + $module->mock(admin_district => sub { 'Admin district' }); + $mech->get_ok( '/admin/report_edit/' . $report->id ); + + $mech->content_contains('Admin district'); + $mech->content_lacks( 'Unbestätigt' ); # Confirmed email $mech->submit_form_ok( { with_fields => { status_update => 'FINAL UPDATE' } } ); $mech->form_with_fields( 'status_update' ); $mech->submit_form_ok( { button => 'publish_response' } ); $mech->get_ok( '/report/' . $report->id ); + $mech->content_contains('Beantwortet'); + $mech->content_contains('Test Test'); + $mech->content_contains('FINAL UPDATE'); + + $email = $mech->get_email; + like $email->header('To'), qr/test\@example.com/, 'to line looks correct'; + like $email->header('From'), qr/do-not-reply\@example.org/, 'from line looks correct'; + like $email->body, qr/FINAL UPDATE/, 'body looks correct'; + $mech->clear_emails_ok; }; -$mech->content_contains('Beantwortet'); -$mech->content_contains('Test Test'); -$mech->content_contains('FINAL UPDATE'); - -$email = $mech->get_email; -like $email->header('To'), qr/test\@example.com/, 'to line looks correct'; -like $email->header('From'), qr/do-not-reply\@example.org/, 'from line looks correct'; -like $email->body, qr/FINAL UPDATE/, 'body looks correct'; -$mech->clear_emails_ok; -# Assign feedback pending (via confirmed), don't confirm email -@reports = $mech->create_problems_for_body( 1, $division->id, 'Second', { - state => 'submitted', - confirmed => undef, - cobrand => 'zurich', - areas => ',423017,', -}); -$report = $reports[0]; +subtest "Assign feedback pending (via confirmed), don't confirm email, no email sent" => sub { + @reports = $mech->create_problems_for_body( 1, $division->id, 'Second', { + state => 'submitted', + confirmed => undef, + cobrand => 'zurich', + areas => ',423017,', + }); + $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 => 'feedback pending' } } ); $mech->get_ok( '/report/' . $report->id ); -}; -$mech->content_contains('In Bearbeitung'); -$mech->content_contains('Second Test'); + $mech->content_contains('In Bearbeitung'); + $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; @@ -631,12 +579,12 @@ FixMyStreet::override_config { $mech->submit_form_ok( { button => 'publish_response', with_fields => { status_update => 'FINAL UPDATE' } } ); $mech->get_ok( '/report/' . $report->id ); -}; -$mech->content_contains('Beantwortet'); -$mech->content_contains('Second Test'); -$mech->content_contains('FINAL UPDATE'); + $mech->content_contains('Beantwortet'); + $mech->content_contains('Second Test'); + $mech->content_contains('FINAL UPDATE'); -$mech->email_count_is(0); + $mech->email_count_is(0); +}; # Report assigned to third party @@ -650,31 +598,27 @@ $report = $reports[0]; subtest "external report triggers email" => sub { my $EXTERNAL_MESSAGE = 'Look Ma, no hands!'; - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - MAP_TYPE => 'Zurich,OSM', - }, sub { - # required to see body_external field - $report->state('feedback pending'); - $report->set_extra_metadata('closure_status' => 'external'); - # 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; + # required to see body_external field + $report->state('feedback pending'); + $report->set_extra_metadata('closure_status' => 'external'); + # 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 ); - $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, 'external', 'Report was closed correctly'); - $mech->content_contains('Extern') + $mech->content_contains('Beantwortet') or die $mech->content; $mech->content_contains('Third Test'); $mech->content_contains($report->get_extra_metadata('public_response')) or die $mech->content; @@ -688,30 +632,25 @@ subtest "external report triggers email" => sub { $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('feedback pending'); - $report->set_extra_metadata('closure_status' => 'external'); - $report->set_extra_metadata('public_response' => 'Freundliche Gruesse Ihre Stadt Zuerich'); - $report->update; + $mech->get_ok( '/admin' ); + # required to see body_external field + $report->state('feedback pending'); + $report->set_extra_metadata('closure_status' => 'external'); + $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'); + 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('Beantwortet'); $mech->content_contains('Third Test'); $mech->content_contains($report->get_extra_metadata('public_response')); send_reports_for_zurich(); @@ -724,30 +663,25 @@ subtest "external report triggers email" => sub { }; 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('feedback pending'); - $report->set_extra_metadata('closure_status' => 'wish'); - $report->update; - is ($report->state, 'feedback pending', '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, - } }); - # Wishes publicly viewable - $mech->get_ok( '/report/' . $report->id ); - $mech->content_contains('Freundliche Gruesse Ihre Stadt Zuerich'); - }; + # set as wish + $report->discard_changes; + $report->state('feedback pending'); + $report->set_extra_metadata('closure_status' => 'wish'); + $report->update; + is ($report->state, 'feedback pending', '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, + } }); + # Wishes publicly viewable + $mech->get_ok( '/report/' . $report->id ); + $mech->content_contains('Freundliche Gruesse Ihre Stadt Zuerich'); send_reports_for_zurich(); $email = $mech->get_email; like $email->header('Subject'), qr/Weitergeleitete Meldung/, 'subject looks okay'; @@ -760,30 +694,26 @@ subtest "external report triggers email" => sub { 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('feedback pending'); - $report->set_extra_metadata('closure_status' => 'external'); - $report->set_extra_metadata('email_confirmed' => 1); - $report->unset_extra_metadata('public_response'); - $report->update; - is ($report->state, 'feedback pending', '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, - } }); - }; + # set as extern + reset_report_state($report); + $report->state('feedback pending'); + $report->set_extra_metadata('closure_status' => 'external'); + $report->set_extra_metadata('email_confirmed' => 1); + $report->unset_extra_metadata('public_response'); + $report->update; + is ($report->state, 'feedback pending', '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 Encode::decode('MIME-Header', $email->header('Subject')), qr/Meldung #$report_id/, 'subject looks okay'; @@ -798,91 +728,89 @@ subtest "superuser and dm can see stats" => sub { $mech->log_out_ok; $user = $mech->log_in_ok( 'super@example.org' ); - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - }, sub { - $mech->get( '/admin/stats' ); - }; + $mech->get( '/admin/stats' ); is $mech->res->code, 200, "superuser should be able to see stats page"; $mech->log_out_ok; $user = $mech->log_in_ok( 'dm1@example.org' ); - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - }, sub { - $mech->get( '/admin/stats' ); - }; + $mech->get( '/admin/stats' ); is $mech->res->code, 200, "dm can now also see stats page"; $mech->log_out_ok; }; subtest "only superuser can edit bodies" => sub { $user = $mech->log_in_ok( 'dm1@example.org' ); - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - MAPIT_URL => 'http://mapit.zurich/', - }, sub { - $mech->get( '/admin/body/' . $zurich->id ); - }; + $mech->get( '/admin/body/' . $zurich->id ); is $mech->res->code, 403, "only superuser should be able to edit bodies"; $mech->log_out_ok; }; subtest "only superuser can see 'Add body' form" => sub { $user = $mech->log_in_ok( 'dm1@example.org' ); - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - MAPIT_URL => 'http://mapit.zurich/', - MAPIT_TYPES => [ 'O08' ], - MAPIT_ID_WHITELIST => [ 423017 ], - }, sub { - $mech->get_ok( '/admin/bodies' ); - }; + $mech->get_ok( '/admin/bodies' ); $mech->content_contains('External Body'); $mech->content_lacks( '<form method="post" action="bodies"' ); $mech->log_out_ok; }; subtest "phone number is mandatory" => sub { - FixMyStreet::override_config { - MAPIT_TYPES => [ 'O08' ], - MAPIT_URL => 'http://mapit.zurich/', - ALLOWED_COBRANDS => [ 'zurich' ], - MAPIT_ID_WHITELIST => [ 423017 ], - MAP_TYPE => 'Zurich,OSM', - }, sub { - $user = $mech->log_in_ok( 'dm1@example.org' ); - $mech->get_ok( '/report/new?lat=47.381817&lon=8.529156' ); - $mech->submit_form( with_fields => { phone => "" } ); - $mech->content_contains( 'Diese Information wird benötigt' ); - $mech->log_out_ok; - }; + $user = $mech->log_in_ok( 'dm1@example.org' ); + $mech->get_ok( '/report/new?lat=47.381817&lon=8.529156' ); + $mech->submit_form( with_fields => { phone => "" } ); + $mech->content_contains( 'Diese Information wird benötigt' ); + $mech->log_out_ok; }; subtest "phone number is not mandatory for reports from mobile apps" => sub { - FixMyStreet::override_config { - MAPIT_TYPES => [ 'O08' ], - MAPIT_URL => 'http://mapit.zurich/', - ALLOWED_COBRANDS => [ 'zurich' ], - MAPIT_ID_WHITELIST => [ 423017 ], - MAP_TYPE => 'Zurich,OSM', - }, sub { - $mech->post_ok( '/report/new/mobile?lat=47.381817&lon=8.529156' , { - service => 'iPhone', - detail => 'Problem-Bericht', - lat => 47.381817, - lon => 8.529156, - email => 'user@example.org', - pc => '', - name => '', - category => 'bad category', - }); - my $res = $mech->response; - ok $res->header('Content-Type') =~ m{^application/json\b}, 'response should be json'; - unlike $res->content, qr/Diese Information wird benötigt/, 'response should not contain phone error'; - # Clear out the mailq - $mech->clear_emails_ok; - }; + $mech->post_ok( '/report/new/mobile?lat=47.381817&lon=8.529156' , { + service => 'iPhone', + detail => 'Problem-Bericht', + lat => 47.381817, + lon => 8.529156, + email => 'user@example.org', + pc => '', + name => '', + category => 'bad category', + }); + my $res = $mech->response; + ok $res->header('Content-Type') =~ m{^application/json\b}, 'response should be json'; + unlike $res->content, qr/Diese Information wird benötigt/, 'response should not contain phone error'; + # Clear out the mailq + $mech->clear_emails_ok; +}; + +subtest "link external body to category" => sub { + $mech->log_in_ok( 'super@example.org' ); + $mech->get_ok( '/admin/body/' . $zurich->id ); + $mech->content_lacks('extra[category]'); + $mech->get_ok( '/admin/body/' . $division->id ); + $mech->content_lacks('extra[category]'); + $mech->get_ok( '/admin/body/' . $subdivision->id ); + $mech->content_lacks('extra[category]'); + $mech->get_ok( '/admin/body/' . $external_body->id ); + $mech->content_contains('extra[category]'); + $mech->submit_form_ok({ with_fields => { 'extra[category]' => 'Cat1' } }); + $mech->content_contains('<option value="Cat1" selected>'); + $external_body->discard_changes; + is $external_body->get_extra_metadata('category'), 'Cat1'; +}; + +subtest "shows correct external bodies" => sub { + $report->discard_changes; + $report->state('feedback pending'); + $report->set_extra_metadata('closure_status' => 'external'); + $report->update; + $user = $mech->log_in_ok( 'dm1@example.org' ); + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->content_like(qr/<option[^>]*>External Body<\/option>\s*<option[^>]*>Another Body External<\/option>/); # Test order + + $user = $mech->log_in_ok( 'dm2@example.org' ); + $user->update({ from_body => $division2->id }); + $report->update({ bodies_str => $division2->id }); + $mech->get_ok( '/admin/report_edit/' . $report->id ); + $mech->content_contains('Another Body External'); + $mech->content_lacks('External Body'); + $report->update({ bodies_str => $division->id }); }; subtest "problems can't be assigned to deleted bodies" => sub { @@ -891,23 +819,15 @@ subtest "problems can't be assigned to deleted bodies" => sub { $user->update; $report->state( 'confirmed' ); $report->update; - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - MAPIT_URL => 'http://mapit.zurich/', - 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 ) - or do { - diag $mech->content; - diag $external_body->name; - die; - }; - }; + $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 ) + or do { + diag $mech->content; + diag $external_body->name; + die; + }; $user->from_body( $division->id ); $user->update; $mech->log_out_ok; @@ -924,44 +844,32 @@ subtest "photo must be supplied for categories that require it" => sub { note => "note for graffiti", extra => { photo_required => 1 } }); - FixMyStreet::override_config { - MAPIT_TYPES => [ 'O08' ], - MAPIT_URL => 'http://mapit.zurich/', - ALLOWED_COBRANDS => [ 'zurich' ], - MAPIT_ID_WHITELIST => [ 423017 ], - MAP_TYPE => 'Zurich,OSM', - }, sub { - $mech->get_ok('/report/new?lat=47.381817&lon=8.529156'); - $mech->submit_form_ok({ with_fields => { - detail => 'Problem-Bericht', - username => 'user@example.org', - category => 'Graffiti - photo required', - }}); - 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'); - }; + $mech->get_ok('/report/new?lat=47.381817&lon=8.529156'); + $mech->submit_form_ok({ with_fields => { + detail => 'Problem-Bericht', + username => 'user@example.org', + category => 'Graffiti - photo required', + }}); + 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'); }; subtest "test stats" => sub { - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - }, sub { - $user = $mech->log_in_ok( 'super@example.org' ); - - $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: 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; - - my $export_count = get_export_rows_count($mech); - if (defined $export_count) { - is $export_count - $EXISTING_REPORT_COUNT, 3, 'Correct number of reports'; - $mech->content_contains('fixed - council'); - } - }; + $user = $mech->log_in_ok( 'super@example.org' ); + + $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: 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; + + my $export_count = get_export_rows_count($mech); + if (defined $export_count) { + is $export_count - $EXISTING_REPORT_COUNT, 3, 'Correct number of reports'; + $mech->content_contains('fixed - council'); + } }; subtest "test admin_log" => sub { @@ -977,136 +885,108 @@ subtest "test admin_log" => sub { }; subtest 'email images to external partners' => sub { - FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - MAP_TYPE => 'Zurich,OSM', - }, sub { - reset_report_state($report); + reset_report_state($report); - my $photo = path(__FILE__)->parent->child('zurich-logo_portal.x.jpg')->slurp_raw; - my $photoset = FixMyStreet::App::Model::PhotoSet->new({ - data_items => [ $photo ], - }); - my $fileid = $photoset->data; - - $report->set_extra_metadata('publish_photo' => { 0 => 1 }); - # The below email comparison must not have an external message. - $report->unset_extra_metadata('external_message'); - $report->update({ - state => 'external', - photo => $fileid, - external_body => $external_body->id, - }); + my $photo = path(__FILE__)->parent->child('zurich-logo_portal.x.jpg')->slurp_raw; + my $photoset = FixMyStreet::App::Model::PhotoSet->new({ + data_items => [ $photo ], + }); + my $fileid = $photoset->data; + + $report->set_extra_metadata('publish_photo' => { 0 => 1 }); + # The below email comparison must not have an external message. + $report->unset_extra_metadata('external_message'); + $report->update({ + state => 'external', + photo => $fileid, + external_body => $external_body->id, + }); - $mech->clear_emails_ok; - send_reports_for_zurich(); + $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 $email = Email::MIME->new($email_as_string); - - my $expected_email_content = path(__FILE__)->parent->child('zurich_attachments.txt')->slurp; - - my $REPORT_ID = $report->id; - $expected_email_content =~ s{Subject: (.*?)\r?\n}{ - my $subj = Encode::decode('MIME-Header', $1); - $subj =~ s{REPORT_ID}{$REPORT_ID}g; - 'Subject: ' . Email::MIME::Encode::mime_encode($subj, "utf-8", 9) . "\n"; - }eg; - $expected_email_content =~ s{REPORT_ID}{$REPORT_ID}g; - $expected_email_content =~ s{BOUNDARY}{$boundary}g; - my $expected_email = Email::MIME->new($expected_email_content); - - my @email_parts; - $email->walk_parts(sub { - my ($part) = @_; - push @email_parts, [ { $part->header_pairs }, $part->body ]; - }); - my @expected_email_parts; - $expected_email->walk_parts(sub { - my ($part) = @_; - push @expected_email_parts, [ { $part->header_pairs }, $part->body ]; - }); - is_deeply \@email_parts, \@expected_email_parts, '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"; - }; + 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 $email = Email::MIME->new($email_as_string); + + my $expected_email_content = path(__FILE__)->parent->child('zurich_attachments.txt')->slurp; + + my $REPORT_ID = $report->id; + $expected_email_content =~ s{Subject: (.*?)\r?\n}{ + my $subj = Encode::decode('MIME-Header', $1); + $subj =~ s{REPORT_ID}{$REPORT_ID}g; + 'Subject: ' . Email::MIME::Encode::mime_encode($subj, "utf-8", 9) . "\n"; + }eg; + $expected_email_content =~ s{REPORT_ID}{$REPORT_ID}g; + $expected_email_content =~ s{BOUNDARY}{$boundary}g; + my $expected_email = Email::MIME->new($expected_email_content); + + my @email_parts; + $email->walk_parts(sub { + my ($part) = @_; + push @email_parts, [ { $part->header_pairs }, $part->body ]; + }); + my @expected_email_parts; + $expected_email->walk_parts(sub { + my ($part) = @_; + push @expected_email_parts, [ { $part->header_pairs }, $part->body ]; + }); + is_deeply \@email_parts, \@expected_email_parts, '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 (['feedback pending', 1, 0, 0], - ['fixed - council', 0, 1, 0], - ['external', 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 ); - $mech->contains_or_lacks($update, "name='status_update'"); - $mech->contains_or_lacks($public || $user_response, '<div class="admin-official-answer">'); - - if ($public) { - $mech->get_ok( '/report/' . $report->id ); - $mech->content_contains('Antwort</h4>'); - } - } - }; + # ALL closed states must hide the public_response edit, and public ones + # must show the answer in blue. + for (['feedback pending', 1, 0, 0], + ['fixed - council', 0, 1, 0], + ['external', 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 ); + $mech->contains_or_lacks($update, "name='status_update'"); + $mech->contains_or_lacks($public || $user_response, '<div class="admin-official-answer">'); + + if ($public) { + $mech->get_ok( '/report/' . $report->id ); + $mech->content_contains('Antwort</h4>'); + } + } }; 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'; - }; + 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; -FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], - MAPIT_URL => 'http://mapit.zurich/', - MAPIT_TYPES => [ 'ZZZ' ], -}, sub { - subtest 'users at the top level can be edited' => sub { - $mech->log_in_ok( $superuser->email ); - $mech->get_ok('/admin/users/' . $superuser->id ); - }; +subtest 'users at the top level can be edited' => sub { + $mech->log_in_ok( $superuser->email ); + $mech->get_ok('/admin/users/' . $superuser->id ); }; -FixMyStreet::override_config { - ALLOWED_COBRANDS => [ 'zurich' ], -}, sub { - subtest 'A visit to /reports is okay' => sub { - $mech->get_ok('/reports'); - }; +subtest 'A visit to /reports is okay' => sub { + $mech->get_ok('/reports'); }; -END { - ok $mech->host("www.fixmystreet.com"), "change host back"; - done_testing(); -} +}; -1; +done_testing(); diff --git a/templates/web/base/admin/bodies/open311-form-fields.html b/templates/web/base/admin/bodies/open311-form-fields.html index bdd4ad935..be2f13af0 100644 --- a/templates/web/base/admin/bodies/open311-form-fields.html +++ b/templates/web/base/admin/bodies/open311-form-fields.html @@ -161,7 +161,7 @@ </p> </div> <p> - <input type="checkbox" id="fetch_all_problems" name="fetch_all_problems"[% ' checked' IF object.get_extra_metadata('fetch_all_problems') %]> + <input type="checkbox" id="fetch_all_problems" name="extra[fetch_all_problems]"[% ' checked' IF object.get_extra_metadata('fetch_all_problems') %]> <label for="fetch_all_problems" class="inline">[% loc('Always fetch all problems') %]</label> </p> </div> diff --git a/templates/web/base/common_header_tags.html b/templates/web/base/common_header_tags.html index e29d96655..728b81363 100644 --- a/templates/web/base/common_header_tags.html +++ b/templates/web/base/common_header_tags.html @@ -23,10 +23,7 @@ [% INCLUDE 'header_rss.html' %] -<title> - [% "$title :: " | html IF title %] - [% site_name -%] -</title> +[% INCLUDE 'header/title.html' %] [% IF bodyclass.match('frontpage') %] <link rel="prefetch" href="[% version('/js/validation_rules.js') %]"> diff --git a/templates/web/base/header/title.html b/templates/web/base/header/title.html new file mode 100644 index 000000000..835c87790 --- /dev/null +++ b/templates/web/base/header/title.html @@ -0,0 +1,4 @@ +<title> + [% "$title :: " | html IF title %] + [% site_name -%] +</title> diff --git a/templates/web/base/reports/_list-filter-status.html b/templates/web/base/reports/_list-filter-status.html new file mode 100644 index 000000000..6923a7929 --- /dev/null +++ b/templates/web/base/reports/_list-filter-status.html @@ -0,0 +1,45 @@ +[% SET show_all_states = c.cobrand.filter_show_all_states OR (c.user_exists AND (c.user.is_superuser OR c.user.belongs_to_body(body.id))) %] + +<select class="form-control js-multiple" name="status" id="statuses" multiple + data-all="[% loc('All') %]" + [% IF show_all_states %] + [% options = []; + FOR group IN filter_states; FOR state IN group.1; + NEXT IF state == 'hidden'; + SET state = 'fixed' IF state == 'fixed - council'; + options.push(state); + END; END + %] + data-all-options='["[% options.join('", "') %]"]' + [%~ ELSE ~%] + [%~ IF has_fixed_state ~%] + data-all-options='["open","closed","fixed"]' + [%~ ELSE ~%] + data-all-options='["open","closed"]' + [%~ END ~%] + [%~ END ~%] + [% INCLUDE 'reports/_status_filter_options.html' %] + > + [% IF c.user_exists AND c.user.has_body_permission_to('planned_reports') AND !shortlist %] + <option value="shortlisted"[% ' selected' IF filter_status.shortlisted %]>[% loc('Shortlisted') %]</option> + <option value="unshortlisted"[% ' selected' IF filter_status.unshortlisted %]>[% loc('Unshortlisted') %]</option> + [% END %] + [% IF c.user_exists AND ( c.user.has_body_permission_to('report_inspect') OR c.user.has_body_permission_to('report_mark_private') ) %] + <option value="non_public"[% ' selected' IF filter_status.non_public %]>[% loc('Private only') %]</option> + [% END %] + [% IF show_all_states %] + [% FOR group IN filter_states %] + [% FOR state IN group.1 %] + [% NEXT IF state == 'hidden' %] + [% SET state = 'fixed' IF state == 'fixed - council' ~%] + <option value="[% state %]"[% ' selected' IF filter_status.$state %]>[% prettify_state(state, 1) %]</option> + [% END %] + [% END %] + [% ELSE %] + <option value="open"[% ' selected' IF filter_status.open %]>[% prettify_state('confirmed') %]</option> + <option value="closed"[% ' selected' IF filter_status.closed %]>[% prettify_state('closed') %]</option> + [% IF has_fixed_state %] + <option value="fixed"[% ' selected' IF filter_status.fixed %]>[% prettify_state('fixed') %]</option> + [% END %] + [% END %] +</select> diff --git a/templates/web/base/reports/_list-filters.html b/templates/web/base/reports/_list-filters.html index 6acb5936c..77c257e01 100644 --- a/templates/web/base/reports/_list-filters.html +++ b/templates/web/base/reports/_list-filters.html @@ -1,49 +1,4 @@ -[% SET show_all_states = c.cobrand.filter_show_all_states OR (c.user_exists AND (c.user.is_superuser OR c.user.belongs_to_body(body.id))) %] -[% select_status = BLOCK %] - <select class="form-control js-multiple" name="status" id="statuses" multiple - data-all="[% loc('All') %]" - [% IF show_all_states %] - [% options = []; - FOR group IN filter_states; FOR state IN group.1; - NEXT IF state == 'hidden'; - SET state = 'fixed' IF state == 'fixed - council'; - options.push(state); - END; END - %] - data-all-options='["[% options.join('", "') %]"]' - [%~ ELSE ~%] - [%~ IF has_fixed_state ~%] - data-all-options='["open","closed","fixed"]' - [%~ ELSE ~%] - data-all-options='["open","closed"]' - [%~ END ~%] - [%~ END ~%] - [% INCLUDE 'reports/_status_filter_options.html' %] - > - [% IF c.user_exists AND c.user.has_body_permission_to('planned_reports') AND !shortlist %] - <option value="shortlisted"[% ' selected' IF filter_status.shortlisted %]>[% loc('Shortlisted') %]</option> - <option value="unshortlisted"[% ' selected' IF filter_status.unshortlisted %]>[% loc('Unshortlisted') %]</option> - [% END %] - [% IF c.user_exists AND ( c.user.has_body_permission_to('report_inspect') OR c.user.has_body_permission_to('report_mark_private') ) %] - <option value="non_public"[% ' selected' IF filter_status.non_public %]>[% loc('Private only') %]</option> - [% END %] - [% IF show_all_states %] - [% FOR group IN filter_states %] - [% FOR state IN group.1 %] - [% NEXT IF state == 'hidden' %] - [% SET state = 'fixed' IF state == 'fixed - council' ~%] - <option value="[% state %]"[% ' selected' IF filter_status.$state %]>[% prettify_state(state, 1) %]</option> - [% END %] - [% END %] - [% ELSE %] - <option value="open"[% ' selected' IF filter_status.open %]>[% prettify_state('confirmed') %]</option> - <option value="closed"[% ' selected' IF filter_status.closed %]>[% prettify_state('closed') %]</option> - [% IF has_fixed_state %] - <option value="fixed"[% ' selected' IF filter_status.fixed %]>[% prettify_state('fixed') %]</option> - [% END %] - [% END %] - </select> -[% END %] +[% select_status = PROCESS 'reports/_list-filter-status.html' %] [% select_category = BLOCK %] [% IF filter_categories.size %] diff --git a/templates/web/zurich/admin/bodies/contact-form.html b/templates/web/zurich/admin/bodies/contact-form.html index 7b59124fb..8449f2d39 100644 --- a/templates/web/zurich/admin/bodies/contact-form.html +++ b/templates/web/zurich/admin/bodies/contact-form.html @@ -15,6 +15,11 @@ <input type="text" class="form-control" name="extra[abbreviation]" id="abbreviation" size="30" value="[% contact.get_extra_metadata('abbreviation') | html %]"> </p> + <p> + <label for="admin_label">Admin-label</label> + <input type="text" class="form-control" name="extra[admin_label]" id="admin_label" size="30" value="[% contact.get_extra_metadata('admin_label') | html %]"> + </p> + <p><strong>[% loc('Email:') %] </strong> <input type="text" class="form-control" name="email" value="[% contact.email | html %]" size="30"> @@ -29,15 +34,12 @@ </div> <p> - [% IF contact.in_storage %] <label for="state">[% loc('State') %]</label> <select name="state" id="state"> <option value="confirmed"[% ' selected' IF contact.state == 'confirmed' %]>[% loc('Confirmed') %] + <option value="inactive"[% ' selected' IF contact.state == 'inactive' %]>[% loc('Inactive') %] <option value="deleted"[% ' selected' IF contact.state == 'deleted' %]>[% loc('Deleted') %] </select> - [% ELSE %] - <input type="hidden" name="state" value="confirmed" id="confirmed"> - [% END %] <input type="checkbox" name="photo_required" value="1" id="photo_required"[% ' checked' IF contact.get_extra_metadata('photo_required') %]> <label class="inline" for="photo_required">[% loc('Photo required') %]</label> </p> diff --git a/templates/web/zurich/admin/bodies/form.html b/templates/web/zurich/admin/bodies/form.html index b625efc44..f9cd4f812 100644 --- a/templates/web/zurich/admin/bodies/form.html +++ b/templates/web/zurich/admin/bodies/form.html @@ -20,6 +20,18 @@ </select> </p> + [% IF body AND NOT body.parent AND NOT body.bodies %] + <p> + <label for="category">[% loc('Category') %]</label> + <select class="form-control" name="extra[category]" id="category"> + <option value="">[% loc('-- Pick a category --') %]</option> + [% FOR cat IN c.cobrand.category_options %] + <option value="[% cat.category %]"[% ' selected' IF cat.category == body.get_extra_metadata('category') %]>[% cat.category_display | html %]</option> + [% END %] + </select> + </p> + [% END %] + <p> <label for="area_ids">[% loc('Area covered') %]</label> <select class="form-control js-multiple" name="area_ids" id="area_ids" multiple data-none="-- [% loc('Select an area') %] --"> diff --git a/templates/web/zurich/admin/index-dm.html b/templates/web/zurich/admin/index-dm.html index c93adbfb3..92df5b415 100644 --- a/templates/web/zurich/admin/index-dm.html +++ b/templates/web/zurich/admin/index-dm.html @@ -1,7 +1,9 @@ [% PROCESS 'admin/header.html' title=loc('Summary') -%] [% PROCESS 'admin/report_blocks.html' %] -[% INCLUDE status_message %] +<div class="index-status"> +[% status_message %] +</div> <h2 id="submitted">[% loc('Submitted') %]</h2> [% INCLUDE list, problems = submitted.all, hash = 'submitted' %] diff --git a/templates/web/zurich/admin/report_edit-sdm.html b/templates/web/zurich/admin/report_edit-sdm.html index b9fb6ff4d..d8e6c2625 100644 --- a/templates/web/zurich/admin/report_edit-sdm.html +++ b/templates/web/zurich/admin/report_edit-sdm.html @@ -39,23 +39,11 @@ <dd class="screen-no-space-after"> <strong>[% PROCESS format_date this_date=problem.created %] [% problem.created.hms %]</strong> </dd> - <dt class="print-only">[% loc('Coordinates:') %] <!-- Koordinaten --></dt> - <dd class="screen-no-space-after print-no-space-after"> - [% problem.local_coords.join(',') %] - <input type="hidden" name="latitude" id="fixmystreet.latitude" value="[% problem.latitude %]"> - <input type="hidden" name="longitude" id="fixmystreet.longitude" value="[% problem.longitude %]"> - </dd> - <dd class="screen-no-space-after print-no-space-after"> - [% IF problem.used_map %] - [% loc('Used map') %] - [% ELSE %] - [% loc("Didn't use map") %] - [% END %] - </dd> - <dd>[% - safe = problem.postcode | html; - tprintf( loc('originally entered: “%s”'), safe ) - %]</dd> + + <dd>[% c.cobrand.admin_district_lookup(problem) %]</dd> + + <input type="hidden" name="latitude" id="fixmystreet.latitude" value="[% problem.latitude %]"> + <input type="hidden" name="longitude" id="fixmystreet.longitude" value="[% problem.longitude %]"> <dt class="print-only">[% loc('Reported by:') %] <!-- Meldende Person --></dt> <dd> @@ -78,10 +66,6 @@ <dt>[% loc('Time spent (in minutes):') %]</dt> <dd>[% problem.get_time_spent %]</dd> - <dd> - [% INCLUDE status_message %] - </dd> - [% IF problem.photo %] <dd> [% FOR photo IN problem.photos %] @@ -102,6 +86,9 @@ <div class="admin-report-edit admin-report-edit--interact"> <p align="right" class="screen-only"><input [% sdm_disabled %] type="submit" class="btn" name="send_back" value="[% loc('Not for my subdivision') %]"></p> + +[% status_message %] + <p align="right" class="screen-only"><input [% sdm_disabled %] type="submit" class="btn" name="not_contactable" value="[% loc('Customer not contactable') %]"></p> <ul class="no-bullets screen-only"> diff --git a/templates/web/zurich/admin/report_edit.html b/templates/web/zurich/admin/report_edit.html index 0186a6286..6f69161fe 100644 --- a/templates/web/zurich/admin/report_edit.html +++ b/templates/web/zurich/admin/report_edit.html @@ -58,23 +58,11 @@ <dd class="screen-no-space-after"> <strong>[% PROCESS format_date this_date=problem.created %] [% problem.created.hms %]</strong> </dd> - <dt class="print-only">[% loc('Coordinates:') %] <!-- Koordinaten --></dt> - <dd class="screen-no-space-after print-no-space-after"> - [% problem.local_coords.join(',') %] - <input type="hidden" name="latitude" id="fixmystreet.latitude" value="[% problem.latitude %]"> - <input type="hidden" name="longitude" id="fixmystreet.longitude" value="[% problem.longitude %]"> - </dd> - <dd class="screen-no-space-after print-no-space-after"> - [% IF problem.used_map %] - [% loc('Used map') %] - [% ELSE %] - [% loc("Didn't use map") %] - [% END %] - </dd> - <dd>[% - safe = problem.postcode | html; - tprintf( loc('originally entered: “%s”'), safe ) - %]</dd> + + <dd>[% c.cobrand.admin_district_lookup(problem) %]</dd> + + <input type="hidden" name="latitude" id="fixmystreet.latitude" value="[% problem.latitude %]"> + <input type="hidden" name="longitude" id="fixmystreet.longitude" value="[% problem.longitude %]"> [% SET fields = problem.get_extra_fields; IF fields.size %] <dd> @@ -129,7 +117,7 @@ <div class="admin-report-edit admin-report-edit--interact"> -[% INCLUDE status_message %] +[% status_message %] <dl [% IF status_message %]class="with-message"[% END %]> @@ -280,6 +268,7 @@ [% ELSE %] [% loc('Message to competent body:') %] [% END %] + [% problem.body(c).endpoint %] </h2> <div class="admin-external-message"> [% problem.extra.external_message | html_para %] diff --git a/templates/web/zurich/header.html b/templates/web/zurich/header.html index b453465f7..cd08e9503 100644 --- a/templates/web/zurich/header.html +++ b/templates/web/zurich/header.html @@ -9,6 +9,7 @@ <meta name="HandHeldFriendly" content="true"> <meta name="mobileoptimized" content="0"> + [% INCLUDE 'header_opengraph.html' %] [% INCLUDE 'header/css.html' %] <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/themes/redmond/jquery-ui.css"> diff --git a/templates/web/zurich/header/title.html b/templates/web/zurich/header/title.html new file mode 100644 index 000000000..118817e48 --- /dev/null +++ b/templates/web/zurich/header/title.html @@ -0,0 +1,4 @@ +<title> + [% "$title :: " | html IF title %] + Züri wie neu – Infrastrukturschäden melden – Stadt Zürich +</title> diff --git a/templates/web/zurich/header_opengraph.html b/templates/web/zurich/header_opengraph.html new file mode 100644 index 000000000..0a7dc42d7 --- /dev/null +++ b/templates/web/zurich/header_opengraph.html @@ -0,0 +1,8 @@ + <meta property="og:url" content="[% c.cobrand.base_url %][% c.req.uri.path %]"> + <meta property="og:title" content="[% title || site_name | html %]"> + <meta property="og:site_name" content="[% site_name %]"> + [% IF c.req.uri.path == '/' %] + <meta name="description" property="og:description" content="Melden Sie Schäden an der Infrastruktur der Stadt Zürich wie Schlaglöcher, defekte Beleuchtung/Signalisation, Graffitis, Schädlinge oder Abfall auf öffentlichem Grund."> + [% END %] + <meta property="og:type" content="website"> + [% INCLUDE 'header_opengraph_image.html' %] diff --git a/templates/web/zurich/reports/_list-filter-status.html b/templates/web/zurich/reports/_list-filter-status.html new file mode 100644 index 000000000..bf56821f6 --- /dev/null +++ b/templates/web/zurich/reports/_list-filter-status.html @@ -0,0 +1,7 @@ +<select class="form-control js-multiple" name="status" id="statuses" multiple + data-all="[% loc('All') %]" data-all-options='["open","closed"]' + [% INCLUDE 'reports/_status_filter_options.html' %] +> + <option value="open"[% ' selected' IF filter_status.open %]>[% prettify_state('confirmed') %]</option> + <option value="closed"[% ' selected' IF filter_status.closed %]>[% prettify_state('closed') %]</option> +</select> diff --git a/web/cobrands/fixmystreet-uk-councils/roadworks.js b/web/cobrands/fixmystreet-uk-councils/roadworks.js index f4da4c310..2b0de306a 100644 --- a/web/cobrands/fixmystreet-uk-councils/roadworks.js +++ b/web/cobrands/fixmystreet-uk-councils/roadworks.js @@ -222,16 +222,4 @@ fixmystreet.roadworks.display_message = function(feature) { $msg.prependTo('#js-post-category-messages'); }; -/* Stop sending a needless header so that no preflight CORS request */ -OpenLayers.Request.XMLHttpRequest.prototype.setRequestHeader = function(sName, sValue) { - if (sName.toLowerCase() == 'x-requested-with') { - return; - } - if (!this._headers) { - this._headers = {}; - } - this._headers[sName] = sValue; - return this._object.setRequestHeader(sName, sValue); -}; - })(); diff --git a/web/cobrands/fixmystreet/assets.js b/web/cobrands/fixmystreet/assets.js index 9113c95a2..0b2205076 100644 --- a/web/cobrands/fixmystreet/assets.js +++ b/web/cobrands/fixmystreet/assets.js @@ -947,16 +947,6 @@ OpenLayers.Format.GML.v3.MultiCurveFix = OpenLayers.Class(OpenLayers.Format.GML. CLASS_NAME: "OpenLayers.Format.GML.v3.MultiCurveFix" }); -OpenLayers.Request.XMLHttpRequest.prototype.setRequestHeader = function(sName, sValue) { - if (sName.toLowerCase() == 'x-requested-with') { - return; - } - if (!this._headers) { - this._headers = {}; - } - this._headers[sName] = sValue; - return this._object.setRequestHeader(sName, sValue); -}; })(); /* Handling of body override functionality */ diff --git a/web/cobrands/zurich/layout.scss b/web/cobrands/zurich/layout.scss index 97ae8fc4a..d98afba5d 100644 --- a/web/cobrands/zurich/layout.scss +++ b/web/cobrands/zurich/layout.scss @@ -315,6 +315,9 @@ body.mappage.admin { font-weight: bold; position: absolute; } + .index-status .message-updated { + margin-top: -1.5em; + } } .admin-nav-wrapper { diff --git a/web/js/map-OpenLayers.js b/web/js/map-OpenLayers.js index ab04d15c9..1588bda2e 100644 --- a/web/js/map-OpenLayers.js +++ b/web/js/map-OpenLayers.js @@ -562,6 +562,9 @@ $.extend(fixmystreet.utils, { } else { $.extend(style.defaultStyle, { fillColor: 'black', strokeColor: 'black' }); } + if (!this.features.length) { + return; + } var geometry = this.features[0].geometry; if (geometry.CLASS_NAME == 'OpenLayers.Geometry.Collection' || geometry.CLASS_NAME == 'OpenLayers.Geometry.MultiPolygon') { @@ -1185,3 +1188,15 @@ OpenLayers.Renderer.SVGBig = OpenLayers.Class(OpenLayers.Renderer.SVG, { CLASS_NAME: "OpenLayers.Renderer.SVGBig" }); + +/* Stop sending a needless header so that no preflight CORS request */ +OpenLayers.Request.XMLHttpRequest.prototype.setRequestHeader = function(sName, sValue) { + if (sName.toLowerCase() == 'x-requested-with') { + return; + } + if (!this._headers) { + this._headers = {}; + } + this._headers[sName] = sValue; + return this._object.setRequestHeader(sName, sValue); +}; diff --git a/web/js/map-wmts-base.js b/web/js/map-wmts-base.js index a8dd21074..43f829ab5 100644 --- a/web/js/map-wmts-base.js +++ b/web/js/map-wmts-base.js @@ -28,27 +28,4 @@ fixmystreet.maps.setup_wmts_base_map = function() { tileOrigin: new OpenLayers.LonLat(fixmystreet.wmts_config.origin_x, fixmystreet.wmts_config.origin_y) }); }); - - // Give main code a new bbox_strategy that translates between - // lat/lon and our WMTS layer's coordinates - fixmystreet.map_bbox_strategy = new OpenLayers.Strategy.ReprojectBBOX({ - ratio: 1 - }); }; - -OpenLayers.Strategy.ReprojectBBOX = OpenLayers.Class(OpenLayers.Strategy.BBOX, { - getMapBounds: function() { - // Get the map bounds but return them in lat/lon, not - // local coordinates - if (this.layer.map === null) { - return null; - } - - var localBounds = this.layer.map.getExtent(); - // Transform bound corners into WGS84 - localBounds.transform( new OpenLayers.Projection(fixmystreet.wmts_config.map_projection), new OpenLayers.Projection("EPSG:4326") ); - return localBounds; - }, - - CLASS_NAME: "OpenLayers.Strategy.ReprojectBBOX" -}); |