aboutsummaryrefslogtreecommitdiffstats
path: root/t/app/controller
diff options
context:
space:
mode:
Diffstat (limited to 't/app/controller')
-rw-r--r--t/app/controller/about.t34
-rw-r--r--t/app/controller/admin.t755
-rw-r--r--t/app/controller/admin_permissions.t205
-rw-r--r--t/app/controller/alert.t115
-rw-r--r--t/app/controller/alert_new.t468
-rw-r--r--t/app/controller/around.t90
-rw-r--r--t/app/controller/auth.t98
-rw-r--r--t/app/controller/auth_social.t259
-rw-r--r--t/app/controller/contact.t138
-rw-r--r--t/app/controller/dashboard.t1045
-rw-r--r--t/app/controller/index.t33
-rw-r--r--t/app/controller/json.t8
-rw-r--r--t/app/controller/moderate.t358
-rw-r--r--t/app/controller/my.t19
-rw-r--r--t/app/controller/my_planned.t64
-rw-r--r--t/app/controller/page_not_found.t2
-rw-r--r--t/app/controller/photo.t79
-rw-r--r--t/app/controller/questionnaire.t123
-rw-r--r--t/app/controller/report_as_other.t190
-rw-r--r--t/app/controller/report_display.t304
-rw-r--r--t/app/controller/report_import.t298
-rw-r--r--t/app/controller/report_inspect.t248
-rw-r--r--t/app/controller/report_interest_count.t75
-rw-r--r--t/app/controller/report_new.t1143
-rw-r--r--t/app/controller/report_new_mobile.t42
-rw-r--r--t/app/controller/report_new_open311.t101
-rw-r--r--t/app/controller/report_updates.t841
-rw-r--r--t/app/controller/reports.t267
-rw-r--r--t/app/controller/rss.t104
-rw-r--r--t/app/controller/sample.jpgbin22588 -> 3061 bytes
-rw-r--r--t/app/controller/token.t35
31 files changed, 5763 insertions, 1778 deletions
diff --git a/t/app/controller/about.t b/t/app/controller/about.t
index 4e49cdac9..cec50abfa 100644
--- a/t/app/controller/about.t
+++ b/t/app/controller/about.t
@@ -1,3 +1,4 @@
+use utf8;
use strict;
use warnings;
@@ -7,25 +8,26 @@ use Test::WWW::Mechanize::Catalyst 'FixMyStreet::App';
ok( my $mech = Test::WWW::Mechanize::Catalyst->new, 'Created mech object' );
# check that we can get the page
-$mech->get_ok('/about');
-$mech->content_like(qr{About us ::\s+FixMyStreet});
+$mech->get_ok('/faq');
+$mech->content_like(qr{Frequently Asked Questions ::\s+FixMyStreet});
$mech->content_contains('html class="no-js" lang="en-gb"');
-SKIP: {
- skip( "Need 'emptyhomes' in ALLOWED_COBRANDS config", 8 )
- unless FixMyStreet::Cobrand->exists('emptyhomes');
+$mech->get_ok('/privacy');
+is $mech->res->code, 200, "got 200 for final destination";
+is $mech->res->previous->code, 302, "got 302 for redirect";
+is $mech->uri->path, '/about/privacy';
- # check that geting the page as EHA produces a different page
- ok $mech->host("reportemptyhomes.co.uk"), 'change host to reportemptyhomes';
- $mech->get_ok('/about');
- $mech->content_like(qr{About us ::\s+Report Empty Homes});
- $mech->content_contains('html lang="en-gb"');
+$mech->get('/about/page-that-does-not-exist');
+ok !$mech->res->is_success(), "want a bad response";
+is $mech->res->code, 404, "got 404";
- # check that geting the page as EHA in welsh produces a different page
- ok $mech->host("cy.reportemptyhomes.co.uk"), 'host to cy.reportemptyhomes';
- $mech->get_ok('/about');
- $mech->content_like(qr{Amdanom ni ::\s+Adrodd am Eiddo Gwag});
- $mech->content_contains('html lang="cy"');
-}
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fiksgatami' ],
+}, sub {
+ ok $mech->host("www.fiksgatami.no"), 'host to fiksgatami';
+ $mech->get_ok('/faq');
+ $mech->content_like(qr{Ofte spurte spørsmål ::});
+ $mech->content_contains('html class="no-js" lang="nb"');
+};
done_testing();
diff --git a/t/app/controller/admin.t b/t/app/controller/admin.t
index 71a391c59..5f8abe5a6 100644
--- a/t/app/controller/admin.t
+++ b/t/app/controller/admin.t
@@ -6,28 +6,23 @@ use FixMyStreet::TestMech;
my $mech = FixMyStreet::TestMech->new;
-my $secret = FixMyStreet::App->model('DB::Secret')->search();
+my $user = $mech->create_user_ok('test@example.com', name => 'Test User');
-# don't explode if there's nothing in the secret table
-if ( $secret == 0 ) {
- diag "You need to put an entry in the secret table for the admin tests to run";
- plan skip_all => 'No entry in secret table';
-}
+my $user2 = $mech->create_user_ok('test2@example.com', name => 'Test User 2');
+
+my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1);
-my $user =
- FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'test@example.com', name => 'Test User' } );
-ok $user, "created test user";
+my $oxfordshire = $mech->create_body_ok(2237, 'Oxfordshire County Council', id => 2237);
+my $oxfordshirecontact = $mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Potholes', email => 'potholes@example.com' );
+$mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Traffic lights', email => 'lights@example.com' );
+my $oxfordshireuser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $oxfordshire);
-my $user2 =
- FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'test2@example.com', name => 'Test User 2' } );
-ok $user2, "created second test user";
+my $oxford = $mech->create_body_ok(2421, 'Oxford City Council');
+$mech->create_contact_ok( body_id => $oxford->id, category => 'Graffiti', email => 'graffiti@example.net' );
+my $bromley = $mech->create_body_ok(2482, 'Bromley Council', id => 2482);
-my $user3 =
- FixMyStreet::App->model('DB::User')
- ->find( { email => 'test3@example.com', name => 'Test User 2' } );
+my $user3 = $mech->create_user_ok('test3@example.com', name => 'Test User 2');
if ( $user3 ) {
$mech->delete_user( $user3 );
@@ -45,7 +40,7 @@ my $dt = DateTime->new(
my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
{
postcode => 'SW1A 1AA',
- council => '2504',
+ bodies_str => '2504',
areas => ',105255,11806,11828,2247,2504,',
category => 'Other',
title => 'Report to Edit',
@@ -53,6 +48,7 @@ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
used_map => 't',
name => 'Test User',
anonymous => 'f',
+ external_id => '13',
state => 'confirmed',
confirmed => $dt->ymd . ' ' . $dt->hms,
lang => 'en-gb',
@@ -69,13 +65,15 @@ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
my $alert = FixMyStreet::App->model('DB::Alert')->find_or_create(
{
- alert_type => 'new_updates',
- parameter => $report->id,
+ alert_type => 'area_problems',
+ parameter => 2482,
confirmed => 1,
user => $user,
},
);
+$mech->log_in_ok( $superuser->email );
+
subtest 'check summary counts' => sub {
my $problems = FixMyStreet::App->model('DB::Problem')->search( { state => { -in => [qw/confirmed fixed closed investigating planned/, 'in progress', 'fixed - user', 'fixed - council'] } } );
@@ -84,16 +82,20 @@ subtest 'check summary counts' => sub {
my $problem_count = $problems->count;
$problems->update( { cobrand => '' } );
- FixMyStreet::App->model('DB::Problem')->search( { council => 2489 } )->update( { council => 1 } );
+ 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 } } );
my $a_count = $alerts->count;
- $mech->get_ok('/admin');
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fixmystreet' ],
+ }, sub {
+ $mech->get_ok('/admin');
+ };
$mech->title_like(qr/Summary/);
@@ -105,11 +107,10 @@ subtest 'check summary counts' => sub {
$mech->content_contains( "$q_count questionnaires sent" );
- SKIP: {
- skip( "Need 'barnet' in ALLOWED_COBRANDS config", 7 )
- unless FixMyStreet::Cobrand->exists('barnet');
-
- ok $mech->host('barnet.fixmystreet.com');
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'oxfordshire' ],
+ }, sub {
+ ok $mech->host('oxfordshire.fixmystreet.com');
$mech->get_ok('/admin');
$mech->title_like(qr/Summary/);
@@ -118,11 +119,11 @@ subtest 'check summary counts' => sub {
my ($num_alerts) = $mech->content =~ /(\d+) confirmed alerts/;
my ($num_qs) = $mech->content =~ /(\d+) questionnaires sent/;
- $report->council(2489);
- $report->cobrand('barnet');
+ $report->bodies_str(2237);
+ $report->cobrand('oxfordshire');
$report->update;
- $alert->cobrand('barnet');
+ $alert->cobrand('oxfordshire');
$alert->update;
$mech->get_ok('/admin');
@@ -131,48 +132,56 @@ subtest 'check summary counts' => sub {
$mech->content_contains( ($num_alerts+1) . " confirmed alerts" );
$mech->content_contains( ($num_qs+1) . " questionnaires sent" );
- $report->council(2504);
+ $report->bodies_str(2504);
$report->cobrand('');
$report->update;
$alert->cobrand('');
$alert->update;
- }
+ };
- FixMyStreet::App->model('DB::Problem')->search( { council => 1 } )->update( { council => 2489 } );
- ok $mech->host('fixmystreet.com');
+ FixMyStreet::App->model('DB::Problem')->search( { bodies_str => 1 } )->update( { bodies_str => 2489 } );
+ ok $mech->host('www.fixmystreet.com');
};
-my $host = FixMyStreet->config('BASE_URL');
-$mech->get_ok('/admin/council_contacts/2650');
+# This override is wrapped around ALL the /admin/body tests
+FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ MAPIT_TYPES => [ 'UTA' ],
+ BASE_URL => 'http://www.example.org',
+}, sub {
+
+my $body = $mech->create_body_ok(2650, 'Aberdeen City Council');
+$mech->get_ok('/admin/body/' . $body->id);
$mech->content_contains('Aberdeen City Council');
$mech->content_like(qr{AB\d\d});
-$mech->content_contains("$host/around");
+$mech->content_contains("http://www.example.org/around");
subtest 'check contact creation' => sub {
my $contact = FixMyStreet::App->model('DB::Contact')->search(
- { body_id => 2650, category => [ 'test category', 'test/category' ] }
+ { body_id => $body->id, category => [ 'test category', 'test/category' ] }
);
$contact->delete_all;
my $history = FixMyStreet::App->model('DB::ContactsHistory')->search(
- { body_id => 2650, category => [ 'test category', 'test/category' ] }
+ { body_id => $body->id, category => [ 'test category', 'test/category' ] }
);
$history->delete_all;
- $mech->get_ok('/admin/council_contacts/2650');
+ $mech->get_ok('/admin/body/' . $body->id);
$mech->submit_form_ok( { with_fields => {
category => 'test category',
email => 'test@example.com',
note => 'test note',
non_public => undef,
+ confirmed => 0,
} } );
$mech->content_contains( 'test category' );
- $mech->content_contains( '<td>test@example.com' );
+ $mech->content_contains( 'test@example.com' );
$mech->content_contains( '<td>test note' );
- $mech->content_contains( '<td>Public' );
+ $mech->content_contains( 'Private:&nbsp;No' );
$mech->submit_form_ok( { with_fields => {
category => 'private category',
@@ -182,7 +191,7 @@ subtest 'check contact creation' => sub {
} } );
$mech->content_contains( 'private category' );
- $mech->content_contains( '<td>Non Public' );
+ $mech->content_contains( 'Private:&nbsp;Yes' );
$mech->submit_form_ok( { with_fields => {
category => 'test/category',
@@ -190,57 +199,67 @@ subtest 'check contact creation' => sub {
note => 'test/note',
non_public => 'on',
} } );
- $mech->get_ok('/admin/council_edit/2650/test/category');
+ $mech->get_ok('/admin/body/' . $body->id . '/test/category');
};
subtest 'check contact editing' => sub {
- $mech->get_ok('/admin/council_edit/2650/test%20category');
+ $mech->get_ok('/admin/body/' . $body->id .'/test%20category');
- $mech->submit_form_ok( { with_fields => {
+ $mech->submit_form_ok( { with_fields => {
email => 'test2@example.com',
note => 'test2 note',
non_public => undef,
} } );
$mech->content_contains( 'test category' );
- $mech->content_contains( '<td>test2@example.com' );
+ $mech->content_contains( 'test2@example.com' );
$mech->content_contains( '<td>test2 note' );
- $mech->content_contains( '<td>Public' );
+ $mech->content_contains( 'Private:&nbsp;No' );
- $mech->submit_form_ok( { with_fields => {
+ $mech->get_ok('/admin/body/' . $body->id . '/test%20category');
+ $mech->submit_form_ok( { with_fields => {
+ email => 'test2@example.com, test3@example.com',
+ note => 'test3 note',
+ } } );
+
+ $mech->content_contains( 'test2@example.com,test3@example.com' );
+
+ $mech->get_ok('/admin/body/' . $body->id . '/test%20category');
+ $mech->content_contains( '<td><strong>test2@example.com,test3@example.com' );
+
+ $mech->get_ok('/admin/body/' . $body->id . '/test%20category');
+ $mech->submit_form_ok( { with_fields => {
email => 'test2@example.com',
note => 'test2 note',
non_public => 'on',
} } );
- $mech->content_contains( '<td>Non Public' );
+ $mech->content_contains( 'Private:&nbsp;Yes' );
- $mech->get_ok('/admin/council_edit/2650/test%20category');
+ $mech->get_ok('/admin/body/' . $body->id . '/test%20category');
$mech->content_contains( '<td><strong>test2@example.com' );
};
subtest 'check contact updating' => sub {
- $mech->get_ok('/admin/council_edit/2650/test%20category');
+ $mech->get_ok('/admin/body/' . $body->id . '/test%20category');
$mech->content_like(qr{test2\@example.com</strong>[^<]*</td>[^<]*<td>No}s);
- $mech->get_ok('/admin/council_contacts/2650');
+ $mech->get_ok('/admin/body/' . $body->id);
$mech->form_number( 1 );
$mech->tick( 'confirmed', 'test category' );
$mech->submit_form_ok({form_number => 1});
- $mech->content_like(qr'test2@example.com</td>[^<]*<td>Yes's);
- $mech->get_ok('/admin/council_edit/2650/test%20category');
+ $mech->content_like(qr'test2@example.com</td>[^<]*<td>\s*Confirmed:&nbsp;Yes's);
+ $mech->get_ok('/admin/body/' . $body->id . '/test%20category');
$mech->content_like(qr{test2\@example.com[^<]*</td>[^<]*<td><strong>Yes}s);
};
-my $open311 =
- FixMyStreet::App->model('DB::Body')->search( { area_id => 2650 } );
-$open311->delete if $open311;
+$body->update({ send_method => undef });
subtest 'check open311 configuring' => sub {
- $mech->get_ok('/admin/council_contacts/2650/');
+ $mech->get_ok('/admin/body/' . $body->id);
$mech->content_lacks('Council contacts configured via Open311');
$mech->form_number(3);
@@ -256,13 +275,9 @@ subtest 'check open311 configuring' => sub {
}
);
$mech->content_contains('Council contacts configured via Open311');
- $mech->content_contains('Configuration updated - contacts will be generated automatically later');
-
- $open311 =
- FixMyStreet::App->model('DB::Body')->search( { area_id => 2650 } );
+ $mech->content_contains('Values updated');
- is $open311->count, 1, 'only one configuration';
- my $conf = $open311->first;
+ my $conf = FixMyStreet::App->model('DB::Body')->find( $body->id );
is $conf->endpoint, 'http://example.com/open311', 'endpoint configured';
is $conf->api_key, 'api key', 'api key configured';
is $conf->jurisdiction, 'mySociety', 'jurisdiction configures';
@@ -280,24 +295,24 @@ subtest 'check open311 configuring' => sub {
}
);
- $mech->content_contains('Configuration updated');
+ $mech->content_contains('Values updated');
- $open311 =
- FixMyStreet::App->model('DB::Body')->search( { area_id => 2650 } );
-
- is $open311->count, 1, 'only one configuration';
- $conf = $open311->first;
+ $conf = FixMyStreet::App->model('DB::Body')->find( $body->id );
is $conf->endpoint, 'http://example.org/open311', 'endpoint updated';
is $conf->api_key, 'new api key', 'api key updated';
is $conf->jurisdiction, 'open311', 'jurisdiction configures';
};
subtest 'check text output' => sub {
- $mech->get_ok('/admin/council_contacts/2650?text=1');
+ $mech->get_ok('/admin/body/' . $body->id . '?text=1');
is $mech->content_type, 'text/plain';
$mech->content_contains('test category');
};
+
+}; # END of override wrap
+
+
my $log_entries = FixMyStreet::App->model('DB::AdminLog')->search(
{
object_type => 'problem',
@@ -327,7 +342,6 @@ foreach my $test (
non_public => undef,
},
changes => { title => 'Edited Report', },
- log_count => 1,
log_entries => [qw/edit/],
resend => 0,
},
@@ -344,7 +358,6 @@ foreach my $test (
non_public => undef,
},
changes => { detail => 'Edited Detail', },
- log_count => 2,
log_entries => [qw/edit edit/],
resend => 0,
},
@@ -361,7 +374,6 @@ foreach my $test (
non_public => undef,
},
changes => { name => 'Edited User', },
- log_count => 3,
log_entries => [qw/edit edit edit/],
resend => 0,
user => $user,
@@ -381,7 +393,6 @@ foreach my $test (
changes => {
flagged => 'on',
},
- log_count => 4,
log_entries => [qw/edit edit edit edit/],
resend => 0,
user => $user,
@@ -399,7 +410,6 @@ foreach my $test (
non_public => undef,
},
changes => { email => $user2->email, },
- log_count => 5,
log_entries => [qw/edit edit edit edit edit/],
resend => 0,
user => $user2,
@@ -417,8 +427,7 @@ foreach my $test (
non_public => undef,
},
changes => { state => 'unconfirmed' },
- log_count => 6,
- log_entries => [qw/state_change edit edit edit edit edit/],
+ log_entries => [qw/edit state_change edit edit edit edit edit/],
resend => 0,
},
{
@@ -434,8 +443,7 @@ foreach my $test (
non_public => undef,
},
changes => { state => 'confirmed' },
- log_count => 7,
- log_entries => [qw/state_change state_change edit edit edit edit edit/],
+ log_entries => [qw/edit state_change edit state_change edit edit edit edit edit/],
resend => 0,
},
{
@@ -451,9 +459,8 @@ foreach my $test (
non_public => undef,
},
changes => { state => 'fixed' },
- log_count => 8,
log_entries =>
- [qw/state_change state_change state_change edit edit edit edit edit/],
+ [qw/edit state_change edit state_change edit state_change edit edit edit edit edit/],
resend => 0,
},
{
@@ -469,9 +476,8 @@ foreach my $test (
non_public => undef,
},
changes => { state => 'hidden' },
- log_count => 9,
log_entries => [
- qw/state_change state_change state_change state_change edit edit edit edit edit/
+ qw/edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/
],
resend => 0,
},
@@ -491,9 +497,8 @@ foreach my $test (
state => 'confirmed',
anonymous => 1,
},
- log_count => 11,
log_entries => [
- qw/edit state_change state_change state_change state_change state_change edit edit edit edit edit/
+ qw/edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/
],
resend => 0,
},
@@ -510,9 +515,8 @@ foreach my $test (
non_public => undef,
},
changes => {},
- log_count => 12,
log_entries => [
- qw/resend edit state_change state_change state_change state_change state_change edit edit edit edit edit/
+ qw/resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/
],
resend => 1,
},
@@ -531,9 +535,8 @@ foreach my $test (
changes => {
non_public => 'on',
},
- log_count => 13,
log_entries => [
- qw/edit resend edit state_change state_change state_change state_change state_change edit edit edit edit edit/
+ qw/edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/
],
resend => 0,
},
@@ -543,6 +546,7 @@ foreach my $test (
$log_entries->reset;
$mech->get_ok("/admin/report_edit/$report_id");
+ @{$test->{fields}}{'external_id', 'external_body', 'external_team', 'category'} = (13, "", "", "Other");
is_deeply( $mech->visible_form_values(), $test->{fields}, 'initial form values' );
my $new_fields = {
@@ -557,13 +561,13 @@ foreach my $test (
}
is_deeply( $mech->visible_form_values(), $new_fields, 'changed form values' );
- is $log_entries->count, $test->{log_count}, 'log entry count';
+ is $log_entries->count, scalar @{$test->{log_entries}}, 'log entry count';
is $log_entries->next->action, $_, 'log entry added' for @{ $test->{log_entries} };
$report->discard_changes;
- if ( $report->state eq 'confirmed' ) {
- $mech->content_contains( 'type="submit" name="resend"', 'no resend button' );
+ if ($report->state eq 'confirmed' && $report->whensent) {
+ $mech->content_contains( 'type="submit" name="resend"', 'resend button' );
} else {
$mech->content_lacks( 'type="submit" name="resend"', 'no resend button' );
}
@@ -584,6 +588,33 @@ foreach my $test (
};
}
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+}, sub {
+
+subtest 'change report category' => sub {
+ my ($ox_report) = $mech->create_problems_for_body(1, $oxfordshire->id, 'Unsure', {
+ category => 'Potholes',
+ areas => ',2237,2421,', # Cached used by categories_for_point...
+ latitude => 51.7549262252,
+ longitude => -1.25617899435,
+ whensent => \'current_timestamp',
+ });
+ $mech->get_ok("/admin/report_edit/" . $ox_report->id);
+
+ $mech->submit_form_ok( { with_fields => { category => 'Traffic lights' } }, 'form_submitted' );
+ $ox_report->discard_changes;
+ is $ox_report->category, 'Traffic lights';
+ isnt $ox_report->whensent, undef;
+
+ $mech->submit_form_ok( { with_fields => { category => 'Graffiti' } }, 'form_submitted' );
+ $ox_report->discard_changes;
+ is $ox_report->category, 'Graffiti';
+ is $ox_report->whensent, undef;
+};
+
+};
+
subtest 'change email to new user' => sub {
$log_entries->delete;
$mech->get_ok("/admin/report_edit/$report_id");
@@ -593,9 +624,13 @@ subtest 'change email to new user' => sub {
state => $report->state,
name => $report->name,
email => $report->user->email,
+ category => 'Other',
anonymous => 1,
flagged => 'on',
non_public => 'on',
+ external_id => '13',
+ external_body => '',
+ external_team => '',
};
is_deeply( $mech->visible_form_values(), $fields, 'initial form values' );
@@ -845,6 +880,10 @@ for my $test (
};
}
+my $westminster = $mech->create_body_ok(2504, 'Westminster City Council');
+$report->bodies_str($westminster->id);
+$report->update;
+
for my $test (
{
desc => 'user is problem owner',
@@ -853,18 +892,18 @@ for my $test (
update_fixed => 0,
update_reopen => 0,
update_state => undef,
- user_council => undef,
+ user_body => undef,
content => 'user is problem owner',
},
{
- desc => 'user is council user',
+ desc => 'user is body user',
problem_user => $user,
update_user => $user2,
update_fixed => 0,
update_reopen => 0,
update_state => undef,
- user_council => 2504,
- content => 'user is from same council as problem - 2504',
+ user_body => $westminster->id,
+ content => 'user is from same council as problem - ' . $westminster->id,
},
{
desc => 'update changed problem state',
@@ -873,7 +912,7 @@ for my $test (
update_fixed => 0,
update_reopen => 0,
update_state => 'planned',
- user_council => 2504,
+ user_body => $westminster->id,
content => 'Update changed problem state to planned',
},
{
@@ -883,7 +922,7 @@ for my $test (
update_fixed => 1,
update_reopen => 0,
update_state => undef,
- user_council => undef,
+ user_body => undef,
content => 'Update marked problem as fixed',
},
{
@@ -893,7 +932,7 @@ for my $test (
update_fixed => 0,
update_reopen => 1,
update_state => undef,
- user_council => undef,
+ user_body => undef,
content => 'Update reopened problem',
},
) {
@@ -907,7 +946,7 @@ for my $test (
$update->mark_open( $test->{update_reopen} );
$update->update;
- $test->{update_user}->from_body( $test->{user_council} );
+ $test->{update_user}->from_body( $test->{user_body} );
$test->{update_user}->update;
$mech->get_ok('/admin/update_edit/' . $update->id );
@@ -1033,41 +1072,47 @@ subtest 'report search' => sub {
$update->user($report->user);
$update->update;
- $mech->get_ok('/admin/search_reports');
- $mech->get_ok('/admin/search_reports?search=' . $report->id );
+ $mech->get_ok('/admin/reports');
+ $mech->get_ok('/admin/reports?search=' . $report->id );
$mech->content_contains( $report->title );
my $r_id = $report->id;
- $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id/">$r_id</a>} );
+ $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id"[^>]*>$r_id</a>} );
- $mech->get_ok('/admin/search_reports?search=' . $report->user->email);
+ $mech->get_ok('/admin/reports?search=' . $report->external_id);
+ $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id"[^>]*>$r_id</a>} );
+
+ $mech->get_ok('/admin/reports?search=ref:' . $report->external_id);
+ $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id"[^>]*>$r_id</a>} );
+
+ $mech->get_ok('/admin/reports?search=' . $report->user->email);
my $u_id = $update->id;
- $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id/">$r_id</a>} );
- $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id/#update_$u_id">$u_id</a>} );
+ $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id"[^>]*>$r_id</a>} );
+ $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id#update_$u_id"[^>]*>$u_id</a>} );
$update->state('hidden');
$update->update;
- $mech->get_ok('/admin/search_reports?search=' . $report->user->email);
+ $mech->get_ok('/admin/reports?search=' . $report->user->email);
$mech->content_like( qr{<tr [^>]*hidden[^>]*> \s* <td> \s* $u_id \s* </td>}xs );
$report->state('hidden');
$report->update;
- $mech->get_ok('/admin/search_reports?search=' . $report->user->email);
- $mech->content_like( qr{<tr [^>]*hidden[^>]*> \s* <td> \s* $r_id \s* </td>}xs );
+ $mech->get_ok('/admin/reports?search=' . $report->user->email);
+ $mech->content_like( qr{<tr [^>]*hidden[^>]*> \s* <td[^>]*> \s* $r_id \s* </td>}xs );
$report->state('fixed - user');
$report->update;
- $mech->get_ok('/admin/search_reports?search=' . $report->user->email);
- $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id/">$r_id</a>} );
+ $mech->get_ok('/admin/reports?search=' . $report->user->email);
+ $mech->content_like( qr{href="http://[^/]*[^.]/report/$r_id"[^>]*>$r_id</a>} );
};
subtest 'search abuse' => sub {
- $mech->get_ok( '/admin/search_users?search=example' );
- $mech->content_like(qr/test4\@example.com.*\n.*\n.*Email in abuse table/);
+ $mech->get_ok( '/admin/users?search=example' );
+ $mech->content_like(qr{test4\@example.com.*</td>\s*<td>.*?</td>\s*<td>\(Email in abuse table}s);
};
subtest 'show flagged entries' => sub {
@@ -1077,27 +1122,53 @@ subtest 'show flagged entries' => sub {
$user->flagged( 1 );
$user->update;
- $mech->get_ok('/admin/list_flagged');
+ $mech->get_ok('/admin/flagged');
$mech->content_contains( $report->title );
$mech->content_contains( $user->email );
};
+my $haringey = $mech->create_body_ok(2509, 'Haringey Borough Council');
+
subtest 'user search' => sub {
- $mech->get_ok('/admin/search_users');
- $mech->get_ok('/admin/search_users?search=' . $user->name);
+ $mech->get_ok('/admin/users');
+ $mech->get_ok('/admin/users?search=' . $user->name);
$mech->content_contains( $user->name);
my $u_id = $user->id;
$mech->content_like( qr{user_edit/$u_id">Edit</a>} );
- $mech->get_ok('/admin/search_users?search=' . $user->email);
+ $mech->get_ok('/admin/users?search=' . $user->email);
$mech->content_like( qr{user_edit/$u_id">Edit</a>} );
- $user->from_body(2509);
+ $user->from_body($haringey->id);
$user->update;
- $mech->get_ok('/admin/search_users?search=2509' );
- $mech->content_contains(2509);
+ $mech->get_ok('/admin/users?search=' . $haringey->id );
+ $mech->content_contains('Haringey');
+};
+
+subtest 'search does not show user from another council' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'oxfordshire' ],
+ }, sub {
+ $mech->get_ok('/admin/users');
+ $mech->get_ok('/admin/users?search=' . $user->name);
+
+ $mech->content_contains( "Searching found no users." );
+
+ $mech->get_ok('/admin/users?search=' . $user->email);
+ $mech->content_contains( "Searching found no users." );
+ };
+};
+
+subtest 'user_edit does not show user from another council' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'oxfordshire' ],
+ }, sub {
+ $mech->get('/admin/user_edit/' . $user->id);
+ ok !$mech->res->is_success(), "want a bad response";
+ is $mech->res->code, 404, "got 404";
+ };
};
$log_entries = FixMyStreet::App->model('DB::AdminLog')->search(
@@ -1115,101 +1186,375 @@ is $log_entries->count, 0, 'no admin log entries';
$user->flagged( 0 );
$user->update;
-for my $test (
- {
- desc => 'edit user name',
- fields => {
- name => 'Test User',
- email => 'test@example.com',
- council => 2509,
- flagged => undef,
- },
- changes => {
- name => 'Changed User',
- },
- log_count => 1,
- log_entries => [qw/edit/],
- },
- {
- desc => 'edit user email',
- fields => {
- name => 'Changed User',
- email => 'test@example.com',
- council => 2509,
- flagged => undef,
- },
- changes => {
- email => 'changed@example.com',
+my $southend = $mech->create_body_ok(2607, 'Southend-on-Sea Borough Council');
+
+my %default_perms = (
+ "permissions[moderate]" => undef,
+ "permissions[planned_reports]" => undef,
+ "permissions[report_edit]" => undef,
+ "permissions[report_edit_category]" => undef,
+ "permissions[report_edit_priority]" => undef,
+ "permissions[report_inspect]" => undef,
+ "permissions[report_instruct]" => undef,
+ "permissions[contribute_as_another_user]" => undef,
+ "permissions[contribute_as_body]" => undef,
+ "permissions[view_body_contribute_details]" => undef,
+ "permissions[user_edit]" => undef,
+ "permissions[user_manage_permissions]" => undef,
+ "permissions[user_assign_body]" => undef,
+ "permissions[user_assign_areas]" => undef,
+ "permissions[template_edit]" => undef,
+ "permissions[responsepriority_edit]" => undef,
+ "permissions[category_edit]" => undef,
+ trusted_bodies => undef,
+);
+
+FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ for my $test (
+ {
+ desc => 'edit user name',
+ fields => {
+ name => 'Test User',
+ email => 'test@example.com',
+ body => $haringey->id,
+ phone => '',
+ flagged => undef,
+ is_superuser => undef,
+ area_id => '',
+ %default_perms,
+ },
+ changes => {
+ name => 'Changed User',
+ },
+ log_count => 1,
+ log_entries => [qw/edit/],
},
- log_count => 2,
- log_entries => [qw/edit edit/],
- },
- {
- desc => 'edit user council',
- fields => {
- name => 'Changed User',
- email => 'changed@example.com',
- council => 2509,
- flagged => undef,
+ {
+ desc => 'edit user email',
+ fields => {
+ name => 'Changed User',
+ email => 'test@example.com',
+ body => $haringey->id,
+ phone => '',
+ flagged => undef,
+ is_superuser => undef,
+ area_id => '',
+ %default_perms,
+ },
+ changes => {
+ email => 'changed@example.com',
+ },
+ log_count => 2,
+ log_entries => [qw/edit edit/],
},
- changes => {
- council => 2607,
+ {
+ desc => 'edit user body',
+ fields => {
+ name => 'Changed User',
+ email => 'changed@example.com',
+ body => $haringey->id,
+ phone => '',
+ flagged => undef,
+ is_superuser => undef,
+ area_id => '',
+ %default_perms,
+ },
+ changes => {
+ body => $southend->id,
+ },
+ log_count => 3,
+ log_entries => [qw/edit edit edit/],
},
- log_count => 3,
- log_entries => [qw/edit edit edit/],
- },
- {
- desc => 'edit user flagged',
- fields => {
- name => 'Changed User',
- email => 'changed@example.com',
- council => 2607,
- flagged => undef,
+ {
+ desc => 'edit user flagged',
+ fields => {
+ name => 'Changed User',
+ email => 'changed@example.com',
+ body => $southend->id,
+ phone => '',
+ flagged => undef,
+ is_superuser => undef,
+ area_id => '',
+ %default_perms,
+ },
+ changes => {
+ flagged => 'on',
+ },
+ log_count => 4,
+ log_entries => [qw/edit edit edit edit/],
},
- changes => {
- flagged => 'on',
+ {
+ desc => 'edit user remove flagged',
+ fields => {
+ name => 'Changed User',
+ email => 'changed@example.com',
+ body => $southend->id,
+ phone => '',
+ flagged => 'on',
+ is_superuser => undef,
+ area_id => '',
+ %default_perms,
+ },
+ changes => {
+ flagged => undef,
+ },
+ log_count => 4,
+ log_entries => [qw/edit edit edit edit/],
},
- log_count => 4,
- log_entries => [qw/edit edit edit edit/],
- },
- {
- desc => 'edit user remove flagged',
- fields => {
- name => 'Changed User',
- email => 'changed@example.com',
- council => 2607,
- flagged => 'on',
+ {
+ desc => 'edit user add is_superuser',
+ fields => {
+ name => 'Changed User',
+ email => 'changed@example.com',
+ body => $southend->id,
+ phone => '',
+ flagged => undef,
+ is_superuser => undef,
+ area_id => '',
+ %default_perms,
+ },
+ changes => {
+ is_superuser => 'on',
+ },
+ removed => [
+ keys %default_perms,
+ ],
+ log_count => 5,
+ log_entries => [qw/edit edit edit edit edit/],
},
- changes => {
- flagged => undef,
+ {
+ desc => 'edit user remove is_superuser',
+ fields => {
+ name => 'Changed User',
+ email => 'changed@example.com',
+ body => $southend->id,
+ phone => '',
+ flagged => undef,
+ is_superuser => 'on',
+ area_id => '',
+ },
+ changes => {
+ is_superuser => undef,
+ },
+ added => {
+ %default_perms,
+ },
+ log_count => 5,
+ log_entries => [qw/edit edit edit edit edit/],
},
- log_count => 4,
- log_entries => [qw/edit edit edit edit/],
- },
-) {
- subtest $test->{desc} => sub {
- $mech->get_ok( '/admin/user_edit/' . $user->id );
+ ) {
+ subtest $test->{desc} => sub {
+ $mech->get_ok( '/admin/user_edit/' . $user->id );
- my $visible = $mech->visible_form_values;
- is_deeply $visible, $test->{fields}, 'expected user';
+ my $visible = $mech->visible_form_values;
+ is_deeply $visible, $test->{fields}, 'expected user';
- my $expected = {
- %{ $test->{fields} },
- %{ $test->{changes} }
+ my $expected = {
+ %{ $test->{fields} },
+ %{ $test->{changes} }
+ };
+
+ $mech->submit_form_ok( { with_fields => $expected } );
+
+ # Some actions cause visible fields to be added/removed
+ foreach my $x (@{ $test->{removed} }) {
+ delete $expected->{$x};
+ }
+ if ( $test->{added} ) {
+ $expected = {
+ %$expected,
+ %{ $test->{added} }
+ };
+ }
+
+ $visible = $mech->visible_form_values;
+ is_deeply $visible, $expected, 'user updated';
+
+ $mech->content_contains( 'Updated!' );
};
+ }
+};
- $mech->submit_form_ok( { with_fields => $expected } );
+subtest "Test setting a report from unconfirmed to something else doesn't cause a front end error" => sub {
+ $report->update( { confirmed => undef, state => 'unconfirmed', non_public => 0 } );
+ $mech->get_ok("/admin/report_edit/$report_id");
+ $mech->submit_form_ok( { with_fields => { state => 'investigating' } } );
+ $report->discard_changes;
+ ok( $report->confirmed, 'report has a confirmed timestamp' );
+ $mech->get_ok("/report/$report_id");
+};
+
+subtest "Check admin_base_url" => sub {
+ my $rs = FixMyStreet::App->model('DB::Problem');
+ my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($report->cobrand)->new();
+
+ is ($report->admin_url($cobrand),
+ (sprintf 'http://www.example.org/admin/report_edit/%d', $report_id),
+ 'get_admin_url OK');
+};
+
+# Finished with the superuser tests
+$mech->log_out_ok;
+
+subtest "Users without from_body can't access admin" => sub {
+ $user->from_body( undef );
+ $user->update;
+
+ $mech->log_in_ok( $user->email );
- $visible = $mech->visible_form_values;
- is_deeply $visible, $expected, 'user updated';
+ ok $mech->get('/admin');
+ is $mech->res->code, 403, "got 403";
- $mech->content_contains( 'Updated!' );
+ $mech->log_out_ok;
+};
+
+subtest "Users with from_body can access their own council's admin" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'oxfordshire' ],
+ }, sub {
+ $mech->log_in_ok( $oxfordshireuser->email );
+
+ $mech->get_ok('/admin');
+ $mech->content_contains( 'FixMyStreet admin:' );
+
+ $mech->log_out_ok;
};
-}
+};
+
+subtest "Users with from_body can't access another council's admin" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'bristol' ],
+ }, sub {
+ $mech->log_in_ok( $oxfordshireuser->email );
+
+ ok $mech->get('/admin');
+ is $mech->res->code, 403, "got 403";
-$mech->delete_user( $user );
-$mech->delete_user( $user2 );
-$mech->delete_user( $user3 );
-$mech->delete_user( 'test4@example.com' );
+ $mech->log_out_ok;
+ };
+};
+
+subtest "Users with from_body can't access fixmystreet.com admin" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fixmystreet' ],
+ }, sub {
+ $mech->log_in_ok( $oxfordshireuser->email );
+
+ ok $mech->get('/admin');
+ is $mech->res->code, 403, "got 403";
+
+ $mech->log_out_ok;
+ };
+};
+
+subtest "response templates can be added" => sub {
+ is $oxfordshire->response_templates->count, 0, "No response templates yet";
+ $mech->log_in_ok( $superuser->email );
+ $mech->get_ok( "/admin/templates/" . $oxfordshire->id . "/new" );
+
+ my $fields = {
+ title => "Report acknowledgement",
+ text => "Thank you for your report. We will respond shortly.",
+ auto_response => undef,
+ "contacts[".$oxfordshirecontact->id."]" => 1,
+ };
+ $mech->submit_form_ok( { with_fields => $fields } );
+
+ is $oxfordshire->response_templates->count, 1, "Response template was added";
+};
+
+subtest "response templates are included on page" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'oxfordshire' ],
+ }, sub {
+ $report->update({ category => $oxfordshirecontact->category, bodies_str => $oxfordshire->id });
+ $mech->log_in_ok( $oxfordshireuser->email );
+
+ $mech->get_ok("/report/" . $report->id);
+ $mech->content_contains( $oxfordshire->response_templates->first->text );
+
+ $mech->log_out_ok;
+ };
+};
+
+$mech->log_in_ok( $superuser->email );
-done_testing();
+subtest "response priorities can be added" => sub {
+ is $oxfordshire->response_priorities->count, 0, "No response priorities yet";
+ $mech->get_ok( "/admin/responsepriorities/" . $oxfordshire->id . "/new" );
+
+ my $fields = {
+ name => "Cat 1A",
+ description => "Fixed within 24 hours",
+ deleted => undef,
+ "contacts[".$oxfordshirecontact->id."]" => 1,
+ };
+ $mech->submit_form_ok( { with_fields => $fields } );
+
+ is $oxfordshire->response_priorities->count, 1, "Response template was added to body";
+ is $oxfordshirecontact->response_priorities->count, 1, "Response template was added to contact";
+};
+
+subtest "response priorities can be listed" => sub {
+ $mech->get_ok( "/admin/responsepriorities/" . $oxfordshire->id );
+
+ $mech->content_contains( $oxfordshire->response_priorities->first->name );
+ $mech->content_contains( $oxfordshire->response_priorities->first->description );
+};
+
+subtest "response priorities are limited by body" => sub {
+ my $bromleypriority = $bromley->response_priorities->create( {
+ deleted => 0,
+ name => "Bromley Cat 0",
+ } );
+
+ is $bromley->response_priorities->count, 1, "Response template was added to Bromley";
+ is $oxfordshire->response_priorities->count, 1, "Response template wasn't added to Oxfordshire";
+
+ $mech->get_ok( "/admin/responsepriorities/" . $oxfordshire->id );
+ $mech->content_lacks( $bromleypriority->name );
+
+ $mech->get_ok( "/admin/responsepriorities/" . $bromley->id );
+ $mech->content_contains( $bromleypriority->name );
+};
+
+$mech->log_out_ok;
+
+subtest "response priorities can't be viewed across councils" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'oxfordshire' ],
+ }, sub {
+ $oxfordshireuser->user_body_permissions->create({
+ body => $oxfordshire,
+ permission_type => 'responsepriority_edit',
+ });
+ $mech->log_in_ok( $oxfordshireuser->email );
+ $mech->get_ok( "/admin/responsepriorities/" . $oxfordshire->id );
+ $mech->content_contains( $oxfordshire->response_priorities->first->name );
+
+
+ $mech->get( "/admin/responsepriorities/" . $bromley->id );
+ ok !$mech->res->is_success(), "want a bad response";
+ is $mech->res->code, 404, "got 404";
+
+ my $bromley_priority_id = $bromley->response_priorities->first->id;
+ $mech->get( "/admin/responsepriorities/" . $bromley->id . "/" . $bromley_priority_id );
+ ok !$mech->res->is_success(), "want a bad response";
+ is $mech->res->code, 404, "got 404";
+ };
+};
+
+END {
+ $mech->delete_user( $user );
+ $mech->delete_user( $user2 );
+ $mech->delete_user( $user3 );
+ $mech->delete_user( $superuser );
+ $mech->delete_user( 'test4@example.com' );
+ $mech->delete_body( $oxfordshire );
+ $mech->delete_body( $oxford );
+ $mech->delete_body( $bromley );
+ $mech->delete_body( $westminster );
+ done_testing();
+}
diff --git a/t/app/controller/admin_permissions.t b/t/app/controller/admin_permissions.t
new file mode 100644
index 000000000..dd256173d
--- /dev/null
+++ b/t/app/controller/admin_permissions.t
@@ -0,0 +1,205 @@
+use strict;
+use warnings;
+use Test::More;
+
+use FixMyStreet::TestMech;
+
+my $mech = FixMyStreet::TestMech->new;
+
+my $user = $mech->create_user_ok('test@example.com', name => 'Test User');
+my $user2 = $mech->create_user_ok('test2@example.com', name => 'Test User 2');
+my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1);
+
+my $oxfordshire = $mech->create_body_ok(2237, 'Oxfordshire County Council', id => 2237);
+my $oxfordshireuser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $oxfordshire);
+
+my $bromley = $mech->create_body_ok(2482, 'Bromley Council', id => 2482);
+
+END {
+ $mech->delete_user( $user );
+ $mech->delete_user( $user2 );
+ $mech->delete_user( $superuser );
+ $mech->delete_user( $oxfordshireuser );
+}
+
+my $dt = DateTime->new(
+ year => 2011,
+ month => 04,
+ day => 16,
+ hour => 15,
+ minute => 47,
+ second => 23
+);
+
+my ($report) = $mech->create_problems_for_body(1, $oxfordshire->id, 'Test', {
+ areas => ',2237,',
+});
+my $report_id = $report->id;
+ok $report, "created test report - $report_id";
+
+$mech->log_in_ok( $oxfordshireuser->email );
+
+subtest "Users can't edit report without report_edit permission" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'oxfordshire' ],
+ }, sub {
+ $mech->get("/admin/report_edit/$report_id");
+ ok !$mech->res->is_success(), "want a bad response";
+ is $mech->res->code, 404, "got 404, can't edit report without report_edit permission";
+ };
+};
+
+subtest "Users can edit report with report_edit permission" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'oxfordshire' ],
+ }, sub {
+ $oxfordshireuser->user_body_permissions->create({
+ body => $oxfordshire,
+ permission_type => 'report_edit',
+ });
+
+ $mech->get_ok("/admin/report_edit/$report_id");
+ $mech->content_contains( $report->title );
+ };
+};
+
+subtest "Users can't edit another council's reports with their own council's report_edit permission" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'oxfordshire' ],
+ }, sub {
+ $report->bodies_str($bromley->id);
+ $report->cobrand('bromley');
+ $report->update;
+
+ $mech->get("/admin/report_edit/$report_id");
+ ok !$mech->res->is_success(), "want a bad response";
+ is $mech->res->code, 404, "got 404, can't edit report with incorrect body in report_edit permission";
+ };
+};
+
+
+FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => [ 'oxfordshire' ],
+}, sub {
+ my $user2_id = $user2->id;
+ $report->update({ bodies_str => $oxfordshire->id });
+
+ foreach my $perm (0, 1) {
+ if ($perm) {
+ $oxfordshireuser->user_body_permissions->find_or_create({
+ body => $oxfordshire,
+ permission_type => 'user_edit',
+ });
+ }
+ foreach my $report_user ($user, $user2) {
+ $report->update({ user => $report_user });
+ foreach my $from_body (undef, $bromley, $oxfordshire) {
+ $user2->update({ from_body => $from_body });
+ my $result = ($from_body || '') eq $oxfordshire || $report->user eq $user2 ? ($perm ? 200 : 404 ) : 404;
+ my $u = $result == 200 ? 'can' : 'cannot';
+ my $b = $from_body ? $from_body->name : 'no body';
+ my $p = $perm ? 'with' : 'without';
+ my $r = $report->user eq $user2 ? 'with' : 'without';
+ subtest "User $u edit user for $b $p permission, $r cobrand relation" => sub {
+ $mech->get("/admin/user_edit/$user2_id");
+ my $success = $mech->res->is_success();
+ ok $result == 200 ? $success : !$success, "got correct response";
+ is $mech->res->code, $result, "got $result";
+ };
+ }
+ }
+ }
+
+ $oxfordshireuser->user_body_permissions->create({
+ body => $oxfordshire,
+ permission_type => 'user_assign_body',
+ });
+
+ subtest "Users can edit users of their own council" => sub {
+ $mech->get_ok("/admin/user_edit/$user2_id");
+ $mech->content_contains( $user2->name );
+
+ # We shouldn't be able to see the permissions tick boxes
+ $mech->content_lacks('Moderate report details');
+
+ $mech->submit_form_ok( { with_fields => {
+ name => 'Test Updated User 2',
+ email => $user2->email,
+ body => $user2->from_body->id,
+ phone => '',
+ flagged => undef,
+ } } );
+ $user2->discard_changes;
+ is $user2->name, 'Test Updated User 2', 'name changed';
+ };
+
+ $oxfordshireuser->user_body_permissions->create({
+ body => $oxfordshire,
+ permission_type => 'user_manage_permissions',
+ });
+
+ subtest "Users can edit permissions" => sub {
+ is $user2->user_body_permissions->count, 0, 'user2 has no permissions';
+
+ $mech->get_ok("/admin/user_edit/$user2_id");
+ $mech->content_contains('Moderate report details');
+
+ $mech->submit_form_ok( { with_fields => {
+ name => $user2->name,
+ email => $user2->email,
+ body => $user2->from_body->id,
+ phone => '',
+ flagged => undef,
+ "permissions[moderate]" => 'on',
+ "permissions[report_edit_category]" => undef,
+ "permissions[report_edit_priority]" => undef,
+ "permissions[report_inspect]" => undef,
+ "permissions[report_instruct]" => undef,
+ "permissions[contribute_as_another_user]" => undef,
+ "permissions[contribute_as_body]" => undef,
+ "permissions[user_edit]" => undef,
+ "permissions[user_manage_permissions]" => undef,
+ "permissions[user_assign_areas]" => undef,
+ } } );
+
+ ok $user2->has_body_permission_to("moderate"), "user2 has been granted moderate permission";
+ };
+
+ $oxfordshireuser->user_body_permissions->create({
+ body => $oxfordshire,
+ permission_type => 'user_assign_areas',
+ });
+
+ subtest "Unsetting user from_body removes all permissions and area " => sub {
+ is $user2->user_body_permissions->count, 1, 'user2 has 1 permission';
+
+ $mech->get_ok("/admin/user_edit/$user2_id");
+ $mech->content_contains('Moderate report details');
+
+ $mech->submit_form_ok( { with_fields => {
+ name => $user2->name,
+ email => $user2->email,
+ body => undef,
+ phone => '',
+ flagged => undef,
+ "permissions[moderate]" => 'on', # NB tick box is left on deliberately
+ "permissions[report_edit_category]" => undef,
+ "permissions[report_edit_priority]" => undef,
+ "permissions[report_inspect]" => undef,
+ "permissions[report_instruct]" => undef,
+ "permissions[contribute_as_another_user]" => undef,
+ "permissions[contribute_as_body]" => undef,
+ "permissions[user_edit]" => undef,
+ "permissions[user_manage_permissions]" => undef,
+ "permissions[user_assign_areas]" => undef,
+ } } );
+
+ is $user2->user_body_permissions->count, 0, 'user2 has had permissions removed';
+ is $user2->area_id, undef, 'user2 has had area removed';
+ };
+};
+
+$mech->log_out_ok;
+
+done_testing();
diff --git a/t/app/controller/alert.t b/t/app/controller/alert.t
index 3d95bef6d..cb5949b8f 100644
--- a/t/app/controller/alert.t
+++ b/t/app/controller/alert.t
@@ -1,12 +1,12 @@
use strict;
use warnings;
use Test::More;
+use LWP::Protocol::PSGI;
+use FixMyStreet::TestMech;
+my $mech = FixMyStreet::TestMech->new;
-use Catalyst::Test 'FixMyStreet::App';
-use Test::WWW::Mechanize::Catalyst 'FixMyStreet::App';
-
-ok( my $mech = Test::WWW::Mechanize::Catalyst->new, 'Created mech object' );
+use t::Mock::Nominatim;
# check that we can get the page
$mech->get_ok('/alert');
@@ -15,52 +15,65 @@ $mech->content_contains('Local RSS feeds and email alerts');
$mech->content_contains('html class="no-js" lang="en-gb"');
# check that we can get list page
-$mech->get_ok('/alert/list');
-$mech->title_like(qr/^Local RSS feeds and email alerts/);
-$mech->content_contains('Local RSS feeds and email alerts');
-$mech->content_contains('html class="no-js" lang="en-gb"');
-
-$mech->get_ok('/alert/list?pc=EH99 1SP');
-$mech->title_like(qr/^Local RSS feeds and email alerts/);
-$mech->content_contains('Here are the types of local problem alerts for &lsquo;EH99&nbsp;1SP&rsquo;');
-$mech->content_contains('html class="no-js" lang="en-gb"');
-$mech->content_contains('Problems within 8.5km');
-$mech->content_contains('rss/pc/EH991SP/2');
-$mech->content_contains('rss/pc/EH991SP/5');
-$mech->content_contains('rss/pc/EH991SP/10');
-$mech->content_contains('rss/pc/EH991SP/20');
-$mech->content_contains('Problems within City of Edinburgh');
-$mech->content_contains('Problems within City Centre ward');
-$mech->content_contains('/rss/reports/City+of+Edinburgh');
-$mech->content_contains('/rss/reports/City+of+Edinburgh/City+Centre');
-$mech->content_contains('council:2651:City_of_Edinburgh');
-$mech->content_contains('ward:2651:20728:City_of_Edinburgh:City_Centre');
-
-$mech->get_ok('/alert/list?pc=High Street');
-$mech->content_contains('We found more than one match for that location');
-
-$mech->get_ok('/alert/list?pc=');
-$mech->content_contains('To find out what local alerts we have for you');
-
-$mech->get_ok('/alert/list?pc=GL502PR');
-$mech->content_contains('Problems within the boundary of');
-
-$mech->get_ok('/alert/subscribe?rss=1&type=local&pc=ky16+8yg&rss=Give+me+an+RSS+feed&rznvy=' );
-$mech->content_contains('Please select the feed you want');
-
-$mech->get_ok('/alert/subscribe?rss=1&feed=invalid:1000:A_Locationtype=local&pc=ky16+8yg&rss=Give+me+an+RSS+feed&rznvy=');
-$mech->content_contains('Illegal feed selection');
-
-$mech->get_ok('/alert/subscribe?rss=1&feed=area:1000:Birmingham');
-is $mech->uri->path, '/rss/reports/Birmingham';
-
-$mech->get_ok('/alert/subscribe?rss=1&feed=area:1000:1001:Cheltenham:Lansdown');
-is $mech->uri->path, '/rss/area/Cheltenham/Lansdown';
-
-$mech->get_ok('/alert/subscribe?rss=1&feed=council:1000:Gloucestershire');
-is $mech->uri->path, '/rss/reports/Gloucestershire';
-
-$mech->get_ok('/alert/subscribe?rss=1&feed=ward:1000:1001:Cheltenham:Lansdown');
-is $mech->uri->path, '/rss/reports/Cheltenham/Lansdown';
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ GEOCODER => '',
+}, sub {
+ $mech->get_ok('/alert/list');
+ $mech->title_like(qr/^Local RSS feeds and email alerts/);
+ $mech->content_contains('Local RSS feeds and email alerts');
+ $mech->content_contains('html class="no-js" lang="en-gb"');
+
+ $mech->get_ok('/alert/list?pc=EH1 1BB');
+ $mech->title_like(qr/^Local RSS feeds and email alerts/);
+ $mech->content_contains('Here are the types of local problem alerts for &lsquo;EH1&nbsp;1BB&rsquo;');
+ $mech->content_contains('html class="no-js" lang="en-gb"');
+ $mech->content_contains('Problems within 10.0km');
+ $mech->content_contains('rss/pc/EH11BB/2');
+ $mech->content_contains('rss/pc/EH11BB/5');
+ $mech->content_contains('rss/pc/EH11BB/10');
+ $mech->content_contains('rss/pc/EH11BB/20');
+ $mech->content_contains('Problems within Edinburgh City');
+ $mech->content_contains('Problems within City Centre ward');
+ $mech->content_contains('/rss/reports/Edinburgh');
+ $mech->content_contains('/rss/reports/Edinburgh/City+Centre');
+ $mech->content_contains('council:2651:Edinburgh');
+ $mech->content_contains('ward:2651:20728:Edinburgh:City_Centre');
+
+ subtest "Test Nominatim lookup" => sub {
+ LWP::Protocol::PSGI->register(t::Mock::Nominatim->run_if_script, host => 'nominatim.openstreetmap.org');
+ $mech->get_ok('/alert/list?pc=High Street');
+ $mech->content_contains('We found more than one match for that location');
+ };
+
+ $mech->get_ok('/alert/list?pc=');
+ $mech->content_contains('To find out what local alerts we have for you');
+
+ $mech->get_ok('/alert/list?pc=GL502PR');
+ $mech->content_contains('Problems within the boundary of');
+
+ $mech->get_ok('/alert/subscribe?rss=1&type=local&pc=ky16+8yg&rss=Give+me+an+RSS+feed&rznvy=' );
+ $mech->content_contains('Please select the feed you want');
+
+ $mech->get_ok('/alert/subscribe?rss=1&feed=invalid:1000:A_Locationtype=local&pc=ky16+8yg&rss=Give+me+an+RSS+feed&rznvy=');
+ $mech->content_contains('Illegal feed selection');
+
+ $mech->create_body_ok(2504, 'Birmingham City Council');
+ $mech->create_body_ok(2226, 'Gloucestershire County Council');
+ $mech->create_body_ok(2326, 'Cheltenham Borough Council');
+
+ $mech->get_ok('/alert/subscribe?rss=1&feed=area:1000:Birmingham');
+ is $mech->uri->path, '/rss/reports/Birmingham';
+
+ $mech->get_ok('/alert/subscribe?rss=1&feed=area:1000:1001:Cheltenham:Lansdown');
+ is $mech->uri->path, '/rss/area/Cheltenham/Lansdown';
+
+ $mech->get_ok('/alert/subscribe?rss=1&feed=council:1000:Gloucestershire');
+ is $mech->uri->path, '/rss/reports/Gloucestershire';
+
+ $mech->get_ok('/alert/subscribe?rss=1&feed=ward:1000:1001:Cheltenham:Lansdown');
+ is $mech->uri->path, '/rss/reports/Cheltenham/Lansdown';
+};
done_testing();
diff --git a/t/app/controller/alert_new.t b/t/app/controller/alert_new.t
index c849b9485..ea38f7c25 100644
--- a/t/app/controller/alert_new.t
+++ b/t/app/controller/alert_new.t
@@ -3,15 +3,20 @@ use warnings;
use Test::More;
use FixMyStreet::TestMech;
+use FixMyStreet::App;
my $mech = FixMyStreet::TestMech->new;
+$mech->log_in_ok('test@example.com');
+$mech->get_ok('/alert/subscribe?id=1');
+my ($csrf) = $mech->content =~ /name="token" value="([^"]*)"/;
+
foreach my $test (
{
email => 'test@example.com',
type => 'area_problems',
- content => 'your alert will not be activated',
- email_text => 'confirm the alert',
+ 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',
param1 => 1000
@@ -19,8 +24,8 @@ foreach my $test (
{
email => 'test@example.com',
type => 'council_problems',
- content => 'your alert will not be activated',
- email_text => 'confirm the alert',
+ 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',
param1 => 1000,
@@ -29,8 +34,8 @@ foreach my $test (
{
email => 'test@example.com',
type => 'ward_problems',
- content => 'your alert will not be activated',
- email_text => 'confirm the alert',
+ 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',
param1 => 1000,
@@ -39,8 +44,8 @@ foreach my $test (
{
email => 'test@example.com',
type => 'local_problems',
- content => 'your alert will not be activated',
- email_text => 'confirm the alert',
+ 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',
param1 => 20.1,
@@ -49,8 +54,8 @@ foreach my $test (
{
email => 'test@example.com',
type => 'new_updates',
- content => 'your alert will not be activated',
- email_text => 'confirm the alert',
+ 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,
}
@@ -70,7 +75,7 @@ foreach my $test (
$mech->delete_user($user);
}
- $mech->get_ok( $test->{uri} );
+ $mech->get_ok( $test->{uri} . "&token=$csrf" );
$mech->content_contains( $test->{content} );
$user =
@@ -93,9 +98,10 @@ foreach my $test (
my $email = $mech->get_email;
ok $email, "got an email";
- like $email->body, qr/$test->{email_text}/i, "Correct email text";
+ like $mech->get_text_body_from_email($email), qr/$test->{email_text}/i, "Correct email text";
- my ( $url, $url_token ) = $email->body =~ m{(http://\S+/A/)(\S+)};
+ my $url = $mech->get_link_from_email($email);
+ my ($url_token) = $url =~ m{/A/(\S+)};
ok $url, "extracted confirm url '$url'";
my $token = FixMyStreet::App->model('DB::Token')->find(
@@ -112,12 +118,10 @@ foreach my $test (
my $existing_id = $alert->id;
my $existing_token = $url_token;
- $mech->get_ok( $test->{uri} );
+ $mech->get_ok( $test->{uri} . "&token=$csrf" );
- $email = $mech->get_email;
- ok $email, 'got a second email';
-
- ($url_token) = $email->body =~ m{http://\S+/A/(\S+)};
+ $url = $mech->get_link_from_email;
+ ($url_token) = $url =~ m{/A/(\S+)};
ok $url_token ne $existing_token, 'sent out a new token';
$token = FixMyStreet::App->model('DB::Token')->find(
@@ -131,7 +135,7 @@ foreach my $test (
ok $token->data->{id} == $existing_id, 'subscribed to existing alert';
$mech->get_ok("/A/$url_token");
- $mech->content_contains('successfully confirmed');
+ $mech->content_contains('alert created');
$alert =
FixMyStreet::App->model('DB::Alert')->find( { id => $existing_id, } );
@@ -151,9 +155,7 @@ foreach my $test (
my $type = 'area_problems';
- my $user =
- FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'test-new@example.com' } );
+ my $user = $mech->create_user_ok('test-new@example.com');
my $alert = FixMyStreet::App->model('DB::Alert')->find(
{
@@ -164,7 +166,7 @@ foreach my $test (
# clear existing data so we can be sure we're creating it
ok $alert->delete() if $alert && !$test->{exist};
- $mech->get_ok( '/alert/subscribe?type=local&rznvy=test-new@example.com&feed=area:1000:A_Location' );
+ $mech->get_ok( '/alert/subscribe?type=local&rznvy=test-new@example.com&feed=area:1000:A_Location&token=' . $csrf );
$alert = FixMyStreet::App->model('DB::Alert')->find(
{
@@ -199,14 +201,17 @@ foreach my $test (
subtest $test->{desc} => sub {
my $type = $test->{type} . '_problems';
- my $user =
- FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => $test->{email} } );
+ my $user = $mech->create_user_ok($test->{email});
$mech->log_in_ok( $test->{email} );
$mech->clear_emails_ok;
- $mech->get_ok('/alert/list?pc=EH991SP');
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok('/alert/list?pc=EH991SP');
+ };
$mech->set_visible( [ radio => 'council:2651:City_of_Edinburgh' ] );
$mech->click('alert');
@@ -230,7 +235,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,
@@ -256,7 +261,7 @@ for my $test (
FixMyStreet::App->model('DB::Abuse')
->find_or_create( { email => $test->{email} } );
- $mech->get_ok( $test->{uri} );
+ $mech->get_ok( $test->{uri} . "&token=$csrf" );
$mech->content_contains( $test->{content} );
$user =
@@ -277,29 +282,8 @@ for my $test (
ok $alert, "Found the alert";
- my $email = $mech->get_email;
- ok $email, "got an email";
- like $email->body, qr/$test->{email_text}/i, "Correct email text";
-
- my ( $url, $url_token ) = $email->body =~ m{(http://\S+/A/)(\S+)};
- ok $url, "extracted confirm url '$url'";
-
- my $token = FixMyStreet::App->model('DB::Token')->find(
- {
- token => $url_token,
- scope => 'alert'
- }
- );
- ok $token, 'Token found in database';
- ok $alert->id == $token->data->{id}, 'token alertid matches alert id';
-
$mech->clear_emails_ok;
- $mech->get_ok("/A/$url_token");
- $mech->content_contains('error confirming');
-
- $alert->discard_changes;
-
ok !$alert->confirmed, 'alert not set to confirmed';
$abuse->delete;
@@ -307,43 +291,48 @@ for my $test (
};
}
+$mech->create_body_ok(2226, 'Gloucestershire County Council');
+$mech->create_body_ok(2326, 'Cheltenham Borough Council');
+
subtest "Test two-tier council alerts" => sub {
for my $alert (
{ feed => "local:51.896269:-2.093063", result => '/rss/l/51.896269,-2.093063' },
{ feed => "area:2326:Cheltenham", result => '/rss/area/Cheltenham' },
{ feed => "area:2326:4544:Cheltenham:Lansdown", result => '/rss/area/Cheltenham/Lansdown' },
{ feed => "area:2226:Gloucestershire", result => '/rss/area/Gloucestershire' },
- { feed => "area:2226:14949:Gloucestershire:Lansdown%2C_Park_and_Warden_Hill",
- result => '/rss/area/Gloucestershire/Lansdown%2C+Park+and+Warden+Hill'
+ { feed => "area:2226:14949:Gloucestershire:Lansdown_and_Park",
+ result => '/rss/area/Gloucestershire/Lansdown+and+Park'
},
{ feed => "council:2326:Cheltenham", result => '/rss/reports/Cheltenham' },
{ feed => "ward:2326:4544:Cheltenham:Lansdown", result => '/rss/reports/Cheltenham/Lansdown' },
{ feed => "council:2226:Gloucestershire", result => '/rss/reports/Gloucestershire' },
- { feed => "ward:2226:14949:Gloucestershire:Lansdown%2C_Park_and_Warden_Hill",
- result => '/rss/reports/Gloucestershire/Lansdown%2C+Park+and+Warden+Hill'
+ { feed => "ward:2226:14949:Gloucestershire:Lansdown_and_Park",
+ result => '/rss/reports/Gloucestershire/Lansdown+and+Park'
},
) {
- $mech->get_ok( '/alert/list?pc=GL502PR' );
- $mech->submit_form_ok( {
- button => 'rss',
- with_fields => {
- feed => $alert->{feed},
- }
- } );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok( '/alert/list?pc=GL502PR' );
+ $mech->submit_form_ok( {
+ button => 'rss',
+ with_fields => {
+ feed => $alert->{feed},
+ }
+ } );
+ };
is $mech->uri->path, $alert->{result}, 'Redirected to right RSS feed';
}
};
subtest "Test normal alert signups and that alerts are sent" => sub {
- my $user1 = FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'reporter@example.com', name => 'Reporter User' } );
- ok $user1, "created test user";
- $user1->alerts->delete;
+ $mech->delete_user( 'reporter@example.com' );
+ $mech->delete_user( 'alerts@example.com' );
- my $user2 = FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'alerts@example.com', name => 'Alert User' } );
- ok $user2, "created test user";
- $user2->alerts->delete;
+ my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User' );
+
+ my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User' );
for my $alert (
{
@@ -355,34 +344,41 @@ subtest "Test normal alert signups and that alerts are sent" => sub {
},
{
fields => {
- feed => 'council:2651:City_of_Edinburgh',
+ feed => 'area:2651:City_of_Edinburgh',
}
},
) {
$mech->get_ok( '/alert' );
- $mech->submit_form_ok( { with_fields => { pc => 'EH11BB' } } );
- $mech->submit_form_ok( {
- button => 'alert',
- with_fields => $alert->{fields},
- } );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'EH11BB' } } );
+ $mech->submit_form_ok( {
+ button => 'alert',
+ with_fields => $alert->{fields},
+ } );
+ };
if ( $alert->{email_confirm} ) {
- my $email = $mech->get_email;
+ my $url = $mech->get_link_from_email;
+ my ($url_token) = $url =~ m{/A/(\S+)};
$mech->clear_emails_ok;
- my ( $url, $url_token ) = $email->body =~ m{http://\S+(/A/(\S+))};
my $token = FixMyStreet::App->model('DB::Token')->find( { token => $url_token, scope => 'alert' } );
$mech->get_ok( $url );
- $mech->content_contains('successfully confirmed');
+ $mech->content_contains('alert created');
} else {
- $mech->content_contains('successfully created');
+ $mech->content_contains('alert created');
}
}
- my $dt = DateTime->now()->add( days => 2);
+ my $dt = DateTime->now(time_zone => 'Europe/London')->add(days => 2);
+
+ my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser;
my $report_time = '2011-03-01 12:00:00';
my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( {
postcode => 'EH1 1BB',
- council => '2651',
+ bodies_str => '1',
areas => ',11808,135007,14419,134935,2651,20728,',
category => 'Street lighting',
title => 'Testing',
@@ -391,9 +387,9 @@ subtest "Test normal alert signups and that alerts are sent" => sub {
name => $user1->name,
anonymous => 0,
state => 'fixed - user',
- confirmed => $dt,
- lastupdate => $dt,
- whensent => $dt->clone->add( minutes => 5 ),
+ confirmed => $dt_parser->format_datetime($dt),
+ lastupdate => $dt_parser->format_datetime($dt),
+ whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )),
lang => 'en-gb',
service => '',
cobrand => 'default',
@@ -439,36 +435,149 @@ subtest "Test normal alert signups and that alerts are sent" => sub {
$update_id = $update->id;
ok $update, "created test update - $update_id";
- FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ };
# TODO Note the below will fail if the db has an existing alert that matches
$mech->email_count_is(3);
my @emails = $mech->get_email;
my $count;
for (@emails) {
- $count++ if $_->body =~ /The following updates have been left on this problem:/;
- $count++ if $_->body =~ /The following new problems have been reported to City of\s*Edinburgh Council:/;
- $count++ if $_->body =~ /The following nearby problems have been added:/;
- $count++ if $_->body =~ /\s+-\s+Testing/;
+ my $body = $mech->get_text_body_from_email($_);
+ $count++ if $body =~ /The following updates have been left on this report:/;
+ $count++ if $body =~ /The following new FixMyStreet reports have been added in the Area 2651 area:/;
+ $count++ if $body =~ /The following FixMyStreet reports have been made within the area you\s+specified:/;
+ $count++ if $body =~ /\s+-\s+Testing/;
}
is $count, 5, 'Three emails, with five matching lines in them';
my $email = $emails[0];
- like $email->body, qr/Other User/, 'Update name given';
- unlike $email->body, qr/Anonymous User/, 'Update name not given';
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/Other User/, 'Update name given';
+ unlike $body, qr/Anonymous User/, 'Update name not given';
- # The update alert was to the problem reporter, so has a login update URL
+ # The update alert was to the problem reporter, so has a special update URL
+ $mech->log_out_ok;
$mech->get_ok( "/report/$report_id" );
$mech->content_lacks( 'has not been fixed' );
- my ($url) = $email->body =~ m{(http://\S+/M/\S+)};
- ok $url, "extracted update url '$url'";
- $mech->get_ok( $url );
+ my @urls = $mech->get_link_from_email($email, 1);
+ ok $urls[0] =~ m{/R/\S+}, "extracted update url '$urls[0]'";
+ $mech->get_ok( $urls[0] );
is $mech->uri->path, "/report/" . $report_id, "redirected to report page";
$mech->content_contains( 'has not been fixed' );
- $mech->logged_in_ok;
+ $mech->not_logged_in_ok;
+
+ ok $urls[-1] =~ m{/A/\S+}, "unsubscribe URL '$urls[-1]'";
+ $mech->get_ok( $urls[-1] );
+ $mech->content_contains('alert deleted');
+ $mech->not_logged_in_ok;
+
+ $mech->delete_user($user1);
+ $mech->delete_user($user2);
+};
+
+subtest "Test signature template is used from cobrand" => sub {
+ $mech->delete_user( 'reporter@example.com' );
+ $mech->delete_user( 'alerts@example.com' );
+
+ my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User' );
+
+ my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User' );
+
+ my $dt = DateTime->now(time_zone => 'Europe/London')->add(days => 2);
+
+ my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser;
+
+ my $report_time = '2011-03-01 12:00:00';
+ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( {
+ postcode => 'EH1 1BB',
+ bodies_str => '2651',
+ areas => ',11808,135007,14419,134935,2651,20728,',
+ category => 'Street lighting',
+ title => 'Testing',
+ detail => 'Testing Detail',
+ used_map => 1,
+ name => $user1->name,
+ anonymous => 0,
+ state => 'fixed - user',
+ confirmed => $dt_parser->format_datetime($dt),
+ lastupdate => $dt_parser->format_datetime($dt),
+ whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )),
+ lang => 'en-gb',
+ service => '',
+ cobrand => 'default',
+ cobrand_data => '',
+ send_questionnaire => 1,
+ latitude => '55.951963',
+ longitude => '-3.189944',
+ user_id => $user1->id,
+ } );
+ my $report_id = $report->id;
+ ok $report, "created test report - $report_id";
+
+ my $alert = FixMyStreet::App->model('DB::Alert')->create( {
+ parameter => $report_id,
+ alert_type => 'new_updates',
+ user => $user1,
+ cobrand => 'default',
+ } );
+ my $ret = $alert->confirm;
+ ok $ret, 'created alert for reporter';
+
+ my $update = FixMyStreet::App->model('DB::Comment')->create( {
+ problem_id => $report_id,
+ user_id => $user2->id,
+ name => 'Other User',
+ mark_fixed => 'false',
+ text => 'This is some update text',
+ state => 'confirmed',
+ confirmed => $dt->clone->add( hours => 7 ),
+ anonymous => 'f',
+ } );
+ my $update_id = $update->id;
+ ok $update, "created test update - $update_id";
- ($url) = $emails[0]->body =~ m{http://\S+(/A/\S+)};
- $mech->get_ok( $url );
- $mech->content_contains('successfully deleted');
+
+ $mech->clear_emails_ok;
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ }, sub {
+ FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ };
+
+ my $email = $mech->get_text_body_from_email;
+ like $email, qr/All the best/, 'default signature used';
+ unlike $email, qr/twitter.com/, 'nothing from fixmystreet signature';
+
+ $update = FixMyStreet::App->model('DB::Comment')->create( {
+ problem_id => $report_id,
+ user_id => $user2->id,
+ name => 'Anonymous User',
+ mark_fixed => 'true',
+ text => 'This is some more update text',
+ state => 'confirmed',
+ confirmed => $dt->clone->add( hours => 8 ),
+ anonymous => 't',
+ } );
+ $update_id = $update->id;
+ ok $update, "created test update - $update_id";
+
+ $alert->cobrand('fixmystreet');
+ $alert->update;
+
+ $mech->clear_emails_ok;
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ }, sub {
+ FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ };
+
+ $email = $mech->get_text_body_from_email;
+ like $email, qr/twitter.com/, 'fixmystreet signature used';
$mech->delete_user($user1);
$mech->delete_user($user2);
@@ -509,15 +618,12 @@ for my $test (
},
) {
subtest $test->{desc} => sub {
- my $user1 = FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'reporter@example.com', name => 'Reporter User' } );
- ok $user1, "created test user";
- $user1->alerts->delete;
+ $mech->delete_user( 'reporter@example.com' );
+ $mech->delete_user( 'alerts@example.com' );
+
+ my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User');
- my $user2 = FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'alerts@example.com', name => 'Alert User' } );
- ok $user2, "created test user";
- $user2->alerts->delete;
+ my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User');
my $dt = DateTime->now->add( minutes => -30 );
my $r_dt = $dt->clone->add( minutes => 20 );
@@ -530,9 +636,11 @@ for my $test (
my $alert_user1 = FixMyStreet::App->model('DB::Alert')->create( $alert_params );
ok $alert_user1, "alert created";
+ my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser;
+
my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( {
postcode => 'EH1 1BB',
- council => '2651',
+ bodies_str => '2651',
areas => ',11808,135007,14419,134935,2651,20728,',
category => 'Street lighting',
title => 'Alert test for non public reports',
@@ -541,9 +649,9 @@ for my $test (
name => $user2->name,
anonymous => 0,
state => 'confirmed',
- confirmed => $r_dt,
- lastupdate => $r_dt,
- whensent => $r_dt->clone->add( minutes => 5 ),
+ confirmed => $dt_parser->format_datetime($r_dt),
+ lastupdate => $dt_parser->format_datetime($r_dt),
+ whensent => $dt_parser->format_datetime($r_dt->clone->add( minutes => 5 )),
lang => 'en-gb',
service => '',
cobrand => 'default',
@@ -556,14 +664,21 @@ for my $test (
} );
$mech->clear_emails_ok;
- FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ };
$mech->email_count_is(0);
$report->update( { non_public => 0 } );
- FixMyStreet::App->model('DB::AlertType')->email_alerts();
- $mech->email_count_is(1);
- my $email = $mech->get_email;
- like $email->body, qr/Alert\s+test\s+for\s+non\s+public\s+reports/, 'alert contains public report';
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ };
+ my $email = $mech->get_text_body_from_email;
+ like $email, qr/Alert\s+test\s+for\s+non\s+public\s+reports/, 'alert contains public report';
$mech->delete_user( $user1 );
$mech->delete_user( $user2 );
@@ -571,26 +686,23 @@ for my $test (
}
subtest 'check new updates alerts for non public reports only go to report owner' => sub {
- my $user1 = FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'reporter@example.com', name => 'Reporter User' } );
- ok $user1, "created test user";
- $user1->alerts->delete;
+ $mech->delete_user( 'reporter@example.com' );
+ $mech->delete_user( 'alerts@example.com' );
- my $user2 = FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'alerts@example.com', name => 'Alert User' } );
- ok $user2, "created test user";
- $user2->alerts->delete;
+ my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User');
- my $user3 = FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'updates@example.com', name => 'Update User' } );
- ok $user3, "created test user";
+ my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User');
+
+ my $user3 = $mech->create_user_ok('updates@example.com', name => 'Update User');
my $dt = DateTime->now->add( minutes => -30 );
my $r_dt = $dt->clone->add( minutes => 20 );
+ my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser;
+
my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( {
postcode => 'EH1 1BB',
- council => '2651',
+ bodies_str => '2651',
areas => ',11808,135007,14419,134935,2651,20728,',
category => 'Street lighting',
title => 'Alert test for non public reports',
@@ -599,9 +711,9 @@ subtest 'check new updates alerts for non public reports only go to report owner
name => $user2->name,
anonymous => 0,
state => 'confirmed',
- confirmed => $r_dt,
- lastupdate => $r_dt,
- whensent => $r_dt->clone->add( minutes => 5 ),
+ confirmed => $dt_parser->format_datetime($r_dt),
+ lastupdate => $dt_parser->format_datetime($r_dt),
+ whensent => $dt_parser->format_datetime($r_dt->clone->add( minutes => 5 )),
lang => 'en-gb',
service => '',
cobrand => 'default',
@@ -648,20 +760,102 @@ subtest 'check new updates alerts for non public reports only go to report owner
ok $alert_user2, "alert created";
FixMyStreet::App->model('DB::AlertType')->email_alerts();
- $mech->email_count_is(1);
- my $email = $mech->get_email;
- like $email->body, qr/This is some more update text/, 'alert contains update text';
+ my $email = $mech->get_text_body_from_email;
+ like $email, qr/This is some more update text/, 'alert contains update text';
$mech->clear_emails_ok;
$report->update( { non_public => 0 } );
FixMyStreet::App->model('DB::AlertType')->email_alerts();
- $mech->email_count_is(1);
- $email = $mech->get_email;
- like $email->body, qr/This is some more update text/, 'alert contains update text';
+ $email = $mech->get_text_body_from_email;
+ like $email, qr/This is some more update text/, 'alert contains update text';
+
+ $mech->delete_user( $user1 );
+ $mech->delete_user( $user2 );
+ $mech->delete_user( $user3 );
+};
+
+subtest 'check setting inlude dates in new updates cobrand option' => sub {
+ my $include_date_in_alert_override= Sub::Override->new(
+ "FixMyStreet::Cobrand::Default::include_time_in_update_alerts",
+ sub { return 1; }
+ );
+ $mech->delete_user( 'reporter@example.com' );
+ $mech->delete_user( 'alerts@example.com' );
+
+ my $user1 = $mech->create_user_ok('reporter@example.com', name => 'Reporter User');
+
+ my $user2 = $mech->create_user_ok('alerts@example.com', name => 'Alert User');
+
+ my $user3 = $mech->create_user_ok('updates@example.com', name => 'Update User');
+
+ my $dt = DateTime->now->add( minutes => -30 );
+ my $r_dt = $dt->clone->add( minutes => 20 );
+
+ my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser;
+
+ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( {
+ postcode => 'EH1 1BB',
+ bodies_str => '2651',
+ areas => ',11808,135007,14419,134935,2651,20728,',
+ category => 'Street lighting',
+ title => 'Alert test for non public reports',
+ detail => 'Testing Detail',
+ used_map => 1,
+ name => $user2->name,
+ anonymous => 0,
+ state => 'confirmed',
+ confirmed => $dt_parser->format_datetime($r_dt),
+ lastupdate => $dt_parser->format_datetime($r_dt),
+ whensent => $dt_parser->format_datetime($r_dt->clone->add( minutes => 5 )),
+ lang => 'en-gb',
+ service => '',
+ cobrand => 'default',
+ cobrand_data => '',
+ send_questionnaire => 1,
+ latitude => '55.951963',
+ longitude => '-3.189944',
+ user_id => $user2->id,
+ } );
+
+ my $update = FixMyStreet::App->model('DB::Comment')->create( {
+ problem_id => $report->id,
+ user_id => $user3->id,
+ name => 'Anonymous User',
+ mark_fixed => 'false',
+ text => 'This is some more update text',
+ state => 'confirmed',
+ confirmed => $r_dt->clone->add( minutes => 8 ),
+ anonymous => 't',
+ } );
+
+ my $alert_user1 = FixMyStreet::App->model('DB::Alert')->create( {
+ user => $user1,
+ alert_type => 'new_updates',
+ parameter => $report->id,
+ confirmed => 1,
+ whensubscribed => $dt,
+ } );
+ ok $alert_user1, "alert created";
+
+
+ $mech->clear_emails_ok;
+ FixMyStreet::App->model('DB::AlertType')->email_alerts();
+
+ # if we don't do this then we're applying the date inflation code and
+ # it's timezone munging to the DateTime object above and not the DateTime
+ # object that's inflated from the database value and these turn out to be
+ # different as the one above has a UTC timezone and not the floating one
+ # that those from the DB do.
+ $update->discard_changes();
+
+ my $date_in_alert = Utils::prettify_dt( $update->confirmed );
+ my $email = $mech->get_text_body_from_email;
+ like $email, qr/$date_in_alert/, 'alert contains date';
$mech->delete_user( $user1 );
$mech->delete_user( $user2 );
$mech->delete_user( $user3 );
+ $include_date_in_alert_override->restore();
};
done_testing();
diff --git a/t/app/controller/around.t b/t/app/controller/around.t
index d973543ce..c8aca04aa 100644
--- a/t/app/controller/around.t
+++ b/t/app/controller/around.t
@@ -7,14 +7,18 @@ my $mech = FixMyStreet::TestMech->new;
subtest "check that if no query we get sent back to the homepage" => sub {
$mech->get_ok('/around');
- is $mech->uri->path, '/around', "still at '/around'";
+ is $mech->uri->path, '/', "redirected to '/'";
};
# x,y requests were generated by the old map code. We keep the behavior for
# historic links
subtest "redirect x,y requests to lat/lon (301 - permanent)" => sub {
- $mech->get_ok('/around?x=3281&y=1113');
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok('/around?x=3281&y=1113');
+ };
# did we redirect to lat,lon?
is $mech->uri->path, '/around', "still on /around";
@@ -50,8 +54,12 @@ foreach my $test (
{
subtest "test bad pc value '$test->{pc}'" => sub {
$mech->get_ok('/');
- $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } },
- "bad location" );
+ FixMyStreet::override_config {
+ GEOCODER => '',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } },
+ "bad location" );
+ };
is_deeply $mech->page_errors, $test->{errors},
"expected errors for pc '$test->{pc}'";
is_deeply $mech->pc_alternatives, $test->{pc_alternatives},
@@ -63,8 +71,8 @@ foreach my $test (
foreach my $test (
{
pc => 'SW1A 1AA',
- latitude => '51.50101',
- longitude => '-0.141587',
+ latitude => '51.501009',
+ longitude => '-0.141588',
},
{
pc => 'TQ 388 773',
@@ -75,8 +83,13 @@ foreach my $test (
{
subtest "check lat/lng for '$test->{pc}'" => sub {
$mech->get_ok('/');
- $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } },
- "good location" );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } },
+ "good location" );
+ };
is_deeply $mech->page_errors, [], "no errors for pc '$test->{pc}'";
is_deeply $mech->extract_location, $test,
"got expected location for pc '$test->{pc}'";
@@ -85,16 +98,21 @@ foreach my $test (
subtest 'check non public reports are not displayed on around page' => sub {
my $params = {
- postcode => 'EH99 1SP',
+ postcode => 'EH1 1BB',
latitude => 55.9519637512,
longitude => -3.17492254484,
};
my @edinburgh_problems =
- $mech->create_problems_for_council( 5, 2651, 'Around page', $params );
+ $mech->create_problems_for_body( 5, 2651, 'Around page', $params );
$mech->get_ok('/');
- $mech->submit_form_ok( { with_fields => { pc => 'EH99 1SP' } },
- "good location" );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB' } },
+ "good location" );
+ };
$mech->content_contains( 'Around page Test 3 for 2651',
'problem to be marked non public visible' );
@@ -102,11 +120,55 @@ subtest 'check non public reports are not displayed on around page' => sub {
ok $private->update( { non_public => 1 } ), 'problem marked non public';
$mech->get_ok('/');
- $mech->submit_form_ok( { with_fields => { pc => 'EH99 1SP' } },
- "good location" );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB' } },
+ "good location" );
+ };
$mech->content_lacks( 'Around page Test 3 for 2651',
'problem marked non public is not visible' );
};
+subtest 'check category and status filtering works on /ajax' => sub {
+ my $categories = [ 'Pothole', 'Vegetation', 'Flytipping' ];
+ my $params = {
+ postcode => 'OX1 1ND',
+ latitude => 51.7435918829363,
+ longitude => -1.23201966270446,
+ };
+ my $bbox = ($params->{longitude} - 0.01) . ',' . ($params->{latitude} - 0.01)
+ . ',' . ($params->{longitude} + 0.01) . ',' . ($params->{latitude} + 0.01);
+
+ # Create one open and one fixed report in each category
+ foreach my $category ( @$categories ) {
+ foreach my $state ( 'confirmed', 'fixed' ) {
+ my %report_params = (
+ %$params,
+ category => $category,
+ state => $state,
+ );
+ $mech->create_problems_for_body( 1, 2237, 'Around page', \%report_params );
+ }
+ }
+
+ my $json = $mech->get_ok_json( '/ajax?bbox=' . $bbox );
+ my $pins = $json->{pins};
+ is scalar @$pins, 6, 'correct number of reports when no filters';
+
+ $json = $mech->get_ok_json( '/ajax?filter_category=Pothole&bbox=' . $bbox );
+ $pins = $json->{pins};
+ is scalar @$pins, 2, 'correct number of Pothole reports';
+
+ $json = $mech->get_ok_json( '/ajax?status=open&bbox=' . $bbox );
+ $pins = $json->{pins};
+ is scalar @$pins, 3, 'correct number of open reports';
+
+ $json = $mech->get_ok_json( '/ajax?status=fixed&filter_category=Vegetation&bbox=' . $bbox );
+ $pins = $json->{pins};
+ is scalar @$pins, 1, 'correct number of fixed Vegetation reports';
+};
+
done_testing();
diff --git a/t/app/controller/auth.t b/t/app/controller/auth.t
index 67466e959..3a11cfc4a 100644
--- a/t/app/controller/auth.t
+++ b/t/app/controller/auth.t
@@ -2,16 +2,19 @@ use strict;
use warnings;
use Test::More;
+use Test::MockModule;
use FixMyStreet::TestMech;
my $mech = FixMyStreet::TestMech->new;
my $test_email = 'test@example.com';
+my $test_email2 = 'test@example.net';
my $test_password = 'foobar';
$mech->delete_user($test_email);
END {
$mech->delete_user($test_email);
+ $mech->delete_user($test_email2);
done_testing();
}
@@ -31,6 +34,13 @@ for my $test (
)
{
my ( $email, $error_message ) = @$test;
+
+ my $resolver = Test::MockModule->new('Net::DNS::Resolver');
+ $resolver->mock('send', sub {
+ my ($self, $domain, $type) = @_;
+ return Net::DNS::Packet->new;
+ });
+
pass "--- testing bad email '$email' gives error '$error_message'";
$mech->get_ok('/auth');
is_deeply $mech->page_errors, [], 'no errors initially';
@@ -46,6 +56,10 @@ for my $test (
is_deeply $mech->page_errors, [ $error_message ], 'errors match';
}
+# Email address parsing should pass from here
+my $resolver = Test::MockModule->new('Email::Valid');
+$resolver->mock('address', sub { $_[1] });
+
# create a new account
$mech->clear_emails_ok;
$mech->get_ok('/auth');
@@ -63,16 +77,14 @@ $mech->not_logged_in_ok;
# check that we got one email
{
- $mech->email_count_is(1);
my $email = $mech->get_email;
$mech->clear_emails_ok;
- is $email->header('Subject'), "Your FixMyStreet.com account details",
+ is $email->header('Subject'), "Your FixMyStreet account details",
"subject is correct";
is $email->header('To'), $test_email, "to is correct";
# extract the link
- my ($link) = $email->body =~ m{(http://\S+)};
- ok $link, "Found a link in email '$link'";
+ my $link = $mech->get_link_from_email($email);
# check that the user does not exist
sub get_user {
@@ -91,13 +103,8 @@ $mech->not_logged_in_ok;
is $mech->uri->path, '/my', "redirected to the 'my' section of site";
$mech->logged_in_ok;
- # logout and try to use the token again
+ # logout
$mech->log_out_ok;
- $mech->get_ok($link);
- is $mech->uri, $link, "not logged in";
- $mech->content_contains( 'Link too old or already used',
- 'token now invalid' );
- $mech->not_logged_in_ok;
}
# get a sign in email and change password
@@ -121,10 +128,7 @@ $mech->not_logged_in_ok;
# follow link and change password - check not prompted for old password
$mech->not_logged_in_ok;
- $mech->email_count_is(1);
- my $email = $mech->get_email;
- $mech->clear_emails_ok;
- my ($link) = $email->body =~ m{(http://\S+)};
+ my $link = $mech->get_link_from_email;
$mech->get_ok($link);
is $mech->uri->path, '/faq', "redirected to the Help page";
@@ -133,7 +137,7 @@ $mech->not_logged_in_ok;
ok my $form = $mech->form_name('change_password'),
"found change password form";
is_deeply [ sort grep { $_ } map { $_->name } $form->inputs ], #
- [ 'confirm', 'new_password' ],
+ [ 'confirm', 'new_password', 'token' ],
"check we got expected fields (ie not old_password)";
# check the various ways the form can be wrong
@@ -180,6 +184,48 @@ $mech->not_logged_in_ok;
ok $user->password, "user now has a password";
}
+subtest "Test change email page" => sub {
+ # Still signed in from the above test
+ $mech->get_ok('/my');
+ $mech->follow_link_ok({url => '/auth/change_email'});
+ $mech->submit_form_ok(
+ { with_fields => { email => "" } },
+ "submit blank change email form"
+ );
+ $mech->content_contains( 'Please enter your email', "found expected error" );
+ $mech->submit_form_ok({ with_fields => { email => $test_email2 } }, "change_email to $test_email2");
+ is $mech->uri->path, '/auth/change_email', "still on change email page";
+ $mech->content_contains( 'Now check your email', "found check your email" );
+ my $link = $mech->get_link_from_email;
+ $mech->get_ok($link);
+ is $mech->uri->path, '/auth/change_email/success', "redirected to the change_email page";
+ $mech->content_contains('successfully confirmed');
+ ok(FixMyStreet::App->model('DB::User')->find( { email => $test_email2 } ), "got a user");
+
+ ok(FixMyStreet::App->model('DB::User')->create( { email => $test_email } ), "created old user");
+ $mech->submit_form_ok({ with_fields => { email => $test_email } },
+ "change_email back to $test_email"
+ );
+ is $mech->uri->path, '/auth/change_email', "still on change email page";
+ $mech->content_contains( 'Now check your email', "found check your email" );
+ $link = $mech->get_link_from_email;
+ $mech->get_ok($link);
+ is $mech->uri->path, '/auth/change_email/success', "redirected to the change_email page";
+ $mech->content_contains('successfully confirmed');
+
+ # Test you can't click the link if logged out
+ $mech->submit_form_ok({ with_fields => { email => $test_email } },
+ "change_email back to $test_email"
+ );
+ is $mech->uri->path, '/auth/change_email', "still on change email page";
+ $mech->content_contains( 'Now check your email', "found check your email" );
+ $link = $mech->get_link_from_email;
+ $mech->log_out_ok;
+ $mech->get_ok($link);
+ isnt $mech->uri->path, '/auth/change_email/success', "not redirected to the change_email page";
+ $mech->content_contains('Sorry');
+};
+
foreach my $remember_me ( '1', '0' ) {
subtest "sign in using valid details (remember_me => '$remember_me')" => sub {
$mech->get_ok('/auth');
@@ -193,7 +239,7 @@ foreach my $remember_me ( '1', '0' ) {
},
button => 'sign_in',
},
- "sign in with '$test_email' & '$test_password"
+ "sign in with '$test_email' & '$test_password'"
);
is $mech->uri->path, '/my', "redirected to correct page";
@@ -218,10 +264,28 @@ $mech->submit_form_ok(
},
button => 'sign_in',
},
- "sign in with '$test_email' & '$test_password"
+ "sign in with '$test_email' & 'not the password'"
);
is $mech->uri->path, '/auth', "redirected to correct page";
$mech->content_contains( 'problem with your email/password combination', 'found error message' );
+subtest "sign in but have email form autofilled" => sub {
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok(
+ {
+ form_name => 'general_auth',
+ fields => {
+ email => $test_email,
+ password_sign_in => $test_password,
+ name => 'Auto-completed from elsewhere',
+ },
+ button => 'sign_in',
+ },
+ "sign in with '$test_email' and auto-completed name"
+ );
+ is $mech->uri->path, '/my', "redirected to correct page";
+};
+
+
# more test:
# TODO: test that email are always lowercased
diff --git a/t/app/controller/auth_social.t b/t/app/controller/auth_social.t
new file mode 100644
index 000000000..09fdf22d3
--- /dev/null
+++ b/t/app/controller/auth_social.t
@@ -0,0 +1,259 @@
+use strict;
+use warnings;
+use Test::More;
+use Test::MockModule;
+use LWP::Protocol::PSGI;
+use LWP::Simple;
+use JSON::MaybeXS;
+
+use t::Mock::Facebook;
+use t::Mock::Twitter;
+
+use FixMyStreet::TestMech;
+my $mech = FixMyStreet::TestMech->new;
+
+# disable info logs for this test run
+FixMyStreet::App->log->disable('info');
+END { FixMyStreet::App->log->enable('info'); }
+
+my ($report) = $mech->create_problems_for_body(1, '2345', 'Test');
+
+FixMyStreet::override_config {
+ FACEBOOK_APP_ID => 'facebook-app-id',
+ TWITTER_KEY => 'twitter-key',
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+
+my $fb_email = 'facebook@example.org';
+my $fb_uid = 123456789;
+
+my $resolver = Test::MockModule->new('Email::Valid');
+$resolver->mock('address', sub { 'facebook@example.org' });
+
+for my $fb_state ( 'refused', 'no email', 'existing UID', 'okay' ) {
+ for my $page ( 'my', 'report', 'update' ) {
+ subtest "test FB '$fb_state' login for page '$page'" => sub {
+ # Lots of user changes happening here, make sure we don't confuse
+ # Catalyst with a cookie session user that no longer exists
+ $mech->log_out_ok;
+ $mech->cookie_jar({});
+ if ($fb_state eq 'existing UID') {
+ my $user = $mech->create_user_ok($fb_email);
+ $user->update({ facebook_id => $fb_uid });
+ } else {
+ $mech->delete_user($fb_email);
+ }
+
+ # Set up a mock to catch (most, see below) requests to Facebook
+ my $fb = t::Mock::Facebook->new;
+ $fb->returns_email(0) if $fb_state eq 'no email' || $fb_state eq 'existing UID';
+ LWP::Protocol::PSGI->register($fb->to_psgi_app, host => 'www.facebook.com');
+ LWP::Protocol::PSGI->register($fb->to_psgi_app, host => 'graph.facebook.com');
+
+ # Due to https://metacpan.org/pod/Test::WWW::Mechanize::Catalyst#External-Redirects-and-allow_external
+ # the redirect to Facebook's OAuth page can mess up the session
+ # cookie. So let's pretend we always on www.facebook.com, which
+ # sorts that out.
+ $mech->host('www.facebook.com');
+
+ # Fetch the page with the form via which we wish to log in
+ my $fields;
+ if ($page eq 'my') {
+ $mech->get_ok('/my');
+ } elsif ($page eq 'report') {
+ $mech->get_ok('/');
+ $mech->submit_form_ok( { with_fields => { pc => 'SW1A1AA' } }, "submit location" );
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ $fields = {
+ title => 'Test title',
+ detail => 'Test detail',
+ };
+ } else {
+ $mech->get_ok('/report/' . $report->id);
+ $fields = {
+ update => 'Test update',
+ };
+ }
+ $mech->submit_form(with_fields => $fields, button => 'facebook_sign_in');
+
+ # As well as the cookie issue above, caused by this external
+ # redirect rewriting the host, the redirect gets handled directly
+ # by Catalyst, not our mocked handler, so will be a 404. Check
+ # the redirect happened instead.
+ is $mech->res->previous->code, 302, 'FB button redirected';
+ like $mech->res->previous->header('Location'), qr{facebook\.com.*dialog/oauth.*facebook-app-id}, 'FB redirect to oauth URL';
+
+ # Okay, now call the callback Facebook would send us to
+ if ($fb_state eq 'refused') {
+ $mech->get_ok('/auth/Facebook?error_code=ERROR');
+ } else {
+ $mech->get_ok('/auth/Facebook?code=response-code');
+ }
+
+ # Check we're showing the right form, regardless of what came back
+ if ($page eq 'report') {
+ $mech->content_contains('/report/new');
+ } elsif ($page eq 'update') {
+ $mech->content_contains('/report/update');
+ }
+
+ if ($fb_state eq 'refused') {
+ $mech->content_contains('Sorry, we could not log you in. Please fill in the form below.');
+ $mech->not_logged_in_ok;
+ } elsif ($fb_state eq 'no email') {
+ $mech->content_contains('We need your email address, please give it below.');
+ # We don't have an email, so check that we can still submit it,
+ # and the ID carries through the confirmation
+ if ($page eq 'update') {
+ $fields->{rznvy} = $fb_email;
+ } else {
+ $fields->{email} = $fb_email;
+ }
+ $fields->{name} = 'Ffion Tester';
+ $mech->submit_form(with_fields => $fields);
+ $mech->content_contains('Nearly done! Now check your email');
+
+ my $url = $mech->get_link_from_email;
+ $mech->clear_emails_ok;
+ ok $url, "extracted confirm url '$url'";
+
+ my $user = FixMyStreet::App->model( 'DB::User' )->find( { email => $fb_email } );
+ if ($page eq 'my') {
+ is $user, undef, 'No user yet exists';
+ } else {
+ is $user->facebook_id, undef, 'User has no facebook ID';
+ }
+ $mech->get_ok( $url );
+ $user = FixMyStreet::App->model( 'DB::User' )->find( { email => $fb_email } );
+ is $user->facebook_id, $fb_uid, 'User now has correct facebook ID';
+
+ } elsif ($page ne 'my') {
+ # /my auth login goes directly there, no message like this
+ $mech->content_contains('You have successfully signed in; please check and confirm your details are accurate');
+ $mech->logged_in_ok;
+ } else {
+ is $mech->uri->path, '/my', 'Successfully on /my page';
+ }
+ }
+ }
+}
+
+$resolver->mock('address', sub { 'twitter@example.org' });
+
+my $tw_email = 'twitter@example.org';
+my $tw_uid = 987654321;
+
+# Twitter has no way of getting the email, so no "okay" state here
+for my $tw_state ( 'refused', 'existing UID', 'no email' ) {
+ for my $page ( 'my', 'report', 'update' ) {
+ subtest "test Twitter '$tw_state' login for page '$page'" => sub {
+ # Lots of user changes happening here, make sure we don't confuse
+ # Catalyst with a cookie session user that no longer exists
+ $mech->log_out_ok;
+ $mech->cookie_jar({});
+ if ($tw_state eq 'existing UID') {
+ my $user = $mech->create_user_ok($tw_email);
+ $user->update({ twitter_id => $tw_uid });
+ } else {
+ $mech->delete_user($tw_email);
+ }
+
+ # Set up a mock to catch (most, see below) requests to Twitter
+ my $tw = t::Mock::Twitter->new;
+ LWP::Protocol::PSGI->register($tw->to_psgi_app, host => 'api.twitter.com');
+
+ # Due to https://metacpan.org/pod/Test::WWW::Mechanize::Catalyst#External-Redirects-and-allow_external
+ # the redirect to Twitter's OAuth page can mess up the session
+ # cookie. So let's pretend we always on api.twitter.com, which
+ # sorts that out.
+ $mech->host('api.twitter.com');
+
+ # Fetch the page with the form via which we wish to log in
+ my $fields;
+ if ($page eq 'my') {
+ $mech->get_ok('/my');
+ } elsif ($page eq 'report') {
+ $mech->get_ok('/');
+ $mech->submit_form_ok( { with_fields => { pc => 'SW1A1AA' } }, "submit location" );
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ $fields = {
+ title => 'Test title',
+ detail => 'Test detail',
+ };
+ } else {
+ $mech->get_ok('/report/' . $report->id);
+ $fields = {
+ update => 'Test update',
+ };
+ }
+ $mech->submit_form(with_fields => $fields, button => 'twitter_sign_in');
+
+ # As well as the cookie issue above, caused by this external
+ # redirect rewriting the host, the redirect gets handled directly
+ # by Catalyst, not our mocked handler, so will be a 404. Check
+ # the redirect happened instead.
+ is $mech->res->previous->code, 302, 'Twitter button redirected';
+ like $mech->res->previous->header('Location'), qr{api\.twitter\.com/oauth/authenticate\?oauth_token=request-token}, 'Twitter redirect to oauth URL';
+
+ # Okay, now call the callback Facebook would send us to
+ if ($tw_state eq 'refused') {
+ $mech->get_ok('/auth/Twitter?denied=token');
+ } else {
+ $mech->get_ok('/auth/Twitter?oauth_token=request-token&oauth_verifier=verifier');
+ }
+
+ # Check we're showing the right form, regardless of what came back
+ if ($page eq 'report') {
+ $mech->content_contains('/report/new');
+ } elsif ($page eq 'update') {
+ $mech->content_contains('/report/update');
+ }
+
+ if ($tw_state eq 'refused') {
+ $mech->content_contains('Sorry, we could not log you in. Please fill in the form below.');
+ $mech->not_logged_in_ok;
+ } elsif ($tw_state eq 'no email') {
+ $mech->content_contains('We need your email address, please give it below.');
+ # We don't have an email, so check that we can still submit it,
+ # and the ID carries through the confirmation
+ if ($page eq 'update') {
+ $fields->{rznvy} = $tw_email;
+ } else {
+ $fields->{email} = $tw_email;
+ }
+ $fields->{name} = 'Ffion Tester';
+ $mech->submit_form(with_fields => $fields);
+ $mech->content_contains('Nearly done! Now check your email');
+
+ my $url = $mech->get_link_from_email;
+ $mech->clear_emails_ok;
+ ok $url, "extracted confirm url '$url'";
+
+ my $user = FixMyStreet::App->model( 'DB::User' )->find( { email => $tw_email } );
+ if ($page eq 'my') {
+ is $user, undef, 'No user yet exists';
+ } else {
+ is $user->twitter_id, undef, 'User has no twitter ID';
+ }
+ $mech->get_ok( $url );
+ $user = FixMyStreet::App->model( 'DB::User' )->find( { email => $tw_email } );
+ is $user->twitter_id, $tw_uid, 'User now has correct twitter ID';
+
+ } elsif ($page ne 'my') {
+ # /my auth login goes directly there, no message like this
+ $mech->content_contains('You have successfully signed in; please check and confirm your details are accurate');
+ $mech->logged_in_ok;
+ } else {
+ is $mech->uri->path, '/my', 'Successfully on /my page';
+ }
+ }
+ }
+}
+
+};
+
+END {
+ $mech->delete_problems_for_body('2345');
+ done_testing();
+}
diff --git a/t/app/controller/contact.t b/t/app/controller/contact.t
index 11e0d30cf..7c2769b9c 100644
--- a/t/app/controller/contact.t
+++ b/t/app/controller/contact.t
@@ -8,7 +8,7 @@ my $mech = FixMyStreet::TestMech->new;
$mech->get_ok('/contact');
$mech->title_like(qr/Contact Us/);
-$mech->content_contains("We'd love to hear what you think about this site");
+$mech->content_contains("It's often quickest to ");
my $problem_main;
@@ -52,12 +52,7 @@ for my $test (
)
{
subtest 'check reporting a problem displays correctly' => sub {
- my $user = FixMyStreet::App->model('DB::User')->find_or_create(
- {
- name => $test->{name},
- email => $test->{email}
- }
- );
+ my $user = $mech->create_user_ok($test->{email}, name => $test->{name});
my $problem = FixMyStreet::App->model('DB::Problem')->create(
{
@@ -80,12 +75,8 @@ for my $test (
if ( $test->{update} ) {
my $update_info = $test->{update};
- my $update_user = FixMyStreet::App->model('DB::User')->find_or_create(
- {
- name => $update_info->{name},
- email => $update_info->{email}
- }
- );
+ my $update_user = $mech->create_user_ok($update_info->{email},
+ name => $update_info->{name});
$update = FixMyStreet::App->model('DB::Comment')->create(
{
@@ -93,7 +84,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',
}
@@ -259,17 +250,17 @@ for my $test (
$mech->get_ok('/contact');
}
$mech->submit_form_ok( { with_fields => $test->{fields} } );
- $mech->content_contains('Thanks for your feedback');
- $mech->email_count_is(1);
+ $mech->content_contains('Thank you for your enquiry');
my $email = $mech->get_email;
is $email->header('Subject'), 'FMS message: ' . $test->{fields}->{subject}, 'subject';
is $email->header('From'), "\"$test->{fields}->{name}\" <$test->{fields}->{em}>", 'from';
- like $email->body, qr/$test->{fields}->{message}/, 'body';
- like $email->body, qr/Sent by contact.cgi on \S+. IP address (?:\d{1,3}\.){3,}\d{1,3}/, 'body footer';
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/$test->{fields}->{message}/, 'body';
+ like $body, qr/Sent by contact.cgi on \S+. IP address (?:\d{1,3}\.){3,}\d{1,3}/, 'body footer';
my $problem_id = $test->{fields}{id};
- like $email->body, qr/Complaint about report $problem_id/, 'reporting a report'
+ like $body, qr/Complaint about report $problem_id/, 'reporting a report'
if $test->{fields}{id};
$problem_main->discard_changes;
@@ -282,6 +273,115 @@ for my $test (
};
}
+for my $test (
+ {
+ fields => {
+ em => 'test@example.com',
+ name => 'A name',
+ subject => 'A subject',
+ message => 'A message',
+ dest => undef,
+ },
+ page_errors =>
+ [ 'There were problems with your report. Please see below.',
+ 'Please enter who your message is for',
+ ]
+ },
+ {
+ fields => {
+ em => 'test@example.com',
+ name => 'A name',
+ subject => 'A subject',
+ message => 'A message',
+ dest => 'council',
+ },
+ page_errors =>
+ [ 'There were problems with your report. Please see below.',
+ 'You can only contact the team behind FixMyStreet using our contact form',
+ ]
+ },
+ {
+ fields => {
+ em => 'test@example.com',
+ name => 'A name',
+ subject => 'A subject',
+ message => 'A message',
+ dest => 'update',
+ },
+ page_errors =>
+ [ 'There were problems with your report. Please see below.',
+ 'You can only contact the team behind FixMyStreet using our contact form',
+ ]
+ },
+ )
+{
+ subtest 'check submit page incorrect destination handling' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fixmystreet' ],
+ }, sub {
+ $mech->host('www.fixmystreet.com');
+ $mech->get_ok( $test->{url} ? $test->{url} : '/contact' );
+ $mech->submit_form_ok( { with_fields => $test->{fields} } );
+ is_deeply $mech->page_errors, $test->{page_errors}, 'page errors';
+
+ # we santise this when we submit so need to remove it
+ delete $test->{fields}->{id}
+ if $test->{fields}->{id} and $test->{fields}->{id} eq 'invalid';
+ is_deeply $mech->visible_form_values, $test->{fields}, 'form values';
+
+ if ( $test->{fields}->{dest} and $test->{fields}->{dest} eq 'update' ) {
+ $mech->content_contains( 'www.writetothem.com', 'includes link to WTT if trying to update report' );
+ } elsif ( $test->{fields}->{dest} and $test->{fields}->{dest} eq 'council' ) {
+ $mech->content_lacks( 'www.writetothem.com', 'does not include link to WTT if trying to contact council' );
+ $mech->content_contains( 'should find contact details', 'mentions checking council website for contact details' );
+ }
+ }
+ };
+}
+
+for my $test (
+ {
+ fields => {
+ em => 'test@example.com',
+ name => 'A name',
+ subject => 'A subject',
+ message => 'A message',
+ dest => 'help',
+ },
+ },
+ {
+ fields => {
+ em => 'test@example.com',
+ name => 'A name',
+ subject => 'A subject',
+ message => 'A message',
+ dest => 'feedback',
+ },
+ },
+ {
+ fields => {
+ em => 'test@example.com',
+ name => 'A name',
+ subject => 'A subject',
+ message => 'A message',
+ dest => 'from_council',
+ },
+ },
+ )
+{
+ subtest 'check email sent correctly with dest field set to us' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fixmystreet' ],
+ }, sub {
+ $mech->clear_emails_ok;
+ $mech->get_ok('/contact');
+ $mech->submit_form_ok( { with_fields => $test->{fields} } );
+ $mech->content_contains('Thank you for your enquiry');
+ $mech->email_count_is(1);
+ }
+ };
+}
+
$problem_main->delete;
done_testing();
diff --git a/t/app/controller/dashboard.t b/t/app/controller/dashboard.t
index 307943abd..903affdcf 100644
--- a/t/app/controller/dashboard.t
+++ b/t/app/controller/dashboard.t
@@ -1,6 +1,7 @@
use strict;
use warnings;
use Test::More;
+use Test::MockTime ':all';
use FixMyStreet::TestMech;
use Web::Scraper;
@@ -12,559 +13,613 @@ my $test_pass = 'password';
my $test_council = 2651;
my $test_ward = 20723;
-$mech->delete_user( $test_user );
-my $user = FixMyStreet::App->model('DB::User')->create( {
- email => $test_user,
- password => $test_pass,
-} );
+my $body = $mech->create_body_ok($test_council, 'City of Edinburgh Council');
-my $p_user = FixMyStreet::App->model('DB::User')->find_or_create( {
- email => 'p_user@example.com'
-} );
+$mech->delete_user( $test_user );
+my $user = $mech->create_user_ok($test_user, password => $test_pass);
-$mech->not_logged_in_ok;
-$mech->get_ok('/dashboard');
+my $p_user = $mech->create_user_ok('p_user@example.com');
-$mech->content_contains( 'sign in' );
+# Dashboard tests assume we are not too early in year, to allow reporting
+# within same year, as a convenience.
+set_absolute_time('2014-03-01T12:00:00');
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
-$mech->submit_form(
- with_fields => { email => $test_user, password_sign_in => $test_pass }
-);
+ $mech->not_logged_in_ok;
+ $mech->get_ok('/dashboard');
-is $mech->status, '404', 'If not council user get 404';
+ $mech->content_contains( 'sign in' );
-$user->from_body( $test_council );
-$user->update;
+ $mech->submit_form(
+ with_fields => { email => $test_user, password_sign_in => $test_pass }
+ );
-$mech->log_out_ok;
-$mech->get_ok('/dashboard');
-$mech->submit_form_ok( {
- with_fields => { email => $test_user, password_sign_in => $test_pass }
-} );
+ is $mech->status, '404', 'If not council user get 404';
-$mech->content_contains( 'City of Edinburgh' );
+ $user->from_body( $body->id );
+ $user->update;
-FixMyStreet::App->model('DB::Contact')->search( { body_id => $test_council } )
- ->delete;
+ $mech->log_out_ok;
+ $mech->get_ok('/dashboard');
+ $mech->submit_form_ok( {
+ with_fields => { email => $test_user, password_sign_in => $test_pass }
+ } );
-delete_problems();
+ $mech->content_contains( 'Area 2651' );
-my @cats = qw( Grafitti Litter Potholes Other );
-for my $contact ( @cats ) {
- FixMyStreet::App->model('DB::Contact')->create(
- {
- body_id => $test_council,
- category => $contact,
- email => "$contact\@example.org",
- confirmed => 1,
- whenedited => DateTime->now,
- deleted => 0,
- editor => 'test',
- note => 'test',
- }
- );
-}
-
-$mech->get_ok('/dashboard');
-
-my $categories = scraper {
- process "select[name=category] > option", 'cats[]' => 'TEXT',
- process "select[name=ward] > option", 'wards[]' => 'TEXT',
- process "table[id=overview] > tr", 'rows[]' => scraper {
- process 'td', 'cols[]' => 'TEXT'
- },
- process "tr[id=total] > td", 'totals[]' => 'TEXT',
- process "tr[id=fixed_council] > td", 'council[]' => 'TEXT',
- process "tr[id=fixed_user] > td", 'user[]' => 'TEXT',
- process "tr[id=total_fixed] > td", 'total_fixed[]' => 'TEXT',
- process "tr[id=in_progress] > td", 'in_progress[]' => 'TEXT',
- process "tr[id=planned] > td", 'planned[]' => 'TEXT',
- process "tr[id=investigating] > td", 'investigating[]' => 'TEXT',
- process "tr[id=marked] > td", 'marked[]' => 'TEXT',
- process "tr[id=avg_marked] > td", 'avg_marked[]' => 'TEXT',
- process "tr[id=avg_fixed] > td", 'avg_fixed[]' => 'TEXT',
- process "tr[id=not_marked] > td", 'not_marked[]' => 'TEXT',
- process "tr[id=closed] > td", 'closed[]' => 'TEXT',
- process "table[id=reports] > tr > td", 'report_lists[]' => scraper {
- process 'ul > li', 'reports[]' => 'TEXT'
- },
-};
+ FixMyStreet::App->model('DB::Contact')->search( { body_id => $body->id } )
+ ->delete;
-my $expected_cats = [ 'All', '-- Pick a category --', @cats ];
-my $res = $categories->scrape( $mech->content );
-is_deeply( $res->{cats}, $expected_cats, 'correct list of categories' );
+ delete_problems();
-foreach my $row ( @{ $res->{rows} }[1 .. 11] ) {
- foreach my $col ( @{ $row->{cols} } ) {
- is $col, 0;
+ my @cats = qw( Grafitti Litter Potholes Other );
+ for my $contact ( @cats ) {
+ FixMyStreet::App->model('DB::Contact')->create(
+ {
+ body_id => $body->id,
+ category => $contact,
+ email => "$contact\@example.org",
+ confirmed => 1,
+ whenedited => DateTime->now,
+ deleted => 0,
+ editor => 'test',
+ note => 'test',
+ }
+ );
}
-}
-for my $reports ( @{ $res->{report_lists} } ) {
- is_deeply $reports, {}, 'No reports';
-}
+ $mech->get_ok('/dashboard');
-foreach my $test (
- {
- desc => 'confirmed today with no state',
- dt => DateTime->now,
- counts => [1,1,1,1],
- report_counts => [1, 0, 0],
- },
- {
- desc => 'confirmed last 7 days with no state',
- dt => DateTime->now->subtract( days => 6, hours => 23 ),
- counts => [1,2,2,2],
- report_counts => [2, 0, 0],
- },
- {
- desc => 'confirmed last 8 days with no state',
- dt => DateTime->now->subtract( days => 8 ),
- counts => [1,2,3,3],
- report_counts => [2, 1, 0],
- },
- {
- desc => 'confirmed last 4 weeks with no state',
- dt => DateTime->now->subtract( weeks => 2 ),
- counts => [1,2,4,4],
- report_counts => [2, 1, 1],
- },
- {
- desc => 'confirmed this year with no state',
- dt => DateTime->now->subtract( weeks => 7 ),
- counts => [1,2,4,5],
- report_counts => [2, 1, 1],
- },
-) {
- subtest $test->{desc} => sub {
- make_problem( { state => 'confirmed', conf_dt => $test->{dt} } );
-
- $mech->get_ok('/dashboard');
- $res = $categories->scrape( $mech->content );
-
- check_row( $res, 'totals', $test->{counts} );
- check_row( $res, 'not_marked', $test->{counts} );
-
- check_report_counts( $res, $test->{report_counts} );
+ my $categories = scraper {
+ process "select[name=category] > option", 'cats[]' => 'TEXT',
+ process "select[name=ward] > option", 'wards[]' => 'TEXT',
+ process "table[id=overview] > tr", 'rows[]' => scraper {
+ process 'td', 'cols[]' => 'TEXT'
+ },
+ process "tr[id=total] > td", 'totals[]' => 'TEXT',
+ process "tr[id=fixed_council] > td", 'council[]' => 'TEXT',
+ process "tr[id=fixed_user] > td", 'user[]' => 'TEXT',
+ process "tr[id=total_fixed] > td", 'total_fixed[]' => 'TEXT',
+ process "tr[id=in_progress] > td", 'in_progress[]' => 'TEXT',
+ process "tr[id=action_scheduled] > td", 'action_scheduled[]' => 'TEXT',
+ process "tr[id=investigating] > td", 'investigating[]' => 'TEXT',
+ process "tr[id=marked] > td", 'marked[]' => 'TEXT',
+ process "tr[id=avg_marked] > td", 'avg_marked[]' => 'TEXT',
+ process "tr[id=avg_fixed] > td", 'avg_fixed[]' => 'TEXT',
+ process "tr[id=not_marked] > td", 'not_marked[]' => 'TEXT',
+ process "tr[id=closed] > td", 'closed[]' => 'TEXT',
+ process "table[id=reports] > tr > td", 'report_lists[]' => scraper {
+ process 'ul > li', 'reports[]' => 'TEXT'
+ },
};
-}
-
-delete_problems();
-
-my $is_monday = DateTime->now->day_of_week == 1 ? 1 : 0;
-
-foreach my $test (
- {
- desc => 'user fixed today',
- confirm_dt => DateTime->now->subtract( days => 1 ),
- mark_dt => DateTime->now,
- state => 'fixed - user',
- counts => {
- totals => $is_monday ? [0,1,1,1] : [1,1,1,1],
- user => [1,1,1,1],
- council => [0,0,0,0],
- avg_fixed => [0,0,0,0],
- total_fixed => [1,1,1,1],
- }
- },
- {
- desc => 'council fixed today',
- confirm_dt => DateTime->now->subtract( days => 1 ),
- mark_dt => DateTime->now,
- state => 'fixed - council',
- counts => {
- totals => $is_monday ? [0,2,2,2] : [2,2,2,2],
- user => [1,1,1,1],
- council => [1,1,1,1],
- avg_fixed => [1,1,1,1],
- total_fixed => [2,2,2,2],
- }
- },
- {
- desc => 'marked investigating today',
- confirm_dt => DateTime->now->subtract( days => 1 ),
- mark_dt => DateTime->now,
- state => 'investigating',
- counts => {
- totals => $is_monday ? [0,3,3,3] : [3,3,3,3],
- user => [1,1,1,1],
- council => [1,1,1,1],
- total_fixed => [2,2,2,2],
- avg_marked => [1,1,1,1],
- investigating => [1,1,1,1],
- marked => [1,1,1,1]
- }
- },
- {
- desc => 'marked in progress today',
- confirm_dt => DateTime->now->subtract( days => 1 ),
- mark_dt => DateTime->now,
- state => 'in progress',
- counts => {
- totals => $is_monday ? [0,4,4,4] : [4,4,4,4],
- user => [1,1,1,1],
- council => [1,1,1,1],
- total_fixed => [2,2,2,2],
- avg_marked => [1,1,1,1],
- investigating => [1,1,1,1],
- in_progress => [1,1,1,1],
- marked => [2,2,2,2]
- }
- },
- {
- desc => 'marked as planned today',
- confirm_dt => DateTime->now->subtract( days => 1 ),
- mark_dt => DateTime->now,
- state => 'planned',
- counts => {
- totals => $is_monday ? [ 0,5,5,5] : [5,5,5,5],
- user => [1,1,1,1],
- council => [1,1,1,1],
- total_fixed => [2,2,2,2],
- avg_marked => [1,1,1,1],
- investigating => [1,1,1,1],
- in_progress => [1,1,1,1],
- planned => [1,1,1,1],
- marked => [3,3,3,3]
- }
- },
- {
- desc => 'marked as planned today, confirmed a week ago',
- confirm_dt => DateTime->now->subtract( days => 8 ),
- mark_dt => DateTime->now,
- state => 'planned',
- counts => {
- totals => $is_monday ? [0,5,6,6] : [5,5,6,6],
- user => [1,1,1,1],
- council => [1,1,1,1],
- total_fixed => [2,2,2,2],
- avg_marked => [3,3,3,3],
- investigating => [1,1,1,1],
- in_progress => [1,1,1,1],
- planned => [2,2,2,2],
- marked => [4,4,4,4]
- }
- },
- {
- desc => 'marked as council fixed today, confirmed a week ago',
- confirm_dt => DateTime->now->subtract( days => 8 ),
- mark_dt => DateTime->now,
- state => 'fixed - council',
- counts => {
- totals => $is_monday ? [0,5,7,7] : [5,5,7,7],
- user => [1,1,1,1],
- council => [2,2,2,2],
- total_fixed => [3,3,3,3],
- avg_fixed => [5,5,5,5],
- avg_marked => [3,3,3,3],
- investigating => [1,1,1,1],
- in_progress => [1,1,1,1],
- planned => [2,2,2,2],
- marked => [4,4,4,4]
- }
- },
- {
- desc => 'marked as council fixed a week ago, confirmed 3 weeks ago',
- confirm_dt => DateTime->now->subtract( days => 21),
- mark_dt => DateTime->now->subtract( days => 8 ),
- state => 'fixed - council',
- counts => {
- totals => $is_monday ? [0,5,8,8] : [5,5,8,8],
- user => [1,1,1,1],
- council => [2,2,3,3],
- total_fixed => [3,3,4,4],
- avg_fixed => [5,5,7,7],
- avg_marked => [3,3,3,3],
- investigating => [1,1,1,1],
- in_progress => [1,1,1,1],
- planned => [2,2,2,2],
- marked => [4,4,4,4]
- }
- },
- {
- desc => 'marked as user fixed 6 weeks ago, confirmed 7 weeks ago',
- confirm_dt => DateTime->now->subtract( weeks => 6 ),
- mark_dt => DateTime->now->subtract( weeks => 7 ),
- state => 'fixed - user',
- counts => {
- totals => $is_monday ? [0,5,8,9] : [5,5,8,9],
- user => [1,1,1,2],
- council => [2,2,3,3],
- total_fixed => [3,3,4,5],
- avg_fixed => [5,5,7,7],
- avg_marked => [3,3,3,3],
- investigating => [1,1,1,1],
- in_progress => [1,1,1,1],
- planned => [2,2,2,2],
- marked => [4,4,4,4]
- }
- },
- {
- desc => 'marked as closed',
- confirm_dt => DateTime->now->subtract( days => 1 ),
- mark_dt => DateTime->now,
- state => 'closed',
- counts => {
- totals => $is_monday ? [0,6,9,10] : [6,6,9,10],
- user => [1,1,1,2],
- council => [2,2,3,3],
- total_fixed => [3,3,4,5],
- avg_fixed => [5,5,7,7],
- avg_marked => [2,2,2,2],
- investigating => [1,1,1,1],
- in_progress => [1,1,1,1],
- planned => [2,2,2,2],
- closed => [1,1,1,1],
- marked => [5,5,5,5]
- }
- },
-) {
- subtest $test->{desc} => sub {
- make_problem(
- {
- state => $test->{state},
- conf_dt => $test->{confirm_dt},
- mark_dt => $test->{mark_dt},
- }
- );
- $mech->get_ok('/dashboard');
- $res = $categories->scrape( $mech->content );
+ my $expected_cats = [ 'All', '-- Pick a category --', @cats ];
+ my $res = $categories->scrape( $mech->content );
+ is_deeply( $res->{cats}, $expected_cats, 'correct list of categories' );
- foreach my $row ( keys %{ $test->{counts} } ) {
- check_row( $res, $row, $test->{counts}->{$row} );
+ foreach my $row ( @{ $res->{rows} }[1 .. 11] ) {
+ foreach my $col ( @{ $row->{cols} } ) {
+ is $col, 0;
}
- };
-}
+ }
-delete_problems();
+ for my $reports ( @{ $res->{report_lists} } ) {
+ is_deeply $reports, {}, 'No reports';
+ }
-for my $test (
- {
- desc => 'Selecting no category does nothing',
- p1 => {
- state => 'confirmed',
- conf_dt => DateTime->now(),
- category => 'Potholes',
+ my $now = DateTime->now(time_zone => 'local');
+ foreach my $test (
+ {
+ desc => 'confirmed today with no state',
+ dt => $now,
+ counts => [1,1,1,1],
+ report_counts => [1, 0, 0],
+ },
+ {
+ desc => 'confirmed last 7 days with no state',
+ dt => $now->clone->subtract( days => 6, hours => 23 ),
+ counts => [1,2,2,2],
+ report_counts => [2, 0, 0],
},
- p2 => {
- state => 'confirmed',
- conf_dt => DateTime->now(),
- category => 'Litter',
+ {
+ desc => 'confirmed last 8 days with no state',
+ dt => $now->clone->subtract( days => 8 ),
+ counts => [1,2,3,3],
+ report_counts => [2, 1, 0],
},
- category => '',
- counts => {
- totals => [2,2,2,2],
+ {
+ desc => 'confirmed last 2 weeks with no state',
+ dt => $now->clone->subtract( weeks => 2 ),
+ counts => [1,2,4,4],
+ report_counts => [2, 1, 1],
},
- counts_after => {
- totals => [2,2,2,2],
+ {
+ desc => 'confirmed this year with no state',
+ dt => $now->clone->subtract( weeks => 7 ),
+ counts => [1,2,4,5],
+ report_counts => [2, 1, 1],
+ },
+ ) {
+ subtest $test->{desc} => sub {
+ make_problem( { state => 'confirmed', conf_dt => $test->{dt} } );
+
+ $mech->get_ok('/dashboard');
+ $res = $categories->scrape( $mech->content );
+
+ check_row( $res, 'totals', $test->{counts} );
+ check_row( $res, 'not_marked', $test->{counts} );
+
+ check_report_counts( $res, $test->{report_counts} );
+ };
+ }
+
+ delete_problems();
+
+ my $is_monday = DateTime->now->day_of_week == 1 ? 1 : 0;
+
+ foreach my $test (
+ {
+ desc => 'user fixed today',
+ confirm_dt => DateTime->now->subtract( days => 1 ),
+ mark_dt => DateTime->now,
+ state => 'fixed - user',
+ counts => {
+ totals => $is_monday ? [0,1,1,1] : [1,1,1,1],
+ user => [1,1,1,1],
+ council => [0,0,0,0],
+ avg_fixed => [0,0,0,0],
+ total_fixed => [1,1,1,1],
+ }
},
- report_counts => [2,0,0],
- report_counts_after => [2,0,0],
- },
- {
- desc => 'Limit display by category',
- category => 'Potholes',
- counts => {
- totals => [2,2,2,2],
+ {
+ desc => 'council fixed today',
+ confirm_dt => DateTime->now->subtract( days => 1 ),
+ mark_dt => DateTime->now,
+ state => 'fixed - council',
+ counts => {
+ totals => $is_monday ? [0,2,2,2] : [2,2,2,2],
+ user => [1,1,1,1],
+ council => [1,1,1,1],
+ avg_fixed => [1,1,1,1],
+ total_fixed => [2,2,2,2],
+ }
},
- counts_after => {
- totals => [1,1,1,1],
+ {
+ desc => 'marked investigating today',
+ confirm_dt => DateTime->now->subtract( days => 1 ),
+ mark_dt => DateTime->now,
+ state => 'investigating',
+ counts => {
+ totals => $is_monday ? [0,3,3,3] : [3,3,3,3],
+ user => [1,1,1,1],
+ council => [1,1,1,1],
+ total_fixed => [2,2,2,2],
+ avg_marked => [1,1,1,1],
+ investigating => [1,1,1,1],
+ marked => [1,1,1,1]
+ }
},
- report_counts => [2,0,0],
- report_counts_after => [1,0,0],
- },
- {
- desc => 'Limit display for category with no entries',
- category => 'Grafitti',
- counts => {
- totals => [2,2,2,2],
+ {
+ desc => 'marked in progress today',
+ confirm_dt => DateTime->now->subtract( days => 1 ),
+ mark_dt => DateTime->now,
+ state => 'in progress',
+ counts => {
+ totals => $is_monday ? [0,4,4,4] : [4,4,4,4],
+ user => [1,1,1,1],
+ council => [1,1,1,1],
+ total_fixed => [2,2,2,2],
+ avg_marked => [1,1,1,1],
+ investigating => [1,1,1,1],
+ in_progress => [1,1,1,1],
+ marked => [2,2,2,2]
+ }
},
- counts_after => {
- totals => [0,0,0,0],
+ {
+ desc => 'marked as action scheduled today',
+ confirm_dt => DateTime->now->subtract( days => 1 ),
+ mark_dt => DateTime->now,
+ state => 'action scheduled',
+ counts => {
+ totals => $is_monday ? [ 0,5,5,5] : [5,5,5,5],
+ user => [1,1,1,1],
+ council => [1,1,1,1],
+ total_fixed => [2,2,2,2],
+ avg_marked => [1,1,1,1],
+ investigating => [1,1,1,1],
+ in_progress => [1,1,1,1],
+ action_scheduled => [1,1,1,1],
+ marked => [3,3,3,3]
+ }
},
- report_counts => [2,0,0],
- report_counts_after => [0,0,0],
- },
- {
- desc => 'Limit display by category for council fixed',
- p1 => {
- state => 'fixed - council',
- conf_dt => DateTime->now()->subtract( weeks => 1 ),
- mark_dt => DateTime->now()->subtract( weeks => 1 ),
- category => 'Potholes',
+ {
+ desc => 'marked as action scheduled today, confirmed a week ago',
+ confirm_dt => DateTime->now->subtract( days => 8 ),
+ mark_dt => DateTime->now,
+ state => 'action scheduled',
+ counts => {
+ totals => $is_monday ? [0,5,6,6] : [5,5,6,6],
+ user => [1,1,1,1],
+ council => [1,1,1,1],
+ total_fixed => [2,2,2,2],
+ avg_marked => [3,3,3,3],
+ investigating => [1,1,1,1],
+ in_progress => [1,1,1,1],
+ action_scheduled => [2,2,2,2],
+ marked => [4,4,4,4]
+ }
},
- p2 => {
- state => 'fixed - council',
- conf_dt => DateTime->now()->subtract( weeks => 1 ),
- mark_dt => DateTime->now()->subtract( weeks => 1 ),
- category => 'Litter',
+ {
+ desc => 'marked as council fixed today, confirmed a week ago',
+ confirm_dt => DateTime->now->subtract( days => 8 ),
+ mark_dt => DateTime->now,
+ state => 'fixed - council',
+ counts => {
+ totals => $is_monday ? [0,5,7,7] : [5,5,7,7],
+ user => [1,1,1,1],
+ council => [2,2,2,2],
+ total_fixed => [3,3,3,3],
+ avg_fixed => [5,5,5,5],
+ avg_marked => [3,3,3,3],
+ investigating => [1,1,1,1],
+ in_progress => [1,1,1,1],
+ action_scheduled => [2,2,2,2],
+ marked => [4,4,4,4]
+ }
},
- category => 'Potholes',
- counts => {
- council => [0,0,2,2],
- totals => [2,2,4,4],
+ {
+ desc => 'marked as council fixed a week ago, confirmed 3 weeks ago',
+ confirm_dt => DateTime->now->subtract( days => 21),
+ mark_dt => DateTime->now->subtract( days => 8 ),
+ state => 'fixed - council',
+ counts => {
+ totals => $is_monday ? [0,5,8,8] : [5,5,8,8],
+ user => [1,1,1,1],
+ council => [2,2,3,3],
+ total_fixed => [3,3,4,4],
+ avg_fixed => [5,5,7,7],
+ avg_marked => [3,3,3,3],
+ investigating => [1,1,1,1],
+ in_progress => [1,1,1,1],
+ action_scheduled => [2,2,2,2],
+ marked => [4,4,4,4]
+ }
},
- counts_after => {
- council => [0,0,1,1],
- totals => [1,1,2,2],
+ {
+ desc => 'marked as user fixed 6 weeks ago, confirmed 7 weeks ago',
+ confirm_dt => DateTime->now->subtract( weeks => 6 ),
+ mark_dt => DateTime->now->subtract( weeks => 7 ),
+ state => 'fixed - user',
+ counts => {
+ totals => $is_monday ? [0,5,8,9] : [5,5,8,9],
+ user => [1,1,1,2],
+ council => [2,2,3,3],
+ total_fixed => [3,3,4,5],
+ avg_fixed => [5,5,7,7],
+ avg_marked => [3,3,3,3],
+ investigating => [1,1,1,1],
+ in_progress => [1,1,1,1],
+ action_scheduled => [2,2,2,2],
+ marked => [4,4,4,4]
+ }
},
- report_counts => [2,2,0],
- report_counts_after => [1,1,0],
- },
- {
- desc => 'Limit display by category for user fixed',
- p1 => {
- state => 'fixed - user',
- conf_dt => DateTime->now()->subtract( weeks => 1 ),
- mark_dt => DateTime->now()->subtract( weeks => 1 ),
- category => 'Potholes',
+ {
+ desc => 'marked as closed',
+ confirm_dt => DateTime->now->subtract( days => 1 ),
+ mark_dt => DateTime->now,
+ state => 'closed',
+ counts => {
+ totals => $is_monday ? [0,6,9,10] : [6,6,9,10],
+ user => [1,1,1,2],
+ council => [2,2,3,3],
+ total_fixed => [3,3,4,5],
+ avg_fixed => [5,5,7,7],
+ avg_marked => [2,2,2,2],
+ investigating => [1,1,1,1],
+ in_progress => [1,1,1,1],
+ action_scheduled => [2,2,2,2],
+ closed => [1,1,1,1],
+ marked => [5,5,5,5]
+ }
},
- p2 => {
- state => 'fixed - user',
- conf_dt => DateTime->now()->subtract( weeks => 1 ),
- mark_dt => DateTime->now()->subtract( weeks => 1 ),
- category => 'Litter',
+ {
+ desc => 'marked as planned',
+ confirm_dt => DateTime->now->subtract( days => 1 ),
+ mark_dt => DateTime->now,
+ state => 'planned',
+ counts => {
+ totals => $is_monday ? [0,7,10,11] : [7,7,10,11],
+ user => [1,1,1,2],
+ council => [2,2,3,3],
+ total_fixed => [3,3,4,5],
+ avg_fixed => [5,5,7,7],
+ avg_marked => [2,2,2,2],
+ investigating => [1,1,1,1],
+ in_progress => [1,1,1,1],
+ action_scheduled => [3,3,3,3],
+ closed => [1,1,1,1],
+ marked => [6,6,6,6]
+ }
},
- category => 'Potholes',
- counts => {
- user => [0,0,2,2],
- council => [0,0,2,2],
- totals => [2,2,6,6],
+ ) {
+ subtest $test->{desc} => sub {
+ make_problem(
+ {
+ state => $test->{state},
+ conf_dt => $test->{confirm_dt},
+ mark_dt => $test->{mark_dt},
+ }
+ );
+
+ $mech->get_ok('/dashboard');
+ $res = $categories->scrape( $mech->content );
+
+ foreach my $row ( keys %{ $test->{counts} } ) {
+ check_row( $res, $row, $test->{counts}->{$row} );
+ }
+ };
+ }
+
+ delete_problems();
+
+ for my $test (
+ {
+ desc => 'Selecting no category does nothing',
+ p1 => {
+ state => 'confirmed',
+ conf_dt => DateTime->now(),
+ category => 'Potholes',
+ },
+ p2 => {
+ state => 'confirmed',
+ conf_dt => DateTime->now(),
+ category => 'Litter',
+ },
+ category => '',
+ counts => {
+ totals => [2,2,2,2],
+ },
+ counts_after => {
+ totals => [2,2,2,2],
+ },
+ report_counts => [2,0,0],
+ report_counts_after => [2,0,0],
},
- counts_after => {
- user => [0,0,1,1],
- council => [0,0,1,1],
- totals => [1,1,3,3],
+ {
+ desc => 'Limit display by category',
+ category => 'Potholes',
+ counts => {
+ totals => [2,2,2,2],
+ },
+ counts_after => {
+ totals => [1,1,1,1],
+ },
+ report_counts => [2,0,0],
+ report_counts_after => [1,0,0],
},
- report_counts => [2,4,0],
- report_counts_after => [1,2,0],
- },
- {
- desc => 'Limit display by ward',
- p1 => {
- state => 'confirmed',
- conf_dt => DateTime->now()->subtract( weeks => 1 ),
- category => 'Potholes',
- # in real life it has commas around it and the search
- # uses them
- areas => ',20720,',
+ {
+ desc => 'Limit display for category with no entries',
+ category => 'Grafitti',
+ counts => {
+ totals => [2,2,2,2],
+ },
+ counts_after => {
+ totals => [0,0,0,0],
+ },
+ report_counts => [2,0,0],
+ report_counts_after => [0,0,0],
},
- p2 => {
- state => 'fixed - council',
- conf_dt => DateTime->now()->subtract( weeks => 1 ),
- mark_dt => DateTime->now()->subtract( weeks => 1 ),
- category => 'Litter',
- areas => ',20720,',
+ {
+ desc => 'Limit display by category for council fixed',
+ p1 => {
+ state => 'fixed - council',
+ conf_dt => DateTime->now()->subtract( weeks => 1 ),
+ mark_dt => DateTime->now()->subtract( weeks => 1 ),
+ category => 'Potholes',
+ },
+ p2 => {
+ state => 'fixed - council',
+ conf_dt => DateTime->now()->subtract( weeks => 1 ),
+ mark_dt => DateTime->now()->subtract( weeks => 1 ),
+ category => 'Litter',
+ },
+ category => 'Potholes',
+ counts => {
+ council => [0,0,2,2],
+ totals => [2,2,4,4],
+ },
+ counts_after => {
+ council => [0,0,1,1],
+ totals => [1,1,2,2],
+ },
+ report_counts => [2,2,0],
+ report_counts_after => [1,1,0],
},
- ward => 20720,
- counts => {
- user => [0,0,2,2],
- council => [0,0,3,3],
- totals => [2,2,8,8],
+ {
+ desc => 'Limit display by category for user fixed',
+ p1 => {
+ state => 'fixed - user',
+ conf_dt => DateTime->now()->subtract( weeks => 1 ),
+ mark_dt => DateTime->now()->subtract( weeks => 1 ),
+ category => 'Potholes',
+ },
+ p2 => {
+ state => 'fixed - user',
+ conf_dt => DateTime->now()->subtract( weeks => 1 ),
+ mark_dt => DateTime->now()->subtract( weeks => 1 ),
+ category => 'Litter',
+ },
+ category => 'Potholes',
+ counts => {
+ user => [0,0,2,2],
+ council => [0,0,2,2],
+ totals => [2,2,6,6],
+ },
+ counts_after => {
+ user => [0,0,1,1],
+ council => [0,0,1,1],
+ totals => [1,1,3,3],
+ },
+ report_counts => [2,4,0],
+ report_counts_after => [1,2,0],
},
- counts_after => {
- user => [0,0,0,0],
- council => [0,0,1,1],
- totals => [0,0,2,2],
+ {
+ desc => 'Limit display by ward',
+ p1 => {
+ state => 'confirmed',
+ conf_dt => DateTime->now()->subtract( weeks => 1 ),
+ category => 'Potholes',
+ # in real life it has commas around it and the search
+ # uses them
+ areas => ',20720,',
+ },
+ p2 => {
+ state => 'fixed - council',
+ conf_dt => DateTime->now()->subtract( weeks => 1 ),
+ mark_dt => DateTime->now()->subtract( weeks => 1 ),
+ category => 'Litter',
+ areas => ',20720,',
+ },
+ ward => 20720,
+ counts => {
+ user => [0,0,2,2],
+ council => [0,0,3,3],
+ totals => [2,2,8,8],
+ },
+ counts_after => {
+ user => [0,0,0,0],
+ council => [0,0,1,1],
+ totals => [0,0,2,2],
+ },
+ report_counts => [2,6,0],
+ report_counts_after => [0,2,0],
},
- report_counts => [2,6,0],
- report_counts_after => [0,2,0],
- },
-) {
- subtest $test->{desc} => sub {
- make_problem( $test->{p1} ) if $test->{p1};
- make_problem( $test->{p2} ) if $test->{p2};
+ ) {
+ subtest $test->{desc} => sub {
+ make_problem( $test->{p1} ) if $test->{p1};
+ make_problem( $test->{p2} ) if $test->{p2};
- $mech->get_ok('/dashboard');
+ $mech->get_ok('/dashboard');
- $res = $categories->scrape( $mech->content );
+ $res = $categories->scrape( $mech->content );
- foreach my $row ( keys %{ $test->{counts} } ) {
- check_row( $res, $row, $test->{counts}->{$row} );
- }
+ foreach my $row ( keys %{ $test->{counts} } ) {
+ check_row( $res, $row, $test->{counts}->{$row} );
+ }
- check_report_counts( $res, $test->{report_counts} );
+ check_report_counts( $res, $test->{report_counts} );
- $mech->submit_form_ok( {
- with_fields => {
- category => $test->{category},
- ward => $test->{ward},
- }
- } );
+ $mech->submit_form_ok( {
+ with_fields => {
+ category => $test->{category},
+ ward => $test->{ward},
+ }
+ } );
- $res = $categories->scrape( $mech->content );
+ $res = $categories->scrape( $mech->content );
- foreach my $row ( keys %{ $test->{counts_after} } ) {
- check_row( $res, $row, $test->{counts_after}->{$row} );
- }
- check_report_counts( $res, $test->{report_counts_after} );
- };
-}
+ foreach my $row ( keys %{ $test->{counts_after} } ) {
+ check_row( $res, $row, $test->{counts_after}->{$row} );
+ }
+ check_report_counts( $res, $test->{report_counts_after} );
+ };
+ }
-delete_problems();
+ delete_problems();
-for my $test (
- {
- desc => 'Selecting no state does nothing',
- p1 => {
- state => 'fixed - user',
- conf_dt => DateTime->now(),
- category => 'Potholes',
+ for my $test (
+ {
+ desc => 'Selecting no state does nothing',
+ p1 => {
+ state => 'fixed - user',
+ conf_dt => DateTime->now(),
+ category => 'Potholes',
+ },
+ p2 => {
+ state => 'confirmed',
+ conf_dt => DateTime->now(),
+ category => 'Litter',
+ },
+ state => '',
+ report_counts => [2,0,0],
+ report_counts_after => [2,0,0],
},
- p2 => {
- state => 'confirmed',
- conf_dt => DateTime->now(),
- category => 'Litter',
+ {
+ desc => 'limit by state works',
+ state => 'fixed',
+ report_counts => [2,0,0],
+ report_counts_after => [1,0,0],
},
- state => '',
- report_counts => [2,0,0],
- report_counts_after => [2,0,0],
- },
- {
- desc => 'limit by state works',
- state => 'fixed',
- report_counts => [2,0,0],
- report_counts_after => [1,0,0],
- },
- {
- desc => 'All fixed states count as fixed',
- p1 => {
- state => 'fixed - council',
- conf_dt => DateTime->now(),
- category => 'Potholes',
+ {
+ desc => 'planned counted as action scheduled',
+ p1 => {
+ state => 'planned',
+ conf_dt => DateTime->now(),
+ category => 'Potholes',
+ },
+ state => 'action scheduled',
+ report_counts => [3,0,0],
+ report_counts_after => [1,0,0],
},
- p2 => {
- state => 'fixed',
- conf_dt => DateTime->now(),
- category => 'Potholes',
+ {
+ desc => 'All fixed states count as fixed',
+ p1 => {
+ state => 'fixed - council',
+ conf_dt => DateTime->now(),
+ category => 'Potholes',
+ },
+ p2 => {
+ state => 'fixed',
+ conf_dt => DateTime->now(),
+ category => 'Potholes',
+ },
+ state => 'fixed',
+ report_counts => [5,0,0],
+ report_counts_after => [3,0,0],
},
- state => 'fixed',
- report_counts => [4,0,0],
- report_counts_after => [3,0,0],
- },
-) {
- subtest $test->{desc} => sub {
- make_problem( $test->{p1} ) if $test->{p1};
- make_problem( $test->{p2} ) if $test->{p2};
+ ) {
+ subtest $test->{desc} => sub {
+ make_problem( $test->{p1} ) if $test->{p1};
+ make_problem( $test->{p2} ) if $test->{p2};
- $mech->get_ok('/dashboard');
+ $mech->get_ok('/dashboard');
- $res = $categories->scrape( $mech->content );
+ $res = $categories->scrape( $mech->content );
- check_report_counts( $res, $test->{report_counts} );
+ check_report_counts( $res, $test->{report_counts} );
- $mech->submit_form_ok( {
- with_fields => {
- state => $test->{state},
- }
- } );
+ $mech->submit_form_ok( {
+ with_fields => {
+ state => $test->{state},
+ }
+ } );
- $res = $categories->scrape( $mech->content );
+ $res = $categories->scrape( $mech->content );
- check_report_counts( $res, $test->{report_counts_after} );
+ check_report_counts( $res, $test->{report_counts_after} );
+ };
+ }
+
+ subtest 'export as csv' => sub {
+ make_problem( {
+ detail => "this report\nis split across\nseveral lines",
+ state => "confirmed",
+ conf_dt => DateTime->now(),
+ } );
+ $mech->get_ok('/dashboard?export=1');
+ open my $data_handle, '<', \$mech->content;
+ my $csv = Text::CSV->new( { binary => 1 } );
+ my @rows;
+ while ( my $row = $csv->getline( $data_handle ) ) {
+ push @rows, $row;
+ }
+ is scalar @rows, 7, '1 (header) + 6 (reports) = 7 lines';
};
-}
+};
+restore_time;
sub make_problem {
my $args = shift;
@@ -573,12 +628,12 @@ sub make_problem {
title => 'a problem',
name => 'a user',
anonymous => 1,
- detail => 'some detail',
+ detail => $args->{detail} || 'some detail',
state => $args->{state},
confirmed => $args->{conf_dt},
whensent => $args->{conf_dt},
lastupdate => $args->{mark_dt} || $args->{conf_dt},
- council => $test_council,
+ bodies_str => $body->id,
postcode => 'EH99 1SP',
latitude => '51',
longitude => '1',
@@ -632,10 +687,10 @@ sub check_report_counts {
sub delete_problems {
FixMyStreet::App->model('DB::Comment')
- ->search( { 'problem.council' => $test_council }, { join => 'problem' } )
+ ->search( { 'problem.bodies_str' => $body->id }, { join => 'problem' } )
->delete;
FixMyStreet::App->model('DB::Problem')
- ->search( { council => $test_council } )->delete();
+ ->search( { bodies_str => $body->id } )->delete();
}
done_testing;
diff --git a/t/app/controller/index.t b/t/app/controller/index.t
index 462b21064..6b28a03d2 100644
--- a/t/app/controller/index.t
+++ b/t/app/controller/index.t
@@ -12,7 +12,6 @@ subtest "check that the form goes to /around" => sub {
$mech->get_ok('/');
is $mech->uri->path, '/', "still on '/'";
- # submit form
$mech->submit_form_ok( { with_fields => { pc => 'SW1A 1AA', } } );
# check that we are at /around
@@ -47,7 +46,11 @@ subtest "does pc, (x,y), (e,n) or (lat,lon) go to /around" => sub {
$uri->query_form( $test->{in} );
# get the uri and check for 302
- $mech->get_ok($uri);
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok($uri);
+ };
# check that we are at /around
is $mech->uri->path, '/around', "Got to /around";
@@ -55,12 +58,10 @@ subtest "does pc, (x,y), (e,n) or (lat,lon) go to /around" => sub {
}
};
-$mech->delete_problems_for_council( 2651 );
-
my $problem_rs = FixMyStreet::App->model('DB::Problem');
my $num = $problem_rs->count;
-my @edinburgh_problems = $mech->create_problems_for_council(5, 2651, 'Front page');
+my @edinburgh_problems = $mech->create_problems_for_body(5, 2651, 'Front page');
is scalar @edinburgh_problems, 5, 'correct number of edinburgh problems created';
$mech->get_ok('/report/' . $edinburgh_problems[2]->id);
@@ -74,4 +75,24 @@ ok $mech->get('/report/' . $edinburgh_problems[2]->id);
is $mech->res->code, 403, 'page forbidden';
is $problem_rs->count, $num+5;
-done_testing();
+my $oxon = $mech->create_body_ok(2237, 'Oxfordshire County Council', id => 2237);
+subtest "prefilters /around if user has categories" => sub {
+ my $user = $mech->log_in_ok('test@example.com');
+ my $categories = [
+ $mech->create_contact_ok( body_id => $oxon->id, category => 'Cows', email => 'cows@example.net' )->id,
+ $mech->create_contact_ok( body_id => $oxon->id, category => 'Potholes', email => 'potholes@example.net' )->id,
+ ];
+ $user->from_body($oxon);
+ $user->set_extra_metadata('categories', $categories);
+ $user->update;
+
+ $mech->get_ok('/');
+ # NB can't use visible_form_values because categories field is hidden
+ $mech->content_contains("Cows,Potholes");
+};
+
+END {
+ $mech->delete_problems_for_body( 2651 );
+ $mech->delete_body($oxon);
+ done_testing();
+}
diff --git a/t/app/controller/json.t b/t/app/controller/json.t
index 468fa5b31..b2cea674f 100644
--- a/t/app/controller/json.t
+++ b/t/app/controller/json.t
@@ -45,9 +45,11 @@ is_deeply #
# put an entry in the database for this test
my $user = $mech->create_user_ok('test@example.com');
+my $body = $mech->create_body_ok(2501, 'Wandsworth Borough Council');
+
my $problem_args = {
postcode => 'sw1a 1aa',
- council => '2501',
+ bodies_str => $body->id,
areas => ',105164,11806,11827,2247,2501,34817,42011,66045,70786,8519,',
category => 'test category',
title => 'Test title',
@@ -86,7 +88,7 @@ is_deeply #
'category' => 'test category',
'confirmed' => '2000-01-01 12:01:00',
'lastupdate' => '2000-01-01 12:00:00',
- 'council' => 'Wandsworth Borough Council',
+ 'bodies_str' => 'Wandsworth Borough Council',
'detail' => 'Test detail',
'id' => $problem->id,
'name' => 'Test Name',
@@ -103,7 +105,7 @@ is_deeply #
'category' => 'test category',
'confirmed' => '2000-01-01 12:02:00',
'lastupdate' => '2000-01-01 12:00:00',
- 'council' => 'Wandsworth Borough Council',
+ 'bodies_str' => 'Wandsworth Borough Council',
'detail' => 'Test detail',
'id' => $anon_problem->id,
'name' => '',
diff --git a/t/app/controller/moderate.t b/t/app/controller/moderate.t
new file mode 100644
index 000000000..10287ab22
--- /dev/null
+++ b/t/app/controller/moderate.t
@@ -0,0 +1,358 @@
+use strict;
+use warnings;
+use Test::More;
+use utf8;
+
+use FixMyStreet::TestMech;
+use FixMyStreet::App;
+use Data::Dumper;
+
+my $mech = FixMyStreet::TestMech->new;
+$mech->host('www.example.org');
+
+my $BROMLEY_ID = 2482;
+my $body = $mech->create_body_ok( $BROMLEY_ID, 'Bromley Council' );
+
+my $dt = DateTime->now;
+
+my $user = $mech->create_user_ok('test-moderation@example.com', name => 'Test User');
+$user->user_body_permissions->delete_all;
+$user->discard_changes;
+
+my $user2 = $mech->create_user_ok('test-moderation2@example.com', name => 'Test User 2');
+
+sub create_report {
+ FixMyStreet::App->model('DB::Problem')->create(
+ {
+ postcode => 'BR1 3SB',
+ bodies_str => $body->id,
+ areas => ",$BROMLEY_ID,",
+ category => 'Other',
+ title => 'Good bad good',
+ detail => 'Good bad bad bad good bad',
+ used_map => 't',
+ name => 'Test User 2',
+ anonymous => 'f',
+ state => 'confirmed',
+ confirmed => $dt->ymd . ' ' . $dt->hms,
+ lang => 'en-gb',
+ service => '',
+ cobrand => 'default',
+ cobrand_data => '',
+ send_questionnaire => 't',
+ latitude => '51.4129',
+ longitude => '0.007831',
+ user_id => $user2->id,
+ photo => $mech->get_photo_data,
+ });
+}
+my $report = create_report();
+my $report2 = create_report();
+
+my $REPORT_URL = '/report/' . $report->id ;
+
+subtest 'Auth' => sub {
+
+ subtest 'Unaffiliated user cannot see moderation' => sub {
+ $mech->get_ok($REPORT_URL);
+ $mech->content_lacks('Moderat');
+
+ $mech->log_in_ok( $user->email );
+
+ $mech->get_ok($REPORT_URL);
+ $mech->content_lacks('Moderat');
+
+ $user->update({ from_body => $body->id });
+
+ $mech->get_ok($REPORT_URL);
+ $mech->content_lacks('Moderat');
+
+ $mech->get('/contact?m=1&id=' . $report->id);
+ is $mech->res->code, 400;
+ $mech->content_lacks('Good bad bad bad');
+ };
+
+ subtest 'Affiliated and permissioned user can see moderation' => sub {
+ # login and from_body are done in previous test.
+ $user->user_body_permissions->create({
+ body => $body,
+ permission_type => 'moderate',
+ });
+
+ $mech->get_ok($REPORT_URL);
+ $mech->content_contains('Moderat');
+ };
+};
+
+my %problem_prepopulated = (
+ problem_show_name => 1,
+ problem_show_photo => 1,
+ problem_title => 'Good bad good',
+ problem_detail => 'Good bad bad bad good bad',
+);
+
+subtest 'Problem moderation' => sub {
+
+ subtest 'Post modify title and text' => sub {
+ $mech->get_ok($REPORT_URL);
+ $mech->submit_form_ok({ with_fields => {
+ %problem_prepopulated,
+ problem_title => 'Good good',
+ problem_detail => 'Good good improved',
+ }});
+ $mech->base_like( qr{\Q$REPORT_URL\E} );
+ $mech->content_like(qr/Moderated by Bromley Council/);
+
+ $report->discard_changes;
+ is $report->title, 'Good [...] good';
+ is $report->detail, 'Good [...] good [...]improved';
+ };
+
+ subtest 'Revert title and text' => sub {
+ $mech->submit_form_ok({ with_fields => {
+ %problem_prepopulated,
+ problem_revert_title => 1,
+ problem_revert_detail => 1,
+ }});
+ $mech->base_like( qr{\Q$REPORT_URL\E} );
+
+ $report->discard_changes;
+ is $report->title, 'Good bad good';
+ is $report->detail, 'Good bad bad bad good bad';
+ };
+
+ subtest 'Make anonymous' => sub {
+ $mech->content_lacks('Reported anonymously');
+
+ $mech->submit_form_ok({ with_fields => {
+ %problem_prepopulated,
+ problem_show_name => 0,
+ }});
+ $mech->base_like( qr{\Q$REPORT_URL\E} );
+
+ $mech->content_contains('Reported anonymously');
+
+ $mech->submit_form_ok({ with_fields => {
+ %problem_prepopulated,
+ problem_show_name => 1,
+ }});
+ $mech->base_like( qr{\Q$REPORT_URL\E} );
+
+ $mech->content_lacks('Reported anonymously');
+ };
+
+ subtest 'Hide photo' => sub {
+ $mech->content_contains('Photo of this report');
+
+ $mech->submit_form_ok({ with_fields => {
+ %problem_prepopulated,
+ problem_show_photo => 0,
+ }});
+ $mech->base_like( qr{\Q$REPORT_URL\E} );
+
+ $mech->content_lacks('Photo of this report');
+
+ $mech->submit_form_ok({ with_fields => {
+ %problem_prepopulated,
+ problem_show_photo => 1,
+ }});
+ $mech->base_like( qr{\Q$REPORT_URL\E} );
+
+ $mech->content_contains('Photo of this report');
+ };
+
+ subtest 'Hide report' => sub {
+ $mech->clear_emails_ok;
+
+ $mech->submit_form_ok({ with_fields => {
+ %problem_prepopulated,
+ problem_hide => 1,
+ }});
+ $mech->base_unlike( qr{/report/}, 'redirected to front page' );
+
+ $report->discard_changes;
+ is $report->state, 'hidden', 'Is hidden';
+
+ my $email = $mech->get_email;
+ is $email->header('To'), '"Test User 2" <test-moderation2@example.com>', 'Sent to correct email';
+ my $url = $mech->get_link_from_email($email);
+ ok $url, "extracted complain url '$url'";
+
+ $mech->get_ok($url);
+ $mech->content_contains('Good bad bad bad');
+
+ # reset
+ $report->update({ state => 'confirmed' });
+ };
+};
+
+$mech->content_lacks('Posted anonymously', 'sanity check');
+
+subtest 'Problem 2' => sub {
+ my $REPORT2_URL = '/report/' . $report2->id ;
+ $mech->get_ok($REPORT2_URL);
+ $mech->submit_form_ok({ with_fields => {
+ %problem_prepopulated,
+ problem_title => 'Good good',
+ problem_detail => 'Good good improved',
+ }});
+ $mech->base_like( qr{\Q$REPORT2_URL\E} );
+
+ $report2->discard_changes;
+ is $report2->title, 'Good [...] good';
+ is $report2->detail, 'Good [...] good [...]improved';
+
+ $mech->submit_form_ok({ with_fields => {
+ %problem_prepopulated,
+ problem_revert_title => 1,
+ problem_revert_detail => 1,
+ }});
+ $mech->base_like( qr{\Q$REPORT2_URL\E} );
+
+ $report2->discard_changes;
+ is $report2->title, 'Good bad good';
+ is $report2->detail, 'Good bad bad bad good bad';
+};
+
+sub create_update {
+ $report->comments->create({
+ user => $user2,
+ name => 'Test User 2',
+ anonymous => 'f',
+ photo => $mech->get_photo_data,
+ text => 'update good good bad good',
+ state => 'confirmed',
+ mark_fixed => 0,
+ });
+}
+my %update_prepopulated = (
+ update_show_name => 1,
+ update_show_photo => 1,
+ update_detail => 'update good good bad good',
+);
+
+my $update = create_update();
+
+subtest 'updates' => sub {
+
+ subtest 'Update modify text' => sub {
+ $mech->get_ok($REPORT_URL);
+ $mech->submit_form_ok({ with_fields => {
+ %update_prepopulated,
+ update_detail => 'update good good good',
+ }}) or die $mech->content;
+ $mech->base_like( qr{\Q$REPORT_URL\E} );
+
+ $update->discard_changes;
+ is $update->text, 'update good good [...] good',
+ };
+
+ subtest 'Revert text' => sub {
+ $mech->submit_form_ok({ with_fields => {
+ %update_prepopulated,
+ update_revert_detail => 1,
+ }});
+ $mech->base_like( qr{\Q$REPORT_URL\E} );
+
+ $update->discard_changes;
+ $update->discard_changes;
+ is $update->text, 'update good good bad good',
+ };
+
+ subtest 'Make anonymous' => sub {
+ $mech->content_lacks('Posted anonymously')
+ or die sprintf '%d (%d)', $update->id, $report->comments->count;
+
+ $mech->submit_form_ok({ with_fields => {
+ %update_prepopulated,
+ update_show_name => 0,
+ }});
+ $mech->base_like( qr{\Q$REPORT_URL\E} );
+
+ $mech->content_contains('Posted anonymously');
+
+ $mech->submit_form_ok({ with_fields => {
+ %update_prepopulated,
+ update_show_name => 1,
+ }});
+ $mech->base_like( qr{\Q$REPORT_URL\E} );
+
+ $mech->content_lacks('Posted anonymously');
+ };
+
+ subtest 'Hide photo' => sub {
+ $report->update({ photo => undef }); # hide the main photo so we can just look for text in comment
+
+ $mech->get_ok($REPORT_URL);
+
+ $mech->content_contains('Photo of this report')
+ or die $mech->content;
+
+ $mech->submit_form_ok({ with_fields => {
+ %update_prepopulated,
+ update_show_photo => 0,
+ }});
+ $mech->base_like( qr{\Q$REPORT_URL\E} );
+
+ $mech->content_lacks('Photo of this report');
+
+ $mech->submit_form_ok({ with_fields => {
+ %update_prepopulated,
+ update_show_photo => 1,
+ }});
+ $mech->base_like( qr{\Q$REPORT_URL\E} );
+
+ $mech->content_contains('Photo of this report');
+ };
+
+ subtest 'Hide comment' => sub {
+ $mech->content_contains('update good good bad good');
+
+ $mech->submit_form_ok({ with_fields => {
+ %update_prepopulated,
+ update_hide => 1,
+ }});
+ $mech->content_lacks('update good good bad good');
+ };
+
+ $update->moderation_original_data->delete;
+};
+
+my $update2 = create_update();
+
+subtest 'Update 2' => sub {
+ $mech->get_ok($REPORT_URL);
+ $mech->submit_form_ok({ with_fields => {
+ %update_prepopulated,
+ update_detail => 'update good good good',
+ }}) or die $mech->content;
+
+ $update2->discard_changes;
+ is $update2->text, 'update good good [...] good',
+};
+
+subtest 'Now stop being a staff user' => sub {
+ $user->update({ from_body => undef });
+ $mech->get_ok($REPORT_URL);
+ $mech->content_contains('Moderated by Bromley Council');
+};
+
+subtest 'And do it as a superuser' => sub {
+ $user->update({ is_superuser => 1 });
+ $mech->get_ok($REPORT_URL);
+ $mech->submit_form_ok({ with_fields => {
+ %problem_prepopulated,
+ problem_title => 'Good good',
+ problem_detail => 'Good good improved',
+ }});
+ $mech->content_contains('Moderated by a FixMyStreet administrator');
+};
+
+$update->delete;
+$update2->delete;
+$report->moderation_original_data->delete;
+$report->delete;
+$report2->delete;
+$mech->delete_user($user);
+
+done_testing();
diff --git a/t/app/controller/my.t b/t/app/controller/my.t
index da509e8ed..00070ed81 100644
--- a/t/app/controller/my.t
+++ b/t/app/controller/my.t
@@ -1,7 +1,7 @@
use strict;
use warnings;
-use Test::More tests => 11;
+use Test::More;
use FixMyStreet::TestMech;
my $mech = FixMyStreet::TestMech->new;
@@ -9,11 +9,20 @@ my $mech = FixMyStreet::TestMech->new;
$mech->get_ok('/my');
is $mech->uri->path, '/auth', "got sent to the sign in page";
-# sign in
+$mech->create_problems_for_body(1, 1234, 'Test Title');
+my $other_user = FixMyStreet::DB->resultset('User')->find_or_create({ email => 'another@example.com' });
+$mech->create_problems_for_body(1, 1234, 'Another Title', { user => $other_user });
+
my $user = $mech->log_in_ok( 'test@example.com' );
$mech->get_ok('/my');
-is $mech->uri->path, '/my', "stayed on '/my/' page";
+is $mech->uri->path, '/my', "stayed on '/my' page";
+
+$mech->content_contains('Test Title');
+$mech->content_lacks('Another Title');
-# cleanup
-$mech->delete_user( $user );
+done_testing();
+END {
+ $mech->delete_user($user);
+ $mech->delete_user($other_user);
+}
diff --git a/t/app/controller/my_planned.t b/t/app/controller/my_planned.t
new file mode 100644
index 000000000..fa463e61e
--- /dev/null
+++ b/t/app/controller/my_planned.t
@@ -0,0 +1,64 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use FixMyStreet::TestMech;
+my $mech = FixMyStreet::TestMech->new;
+
+$mech->get_ok('/my/planned');
+is $mech->uri->path, '/auth', "got sent to the sign in page";
+
+my $body = $mech->create_body_ok(2237, 'Oxfordshire');
+my ($problem) = $mech->create_problems_for_body(1, $body->id, 'Test Title');
+
+$mech->get_ok($problem->url);
+$mech->content_lacks('Shortlist');
+$mech->content_lacks('Shortlisted');
+
+my $user = $mech->log_in_ok( 'test@example.com' );
+$user->update({ from_body => $body });
+$user->user_body_permissions->find_or_create({
+ body => $body,
+ permission_type => 'planned_reports',
+});
+
+$mech->get_ok('/my/planned');
+$mech->content_lacks('Test Title');
+
+$user->add_to_planned_reports($problem);
+$mech->get_ok('/my/planned');
+$mech->content_contains('Test Title');
+
+$user->remove_from_planned_reports($problem);
+$mech->get_ok('/my/planned');
+$mech->content_lacks('Test Title');
+
+$user->add_to_planned_reports($problem);
+$mech->get_ok('/my/planned');
+$mech->content_contains('Test Title');
+
+$mech->get_ok($problem->url);
+$mech->content_contains('Shortlisted');
+$mech->submit_form_ok({ with_fields => { 'shortlist-remove' => 1 } });
+$mech->content_contains('Shortlist');
+$mech->submit_form_ok({ with_fields => { 'shortlist-add' => 1 } });
+$mech->content_contains('Shortlisted');
+
+$mech->get_ok('/my/planned?sort=shortlist&ajax=1');
+$mech->content_contains('shortlist-up');
+$mech->content_contains('shortlist-down');
+
+$mech->get_ok('/my/planned?sort=created-desc&ajax=1');
+$mech->content_lacks('shortlist-up');
+$mech->content_lacks('shortlist-down');
+
+$mech->get_ok('/my/planned?ajax=1');
+$mech->content_contains('shortlist-up');
+$mech->content_contains('shortlist-down');
+
+done_testing();
+
+END {
+ $mech->delete_user($user);
+}
diff --git a/t/app/controller/page_not_found.t b/t/app/controller/page_not_found.t
index 05e983109..3c2bc3c3d 100644
--- a/t/app/controller/page_not_found.t
+++ b/t/app/controller/page_not_found.t
@@ -1,5 +1,3 @@
-#!/usr/bin/perl
-
use strict;
use warnings;
diff --git a/t/app/controller/photo.t b/t/app/controller/photo.t
new file mode 100644
index 000000000..ad857b5e3
--- /dev/null
+++ b/t/app/controller/photo.t
@@ -0,0 +1,79 @@
+use strict;
+use utf8; # sign in error message has &ndash; 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.uk/',
+ 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->get_ok('/report/new?lat=53.4031156&lon=-2.9840579');
+ my ($csrf) = $mech->content =~ /name="token" value="([^"]*)"/;
+
+ $mech->post( '/report/new',
+ Content_Type => 'form-data',
+ Content =>
+ {
+ submit_problem => 1,
+ token => $csrf,
+ 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',
+ }
+ );
+ ok $mech->success, 'Made request with multiple photo upload';
+ $mech->base_is('http://localhost/report/new');
+ $mech->content_like(
+ qr[(<img align="right" src="/photo/temp.74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg" alt="">\s*){3}],
+ 'Three uploaded pictures are all shown, safe');
+ $mech->content_contains(
+ 'name="upload_fileid" value="74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg,74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg,74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg"',
+ 'Returned upload_fileid contains expected hash, 3 times');
+ my $image_file = path($UPLOAD_DIR, '74e3362283b6ef0c48686fb0e161da4043bbcc97.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 3a6a3d6ad..f42908a3e 100644
--- a/t/app/controller/questionnaire.t
+++ b/t/app/controller/questionnaire.t
@@ -17,10 +17,7 @@ $mech->clear_emails_ok;
# create a test user and report
$mech->delete_user('test@example.com');
-my $user =
- FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'test@example.com', name => 'Test User' } );
-ok $user, "created test user";
+my $user = $mech->create_user_ok('test@example.com', name => 'Test User');
my $dt = DateTime->now()->subtract( weeks => 5 );
my $report_time = $dt->ymd . ' ' . $dt->hms;
@@ -30,7 +27,7 @@ my $sent_time = $sent->ymd . ' ' . $sent->hms;
my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
{
postcode => 'EH1 1BB',
- council => '2651',
+ bodies_str => '2651',
areas => ',11808,135007,14419,134935,2651,20728,',
category => 'Street lighting',
title => 'Testing',
@@ -61,12 +58,14 @@ FixMyStreet::App->model('DB::Questionnaire')->send_questionnaires( {
} );
my $email = $mech->get_email;
ok $email, "got an email";
-like $email->body, qr/fill in our short questionnaire/i, "got questionnaire email";
+my $plain = $mech->get_text_body_from_email($email, 1);
+like $plain->body, qr/fill in our short questionnaire/i, "got questionnaire email";
-like $email->body, qr/Testing =96 Detail/, 'email contains encoded character';
-is $email->header('Content-Type'), 'text/plain; charset="windows-1252"', 'in the right character set';
+like $plain->body_str, qr/Testing \x{2013} Detail/, 'email contains encoded character';
+is $plain->header('Content-Type'), 'text/plain; charset="utf-8"', 'in the right character set';
-my ($token) = $email->body =~ m{http://.*?/Q/(\S+)};
+my $url = $mech->get_link_from_email($email);
+my ($token) = $url =~ m{/Q/(\S+)};
ok $token, "extracted questionnaire token '$token'";
$mech->clear_emails_ok;
@@ -87,17 +86,20 @@ foreach my $test (
{
desc => 'User goes to questionnaire URL with a bad token',
token_extra => 'BAD',
- content => "we couldn't validate that token",
+ content => "Sorry, that wasn&rsquo;t a valid link",
+ code => 400,
},
{
desc => 'User goes to questionnaire URL for a now-hidden problem',
state => 'hidden',
content => "we couldn't locate your problem",
+ code => 400,
},
{
desc => 'User goes to questionnaire URL for an already answered questionnaire',
- answered => \'ms_current_timestamp()',
+ answered => \'current_timestamp',
content => 'already answered this questionnaire',
+ code => 400,
},
) {
subtest $test->{desc} => sub {
@@ -107,7 +109,8 @@ foreach my $test (
$questionnaire->update;
(my $token = $token->token);
$token .= $test->{token_extra} if $test->{token_extra};
- $mech->get_ok("/Q/$token");
+ $mech->get("/Q/$token");
+ is $mech->res->code, $test->{code}, "Right status received";
$mech->content_contains( $test->{content} );
# Reset, no matter what test did
$report->state( 'confirmed' );
@@ -191,6 +194,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 => {
@@ -252,13 +265,13 @@ foreach my $test (
# Check the right HTML page has been returned
$mech->content_like( qr/<title>[^<]*Questionnaire/m );
- $mech->content_contains( 'glad to hear it&rsquo;s been fixed' )
+ $mech->content_contains( 'Glad to hear' )
if $result =~ /fixed/;
- $mech->content_lacks( 'glad to hear it&rsquo;s been fixed' )
+ $mech->content_lacks( 'Glad to hear' )
if $result !~ /fixed/;
$mech->content_contains( 'get some more information about the status of your problem' )
if $result eq 'unknown';
- $mech->content_contains( "sorry to hear that" )
+ $mech->content_contains( "sorry to hear" )
if $result eq 'confirmed' || $result eq 'closed';
# Check the database has the right information
@@ -266,7 +279,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,11 +328,11 @@ 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' );
};
-for my $test (
+for my $test (
{
state => 'confirmed',
fixed => 0
@@ -329,6 +342,10 @@ for my $test (
fixed => 0
},
{
+ state => 'action scheduled',
+ fixed => 0
+ },
+ {
state => 'in progress',
fixed => 0
},
@@ -337,6 +354,18 @@ for my $test (
fixed => 0
},
{
+ state => 'duplicate',
+ fixed => 0
+ },
+ {
+ state => 'not responsible',
+ fixed => 0
+ },
+ {
+ state => 'unable to fix',
+ fixed => 0
+ },
+ {
state => 'closed',
fixed => 0
},
@@ -367,32 +396,25 @@ for my $test (
};
}
-SKIP: {
- skip( "Need 'emptyhomes' in ALLOWED_COBRANDS config", 18 )
- unless FixMyStreet::Cobrand->exists('emptyhomes');
-
- # EHA extra checking
- ok $mech->host("reportemptyhomes.com"), 'change host to reportemptyhomes';
-
- # Reset, and all the questionaire sending function - FIXME should it detect site itself somehow?
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fixmystreet' ],
+}, sub {
+ $report->discard_changes;
$report->send_questionnaire( 1 );
$report->update;
$questionnaire->delete;
- FixMyStreet::App->model('DB::Questionnaire')->send_questionnaires( {
- site => 'emptyhomes'
- } );
- $email = $mech->get_email;
- ok $email, "got an email";
- $mech->clear_emails_ok;
+ FixMyStreet::App->model('DB::Questionnaire')->send_questionnaires();
- like $email->body, qr/fill in this short questionnaire/i, "got questionnaire email";
- ($token) = $email->body =~ m{http://.*?/Q/(\S+)};
+ my $email = $mech->get_email;
+ my $body = $mech->get_text_body_from_email($email);
+ $mech->clear_emails_ok;
+ $body =~ s/\s+/ /g;
+ like $body, qr/fill in our short questionnaire/i, "got questionnaire email";
+ my $url = $mech->get_link_from_email($email);
+ ($token) = $url =~ m{/Q/(\S+)};
ok $token, "extracted questionnaire token '$token'";
- $mech->get_ok("/Q/" . $token);
- $mech->content_contains( 'should have reported what they have done' );
-
# Test already answered the ever reported question, so not shown again
$dt = $dt->add( weeks => 4 );
my $questionnaire2 = FixMyStreet::App->model('DB::Questionnaire')->find_or_create(
@@ -403,43 +425,38 @@ SKIP: {
}
);
ok $questionnaire2, 'added another questionnaire';
- ok $mech->host("fixmystreet.com"), 'change host to fixmystreet';
$mech->get_ok("/Q/" . $token);
$mech->title_like( qr/Questionnaire/ );
$mech->content_contains( 'Has this problem been fixed?' );
$mech->content_lacks( 'ever reported' );
- # EHA extra checking
- ok $mech->host("reportemptyhomes.com"), 'change host to reportemptyhomes';
- $mech->get_ok("/Q/" . $token);
- $mech->content_contains( 'made a lot of progress' );
-
$token = FixMyStreet::App->model("DB::Token")->find( { scope => 'questionnaire', token => $token } );
ok $token, 'found token for questionnaire';
$questionnaire = FixMyStreet::App->model('DB::Questionnaire')->find( { id => $token->data } );
ok $questionnaire, 'found questionnaire';
$questionnaire2->delete;
-}
-
-SKIP: {
- skip( "Need 'fiksgatami' in ALLOWED_COBRANDS config", 5 )
- unless FixMyStreet::Cobrand->exists('fiksgatami');
+};
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fiksgatami' ],
+}, sub {
# I18N Unicode extra testing using FiksGataMi
+ $report->discard_changes;
$report->send_questionnaire( 1 );
$report->cobrand( 'fiksgatami' );
$report->update;
$questionnaire->delete;
- FixMyStreet::App->model('DB::Questionnaire')->send_questionnaires( { site => 'fixmystreet' } ); # It's either fixmystreet or emptyhomes
+ FixMyStreet::App->model('DB::Questionnaire')->send_questionnaires();
$email = $mech->get_email;
ok $email, "got an email";
$mech->clear_emails_ok;
- like $email->body, qr/Testing =96 Detail/, 'email contains encoded character from user';
- like $email->body, qr/sak p=E5 FiksGataMi/, 'email contains encoded character from template';
- is $email->header('Content-Type'), 'text/plain; charset="windows-1252"', 'email is in right encoding';
-}
+ my $plain = $mech->get_text_body_from_email($email, 1);
+ like $plain->body_str, qr/Testing \x{2013} Detail/, 'email contains encoded character from user';
+ like $plain->body_str, qr/sak p\xe5 FiksGataMi/, 'email contains encoded character from template';
+ is $plain->header('Content-Type'), 'text/plain; charset="utf-8"', 'email is in right encoding';
+};
$mech->delete_user('test@example.com');
done_testing();
diff --git a/t/app/controller/report_as_other.t b/t/app/controller/report_as_other.t
new file mode 100644
index 000000000..551a59481
--- /dev/null
+++ b/t/app/controller/report_as_other.t
@@ -0,0 +1,190 @@
+use strict;
+use warnings;
+use Test::More;
+
+use FixMyStreet::TestMech;
+use FixMyStreet::App;
+
+# disable info logs for this test run
+FixMyStreet::App->log->disable('info');
+END { FixMyStreet::App->log->enable('info'); }
+
+my $mech = FixMyStreet::TestMech->new;
+
+my $body = $mech->create_body_ok(2237, 'Oxfordshire County Council');
+my $contact1 = $mech->create_contact_ok( body_id => $body->id, category => 'Street lighting', email => 'highways@example.com' );
+my $contact2 = $mech->create_contact_ok( body_id => $body->id, category => 'Potholes', email => 'potholes@example.com' );
+
+my $test_email = 'body-user@example.net';
+my $user = $mech->log_in_ok($test_email);
+$user->update({ from_body => $body->id, name => 'Body User' });
+
+my ($report_to_update) = $mech->create_problems_for_body(1, $body->id, 'Title');
+
+subtest "Body user, no permissions, no special reporting tools shown" => sub {
+ start_report();
+ dropdown_shown(0);
+ start_update();
+ dropdown_shown(0, 'updateForm');
+};
+
+subtest "Body user, has permission to add report as council" => sub {
+ my $report = add_report(
+ 'contribute_as_body',
+ form_as => 'body',
+ title => "Test Report",
+ detail => 'Test report details.',
+ category => 'Street lighting',
+ );
+ is $report->name, 'Oxfordshire County Council', 'report name is body';
+ is $report->user->name, 'Body User', 'user name unchanged';
+ is $report->user->id, $user->id, 'user matches';
+ is $report->anonymous, 0, 'report not anonymous';
+};
+
+my @users;
+subtest "Body user, has permission to add report as another user" => sub {
+ my $report = add_report(
+ 'contribute_as_another_user',
+ form_as => 'another_user',
+ title => "Test Report",
+ detail => 'Test report details.',
+ category => 'Potholes',
+ name => 'Another User',
+ email => 'another@example.net',
+ );
+ is $report->name, 'Another User', 'report name is given name';
+ is $report->user->name, 'Another User', 'user name matches';
+ is $report->user->email, 'another@example.net', 'user email correct';
+ isnt $report->user->id, $user->id, 'user does not match';
+ like $mech->get_text_body_from_email, qr/Your report to Oxfordshire County Council has been logged/;
+ push @users, $report->user;
+};
+
+subtest "Body user, has permission to add report as another (existing) user" => sub {
+ $mech->create_user_ok('existing@example.net', name => 'Existing User');
+ my $report = add_report(
+ 'contribute_as_another_user',
+ form_as => 'another_user',
+ title => "Test Report",
+ detail => 'Test report details.',
+ category => 'Potholes',
+ name => 'Existing Yooser',
+ email => 'existing@example.net',
+ );
+ is $report->name, 'Existing Yooser', 'report name is given name';
+ is $report->user->name, 'Existing User', 'user name remains same';
+ is $report->user->email, 'existing@example.net', 'user email correct';
+ isnt $report->user->id, $user->id, 'user does not match';
+ like $mech->get_text_body_from_email, qr/Your report to Oxfordshire County Council has been logged/;
+ push @users, $report->user;
+};
+
+subtest "Body user, has permission to add update as council" => sub {
+ my $update = add_update(
+ 'contribute_as_body',
+ form_as => 'body',
+ update => 'Test Update',
+ );
+ is $update->name, 'Oxfordshire County Council', 'update name is body';
+ is $update->user->name, 'Body User', 'user name unchanged';
+ is $update->user->id, $user->id, 'user matches';
+ is $update->anonymous, 0, 'update not anonymous';
+};
+
+subtest "Body user, has permission to add update as another user" => sub {
+ my $update = add_update(
+ 'contribute_as_another_user',
+ form_as => 'another_user',
+ update => 'Test Update',
+ name => 'Another User',
+ rznvy => 'another2@example.net',
+ );
+ is $update->name, 'Another User', 'update name is given name';
+ is $update->user->name, 'Another User', 'user name matches';
+ is $update->user->email, 'another2@example.net', 'user email correct';
+ isnt $update->user->id, $user->id, 'user does not match';
+ like $mech->get_text_body_from_email, qr/Your update has been logged/;
+ push @users, $update->user;
+};
+
+subtest "Body user, has permission to add update as another (existing) user" => sub {
+ my $update = add_update(
+ 'contribute_as_another_user',
+ form_as => 'another_user',
+ update => 'Test Update',
+ name => 'Existing Yooser',
+ rznvy => 'existing@example.net',
+ );
+ is $update->name, 'Existing Yooser', 'update name is given name';
+ is $update->user->name, 'Existing User', 'user name remains same';
+ is $update->user->email, 'existing@example.net', 'user email correct';
+ isnt $update->user->id, $user->id, 'user does not match';
+ like $mech->get_text_body_from_email, qr/Your update has been logged/;
+};
+
+done_testing();
+
+END {
+ $mech->delete_body($body);
+ $mech->delete_user($_) for @users;
+}
+
+sub start_report {
+ my $permission = shift;
+ $_->delete for $user->user_body_permissions;
+ $user->user_body_permissions->create({ body => $body, permission_type => $permission })
+ if $permission;
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fixmystreet' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok('/report/new?latitude=51.7549262252&longitude=-1.25617899435');
+ };
+}
+
+sub add_report {
+ my ($permission, %fields) = @_;
+ start_report($permission);
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fixmystreet' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ dropdown_shown(1);
+ $mech->submit_form_ok({
+ with_fields => \%fields,
+ }, "submit details");
+ };
+ $mech->content_contains('Thank you for reporting this issue');
+ my $report = FixMyStreet::DB->resultset("Problem")->search(undef, { order_by => { -desc => 'id' } })->first;
+ ok $report, "Found the report";
+ is $report->state, 'confirmed', "report is now confirmed";
+ return $report;
+}
+
+sub start_update {
+ my $permission = shift;
+ $_->delete for $user->user_body_permissions;
+ $user->user_body_permissions->create({ body => $body, permission_type => $permission })
+ if $permission;
+ $mech->get_ok('/report/' . $report_to_update->id);
+}
+
+sub add_update {
+ my ($permission, %fields) = @_;
+ start_update($permission);
+ dropdown_shown(1, 'updateForm');
+ $mech->submit_form_ok({
+ with_fields => \%fields,
+ }, "submit details");
+ $mech->content_contains('Thank you for updating this issue');
+ my $update = FixMyStreet::DB->resultset("Comment")->search(undef, { order_by => { -desc => 'id' } })->first;
+ ok $update, "Found the update";
+ is $update->state, 'confirmed', "update is now confirmed";
+ return $update;
+}
+
+sub dropdown_shown {
+ my ($shown, $name) = @_;
+ is grep({ $_ eq 'form_as' } keys %{$mech->visible_form_values($name)}), $shown, "Dropdown shown = $shown";
+}
diff --git a/t/app/controller/report_display.t b/t/app/controller/report_display.t
index 39f1b59a7..b35a4a026 100644
--- a/t/app/controller/report_display.t
+++ b/t/app/controller/report_display.t
@@ -5,21 +5,16 @@ use Test::More;
use FixMyStreet::TestMech;
use Web::Scraper;
use Path::Class;
+use Test::LongString;
use DateTime;
my $mech = FixMyStreet::TestMech->new;
# create a test user and report
$mech->delete_user('test@example.com');
-my $user =
- FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'test@example.com', name => 'Test User' } );
-ok $user, "created test user";
+my $user = $mech->create_user_ok('test@example.com', name => 'Test User');
-my $user2 =
- FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'test2@example.com', name => 'Other User' } );
-ok $user2, "created test user";
+my $user2 = $mech->create_user_ok('test2@example.com', name => 'Other User');
my $dt = DateTime->new(
year => 2011,
@@ -30,31 +25,16 @@ my $dt = DateTime->new(
second => 23
);
-my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
- {
- postcode => 'SW1A 1AA',
- council => '2504',
- areas => ',105255,11806,11828,2247,2504,',
- category => 'Other',
- title => 'Test 2',
- detail => 'Test 2 Detail',
- used_map => 't',
- name => 'Test User',
- anonymous => 'f',
- state => 'confirmed',
- confirmed => $dt->ymd . ' ' . $dt->hms,
- lang => 'en-gb',
- service => '',
- cobrand => 'default',
- cobrand_data => '',
- send_questionnaire => 't',
- latitude => '51.5016605453401',
- longitude => '-0.142497580865087',
- user_id => $user->id,
- }
-);
+my $westminster = $mech->create_body_ok(2504, 'Westminster City Council');
+my ($report, $report2) = $mech->create_problems_for_body(2, $westminster->id, "Example", {
+ user => $user,
+ confirmed => $dt->ymd . ' ' . $dt->hms,
+});
+$report->update({
+ title => 'Test 2',
+ detail => 'Test 2 Detail'
+});
my $report_id = $report->id;
-ok $report, "created test report - $report_id";
subtest "check that no id redirects to homepage" => sub {
$mech->get_ok('/report');
@@ -94,6 +74,7 @@ subtest "change report to unconfirmed and check for 404 status" => sub {
ok $report->update( { state => 'confirmed' } ), 'confirm report again';
};
+
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'";
@@ -129,6 +110,22 @@ subtest "check owner of report can view non public reports" => sub {
ok $report->update( { non_public => 0 } ), 'make report public';
};
+subtest "duplicate reports are signposted correctly" => sub {
+ $report2->set_extra_metadata(duplicate_of => $report->id);
+ $report2->state('duplicate');
+ $report2->update;
+
+ my $report2_id = $report2->id;
+ ok $mech->get("/report/$report2_id"), "get '/report/$report2_id'";
+ $mech->content_contains('This report is a duplicate');
+ $mech->content_contains($report->title);
+ $mech->log_out_ok;
+
+ $report2->unset_extra_metadata('duplicate_of');
+ $report2->state('confirmed');
+ $report2->update;
+};
+
subtest "test a good report" => sub {
$mech->get_ok("/report/$report_id");
is $mech->uri->path, "/report/$report_id", "at /report/$report_id";
@@ -169,14 +166,14 @@ foreach my $meta (
category => '',
service => 'Transport service',
meta =>
-'Reported by Transport service by Test User at 15:47, Sat 16 April 2011'
+'Reported via Transport service by Test User at 15:47, Sat 16 April 2011'
},
{
anonymous => 'f',
category => 'Roads',
service => 'Transport service',
meta =>
-'Reported by Transport service in the Roads category by Test User at 15:47, Sat 16 April 2011'
+'Reported via Transport service in the Roads category by Test User at 15:47, Sat 16 April 2011'
},
{
anonymous => 't',
@@ -196,14 +193,14 @@ foreach my $meta (
category => '',
service => 'Transport service',
meta =>
-'Reported by Transport service anonymously at 15:47, Sat 16 April 2011'
+'Reported via Transport service anonymously at 15:47, Sat 16 April 2011'
},
{
anonymous => 't',
category => 'Roads',
service => 'Transport service',
meta =>
-'Reported by Transport service in the Roads category anonymously at 15:47, Sat 16 April 2011'
+'Reported via Transport service in the Roads category anonymously at 15:47, Sat 16 April 2011'
},
)
{
@@ -213,13 +210,13 @@ foreach my $meta (
$report->update;
subtest "test correct problem meta information" => sub {
$mech->get_ok("/report/$report_id");
-
+
is $mech->extract_problem_meta, $meta->{meta};
};
}
-for my $test (
+for my $test (
{
description => 'new report',
date => DateTime->now,
@@ -283,6 +280,38 @@ for my $test (
fixed => 1
},
{
+ description => 'duplicate report',
+ date => DateTime->now,
+ state => 'duplicate',
+ banner_id => 'closed',
+ banner_text => 'closed',
+ fixed => 0
+ },
+ {
+ description => 'not responsible report',
+ date => DateTime->now,
+ state => 'not responsible',
+ banner_id => 'closed',
+ banner_text => 'closed',
+ fixed => 0
+ },
+ {
+ description => 'unable to fix report',
+ date => DateTime->now,
+ state => 'unable to fix',
+ banner_id => 'closed',
+ banner_text => 'closed',
+ fixed => 0
+ },
+ {
+ description => 'internal referral report',
+ date => DateTime->now,
+ state => 'internal referral',
+ banner_id => 'closed',
+ banner_text => 'closed',
+ fixed => 0
+ },
+ {
description => 'closed report',
date => DateTime->now,
state => 'closed',
@@ -299,6 +328,14 @@ for my $test (
fixed => 0
},
{
+ description => 'action scheduled report',
+ date => DateTime->now,
+ state => 'action scheduled',
+ banner_id => 'progress',
+ banner_text => 'progress',
+ fixed => 0
+ },
+ {
description => 'planned report',
date => DateTime->now,
state => 'planned',
@@ -307,7 +344,7 @@ for my $test (
fixed => 0
},
{
- description => 'in progressreport',
+ description => 'in progress report',
date => DateTime->now,
state => 'in progress',
banner_id => 'progress',
@@ -345,30 +382,33 @@ for my $test (
};
}
-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 => 0,
+ from_body => undef,
no_state => 1,
- report_council => '2504',
+ report_body => $body_westminster->id,
},
{
desc => 'state dropdown if user from authority',
- from_body => 2504,
+ from_body => $body_westminster->id,
no_state => 0,
- report_council => '2504',
+ report_body => $body_westminster->id,
},
{
- desc => 'no state dropdown if user not from same council as problem',
- from_body => 2505,
+ desc => 'no state dropdown if user not from same body as problem',
+ from_body => $body_camden->id,
no_state => 1,
- report_council => '2504',
+ report_body => $body_westminster->id,
},
{
- desc => 'state dropdown if user from authority and problem sent to multiple councils',
- from_body => 2504,
+ desc => 'state dropdown if user from authority and problem sent to multiple bodies',
+ from_body => $body_westminster->id,
no_state => 0,
- report_council => '2504,2506',
+ report_body => $body_westminster->id . ',2506',
},
) {
subtest $test->{desc} => sub {
@@ -377,7 +417,7 @@ for my $test (
$user->update;
$report->discard_changes;
- $report->council( $test->{report_council} );
+ $report->bodies_str( $test->{report_body} );
$report->update;
$mech->get_ok("/report/$report_id");
@@ -390,10 +430,160 @@ for my $test (
};
}
-$report->discard_changes;
-$report->council( 2504 );
-$report->update;
+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( '&Uuml;berpr&uuml;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' );
-# tidy up
-$mech->delete_user('test@example.com');
-done_testing();
+ for my $test (
+ {
+ description => 'new report',
+ state => 'unconfirmed',
+ banner_id => 'closed',
+ banner_text => 'Erfasst'
+ },
+ {
+ description => 'confirmed report',
+ state => 'confirmed',
+ banner_id => 'closed',
+ banner_text => 'Aufgenommen',
+ },
+ {
+ description => 'fixed report',
+ state => 'fixed - council',
+ banner_id => 'fixed',
+ banner_text => 'Beantwortet',
+ },
+ {
+ description => 'closed report',
+ state => 'closed',
+ banner_id => 'closed',
+ banner_text => _('Extern'),
+ },
+ {
+ description => 'in progress report',
+ state => 'in progress',
+ banner_id => 'progress',
+ banner_text => 'In Bearbeitung',
+ },
+ {
+ description => 'planned report',
+ state => 'planned',
+ 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} );
+ $report->update;
+
+ $mech->get_ok("/report/$report_id");
+ is $mech->uri->path, "/report/$report_id", "at /report/$report_id";
+ my $banner = $mech->extract_problem_banner;
+ if ( $banner->{text} ) {
+ $banner->{text} =~ s/^ //g;
+ $banner->{text} =~ s/ $//g;
+ }
+
+ is $banner->{id}, $test->{banner_id}, 'banner id';
+ if ($test->{banner_text}) {
+ like_string( $banner->{text}, qr/$test->{banner_text}/i, 'banner text is ' . $test->{banner_text} );
+ } else {
+ is $banner->{text}, $test->{banner_text}, 'banner text';
+ }
+
+ };
+ }
+
+ $mech->host( 'www.fixmystreet.com' );
+ };
+};
+
+my $oxfordshire = $mech->create_body_ok(2237, 'Oxfordshire County Council', id => 2237);
+my $oxfordshireuser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $oxfordshire);
+
+subtest "check user details show when a user has correct permissions" => sub {
+ $report->update( {
+ name => 'Oxfordshire County Council',
+ user_id => $oxfordshireuser->id,
+ service => '',
+ anonymous => 'f',
+ bodies_str => $oxfordshire->id,
+ confirmed => '2012-01-10 15:17:00'
+ });
+
+ ok $oxfordshireuser->user_body_permissions->create({
+ body => $oxfordshire,
+ permission_type => 'view_body_contribute_details',
+ });
+
+ $mech->log_in_ok( $oxfordshireuser->email );
+ ok $mech->get("/report/$report_id"), "get '/report/$report_id'";
+ is $mech->extract_problem_meta,
+ 'Reported in the Roads category by Oxfordshire County Council (Council User) at 15:17, Tue 10 January 2012',
+ 'correct problem meta information';
+
+ ok $oxfordshireuser->user_body_permissions->delete_all, "Remove view_body_contribute_details permissions";
+
+ ok $mech->get("/report/$report_id"), "get '/report/$report_id'";
+ is $mech->extract_problem_meta,
+ 'Reported in the Roads category by Oxfordshire County Council at 15:17, Tue 10 January 2012',
+ 'correct problem meta information for user without relevant permissions';
+
+ $mech->log_out_ok;
+
+ ok $mech->get("/report/$report_id"), "get '/report/$report_id'";
+ is $mech->extract_problem_meta,
+ 'Reported in the Roads category by Oxfordshire County Council at 15:17, Tue 10 January 2012',
+ 'correct problem meta information for logged out user';
+
+};
+
+subtest "check brackets don't appear when username and report name are the same" => sub {
+ $report->update( {
+ name => 'Council User'
+ });
+
+ $mech->log_in_ok( $oxfordshireuser->email );
+ ok $mech->get("/report/$report_id"), "get '/report/$report_id'";
+ is $mech->extract_problem_meta,
+ 'Reported in the Roads category by Council User at 15:17, Tue 10 January 2012',
+ 'correct problem meta information';
+};
+
+END {
+ $mech->delete_user('test@example.com');
+ $mech->delete_body($westminster);
+ done_testing();
+}
diff --git a/t/app/controller/report_import.t b/t/app/controller/report_import.t
index eb686b44e..b956b61ae 100644
--- a/t/app/controller/report_import.t
+++ b/t/app/controller/report_import.t
@@ -3,8 +3,13 @@ use warnings;
use Test::More;
use FixMyStreet::TestMech;
+use FixMyStreet::App;
use Web::Scraper;
use Path::Class;
+use LWP::Protocol::PSGI;
+use t::Mock::MapItZurich;
+
+LWP::Protocol::PSGI->register(t::Mock::MapItZurich->to_psgi_app, host => 'mapit.zurich');
my $mech = FixMyStreet::TestMech->new;
$mech->get_ok('/import');
@@ -12,6 +17,22 @@ $mech->get_ok('/import');
my $sample_file = file(__FILE__)->parent->file("sample.jpg")->stringify;
ok -e $sample_file, "sample file $sample_file exists";
+# disable info logs for this test run
+FixMyStreet::App->log->disable('info');
+END { FixMyStreet::App->log->enable('info'); }
+
+my $body = $mech->create_body_ok(2245, 'Wiltshire Council');
+$mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'Street lighting',
+ email => 'streetlighting@example.com',
+);
+$mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'Potholes',
+ email => 'highways@example.com',
+);
+
# submit an empty report to import - check we get all errors
subtest "Test creating bad partial entries" => sub {
@@ -58,10 +79,14 @@ subtest "Test creating bad partial entries" => sub {
{
$mech->get_ok('/import');
- $mech->submit_form_ok( #
- { with_fields => $test->{fields} },
- "fill in form"
- );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ }, sub {
+ $mech->submit_form_ok( #
+ { with_fields => $test->{fields} },
+ "fill in form"
+ );
+ };
is_deeply( $mech->import_errors, $test->{errors}, "expected errors" );
}
@@ -69,7 +94,6 @@ subtest "Test creating bad partial entries" => sub {
};
subtest "Submit a correct entry" => sub {
-
$mech->get_ok('/import');
$mech->submit_form_ok( #
@@ -90,15 +114,16 @@ subtest "Submit a correct entry" => sub {
is $mech->content, 'SUCCESS', "Got success response";
# check that we have received the email
- $mech->email_count_is(1);
- my $email = $mech->get_email;
+ my $token_url = $mech->get_link_from_email;
$mech->clear_emails_ok;
-
- my ($token_url) = $email->body =~ m{(http://\S+)};
ok $token_url, "Found a token url $token_url";
# go to the token url
- $mech->get_ok($token_url);
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok($token_url);
+ };
# check that we are on '/around'
is $mech->uri->path, '/around', "sent to /around";
@@ -107,10 +132,15 @@ subtest "Submit a correct entry" => sub {
is_deeply $mech->visible_form_values, { pc => '' },
"check only pc field is shown";
- $mech->submit_form_ok( #
- { with_fields => { pc => 'SW1A 1AA' } },
- "fill in postcode"
- );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fixmystreet' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok(
+ { with_fields => { pc => 'SN15 5NG' } },
+ "fill in postcode"
+ );
+ };
is $mech->uri->path, '/report/new', "sent to report page";
@@ -120,7 +150,9 @@ subtest "Submit a correct entry" => sub {
name => 'Test User',
title => 'Test report',
detail => 'This is a test report',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
phone => '',
may_show_name => '1',
category => '-- Pick a category --',
@@ -129,19 +161,24 @@ 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.50101"', 'Check latitude');
- $mech->content_contains('longitude" value="-0.141587"', 'Check longitude');
- $mech->submit_form_ok(
- {
- button => 'tile_32742.21793',
- x => 10,
- y => 10,
- },
- "New map location"
- );
+ $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.uk/',
+ }, sub {
+ $mech->submit_form_ok(
+ {
+ button => 'tile_16192.10896',
+ x => 10,
+ y => 10,
+ },
+ "New map location"
+ );
+ };
$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,
@@ -149,7 +186,9 @@ subtest "Submit a correct entry" => sub {
name => 'Test User',
title => 'Test report',
detail => 'This is a test report',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
phone => '',
may_show_name => '1',
category => '-- Pick a category --',
@@ -157,19 +196,24 @@ subtest "Submit a correct entry" => sub {
"check imported fields are shown";
# change the details
- $mech->submit_form_ok( #
- {
- with_fields => {
- name => 'New Test User',
- title => 'New Test report',
- detail => 'This is a test report',
- phone => '01234 567 890',
- may_show_name => '1',
- category => 'Street lighting',
- }
- },
- "Update details and save"
- );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ name => 'New Test User',
+ title => 'New Test report',
+ detail => 'This is a test report',
+ phone => '01234 567 890',
+ may_show_name => '1',
+ category => 'Street lighting',
+ }
+ },
+ "Update details and save"
+ );
+ };
# check that report has been created
my $user =
@@ -192,8 +236,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',
@@ -208,15 +252,17 @@ subtest "Submit a correct entry (with location)" => sub {
is $mech->content, 'SUCCESS', "Got success response";
# check that we have received the email
- $mech->email_count_is(1);
- my $email = $mech->get_email;
+ my $token_url = $mech->get_link_from_email;
$mech->clear_emails_ok;
-
- my ($token_url) = $email->body =~ m{(http://\S+)};
ok $token_url, "Found a token url $token_url";
# go to the token url
- $mech->get_ok($token_url);
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok($token_url);
+ };
# check that we are on '/report/new'
is $mech->uri->path, '/report/new', "sent to /report/new";
@@ -227,7 +273,9 @@ subtest "Submit a correct entry (with location)" => sub {
name => 'Test User ll',
title => 'Test report ll',
detail => 'This is a test report ll',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
phone => '',
may_show_name => '1',
category => '-- Pick a category --',
@@ -235,19 +283,24 @@ subtest "Submit a correct entry (with location)" => sub {
"check imported fields are shown";
# change the details
- $mech->submit_form_ok( #
- {
- with_fields => {
- name => 'New Test User ll',
- title => 'New Test report ll',
- detail => 'This is a test report ll',
- phone => '01234 567 890',
- may_show_name => '1',
- category => 'Street lighting',
- }
- },
- "Update details and save"
- );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( #
+ {
+ with_fields => {
+ name => 'New Test User ll',
+ title => 'New Test report ll',
+ detail => 'This is a test report ll',
+ phone => '01234 567 890',
+ may_show_name => '1',
+ category => 'Street lighting',
+ }
+ },
+ "Update details and save"
+ );
+ };
# check that report has been created
my $user =
@@ -263,72 +316,77 @@ subtest "Submit a correct entry (with location)" => sub {
};
subtest "Submit a correct entry (with location) to cobrand" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'zurich' ],
+ MAPIT_URL => 'http://mapit.zurich/',
+ MAPIT_TYPES => [ 'O08' ],
+ MAPIT_ID_WHITELIST => [],
+ MAP_TYPE => 'Zurich,OSM',
+ }, sub {
+ ok $mech->host("zurich.example.org"), 'change host to zurich';
- SKIP: {
- skip( "Need 'fiksgatami' in ALLOWED_COBRANDS config", 20 )
- unless FixMyStreet::Cobrand->exists('fiksgatami');
- mySociety::MaPit::configure('http://mapit.nuug.no/');
- ok $mech->host("fiksgatami.no"), 'change host to fiksgatami';
+ $mech->get_ok('/import');
- $mech->get_ok('/import');
+ $mech->submit_form_ok( #
+ {
+ with_fields => {
+ service => 'test-script',
+ lat => '47.4',
+ lon => '8.5',
+ name => 'Test User ll',
+ email => 'test-ll@example.com',
+ subject => 'Test report ll',
+ detail => 'This is a test report ll',
+ photo => $sample_file,
+ }
+ },
+ "fill in form"
+ );
- $mech->submit_form_ok( #
- {
- with_fields => {
- service => 'test-script',
- lat => '59',
- lon => '10',
- name => 'Test User ll',
- email => 'test-ll@example.com',
- subject => 'Test report ll',
- detail => 'This is a test report ll',
- photo => $sample_file,
- }
- },
- "fill in form"
- );
+ is_deeply( $mech->import_errors, [], "got no errors" );
+ is $mech->content, 'SUCCESS', "Got success response";
- is_deeply( $mech->import_errors, [], "got no errors" );
- is $mech->content, 'SUCCESS', "Got success response";
+ # check that we have received the email
+ my $token_url = $mech->get_link_from_email;
+ $mech->clear_emails_ok;
+ ok $token_url, "Found a token url $token_url";
- # check that we have received the email
- $mech->email_count_is(1);
- my $email = $mech->get_email;
- $mech->clear_emails_ok;
+ # go to the token url
+ $mech->get_ok($token_url);
- my ($token_url) = $email->body =~ m{(http://\S+)};
- ok $token_url, "Found a token url $token_url";
+ # check that we are on '/report/new'
+ is $mech->uri->path, '/report/new', "sent to /report/new";
- # go to the token url
- $mech->get_ok($token_url);
+ # check that fields are prefilled for us
+ is_deeply $mech->visible_form_values,
+ {
+ name => 'Test User ll',
+ detail => 'This is a test report ll',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ phone => '',
+ email => 'test-ll@example.com',
+ },
+ "check imported fields are shown"
+ or diag Dumper( $mech->visible_form_values ); use Data::Dumper;
- # check that we are on '/report/new'
- is $mech->uri->path, '/report/new', "sent to /report/new";
-
- # check that fields are prefilled for us
- is_deeply $mech->visible_form_values,
- {
- name => 'Test User ll',
- title => 'Test report ll',
- detail => 'This is a test report ll',
- photo => '',
- phone => '',
- may_show_name => '1',
- },
- "check imported fields are shown";
-
- my $user =
- FixMyStreet::App->model('DB::User')
- ->find( { email => 'test-ll@example.com' } );
- ok $user, "Found a user";
-
- my $report = $user->problems->first;
- is $report->state, 'partial', 'is still partial';
- is $report->title, 'Test report ll', 'title is correct';
- is $report->lang, 'nb', 'language is correct';
-
- $mech->delete_user($user);
- }
+ my $user =
+ FixMyStreet::App->model('DB::User')
+ ->find( { email => 'test-ll@example.com' } );
+ ok $user, "Found a user";
+
+ my $report = $user->problems->first;
+ is $report->state, 'partial', 'is still partial';
+ is $report->title, 'Test report ll', 'title is correct';
+ is $report->lang, 'de-ch', 'language is correct';
+
+ $mech->delete_user($user);
+ };
};
done_testing();
+
+END {
+ $mech->delete_body($body);
+}
diff --git a/t/app/controller/report_inspect.t b/t/app/controller/report_inspect.t
new file mode 100644
index 000000000..69e43ad99
--- /dev/null
+++ b/t/app/controller/report_inspect.t
@@ -0,0 +1,248 @@
+use strict;
+use warnings;
+use Test::More;
+
+use FixMyStreet::TestMech;
+
+my $mech = FixMyStreet::TestMech->new;
+
+my $brum = $mech->create_body_ok(2514, 'Birmingham City Council', id => 2514);
+my $oxon = $mech->create_body_ok(2237, 'Oxfordshire County Council', id => 2237);
+my $contact = $mech->create_contact_ok( body_id => $oxon->id, category => 'Cows', email => 'cows@example.net' );
+my $rp = FixMyStreet::DB->resultset("ResponsePriority")->create({
+ body => $oxon,
+ name => 'High Priority',
+});
+FixMyStreet::DB->resultset("ContactResponsePriority")->create({
+ contact => $contact,
+ response_priority => $rp,
+});
+my $wodc = $mech->create_body_ok(2420, 'West Oxfordshire District Council', id => 2420);
+$mech->create_contact_ok( body_id => $wodc->id, category => 'Horses', email => 'horses@example.net' );
+
+
+my ($report, $report2) = $mech->create_problems_for_body(2, $oxon->id, 'Test', {
+ category => 'Cows', cobrand => 'fixmystreet', areas => ',2237,2420',
+ whensent => \'current_timestamp',
+ latitude => 51.847693, longitude => -1.355908,
+});
+my $report_id = $report->id;
+my $report2_id = $report2->id;
+
+
+my $user = $mech->log_in_ok('test@example.com');
+$user->update( { from_body => $oxon } );
+
+FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ ALLOWED_COBRANDS => 'fixmystreet',
+}, sub {
+ subtest "test inspect page" => sub {
+ $mech->get_ok("/report/$report_id");
+ $mech->content_lacks('Save changes');
+ $mech->content_lacks('Priority');
+ $mech->content_lacks('Traffic management');
+
+ $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_edit_priority' });
+ $mech->get_ok("/report/$report_id");
+ $mech->content_contains('Save changes');
+ $mech->content_contains('Priority');
+ $mech->content_lacks('Traffic management');
+
+ $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_inspect' });
+ $mech->get_ok("/report/$report_id");
+ $mech->content_contains('Save changes');
+ $mech->content_contains('Priority');
+ $mech->content_contains('Traffic management');
+ };
+
+ subtest "test basic inspect submission" => sub {
+ $mech->submit_form_ok({ button => 'save', with_fields => { traffic_information => 'Yes', state => 'Action Scheduled', include_update => undef } });
+ $report->discard_changes;
+ is $report->state, 'action scheduled', 'report state changed';
+ is $report->get_extra_metadata('traffic_information'), 'Yes', 'report data changed';
+ };
+
+ subtest "test inspect & instruct submission" => sub {
+ $report->unset_extra_metadata('inspected');
+ $report->state('confirmed');
+ $report->update;
+ $report->inspection_log_entry->delete;
+ my $reputation = $report->user->get_extra_metadata("reputation");
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form_ok({ button => 'save', with_fields => { public_update => "This is a public update.", include_update => "1", state => 'action scheduled' } });
+ $report->discard_changes;
+ is $report->comments->first->text, "This is a public update.", 'Update was created';
+ is $report->get_extra_metadata('inspected'), 1, 'report marked as inspected';
+ is $report->user->get_extra_metadata('reputation'), $reputation, "User reputation wasn't changed";
+ };
+
+ subtest "test update is required when instructing" => sub {
+ $report->unset_extra_metadata('inspected');
+ $report->update;
+ $report->inspection_log_entry->delete;
+ $report->comments->delete_all;
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form_ok({ button => 'save', with_fields => { public_update => undef, include_update => "1" } });
+ is_deeply $mech->page_errors, [ "Please provide a public update for this report." ], 'errors match';
+ $report->discard_changes;
+ is $report->comments->count, 0, "Update wasn't created";
+ is $report->get_extra_metadata('inspected'), undef, 'report not marked as inspected';
+ };
+
+ subtest "test location changes" => sub {
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form_ok({ button => 'save', with_fields => { latitude => 55, longitude => -2 } });
+ $mech->content_contains('Invalid location');
+ $mech->submit_form_ok({ button => 'save', with_fields => { latitude => 51.754926, longitude => -1.256179 } });
+ $mech->content_lacks('Invalid location');
+ };
+
+ subtest "test duplicate reports are shown" => sub {
+ my $old_state = $report->state;
+ $report->set_extra_metadata('duplicate_of' => $report2->id);
+ $report->state('duplicate');
+ $report->update;
+
+ $mech->get_ok("/report/$report_id");
+ $mech->content_contains($report2->title);
+
+ $mech->get_ok("/report/$report2_id");
+ $mech->content_contains($report->title);
+
+ $report->unset_extra_metadata('duplicate_of');
+ $report->state($old_state);
+ $report->update;
+ };
+
+ subtest "marking a report as a duplicate with update correctly sets update status" => sub {
+ my $old_state = $report->state;
+ $report->comments->delete_all;
+
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form_ok({ button => 'save', with_fields => { state => 'Duplicate', duplicate_of => $report2->id, public_update => "This is a duplicate.", include_update => "1" } });
+ $report->discard_changes;
+
+ is $report->state, 'duplicate', 'report marked as duplicate';
+ is $report->comments->search({ problem_state => 'duplicate' })->count, 1, 'update marking report as duplicate was left';
+
+ $report->update({ state => $old_state });
+ };
+
+ subtest "marking a report as a duplicate doesn't clobber user-provided update" => sub {
+ my $old_state = $report->state;
+ $report->comments->delete_all;
+
+ $mech->get_ok("/report/$report_id");
+ my $update_text = "This text was entered as an update by the user.";
+ $mech->submit_form_ok({ button => 'save', with_fields => {
+ state => 'Duplicate',
+ duplicate_of => $report2->id,
+ public_update => $update_text,
+ include_update => "1",
+ }});
+ $report->discard_changes;
+
+ is $report->state, 'duplicate', 'report marked as duplicate';
+ is $report->comments->search({ problem_state => 'duplicate' })->count, 1, 'update marked report as duplicate';
+ $mech->content_contains($update_text);
+ $mech->content_lacks("Thank you for your report. This problem has already been reported.");
+
+ $report->update({ state => $old_state });
+ };
+
+ foreach my $test (
+ { type => 'report_edit_priority', priority => 1 },
+ { type => 'report_edit_category', category => 1 },
+ { type => 'report_inspect', priority => 1, category => 1, detailed => 1 },
+ ) {
+ subtest "test $test->{type} permission" => sub {
+ $user->user_body_permissions->delete;
+ $user->user_body_permissions->create({ body => $oxon, permission_type => $test->{type} });
+ $mech->get_ok("/report/$report_id");
+ $mech->contains_or_lacks($test->{priority}, 'Priority</label>');
+ $mech->contains_or_lacks($test->{priority}, '>High');
+ $mech->contains_or_lacks($test->{category}, 'Category');
+ $mech->contains_or_lacks($test->{detailed}, 'Extra details');
+ $mech->submit_form_ok({
+ button => 'save',
+ with_fields => {
+ $test->{priority} ? (priority => 1) : (),
+ $test->{category} ? (category => 'Cows') : (),
+ $test->{detailed} ? (detailed_information => 'Highland ones') : (),
+ }
+ });
+ };
+ }
+};
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'oxfordshire',
+}, sub {
+ subtest "test negative reputation" => sub {
+ my $reputation = $report->user->get_extra_metadata("reputation") || 0;
+
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form( button => 'remove_from_site' );
+
+ $report->discard_changes;
+ is $report->user->get_extra_metadata('reputation'), $reputation-1, "User reputation was decreased";
+ $report->update({ state => 'confirmed' });
+ };
+
+ subtest "test positive reputation" => sub {
+ $report->unset_extra_metadata('inspected');
+ $report->update;
+ $report->inspection_log_entry->delete if $report->inspection_log_entry;
+ my $reputation = $report->user->get_extra_metadata("reputation") || 0;
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form_ok({ button => 'save', with_fields => { state => 'action scheduled', include_update => undef } });
+ $report->discard_changes;
+ is $report->get_extra_metadata('inspected'), 1, 'report marked as inspected';
+ is $report->user->get_extra_metadata('reputation'), $reputation+1, "User reputation was increased";
+ };
+
+ subtest "Oxfordshire-specific traffic management options are shown" => sub {
+ $report->update({ state => 'confirmed' });
+ $mech->get_ok("/report/$report_id");
+ $mech->submit_form_ok({ button => 'save', with_fields => { traffic_information => 'Signs and Cones', state => 'Action Scheduled', include_update => undef } });
+ $report->discard_changes;
+ is $report->state, 'action scheduled', 'report state changed';
+ is $report->get_extra_metadata('traffic_information'), 'Signs and Cones', 'report data changed';
+ };
+
+};
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'oxfordshire', 'fixmystreet' ],
+ BASE_URL => 'http://fixmystreet.site',
+}, sub {
+ subtest "test category/body changes" => sub {
+ $mech->host('oxfordshire.fixmystreet.site');
+ $report->update({ state => 'confirmed' });
+ $mech->get_ok("/report/$report_id");
+ # Then change the category to the other council in this location,
+ # which should cause it to be resent. We clear the host because
+ # otherwise testing stays on host() above.
+ $mech->clear_host;
+ $mech->submit_form(button => 'save', with_fields => { category => 'Horses', include_update => undef, });
+
+ $report->discard_changes;
+ is $report->category, "Horses", "Report in correct category";
+ is $report->whensent, undef, "Report marked as unsent";
+ is $report->bodies_str, $wodc->id, "Reported to WODC";
+
+ is $mech->uri->path, "/report/$report_id", "redirected to correct page";
+ is $mech->res->code, 200, "got 200 for final destination";
+ is $mech->res->previous->code, 302, "got 302 for redirect";
+ # Extra check given host weirdness
+ is $mech->res->previous->header('Location'), "http://fixmystreet.site/report/$report_id";
+ };
+};
+
+
+END {
+ $mech->delete_body($oxon);
+ $mech->delete_body($brum);
+ done_testing();
+}
diff --git a/t/app/controller/report_interest_count.t b/t/app/controller/report_interest_count.t
index 0a8a5ac0b..3cb80ea5f 100644
--- a/t/app/controller/report_interest_count.t
+++ b/t/app/controller/report_interest_count.t
@@ -1,5 +1,16 @@
use strict;
use warnings;
+
+package FixMyStreet::Cobrand::Tester;
+
+use parent 'FixMyStreet::Cobrand::Default';
+
+sub can_support_problems {
+ return 1;
+}
+
+package main;
+
use Test::More;
use FixMyStreet::TestMech;
@@ -11,15 +22,7 @@ my $mech = FixMyStreet::TestMech->new;
# create a test user and report
$mech->delete_user('test@example.com');
-my $user =
- FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'test@example.com', name => 'Test User' } );
-ok $user, "created test user";
-
-my $user2 =
- FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'test2@example.com', name => 'Other User' } );
-ok $user2, "created test user";
+my $user = $mech->create_user_ok('test@example.com', name => 'Test User');
my $dt = DateTime->new(
year => 2011,
@@ -33,7 +36,7 @@ my $dt = DateTime->new(
my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
{
postcode => 'SW1A 1AA',
- council => '2504',
+ bodies_str => '2504',
areas => ',105255,11806,11828,2247,2504,',
category => 'Other',
title => 'Test 2',
@@ -56,37 +59,38 @@ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
my $report_id = $report->id;
ok $report, "created test report - $report_id";
-SKIP: {
- skip( "Need 'fixmybarangay' in ALLOWED_COBRANDS config", 29 )
- unless FixMyStreet::Cobrand->exists('fixmybarangay');
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'tester' ],
+}, sub {
+ my $body = $mech->create_body_ok(2504, 'Westminster City Council');
+
for my $test (
{
- desc => 'if not from council then no supporter button',
- from_body => 0,
+ desc => 'if not from body then no supporter button',
+ from_body => undef,
support_string => 'No supporters',
},
{
- desc => 'from council user can increment supported count',
- from_body => 2504,
+ desc => 'from body user can increment supported count',
+ from_body => $body->id,
support_string => 'No supporters',
updated_support => '1 supporter'
},
{
desc => 'correct grammar for more than one supporter',
- from_body => 2504,
+ from_body => $body->id,
support_string => '1 supporter',
updated_support => '2 supporters'
},
) {
subtest $test->{desc} => sub {
- ok $mech->host('fixmybarangay.com'), 'changed to fixmybarangay';
$mech->log_in_ok( $user->email );
$user->from_body( $test->{from_body} );
$user->update;
- $report->discard_changes;
- $report->council( $test->{report_council} );
- $report->update;
+ $report->update( {
+ bodies_str => $test->{report_council}
+ } );
$mech->get_ok("/report/$report_id");
$mech->content_contains( $test->{support_string} );
@@ -95,7 +99,7 @@ SKIP: {
$mech->content_contains('Add support');
$mech->submit_form_ok( { form_number => 1 } );
- is $mech->uri, "http://fixmybarangay.com/report/$report_id", 'add support redirects to report page';
+ is $mech->uri->path, "/report/$report_id", 'add support redirects to report page';
$mech->content_contains($test->{updated_support});
} else {
@@ -104,29 +108,23 @@ SKIP: {
};
}
- subtest 'check non council user cannot increment support count' => sub {
- ok $mech->host('fixmybarangay.com'), 'changed to fixmybarangay';
- $report->discard_changes;
- $report->interest_count(1);
- ok $report->update(), 'updated interest count';
-
- $report->discard_changes;
+ subtest 'check non body user cannot increment support count' => sub {
+ ok $report->update({ interest_count => 1 }), 'updated interest count';
is $report->interest_count, 1, 'correct interest count';
$mech->get_ok("/report/$report_id");
$mech->content_contains( '1 supporter' );
+ $mech->log_out_ok( $user->email );
$mech->post_ok("/report/support", { id => $report_id } );
- is $mech->uri, "http://fixmybarangay.com/report/$report_id", 'add support redirects to report page';
+ is $mech->uri->path, "/report/$report_id", 'add support redirects to report page';
$mech->content_contains( '1 supporter' );
};
};
subtest 'check support details not shown if not enabled in cobrand' => sub {
- ok $mech->host('fixmystreet.com'), 'changed to fixmystreet';
-
$report->interest_count(1);
ok $report->update, 'updated interest count';
@@ -134,10 +132,7 @@ subtest 'check support details not shown if not enabled in cobrand' => sub {
$mech->content_lacks( '1 supporter' );
};
-$report->discard_changes;
-$report->council( 2504 );
-$report->update;
-
-# tidy up
-$mech->delete_user('test@example.com');
-done_testing();
+END {
+ $mech->delete_user('test@example.com');
+ done_testing();
+}
diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t
index 92943bde9..71090cd26 100644
--- a/t/app/controller/report_new.t
+++ b/t/app/controller/report_new.t
@@ -2,12 +2,16 @@ use strict;
use utf8; # sign in error message has &ndash; in it
use warnings;
use Test::More;
-use utf8;
use FixMyStreet::TestMech;
+use FixMyStreet::App;
use Web::Scraper;
use Path::Class;
+# disable info logs for this test run
+FixMyStreet::App->log->disable('info');
+END { FixMyStreet::App->log->enable('info'); }
+
my $mech = FixMyStreet::TestMech->new;
$mech->get_ok('/report/new');
@@ -17,86 +21,146 @@ ok -e $sample_file, "sample file $sample_file exists";
subtest "test that bare requests to /report/new get redirected" => sub {
$mech->get_ok('/report/new');
- is $mech->uri->path, '/around', "went to /around";
+ is $mech->uri->path, '/', "went to /";
is_deeply { $mech->uri->query_form }, {}, "query empty";
- $mech->get_ok('/report/new?pc=SW1A%201AA');
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok('/report/new?pc=SW1A%201AA');
+ };
is $mech->uri->path, '/around', "went to /around";
is_deeply { $mech->uri->query_form }, { pc => 'SW1A 1AA' },
"pc correctly transferred";
};
-my %contact_params = (
- confirmed => 1,
- deleted => 0,
- editor => 'Test',
- whenedited => \'current_timestamp',
- note => 'Created for test',
-);
+my %body_ids;
+my @bodies;
+for my $body (
+ { area_id => 2651, name => 'City of Edinburgh Council' },
+ { area_id => 2226, name => 'Gloucestershire County Council' },
+ { area_id => 2326, name => 'Cheltenham Borough Council' },
+ { area_id => 2504, name => 'Westminster City Council' },
+ # The next three have fixed IDs because bits of the code rely on
+ # the body ID === MapIt area ID.
+ { area_id => 2482, name => 'Bromley Council', id => 2482 },
+ { area_id => 2227, name => 'Hampshire County Council', id => 2227 },
+ { area_id => 2333, name => 'Hart Council', id => 2333 },
+) {
+ my $body_obj = $mech->create_body_ok($body->{area_id}, $body->{name}, id => $body->{id});
+ push @bodies, $body_obj;
+ $body_ids{$body->{area_id}} = $body_obj->id;
+}
+
# Let's make some contacts to send things to!
-FixMyStreet::App->model('DB::Contact')->search( {
- email => { 'like', '%example.com' },
-} )->delete;
-my $contact1 = FixMyStreet::App->model('DB::Contact')->find_or_create( {
- %contact_params,
- body_id => 2651, # Edinburgh
+my $contact1 = $mech->create_contact_ok(
+ body_id => $body_ids{2651}, # Edinburgh
category => 'Street lighting',
email => 'highways@example.com',
-} );
-my $contact2 = FixMyStreet::App->model('DB::Contact')->find_or_create( {
- %contact_params,
- body_id => 2226, # Gloucestershire
+);
+my $contact2 = $mech->create_contact_ok(
+ body_id => $body_ids{2226}, # Gloucestershire
category => 'Potholes',
email => 'potholes@example.com',
-} );
-my $contact3 = FixMyStreet::App->model('DB::Contact')->find_or_create( {
- %contact_params,
- body_id => 2326, # Cheltenham
+);
+my $contact3 = $mech->create_contact_ok(
+ body_id => $body_ids{2326}, # Cheltenham
category => 'Trees',
email => 'trees@example.com',
-} );
-my $contact4 = FixMyStreet::App->model('DB::Contact')->find_or_create( {
- %contact_params,
- body_id => 2482, # Bromley
+);
+my $contact4 = $mech->create_contact_ok(
+ body_id => $body_ids{2482}, # Bromley
category => 'Trees',
email => 'trees@example.com',
-} );
-my $contact5 = FixMyStreet::App->model('DB::Contact')->find_or_create( {
- %contact_params,
- body_id => 2651, # Edinburgh
+);
+my $contact5 = $mech->create_contact_ok(
+ body_id => $body_ids{2651}, # Edinburgh
category => 'Trees',
email => 'trees@example.com',
-} );
-my $contact6 = FixMyStreet::App->model('DB::Contact')->find_or_create( {
- %contact_params,
- body_id => 2434, # Lichfield
+);
+my $contact6 = $mech->create_contact_ok(
+ body_id => $body_ids{2333}, # Hart
category => 'Trees',
email => 'trees@example.com',
-} );
-my $contact7 = FixMyStreet::App->model('DB::Contact')->find_or_create( {
- %contact_params,
- body_id => 2240, # Lichfield
- category => 'Street lighting',
+);
+my $contact7 = $mech->create_contact_ok(
+ body_id => $body_ids{2227}, # Hampshire
+ category => 'Street lighting',
email => 'highways@example.com',
-} );
-ok $contact1, "created test contact 1";
-ok $contact2, "created test contact 2";
-ok $contact3, "created test contact 3";
-ok $contact4, "created test contact 4";
-ok $contact5, "created test contact 5";
-ok $contact6, "created test contact 6";
-ok $contact7, "created test contact 7";
+);
+my $contact8 = $mech->create_contact_ok(
+ body_id => $body_ids{2504},
+ category => 'Street lighting',
+ email => 'highways@example.com'
+);
# test that the various bit of form get filled in and errors correctly
# generated.
foreach my $test (
{
msg => 'all fields empty',
+ pc => 'OX1 3DH',
+ fields => {
+ title => '',
+ detail => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => '',
+ may_show_name => '1',
+ email => '',
+ phone => '',
+ password_sign_in => '',
+ password_register => '',
+ remember_me => undef,
+ },
+ changes => {},
+ errors => [
+ 'Please enter a subject',
+ 'Please enter some details',
+ # No category error, as no categories for Oxon at all, so is skipped
+ 'Please enter your email',
+ 'Please enter your name',
+ ],
+ },
+ {
+ msg => 'all fields empty, bad category',
+ pc => 'GL50 2PR',
+ fields => {
+ title => '',
+ detail => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => '',
+ may_show_name => '1',
+ email => '',
+ phone => '',
+ category => 'Something bad',
+ password_sign_in => '',
+ password_register => '',
+ remember_me => undef,
+ },
+ changes => {
+ category => '-- Pick a category --',
+ },
+ errors => [
+ 'Please enter a subject',
+ 'Please enter some details',
+ 'Please choose a category',
+ 'Please enter your email',
+ 'Please enter your name',
+ ],
+ },
+ {
+ msg => 'all fields empty except category',
pc => 'SW1A 1AA',
fields => {
title => '',
detail => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => '',
may_show_name => '1',
email => '',
@@ -120,7 +184,9 @@ foreach my $test (
fields => {
title => '',
detail => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => '',
may_show_name => undef,
email => '',
@@ -144,7 +210,9 @@ foreach my $test (
fields => {
title => '',
detail => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => 'Bob Jones',
may_show_name => undef,
email => '',
@@ -167,7 +235,9 @@ foreach my $test (
fields => {
title => '',
detail => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => 'Bob Jones',
may_show_name => '1',
email => '',
@@ -190,7 +260,9 @@ foreach my $test (
fields => {
title => "DOG SHIT\r\nON WALLS",
detail => "on this portakabin -\r\n\r\nmore of a portaloo HEH!!",
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => 'Bob Jones',
may_show_name => '1',
email => '',
@@ -213,7 +285,9 @@ foreach my $test (
fields => {
title => 'Test title',
detail => 'Test detail',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => 'DUDE',
may_show_name => '1',
email => '',
@@ -235,7 +309,9 @@ foreach my $test (
fields => {
title => 'Test title',
detail => 'Test detail',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => 'anonymous',
may_show_name => '1',
email => '',
@@ -257,7 +333,9 @@ foreach my $test (
fields => {
title => 'Test title',
detail => 'Test detail',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => 'Joe Smith',
may_show_name => '1',
email => 'not an email',
@@ -276,7 +354,9 @@ foreach my $test (
fields => {
title => " Test title ",
detail => " first line \n\n second\nline\n\n ",
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => '',
may_show_name => '1',
email => '',
@@ -301,7 +381,9 @@ foreach my $test (
fields => {
title => '',
detail => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => ' Bob Jones ',
may_show_name => '1',
email => ' BOB @ExAmplE.COM ',
@@ -323,7 +405,9 @@ foreach my $test (
fields => {
title => 'Title',
detail => 'Detail',
- photo => [ [ undef, 'bad.txt', Content => 'This is not a JPEG', Content_Type => 'text/plain' ], 1 ],
+ photo1 => [ [ undef, 'bad.txt', Content => 'This is not a JPEG', Content_Type => 'text/plain' ], 1 ],
+ photo2 => '',
+ photo3 => '',
name => 'Bob Jones',
may_show_name => '1',
email => 'bob@example.com',
@@ -334,9 +418,9 @@ foreach my $test (
remember_me => undef,
},
changes => {
- photo => '',
+ photo1 => '',
},
- errors => [ "Please upload a JPEG image only" ],
+ errors => [ "Please upload an image only" ],
},
{
msg => 'bad photo upload gives error',
@@ -344,7 +428,9 @@ foreach my $test (
fields => {
title => 'Title',
detail => 'Detail',
- photo => [ [ undef, 'fake.jpeg', Content => 'This is not a JPEG', Content_Type => 'image/jpeg' ], 1 ],
+ photo1 => [ [ undef, 'fake.jpeg', Content => 'This is not a JPEG', Content_Type => 'image/jpeg' ], 1 ],
+ photo2 => '',
+ photo3 => '',
name => 'Bob Jones',
may_show_name => '1',
email => 'bob@example.com',
@@ -355,9 +441,9 @@ foreach my $test (
remember_me => undef,
},
changes => {
- photo => '',
+ photo1 => '',
},
- errors => [ "That image doesn't appear to have uploaded correctly (Please upload a JPEG image only ), please try again." ],
+ errors => [ "That image doesn't appear to have uploaded correctly (Please upload an image only ), please try again." ],
},
{
msg => 'photo with octet-stream gets through okay',
@@ -365,7 +451,9 @@ foreach my $test (
fields => {
title => '',
detail => 'Detail',
- photo => [ [ $sample_file, undef, Content_Type => 'application/octet-stream' ], 1 ],
+ photo1 => [ [ $sample_file, undef, Content_Type => 'application/octet-stream' ], 1 ],
+ photo2 => '',
+ photo3 => '',
name => 'Bob Jones',
may_show_name => '1',
email => 'bob@example.com',
@@ -376,7 +464,7 @@ foreach my $test (
remember_me => undef,
},
changes => {
- photo => '',
+ photo1 => '',
},
errors => [ "Please enter a subject" ],
},
@@ -386,20 +474,25 @@ foreach my $test (
$mech->get_ok('/around');
# submit initial pc form
- $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } },
- "submit location" );
- is_deeply $mech->page_errors, [], "no errors for pc '$test->{pc}'";
-
- # click through to the report page
- $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
- "follow 'skip this step' link" );
-
- # submit the main form
- $mech->submit_form_ok( { with_fields => $test->{fields} },
- "submit form" );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } },
+ "submit location" );
+ is_deeply $mech->page_errors, [], "no errors for pc '$test->{pc}'";
+
+ # click through to the report page
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
+ "follow 'skip this step' link" );
+
+ # submit the main form
+ $mech->submit_form_ok( { with_fields => $test->{fields} },
+ "submit form" );
+ };
# check that we got the errors expected
- is_deeply $mech->page_errors, $test->{errors}, "check errors";
+ is_deeply [ sort @{$mech->page_errors} ], [ sort @{$test->{errors}} ], "check errors";
# check that fields have changed as expected
my $new_values = {
@@ -454,30 +547,35 @@ foreach my $test (
# submit initial pc form
$mech->get_ok('/around');
- $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } },
- "submit location" );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } },
+ "submit location" );
- # click through to the report page
- $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
- "follow 'skip this step' link" );
+ # click through to the report page
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
+ "follow 'skip this step' link" );
- $mech->submit_form_ok(
- {
- button => 'submit_register',
- with_fields => {
- title => 'Test Report',
- detail => 'Test report details.',
- photo => '',
- name => 'Joe Bloggs',
- may_show_name => '1',
- email => 'test-1@example.com',
- phone => '07903 123 456',
- category => 'Street lighting',
- password_register => $test->{password} ? 'secret' : '',
- }
- },
- "submit good details"
- );
+ $mech->submit_form_ok(
+ {
+ button => 'submit_register',
+ with_fields => {
+ title => 'Test Report',
+ detail => 'Test report details.',
+ photo1 => '',
+ name => 'Joe Bloggs',
+ may_show_name => '1',
+ email => 'test-1@example.com',
+ phone => '07903 123 456',
+ category => 'Street lighting',
+ password_register => $test->{password} ? 'secret' : '',
+ }
+ },
+ "submit good details"
+ );
+ };
# check that we got the errors expected
is_deeply $mech->page_errors, [], "check there were no errors";
@@ -503,15 +601,14 @@ foreach my $test (
is $mech->get( '/report/' . $report->id )->code, 404, "report not found";
# Check the report has been assigned appropriately
- is $report->council, 2651;
+ is $report->bodies_str, $body_ids{2651};
# receive token
my $email = $mech->get_email;
ok $email, "got an email";
- like $email->body, qr/confirm the problem/i, "confirm the problem";
+ like $mech->get_text_body_from_email($email), qr/confirm that you want to send your\s+report/i, "confirm the problem";
- my ($url) = $email->body =~ m{(http://\S+)};
- ok $url, "extracted confirm url '$url'";
+ my $url = $mech->get_link_from_email($email);
# confirm token
$mech->get_ok($url);
@@ -555,8 +652,7 @@ subtest "test password errors for a user who is signing in as they report" => su
# check that the user does not exist
my $test_email = 'test-2@example.com';
- my $user = FixMyStreet::App->model('DB::User')->find_or_create( { email => $test_email } );
- ok $user, "test user does exist";
+ my $user = $mech->create_user_ok($test_email);
# setup the user.
ok $user->update( {
@@ -567,27 +663,32 @@ subtest "test password errors for a user who is signing in as they report" => su
# submit initial pc form
$mech->get_ok('/around');
- $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } },
- "submit location" );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } },
+ "submit location" );
- # click through to the report page
- $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
- "follow 'skip this step' link" );
+ # click through to the report page
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
+ "follow 'skip this step' link" );
- $mech->submit_form_ok(
- {
- button => 'submit_sign_in',
- with_fields => {
- title => 'Test Report',
- detail => 'Test report details.',
- photo => '',
- email => 'test-2@example.com',
- password_sign_in => 'secret1',
- category => 'Street lighting',
- }
- },
- "submit with wrong password"
- );
+ $mech->submit_form_ok(
+ {
+ button => 'submit_sign_in',
+ with_fields => {
+ title => 'Test Report',
+ detail => 'Test report details.',
+ photo1 => '',
+ email => 'test-2@example.com',
+ password_sign_in => 'secret1',
+ category => 'Street lighting',
+ }
+ },
+ "submit with wrong password"
+ );
+ };
# check that we got the errors expected
is_deeply $mech->page_errors, [
@@ -597,13 +698,13 @@ subtest "test password errors for a user who is signing in as they report" => su
subtest "test report creation for a user who is signing in as they report" => sub {
$mech->log_out_ok;
+ $mech->cookie_jar({});
$mech->clear_emails_ok;
# check that the user does not exist
my $test_email = 'test-2@example.com';
- my $user = FixMyStreet::App->model('DB::User')->find_or_create( { email => $test_email } );
- ok $user, "test user does exist";
+ my $user = $mech->create_user_ok($test_email);
# setup the user.
ok $user->update( {
@@ -614,52 +715,54 @@ subtest "test report creation for a user who is signing in as they report" => su
# submit initial pc form
$mech->get_ok('/around');
- $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } },
- "submit location" );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } },
+ "submit location" );
- # click through to the report page
- $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
- "follow 'skip this step' link" );
+ # click through to the report page
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
+ "follow 'skip this step' link" );
- $mech->submit_form_ok(
- {
- button => 'submit_sign_in',
- with_fields => {
- title => 'Test Report',
- detail => 'Test report details.',
- photo => '',
- email => 'test-2@example.com',
- password_sign_in => 'secret2',
- category => 'Street lighting',
- }
- },
- "submit good details"
- );
+ $mech->submit_form_ok(
+ {
+ button => 'submit_sign_in',
+ with_fields => {
+ title => 'Test Report',
+ detail => 'Test report details.',
+ photo1 => '',
+ email => 'test-2@example.com',
+ password_sign_in => 'secret2',
+ category => 'Street lighting',
+ }
+ },
+ "submit good details"
+ );
- # check that we got the errors expected
- is_deeply $mech->page_errors, [
- 'You have successfully signed in; please check and confirm your details are accurate:',
- ], "check there were errors";
+ # check that we got the message expected
+ $mech->content_contains( 'You have successfully signed in; please check and confirm your details are accurate:' );
- # Now submit with a name
- $mech->submit_form_ok(
- {
- with_fields => {
- name => 'Joe Bloggs',
- }
- },
- "submit good details"
- );
+ # Now submit with a name
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ name => 'Joe Bloggs',
+ }
+ },
+ "submit good details"
+ );
+ };
# find the report
my $report = $user->problems->first;
ok $report, "Found the report";
- # check that we got redirected to /report/
- is $mech->uri->path, "/report/" . $report->id, "redirected to report page";
+ $mech->content_contains('Thank you for reporting this issue');
# Check the report has been assigned appropriately
- is $report->council, 2651;
+ is $report->bodies_str, $body_ids{2651};
# check that no emails have been sent
$mech->email_count_is(0);
@@ -708,52 +811,58 @@ foreach my $test (
# submit initial pc form
$mech->get_ok('/around');
- $mech->submit_form_ok( { with_fields => { pc => 'GL50 2PR', } },
- "submit location" );
-
- # click through to the report page
- $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
- "follow 'skip this step' link" );
-
- # check that the fields are correctly prefilled
- is_deeply(
- $mech->visible_form_values,
- {
- title => '',
- detail => '',
- may_show_name => '1',
- name => 'Test User',
- phone => '01234 567 890',
- photo => '',
- category => '-- Pick a category --',
- },
- "user's details prefilled"
- );
-
- $mech->submit_form_ok(
- {
- with_fields => {
- title => "Test Report at café",
- detail => 'Test report details.',
- photo => '',
- name => 'Joe Bloggs',
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'GL50 2PR', } },
+ "submit location" );
+
+ # click through to the report page
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
+ "follow 'skip this step' link" );
+
+ # check that the fields are correctly prefilled
+ is_deeply(
+ $mech->visible_form_values,
+ {
+ title => '',
+ detail => '',
may_show_name => '1',
- phone => '07903 123 456',
- category => $test->{category},
- }
- },
- "submit good details"
- );
+ name => 'Test User',
+ phone => '01234 567 890',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ category => '-- Pick a category --',
+ },
+ "user's details prefilled"
+ );
+
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ title => "Test Report at café",
+ detail => 'Test report details.',
+ photo1 => '',
+ name => 'Joe Bloggs',
+ may_show_name => '1',
+ phone => '07903 123 456',
+ category => $test->{category},
+ }
+ },
+ "submit good details"
+ );
+ };
# find the report
my $report = $user->problems->first;
ok $report, "Found the report";
# Check the report has been assigned appropriately
- is $report->council, $test->{council};
+ is $report->bodies_str, $body_ids{$test->{council}};
- # check that we got redirected to /report/
- is $mech->uri->path, "/report/" . $report->id, "redirected to report page";
+ $mech->content_contains('Thank you for reporting this issue');
# check that no emails have been sent
$mech->email_count_is(0);
@@ -795,34 +904,38 @@ subtest "test report creation for a category that is non public" => sub {
# check that the user does not exist
my $test_email = 'test-2@example.com';
- my $user = FixMyStreet::App->model('DB::User')->find_or_create( { email => $test_email } );
- ok $user, "test user does exist";
+ my $user = $mech->create_user_ok($test_email);
$contact1->update( { non_public => 1 } );
# submit initial pc form
$mech->get_ok('/around');
- $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } },
- "submit location" );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } },
+ "submit location" );
- # click through to the report page
- $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
- "follow 'skip this step' link" );
+ # click through to the report page
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
+ "follow 'skip this step' link" );
- $mech->submit_form_ok(
- {
- button => 'submit_register',
- with_fields => {
- title => 'Test Report',
- detail => 'Test report details.',
- photo => '',
- email => 'test-2@example.com',
- name => 'Joe Bloggs',
- category => 'Street lighting',
- }
- },
- "submit good details"
- );
+ $mech->submit_form_ok(
+ {
+ button => 'submit_register',
+ with_fields => {
+ title => 'Test Report',
+ detail => 'Test report details.',
+ photo1 => '',
+ email => 'test-2@example.com',
+ name => 'Joe Bloggs',
+ category => 'Street lighting',
+ }
+ },
+ "submit good details"
+ );
+ };
# find the report
my $report = $user->problems->first;
@@ -833,10 +946,9 @@ subtest "test report creation for a category that is non public" => sub {
my $email = $mech->get_email;
ok $email, "got an email";
- like $email->body, qr/confirm the problem/i, "confirm the problem";
+ like $mech->get_text_body_from_email($email), qr/confirm that you want to send your\s+report/i, "confirm the problem";
- my ($url) = $email->body =~ m{(http://\S+)};
- ok $url, "extracted confirm url '$url'";
+ my $url = $mech->get_link_from_email($email);
# confirm token
$mech->get_ok($url);
@@ -858,8 +970,24 @@ subtest "test report creation for a category that is non public" => sub {
$contact2->category( "Pothol\xc3\xa9s" );
$contact2->update;
-$mech->get_ok( '/report/new/ajax?latitude=' . $saved_lat . '&longitude=' . $saved_lon );
+
+my $extra_details;
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=' . $saved_lat . '&longitude=' . $saved_lon );
+};
$mech->content_contains( "Pothol\xc3\xa9s" );
+ok !$extra_details->{titles_list}, 'Non Bromley does not send back list of titles';
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=51.4021&longitude=0.01578');
+};
+ok $extra_details->{titles_list}, 'Bromley sends back list of titles';
#### test uploading an image
@@ -867,18 +995,22 @@ $mech->content_contains( "Pothol\xc3\xa9s" );
#### possibly manual testing
# create report without using map
-# create report by clicking on may with javascript off
+# create report by clicking on map with javascript off
# create report with images off
subtest "check that a lat/lon off coast leads to /around" => sub {
my $off_coast_latitude = 50.78301;
my $off_coast_longitude = -0.646929;
- $mech->get_ok( #
- "/report/new"
- . "?latitude=$off_coast_latitude"
- . "&longitude=$off_coast_longitude"
- );
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok( #
+ "/report/new"
+ . "?latitude=$off_coast_latitude"
+ . "&longitude=$off_coast_longitude"
+ );
+ };
is $mech->uri->path, '/around', "redirected to '/around'";
@@ -892,15 +1024,15 @@ subtest "check that a lat/lon off coast leads to /around" => sub {
for my $test (
{
desc => 'user title not set if not bromley problem',
- host => 'http://www.fixmystreet.com',
- postcode => 'EH99 1SP',
+ host => 'www.fixmystreet.com',
+ postcode => 'EH1 1BB',
fms_extra_title => '',
- extra => undef,
+ extra => [],
user_title => undef,
},
{
desc => 'title shown for bromley problem on main site',
- host => 'http://www.fixmystreet.com',
+ host => 'www.fixmystreet.com',
postcode => 'BR1 3UH',
fms_extra_title => 'MR',
extra => [
@@ -915,7 +1047,7 @@ for my $test (
{
desc =>
'title, first and last name shown for bromley problem on cobrand',
- host => 'http://bromley.fixmystreet.com',
+ host => 'bromley.fixmystreet.com',
postcode => 'BR1 3UH',
first_name => 'Test',
last_name => 'User',
@@ -942,9 +1074,10 @@ for my $test (
)
{
subtest $test->{desc} => sub {
- if ( $test->{host} =~ /bromley/ && !FixMyStreet::Cobrand->exists('bromley') ) {
- plan skip_all => 'Skipping Bromley tests without Bromley cobrand';
- }
+ my $override = {
+ ALLOWED_COBRANDS => [ $test->{host} =~ /bromley/ ? 'bromley' : 'fixmystreet' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ };
$mech->host( $test->{host} );
@@ -952,12 +1085,14 @@ for my $test (
$mech->clear_emails_ok;
$mech->get_ok('/');
- $mech->submit_form_ok( { with_fields => { pc => $test->{postcode}, } },
- "submit location" );
- $mech->follow_link_ok(
- { text_regex => qr/skip this step/i, },
- "follow 'skip this step' link"
- );
+ FixMyStreet::override_config $override, sub {
+ $mech->submit_form_ok( { with_fields => { pc => $test->{postcode}, } },
+ "submit location" );
+ $mech->follow_link_ok(
+ { text_regex => qr/skip this step/i, },
+ "follow 'skip this step' link"
+ );
+ };
my $fields = $mech->visible_form_values('mapSkippedForm');
if ( $test->{fms_extra_title} ) {
@@ -980,7 +1115,7 @@ for my $test (
my $submission_fields = {
title => "Test Report",
detail => 'Test report details.',
- photo => '',
+ photo1 => '',
email => 'firstlast@example.com',
may_show_name => '1',
phone => '07903 123 456',
@@ -999,15 +1134,16 @@ for my $test (
$submission_fields->{name} = 'Test User';
}
- $mech->submit_form_ok( { with_fields => $submission_fields },
- "submit good details" );
+ FixMyStreet::override_config $override, sub {
+ $mech->submit_form_ok( { with_fields => $submission_fields },
+ "submit good details" );
+ };
my $email = $mech->get_email;
ok $email, "got an email";
- like $email->body, qr/confirm the problem/i, "confirm the problem";
+ like $mech->get_text_body_from_email($email), qr/confirm that you want to send your\s+report/i, "confirm the problem";
- my ($url) = $email->body =~ m{(https?://\S+)};
- ok $url, "extracted confirm url '$url'";
+ my $url = $mech->get_link_from_email($email);
# confirm token in order to update the user details
$mech->get_ok($url);
@@ -1018,7 +1154,7 @@ for my $test (
my $report = $user->problems->first;
ok $report, "Found the report";
- my $extras = $report->extra;
+ my $extras = $report->get_extra_fields;
is $user->title, $test->{'user_title'}, 'user title correct';
is_deeply $extras, $test->{extra}, 'extra contains correct values';
@@ -1030,7 +1166,7 @@ for my $test (
subtest 'user title not reset if no user title in submission' => sub {
$mech->log_out_ok;
- $mech->host( 'http://fixmystreet.com' );
+ $mech->host( 'www.fixmystreet.com' );
my $user = $mech->log_in_ok( 'userwithtitle@example.com' );
@@ -1047,7 +1183,7 @@ subtest 'user title not reset if no user title in submission' => sub {
my $submission_fields = {
title => "Test Report",
detail => 'Test report details.',
- photo => '',
+ photo1 => '',
name => 'Has Title',
may_show_name => '1',
phone => '07903 123 456',
@@ -1055,18 +1191,23 @@ subtest 'user title not reset if no user title in submission' => sub {
};
$mech->get_ok('/');
- $mech->submit_form_ok( { with_fields => { pc => 'EH99 1SP', } },
- "submit location" );
- $mech->follow_link_ok(
- { text_regex => qr/skip this step/i, },
- "follow 'skip this step' link"
- );
-
- my $fields = $mech->visible_form_values('mapSkippedForm');
- ok !exists( $fields->{fms_extra_title} ), 'user title field not displayed';
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $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"
+ );
+
+ my $fields = $mech->visible_form_values('mapSkippedForm');
+ ok !exists( $fields->{fms_extra_title} ), 'user title field not displayed';
- $mech->submit_form_ok( { with_fields => $submission_fields },
- "submit good details" );
+ $mech->submit_form_ok( { with_fields => $submission_fields },
+ "submit good details" );
+ };
$user->discard_changes;
my $report = $user->problems->first;
@@ -1075,79 +1216,427 @@ subtest 'user title not reset if no user title in submission' => sub {
is $user->title, 'MR', 'User title unchanged';
};
-SKIP: {
- skip( "Need 'lichfielddc' in ALLOWED_COBRANDS config", 100 )
- unless FixMyStreet::Cobrand->exists('lichfielddc');
+subtest "test Hart" => sub {
+ for my $test (
+ {
+ desc => 'confirm link for cobrand council in two tier cobrand links to cobrand site',
+ category => 'Trees',
+ council => 2333,
+ national => 0,
+ button => 'submit_register',
+ },
+ {
+ desc => 'confirm link for non cobrand council in two tier cobrand links to national site',
+ category => 'Street Lighting',
+ council => 2227,
+ national => 1,
+ button => 'submit_register',
+ },
+ {
+ desc => 'confirmation page for cobrand council in two tier cobrand links to cobrand site',
+ category => 'Trees',
+ council => 2333,
+ national => 0,
+ confirm => 1,
+ },
+ {
+ desc => 'confirmation page for non cobrand council in two tier cobrand links to national site',
+ category => 'Street Lighting',
+ council => 2227,
+ national => 1,
+ confirm => 1,
+ },
+ ) {
+ subtest $test->{ desc } => sub {
+ my $test_email = 'test-22@example.com';
+ $mech->host( 'hart.fixmystreet.com' );
+ $mech->clear_emails_ok;
+ $mech->log_out_ok;
+
+ my $user = $mech->log_in_ok($test_email) if $test->{confirm};
+
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'hart', 'fixmystreet' ],
+ BASE_URL => 'http://www.fixmystreet.com',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok('/around');
+ $mech->content_contains( "Hart Council" );
+ $mech->submit_form_ok( { with_fields => { pc => 'GU51 4AE' } }, "submit location" );
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ my %optional_fields = $test->{confirm} ? () :
+ ( email => $test_email, phone => '07903 123 456' );
+
+ # we do this as otherwise test::www::mechanize::catalyst
+ # goes to the value set in ->host above irregardless and
+ # that is a 404. It works but it is not pleasant.
+ $mech->clear_host if $test->{confirm} && $test->{national};
+ $mech->submit_form_ok(
+ {
+ button => $test->{button},
+ with_fields => {
+ title => 'Test Report',
+ detail => 'Test report details.',
+ photo1 => '',
+ name => 'Joe Bloggs',
+ may_show_name => '1',
+ category => $test->{category},
+ %optional_fields
+ }
+ },
+ "submit good details"
+ );
+ };
+ is_deeply $mech->page_errors, [], "check there were no errors";
+
+ # check that the user has been created/ not changed
+ $user =
+ FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ ok $user, "user found";
+
+ # find the report
+ my $report = $user->problems->first;
+ ok $report, "Found the report";
+
+ # Check the report has been assigned appropriately
+ is $report->bodies_str, $body_ids{$test->{council}};
+
+ if ( $test->{confirm} ) {
+ is $mech->uri->path, "/report/new";
+ my $base = 'www.fixmystreet.com';
+ $base = "hart.fixmystreet.com" unless $test->{national};
+ $mech->content_contains("$base/report/" . $report->id, "links to correct site");
+ } else {
+ # receive token
+ my $email = $mech->get_email;
+ ok $email, "got an email";
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/to confirm that you want to send your/i, "confirm the problem";
+
+ # does it reference the fact that this report hasn't been sent to Hart?
+ if ( $test->{national} ) {
+ like $body, qr/Hart Council is not responsible for this type/i, "mentions report hasn't gone to Hart";
+ } else {
+ unlike $body, qr/Hart Council is not responsible for this type/i, "doesn't mention report hasn't gone to Hart";
+ }
- my $test_email = 'test-22@example.com';
- $mech->host( 'http://lichfielddc.fixmystreet.com/' );
- $mech->clear_emails_ok;
- $mech->log_out_ok;
+ my $url = $mech->get_link_from_email($email);
+
+ # confirm token
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'hart', 'fixmystreet' ],
+ BASE_URL => 'http://www.fixmystreet.com',
+ }, sub {
+ $mech->get_ok($url);
+ };
+
+ my $base = 'www.fixmystreet.com';
+ $base = 'hart.fixmystreet.com' unless $test->{national};
+ $mech->content_contains( $base . '/report/' .
+ $report->id, 'confirm page links to correct site' );
+
+ if ( $test->{national} ) {
+ # Shouldn't be found, as it was a county problem
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'hart', 'fixmystreet' ],
+ }, sub {
+ is $mech->get( '/report/' . $report->id )->code, 404, "report not found";
+ };
+
+ # But should be on the main site
+ $mech->host( 'www.fixmystreet.com' );
+ }
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'hart', 'fixmystreet' ],
+ }, sub {
+ $mech->get_ok( '/report/' . $report->id );
+ };
+ }
- $mech->get_ok('/around');
- $mech->content_contains( "Lichfield District Council FixMyStreet" );
- $mech->submit_form_ok( { with_fields => { pc => 'WS13 7RD' } }, "submit location" );
- $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
- $mech->submit_form_ok(
- {
- button => 'submit_register',
- with_fields => {
- title => 'Test Report',
- detail => 'Test report details.',
- photo => '',
- name => 'Joe Bloggs',
- may_show_name => '1',
- email => $test_email,
- phone => '07903 123 456',
- category => 'Street lighting',
+ $report->discard_changes;
+ is $report->state, 'confirmed', "Report is now confirmed";
+
+ is $report->name, 'Joe Bloggs', 'name updated correctly';
+
+ $mech->delete_user($user);
+ };
+ }
+};
+
+subtest "categories from deleted bodies shouldn't be visible for new reports" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok('/report/new/ajax?latitude=51.896268&longitude=-2.093063'); # Cheltenham
+ ok $mech->content_contains( $contact3->category );
+
+ # Delete the body which the contact belongs to.
+ $contact3->body->update( { deleted => 1 } );
+
+ $mech->get_ok('/report/new/ajax?latitude=51.896268&longitude=-2.093063'); # Cheltenham
+ ok $mech->content_lacks( $contact3->category );
+
+ $contact3->body->update( { deleted => 0 } );
+ };
+};
+
+subtest "unresponsive body handling works" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ # Test body-level send method
+ my $old_send = $contact1->body->send_method;
+ $contact1->body->update( { send_method => 'Refused' } );
+ $mech->get_ok('/report/new/ajax?latitude=55.952055&longitude=-3.189579'); # Edinburgh
+ my $body_id = $contact1->body->id;
+ ok $mech->content_like( qr{Edinburgh.*accept reports.*/unresponsive\?body=$body_id} );
+
+ my $test_email = 'test-2@example.com';
+ $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" );
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ title => "Test Report at café",
+ detail => 'Test report details.',
+ photo1 => '',
+ name => 'Joe Bloggs',
+ email => $test_email,
+ may_show_name => '1',
+ phone => '07903 123 456',
+ category => 'Trees',
+ }
+ },
+ "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";
+
+ like $mech->get_text_body_from_email, qr/despite not being sent/i, "correct email sent";
+
+ $user->problems->delete;
+ $mech->clear_emails_ok;
+
+ # Make sure the same behaviour occurs for reports from the mobile app
+ $mech->log_out_ok;
+ $mech->post_ok( '/report/new/mobile', {
+ title => "Test Report at café",
+ detail => 'Test report details.',
+ photo1 => '',
+ name => 'Joe Bloggs',
+ email => $test_email,
+ may_show_name => '1',
+ phone => '07903 123 456',
+ category => 'Trees',
+ service => 'iOS',
+ lat => 55.952055,
+ lon => -3.189579,
+ pc => '',
+ used_map => '1',
+ submit_register => '1',
+ password_register => '',
+ });
+ my $res = $mech->response;
+ ok $res->header('Content-Type') =~ m{^application/json\b}, 'response should be json';
+
+ $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ ok $user, "test user does exist";
+
+ $report = $user->problems->first;
+ ok $report, "Found the report";
+ is $report->bodies_str, undef, "Report not going anywhere";
+
+ like $mech->get_text_body_from_email, qr/despite not being sent/i, "correct email sent";
+
+ $user->problems->delete;
+ $mech->clear_emails_ok;
+
+ $contact1->body->update( { send_method => $old_send } );
+
+ # And test per-category refusing
+ my $old_email = $contact3->email;
+ $contact3->update( { email => 'REFUSED' } );
+ $mech->get_ok('/report/new/category_extras?category=Trees&latitude=51.896268&longitude=-2.093063');
+ ok $mech->content_like( qr/Cheltenham.*Trees.*unresponsive.*category=Trees/ );
+
+ $mech->get_ok('/around');
+ $mech->submit_form_ok( { with_fields => { pc => 'GL50 2PR', } }, "submit location" );
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, }, "follow 'skip this step' link" );
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ title => "Test Report at café",
+ detail => 'Test report details.',
+ photo1 => '',
+ name => 'Joe Bloggs',
+ email => $test_email,
+ may_show_name => '1',
+ phone => '07903 123 456',
+ category => 'Trees',
+ }
+ },
+ "submit good details"
+ );
+
+ $report = $user->problems->first;
+ ok $report, "Found the report";
+ is $report->bodies_str, undef, "Report not going anywhere";
+
+ $contact3->update( { email => $old_email } );
+ $mech->delete_user($user);
+ };
+};
+
+subtest "unresponsive body page works" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ }, sub {
+ my $old_send = $contact1->body->send_method;
+ my $body_id = $contact1->body->id;
+ my $url = "/unresponsive?body=$body_id";
+ is $mech->get($url)->code, 404, "page not found";
+ $contact1->body->update( { send_method => 'Refused' } );
+ $mech->get_ok($url);
+ $mech->content_contains('Edinburgh');
+ $contact1->body->update( { send_method => $old_send } );
+
+ my $old_email = $contact3->email;
+ $body_id = $contact3->body->id;
+ $url = "/unresponsive?body=$body_id;category=Trees";
+ is $mech->get($url)->code, 404, "page not found";
+ $contact3->update( { email => 'REFUSED' } );
+ $mech->get_ok($url);
+ $mech->content_contains('Cheltenham');
+ $mech->content_contains('Trees');
+ $contact3->update( { email => $old_email } );
+ };
+};
+
+subtest "extra google analytics code displayed on logged in problem creation" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ BASE_URL => 'https://www.fixmystreet.com',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ # check that the user does not exist
+ my $test_email = 'test-2@example.com';
+
+ $mech->clear_emails_ok;
+ my $user = $mech->log_in_ok($test_email);
+
+ # setup the user.
+ ok $user->update(
+ {
+ name => 'Test User',
+ phone => '01234 567 890',
}
- },
- "submit good details"
- );
- is_deeply $mech->page_errors, [], "check there were no errors";
+ ),
+ "set users details";
- # check that the user has been created/ not changed
- my $user =
- FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
- ok $user, "user found";
+ # submit initial pc form
+ $mech->get_ok('/around');
+ $mech->submit_form_ok( { with_fields => { pc => 'GL50 2PR', } },
+ "submit location" );
- # find the report
- my $report = $user->problems->first;
- ok $report, "Found the report";
+ # click through to the report page
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
+ "follow 'skip this step' link" );
- # Check the report has been assigned appropriately
- is $report->council, 2240;
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ title => "Test Report at café",
+ detail => 'Test report details.',
+ photo1 => '',
+ name => 'Joe Bloggs',
+ may_show_name => '1',
+ phone => '07903 123 456',
+ category => 'Trees',
+ }
+ },
+ "submit good details"
+ );
- # receive token
- my $email = $mech->get_email;
- ok $email, "got an email";
- like $email->body, qr/confirm the problem/i, "confirm the problem";
+ # find the report
+ my $report = $user->problems->first;
+ ok $report, "Found the report";
- my ($url) = $email->body =~ m{(http://\S+)};
- ok $url, "extracted confirm url '$url'";
+ $mech->content_contains( "'id': 'report/" . $report->id . "'", 'extra google code present' );
- # confirm token
- $mech->get_ok($url);
- $report->discard_changes;
- is $report->state, 'confirmed', "Report is now confirmed";
+ # cleanup
+ $mech->delete_user($user);
+ };
+};
- # Shouldn't be found, as it was a county problem
- is $mech->get( '/report/' . $report->id )->code, 404, "report not found";
+subtest "extra google analytics code displayed on email confirmation problem creation" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ BASE_URL => 'https://www.fixmystreet.com',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->log_out_ok;
+ $mech->clear_emails_ok;
- # But should be on the main site
- $mech->host( 'www.fixmystreet.com' );
- $mech->get_ok( '/report/' . $report->id );
- is $report->name, 'Joe Bloggs', 'name updated correctly';
+ $mech->get_ok('/');
+ $mech->submit_form_ok( { with_fields => { pc => 'GL50 2PR' } },
+ "submit location" );
+ $mech->follow_link_ok(
+ { text_regex => qr/skip this step/i, },
+ "follow 'skip this step' link"
+ );
- $mech->delete_user($user);
-}
+ my $fields = $mech->visible_form_values('mapSkippedForm');
+ my $submission_fields = {
+ title => "Test Report",
+ detail => 'Test report details.',
+ photo1 => '',
+ email => 'firstlast@example.com',
+ name => 'Test User',
+ may_show_name => '1',
+ phone => '07903 123 456',
+ category => 'Trees',
+ password_register => '',
+ };
-$contact1->delete;
-$contact2->delete;
-$contact3->delete;
-$contact4->delete;
-$contact5->delete;
-$contact6->delete;
-$contact7->delete;
+ $mech->submit_form_ok( { with_fields => $submission_fields },
+ "submit good details" );
+
+ my $email = $mech->get_email;
+ ok $email, "got an email";
+ like $mech->get_text_body_from_email($email), qr/confirm that you want to/i, "confirm the problem";
+
+ my $url = $mech->get_link_from_email($email);
+
+ # confirm token in order to update the user details
+ $mech->get_ok($url);
+
+ # find the report
+ my $user =
+ FixMyStreet::App->model('DB::User')
+ ->find( { email => 'firstlast@example.com' } );
+
+ my $report = $user->problems->first;
+ ok $report, "Found the report";
+
+ $mech->content_contains( "'id': 'report/" . $report->id . "'", 'extra google code present' );
+
+ $user->problems->delete;
+ $user->alerts->delete;
+ $user->delete;
+ };
+};
done_testing();
+
+END {
+ $mech->delete_body($_) foreach @bodies;
+}
diff --git a/t/app/controller/report_new_mobile.t b/t/app/controller/report_new_mobile.t
new file mode 100644
index 000000000..3dfb99b2f
--- /dev/null
+++ b/t/app/controller/report_new_mobile.t
@@ -0,0 +1,42 @@
+use Test::More;
+use FixMyStreet::TestMech;
+use LWP::Protocol::PSGI;
+use t::Mock::MapItZurich;
+
+my $mech = FixMyStreet::TestMech->new;
+
+# disable info logs for this test run
+FixMyStreet::App->log->disable('info');
+END { FixMyStreet::App->log->enable('info'); }
+
+LWP::Protocol::PSGI->register(t::Mock::MapItZurich->to_psgi_app, host => 'mapit.zurich');
+
+subtest "Check signed up for alert when logged in" => sub {
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.zurich',
+ MAPIT_TYPES => [ 'O08' ],
+ }, sub {
+ $mech->log_in_ok('user@example.org');
+ $mech->post_ok( '/report/new/mobile', {
+ service => 'iPhone',
+ title => 'Title',
+ detail => 'Problem detail',
+ lat => 47.381817,
+ lon => 8.529156,
+ email => 'user@example.org',
+ pc => '',
+ name => 'Name',
+ });
+ my $res = $mech->response;
+ ok $res->header('Content-Type') =~ m{^application/json\b}, 'response should be json';
+
+ my $user = FixMyStreet::DB->resultset('User')->search({ email => 'user@example.org' })->first;
+ my $a = FixMyStreet::DB->resultset('Alert')->search({ user_id => $user->id })->first;
+ isnt $a, undef, 'User is signed up for alert';
+ };
+};
+
+END {
+ $mech->delete_user('user@example.org');
+ done_testing();
+}
diff --git a/t/app/controller/report_new_open311.t b/t/app/controller/report_new_open311.t
index e9ada9f41..e3a464f88 100644
--- a/t/app/controller/report_new_open311.t
+++ b/t/app/controller/report_new_open311.t
@@ -3,44 +3,46 @@ use warnings;
use Test::More;
use FixMyStreet::TestMech;
+use FixMyStreet::App;
use Web::Scraper;
+# disable info logs for this test run
+FixMyStreet::App->log->disable('info');
+END { FixMyStreet::App->log->enable('info'); }
+
my $mech = FixMyStreet::TestMech->new;
-FixMyStreet::App->model('DB::Body')->find_or_create( {
- area_id => 2651,
- endpoint => 'http://example.com/open311',
- jurisdiction => 'mySociety',
- api_key => 'apikey',
-} );
-
-my %contact_params = (
- confirmed => 1,
- deleted => 0,
- editor => 'Test',
- whenedited => \'current_timestamp',
- note => 'Created for test',
-);
+my $body = $mech->create_body_ok(2245, 'Wiltshire Council');
+$body->update({
+ endpoint => 'http://example.com/open311',
+ jurisdiction => 'mySociety',
+ api_key => 'apikey',
+});
+
# Let's make some contacts to send things to!
-my $contact1 = FixMyStreet::App->model('DB::Contact')->find_or_create( {
- %contact_params,
- body_id => 2651, # Edinburgh
+my $contact1 = $mech->create_contact_ok(
+ body_id => $body->id, # Edinburgh
category => 'Street lighting',
email => '100',
extra => [ { description => 'Lamppost number', code => 'number', required => 'True' },
{ description => 'Lamppost type', code => 'type', required => 'False', values =>
{ value => [ { name => ['Gas'], key => ['old'] }, { name => [ 'Yellow' ], key => [ 'modern' ] } ] }
- }
+ }
+ ],
+);
+my $contact1b = $mech->create_contact_ok(
+ body_id => $body->id, # Edinburgh
+ category => 'Moon lighting',
+ email => '100b',
+ extra => [ { description => 'Moon type', code => 'type', required => 'False', values =>
+ [ { name => 'Full', key => 'full' }, { name => 'New', key => 'new' } ] }
],
-} );
-my $contact2 = FixMyStreet::App->model('DB::Contact')->find_or_create( {
- %contact_params,
- body_id => 2651, # Edinburgh
+);
+my $contact2 = $mech->create_contact_ok(
+ body_id => $body->id, # Edinburgh
category => 'Graffiti Removal',
email => '101',
-} );
-ok $contact1, "created test contact 1";
-ok $contact2, "created test contact 2";
+);
# test that the various bit of form get filled in and errors correctly
# generated.
@@ -51,7 +53,9 @@ foreach my $test (
fields => {
title => '',
detail => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
name => '',
may_show_name => '1',
email => '',
@@ -66,9 +70,9 @@ foreach my $test (
type => 'old',
},
errors => [
+ 'This information is required',
'Please enter a subject',
'Please enter some details',
- 'This information is required',
'Please enter your email',
'Please enter your name',
],
@@ -111,17 +115,22 @@ foreach my $test (
$mech->get_ok('/around');
# submit initial pc form
- $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } },
- "submit location" );
- is_deeply $mech->page_errors, [], "no errors for pc '$test->{pc}'";
-
- # click through to the report page
- $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
- "follow 'skip this step' link" );
-
- # submit the main form
- $mech->submit_form_ok( { with_fields => $test->{fields} },
- "submit form" );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => { pc => $test->{pc} } },
+ "submit location" );
+ is_deeply $mech->page_errors, [], "no errors for pc '$test->{pc}'";
+
+ # click through to the report page
+ $mech->follow_link_ok( { text_regex => qr/skip this step/i, },
+ "follow 'skip this step' link" );
+
+ # submit the main form
+ $mech->submit_form_ok( { with_fields => $test->{fields} },
+ "submit form" );
+ };
# check that we got the errors expected
is_deeply $mech->page_errors, $test->{errors}, "check errors";
@@ -147,21 +156,27 @@ foreach my $test (
%{ $test->{fields} },
%{ $test->{submit_with} },
};
- $mech->submit_form_ok( { with_fields => $new_values } );
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->submit_form_ok( { with_fields => $new_values } );
+ };
$user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
ok $user, 'created user';
my $prob = $user->problems->first;
ok $prob, 'problem created';
- is_deeply $prob->extra, $test->{extra}, 'extra open311 data added to problem';
+ is_deeply $prob->get_extra_fields, $test->{extra}, 'extra open311 data added to problem';
$user->problems->delete;
$user->delete;
};
}
-$contact1->delete;
-$contact2->delete;
-
done_testing();
+
+END {
+ $mech->delete_body($body);
+}
diff --git a/t/app/controller/report_updates.t b/t/app/controller/report_updates.t
index 2c7294222..de153978b 100644
--- a/t/app/controller/report_updates.t
+++ b/t/app/controller/report_updates.t
@@ -13,15 +13,11 @@ my $mech = FixMyStreet::TestMech->new;
$mech->delete_user('commenter@example.com');
$mech->delete_user('test@example.com');
-my $user =
- FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'test@example.com', name => 'Test User' } );
-ok $user, "created test user";
+my $user = $mech->create_user_ok('test@example.com', name => 'Test User');
-my $user2 =
- FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'commenter@example.com', name => 'Commenter' } );
-ok $user2, "created comment user";
+my $user2 = $mech->create_user_ok('commenter@example.com', name => 'Commenter');
+
+my $body = $mech->create_body_ok(2504, 'Westminster City Council');
my $dt = DateTime->new(
year => 2011,
@@ -35,7 +31,7 @@ my $dt = DateTime->new(
my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
{
postcode => 'SW1A 1AA',
- council => '2504',
+ bodies_str => $body->id,
areas => ',105255,11806,11828,2247,2504,',
category => 'Other',
title => 'Test 2',
@@ -135,6 +131,19 @@ for my $test (
};
}
+subtest "updates displayed on report with empty bodies_str" => sub {
+ my $old_bodies_str = $report->bodies_str;
+ $report->update({ bodies_str => undef });
+ $comment->update({ problem_state => 'fixed' , mark_open => 'false', mark_fixed => 'false' });
+
+ $mech->get_ok("/report/$report_id");
+
+ my $meta = $mech->extract_update_metas;
+ is scalar @$meta, 1, 'update displayed';
+
+ $report->update({ bodies_str => $old_bodies_str });
+};
+
subtest "unconfirmed updates not displayed" => sub {
$comment->state( 'unconfirmed' );
$comment->update;
@@ -197,7 +206,9 @@ for my $test (
rznvy => '',
update => '',
name => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
fixed => undef,
add_alert => 1,
may_show_name => undef,
@@ -214,7 +225,9 @@ for my $test (
rznvy => 'test',
update => '',
name => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
fixed => undef,
add_alert => 1,
may_show_name => undef,
@@ -231,7 +244,9 @@ for my $test (
rznvy => 'test @ example. com',
update => '',
name => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
fixed => undef,
add_alert => 1,
may_show_name => undef,
@@ -250,7 +265,9 @@ for my $test (
rznvy => 'test@EXAMPLE.COM',
update => '',
name => '',
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
fixed => undef,
add_alert => 1,
may_show_name => undef,
@@ -290,7 +307,9 @@ for my $test (
rznvy => '',
may_show_name => 1,
add_alert => 1,
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
update => '',
fixed => undef,
remember_me => undef,
@@ -314,7 +333,9 @@ for my $test (
rznvy => '',
may_show_name => 1,
add_alert => 1,
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
update => '',
fixed => undef,
remember_me => undef,
@@ -351,13 +372,14 @@ 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";
- like $email->body, qr/confirm the update you/i, "Correct email text";
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/confirm your update on/i, "Correct email text";
- my ( $url, $url_token ) = $email->body =~ m{(http://\S+/C/)(\S+)};
+ my $url = $mech->get_link_from_email($email);
+ my ($url_token) = $url =~ m{/C/(\S+)};
ok $url, "extracted confirm url '$url'";
my $token = FixMyStreet::App->model('DB::Token')->find(
@@ -384,7 +406,7 @@ for my $test (
is $update->text, $details->{update}, 'update text';
is $add_alerts, $details->{add_alert} ? 1 : 0, 'do not sign up for alerts';
- $mech->get_ok( $url . $url_token );
+ $mech->get_ok( $url );
$mech->content_contains("/report/$report_id#update_$update_id");
my $unreg_user = FixMyStreet::App->model( 'DB::User' )->find( { email => $details->{rznvy} } );
@@ -407,24 +429,103 @@ for my $test (
$report->state('confirmed');
$report->update;
+for my $test (
+ {
+ desc => 'overriding email confirmation allows report confirmation with no email sent',
+ initial_values => {
+ name => '',
+ rznvy => '',
+ may_show_name => 1,
+ add_alert => 1,
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ update => '',
+ fixed => undef,
+ remember_me => undef,
+ password_register => '',
+ password_sign_in => '',
+ },
+ form_values => {
+ submit_update => 1,
+ rznvy => 'unregistered@example.com',
+ update => "update no email confirm",
+ add_alert => 1,
+ name => 'Unreg User',
+ may_show_name => undef,
+ },
+ changes => {
+ update => "Update no email confirm",
+ },
+ }
+) {
+ subtest $test->{desc} => sub {
+ my $send_confirmation_mail_override = Sub::Override->new(
+ "FixMyStreet::Cobrand::Default::never_confirm_updates",
+ sub { return 1; }
+ );
+ $mech->log_out_ok();
+ $mech->clear_emails_ok();
+
+ $mech->get_ok("/report/$report_id");
+
+ my $values = $mech->visible_form_values('updateForm');
+
+ is_deeply $values, $test->{initial_values}, 'initial form values';
+
+ $mech->submit_form_ok(
+ {
+ with_fields => $test->{form_values}
+ },
+ 'submit update'
+ );
+ $mech->content_contains("/report/$report_id");
+ $mech->get_ok("/report/$report_id");
+
+ $mech->content_contains('Test 2');
+ $mech->content_contains('Update no email confirm');
+
+ my $email = $mech->email_count_is(0);
+
+ my $update =
+ FixMyStreet::App->model('DB::Comment')->find( { problem_id => $report_id, text => 'Update no email confirm' } );
+ my $update_id = $update->id;
+
+ $mech->content_contains('name="update_' . $update_id . '"');
+
+ my $details = {
+ %{ $test->{form_values} },
+ %{ $test->{changes} }
+ };
+
+ ok $update, 'found update in database';
+ is $update->state, 'confirmed', 'update confirmed';
+ is $update->user->email, $details->{rznvy}, 'update email';
+ is $update->text, $details->{update}, 'update text';
+
+ my $unreg_user = FixMyStreet::App->model( 'DB::User' )->find( { email => $details->{rznvy} } );
+
+ ok $unreg_user, 'found user';
+
+ $mech->delete_user( $unreg_user );
+ $send_confirmation_mail_override->restore();
+ };
+}
+
subtest 'check non authority user cannot change set state' => sub {
$mech->log_in_ok( $user->email );
- $user->from_body( 0 );
+ $user->from_body( undef );
$user->update;
$mech->get_ok("/report/$report_id");
- $mech->post_ok( "/report/update", {
- submit_update => 1,
- id => $report_id,
- name => $user->name,
- may_show_name => 1,
- add_alert => undef,
- photo => '',
- update => 'this is a forbidden update',
- state => 'fixed - council',
+ $mech->submit_form_ok( {
+ form_id => 'form_update_form',
+ fields => {
+ may_show_name => 1,
+ update => 'this is a forbidden update',
+ state => 'fixed - council',
},
- 'submitted with state',
- );
+ }, 'submitted with state');
is $mech->uri->path, "/report/update", "at /report/update";
@@ -437,22 +538,18 @@ subtest 'check non authority user cannot change set state' => sub {
for my $state ( qw/unconfirmed hidden partial/ ) {
subtest "check that update cannot set state to $state" => sub {
$mech->log_in_ok( $user->email );
- $user->from_body( 2504 );
+ $user->from_body( $body->id );
$user->update;
$mech->get_ok("/report/$report_id");
- $mech->post_ok( "/report/update", {
- submit_update => 1,
- id => $report_id,
- name => $user->name,
- may_show_name => 1,
- add_alert => undef,
- photo => '',
- update => 'this is a forbidden update',
- state => $state,
+ $mech->submit_form_ok( {
+ form_id => 'form_update_form',
+ fields => {
+ may_show_name => 1,
+ update => 'this is a forbidden update',
+ state => $state,
},
- 'submitted with state',
- );
+ }, 'submitted with state');
is $mech->uri->path, "/report/update", "at /report/update";
@@ -469,96 +566,136 @@ for my $test (
fields => {
name => $user->name,
may_show_name => 1,
- add_alert => undef,
- photo => '',
update => 'Set state to investigating',
state => 'investigating',
},
state => 'investigating',
},
{
- desc => 'from authority user marks report as planned',
+ desc => 'from authority user marks report as in progress',
fields => {
name => $user->name,
may_show_name => 1,
- add_alert => undef,
- photo => '',
- update => 'Set state to planned',
- state => 'planned',
+ update => 'Set state to in progress',
+ state => 'in progress',
+ },
+ state => 'in progress',
+ },
+ {
+ desc => 'from authority user marks report as fixed',
+ fields => {
+ name => $user->name,
+ may_show_name => 1,
+ update => 'Set state to fixed',
+ state => 'fixed',
},
- state => 'planned',
+ state => 'fixed - council',
},
{
- desc => 'from authority user marks report as in progress',
+ desc => 'from authority user marks report as action scheduled',
fields => {
name => $user->name,
may_show_name => 1,
- add_alert => undef,
- photo => '',
- update => 'Set state to in progress',
- state => 'in progress',
+ update => 'Set state to action scheduled',
+ state => 'action scheduled',
},
- state => 'in progress',
+ state => 'action scheduled',
},
{
- desc => 'from authority user marks report as closed',
+ desc => 'from authority user marks report as unable to fix',
fields => {
name => $user->name,
may_show_name => 1,
- add_alert => undef,
- photo => '',
- update => 'Set state to closed',
- state => 'closed',
+ update => 'Set state to unable to fix',
+ state => 'no further action',
},
- state => 'closed',
+ state => 'unable to fix',
},
{
- desc => 'from authority user marks report as fixed',
+ desc => 'from authority user marks report as internal referral',
fields => {
name => $user->name,
may_show_name => 1,
- add_alert => undef,
- photo => '',
- update => 'Set state to fixed',
- state => 'fixed',
+ update => 'Set state to internal referral',
+ state => 'internal referral',
},
- state => 'fixed - council',
+ state => 'internal referral',
+ meta => "an internal referral",
},
{
- desc => 'from authority user marks report as confirmed',
+ desc => 'from authority user marks report as not responsible',
fields => {
name => $user->name,
may_show_name => 1,
- add_alert => undef,
- photo => '',
- update => 'Set state to confirmed',
- state => 'confirmed',
+ update => 'Set state to not responsible',
+ state => 'not responsible',
+ },
+ state => 'not responsible',
+ meta => "not the council's responsibility"
+ },
+ {
+ desc => 'from authority user marks report as duplicate',
+ fields => {
+ name => $user->name,
+ may_show_name => 1,
+ update => 'Set state to duplicate',
+ state => 'duplicate',
+ },
+ state => 'duplicate',
+ meta => 'a duplicate report',
+ },
+ {
+ desc => 'from authority user marks report as internal referral',
+ fields => {
+ name => $user->name,
+ may_show_name => 1,
+ update => 'Set state to internal referral',
+ state => 'internal referral',
},
- state => 'confirmed',
+ state => 'internal referral',
+ meta => 'an internal referral',
},
{
desc => 'from authority user marks report sent to two councils as fixed',
fields => {
name => $user->name,
may_show_name => 1,
- add_alert => undef,
- photo => '',
update => 'Set state to fixed',
state => 'fixed',
},
state => 'fixed - council',
- report_councils => '2504,2505',
+ report_bodies => $body->id . ',2505',
+ },
+ {
+ desc => 'from authority user show username for users with correct permissions',
+ fields => {
+ name => $user->name,
+ may_show_name => 1,
+ update => 'Set state to fixed',
+ state => 'fixed',
+ },
+ state => 'fixed - council',
+ report_bodies => $body->id . ',2505',
+ view_username => 1
},
) {
subtest $test->{desc} => sub {
$report->comments->delete;
- if ( $test->{ report_councils } ) {
- $report->council( $test->{ report_councils } );
+ if ( $test->{ report_bodies } ) {
+ $report->bodies_str( $test->{ report_bodies } );
$report->update;
}
$mech->log_in_ok( $user->email );
- $user->from_body( 2504 );
+
+ if ($test->{view_username}) {
+ ok $user->user_body_permissions->create({
+ body => $body,
+ permission_type => 'view_body_contribute_details'
+ }), 'Give user view_body_contribute_details permissions';
+ }
+
+ $user->from_body( $body->id );
$user->update;
$mech->get_ok("/report/$report_id");
@@ -569,6 +706,7 @@ for my $test (
},
'submit update'
);
+ $mech->get_ok("/report/$report_id");
$report->discard_changes;
my $update = $report->comments->first;
@@ -577,14 +715,22 @@ for my $test (
is $update->problem_state, $test->{state}, 'problem state set';
my $update_meta = $mech->extract_update_metas;
- # setting it to confirmed shouldn't say anything
- if ( $test->{fields}->{state} ne 'confirmed' ) {
- like $update_meta->[0], qr/marked as $test->{fields}->{state}$/, 'update meta includes state change';
+ my $meta_state = $test->{meta} || $test->{fields}->{state};
+ if ( $test->{reopened} ) {
+ like $update_meta->[0], qr/reopened$/, 'update meta says reopened';
+ } elsif ( $test->{state} eq 'duplicate' ) {
+ like $update_meta->[0], qr/closed as $meta_state$/, 'update meta includes state change';
} else {
- like $update_meta->[0], qr/reopened$/, 'update meta includes state change';
+ like $update_meta->[0], qr/marked as $meta_state$/, 'update meta includes state change';
+ }
+
+ if ($test->{view_username}) {
+ like $update_meta->[0], qr{Westminster City Council \(Test User\)}, 'update meta includes council and user name';
+ $user->user_body_permissions->delete_all;
+ } else {
+ like $update_meta->[0], qr{Westminster City Council}, 'update meta includes council name';
+ $mech->content_contains( '<strong>Westminster City Council</strong>', 'council name in bold');
}
- like $update_meta->[0], qr{Test User \(Westminster City Council\)}, 'update meta includes council name';
- $mech->content_contains( 'Test User (<strong>Westminster City Council</strong>)', 'council name in bold');
$report->discard_changes;
is $report->state, $test->{state}, 'state set';
@@ -598,7 +744,8 @@ subtest 'check meta correct for comments marked confirmed but not marked open' =
user => $user,
problem_id => $report->id,
text => 'update text',
- confirmed => DateTime->now,
+ # Subtract a day to deal with any code/db timezone difference
+ confirmed => DateTime->now( time_zone => 'local' ) - DateTime::Duration->new( days => 1 ),
problem_state => 'confirmed',
anonymous => 0,
mark_open => 0,
@@ -609,7 +756,7 @@ subtest 'check meta correct for comments marked confirmed but not marked open' =
$mech->get_ok( "/report/" . $report->id );
my $update_meta = $mech->extract_update_metas;
- like $update_meta->[0], qr/reopened$/,
+ unlike $update_meta->[0], qr/reopened$/,
'update meta does not say reopened';
$comment->update( { mark_open => 1, problem_state => undef } );
@@ -627,13 +774,170 @@ subtest 'check meta correct for comments marked confirmed but not marked open' =
unlike $update_meta->[0], qr/marked as open$/,
'update meta does not says marked as open';
unlike $update_meta->[0], qr/reopened$/, 'update meta does not say reopened';
- };
+};
+
+subtest "check first comment with no status change has no status in meta" => sub {
+ $mech->log_in_ok( $user->email );
+ $user->from_body( undef );
+ $user->update;
+
+ my $comment = $report->comments->first;
+ $comment->update( { mark_fixed => 0, problem_state => 'confirmed' } );
+
+ $mech->get_ok("/report/$report_id");
+
+ my $update_meta = $mech->extract_update_metas;
+ unlike $update_meta->[0], qr/marked as|reopened/, 'update meta does not include state change';
+};
+
+subtest "check comment with no status change has not status in meta" => sub {
+ $mech->log_in_ok( $user->email );
+ $user->from_body( undef );
+ $user->update;
+
+ my $comment = $report->comments->first;
+ $comment->update( { mark_fixed => 1, problem_state => 'fixed - council' } );
+
+ $mech->get_ok("/report/$report_id");
+
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ name => $user->name,
+ may_show_name => 1,
+ add_alert => undef,
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ update => 'Comment that does not change state',
+ },
+ },
+ 'submit update'
+ );
+ $mech->get_ok("/report/$report_id");
+
+ $report->discard_changes;
+ my @updates = $report->comments->all;
+ is scalar @updates, 2, 'correct number of updates';
+
+ my $update = pop @updates;
+
+ is $report->state, 'fixed - council', 'correct report state';
+ is $update->problem_state, 'fixed - council', 'correct update state';
+ my $update_meta = $mech->extract_update_metas;
+ unlike $update_meta->[1], qr/marked as/, 'update meta does not include state change';
+
+ $user->from_body( $body->id );
+ $user->update;
+
+ $mech->get_ok("/report/$report_id");
+
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ name => $user->name,
+ may_show_name => 1,
+ add_alert => undef,
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ update => 'Comment that sets state to investigating',
+ state => 'investigating',
+ },
+ },
+ 'submit update'
+ );
+ $mech->get_ok("/report/$report_id");
+
+ $report->discard_changes;
+ @updates = $report->comments->search(undef, { order_by => 'created' })->all;;
+
+ is scalar @updates, 3, 'correct number of updates';
+
+ $update = pop @updates;
+
+ is $report->state, 'investigating', 'correct report state';
+ is $update->problem_state, 'investigating', 'correct update state';
+ $update_meta = $mech->extract_update_metas;
+ like $update_meta->[0], qr/marked as fixed/, 'first update meta says fixed';
+ unlike $update_meta->[1], qr/marked as/, 'second update meta does not include state change';
+ like $update_meta->[2], qr/marked as investigating/, 'third update meta says investigating';
+
+ my $dt = DateTime->now( time_zone => "local" )->add( seconds => 1 );
+ $comment = FixMyStreet::App->model('DB::Comment')->find_or_create(
+ {
+ problem_id => $report_id,
+ user_id => $user->id,
+ name => 'Other User',
+ mark_fixed => 'false',
+ text => 'This is some update text',
+ state => 'confirmed',
+ confirmed => $dt->ymd . ' ' . $dt->hms,
+ anonymous => 'f',
+ }
+ );
+
+ $mech->get_ok("/report/$report_id");
+
+ $report->discard_changes;
+ @updates = $report->comments->search(undef, { order_by => 'created' })->all;;
+ is scalar @updates, 4, 'correct number of updates';
+
+ $update = pop @updates;
+
+ is $report->state, 'investigating', 'correct report state';
+ is $update->problem_state, undef, 'no update state';
+ $update_meta = $mech->extract_update_metas;
+ like $update_meta->[0], qr/marked as fixed/, 'first update meta says fixed';
+ unlike $update_meta->[1], qr/marked as/, 'second update meta does not include state change';
+ like $update_meta->[2], qr/marked as investigating/, 'third update meta says investigating';
+ unlike $update_meta->[3], qr/marked as/, 'fourth update meta has no state change';
+};
+
+subtest 'check meta correct for second comment marking as reopened' => sub {
+ $report->comments->delete;
+ my $comment = FixMyStreet::App->model('DB::Comment')->create(
+ {
+ user => $user,
+ problem_id => $report->id,
+ text => 'update text',
+ confirmed => DateTime->now( time_zone => 'local'),
+ problem_state => 'fixed - user',
+ anonymous => 0,
+ mark_open => 0,
+ mark_fixed => 1,
+ state => 'confirmed',
+ }
+ );
+
+ $mech->get_ok( "/report/" . $report->id );
+ my $update_meta = $mech->extract_update_metas;
+ like $update_meta->[0], qr/fixed$/, 'update meta says fixed';
-$user->from_body(0);
+ $comment = FixMyStreet::App->model('DB::Comment')->create(
+ {
+ user => $user,
+ problem_id => $report->id,
+ text => 'update text',
+ confirmed => DateTime->now( time_zone => 'local' ) + DateTime::Duration->new( minutes => 1 ),
+ problem_state => 'confirmed',
+ anonymous => 0,
+ mark_open => 0,
+ mark_fixed => 0,
+ state => 'confirmed',
+ }
+ );
+
+ $mech->get_ok( "/report/" . $report->id );
+ $update_meta = $mech->extract_update_metas;
+ like $update_meta->[1], qr/reopened$/, 'update meta says reopened';
+};
+
+$user->from_body(undef);
$user->update;
$report->state('confirmed');
-$report->council('2504');
+$report->bodies_str($body->id);
$report->update;
for my $test (
@@ -660,9 +964,7 @@ for my $test (
add_alert => undef,
password_sign_in => 'secret2',
},
- field_errors => [
- 'You have successfully signed in; please check and confirm your details are accurate:',
- ],
+ message => 'You have successfully signed in; please check and confirm your details are accurate:',
}
) {
subtest $test->{desc} => sub {
@@ -683,7 +985,10 @@ for my $test (
'submit update'
);
- is_deeply $mech->page_errors, $test->{field_errors}, 'check there were errors';
+ $mech->content_contains($test->{message}) if $test->{message};
+
+ is_deeply $mech->page_errors, $test->{field_errors}, 'check there were errors'
+ if $test->{field_errors};
SKIP: {
skip( "Incorrect password", 5 ) unless $test->{form_values}{password_sign_in} eq $pw;
@@ -698,7 +1003,7 @@ for my $test (
"submit good details"
);
- is $mech->uri->path, "/report/" . $report_id, "redirected to report page";
+ $mech->content_contains('Thank you for updating this issue');
$mech->email_count_is(0);
my $update = $report->comments->first;
@@ -729,7 +1034,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;
@@ -737,10 +1042,11 @@ subtest 'submit an update for a registered user, creating update by email' => su
is $user->name, 'Mr Reg', 'name unchanged';
my $email = $mech->get_email;
- ok $email, "got an email";
- like $email->body, qr/confirm the update you/i, "Correct email text";
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/confirm your update on/i, "Correct email text";
- my ( $url, $url_token ) = $email->body =~ m{(http://\S+/C/)(\S+)};
+ my $url = $mech->get_link_from_email($email);
+ my ($url_token) = $url =~ m{/C/(\S+)};
ok $url, "extracted confirm url '$url'";
my $token = FixMyStreet::App->model('DB::Token')->find( {
@@ -758,7 +1064,7 @@ subtest 'submit an update for a registered user, creating update by email' => su
is $update->user->email, 'registered@example.com', 'update email';
is $update->text, 'Update from a user', 'update text';
- $mech->get_ok( $url . $url_token );
+ $mech->get_ok( $url );
$mech->content_contains("/report/$report_id#update_$update_id");
# User should have new name and password
@@ -771,6 +1077,9 @@ subtest 'submit an update for a registered user, creating update by email' => su
$mech->delete_user( $user );
};
+my $sample_file = file(__FILE__)->parent->file("sample.jpg")->stringify;
+ok -e $sample_file, "sample file $sample_file exists";
+
for my $test (
{
desc => 'submit update for registered user',
@@ -778,7 +1087,9 @@ for my $test (
name => 'Test User',
may_show_name => 1,
add_alert => 1,
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
update => '',
fixed => undef,
},
@@ -788,6 +1099,7 @@ for my $test (
update => 'update from a registered user',
add_alert => undef,
fixed => undef,
+ photo1 => [ [ $sample_file, undef, Content_Type => 'image/jpeg' ], 1 ],
},
changed => {
update => 'Update from a registered user'
@@ -803,7 +1115,9 @@ for my $test (
name => 'Test User',
may_show_name => 1,
add_alert => 1,
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
update => '',
fixed => undef,
},
@@ -829,7 +1143,9 @@ for my $test (
name => 'Test User',
may_show_name => 1,
add_alert => 1,
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
update => '',
fixed => undef,
},
@@ -854,7 +1170,9 @@ for my $test (
name => 'Commenter',
may_show_name => 1,
add_alert => 1,
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
update => '',
fixed => undef,
},
@@ -879,7 +1197,9 @@ for my $test (
name => 'Commenter',
may_show_name => 1,
add_alert => 1,
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
update => '',
},
email => 'commenter@example.com',
@@ -928,7 +1248,14 @@ for my $test (
'submit update'
);
- is $mech->uri->path, "/report/" . $report_id, "redirected to report page";
+ $mech->content_contains('Thank you for updating this issue');
+ $mech->content_contains("/report/" . $report_id);
+ $mech->get_ok("/report/" . $report_id);
+
+ my $update = $report->comments->first;
+ ok $update, 'found update';
+
+ $mech->content_contains("/photo/c/" . $update->id . ".0.jpeg") if $test->{fields}->{photo1};
if ( !defined( $test->{endstate_banner} ) ) {
is $mech->extract_problem_banner->{text}, undef, 'endstate banner';
@@ -943,8 +1270,6 @@ for my $test (
%{ $test->{changed} },
};
- my $update = $report->comments->first;
- ok $update, 'found update';
is $update->text, $results->{update}, 'update text';
is $update->user->email, $test->{email}, 'update user';
is $update->state, 'confirmed', 'update confirmed';
@@ -965,7 +1290,9 @@ foreach my $test (
name => 'Test User',
may_show_name => 1,
add_alert => 1,
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
update => '',
fixed => undef,
},
@@ -982,7 +1309,6 @@ foreach my $test (
alert => 1, # we signed up for alerts before, do not unsign us
anonymous => 0,
answered => 0,
- path => '/report/update',
content =>
"Thanks, glad to hear it's been fixed! Could we just ask if you have ever reported a problem to a council before?",
},
@@ -992,7 +1318,9 @@ foreach my $test (
name => 'Test User',
may_show_name => 1,
add_alert => 1,
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
update => '',
fixed => undef,
},
@@ -1009,7 +1337,6 @@ foreach my $test (
alert => 1, # we signed up for alerts before, do not unsign us
anonymous => 0,
answered => 0,
- path => '/report/update',
content =>
"Thanks, glad to hear it's been fixed! Could we just ask if you have ever reported a problem to a council before?",
},
@@ -1020,7 +1347,9 @@ foreach my $test (
name => 'Test User',
may_show_name => 1,
add_alert => 1,
- photo => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
update => '',
fixed => undef,
},
@@ -1037,7 +1366,6 @@ foreach my $test (
alert => 1, # we signed up for alerts before, do not unsign us
anonymous => 0,
answered => 1,
- path => '/report/' . $report->id,
content => $report->title,
},
)
@@ -1062,7 +1390,7 @@ foreach my $test (
{
problem_id => $report_id,
ever_reported => 'y',
- whensent => \'ms_current_timestamp()',
+ whensent => \'current_timestamp',
}
);
@@ -1090,7 +1418,7 @@ foreach my $test (
$mech->submit_form_ok( { with_fields => $test->{fields}, },
'submit update' );
- is $mech->uri->path, $test->{path}, "page after submission";
+ is $mech->uri->path, '/report/update', "page after submission";
$mech->content_contains( $test->{content} );
@@ -1120,7 +1448,8 @@ foreach my $test (
$mech->submit_form_ok( { with_fields => { reported => 'Yes' } } );
- $mech->content_contains( 'Thank you &mdash; you can' );
+ $mech->content_contains( $report->title );
+ $mech->content_contains( 'Thank you for updating this issue' );
$questionnaire = FixMyStreet::App->model( 'DB::Questionnaire' )->find(
{ problem_id => $report_id }
@@ -1179,7 +1508,7 @@ for my $test (
anonymous => 0,
answered => 1,
path => '/report/update',
- content => "You have successfully confirmed your update",
+ content => "Thank you for updating this issue",
},
)
{
@@ -1203,7 +1532,7 @@ for my $test (
{
problem_id => $report_id,
ever_reported => 'y',
- whensent => \'ms_current_timestamp()',
+ whensent => \'current_timestamp',
}
);
@@ -1228,8 +1557,6 @@ for my $test (
$mech->content_contains( 'Now check your email' );
- $mech->email_count_is(1);
-
my $results = { %{ $test->{fields} }, %{ $test->{changed} }, };
my $update = $report->comments->first;
@@ -1240,10 +1567,11 @@ for my $test (
is $update->anonymous, $test->{anonymous}, 'user anonymous';
my $email = $mech->get_email;
- ok $email, "got an email";
- like $email->body, qr/confirm the update you/i, "Correct email text";
+ my $body = $mech->get_text_body_from_email($email);
+ like $body, qr/confirm your update on/i, "Correct email text";
- my ( $url, $url_token ) = $email->body =~ m{(http://\S+/C/)(\S+)};
+ my $url = $mech->get_link_from_email($email);
+ my ($url_token) = $url =~ m{/C/(\S+)};
ok $url, "extracted confirm url '$url'";
my $token = FixMyStreet::App->model('DB::Token')->find(
@@ -1269,7 +1597,8 @@ for my $test (
$mech->submit_form_ok( { with_fields => { reported => 'Yes' } } );
- $mech->content_contains( 'Thank you &mdash; you can' );
+ $mech->content_contains( $report->title );
+ $mech->content_contains( 'Thank you for updating this issue' );
$questionnaire = FixMyStreet::App->model( 'DB::Questionnaire' )->find(
{ problem_id => $report_id }
@@ -1286,10 +1615,261 @@ for my $test (
};
}
+for my $test (
+ {
+ desc => 'update confirmed without marking as fixed leaves state unchanged',
+ initial_state => 'confirmed',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 0,
+ },
+ end_state => 'confirmed',
+ },
+ {
+ desc => 'update investigating without marking as fixed leaves state unchanged',
+ initial_state => 'investigating',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 0,
+ },
+ end_state => 'investigating',
+ },
+ {
+ desc => 'update in progress without marking as fixed leaves state unchanged',
+ initial_state => 'in progress',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 0,
+ },
+ end_state => 'in progress',
+ },
+ {
+ desc => 'update action scheduled without marking as fixed leaves state unchanged',
+ initial_state => 'action scheduled',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 0,
+ },
+ end_state => 'action scheduled',
+ },
+ {
+ desc => 'update fixed without marking as open leaves state unchanged',
+ initial_state => 'fixed',
+ expected_form_fields => {
+ reopen => undef,
+ },
+ submitted_form_fields => {
+ reopen => 0,
+ },
+ end_state => 'fixed',
+ },
+ {
+ desc => 'update unable to fix without marking as fixed leaves state unchanged',
+ initial_state => 'unable to fix',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 0,
+ },
+ end_state => 'unable to fix',
+ },
+ {
+ desc => 'update internal referral without marking as fixed leaves state unchanged',
+ initial_state => 'internal referral',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 0,
+ },
+ end_state => 'internal referral',
+ },
+ {
+ desc => 'update not responsible without marking as fixed leaves state unchanged',
+ initial_state => 'not responsible',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 0,
+ },
+ end_state => 'not responsible',
+ },
+ {
+ desc => 'update duplicate without marking as fixed leaves state unchanged',
+ initial_state => 'duplicate',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 0,
+ },
+ end_state => 'duplicate',
+ },
+ {
+ desc => 'can mark confirmed as fixed',
+ initial_state => 'confirmed',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 1,
+ },
+ end_state => 'fixed - user',
+ },
+ {
+ desc => 'can mark investigating as fixed',
+ initial_state => 'investigating',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 1,
+ },
+ end_state => 'fixed - user',
+ },
+ {
+ desc => 'can mark in progress as fixed',
+ initial_state => 'in progress',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 1,
+ },
+ end_state => 'fixed - user',
+ },
+ {
+ desc => 'can mark action scheduled as fixed',
+ initial_state => 'action scheduled',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 1,
+ },
+ end_state => 'fixed - user',
+ },
+ {
+ desc => 'cannot mark fixed as fixed, can mark as not fixed',
+ initial_state => 'fixed',
+ expected_form_fields => {
+ reopen => undef,
+ },
+ submitted_form_fields => {
+ reopen => 1,
+ },
+ end_state => 'confirmed',
+ },
+ {
+ desc => 'can mark unable to fix as fixed, cannot mark not closed',
+ initial_state => 'unable to fix',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 1,
+ },
+ end_state => 'fixed - user',
+ },
+ {
+ desc => 'can mark internal referral as fixed, cannot mark not closed',
+ initial_state => 'internal referral',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 1,
+ },
+ end_state => 'fixed - user',
+ },
+ {
+ desc => 'can mark not responsible as fixed, cannot mark not closed',
+ initial_state => 'not responsible',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 1,
+ },
+ end_state => 'fixed - user',
+ },
+ {
+ desc => 'can mark duplicate as fixed, cannot mark not closed',
+ initial_state => 'duplicate',
+ expected_form_fields => {
+ fixed => undef,
+ },
+ submitted_form_fields => {
+ fixed => 1,
+ },
+ end_state => 'fixed - user',
+ },
+) {
+ subtest $test->{desc} => sub {
+ $mech->log_in_ok( $report->user->email );
+
+ my %standard_fields = (
+ name => $report->user->name,
+ update => 'update text',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ may_show_name => 1,
+ add_alert => 1,
+ );
+
+ my %expected_fields = (
+ %standard_fields,
+ %{ $test->{expected_form_fields} },
+ update => '',
+ );
+
+ my %submitted_fields = (
+ %standard_fields,
+ %{ $test->{submitted_form_fields} },
+ );
+
+ # clear out comments for this problem to make
+ # checking details easier later
+ ok( $_->delete, 'deleted comment ' . $_->id ) for $report->comments;
+
+ $report->discard_changes;
+ $report->state($test->{initial_state});
+ $report->update;
+
+ $mech->get_ok("/report/$report_id");
+
+ my $values = $mech->visible_form_values('updateForm');
+ is_deeply $values, \%expected_fields, 'correct form fields present';
+
+ if ( $test->{submitted_form_fields} ) {
+ $mech->submit_form_ok( {
+ with_fields => \%submitted_fields
+ },
+ 'submit update'
+ );
+
+ $report->discard_changes;
+ is $report->state, $test->{end_state}, 'update sets correct report state';
+ }
+ };
+}
+
subtest 'check have to be logged in for creator fixed questionnaire' => sub {
$mech->log_out_ok();
- $mech->get_ok( "/questionnaire/submit?problem=$report_id&reported=Yes" );
+ $mech->get( "/questionnaire/submit?problem=$report_id&reported=Yes" );
+ is $mech->res->code, 400, "got 400";
$mech->content_contains( "I'm afraid we couldn't locate your problem in the database." )
};
@@ -1298,7 +1878,8 @@ subtest 'check cannot answer other user\'s creator fixed questionnaire' => sub {
$mech->log_out_ok();
$mech->log_in_ok( $user2->email );
- $mech->get_ok( "/questionnaire/submit?problem=$report_id&reported=Yes" );
+ $mech->get( "/questionnaire/submit?problem=$report_id&reported=Yes" );
+ is $mech->res->code, 400, "got 400";
$mech->content_contains( "I'm afraid we couldn't locate your problem in the database." )
};
diff --git a/t/app/controller/reports.t b/t/app/controller/reports.t
index a4dab6597..a21d3ad65 100644
--- a/t/app/controller/reports.t
+++ b/t/app/controller/reports.t
@@ -8,17 +8,85 @@ use DateTime;
ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' );
-$mech->delete_problems_for_council( 2504 );
-$mech->delete_problems_for_council( 2651 );
+$mech->create_body_ok(2514, 'Birmingham City Council');
+my $body_edin_id = $mech->create_body_ok(2651, 'City of Edinburgh Council')->id;
+my $body_west_id = $mech->create_body_ok(2504, 'Westminster City Council')->id;
+my $body_fife_id = $mech->create_body_ok(2649, 'Fife Council')->id;
+my $body_slash_id = $mech->create_body_ok(10000, 'Electricity/Gas Council')->id;
-my @edinburgh_problems = $mech->create_problems_for_council(3, 2651, 'All reports');
-my @westminster_problems = $mech->create_problems_for_council(5, 2504, 'All reports');
+$mech->delete_problems_for_body( $body_west_id );
+$mech->delete_problems_for_body( $body_edin_id );
+$mech->delete_problems_for_body( $body_fife_id );
+
+my @edinburgh_problems = $mech->create_problems_for_body(3, $body_edin_id, 'All reports');
+my @westminster_problems = $mech->create_problems_for_body(5, $body_west_id, 'All reports');
+my @fife_problems = $mech->create_problems_for_body(15, $body_fife_id, 'All reports');
is scalar @westminster_problems, 5, 'correct number of westminster problems created';
is scalar @edinburgh_problems, 3, 'correct number of edinburgh problems created';
+is scalar @fife_problems, 15, 'correct number of fife problems created';
+
+$edinburgh_problems[1]->update( {
+ state => 'in progress',
+ confirmed => DateTime->now()->subtract( weeks => 6 ),
+ lastupdate => DateTime->now()->subtract( weeks => 5 ),
+} );
+
+$fife_problems[1]->update( {
+ state => 'fixed - user',
+ confirmed => DateTime->now()->subtract( weeks => 6 ),
+ lastupdate => DateTime->now()->subtract( weeks => 5 ),
+});
+
+$fife_problems[2]->update( {
+ state => 'fixed - user',
+ confirmed => DateTime->now()->subtract( weeks => 2 ),
+ lastupdate => DateTime->now()->subtract( weeks => 1 ),
+});
+
+$fife_problems[3]->update( {
+ state => 'fixed - user',
+ confirmed => DateTime->now()->subtract( weeks => 10 ),
+ lastupdate => DateTime->now()->subtract( weeks => 9 ),
+});
+
+$fife_problems[4]->update( {
+ confirmed => DateTime->now()->subtract( weeks => 10 ),
+ lastupdate => DateTime->now()->subtract( weeks => 9 ),
+});
+
+$fife_problems[5]->update( {
+ confirmed => DateTime->now()->subtract( weeks => 7 ),
+ lastupdate => DateTime->now()->subtract( weeks => 5 ),
+});
+
+$fife_problems[6]->update( {
+ confirmed => DateTime->now()->subtract( weeks => 7 ),
+ lastupdate => DateTime->now()->subtract( weeks => 2 ),
+});
+
+$fife_problems[7]->update( {
+ confirmed => DateTime->now()->subtract( weeks => 10 ),
+ lastupdate => DateTime->now()->subtract( weeks => 6 ),
+});
+
+$fife_problems[8]->update( {
+ confirmed => DateTime->now()->subtract( weeks => 10 ),
+ lastupdate => DateTime->now()->subtract( weeks => 2 ),
+});
+
+$fife_problems[9]->update( {
+ state => 'fixed - user',
+ confirmed => DateTime->now()->subtract( weeks => 10 ),
+ lastupdate => DateTime->now()->subtract( weeks => 7 ),
+});
+
+$fife_problems[10]->update( {
+ state => 'hidden',
+});
# Run the cron script that makes the data for /reports so we don't get an error.
-system( "bin/cron-wrapper update-all-reports" );
+system( "bin/update-all-reports" );
# check that we can get the page
$mech->get_ok('/reports');
@@ -27,49 +95,192 @@ $mech->content_contains('Birmingham');
my $stats = $mech->extract_report_stats;
-is $stats->{'City of Edinburgh Council'}->[1], 3, 'correct number of reports for Edinburgh';
+is $stats->{'City of Edinburgh Council'}->[1], 2, 'correct number of new reports for Edinburgh';
+is $stats->{'City of Edinburgh Council'}->[2], 1, 'correct number of older reports for Edinburgh';
+
is $stats->{'Westminster City Council'}->[1], 5, 'correct number of reports for Westminster';
-$mech->follow_link_ok( { text_regex => qr/Birmingham/ } );
+is $stats->{'Fife Council'}->[1], 5, 'correct number of new reports for Fife';
+is $stats->{'Fife Council'}->[2], 4, 'correct number of old reports for Fife';
+is $stats->{'Fife Council'}->[3], 1, 'correct number of unknown reports for Fife';
+is $stats->{'Fife Council'}->[4], 3, 'correct number of fixed reports for Fife';
+is $stats->{'Fife Council'}->[5], 1, 'correct number of older fixed reports for Fife';
+
+FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ $mech->follow_link_ok( { text_regex => qr/Birmingham/ } );
+ $mech->get_ok('/reports/Westminster');
+};
-$mech->get_ok('/reports/Westminster');
$mech->title_like(qr/Westminster City Council/);
$mech->content_contains('Westminster City Council');
-$mech->content_contains('All reports Test 3 for 2504', 'problem to be marked non public visible');
+$mech->content_contains('All reports Test 3 for ' . $body_west_id, 'problem to be marked non public visible');
my $problems = $mech->extract_problem_list;
is scalar @$problems, 5, 'correct number of problems displayed';
+FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ $mech->get_ok('/reports');
+ $mech->follow_link_ok({ url_regex => qr{/reports/Electricity_Gas\+Council} });
+ is $mech->uri->path, '/reports/Electricity_Gas+Council', 'Path is correct';
+
+ $mech->get_ok('/reports/City+of+Edinburgh?t=new');
+};
+$problems = $mech->extract_problem_list;
+is scalar @$problems, 2, 'correct number of new problems displayed';
+
+FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ $mech->get_ok('/reports/City+of+Edinburgh?t=older');
+};
+$problems = $mech->extract_problem_list;
+is scalar @$problems, 1, 'correct number of older problems displayed';
+
+for my $test (
+ {
+ desc => 'new fife problems on report page',
+ type => 'new',
+ expected => 5
+ },
+ {
+ desc => 'older fife problems on report page',
+ type => 'older',
+ expected => 4
+ },
+ {
+ desc => 'unknown fife problems on report page',
+ type => 'unknown',
+ expected => 1
+ },
+ {
+ desc => 'fixed fife problems on report page',
+ type => 'fixed',
+ expected => 3
+ },
+ {
+ desc => 'older_fixed fife problems on report page',
+ type => 'older_fixed',
+ expected => 1
+ },
+) {
+ subtest $test->{desc} => sub {
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok('/reports/Fife+Council?t=' . $test->{type});
+ };
+
+ $problems = $mech->extract_problem_list;
+ is scalar @$problems, $test->{expected}, 'correct number of ' . $test->{type} . ' problems displayed';
+ };
+}
+
my $private = $westminster_problems[2];
ok $private->update( { non_public => 1 } ), 'problem marked non public';
-$mech->get_ok('/reports/Westminster');
+FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ $mech->get_ok('/reports/Westminster');
+};
$problems = $mech->extract_problem_list;
is scalar @$problems, 4, 'only public problems are displayed';
-$mech->content_lacks('All reports Test 3 for 2504', 'non public problem is not visible');
+$mech->content_lacks('All reports Test 3 for ' . $body_west_id, 'non public problem is not visible');
$mech->get_ok('/reports');
$stats = $mech->extract_report_stats;
is $stats->{'Westminster City Council'}->[1], 5, 'non public reports included in stats';
-SKIP: {
- skip( "Need 'emptyhomes' in ALLOWED_COBRANDS config", 8 )
- unless FixMyStreet::Cobrand->exists('emptyhomes');
- ok $mech->host("reportemptyhomes.com"), 'change host to reportemptyhomes';
- $mech->get_ok('/reports');
- # EHA lacks one column the others have
- $mech->content_lacks('state unknown');
+subtest "test fiksgatami all reports page" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fiksgatami' ],
+ MAPIT_URL => 'http://mapit.nuug.no/',
+ }, sub {
+ $mech->create_body_ok(3, 'Oslo');
+ ok $mech->host("fiksgatami.no"), 'change host to fiksgatami';
+ $mech->get_ok('/reports');
+ # There should only be one Oslo
+ $mech->content_contains('Oslo');
+ $mech->content_unlike(qr{Oslo">Oslo.*Oslo}s);
+ }
+};
- skip( "Need 'fiksgatami' in ALLOWED_COBRANDS config", 8 )
- unless FixMyStreet::Cobrand->exists('fiksgatami');
- mySociety::MaPit::configure('http://mapit.nuug.no/');
- ok $mech->host("fiksgatami.no"), 'change host to fiksgatami';
- $mech->get_ok('/reports');
- # There should only be one Oslo
- $mech->content_contains('Oslo');
- $mech->content_unlike(qr{Oslo">Oslo.*Oslo}s);
-}
+subtest "test greenwich all reports page" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'greenwich' ],
+ MAPIT_URL => 'http://mapit.uk/'
+ }, 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, undef, 'deleted categories are not shown';
-done_testing();
+ # Clean up after the test
+ $deleted_contact->delete;
+ }
+};
+
+subtest "it lists shortlisted reports" => sub {
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/'
+ }, sub {
+ my $body = FixMyStreet::App->model('DB::Body')->find( $body_edin_id );
+ my $user = $mech->log_in_ok( 'test@example.com' );
+ $user->update({ from_body => $body });
+ $user->user_body_permissions->find_or_create({
+ body => $body,
+ permission_type => 'planned_reports',
+ });
+
+ my ($shortlisted_problem) = $mech->create_problems_for_body(1, $body_edin_id, 'Shortlisted report');
+ my ($unshortlisted_problem) = $mech->create_problems_for_body(1, $body_edin_id, 'Unshortlisted report');
+ my ($removed_from_shortlist_problem) = $mech->create_problems_for_body(1, $body_edin_id, 'Removed from shortlist report');
+
+ $user->add_to_planned_reports($shortlisted_problem);
+ $user->add_to_planned_reports($removed_from_shortlist_problem);
+ $user->remove_from_planned_reports($removed_from_shortlist_problem);
+ $mech->get_ok('/reports/City+of+Edinburgh+Council');
+ $mech->content_contains('<option value="shortlisted">Shortlisted</option>');
+ $mech->content_contains('<option value="unshortlisted">Unshortlisted</option>');
+
+ $mech->get_ok('/reports/City+of+Edinburgh+Council?status=shortlisted');
+
+ $mech->content_contains('Shortlisted report');
+ $mech->content_lacks('Unshortlisted report');
+ $mech->content_lacks('Removed from shortlist report');
+
+ $mech->get_ok('/reports/City+of+Edinburgh+Council?status=shortlisted,open');
+
+ $mech->content_contains('Shortlisted report');
+ $mech->content_lacks('Unshortlisted report');
+ $mech->content_lacks('Removed from shortlist report');
+
+ $mech->get_ok('/reports/City+of+Edinburgh+Council?status=unshortlisted,open');
+
+ $mech->content_contains('Unshortlisted report');
+ $mech->content_contains('Removed from shortlist report');
+ $mech->content_lacks('Shortlisted report');
+
+ $user->admin_user_body_permissions->delete;
+
+ $mech->get_ok('/reports/City+of+Edinburgh+Council');
+ $mech->content_lacks('<option value="shortlisted">Shortlisted</option>');
+ $mech->content_lacks('<option value="unshortlisted">Unshortlisted</option>');
+ };
+};
+
+done_testing();
diff --git a/t/app/controller/rss.t b/t/app/controller/rss.t
index 77e2c7ee1..bec504760 100644
--- a/t/app/controller/rss.t
+++ b/t/app/controller/rss.t
@@ -3,6 +3,7 @@ use warnings;
use Test::More;
use FixMyStreet::TestMech;
+use FixMyStreet::App;
my $mech = FixMyStreet::TestMech->new;
@@ -12,12 +13,13 @@ my $dt = DateTime->new(
day => 10
);
-my $user1 = FixMyStreet::App->model('DB::User')
- ->find_or_create( { email => 'reporter@example.com', name => 'Reporter User' } );
+my $user1 = $mech->create_user_ok('reporter-rss@example.com', name => 'Reporter User');
+
+my $dt_parser = FixMyStreet::App->model('DB')->schema->storage->datetime_parser;
my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( {
postcode => 'eh1 1BB',
- council => '2651',
+ bodies_str => '2651',
areas => ',11808,135007,14419,134935,2651,20728,',
category => 'Street lighting',
title => 'Testing',
@@ -26,9 +28,9 @@ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( {
name => $user1->name,
anonymous => 0,
state => 'confirmed',
- confirmed => $dt,
- lastupdate => $dt,
- whensent => $dt->clone->add( minutes => 5 ),
+ confirmed => $dt_parser->format_datetime($dt),
+ lastupdate => $dt_parser->format_datetime($dt),
+ whensent => $dt_parser->format_datetime($dt->clone->add( minutes => 5 )),
lang => 'en-gb',
service => '',
cobrand => 'default',
@@ -39,10 +41,16 @@ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create( {
user_id => $user1->id,
} );
-
-$mech->get_ok("/rss/pc/EH11BB/2");
+$mech->host('www.fixmystreet.com');
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fixmystreet' ],
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ $mech->get_ok("/rss/pc/EH11BB/2");
+};
$mech->content_contains( "Testing, 10th October" );
$mech->content_lacks( 'Nearest road to the pin' );
+is $mech->response->header('Access-Control-Allow-Origin'), '*';
$report->geocode(
{
@@ -108,11 +116,87 @@ $report->geocode(
);
$report->update();
-$mech->get_ok("/rss/pc/EH11BB/2");
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fixmystreet' ],
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ $mech->get_ok("/rss/pc/EH11BB/2");
+};
$mech->content_contains( "Testing, 10th October" );
$mech->content_contains( '18 North Bridge, Edinburgh' );
$report->delete();
-$user1->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 => $council->id,
+ areas => ',2333,2227,',
+ category => 'Other',
+ title => 'council report',
+ detail => 'Test 2 Detail',
+ used_map => 't',
+ name => 'Test User',
+ anonymous => 'f',
+ state => 'closed',
+ confirmed => $now->ymd . ' ' . $now->hms,
+ lang => 'en-gb',
+ service => '',
+ cobrand => 'default',
+ cobrand_data => '',
+ send_questionnaire => 't',
+ latitude => '51.279616',
+ longitude => '-0.846040',
+ user_id => $user1->id,
+ }
+);
+
+my $report_to_county_council = FixMyStreet::App->model('DB::Problem')->find_or_create(
+ {
+ postcode => 'GU51 4AE',
+ bodies_str => $county->id,
+ areas => ',2333,2227,',
+ category => 'Other',
+ title => 'county report',
+ detail => 'Test 2 Detail',
+ used_map => 't',
+ name => 'Test User',
+ anonymous => 'f',
+ state => 'closed',
+ confirmed => $now->ymd . ' ' . $now->hms,
+ lang => 'en-gb',
+ service => '',
+ cobrand => 'default',
+ cobrand_data => '',
+ send_questionnaire => 't',
+ latitude => '51.279616',
+ longitude => '-0.846040',
+ user_id => $user1->id,
+ }
+);
+
+subtest "check RSS feeds on cobrand have correct URLs for non-cobrand reports" => sub {
+ $mech->host('hart.fixmystreet.com');
+ my $expected1 = FixMyStreet->config('BASE_URL') . '/report/' . $report_to_county_council->id;
+ my $expected2;
+
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'hart' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok("/rss/area/Hart");
+ my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker('hart')->new();
+ $expected2 = $cobrand->base_url . '/report/' . $report_to_council->id;
+ };
+
+ $mech->content_contains($expected1, 'non cobrand area report point to fixmystreet.com');
+ $mech->content_contains($expected2, 'cobrand area report point to cobrand url');
+};
+
+$mech->delete_user( $user1 );
done_testing();
diff --git a/t/app/controller/sample.jpg b/t/app/controller/sample.jpg
index 23198cb83..b84c0c94e 100644
--- a/t/app/controller/sample.jpg
+++ b/t/app/controller/sample.jpg
Binary files differ
diff --git a/t/app/controller/token.t b/t/app/controller/token.t
new file mode 100644
index 000000000..ac88f4f7a
--- /dev/null
+++ b/t/app/controller/token.t
@@ -0,0 +1,35 @@
+use strict;
+use warnings;
+use Test::More;
+use utf8;
+
+use FixMyStreet::TestMech;
+use FixMyStreet::App;
+
+my $mech = FixMyStreet::TestMech->new;
+my $user = $mech->create_user_ok('bob@example.com', name => 'Bob');
+
+subtest 'Zurich special case for C::Tokens->problem_confirm' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => ['zurich'],
+ }, sub {
+ my $c = FixMyStreet::App->new;
+ my $zurich = $mech->create_body_ok( 1, 'Zurich' );
+ my ($report) = $mech->create_problems_for_body(
+ 1, $zurich->id,
+ {
+ state => 'unconfirmed',
+ confirmed => undef,
+ cobrand => 'zurich',
+ });
+
+ is $report->get_extra_metadata('email_confirmed'), undef, 'email_confirmed not yet set (sanity)';
+ my $token = $c->model('DB::Token')->create({ scope => 'problem', data => $report->id });
+
+ $mech->get_ok('/P/' . $token->token);
+ $report->discard_changes;
+ is $report->get_extra_metadata('email_confirmed'), 1, 'email_confirmed set by Zurich special case';
+ };
+};
+
+done_testing;