aboutsummaryrefslogtreecommitdiffstats
path: root/t/app/controller
diff options
context:
space:
mode:
Diffstat (limited to 't/app/controller')
-rw-r--r--t/app/controller/about.t9
-rw-r--r--t/app/controller/admin.t28
-rw-r--r--t/app/controller/admin/bodies.t129
-rw-r--r--t/app/controller/admin/defecttypes.t21
-rw-r--r--t/app/controller/admin/manifesttheme.t340
-rw-r--r--t/app/controller/admin/permissions.t8
-rw-r--r--t/app/controller/admin/priorities.t43
-rw-r--r--t/app/controller/admin/report_edit.t25
-rw-r--r--t/app/controller/admin/reportextrafields.t131
-rw-r--r--t/app/controller/admin/roles.t139
-rw-r--r--t/app/controller/admin/search.t6
-rw-r--r--t/app/controller/admin/templates.t159
-rw-r--r--t/app/controller/admin/translations.t2
-rw-r--r--t/app/controller/admin/triage.t126
-rw-r--r--t/app/controller/admin/update_edit.t30
-rw-r--r--t/app/controller/admin/users.t159
-rw-r--r--t/app/controller/admin/users_import.t34
-rw-r--r--t/app/controller/alert_new.t179
-rw-r--r--t/app/controller/around.t100
-rw-r--r--t/app/controller/auth.t171
-rw-r--r--t/app/controller/auth_phone.t2
-rw-r--r--t/app/controller/auth_profile.t111
-rw-r--r--t/app/controller/auth_social.t246
-rw-r--r--t/app/controller/contact.t102
-rw-r--r--t/app/controller/contact_enquiry.t267
-rw-r--r--t/app/controller/dashboard.t43
-rw-r--r--t/app/controller/index.t9
-rw-r--r--t/app/controller/moderate.t65
-rw-r--r--t/app/controller/my.t2
-rw-r--r--t/app/controller/my_planned.t8
-rw-r--r--t/app/controller/offline.t67
-rw-r--r--t/app/controller/open311.t10
-rw-r--r--t/app/controller/open311_updates.t99
-rw-r--r--t/app/controller/photo.t72
-rw-r--r--t/app/controller/questionnaire.t25
-rw-r--r--t/app/controller/report_as_other.t62
-rw-r--r--t/app/controller/report_display.t82
-rw-r--r--t/app/controller/report_import.t9
-rw-r--r--t/app/controller/report_inspect.t164
-rw-r--r--t/app/controller/report_interest_count.t2
-rw-r--r--t/app/controller/report_new.t1143
-rw-r--r--t/app/controller/report_new_anon.t272
-rw-r--r--t/app/controller/report_new_errors.t745
-rw-r--r--t/app/controller/report_new_mobile.t5
-rw-r--r--t/app/controller/report_new_open311.t216
-rw-r--r--t/app/controller/report_new_staff.t268
-rw-r--r--t/app/controller/report_new_text.t12
-rw-r--r--t/app/controller/report_new_unresponsive.t122
-rw-r--r--t/app/controller/report_new_update.t71
-rw-r--r--t/app/controller/report_non_public.t87
-rw-r--r--t/app/controller/report_update_text.t12
-rw-r--r--t/app/controller/report_updates.t71
-rw-r--r--t/app/controller/reports.t7
-rw-r--r--t/app/controller/root.t12
-rw-r--r--t/app/controller/rss.t20
-rw-r--r--t/app/controller/sample.pdfbin0 -> 12501 bytes
-rw-r--r--t/app/controller/token.t4
57 files changed, 4653 insertions, 1700 deletions
diff --git a/t/app/controller/about.t b/t/app/controller/about.t
index 04d902bc5..e1ffc34bb 100644
--- a/t/app/controller/about.t
+++ b/t/app/controller/about.t
@@ -4,6 +4,7 @@ sub path_to_web_templates { [ FixMyStreet->path_to( 't', 'app', 'controller', 't
package main;
+use utf8;
use FixMyStreet::TestMech;
ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' );
@@ -23,12 +24,12 @@ ok !$mech->res->is_success(), "want a bad response";
is $mech->res->code, 404, "got 404";
FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ 'fiksgatami' ],
+ ALLOWED_COBRANDS => [ 'fixamingata' ],
}, sub {
- ok $mech->host("www.fiksgatami.no"), 'host to fiksgatami';
+ ok $mech->host("www.fixamingata.se"), 'host to fixamingata';
$mech->get_ok('/faq');
- $mech->content_like(qr{Ofte spurte spørsmål ::});
- $mech->content_contains('html class="no-js" lang="nb"');
+ $mech->content_like(qr{Vanliga frågor ::});
+ $mech->content_contains('html class="no-js" lang="sv"');
};
$mech->get_ok('/');
diff --git a/t/app/controller/admin.t b/t/app/controller/admin.t
index d50702086..5607f2dc3 100644
--- a/t/app/controller/admin.t
+++ b/t/app/controller/admin.t
@@ -25,7 +25,7 @@ my $dt = DateTime->new(
second => 23
);
-my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
+my $report = FixMyStreet::DB->resultset('Problem')->find_or_create(
{
postcode => 'SW1A 1AA',
bodies_str => '2504',
@@ -53,7 +53,7 @@ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
my $report_id = $report->id;
ok $report, "created test report - $report_id";
-my $alert = FixMyStreet::App->model('DB::Alert')->find_or_create(
+my $alert = FixMyStreet::DB->resultset('Alert')->find_or_create(
{
alert_type => 'area_problems',
parameter => 2482,
@@ -65,34 +65,34 @@ my $alert = FixMyStreet::App->model('DB::Alert')->find_or_create(
$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'] } } );
+ my $problems = FixMyStreet::DB->resultset('Problem')->search( { state => { -in => [qw/confirmed fixed closed investigating planned/, 'in progress', 'fixed - user', 'fixed - council'] } } );
ok $mech->host('www.fixmystreet.com');
my $problem_count = $problems->count;
$problems->update( { cobrand => '' } );
- FixMyStreet::App->model('DB::Problem')->search( { bodies_str => 2489 } )->update( { bodies_str => 1 } );
+ FixMyStreet::DB->resultset('Problem')->search( { bodies_str => 2489 } )->update( { bodies_str => 1 } );
- my $q = FixMyStreet::App->model('DB::Questionnaire')->find_or_new( { problem => $report, });
+ my $q = FixMyStreet::DB->resultset('Questionnaire')->find_or_new( { problem => $report, });
$q->whensent( \'current_timestamp' );
$q->in_storage ? $q->update : $q->insert;
- my $alerts = FixMyStreet::App->model('DB::Alert')->search( { confirmed => { '>' => 0 } } );
+ my $alerts = FixMyStreet::DB->resultset('Alert')->search( { confirmed => { '>' => 0 } } );
my $a_count = $alerts->count;
FixMyStreet::override_config {
ALLOWED_COBRANDS => [ 'fixmystreet' ],
}, sub {
- $mech->get_ok('/admin');
+ $mech->get_ok('/admin/stats');
};
- $mech->title_like(qr/Summary/);
+ $mech->title_like(qr/Stats/);
$mech->content_contains( "$problem_count</strong> live problems" );
$mech->content_contains( "$a_count confirmed alerts" );
- my $questionnaires = FixMyStreet::App->model('DB::Questionnaire')->search( { whensent => { -not => undef } } );
+ my $questionnaires = FixMyStreet::DB->resultset('Questionnaire')->search( { whensent => { -not => undef } } );
my $q_count = $questionnaires->count();
$mech->content_contains( "$q_count questionnaires sent" );
@@ -102,8 +102,8 @@ subtest 'check summary counts' => sub {
}, sub {
ok $mech->host('oxfordshire.fixmystreet.com');
- $mech->get_ok('/admin');
- $mech->title_like(qr/Summary/);
+ $mech->get_ok('/admin/stats');
+ $mech->title_like(qr/Stats/);
my ($num_live) = $mech->content =~ /(\d+)<\/strong> live problems/;
my ($num_alerts) = $mech->content =~ /(\d+) confirmed alerts/;
@@ -116,7 +116,7 @@ subtest 'check summary counts' => sub {
$alert->cobrand('oxfordshire');
$alert->update;
- $mech->get_ok('/admin');
+ $mech->get_ok('/admin/stats');
$mech->content_contains( ($num_live+1) . "</strong> live problems" );
$mech->content_contains( ($num_alerts+1) . " confirmed alerts" );
@@ -130,12 +130,12 @@ subtest 'check summary counts' => sub {
$alert->update;
};
- FixMyStreet::App->model('DB::Problem')->search( { bodies_str => 1 } )->update( { bodies_str => 2489 } );
+ FixMyStreet::DB->resultset('Problem')->search( { bodies_str => 1 } )->update( { bodies_str => 2489 } );
ok $mech->host('www.fixmystreet.com');
};
subtest "Check admin_base_url" => sub {
- my $rs = FixMyStreet::App->model('DB::Problem');
+ my $rs = FixMyStreet::DB->resultset('Problem');
my $cobrand = $report->get_cobrand_logged;
is ($report->admin_url($cobrand),
diff --git a/t/app/controller/admin/bodies.t b/t/app/controller/admin/bodies.t
index f67e45bf6..c73a90da1 100644
--- a/t/app/controller/admin/bodies.t
+++ b/t/app/controller/admin/bodies.t
@@ -1,10 +1,3 @@
-package FixMyStreet::Cobrand::Tester;
-
-use parent 'FixMyStreet::Cobrand::Default';
-
-sub enable_category_groups { 1 }
-
-package main;
use FixMyStreet::TestMech;
my $mech = FixMyStreet::TestMech->new;
@@ -58,7 +51,7 @@ subtest 'check contact creation' => sub {
non_public => 'on',
} } );
$mech->get_ok('/admin/body/' . $body->id . '/test/category');
- $mech->content_contains('<h1>test/category</h1>');
+ $mech->content_contains('test/category');
};
subtest 'check contact editing' => sub {
@@ -98,6 +91,21 @@ subtest 'check contact editing' => sub {
$mech->content_contains( '<td><strong>test2@example.com' );
};
+subtest 'check contact renaming' => sub {
+ my ($report) = $mech->create_problems_for_body(1, $body->id, 'Title', { category => 'test category' });
+ $mech->get_ok('/admin/body/' . $body->id .'/test%20category');
+ $mech->submit_form_ok( { with_fields => { category => 'private category' } } );
+ $mech->content_contains('You cannot rename');
+ $mech->submit_form_ok( { with_fields => { category => 'testing category' } } );
+ $mech->content_contains( 'testing category' );
+ $mech->get('/admin/body/' . $body->id . '/test%20category');
+ is $mech->res->code, 404;
+ $mech->get_ok('/admin/body/' . $body->id . '/testing%20category');
+ $report->discard_changes;
+ is $report->category, 'testing category';
+ $mech->submit_form_ok( { with_fields => { category => 'test category' } } );
+};
+
subtest 'check contact updating' => sub {
$mech->get_ok('/admin/body/' . $body->id . '/test%20category');
$mech->content_like(qr{test2\@example.com</strong>[^<]*</td>[^<]*<td>unconfirmed}s);
@@ -134,7 +142,7 @@ subtest 'check open311 configuring' => sub {
$mech->content_contains('Council contacts configured via Open311');
$mech->content_contains('Values updated');
- my $conf = FixMyStreet::App->model('DB::Body')->find( $body->id );
+ my $conf = FixMyStreet::DB->resultset('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';
@@ -154,7 +162,7 @@ subtest 'check open311 configuring' => sub {
$mech->content_contains('Values updated');
- $conf = FixMyStreet::App->model('DB::Body')->find( $body->id );
+ $conf = FixMyStreet::DB->resultset('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';
@@ -169,14 +177,14 @@ subtest 'check open311 configuring' => sub {
jurisdiction => 'open311',
send_comments => 0,
send_method => 'Open311',
- fetch_all_problems => 1,
+ 'extra[fetch_all_problems]' => 1,
}
}
);
$mech->content_contains('Values updated');
- $conf = FixMyStreet::App->model('DB::Body')->find( $body->id );
+ $conf = FixMyStreet::DB->resultset('Body')->find( $body->id );
ok $conf->get_extra_metadata('fetch_all_problems'), 'fetch all problems set';
$mech->form_number(3);
@@ -188,17 +196,35 @@ subtest 'check open311 configuring' => sub {
jurisdiction => 'open311',
send_comments => 0,
send_method => 'Open311',
- fetch_all_problems => 0,
+ 'extra[fetch_all_problems]' => 0,
+ can_be_devolved => 1, # for next test
}
}
);
$mech->content_contains('Values updated');
- $conf = FixMyStreet::App->model('DB::Body')->find( $body->id );
+ $conf = FixMyStreet::DB->resultset('Body')->find( $body->id );
ok !$conf->get_extra_metadata('fetch_all_problems'), 'fetch all problems unset';
};
+subtest 'check open311 devolved editing' => sub {
+ $mech->get_ok('/admin/body/' . $body->id . '/test%20category');
+ $mech->submit_form_ok( { with_fields => {
+ send_method => 'Email',
+ email => 'testing@example.org',
+ note => 'Updating contact to email',
+ } } );
+ $mech->content_contains('Values updated');
+ $mech->get_ok('/admin/body/' . $body->id . '/test%20category');
+ $mech->submit_form_ok( { with_fields => {
+ send_method => '',
+ email => 'open311-code',
+ note => 'Removing email send method',
+ } } );
+ $mech->content_contains('Values updated');
+};
+
subtest 'check text output' => sub {
$mech->get_ok('/admin/body/' . $body->id . '?text=1');
is $mech->content_type, 'text/plain';
@@ -206,18 +232,49 @@ subtest 'check text output' => sub {
$mech->content_lacks('<body');
};
+subtest 'disable form message editing' => sub {
+ $mech->get_ok('/admin/body/' . $body->id . '/test%20category');
+ $mech->submit_form_ok( { with_fields => {
+ disable => 1,
+ disable_message => '<em>Please</em> <u>ring</u> us on <a href="tel:01234">01234</a>, click <a href="javascript:bad">bad</a>',
+ note => 'Adding emergency message',
+ } } );
+ $mech->content_contains('Values updated');
+ my $contact = $body->contacts->find({ category => 'test category' });
+ is_deeply $contact->get_extra_fields, [{
+ description => '<em>Please</em> ring us on <a href="tel:01234">01234</a>, click <a>bad</a>',
+ code => '_fms_disable_',
+ protected => 'true',
+ variable => 'false',
+ disable_form => 'true',
+ }], 'right message added';
+};
+
+subtest 'open311 protection editing' => sub {
+ $mech->get_ok('/admin/body/' . $body->id . '/test%20category');
+ $mech->submit_form_ok( { with_fields => {
+ open311_protect => 1,
+ note => 'Protected from Open311 changes',
+ } } );
+ $mech->content_contains('Values updated');
+ my $contact = $body->contacts->find({ category => 'test category' });
+ is $contact->get_extra_metadata('open311_protect'), 1, 'Open311 protect flag set';
+};
+
}; # END of override wrap
FixMyStreet::override_config {
- ALLOWED_COBRANDS => ['tester'],
MAPIT_URL => 'http://mapit.uk/',
MAPIT_TYPES => [ 'UTA' ],
BASE_URL => 'http://www.example.org',
+ COBRAND_FEATURES => {
+ category_groups => { default => 1 },
+ }
}, sub {
subtest 'group editing works' => sub {
$mech->get_ok('/admin/body/' . $body->id);
- $mech->content_contains( 'group</strong> is used for the top-level category' );
+ $mech->content_contains('Parent categories');
$mech->submit_form_ok( { with_fields => {
category => 'grouped category',
@@ -229,12 +286,12 @@ FixMyStreet::override_config {
} } );
my $contact = $body->contacts->find({ category => 'grouped category' });
- is $contact->get_extra_metadata('group'), 'group a', "group stored correctly";
+ is_deeply $contact->get_extra_metadata('group'), ['group a'], "group stored correctly";
};
subtest 'group can be unset' => sub {
$mech->get_ok('/admin/body/' . $body->id);
- $mech->content_contains( 'group</strong> is used for the top-level category' );
+ $mech->content_contains('Parent categories');
$mech->submit_form_ok( { with_fields => {
category => 'grouped category',
@@ -251,5 +308,41 @@ FixMyStreet::override_config {
};
+FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ MAPIT_TYPES => [ 'UTA' ],
+ BASE_URL => 'http://www.example.org',
+ COBRAND_FEATURES => {
+ category_groups => { default => 1 },
+ }
+}, sub {
+ subtest 'multi group editing works' => sub {
+ $mech->get_ok('/admin/body/' . $body->id);
+ $mech->content_contains('Parent categories');
+
+ # have to do this as a post as adding a second group requires
+ # javascript
+ $mech->post_ok( '/admin/body/' . $body->id, {
+ posted => 'new',
+ token => $mech->form_id('category_edit')->value('token'),
+ category => 'grouped category',
+ email => 'test@example.com',
+ note => 'test note',
+ 'group' => [ 'group a', 'group b'],
+ non_public => undef,
+ state => 'unconfirmed',
+ } );
+
+ my $contact = $body->contacts->find({ category => 'grouped category' });
+ is_deeply $contact->get_extra_metadata('group'), ['group a', 'group b'], "group stored correctly";
+ };
+};
+
+subtest 'check log of the above' => sub {
+ $mech->get_ok('/admin/users/' . $superuser->id . '/log');
+ $mech->content_contains('Added category <a href="/admin/body/' . $body->id . '/test/category">test/category</a>');
+ $mech->content_contains('Edited category <a href="/admin/body/' . $body->id . '/test category">test category</a>');
+ $mech->content_contains('Edited body <a href="/admin/body/' . $body->id . '">Aberdeen City Council</a>');
+};
done_testing();
diff --git a/t/app/controller/admin/defecttypes.t b/t/app/controller/admin/defecttypes.t
index 12ae8948c..15fdac2f8 100644
--- a/t/app/controller/admin/defecttypes.t
+++ b/t/app/controller/admin/defecttypes.t
@@ -1,5 +1,4 @@
use FixMyStreet::TestMech;
-use Test::MockModule;
my $mech = FixMyStreet::TestMech->new;
@@ -27,16 +26,6 @@ FixMyStreet::override_config { ALLOWED_COBRANDS => ['bromley'], }, sub {
FixMyStreet::override_config { ALLOWED_COBRANDS => ['oxfordshire'], }, sub {
- my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Oxfordshire');
- $cobrand->mock('available_permissions', sub {
- my $self = shift;
-
- my $perms = FixMyStreet::Cobrand::Default->available_permissions;
- $perms->{Bodies}->{defect_type_edit} = "Add/edit defect types";
-
- return $perms;
- });
-
my $body = $mech->create_body_ok( 2237, 'Oxfordshire County Council' );
subtest 'check defect types menu available to superusers' => sub {
@@ -107,7 +96,7 @@ FixMyStreet::override_config { ALLOWED_COBRANDS => ['oxfordshire'], }, sub {
};
subtest 'check editing a defect type' => sub {
- my $defect = FixMyStreet::App->model('DB::DefectType')->search( {
+ my $defect = FixMyStreet::DB->resultset('DefectType')->search( {
name => 'A defect',
body_id => $body->id
} )->first;
@@ -126,7 +115,7 @@ FixMyStreet::override_config { ALLOWED_COBRANDS => ['oxfordshire'], }, sub {
$mech->content_lacks('A defect');
$mech->content_contains('Updated defect');
- my $defects = FixMyStreet::App->model('DB::DefectType')->search( {
+ my $defects = FixMyStreet::DB->resultset('DefectType')->search( {
body_id => $body->id
} );
@@ -134,7 +123,7 @@ FixMyStreet::override_config { ALLOWED_COBRANDS => ['oxfordshire'], }, sub {
};
subtest 'check adding a category to a defect' => sub {
- my $defect = FixMyStreet::App->model('DB::DefectType')->search( {
+ my $defect = FixMyStreet::DB->resultset('DefectType')->search( {
name => 'Updated defect',
body_id => $body->id
} )->first;
@@ -163,7 +152,7 @@ FixMyStreet::override_config { ALLOWED_COBRANDS => ['oxfordshire'], }, sub {
};
subtest 'check removing category from a defect' => sub {
- my $defect = FixMyStreet::App->model('DB::DefectType')->search( {
+ my $defect = FixMyStreet::DB->resultset('DefectType')->search( {
name => 'Updated defect',
body_id => $body->id
} )->first;
@@ -191,7 +180,7 @@ FixMyStreet::override_config { ALLOWED_COBRANDS => ['oxfordshire'], }, sub {
};
subtest 'check adding codes to a defect' => sub {
- my $defect = FixMyStreet::App->model('DB::DefectType')->search( {
+ my $defect = FixMyStreet::DB->resultset('DefectType')->search( {
name => 'Updated defect',
body_id => $body->id
} )->first;
diff --git a/t/app/controller/admin/manifesttheme.t b/t/app/controller/admin/manifesttheme.t
new file mode 100644
index 000000000..c1b2d4542
--- /dev/null
+++ b/t/app/controller/admin/manifesttheme.t
@@ -0,0 +1,340 @@
+use Path::Tiny;
+use FixMyStreet::DB;
+use FixMyStreet::TestMech;
+
+my $mech = FixMyStreet::TestMech->new;
+
+my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1);
+
+$mech->log_in_ok( $superuser->email );
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'lincolnshire', 'tfl', 'fixmystreet' ],
+}, sub {
+
+ok $mech->host('lincolnshire.fixmystreet.com');
+
+subtest "theme link on cobrand admin goes to create form if no theme exists" => sub {
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 0, "no themes yet" );
+
+ $mech->get_ok("/admin");
+ $mech->follow_link_ok({ text => "Manifest Theme" });
+
+ is $mech->res->previous->code, 302, "got 302 for redirect";
+ is $mech->res->previous->base->path, "/admin/manifesttheme", "redirected from index";
+ is $mech->uri->path, '/admin/manifesttheme/create', "redirected to create page";
+};
+
+subtest "name and short_name are required fields" => sub {
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 0, "no themes yet" );
+
+ $mech->get_ok("/admin/manifesttheme/create");
+ $mech->content_lacks("Delete theme");
+
+ $mech->submit_form_ok({});
+ is $mech->uri->path, '/admin/manifesttheme/create', "stayed on create page";
+ $mech->content_contains("field is required");
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 0, "theme not created" );
+
+ $mech->get_ok("/admin/manifesttheme/create");
+ $mech->submit_form_ok({ with_fields => { short_name => "Lincs FMS" } });
+ is $mech->uri->path, '/admin/manifesttheme/create', "stayed on create page";
+ $mech->content_contains("field is required", "name is required");
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 0, "theme not created" );
+
+ $mech->get_ok("/admin/manifesttheme/create");
+ $mech->submit_form_ok({ with_fields => { name => "Lincolnshire FixMyStreet" } });
+ is $mech->uri->path, '/admin/manifesttheme/create', "stayed on create page";
+ $mech->content_contains("field is required", "short_name is required");
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 0, "theme not created" );
+};
+
+subtest "cobrand admin lets you create a new theme" => sub {
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 0, "no themes yet" );
+
+ $mech->get_ok("/admin/manifesttheme/create");
+ $mech->content_lacks("Delete theme");
+
+ my $fields = {
+ name => "Lincolnshire FixMyStreet",
+ short_name => "Lincs FMS",
+ };
+ $mech->submit_form_ok( { with_fields => $fields } );
+ is $mech->uri->path, '/admin/manifesttheme/lincolnshire', "redirected to edit page";
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 1, "theme was created" );
+
+ my $theme = FixMyStreet::DB->resultset('ManifestTheme')->find({ cobrand => 'lincolnshire' });
+ is $theme->name, "Lincolnshire FixMyStreet";
+ is $theme->short_name, "Lincs FMS";
+ is $theme->background_colour, undef;
+
+ my $log = $superuser->admin_logs->search({}, { order_by => { -desc => 'id' } })->first;
+ is $log->object_id, $theme->id;
+ is $log->action, "add";
+ is $log->object_summary, "lincolnshire";
+ is $log->link, "/admin/manifesttheme/lincolnshire";
+};
+
+subtest "cobrand admin lets you update an existing theme" => sub {
+ $mech->get_ok("/admin/manifesttheme/lincolnshire");
+
+ my $fields = {
+ background_colour => "#663399",
+ theme_colour => "rgb(102, 51, 153)",
+ };
+ $mech->submit_form_ok( { with_fields => $fields } );
+
+ my $theme = FixMyStreet::DB->resultset('ManifestTheme')->find({ cobrand => 'lincolnshire' });
+ is $theme->background_colour, "#663399";
+ is $theme->theme_colour, "rgb(102, 51, 153)";
+
+ my $log = $superuser->admin_logs->search({}, { order_by => { -desc => 'id' } })->first;
+ is $log->object_id, $theme->id;
+ is $log->action, "edit";
+};
+
+subtest "cobrand admin lets you add an icon to an existing theme" => sub {
+ $mech->get_ok("/admin/manifesttheme/lincolnshire");
+
+ my $sample_jpeg = path(__FILE__)->parent->parent->child("sample.jpg");
+ ok $sample_jpeg->exists, "sample image $sample_jpeg exists";
+ my $icon_filename = '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpg';
+
+ $mech->post( '/admin/manifesttheme/lincolnshire',
+ Content_Type => 'form-data',
+ Content => {
+ name => "Lincolnshire FixMyStreet",
+ short_name => "Lincs FMS",
+ background_colour => "#663399",
+ theme_colour => "rgb(102, 51, 153)",
+ cobrand => 'lincolnshire',
+ icon => [ $sample_jpeg, undef, Content_Type => 'image/jpeg' ],
+ },
+ );
+ ok $mech->success, 'Posted request successfully';
+
+ is $mech->uri->path, '/admin/manifesttheme/lincolnshire', "redirected back to edit page";
+ $mech->content_contains("<img src=\"/theme/lincolnshire/" . $icon_filename);
+ $mech->content_contains("<td class=\"icon-size\">133x100</td>");
+ my $icon_dest = path(FixMyStreet->path_to('web/theme/lincolnshire/', $icon_filename));
+ ok $icon_dest->exists, "Icon stored on disk";
+};
+
+subtest "cobrand admin lets you delete an icon from an existing theme" => sub {
+ my $icon_filename = '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpg';
+ my $icon_dest = path(FixMyStreet->path_to('web/theme/lincolnshire/', $icon_filename));
+ ok $icon_dest->exists, "Icon exists on disk";
+
+ $mech->get_ok("/admin/manifesttheme/lincolnshire");
+ my $fields = {
+ delete_icon => "/theme/lincolnshire/$icon_filename",
+ };
+ $mech->submit_form_ok( { with_fields => $fields } );
+
+ is $mech->uri->path, '/admin/manifesttheme/lincolnshire', "redirected back to edit page";
+ $mech->content_lacks("<img src=\"/theme/lincolnshire/" . $icon_filename);
+ $mech->content_lacks("<td class=\"icon-size\">133x100</td>");
+ ok !$icon_dest->exists, "Icon removed from disk";
+};
+
+subtest "cobrand admin rejects non-images" => sub {
+ $mech->get_ok("/admin/manifesttheme/lincolnshire");
+
+ my $sample_pdf = path(__FILE__)->parent->parent->child("sample.pdf");
+ ok $sample_pdf->exists, "sample image $sample_pdf exists";
+
+ $mech->post( '/admin/manifesttheme/lincolnshire',
+ Content_Type => 'form-data',
+ Content => {
+ name => "Lincolnshire FixMyStreet",
+ short_name => "Lincs FMS",
+ background_colour => "#663399",
+ theme_colour => "rgb(102, 51, 153)",
+ cobrand => 'lincolnshire',
+ icon => [ $sample_pdf, undef, Content_Type => 'application/pdf' ],
+ },
+ );
+ ok $mech->success, 'Posted request successfully';
+
+ is $mech->uri->path, '/admin/manifesttheme/lincolnshire', "redirected back to edit page";
+ $mech->content_lacks("90f7a64043fb458d58de1a0703a6355e2856b15e.pdf");
+ $mech->content_contains("File type not recognised. Please upload an image.");
+};
+
+subtest "theme link on cobrand admin goes to edit form when theme exists" => sub {
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 1, "theme exists" );
+
+ $mech->get_ok("/admin");
+ $mech->follow_link_ok({ text => "Manifest Theme" });
+
+ is $mech->res->previous->code, 302, "got 302 for redirect";
+ is $mech->res->previous->base->path, "/admin/manifesttheme", "redirected from index";
+ is $mech->uri->path, '/admin/manifesttheme/lincolnshire', "redirected to edit page";
+};
+
+subtest "create page on cobrand admin redirects to edit form when theme exists" => sub {
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 1, "theme exists" );
+
+ $mech->get_ok("/admin/manifesttheme/create");
+
+ is $mech->res->previous->code, 302, "got 302 for redirect";
+ is $mech->uri->path, '/admin/manifesttheme/lincolnshire', "redirected to edit page";
+};
+
+subtest "can delete theme" => sub {
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 1, "theme exists" );
+
+ my $theme_id = FixMyStreet::DB->resultset('ManifestTheme')->find({ cobrand => 'lincolnshire' })->id;
+
+ # Add an icon so we can test it gets deleted when the theme is deleted
+ my $sample_jpeg = path(__FILE__)->parent->parent->child("sample.jpg");
+ ok $sample_jpeg->exists, "sample image $sample_jpeg exists";
+ my $icon_filename = '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpg';
+
+ $mech->post( '/admin/manifesttheme/lincolnshire',
+ Content_Type => 'form-data',
+ Content => {
+ name => "Lincolnshire FixMyStreet",
+ short_name => "Lincs FMS",
+ background_colour => "#663399",
+ theme_colour => "rgb(102, 51, 153)",
+ cobrand => "lincolnshire",
+ icon => [ $sample_jpeg, undef, Content_Type => 'image/jpeg' ],
+ },
+ );
+ ok $mech->success, 'Posted request successfully';
+
+ is $mech->uri->path, '/admin/manifesttheme/lincolnshire', "redirected back to edit page";
+ my $icon_dest = path(FixMyStreet->path_to('web/theme/lincolnshire/', $icon_filename));
+ ok $icon_dest->exists, "Icon stored on disk";
+
+ $mech->submit_form_ok({ button => 'delete_theme' });
+ is $mech->uri->path, '/admin/manifesttheme/create', "redirected to create page";
+
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 0, "theme deleted" );
+ ok !$icon_dest->exists, "Icon removed from disk";
+
+ my $log = $superuser->admin_logs->search({}, { order_by => { -desc => 'id' } })->first;
+ is $log->object_id, $theme_id;
+ is $log->action, "delete";
+};
+
+subtest "can't edit another cobrand's theme" => sub {
+ FixMyStreet::DB->resultset('ManifestTheme')->create({
+ cobrand => "tfl",
+ name => "Transport for London Street Care",
+ short_name => "TfL Street Care",
+ });
+
+ $mech->get("/admin/manifesttheme/tfl");
+ ok !$mech->res->is_success(), "want a bad response";
+ is $mech->res->code, 404, "got 404";
+};
+
+ok $mech->host('www.fixmystreet.com');
+
+subtest "fms cobrand lets you view all manifest themes" => sub {
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 1, "theme already exists" );
+
+ $mech->get_ok("/admin");
+ $mech->follow_link_ok({ text => "Manifest Theme" });
+
+ is $mech->uri->path, '/admin/manifesttheme', "taken to list page";
+
+ $mech->content_contains("Transport for London Street Care");
+ $mech->content_contains("TfL Street Care");
+
+};
+
+subtest "fms cobrand lets you edit a cobrand's manifest theme" => sub {
+ $mech->get_ok("/admin/manifesttheme");
+ $mech->follow_link_ok({ url => "manifesttheme/tfl" }) or diag $mech->content;
+
+ my $fields = {
+ name => "Transport for London Report It",
+ };
+ $mech->submit_form_ok( { with_fields => $fields } );
+ is $mech->uri->path, '/admin/manifesttheme', "redirected back to list page";
+
+ my $theme = FixMyStreet::DB->resultset('ManifestTheme')->find({ cobrand => 'tfl' });
+ is $theme->name, "Transport for London Report It";
+
+};
+
+subtest "fms cobrand lets you create a new manifest theme" => sub {
+ $mech->get_ok("/admin/manifesttheme");
+ $mech->follow_link_ok({ text => "Create" });
+
+ my $fields = {
+ name => "FixMyStreet Pro",
+ short_name => "FMS Pro",
+ cobrand => "fixmystreet",
+ };
+ $mech->submit_form_ok( { with_fields => $fields } );
+ is $mech->uri->path, '/admin/manifesttheme', "redirected to list page";
+
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 2, "theme added" );
+ my $theme = FixMyStreet::DB->resultset('ManifestTheme')->find({ cobrand => 'fixmystreet' });
+ is $theme->name, "FixMyStreet Pro";
+};
+
+subtest "fms cobrand prevents you creating a duplicate theme" => sub {
+ $mech->get_ok("/admin/manifesttheme");
+ $mech->follow_link_ok({ text => "Create" });
+
+ my $fields = {
+ name => "FixMyStreet Pro",
+ short_name => "FMS Pro",
+ cobrand => "fixmystreet",
+ };
+ $mech->submit_form_ok( { with_fields => $fields } );
+ is $mech->uri->path, '/admin/manifesttheme/create', "stayed on create form";
+
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 2, "theme not added" );
+};
+
+subtest "fms cobrand prevents creating a duplicate by editing" => sub {
+ $mech->get_ok("/admin/manifesttheme");
+ $mech->follow_link_ok({ url => "manifesttheme/tfl" });
+
+ my $fields = {
+ cobrand => "fixmystreet",
+ };
+ $mech->submit_form_ok( { with_fields => $fields } );
+ is $mech->uri->path, '/admin/manifesttheme/tfl', "stayed on edit page";
+};
+
+};
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'fixamingata' ],
+}, sub {
+
+ok $mech->host("www.fixamingata.se"), "change host to FixaMinGata";
+
+subtest "single cobrand behaves correctly" => sub {
+ FixMyStreet::DB->resultset('ManifestTheme')->delete_all;
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 0, "themes all deleted" );
+
+ $mech->get_ok("/admin/manifesttheme");
+ is $mech->uri->path, '/admin/manifesttheme/create', "redirected to create page";
+
+ my $fields = {
+ name => "FixaMinGata Theme Test",
+ short_name => "FixaMinGata Short Name",
+ cobrand => "fixamingata",
+ };
+ $mech->submit_form_ok( { with_fields => $fields } );
+ is $mech->uri->path, '/admin/manifesttheme/fixamingata', "redirected to edit form page";
+ $mech->content_contains("FixaMinGata Theme Test");
+ $mech->content_contains("FixaMinGata Short Name");
+
+ is( FixMyStreet::DB->resultset('ManifestTheme')->count, 1, "theme added" );
+ my $theme = FixMyStreet::DB->resultset('ManifestTheme')->find({ cobrand => 'fixamingata' });
+ is $theme->name, "FixaMinGata Theme Test";
+};
+
+
+};
+
+done_testing();
diff --git a/t/app/controller/admin/permissions.t b/t/app/controller/admin/permissions.t
index ff5a8ec4f..b7bffaaa5 100644
--- a/t/app/controller/admin/permissions.t
+++ b/t/app/controller/admin/permissions.t
@@ -1,5 +1,4 @@
use FixMyStreet::TestMech;
-use Test::MockModule;
my $mech = FixMyStreet::TestMech->new;
@@ -29,13 +28,6 @@ ok $report, "created test report - $report_id";
$mech->log_in_ok( $oxfordshireuser->email );
-my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Oxfordshire');
-$cobrand->mock('available_permissions', sub {
- my $self = shift;
-
- return FixMyStreet::Cobrand::Default->available_permissions;
-});
-
subtest "Users can't edit report without report_edit permission" => sub {
FixMyStreet::override_config {
ALLOWED_COBRANDS => [ 'oxfordshire' ],
diff --git a/t/app/controller/admin/priorities.t b/t/app/controller/admin/priorities.t
index 4eff20be7..8341e212d 100644
--- a/t/app/controller/admin/priorities.t
+++ b/t/app/controller/admin/priorities.t
@@ -16,14 +16,14 @@ $mech->log_in_ok( $superuser->email );
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" );
+ $mech->get_ok( "/admin/responsepriorities/" . $oxfordshire->id . "/create" );
my $fields = {
name => "Cat 1A",
description => "Fixed within 24 hours",
deleted => undef,
is_default => undef,
- "contacts[".$oxfordshirecontact->id."]" => 1,
+ contacts => $oxfordshirecontact->id,
};
$mech->submit_form_ok( { with_fields => $fields } );
@@ -41,7 +41,7 @@ subtest "response priorities can set to default" => sub {
description => "Fixed within 24 hours",
deleted => undef,
is_default => 1,
- "contacts[".$oxfordshirecontact->id."]" => 1,
+ contacts => $oxfordshirecontact->id,
};
$mech->submit_form_ok( { with_fields => $fields } );
@@ -51,49 +51,36 @@ subtest "response priorities can set to default" => sub {
};
subtest "response priorities can be listed" => sub {
- $mech->get_ok( "/admin/responsepriorities/" . $oxfordshire->id );
+ $mech->get_ok( "/admin/responsepriorities" );
$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 priority was added to Bromley";
- is $oxfordshire->response_priorities->count, 1, "Response priority 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 {
+ my $bromley_priority = $bromley->response_priorities->create( {
+ deleted => 0,
+ name => "Bromley Cat 0",
+ } );
+
+ is $bromley->response_priorities->count, 1, "Response priority was added to Bromley";
+ is $oxfordshire->response_priorities->count, 1, "Response priority wasn't added to Oxfordshire";
+
$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->get_ok( "/admin/responsepriorities" );
$mech->content_contains( $oxfordshire->response_priorities->first->name );
+ $mech->content_lacks( $bromley_priority->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 );
+ $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";
};
diff --git a/t/app/controller/admin/report_edit.t b/t/app/controller/admin/report_edit.t
index c6e03ff7e..438bcc241 100644
--- a/t/app/controller/admin/report_edit.t
+++ b/t/app/controller/admin/report_edit.t
@@ -24,7 +24,7 @@ my $dt = DateTime->new(
second => 23
);
-my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
+my $report = FixMyStreet::DB->resultset('Problem')->find_or_create(
{
postcode => 'SW1A 1AA',
bodies_str => '2504',
@@ -52,7 +52,7 @@ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
$mech->log_in_ok( $superuser->email );
-my $log_entries = FixMyStreet::App->model('DB::AdminLog')->search(
+my $log_entries = FixMyStreet::DB->resultset('AdminLog')->search(
{
object_type => 'problem',
object_id => $report->id
@@ -353,7 +353,7 @@ foreach my $test (
user_body => $oxfordshire,
changes => { state => 'in progress', category => 'Potholes' },
log_entries => [
- qw/edit state_change edit state_change edit edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/
+ qw/edit state_change category_change edit state_change edit edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/
],
resend => 0,
},
@@ -412,6 +412,13 @@ foreach my $test (
delete $test->{changes}->{closed_updates};
}
+ if ($test->{changes}{title} || $test->{changes}{detail} || $test->{changes}{anonymous}) {
+ $mech->get_ok("/report/$report_id");
+ $mech->content_contains("Anonymous: <del style='background-color:#fcc'>No</del><ins style='background-color:#cfc'>Yes</ins>") if $test->{changes}{anonymous};
+ $mech->content_contains("Details: <ins style='background-color:#cfc'>Edited </ins>Detail<del style='background-color:#fcc'> for Report to Edit</del>") if $test->{changes}{detail};
+ $mech->content_contains("Subject: <ins style='background-color:#cfc'>Edited </ins>Repor<del style='background-color:#fcc'>t to Edi</del>") if $test->{changes}{title};
+ }
+
is $report->$_, $test->{changes}->{$_}, "$_ updated" for grep { $_ ne 'username' } keys %{ $test->{changes} };
if ( $test->{user} ) {
@@ -504,7 +511,7 @@ subtest 'change email to new user' => sub {
username => 'test3@example.com'
};
- my $user3 = FixMyStreet::App->model('DB::User')->find( { email => 'test3@example.com' } );
+ my $user3 = FixMyStreet::DB->resultset('User')->find( { email => 'test3@example.com' } );
ok !$user3, 'user not in database';
@@ -523,7 +530,7 @@ subtest 'change email to new user' => sub {
is $log_entries->first->action, 'edit', 'log action';
is_deeply( $mech->visible_form_values(), $new_fields, 'changed form values' );
- $user3 = FixMyStreet::App->model('DB::User')->find( { email => 'test3@example.com' } );
+ $user3 = FixMyStreet::DB->resultset('User')->find( { email => 'test3@example.com' } );
$report->discard_changes;
@@ -534,7 +541,7 @@ subtest 'change email to new user' => sub {
subtest 'adding email to abuse list from report page' => sub {
my $email = $report->user->email;
- my $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $email } );
+ my $abuse = FixMyStreet::DB->resultset('Abuse')->find( { email => $email } );
$abuse->delete if $abuse;
$mech->get_ok( '/admin/report_edit/' . $report->id );
@@ -545,7 +552,7 @@ subtest 'adding email to abuse list from report page' => sub {
$mech->content_contains('User added to abuse list');
$mech->content_contains('<small>User in abuse table</small>');
- $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $email } );
+ $abuse = FixMyStreet::DB->resultset('Abuse')->find( { email => $email } );
ok $abuse, 'entry created in abuse table';
$mech->get_ok( '/admin/report_edit/' . $report->id );
@@ -612,7 +619,7 @@ subtest "Test alert count display" => sub {
$mech->get_ok("/admin/report_edit/$report_id");
$mech->content_contains('Alerts: 0');
- my $alert = FixMyStreet::App->model('DB::Alert')->find_or_create(
+ my $alert = FixMyStreet::DB->resultset('Alert')->find_or_create(
{
alert_type => 'new_updates',
parameter => $report_id,
@@ -634,7 +641,7 @@ subtest "Test alert count display" => sub {
$alert->delete;
};
-my $report2 = FixMyStreet::App->model('DB::Problem')->find_or_create(
+my $report2 = FixMyStreet::DB->resultset('Problem')->find_or_create(
{
postcode => 'SW1A 1AA',
bodies_str => '2504',
diff --git a/t/app/controller/admin/reportextrafields.t b/t/app/controller/admin/reportextrafields.t
index e02df864f..dede25207 100644
--- a/t/app/controller/admin/reportextrafields.t
+++ b/t/app/controller/admin/reportextrafields.t
@@ -9,6 +9,8 @@ sub allow_report_extra_fields { 1 }
sub area_types { [ 'UTA' ] }
+sub must_have_2fa { 0 }
+
package FixMyStreet::Cobrand::SecondTester;
@@ -62,13 +64,12 @@ FixMyStreet::override_config {
$mech->get_ok("/admin/body/" . $body->id . "/" . $contact->category);
$mech->submit_form_ok( { with_fields => {
- "metadata[0].order" => "1",
- "metadata[0].code" => "string_test",
- "metadata[0].required" => "on",
- "metadata[0].notice" => "",
- "metadata[0].description" => "this is a test description",
- "metadata[0].datatype_description" => "hint here",
- "metadata[0].datatype" => "string",
+ "metadata[9999].order" => "1",
+ "metadata[9999].code" => "string_test",
+ "metadata[9999].required" => 1,
+ "metadata[9999].behaviour" => "question",
+ "metadata[9999].description" => "<div style='foo'>this is a test description</div>",
+ "metadata[9999].datatype" => "string",
"note" => "Added extra field",
}});
$mech->content_contains('Values updated');
@@ -78,25 +79,23 @@ FixMyStreet::override_config {
code => "string_test",
required => "true",
variable => "true",
+ protected => "false",
description => "this is a test description",
- datatype_description => "hint here",
datatype => "string",
};
$contact->discard_changes;
is_deeply $contact->get_extra_fields, $contact_extra_fields, 'new string field was added';
-
$mech->get_ok("/admin/body/" . $body->id . "/" . $contact->category);
$mech->submit_form_ok( { with_fields => {
- "metadata[1].order" => "2",
- "metadata[1].code" => "list_test",
- "metadata[1].required" => undef,
- "metadata[1].notice" => "",
- "metadata[1].description" => "this field is a list",
- "metadata[1].datatype_description" => "",
- "metadata[1].datatype" => "list",
- "metadata[1].values[0].key" => "key1",
- "metadata[1].values[0].name" => "name1",
+ "metadata[9999].order" => "2",
+ "metadata[9999].code" => "list_test",
+ "metadata[9999].required" => undef,
+ "metadata[9999].behaviour" => "question",
+ "metadata[9999].description" => "this field is a list",
+ "metadata[9999].datatype" => "singlevaluelist",
+ "metadata[9999].values[8888].key" => "key1",
+ "metadata[9999].values[8888].name" => "name1",
"note" => "Added extra list field",
}});
$mech->content_contains('Values updated');
@@ -106,8 +105,8 @@ FixMyStreet::override_config {
code => "list_test",
required => "false",
variable => "true",
+ protected => "false",
description => "this field is a list",
- datatype_description => "",
datatype => "singlevaluelist",
values => [
{ name => "name1", key => "key1" },
@@ -116,6 +115,28 @@ FixMyStreet::override_config {
$contact->discard_changes;
is_deeply $contact->get_extra_fields, $contact_extra_fields, 'new list field was added';
+ $mech->get_ok("/admin/body/" . $body->id . "/" . $contact->category);
+ $mech->submit_form_ok( { with_fields => {
+ "metadata[9999].order" => "3",
+ "metadata[9999].code" => "emergency",
+ "metadata[9999].behaviour" => "notice",
+ "metadata[9999].disable_form" => "1",
+ "metadata[9999].description" => "please ring",
+ "note" => "Added notice field",
+ }});
+ $mech->content_contains('Values updated');
+
+ push @$contact_extra_fields, {
+ order => "3",
+ code => "emergency",
+ protected => "false",
+ description => "please ring",
+ disable_form => 'true',
+ variable => 'false',
+ };
+ $contact->discard_changes;
+ is_deeply $contact->get_extra_fields, $contact_extra_fields, 'new field was added';
+
$contact->set_extra_fields();
$contact->update;
};
@@ -137,11 +158,7 @@ FixMyStreet::override_config {
is $contact->email, 'test4@example.com', 'contact updated';
is_deeply $meta_data, [ {
order => 0,
- datatype => 'string',
- datatype_description => '',
- description => '',
- required => 'false',
- variable => 'true',
+ protected => 'false',
code => 'POT',
automated => 'server_set'
} ], "automated fields not unset";
@@ -151,7 +168,7 @@ FixMyStreet::override_config {
subtest 'Create and update new ReportExtraFields' => sub {
my $extra_fields = [];
- my $model = FixMyStreet::App->model('DB::ReportExtraField');
+ my $model = FixMyStreet::DB->resultset('ReportExtraField');
is $model->count, 0, 'no ReportExtraFields yet';
$mech->get_ok("/admin/reportextrafields");
@@ -161,13 +178,12 @@ FixMyStreet::override_config {
name => "Test extra fields",
cobrand => "tester",
language => undef,
- "metadata[0].order" => "1",
- "metadata[0].code" => "string_test",
- "metadata[0].required" => "on",
- "metadata[0].notice" => "",
- "metadata[0].description" => "this is a test description",
- "metadata[0].datatype_description" => "hint here",
- "metadata[0].datatype" => "string",
+ "metadata[9999].order" => "1",
+ "metadata[9999].code" => "string_test",
+ "metadata[9999].required" => 1,
+ "metadata[9999].behaviour" => "question",
+ "metadata[9999].description" => "this is a test description",
+ "metadata[9999].datatype" => "string",
}});
is $model->count, 1, 'new ReportExtraFields created';
@@ -177,8 +193,8 @@ FixMyStreet::override_config {
code => "string_test",
required => "true",
variable => "true",
+ protected => "false",
description => "this is a test description",
- datatype_description => "hint here",
datatype => "string",
};
is_deeply $object->get_extra_fields, $extra_fields, 'new string field was added';
@@ -188,15 +204,14 @@ FixMyStreet::override_config {
$mech->get_ok("/admin/reportextrafields/" . $object->id);
$mech->submit_form_ok( { with_fields => {
"language" => "en-gb",
- "metadata[1].order" => "2",
- "metadata[1].code" => "list_test",
- "metadata[1].required" => undef,
- "metadata[1].notice" => "",
- "metadata[1].description" => "this field is a list",
- "metadata[1].datatype_description" => "",
- "metadata[1].datatype" => "list",
- "metadata[1].values[0].key" => "key1",
- "metadata[1].values[0].name" => "name1",
+ "metadata[9999].order" => "2",
+ "metadata[9999].code" => "list_test",
+ "metadata[9999].required" => undef,
+ "metadata[9999].behaviour" => "question",
+ "metadata[9999].description" => "this field is a list",
+ "metadata[9999].datatype" => "singlevaluelist",
+ "metadata[9999].values[8888].key" => "key1",
+ "metadata[9999].values[8888].name" => "name1",
}});
push @$extra_fields, {
@@ -204,8 +219,8 @@ FixMyStreet::override_config {
code => "list_test",
required => "false",
variable => "true",
+ protected => "false",
description => "this field is a list",
- datatype_description => "",
datatype => "singlevaluelist",
values => [
{ name => "name1", key => "key1" },
@@ -218,24 +233,16 @@ FixMyStreet::override_config {
$mech->get_ok("/admin/reportextrafields/" . $object->id);
$mech->submit_form_ok({ with_fields => {
- "metadata[2].order" => "3",
- "metadata[2].code" => "automated_test",
- "metadata[2].required" => undef,
- "metadata[2].notice" => "",
- "metadata[2].description" => "",
- "metadata[2].datatype_description" => "",
- "metadata[2].datatype" => "string",
- "metadata[2].automated" => "server_set",
+ "metadata[9999].order" => "3",
+ "metadata[9999].code" => "automated_test",
+ "metadata[9999].required" => undef,
+ "metadata[9999].behaviour" => "server",
}});
push @$extra_fields, {
order => "3",
code => "automated_test",
- required => "false",
- variable => "true",
- description => "",
- datatype_description => "",
- datatype => "string",
+ protected => "false",
automated => "server_set",
};
@@ -245,8 +252,8 @@ FixMyStreet::override_config {
$mech->get_ok("/admin/reportextrafields/" . $object->id);
$mech->submit_form_ok( { with_fields => {
- "metadata[1].values[1].key" => "key2",
- "metadata[1].values[1].name" => "name2",
+ "metadata[1].values[8888].key" => "key2",
+ "metadata[1].values[8888].name" => "name2",
}});
push @{$extra_fields->[1]->{values}}, { name => "name2", key => "key2" };
@@ -291,7 +298,7 @@ FixMyStreet::override_config {
LANGUAGES => [ 'en-gb,English,en_GB' ]
}, sub {
subtest "Extra fields are missing from cobrand that doesn't allow them" => sub {
- my $object = FixMyStreet::App->model('DB::ReportExtraField')->first;
+ my $object = FixMyStreet::DB->resultset('ReportExtraField')->first;
$object->update({ language => "", cobrand => ""});
$mech->get_ok("/report/new?longitude=-1.351488&latitude=51.847235&category=" . $contact->category);
@@ -300,7 +307,7 @@ FixMyStreet::override_config {
};
};
-FixMyStreet::App->model('DB::ReportExtraField')->delete_all;
+FixMyStreet::DB->resultset('ReportExtraField')->delete_all;
$mech->log_out_ok;
subtest 'Reports are created with correct extra metadata' => sub {
@@ -308,7 +315,7 @@ subtest 'Reports are created with correct extra metadata' => sub {
ALLOWED_COBRANDS => [ 'tester' ],
MAPIT_URL => 'http://mapit.uk/',
}, sub {
- my $model = FixMyStreet::App->model('DB::ReportExtraField');
+ my $model = FixMyStreet::DB->resultset('ReportExtraField');
my $extra_fields = $model->find_or_create({
name => "Test extra fields",
language => "",
@@ -320,7 +327,6 @@ subtest 'Reports are created with correct extra metadata' => sub {
required => "true",
variable => "true",
description => "this is a test description",
- datatype_description => "hint here",
datatype => "string",
});
$extra_fields->push_extra_fields({
@@ -329,7 +335,6 @@ subtest 'Reports are created with correct extra metadata' => sub {
required => "false",
variable => "true",
description => "this field is a list",
- datatype_description => "",
datatype => "singlevaluelist",
values => [
{ name => "name1", key => "key1" },
diff --git a/t/app/controller/admin/roles.t b/t/app/controller/admin/roles.t
new file mode 100644
index 000000000..bc8371404
--- /dev/null
+++ b/t/app/controller/admin/roles.t
@@ -0,0 +1,139 @@
+use FixMyStreet::TestMech;
+
+my $mech = FixMyStreet::TestMech->new;
+
+my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1);
+
+my $body = $mech->create_body_ok(2237, 'Oxfordshire County Council');
+my $body2 = $mech->create_body_ok(2482, 'Bromley Council');
+my $editor = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $body);
+my $user = $mech->create_user_ok('staffuser@example.com', name => 'Other Council User', from_body => $body);
+
+$editor->user_body_permissions->create({
+ body => $body,
+ permission_type => 'user_edit',
+});
+$editor->user_body_permissions->create({
+ body => $body,
+ permission_type => 'user_manage_permissions',
+});
+$user->user_body_permissions->create({
+ body => $body,
+ permission_type => 'report_edit_priority',
+});
+
+my $role_a = FixMyStreet::DB->resultset("Role")->create({
+ body => $body,
+ name => 'Role A',
+ permissions => ['moderate', 'user_edit'],
+});
+FixMyStreet::DB->resultset("Role")->create({
+ body => $body2,
+ name => 'Role Z',
+ permissions => ['report_inspect', 'planned_reports'],
+});
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'oxfordshire',
+ MAPIT_URL => 'http://mapit.uk',
+}, sub {
+
+ $mech->log_in_ok( $editor->email );
+
+ subtest 'role index page' => sub {
+ $mech->get_ok("/admin/roles");
+ $mech->content_contains('Role A');
+ $mech->content_contains('Moderate report details');
+ $mech->content_lacks('Role Z');
+ $mech->content_lacks('Manage shortlist');
+ $mech->content_lacks('Add/edit response templates'); # About to be added
+ };
+
+ subtest 'create a role' => sub {
+ $mech->follow_link_ok({ text => 'Create' });
+ $mech->content_lacks('Body');
+ $mech->submit_form_ok({ with_fields => { name => 'Role A' }});
+ $mech->content_contains('Role names must be unique');
+ $mech->submit_form_ok({ with_fields => {
+ name => 'Role B',
+ permissions => [ ['template_edit', 'user_manage_permissions'] ],
+ }});
+
+ $mech->content_contains('Role B');
+ $mech->content_contains('Add/edit response templates');
+ };
+
+ subtest 'editing a role preselects correct options' => sub {
+ $mech->follow_link_ok({ text => 'Edit' });
+ $mech->content_like(qr/value="moderate"[^>]*checked/);
+ $mech->content_like(qr/value="user_edit"[^>]*checked/);
+ };
+
+ subtest 'editing a role to same name as another fails' => sub {
+ $mech->submit_form_ok({ with_fields => { name => 'Role B' }});
+ $mech->content_contains('Role names must be unique');
+ };
+
+ subtest 'delete a role' => sub {
+ $mech->submit_form_ok({ button => 'delete_role' });
+ $mech->content_lacks('Role A');
+ };
+
+ subtest 'assign a user to a role' => sub {
+ $mech->get_ok('/admin/users/' . $user->id);
+ $mech->content_contains('Role B');
+ $mech->content_lacks('Role Z');
+ $mech->submit_form_ok({ with_fields => {
+ roles => 'Role B',
+ }});
+ $mech->content_like(qr/<option[^>]*selected>Role B/);
+ $mech->content_like(qr/<input[^>]*checkbox[^>]*template_edit[^>]*checked/);
+ is $user->roles->count, 1, 'in one role';
+ is $user->user_body_permissions->count, 0, 'permissions removed';
+ };
+
+ subtest 'check user has the permissions of the role' => sub {
+ $mech->log_in_ok($user->email);
+ $mech->get_ok('/admin/templates');
+ };
+
+ subtest 'remove user from role' => sub {
+ $mech->log_in_ok( $editor->email );
+ $mech->get_ok('/admin/users/' . $user->id);
+ $mech->submit_form_ok({ with_fields => {
+ roles => undef,
+ }}, 'remove role');
+ };
+};
+
+subtest 'superuser can see all bodies' => sub {
+ $mech->log_in_ok( $superuser->email );
+
+ $mech->get_ok("/admin/roles");
+ $mech->content_contains('Oxfordshire');
+ $mech->content_contains('Bromley');
+ $mech->content_contains('Role B');
+ $mech->content_contains('Role Z');
+ $mech->follow_link_ok({ text => 'Create' });
+ $mech->content_contains('Body');
+ $mech->content_contains('Bromley');
+
+ $mech->submit_form_ok({ with_fields => { body => $body->id, name => 'Role B' }});
+ $mech->content_contains('Role names must be unique');
+
+ $mech->submit_form_ok({ with_fields => {
+ name => 'Role C',
+ body => $body2->id,
+ permissions => 'contribute_as_body',
+ }});
+ $mech->content_contains('Role C');
+};
+
+subtest 'check log of the above' => sub {
+ my $id = FixMyStreet::DB->resultset("Role")->find({ name => "Role B" })->id;
+ $mech->get_ok('/admin/users/' . $editor->id . '/log');
+ $mech->content_contains('Added role <a href="/admin/roles/' . $id . '">Role B</a>');
+ $mech->content_contains('Deleted role ' . $role_a->id);
+};
+
+done_testing();
diff --git a/t/app/controller/admin/search.t b/t/app/controller/admin/search.t
index f8e70cb7a..d46843799 100644
--- a/t/app/controller/admin/search.t
+++ b/t/app/controller/admin/search.t
@@ -20,7 +20,7 @@ $mech->create_contact_ok( body_id => $oxford->id, category => 'Graffiti', email
my $bromley = $mech->create_body_ok(2482, 'Bromley Council');
-my $user3 = FixMyStreet::App->model('DB::User')->create( { email => 'test3@example.com' } );
+my $user3 = FixMyStreet::DB->resultset('User')->create( { email => 'test3@example.com' } );
my $dt = DateTime->new(
year => 2011,
@@ -31,7 +31,7 @@ my $dt = DateTime->new(
second => 23
);
-my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
+my $report = FixMyStreet::DB->resultset('Problem')->find_or_create(
{
postcode => 'SW1A 1AA',
bodies_str => '2504',
@@ -68,7 +68,7 @@ subtest 'show flagged entries' => sub {
$mech->content_contains( $report->title );
};
-my $update = FixMyStreet::App->model('DB::Comment')->create(
+my $update = FixMyStreet::DB->resultset('Comment')->create(
{
text => 'this is an update',
user => $user,
diff --git a/t/app/controller/admin/templates.t b/t/app/controller/admin/templates.t
index 0d4430cad..ad5b3e77b 100644
--- a/t/app/controller/admin/templates.t
+++ b/t/app/controller/admin/templates.t
@@ -8,18 +8,36 @@ my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super Us
my $oxfordshire = $mech->create_body_ok(2237, 'Oxfordshire County Council');
my $oxfordshirecontact = $mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Potholes', email => 'potholes@example.com' );
+my $oxfordshirecontact2 = $mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Flytipping', email => 'flytipping@example.com' );
my $oxfordshireuser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $oxfordshire);
-my $dt = DateTime->new(
- year => 2011,
- month => 04,
- day => 16,
- hour => 15,
- minute => 47,
- second => 23
-);
-
-my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
+my $bromley = $mech->create_body_ok(2482, 'Bromley Borough Council');
+my $bromleycontact = $mech->create_contact_ok( body_id => $bromley->id, category => 'Potholes', email => 'potholes@example.com' );
+my $bromleyuser = $mech->create_user_ok('bromleyuser@example.com', name => 'Council User', from_body => $bromley);
+$bromleyuser->user_body_permissions->find_or_create({
+ body => $bromley,
+ permission_type => 'report_inspect',
+});
+my $bromleytemplate = $bromley->response_templates->create({
+ title => "Bromley-specific response template.",
+ text => "This template will only appear on the Bromley cobrand.",
+});
+
+my $tfl = $mech->create_body_ok(2482, 'TfL');
+my $tflcontact = $mech->create_contact_ok( body_id => $tfl->id, category => 'Potholes', email => 'potholes@example.com' );
+my $tfluser = $mech->create_user_ok('tfluser@example.com', name => 'Council User', from_body => $tfl);
+$tfluser->user_body_permissions->find_or_create({
+ body => $tfl,
+ permission_type => 'report_inspect',
+});
+my $tfltemplate = $tfl->response_templates->create({
+ title => "TfL-specific response template.",
+ text => "This template will only appear on the TfL cobrand.",
+});
+
+my $dt = DateTime->now();
+
+my $report = FixMyStreet::DB->resultset('Problem')->find_or_create(
{
postcode => 'SW1A 1AA',
bodies_str => '2504',
@@ -45,8 +63,6 @@ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
}
);
-$mech->log_in_ok( $superuser->email );
-
my $report_id = $report->id;
ok $report, "created test report - $report_id";
@@ -63,7 +79,37 @@ subtest "response templates can be added" => sub {
};
$mech->submit_form_ok( { with_fields => $fields } );
- is $oxfordshire->response_templates->count, 1, "Response template was added";
+ is $oxfordshire->response_templates->count, 1, "Response template was added";
+};
+
+subtest 'check log of the above' => sub {
+ my $template_id = $oxfordshire->response_templates->first->id;
+ $mech->get_ok('/admin/users/' . $superuser->id . '/log');
+ $mech->content_contains('Added template <a href="/admin/templates/' . $oxfordshire->id . '/' . $template_id . '">Report acknowledgement</a>');
+};
+
+subtest "but not another with the same title" => sub {
+ my $fields = {
+ title => "Report acknowledgement",
+ text => "Another report acknowledgement.",
+ auto_response => undef,
+ "contacts[".$oxfordshirecontact->id."]" => 1,
+ };
+ my $list_url = "/admin/templates/" . $oxfordshire->id;
+ $mech->get_ok( "$list_url/new" );
+ $mech->submit_form_ok( { with_fields => $fields } );
+ is $mech->uri->path, "$list_url/new", 'not redirected';
+ $mech->content_contains( 'Please correct the errors below' );
+ $mech->content_contains( 'There is already a template with that title.' );
+
+ my @ts = $oxfordshire->response_templates->all;
+ is @ts, 1, "No new response template was added";
+
+ my $url = "$list_url/" . $ts[0]->id;
+ $mech->get_ok($url);
+ $mech->submit_form_ok( { with_fields => $fields } );
+ is $mech->uri->path, $list_url, 'redirected';
+ is $oxfordshire->response_templates->count, 1, "No new response template was added";
};
subtest "response templates are included on page" => sub {
@@ -193,7 +239,6 @@ subtest "auto-response templates that duplicate external_status_code can't be ad
});
is $oxfordshire->response_templates->count, 1, "Initial response template was created";
-
$mech->log_in_ok( $superuser->email );
$mech->get_ok( "/admin/templates/" . $oxfordshire->id . "/new" );
@@ -231,4 +276,90 @@ subtest "templates that set state and external_status_code can't be added" => su
is $oxfordshire->response_templates->count, 0, "Invalid response template wasn't added";
};
+subtest "category groups are shown" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'oxfordshire' ],
+ COBRAND_FEATURES => {
+ category_groups => {
+ oxfordshire => 1,
+ },
+ multiple_category_groups => {
+ oxfordshire => 1,
+ },
+ },
+ }, sub {
+
+ $mech->log_in_ok( $superuser->email );
+
+ $mech->get_ok( "/admin/templates/" . $oxfordshire->id . "/new" );
+ $mech->content_contains("No Group") or diag $mech->content;
+ $mech->content_lacks("Multiple Groups");
+ $mech->content_lacks("These categories appear in more than one group:");
+
+ $oxfordshirecontact->set_extra_metadata( group => [ 'Highways' ] );
+ $oxfordshirecontact->update;
+ $oxfordshirecontact2->set_extra_metadata( group => [ 'Street Cleaning' ] );
+ $oxfordshirecontact2->update;
+ $mech->get_ok( "/admin/templates/" . $oxfordshire->id . "/new" );
+ $mech->content_lacks("No Group");
+ $mech->content_lacks("Multiple Groups");
+ $mech->content_lacks("These categories appear in more than one group:");
+ $mech->content_contains("Highways");
+ $mech->content_contains("Street Cleaning");
+
+ $oxfordshirecontact->set_extra_metadata( group => [ 'Highways', 'Roads & Pavements' ] );
+ $oxfordshirecontact->update;
+ $oxfordshirecontact2->set_extra_metadata( group => [ 'Street Cleaning' ] );
+ $oxfordshirecontact2->update;
+ $mech->get_ok( "/admin/templates/" . $oxfordshire->id . "/new" );
+ $mech->content_lacks("No Group");
+ $mech->content_contains("Multiple Groups");
+ $mech->content_contains("These categories appear in more than one group:");
+ $mech->content_contains("Highways; Roads &amp; Pavements");
+ $mech->content_contains("Street Cleaning");
+ };
+};
+
+subtest "TfL cobrand only shows TfL templates" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'tfl' ],
+ COBRAND_FEATURES => { internal_ips => { tfl => [ '127.0.0.1' ] } },
+ }, sub {
+ $report->update({
+ category => $tflcontact->category,
+ bodies_str => $tfl->id,
+ latitude => 51.402096,
+ longitude => 0.015784,
+ state => 'confirmed',
+ areas => ',2482,',
+ });
+ $mech->log_in_ok( $tfluser->email );
+
+ $mech->get_ok("/report/" . $report->id);
+ $mech->content_contains( $tfltemplate->text );
+ $mech->content_contains( $tfltemplate->title );
+ $mech->content_lacks( $bromleytemplate->text );
+ $mech->content_lacks( $bromleytemplate->title );
+
+ $mech->log_out_ok;
+ };
+};
+
+subtest "Bromley cobrand only shows Bromley templates" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'bromley', 'tfl' ],
+ }, sub {
+ $report->update({ category => $bromleycontact->category, bodies_str => $bromley->id });
+ $mech->log_in_ok( $bromleyuser->email );
+
+ $mech->get_ok("/report/" . $report->id);
+ $mech->content_contains( $bromleytemplate->text );
+ $mech->content_contains( $bromleytemplate->title );
+ $mech->content_lacks( $tfltemplate->text );
+ $mech->content_lacks( $tfltemplate->title );
+
+ $mech->log_out_ok;
+ };
+};
+
done_testing();
diff --git a/t/app/controller/admin/translations.t b/t/app/controller/admin/translations.t
index f5c32baa6..442be68d5 100644
--- a/t/app/controller/admin/translations.t
+++ b/t/app/controller/admin/translations.t
@@ -59,7 +59,7 @@ subtest 'check add category with translation' => sub {
$mech->submit_form_ok( { with_fields => {
category => 'Potholes',
translation_de => 'DE potholes',
- email => 'potholes@example.org',
+ email => 'potholes',
} } );
# check that error page includes translations
diff --git a/t/app/controller/admin/triage.t b/t/app/controller/admin/triage.t
new file mode 100644
index 000000000..6e134ff67
--- /dev/null
+++ b/t/app/controller/admin/triage.t
@@ -0,0 +1,126 @@
+use FixMyStreet::TestMech;
+use FixMyStreet::Script::Alerts;
+
+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 $iow = $mech->create_body_ok(2636, 'Isle of Wight Council', { can_be_devolved => 1 } );
+my $iow_contact = $mech->create_contact_ok(
+ body_id => $iow->id,
+ category => 'Potholes',
+ email => 'potholes@example.com',
+ send_method => 'Triage'
+);
+$mech->create_contact_ok(
+ body_id => $iow->id,
+ category => 'Traffic lights',
+ email => 'lights@example.com'
+);
+
+my $dt = DateTime->now();
+
+my ($report) = $mech->create_problems_for_body(
+ 1,
+ $iow->id,
+ 'TITLE',
+ {
+ areas => 2636,
+ category => 'Potholes',
+ whensent => $dt,
+ latitude => 50.71086,
+ longitude => -1.29573,
+ send_method_used => 'Triage',
+ }
+);
+
+FixMyStreet::override_config {
+ STAGING_FLAGS => { send_reports => 1, skip_checks => 0 },
+ ALLOWED_COBRANDS => [ 'isleofwight' ],
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ subtest "user can access triage page with triage permission" => sub {
+ $user->update({ from_body => $iow });
+ $mech->log_out_ok;
+ $mech->get_ok('/admin/triage');
+
+ $mech->log_in_ok($user->email);
+ $mech->get('/admin/triage');
+ is $mech->res->code, 403, 'permission denied';
+
+ $user->user_body_permissions->create( { body => $iow, permission_type => 'triage' } );
+ $mech->get_ok('/admin/triage');
+ };
+
+ subtest "reports marked for triage show triage interface" => sub {
+ $mech->log_out_ok;
+ $mech->log_in_ok( $user->email );
+
+ $mech->get_ok('/report/' . $report->id);
+ $mech->content_lacks('CONFIRM Subject');
+
+ $report->update( { state => 'for triage' } );
+
+ $mech->get_ok('/report/' . $report->id);
+ $mech->content_contains('CONFIRM Subject');
+ };
+
+ subtest "changing report category marks report as confirmed" => sub {
+ my $report_url = '/report/' . $report->id;
+ $mech->get_ok($report_url);
+
+ my $alert = FixMyStreet::DB->resultset('Alert')->create(
+ {
+ user => $user2,
+ alert_type => 'new_updates',
+ parameter => $report->id,
+ parameter2 => '',
+ confirmed => 1,
+ }
+ );
+
+ $mech->content_contains('Traffic lights');
+
+ $mech->submit_form_ok( {
+ with_fields => {
+ category => 'Traffic lights',
+ include_update => 0,
+ }
+ },
+ 'triage form submitted'
+ );
+
+ $mech->content_contains('Potholes');
+
+ $report->discard_changes;
+ is $report->state, 'confirmed', 'report marked as confirmed';
+ ok !$report->whensent, 'report marked to resend';
+
+ my @comments = $report->comments;
+ my $comment = $comments[0];
+ my $extra = $comment->get_extra_metadata();
+ is $extra->{triage_report}, 1, 'comment indicates it is for triage in extra';
+ is $extra->{holding_category}, 'Potholes', 'comment extra has previous category';
+ is $extra->{new_category}, 'Traffic lights', 'comment extra has new category';
+ ok $comment->whensent, 'comment is marked as sent';
+
+ $mech->get_ok($report_url);
+ $mech->content_contains('Report triaged from Potholes to Traffic lights');
+
+ $mech->log_out_ok;
+ $mech->get_ok($report_url);
+ $mech->content_lacks('Report triaged from Potholes to Traffic lights');
+
+ $mech->clear_emails_ok;
+ FixMyStreet::Script::Alerts::send();
+ $mech->email_count_is(0);
+ };
+};
+
+done_testing();
diff --git a/t/app/controller/admin/update_edit.t b/t/app/controller/admin/update_edit.t
index 6ddbdbdfc..57c8973d4 100644
--- a/t/app/controller/admin/update_edit.t
+++ b/t/app/controller/admin/update_edit.t
@@ -10,7 +10,7 @@ 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 $user3 = FixMyStreet::App->model('DB::User')->create( { email => 'test3@example.com' } );
+my $user3 = FixMyStreet::DB->resultset('User')->create( { email => 'test3@example.com' } );
my $dt = DateTime->new(
year => 2011,
@@ -21,7 +21,7 @@ my $dt = DateTime->new(
second => 23
);
-my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
+my $report = FixMyStreet::DB->resultset('Problem')->find_or_create(
{
postcode => 'SW1A 1AA',
bodies_str => '2504',
@@ -52,7 +52,7 @@ $mech->log_in_ok( $superuser->email );
my $report_id = $report->id;
ok $report, "created test report - $report_id";
-my $update = FixMyStreet::App->model('DB::Comment')->create(
+my $update = FixMyStreet::DB->resultset('Comment')->create(
{
text => 'this is an update',
user => $user,
@@ -63,7 +63,7 @@ my $update = FixMyStreet::App->model('DB::Comment')->create(
}
);
-my $log_entries = FixMyStreet::App->model('DB::AdminLog')->search(
+my $log_entries = FixMyStreet::DB->resultset('AdminLog')->search(
{
object_type => 'update',
object_id => $update->id
@@ -83,7 +83,7 @@ for my $test (
state => 'confirmed',
name => '',
anonymous => 1,
- username => 'test@example.com',
+ username => $update->user->email,
},
changes => {
text => 'this is a changed update',
@@ -98,7 +98,7 @@ for my $test (
state => 'confirmed',
name => '',
anonymous => 1,
- username => 'test@example.com',
+ username => $update->user->email,
},
changes => {
name => 'A User',
@@ -113,7 +113,7 @@ for my $test (
state => 'confirmed',
name => 'A User',
anonymous => 1,
- username => 'test@example.com',
+ username => $update->user->email,
},
changes => {
anonymous => 0,
@@ -128,10 +128,10 @@ for my $test (
state => 'confirmed',
name => 'A User',
anonymous => 0,
- username => 'test@example.com',
+ username => $update->user->email,
},
changes => {
- username => 'test2@example.com',
+ username => $user2->email,
},
log_count => 4,
log_entries => [qw/edit edit edit edit/],
@@ -144,7 +144,7 @@ for my $test (
state => 'confirmed',
name => 'A User',
anonymous => 0,
- username => 'test2@example.com',
+ username => $user2->email,
},
changes => {
state => 'unconfirmed',
@@ -159,7 +159,7 @@ for my $test (
state => 'unconfirmed',
name => 'A User',
anonymous => 0,
- username => 'test2@example.com',
+ username => $user2->email,
},
changes => {
text => 'this is a twice changed update',
@@ -275,7 +275,7 @@ for my $test (
}
subtest 'editing update email creates new user if required' => sub {
- my $user = FixMyStreet::App->model('DB::User')->find( { email => 'test4@example.com' } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => 'test4@example.com' } );
$user->delete if $user;
@@ -289,7 +289,7 @@ subtest 'editing update email creates new user if required' => sub {
$mech->submit_form_ok( { with_fields => $fields } );
- $user = FixMyStreet::App->model('DB::User')->find( { email => 'test4@example.com' } );
+ $user = FixMyStreet::DB->resultset('User')->find( { email => 'test4@example.com' } );
is_deeply $mech->visible_form_values, $fields, 'submitted form values';
@@ -302,7 +302,7 @@ subtest 'editing update email creates new user if required' => sub {
subtest 'adding email to abuse list from update page' => sub {
my $email = $update->user->email;
- my $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $email } );
+ my $abuse = FixMyStreet::DB->resultset('Abuse')->find( { email => $email } );
$abuse->delete if $abuse;
$mech->get_ok( '/admin/update_edit/' . $update->id );
@@ -313,7 +313,7 @@ subtest 'adding email to abuse list from update page' => sub {
$mech->content_contains('User added to abuse list');
$mech->content_contains('<small>User in abuse table</small>');
- $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $email } );
+ $abuse = FixMyStreet::DB->resultset('Abuse')->find( { email => $email } );
ok $abuse, 'entry created in abuse table';
$mech->get_ok( '/admin/update_edit/' . $update->id );
diff --git a/t/app/controller/admin/users.t b/t/app/controller/admin/users.t
index e2c922a23..4f0298103 100644
--- a/t/app/controller/admin/users.t
+++ b/t/app/controller/admin/users.t
@@ -3,6 +3,9 @@ use FixMyStreet::TestMech;
my $mech = FixMyStreet::TestMech->new;
my $user = $mech->create_user_ok('test@example.com', name => 'Test User');
+my $original_user_id = $user->id; # For log later
+my $user2 = $mech->create_user_ok('test2@example.com', name => 'Test User 2');
+my $user3 = $mech->create_user_ok('test3@example.com', name => 'Test User 3');
my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1);
@@ -13,7 +16,7 @@ my $southend = $mech->create_body_ok(2607, 'Southend-on-Sea Borough Council');
$mech->log_in_ok( $superuser->email );
subtest 'search abuse' => sub {
- my $abuse = FixMyStreet::App->model('DB::Abuse')->find_or_create( { email => $user->email } );
+ my $abuse = FixMyStreet::DB->resultset('Abuse')->find_or_create( { email => $user->email } );
$mech->get_ok( '/admin/users?search=example' );
$mech->content_like(qr{test\@example.com.*</td>\s*<td>.*?</td>\s*<td>User in abuse table}s);
};
@@ -24,26 +27,26 @@ subtest 'remove user from abuse list from edit user page' => sub {
$mech->click_ok('unban');
- my $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $user->email } );
+ my $abuse = FixMyStreet::DB->resultset('Abuse')->find( { email => $user->email } );
ok !$abuse, 'record removed from abuse table';
};
subtest 'remove user with phone account from abuse list from edit user page' => sub {
my $abuse_user = $mech->create_user_ok('01234 456789');
- my $abuse = FixMyStreet::App->model('DB::Abuse')->find_or_create( { email => $abuse_user->phone } );
+ my $abuse = FixMyStreet::DB->resultset('Abuse')->find_or_create( { email => $abuse_user->phone } );
$mech->get_ok( '/admin/users/' . $abuse_user->id );
$mech->content_contains('User in abuse table');
- my $abuse_found = FixMyStreet::App->model('DB::Abuse')->find( { email => $abuse_user->phone } );
+ my $abuse_found = FixMyStreet::DB->resultset('Abuse')->find( { email => $abuse_user->phone } );
ok $abuse_found, 'user in abuse table';
$mech->click_ok('unban');
- $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $user->phone } );
+ $abuse = FixMyStreet::DB->resultset('Abuse')->find( { email => $user->phone } );
ok !$abuse, 'record removed from abuse table';
};
subtest 'no option to remove user already in abuse list' => sub {
- my $abuse = FixMyStreet::App->model('DB::Abuse')->find( { email => $user->email } );
+ my $abuse = FixMyStreet::DB->resultset('Abuse')->find( { email => $user->email } );
$abuse->delete if $abuse;
$mech->get_ok( '/admin/users/' . $user->id );
$mech->content_lacks('User in abuse table');
@@ -60,6 +63,7 @@ subtest 'show flagged entries' => sub {
$user->update;
};
+my $role;
subtest 'user search' => sub {
$mech->get_ok('/admin/users');
$mech->get_ok('/admin/users?search=' . $user->name);
@@ -74,17 +78,37 @@ subtest 'user search' => sub {
$user->from_body($haringey->id);
$user->update;
+ $role = $user->roles->create({
+ body => $haringey,
+ name => 'Role A',
+ permissions => ['moderate', 'user_edit'],
+ });
+ $user->add_to_roles($role);
$mech->get_ok('/admin/users?search=' . $haringey->id );
- $mech->content_contains('Haringey');
+ $mech->content_contains('test@example.com');
+ $mech->get_ok('/admin/users?role=' . $role->id);
+ $mech->content_contains('selected>Role A');
+ $mech->content_contains('test@example.com');
+};
+
+subtest 'user assign role' => sub {
+ $user->remove_from_roles($role);
+ is $user->roles->count, 0;
+ $mech->get_ok('/admin/users');
+ $mech->submit_form_ok({ with_fields => { uid => $user->id, roles => $role->id } });
+ is $user->roles->count, 1;
};
subtest 'search does not show user from another council' => sub {
FixMyStreet::override_config {
ALLOWED_COBRANDS => [ 'oxfordshire' ],
}, sub {
+ $superuser->update({ from_body => $oxfordshire->id });
$mech->get_ok('/admin/users');
- $mech->get_ok('/admin/users?search=' . $user->name);
+ $mech->content_lacks('Super User');
+ $superuser->update({ from_body => undef });
+ $mech->get_ok('/admin/users?search=' . $user->name);
$mech->content_contains( "Searching found no users." );
$mech->get_ok('/admin/users?search=' . $user->email);
@@ -102,6 +126,71 @@ subtest 'user_edit does not show user from another council' => sub {
};
};
+$mech->log_out_ok;
+
+subtest 'user_edit redirects appropriately' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'oxfordshire' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $user2->update({ from_body => $oxfordshire->id });
+ $user3->update({ from_body => $oxfordshire->id });
+ $user3->user_body_permissions->create( {
+ body => $oxfordshire,
+ permission_type => 'user_edit',
+ } );
+ $user3->user_body_permissions->create( {
+ body => $oxfordshire,
+ permission_type => 'user_assign_body',
+ } );
+ $mech->log_in_ok( $user3->email );
+
+ $mech->get_ok('/admin/users/' . $user2->id);
+ $mech->submit_form_ok( { with_fields => {
+ name => "Updated Name"
+ } } );
+ $user2->discard_changes;
+ is $user2->name, "Updated Name", "Name set correctly";
+ is $mech->uri->path, '/admin/users/' . $user2->id, 'redirected back to user form';
+
+ $mech->get_ok('/admin/users/' . $user2->id);
+ $mech->submit_form_ok( { with_fields => {
+ body => undef
+ } } );
+ $user2->discard_changes;
+ is $user2->from_body, undef, "from_body unset";
+ is $mech->uri->path, '/admin/users', 'redirected back to users list';
+
+ $mech->log_out_ok;
+ };
+};
+
+subtest 'user categories are cleared when from_body is unset' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'oxfordshire' ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->log_in_ok( $user3->email );
+
+ my $cat1 = $mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Traffic lights', email => 'lights@example.com' );
+ my $cat2 = $mech->create_contact_ok( body_id => $oxfordshire->id, category => 'Potholes', email => 'potholes@example.com' );
+ $user2->set_extra_metadata('categories', [ $cat1->id, $cat2->id ]);
+ $user2->from_body($oxfordshire->id);
+ $user2->update;
+
+ $mech->get_ok('/admin/users/' . $user2->id);
+ $mech->submit_form_ok( { with_fields => {
+ body => undef
+ } } );
+
+ $user2->discard_changes;
+ is $user2->from_body, undef, "from_body unset";
+ is $user2->get_extra_metadata('categories'), undef, "categories unset";
+ };
+};
+
+$mech->log_in_ok( $superuser->email );
+
for my $test (
{
desc => 'add user - blank form',
@@ -157,6 +246,7 @@ for my $test (
subtest $test->{desc} => sub {
$mech->get_ok('/admin/users');
$mech->submit_form_ok( { with_fields => $test->{fields} } );
+ $mech->content_contains('Norman') if $test->{fields}{name};
if ($test->{error}) {
$mech->content_contains($_) for @{$test->{error}};
} else {
@@ -166,7 +256,7 @@ for my $test (
}
my %default_perms = (
- "permissions[moderate]" => undef,
+ "permissions[moderate]" => 'on',
"permissions[planned_reports]" => undef,
"permissions[report_mark_private]" => undef,
"permissions[report_edit]" => undef,
@@ -180,14 +270,13 @@ my %default_perms = (
"permissions[contribute_as_body]" => undef,
"permissions[default_to_body]" => undef,
"permissions[view_body_contribute_details]" => undef,
- "permissions[user_edit]" => undef,
+ "permissions[user_edit]" => 'on',
"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,
);
# Start this section with user having no name
@@ -202,7 +291,7 @@ FixMyStreet::override_config {
desc => 'edit user name',
fields => {
name => '',
- email => 'test@example.com',
+ email => $user->email,
email_verified => 1,
body => $haringey->id,
phone => '',
@@ -211,6 +300,7 @@ FixMyStreet::override_config {
is_superuser => undef,
area_ids => undef,
%default_perms,
+ roles => $role->id,
},
changes => {
name => 'Changed User',
@@ -222,7 +312,7 @@ FixMyStreet::override_config {
desc => 'edit user email',
fields => {
name => 'Changed User',
- email => 'test@example.com',
+ email => $user->email,
email_verified => 1,
body => $haringey->id,
phone => '',
@@ -231,6 +321,7 @@ FixMyStreet::override_config {
is_superuser => undef,
area_ids => undef,
%default_perms,
+ roles => $role->id,
},
changes => {
email => 'changed@example.com',
@@ -251,10 +342,14 @@ FixMyStreet::override_config {
is_superuser => undef,
area_ids => undef,
%default_perms,
+ roles => $role->id,
},
changes => {
body => $southend->id,
},
+ removed => [
+ 'roles',
+ ],
log_count => 3,
log_entries => [qw/edit edit edit/],
},
@@ -339,6 +434,8 @@ FixMyStreet::override_config {
},
added => {
%default_perms,
+ 'permissions[moderate]' => undef,
+ 'permissions[user_edit]' => undef,
},
log_count => 5,
log_entries => [qw/edit edit edit edit edit/],
@@ -394,7 +491,7 @@ FixMyStreet::override_config {
$mech->create_problems_for_body(2, 2514, 'Title', { user => $existing_user });
my $count = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count;
$mech->get_ok( '/admin/users/' . $user->id );
- $mech->submit_form_ok( { with_fields => { email => 'existing@example.com' } }, 'submit email change' );
+ $mech->submit_form_ok( { with_fields => { email => $existing_user->email } }, 'submit email change' );
is $mech->uri->path, '/admin/users/' . $existing_user->id, 'redirected';
my $p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $existing_user->id })->count;
is $p, $count + 2, 'reports merged';
@@ -448,7 +545,7 @@ subtest "Send login email from admin for unverified email" => sub {
is $email->header('Subject'), "Your FixMyStreet account details",
"subject is correct";
- is $email->header('To'), 'test@example.com', "to is correct";
+ is $email->header('To'), $user->email, "to is correct";
my $link = $mech->get_link_from_email($email);
@@ -470,7 +567,10 @@ subtest "Send login email from admin for unverified email" => sub {
};
subtest "Anonymizing user from admin" => sub {
- $mech->create_problems_for_body(4, 2237, 'Title');
+ my ($problem) = $mech->create_problems_for_body(4, 2237, 'Title');
+ $mech->create_comment_for_problem($problem, $user, $user->name, 'An update', 'f', 'confirmed', 'confirmed');
+ $mech->create_comment_for_problem($problem, $user, $user->name, '2nd update', 't', 'confirmed', 'fixed - user');
+ $mech->create_comment_for_problem($problem, $user, $user->name, '3rd update', 'f', 'unconfirmed', 'confirmed');
my $count_p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count;
my $count_u = FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id })->count;
$mech->get_ok( '/admin/users/' . $user->id );
@@ -492,6 +592,12 @@ subtest "Hiding user's reports from admin" => sub {
is $c, $count_u;
};
+subtest "Hiding user with only unconfirmed updates does not error" => sub {
+ FixMyStreet::DB->resultset('Comment')->search({ user_id => $user->id, state => 'hidden' })->update({ state => 'unconfirmed' });
+ $mech->get_ok( '/admin/users/' . $user->id );
+ $mech->submit_form_ok({ button => 'hide_everywhere' });
+};
+
subtest "Logging user out" => sub {
my $mech2 = FixMyStreet::TestMech->new;
$mech2->log_in_ok($user->email);
@@ -580,4 +686,25 @@ subtest "View timeline" => sub {
$mech->get_ok('/admin/timeline');
};
+subtest 'View user log' => sub {
+ my $p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->first;
+ $user->add_to_planned_reports($p);
+
+ # User 1 created all the reports
+ my $id = $p->id;
+ $mech->get_ok('/admin/users?search=' . $user->email);
+ $mech->follow_link_ok({ text => 'Timeline', n => 2 });
+ $mech->content_like(qr/Problem.*?>$id<\/a> created/);
+ $mech->content_like(qr/Problem.*?>$id<\/a> added to shortlist/);
+
+ # User 3 edited user 2 above
+ $mech->get_ok('/admin/users/' . $user3->id . '/log');
+ $mech->content_like(qr/Edited user.*?test2\@example/);
+
+ # Superuser added a user, and merged one
+ $mech->get_ok('/admin/users/' . $superuser->id . '/log');
+ $mech->content_like(qr/Added user.*?0156/);
+ $mech->content_like(qr/Merged user $original_user_id/);
+};
+
done_testing();
diff --git a/t/app/controller/admin/users_import.t b/t/app/controller/admin/users_import.t
new file mode 100644
index 000000000..df8884797
--- /dev/null
+++ b/t/app/controller/admin/users_import.t
@@ -0,0 +1,34 @@
+use FixMyStreet::TestMech;
+
+my $mech = FixMyStreet::TestMech->new;
+
+my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1);
+my $body = $mech->create_body_ok(2509, 'Haringey Borough Council');
+
+$mech->log_in_ok( $superuser->email );
+
+my $body_id = $body->id;
+my $csv = <<EOF;
+name,email,from_body,permissions,roles
+Adrian,adrian\@example.org,$body_id,moderate:user_edit,
+Belinda,belinda\@example.org,$body_id,,Customer Service
+EOF
+
+FixMyStreet::DB->resultset("Role")->create({
+ body => $body,
+ name => 'Customer Service',
+});
+
+subtest 'import CSV file' => sub {
+ $mech->get_ok('/admin/users/import');
+ $mech->submit_form_ok({ with_fields => {
+ csvfile => [ [ undef, 'foo.csv', Content => $csv ], 1],
+ }});
+ $mech->content_contains('Created 2 new users');
+ my $a = FixMyStreet::DB->resultset("User")->find({ email => 'adrian@example.org' });
+ is $a->user_body_permissions->count, 2;
+ my $b = FixMyStreet::DB->resultset("User")->find({ email => 'belinda@example.org' });
+ is $b->roles->count, 1;
+};
+
+done_testing();
diff --git a/t/app/controller/alert_new.t b/t/app/controller/alert_new.t
index f77114d86..7eba90530 100644
--- a/t/app/controller/alert_new.t
+++ b/t/app/controller/alert_new.t
@@ -1,60 +1,61 @@
use FixMyStreet::TestMech;
-use FixMyStreet::App;
use FixMyStreet::Script::Alerts;
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="([^"]*)"/;
+my $user = FixMyStreet::App->model('DB::User')
+ ->new( { email => 'test@example.com' } );
+
+my $body = $mech->create_body_ok(2651, 'Edinburgh Council');
+my ($report) = $mech->create_problems_for_body(1, $body->id, 'Existing');
foreach my $test (
{
- email => 'test@example.com',
+ email => $user->email,
type => 'area_problems',
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',
+'/alert/subscribe?type=local&rznvy=' . $user->email . '&feed=area:1000:A_Location',
param1 => 1000
},
{
- email => 'test@example.com',
+ email => $user->email,
type => 'council_problems',
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',
+'/alert/subscribe?type=local&rznvy=' . $user->email . '&feed=council:1000:A_Location',
param1 => 1000,
param2 => 1000,
},
{
- email => 'test@example.com',
+ email => $user->email,
type => 'ward_problems',
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',
+'/alert/subscribe?type=local&rznvy=' . $user->email . '&feed=ward:1000:1001:A_Location:Diff_Location',
param1 => 1000,
param2 => 1001,
},
{
- email => 'test@example.com',
+ email => $user->email,
type => 'local_problems',
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',
+'/alert/subscribe?type=local&rznvy=' . $user->email . '&feed=local:10.2:20.1',
param1 => 20.1,
param2 => 10.2,
},
{
- email => 'test@example.com',
+ email => $user->email,
type => 'new_updates',
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,
+ uri => '/alert/subscribe?type=updates&rznvy=' . $user->email . '&id=' . $report->id,
+ param1 => $report->id,
}
)
{
@@ -63,25 +64,19 @@ foreach my $test (
my $type = $test->{type};
- my $user =
- FixMyStreet::App->model('DB::User')
- ->find( { email => $test->{email} } );
-
- # we don't want an alert
- if ($user) {
- $mech->delete_user($user);
- }
+ $mech->get_ok('/alert/subscribe?id=' . $report->id);
+ my ($csrf) = $mech->content =~ /name="token" value="([^"]*)"/;
$mech->get_ok( $test->{uri} . "&token=$csrf" );
$mech->content_contains( $test->{content} );
- $user =
- FixMyStreet::App->model('DB::User')
+ my $user =
+ FixMyStreet::DB->resultset('User')
->find( { email => $test->{email} } );
ok $user, 'user created for alert';
- my $alert = FixMyStreet::App->model('DB::Alert')->find(
+ my $alert = FixMyStreet::DB->resultset('Alert')->find(
{
user => $user,
alert_type => $type,
@@ -101,7 +96,7 @@ foreach my $test (
my ($url_token) = $url =~ m{/A/(\S+)};
ok $url, "extracted confirm url '$url'";
- my $token = FixMyStreet::App->model('DB::Token')->find(
+ my $token = FixMyStreet::DB->resultset('Token')->find(
{
token => $url_token,
scope => 'alert'
@@ -121,7 +116,7 @@ foreach my $test (
($url_token) = $url =~ m{/A/(\S+)};
ok $url_token ne $existing_token, 'sent out a new token';
- $token = FixMyStreet::App->model('DB::Token')->find(
+ $token = FixMyStreet::DB->resultset('Token')->find(
{
token => $url_token,
scope => 'alert'
@@ -135,7 +130,7 @@ foreach my $test (
$mech->content_contains('alert created');
$alert =
- FixMyStreet::App->model('DB::Alert')->find( { id => $existing_id, } );
+ FixMyStreet::DB->resultset('Alert')->find( { id => $existing_id, } );
ok $alert->confirmed, 'alert set to confirmed';
$mech->delete_user($user);
@@ -154,7 +149,7 @@ foreach my $test (
my $user = $mech->create_user_ok('test-new@example.com');
- my $alert = FixMyStreet::App->model('DB::Alert')->find(
+ my $alert = FixMyStreet::DB->resultset('Alert')->find(
{
user => $user,
alert_type => $type
@@ -163,9 +158,12 @@ 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&token=' . $csrf );
+ $mech->get_ok('/alert/subscribe?id=' . $report->id);
+ my ($csrf) = $mech->content =~ /name="token" value="([^"]*)"/;
+
+ $mech->get_ok( '/alert/subscribe?type=local&rznvy=' . $user->email . '&feed=area:1000:A_Location&token=' . $csrf );
- $alert = FixMyStreet::App->model('DB::Alert')->find(
+ $alert = FixMyStreet::DB->resultset('Alert')->find(
{
user => $user,
alert_type => $type,
@@ -184,8 +182,6 @@ foreach my $test (
};
}
-my $body = $mech->create_body_ok(2651, 'Edinburgh Council');
-
foreach my $test (
{
desc => 'logged in user signing up',
@@ -206,7 +202,7 @@ foreach my $test (
$mech->clear_emails_ok;
FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ ALLOWED_COBRANDS => 'fixmystreet',
MAPIT_URL => 'http://mapit.uk/',
}, sub {
$mech->get_ok('/alert/list?pc=EH11BB');
@@ -214,7 +210,7 @@ foreach my $test (
$mech->set_visible( [ radio => 'council:' . $body->id . ':City_of_Edinburgh' ] );
$mech->click('alert');
- my $alert = FixMyStreet::App->model('DB::Alert')->find(
+ my $alert = FixMyStreet::DB->resultset('Alert')->find(
{
user => $user,
alert_type => $type,
@@ -232,12 +228,12 @@ foreach my $test (
for my $test (
{
- email => 'test@example.com',
+ email => $user->email,
type => 'new_updates',
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,
+ uri => '/alert/subscribe?type=updates&rznvy=' . $user->email . '&id=' . $report->id,
+ param1 => $report->id,
}
)
{
@@ -247,7 +243,7 @@ for my $test (
my $type = $test->{type};
my $user =
- FixMyStreet::App->model('DB::User')
+ FixMyStreet::DB->resultset('User')
->find( { email => $test->{email} } );
# we don't want an alert
@@ -257,19 +253,22 @@ for my $test (
}
my $abuse =
- FixMyStreet::App->model('DB::Abuse')
+ FixMyStreet::DB->resultset('Abuse')
->find_or_create( { email => $test->{email} } );
+ $mech->get_ok('/alert/subscribe?id=' . $report->id);
+ my ($csrf) = $mech->content =~ /name="token" value="([^"]*)"/;
+
$mech->get_ok( $test->{uri} . "&token=$csrf" );
$mech->content_contains( $test->{content} );
$user =
- FixMyStreet::App->model('DB::User')
+ FixMyStreet::DB->resultset('User')
->find( { email => $test->{email} } );
ok $user, 'user created for alert';
- $alert = FixMyStreet::App->model('DB::Alert')->find(
+ $alert = FixMyStreet::DB->resultset('Alert')->find(
{
user => $user,
alert_type => $type,
@@ -290,6 +289,53 @@ for my $test (
};
}
+subtest 'Test body user signing someone else up for alerts' => sub {
+ my $staff_user = $mech->create_user_ok('astaffuser@example.com', name => 'A staff user', from_body => $body);
+ $mech->log_in_ok($staff_user->email);
+
+ $mech->get_ok('/alert/subscribe?id=' . $report->id);
+ my ($csrf) = $mech->content =~ /name="token" value="([^"]*)"/;
+ $mech->post_ok('/alert/subscribe', { rznvy => 'someoneelse@example.org', id => $report->id, type => 'updates', token => $csrf });
+
+ my $user = FixMyStreet::DB->resultset('User')->find({ email => 'someoneelse@example.org' });
+ is $user, undef, 'No user made by bad request';
+
+ my $alert = FixMyStreet::DB->resultset('Alert')->find({
+ user => $staff_user,
+ alert_type => 'new_updates',
+ parameter => $report->id,
+ confirmed => 1,
+ });
+ ok $alert, 'New alert created with logged in user';
+ $alert->delete;
+
+ $staff_user->user_body_permissions->create({ permission_type => 'contribute_as_another_user', body => $body });
+ $mech->get_ok('/alert/subscribe?id=' . $report->id);
+ $mech->submit_form_ok({ with_fields => { rznvy => 'someoneelse@example.org' } });
+ $mech->content_contains('Email alert created');
+
+ $user = FixMyStreet::DB->resultset('User')->find({ email => 'someoneelse@example.org' });
+ ok $user, 'user created for alert';
+
+ $alert = FixMyStreet::DB->resultset('Alert')->find({
+ user => $user,
+ alert_type => 'new_updates',
+ parameter => $report->id,
+ confirmed => 1,
+ });
+ ok $alert, 'New alert created for another user';
+
+ $alert = FixMyStreet::DB->resultset('Alert')->find({
+ user => $staff_user,
+ alert_type => 'new_updates',
+ parameter => $report->id,
+ confirmed => 1,
+ });
+ is $alert, undef, 'No alert created for staff user';
+};
+
+$report->delete; # Emails sent otherwise below
+
my $gloucester = $mech->create_body_ok(2226, 'Gloucestershire County Council');
$mech->create_body_ok(2326, 'Cheltenham Borough Council');
@@ -310,7 +356,7 @@ subtest "Test two-tier council alerts" => sub {
},
) {
FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ ALLOWED_COBRANDS => 'fixmystreet',
MAPIT_URL => 'http://mapit.uk/',
}, sub {
$mech->get_ok( '/alert/list?pc=GL502PR' );
@@ -345,7 +391,7 @@ subtest "Test normal alert signups and that alerts are sent" => sub {
) {
$mech->get_ok( '/alert' );
FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ ALLOWED_COBRANDS => 'fixmystreet',
MAPIT_URL => 'http://mapit.uk/',
}, sub {
$mech->submit_form_ok( { with_fields => { pc => 'EH11BB' } } );
@@ -358,7 +404,7 @@ subtest "Test normal alert signups and that alerts are sent" => sub {
my $url = $mech->get_link_from_email;
my ($url_token) = $url =~ m{/A/(\S+)};
$mech->clear_emails_ok;
- my $token = FixMyStreet::App->model('DB::Token')->find( { token => $url_token, scope => 'alert' } );
+ my $token = FixMyStreet::DB->resultset('Token')->find( { token => $url_token, scope => 'alert' } );
$mech->get_ok( $url );
$mech->content_contains('alert created');
} else {
@@ -414,6 +460,9 @@ subtest "Test normal alert signups and that alerts are sent" => sub {
is +(my $c = () = $email->as_string =~ /Other User/g), 2, 'Update name given, twice';
unlike $email->as_string, qr/Anonymous User/, 'Update name not given';
+ $report->discard_changes;
+ ok $report->get_extra_metadata('closure_alert_sent_at'), 'Closure time set';
+
# The update alert was to the problem reporter, so has a special update URL
$mech->log_out_ok;
$mech->get_ok( "/report/$report_id" );
@@ -449,14 +498,14 @@ subtest "Test alerts are not sent for no-text updates" => sub {
ok $report2, "created test report - $report2_id";
# Must be first
- my $alert2 = FixMyStreet::App->model('DB::Alert')->create( {
+ my $alert2 = FixMyStreet::DB->resultset('Alert')->create( {
parameter => $report2_id,
alert_type => 'new_updates',
user => $user2,
} )->confirm;
ok $alert2, 'created alert for other user';
- my $alert = FixMyStreet::App->model('DB::Alert')->create( {
+ my $alert = FixMyStreet::DB->resultset('Alert')->create( {
parameter => $report_id,
alert_type => 'new_updates',
user => $user2,
@@ -492,7 +541,7 @@ subtest "Test no marked as confirmed added to alerts" => sub {
my $report_id = $report->id;
ok $report, "created test report - $report_id";
- my $alert = FixMyStreet::App->model('DB::Alert')->create( {
+ my $alert = FixMyStreet::DB->resultset('Alert')->create( {
parameter => $report_id,
alert_type => 'new_updates',
user => $user2,
@@ -552,7 +601,7 @@ for my $test (
my $report_id = $report->id;
ok $report, "created test report - $report_id";
- my $alert = FixMyStreet::App->model('DB::Alert')->create( {
+ my $alert = FixMyStreet::DB->resultset('Alert')->create( {
parameter => $report_id,
alert_type => 'new_updates',
user => $user2,
@@ -597,7 +646,7 @@ subtest "Test signature template is used from cobrand" => sub {
my $report_id = $report->id;
ok $report, "created test report - $report_id";
- my $alert = FixMyStreet::App->model('DB::Alert')->create( {
+ my $alert = FixMyStreet::DB->resultset('Alert')->create( {
parameter => $report_id,
alert_type => 'new_updates',
user => $user1,
@@ -611,9 +660,9 @@ subtest "Test signature template is used from cobrand" => sub {
$mech->clear_emails_ok;
FixMyStreet::override_config {
MAPIT_URL => 'http://mapit.uk/',
- ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ ALLOWED_COBRANDS => 'fixmystreet',
}, sub {
- FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ FixMyStreet::DB->resultset('AlertType')->email_alerts();
};
my $email = $mech->get_text_body_from_email;
@@ -628,9 +677,9 @@ subtest "Test signature template is used from cobrand" => sub {
$mech->clear_emails_ok;
FixMyStreet::override_config {
MAPIT_URL => 'http://mapit.uk/',
- ALLOWED_COBRANDS => [ { 'fixmystreet' => '.' } ],
+ ALLOWED_COBRANDS => 'fixmystreet',
}, sub {
- FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ FixMyStreet::DB->resultset('AlertType')->email_alerts();
};
$email = $mech->get_text_body_from_email;
@@ -686,7 +735,7 @@ for my $test (
$alert_params->{whensubscribed} = $dt;
$alert_params->{confirmed} = 1;
- my $alert_user1 = FixMyStreet::App->model('DB::Alert')->create( $alert_params );
+ my $alert_user1 = FixMyStreet::DB->resultset('Alert')->create( $alert_params );
ok $alert_user1, "alert created";
my ($report) = $mech->create_problems_for_body(1, $body->id, 'Testing', {
@@ -703,7 +752,7 @@ for my $test (
FixMyStreet::override_config {
MAPIT_URL => 'http://mapit.uk/',
}, sub {
- FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ FixMyStreet::DB->resultset('AlertType')->email_alerts();
};
$mech->email_count_is(0);
@@ -711,7 +760,7 @@ for my $test (
FixMyStreet::override_config {
MAPIT_URL => 'http://mapit.uk/',
}, sub {
- FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ FixMyStreet::DB->resultset('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';
@@ -736,7 +785,7 @@ subtest 'check new updates alerts for non public reports only go to report owner
$mech->create_comment_for_problem($report, $user3, 'Anonymous User', 'This is some more update text', 't', 'confirmed', undef, { confirmed => $r_dt->clone->add( minutes => 8 ) });
- my $alert_user1 = FixMyStreet::App->model('DB::Alert')->create( {
+ my $alert_user1 = FixMyStreet::DB->resultset('Alert')->create( {
user => $user1,
alert_type => 'new_updates',
parameter => $report->id,
@@ -746,10 +795,10 @@ subtest 'check new updates alerts for non public reports only go to report owner
ok $alert_user1, "alert created";
$mech->clear_emails_ok;
- FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ FixMyStreet::DB->resultset('AlertType')->email_alerts();
$mech->email_count_is(0);
- my $alert_user2 = FixMyStreet::App->model('DB::Alert')->create( {
+ my $alert_user2 = FixMyStreet::DB->resultset('Alert')->create( {
user => $user2,
alert_type => 'new_updates',
parameter => $report->id,
@@ -758,13 +807,13 @@ 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();
+ FixMyStreet::DB->resultset('AlertType')->email_alerts();
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();
+ FixMyStreet::DB->resultset('AlertType')->email_alerts();
$email = $mech->get_text_body_from_email;
like $email, qr/This is some more update text/, 'alert contains update text';
@@ -792,7 +841,7 @@ subtest 'check setting include dates in new updates cobrand option' => sub {
my $update = $mech->create_comment_for_problem($report, $user3, 'Anonymous User', 'This is some more update text', 't', 'confirmed', undef, { confirmed => $r_dt });
- my $alert_user1 = FixMyStreet::App->model('DB::Alert')->create( {
+ my $alert_user1 = FixMyStreet::DB->resultset('Alert')->create( {
user => $user1,
alert_type => 'new_updates',
parameter => $report->id,
@@ -803,7 +852,7 @@ subtest 'check setting include dates in new updates cobrand option' => sub {
$mech->clear_emails_ok;
- FixMyStreet::App->model('DB::AlertType')->email_alerts();
+ FixMyStreet::DB->resultset('AlertType')->email_alerts();
my $date_in_alert = Utils::prettify_dt( $update->confirmed );
my $email = $mech->get_text_body_from_email;
diff --git a/t/app/controller/around.t b/t/app/controller/around.t
index b123692fa..186b833fd 100644
--- a/t/app/controller/around.t
+++ b/t/app/controller/around.t
@@ -100,6 +100,16 @@ subtest 'check lookup by reference' => sub {
is $mech->uri->path, "/report/$id", "redirected to report page";
};
+subtest 'check lookup by reference does not show non_public reports' => sub {
+ $edinburgh_problems[0]->update({
+ non_public => 1
+ });
+ my $id = $edinburgh_problems[0]->id;
+ $mech->get_ok('/');
+ $mech->submit_form_ok( { with_fields => { pc => "ref:$id" } }, 'non_public ref');
+ $mech->content_contains('Searching found no reports');
+};
+
subtest 'check non public reports are not displayed on around page' => sub {
$mech->get_ok('/');
FixMyStreet::override_config {
@@ -127,6 +137,18 @@ subtest 'check non public reports are not displayed on around page' => sub {
'problem marked non public is not visible' );
};
+subtest 'check missing body message not shown when it does not need to be' => sub {
+ $mech->get_ok('/');
+ 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('yet have details for the other councils that cover this location');
+};
+
for my $permission ( qw/ report_inspect report_mark_private/ ) {
subtest 'check non public reports are displayed on around page with $permission permission' => sub {
my $body = FixMyStreet::DB->resultset('Body')->find( $body_edin_id );
@@ -210,7 +232,11 @@ subtest 'check category, status and extra filtering works on /around' => sub {
# Create one open and one fixed report in each category
foreach my $category ( @$categories ) {
- $mech->create_contact_ok( category => $category, body_id => $body->id, email => "$category\@example.org" );
+ my $contact = $mech->create_contact_ok( category => $category, body_id => $body->id, email => "$category\@example.org" );
+ if ($category ne 'Pothole') {
+ $contact->set_extra_metadata(group => ['Environment']);
+ $contact->update;
+ }
foreach my $state ( 'confirmed', 'fixed - user', 'fixed - council' ) {
my %report_params = (
%$params,
@@ -230,9 +256,14 @@ subtest 'check category, status and extra filtering works on /around' => sub {
FixMyStreet::override_config {
ALLOWED_COBRANDS => 'fixmystreet',
MAPIT_URL => 'http://mapit.uk/',
+ COBRAND_FEATURES => { category_groups => { fixmystreet => 1 } },
}, sub {
$mech->get_ok( '/around?filter_category=Pothole&bbox=' . $bbox );
$mech->content_contains('<option value="Pothole" selected>');
+ $mech->content_contains('<optgroup label="Environment">');
+
+ $mech->get_ok( '/around?filter_group=Environment&bbox=' . $bbox );
+ $mech->content_contains('<option value="Flytipping" selected>');
};
$json = $mech->get_ok_json( '/around?ajax=1&filter_category=Pothole&bbox=' . $bbox );
@@ -268,7 +299,7 @@ subtest 'check old problems not shown by default on around page' => sub {
my $pins = $json->{pins};
is scalar @$pins, 9, 'correct number of reports when no age';
- my $problems = FixMyStreet::App->model('DB::Problem')->to_body( $body->id );
+ my $problems = FixMyStreet::DB->resultset('Problem')->to_body( $body->id );
$problems->first->update( { confirmed => \"current_timestamp-'7 months'::interval" } );
$json = $mech->get_ok_json( '/around?ajax=1&bbox=' . $bbox );
@@ -282,7 +313,7 @@ subtest 'check old problems not shown by default on around page' => sub {
$problems->update( { confirmed => \"current_timestamp" } );
};
-subtest 'check sorting by update uses lastupdate to determine age' => sub {
+subtest 'check sorting' => sub {
my $params = {
postcode => 'OX20 1SZ',
latitude => 51.754926,
@@ -291,19 +322,31 @@ subtest 'check sorting by update uses lastupdate to determine age' => sub {
my $bbox = ($params->{longitude} - 0.01) . ',' . ($params->{latitude} - 0.01)
. ',' . ($params->{longitude} + 0.01) . ',' . ($params->{latitude} + 0.01);
- my $problems = FixMyStreet::App->model('DB::Problem')->to_body( $body->id );
- $problems->first->update( { confirmed => \"current_timestamp-'7 months'::interval" } );
+ subtest 'by update uses lastupdate to determine age' => sub {
+ my $problems = FixMyStreet::DB->resultset('Problem')->to_body( $body->id );
+ $problems->first->update( { confirmed => \"current_timestamp-'7 months'::interval" } );
- my $json = $mech->get_ok_json( '/around?ajax=1&bbox=' . $bbox );
- my $pins = $json->{pins};
- is scalar @$pins, 8, 'correct number of reports with default sorting';
+ my $json = $mech->get_ok_json( '/around?ajax=1&bbox=' . $bbox );
+ my $pins = $json->{pins};
+ is scalar @$pins, 8, 'correct number of reports with default sorting';
+ $json = $mech->get_ok_json( '/around?ajax=1&sort=updated-desc&bbox=' . $bbox );
+ $pins = $json->{pins};
+ is scalar @$pins, 9, 'correct number of reports with updated sort';
- $json = $mech->get_ok_json( '/around?ajax=1&sort=updated-desc&bbox=' . $bbox );
- $pins = $json->{pins};
- is scalar @$pins, 9, 'correct number of reports with updated sort';
+ $problems->update( { confirmed => \"current_timestamp" } );
+ };
- $problems->update( { confirmed => \"current_timestamp" } );
+ subtest 'by comment count' => sub {
+ my @problems = FixMyStreet::DB->resultset('Problem')->to_body( $body->id )->all;
+ $mech->create_comment_for_problem($problems[3], $problems[0]->user, 'Name', 'Text', 'f', 'confirmed', 'confirmed');
+ $mech->create_comment_for_problem($problems[3], $problems[0]->user, 'Name', 'Text', 'f', 'confirmed', 'confirmed');
+ $mech->create_comment_for_problem($problems[6], $problems[0]->user, 'Name', 'Text', 'f', 'confirmed', 'confirmed');
+ my $json = $mech->get_ok_json( '/around?ajax=1&sort=comments-desc&bbox=' . $bbox );
+ my $pins = $json->{pins};
+ is $pins->[0][3], $problems[3]->id, 'Report with two updates first';
+ is $pins->[1][3], $problems[6]->id, 'Report with one update second';
+ };
};
subtest 'check show old reports checkbox shown on around page' => sub {
@@ -314,7 +357,7 @@ subtest 'check show old reports checkbox shown on around page' => sub {
$mech->get_ok( '/around?pc=OX20+1SZ' );
$mech->content_contains('id="show_old_reports_wrapper" class="report-list-filters hidden"');
- my $problems = FixMyStreet::App->model('DB::Problem')->to_body( $body->id );
+ my $problems = FixMyStreet::DB->resultset('Problem')->to_body( $body->id );
$problems->first->update( { confirmed => \"current_timestamp-'7 months'::interval" } );
$mech->get_ok( '/around?pc=OX20+1SZ&status=all' );
@@ -366,7 +409,36 @@ subtest 'check map zoom level customisation' => sub {
subtest 'check nearby lookup' => sub {
my $p = FixMyStreet::DB->resultset("Problem")->search({ external_body => "Pothole-confirmed" })->first;
$mech->get_ok('/around/nearby?latitude=51.754926&longitude=-1.256179&filter_category=Pothole');
- $mech->content_contains('["51.754926","-1.256179","yellow",' . $p->id . ',"Around page Test 1 for ' . $body->id . '","small",false]');
+ $mech->content_contains('[51.754926,-1.256179,"yellow",' . $p->id . ',"Around page Test 1 for ' . $body->id . '","small",false]');
+};
+
+my $he = Test::MockModule->new('HighwaysEngland');
+$he->mock('_lookup_db', sub {
+ my ($road, $table, $thing, $thing_name) = @_;
+
+ if ($road eq 'M6' && $thing eq '11') {
+ return { latitude => 52.65866, longitude => -2.06447 };
+ } elsif ($road eq 'M5' && $thing eq '132.5') {
+ return { latitude => 51.5457, longitude => 2.57136 };
+ }
+});
+
+subtest 'junction lookup' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ MAPIT_URL => 'http://mapit.uk',
+ MAPIT_TYPES => ['EUR'],
+ }, sub {
+ $mech->log_out_ok;
+
+ $mech->get_ok('/');
+ $mech->submit_form_ok({ with_fields => { pc => 'M6, Junction 11' } });
+ $mech->content_contains('52.65866');
+
+ $mech->get_ok('/');
+ $mech->submit_form_ok({ with_fields => { pc => 'M5 132.5' } });
+ $mech->content_contains('51.5457');
+ };
};
done_testing();
diff --git a/t/app/controller/auth.t b/t/app/controller/auth.t
index ffabc75f3..24deb8cab 100644
--- a/t/app/controller/auth.t
+++ b/t/app/controller/auth.t
@@ -1,3 +1,19 @@
+package FixMyStreet::Cobrand::Dummy;
+use parent 'FixMyStreet::Cobrand::Default';
+
+sub must_have_2fa {
+ my ($self, $user) = @_;
+ return 'skip' if $user->name eq 'skip';
+ return 1;
+}
+
+package FixMyStreet::Cobrand::Expiring;
+use parent 'FixMyStreet::Cobrand::Default';
+
+sub password_expiry { 86400 }
+
+package main;
+
use Test::MockModule;
use FixMyStreet::TestMech;
@@ -7,10 +23,6 @@ my $test_email = 'test@example.com';
my $test_email3 = 'newuser@example.org';
my $test_password = 'foobar123';
-END {
- done_testing();
-}
-
$mech->get_ok('/auth');
# check that we can't reach a page that is only available to authenticated users
@@ -81,7 +93,7 @@ $mech->not_logged_in_ok;
# check that the user does not exist
sub get_user {
- FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
}
ok !get_user(), "no user exists";
@@ -92,8 +104,10 @@ $mech->not_logged_in_ok;
# visit the confirm link and check user is confirmed
$mech->get_ok($link);
- ok get_user(), "user created";
+ my $user = get_user();
+ ok $user, "user created";
is $mech->uri->path, '/my', "redirected to the 'my' section of site";
+ ok $user->get_extra_metadata('last_password_change'), 'password change set';
$mech->logged_in_ok;
# logout
@@ -154,7 +168,7 @@ subtest "sign in with uppercase email" => sub {
$mech->content_contains($test_email);
$mech->content_lacks($uc_test_email);
- my $count = FixMyStreet::App->model('DB::User')->search( { email => $uc_test_email } )->count;
+ my $count = FixMyStreet::DB->resultset('User')->search( { email => $uc_test_email } )->count;
is $count, 0, "uppercase user wasn't created";
};
@@ -178,7 +192,7 @@ FixMyStreet::override_config {
ok $mech->email_count_is(0);
- my $count = FixMyStreet::App->model('DB::User')->search( { email => $test_email3 } )->count;
+ my $count = FixMyStreet::DB->resultset('User')->search( { email => $test_email3 } )->count;
is $count, 0, "no user exists";
};
@@ -229,7 +243,7 @@ subtest "check logging in with token" => sub {
$mech->log_out_ok;
$mech->not_logged_in_ok;
- my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
# token needs to be 18 characters
$user->set_extra_metadata('access_token', '1234567890abcdefgh');
$user->update();
@@ -281,6 +295,7 @@ subtest 'test forgotten password page' => sub {
fields => { username => $test_email, password_register => 'squirblewirble' },
button => 'sign_in_by_code',
});
+ $mech->clear_emails_ok;
};
subtest "Test two-factor authentication login" => sub {
@@ -289,8 +304,7 @@ subtest "Test two-factor authentication login" => sub {
my $code = $auth->code;
my $wrong_code = $auth->code(undef, time() - 120);
- my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
- $user->is_superuser(1);
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
$user->password('password');
$user->set_extra_metadata('2fa_secret', $auth->secret32);
$user->update;
@@ -305,3 +319,138 @@ subtest "Test two-factor authentication login" => sub {
$mech->submit_form_ok({ with_fields => { '2fa_code' => $code } }, "provide correct 2FA code" );
$mech->logged_in_ok;
};
+
+subtest "Test enforced two-factor authentication" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'dummy',
+ }, sub {
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
+ $user->unset_extra_metadata('2fa_secret');
+ $user->update;
+
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok(
+ { with_fields => { username => $test_email, password_sign_in => 'password' } },
+ "sign in using form" );
+
+ $mech->content_contains('requires two-factor');
+ $mech->submit_form_ok({ with_fields => { '2fa_action' => 'activate' } }, "submit 2FA activation");
+ my ($token) = $mech->content =~ /name="secret32" value="([^"]*)">/;
+
+ use Auth::GoogleAuth;
+ my $auth = Auth::GoogleAuth->new({ secret32 => $token });
+ my $code = $auth->code;
+ my $wrong_code = $auth->code(undef, time() - 120);
+
+ $mech->submit_form_ok({ with_fields => { '2fa_code' => $wrong_code } }, "provide wrong 2FA code" );
+ $mech->content_contains('Try again');
+ $mech->submit_form_ok({ with_fields => { '2fa_code' => $code } }, "provide correct 2FA code" );
+ $mech->content_contains('successfully enabled two-factor authentication', "2FA activated");
+
+ $user->discard_changes();
+ my $user_token = $user->get_extra_metadata('2fa_secret');
+ is $token, $user_token, '2FA secret set';
+
+ $mech->logged_in_ok;
+
+ $user->name('skip');
+ $user->update;
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok(
+ { with_fields => { username => $test_email, password_sign_in => 'password' } },
+ "sign in using form" );
+ $mech->content_contains('<h1>Your account');
+ };
+};
+
+subtest "Test enforced two-factor authentication, no password yet set" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'dummy',
+ }, sub {
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
+ $user->unset_extra_metadata('2fa_secret');
+ $user->name('Test User');
+ $user->update;
+
+ $mech->clear_emails_ok;
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok({
+ fields => { username => $test_email, password_register => $test_password },
+ button => 'sign_in_by_code',
+ }, "log in by email");
+
+ my $link = $mech->get_link_from_email;
+ $mech->get_ok($link);
+
+ $mech->content_contains('requires two-factor');
+ $mech->submit_form_ok({ with_fields => { '2fa_action' => 'activate' } }, "submit 2fa activation");
+ my ($token) = $mech->content =~ /name="secret32" value="([^"]*)">/;
+
+ my $auth = Auth::GoogleAuth->new({ secret32 => $token });
+ my $code = $auth->code;
+ $mech->submit_form_ok({ with_fields => { '2fa_code' => $code } }, "provide correct 2fa code" );
+
+ $user->discard_changes();
+ my $user_token = $user->get_extra_metadata('2fa_secret');
+ is $token, $user_token, '2FA secret set';
+
+ $mech->logged_in_ok;
+
+ $mech->get_ok($link);
+ $mech->content_contains('Please generate a two-factor code');
+ $mech->submit_form_ok({ with_fields => { '2fa_code' => $code } }, "provide correct 2FA code" );
+ $mech->content_lacks('requires two-factor');
+
+ $user->name('skip');
+ $user->update;
+ $mech->get_ok($link);
+ $mech->content_contains('Your account');
+ };
+};
+
+subtest "Check two-factor log in by email works" => sub {
+ use Auth::GoogleAuth;
+ my $auth = Auth::GoogleAuth->new;
+ my $code = $auth->code;
+
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
+ $user->set_extra_metadata('2fa_secret', $auth->secret32);
+ $user->update;
+
+ $mech->clear_emails_ok;
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok({
+ fields => { username => $test_email, password_register => $test_password },
+ button => 'sign_in_by_code',
+ }, "log in by email");
+
+ my $link = $mech->get_link_from_email;
+ $mech->get_ok($link);
+ $mech->content_contains('Please generate a two-factor code');
+ $mech->submit_form_ok({ with_fields => { '2fa_code' => $code } }, "provide correct 2FA code" );
+ $mech->logged_in_ok;
+};
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'expiring'
+}, sub {
+ subtest 'Password expiry' => sub {
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
+ $user->set_extra_metadata('last_password_change', time() - 200000);
+ $user->unset_extra_metadata('2fa_secret');
+ $user->update;
+
+ $mech->get_ok('/');
+ $mech->content_contains('Password expired');
+ $mech->submit_form_ok(
+ { with_fields => { password_register => 'new-password' } },
+ "fill in reset form" );
+
+ my $link = $mech->get_link_from_email;
+ $mech->clear_emails_ok;
+ $mech->get_ok($link);
+ $mech->logged_in_ok;
+ };
+};
+
+done_testing();
diff --git a/t/app/controller/auth_phone.t b/t/app/controller/auth_phone.t
index dea1c3493..e5f49ed19 100644
--- a/t/app/controller/auth_phone.t
+++ b/t/app/controller/auth_phone.t
@@ -60,7 +60,7 @@ FixMyStreet::override_config {
with_fields => { code => $code }
}, 'submit correct code');
- my $user = FixMyStreet::App->model('DB::User')->find( { phone => '+18165550100' } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { phone => '+18165550100' } );
ok $user, "user created";
is $mech->uri->path, '/my', "redirected to the 'my' section of site";
$mech->logged_in_ok;
diff --git a/t/app/controller/auth_profile.t b/t/app/controller/auth_profile.t
index 4be1be12c..e5dfe2764 100644
--- a/t/app/controller/auth_profile.t
+++ b/t/app/controller/auth_profile.t
@@ -1,6 +1,17 @@
+package FixMyStreet::Cobrand::Dummy;
+use parent 'FixMyStreet::Cobrand::Default';
+
+sub must_have_2fa { 1 }
+
+package main;
+
+use Test::MockModule;
use FixMyStreet::TestMech;
my $mech = FixMyStreet::TestMech->new;
+my $resolver = Test::MockModule->new('Email::Valid');
+$resolver->mock('address', sub { $_[1] });
+
use t::Mock::Twilio;
my $twilio = t::Mock::Twilio->new;
@@ -10,10 +21,6 @@ my $test_email = 'test@example.com';
my $test_email2 = 'test@example.net';
my $test_password = 'foobar123';
-END {
- done_testing();
-}
-
# get a sign in email and change password
subtest "Test change password page" => sub {
$mech->clear_emails_ok;
@@ -66,7 +73,7 @@ subtest "Test change password page" => sub {
$mech->content_contains( $test->{err}, "found expected error" );
}
- my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
ok $user, "got a user";
ok !$user->password, "user has no password";
@@ -126,7 +133,7 @@ subtest "Test change password page with current password" => sub {
$mech->content_contains( $test->{err}, "found expected error" );
}
- my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
ok $user, "got a user";
$mech->get_ok('/auth/change_password');
@@ -179,12 +186,12 @@ subtest "Test change email page" => sub {
$mech->get_ok($link);
is $mech->uri->path, '/my', "redirected to /my page";
$mech->content_contains('successfully confirmed');
- ok(FixMyStreet::App->model('DB::User')->find( { email => $test_email2 } ), "got a user");
+ ok(FixMyStreet::DB->resultset('User')->find( { email => $test_email2 } ), "got a user");
my $p = FixMyStreet::DB->resultset("Problem")->first;
is $p->user->email, $test_email2, 'problem user updated';
- my $user1 = FixMyStreet::App->model('DB::User')->create( { email => $test_email, email_verified => 1 } );
+ my $user1 = FixMyStreet::DB->resultset('User')->create( { email => $test_email, email_verified => 1 } );
ok($user1, "created old user");
$mech->create_problems_for_body(1, 2514, 'Title1', { user => $user1 } );
@@ -222,7 +229,7 @@ my $test_landline = '01214960000';
my $test_mobile = '+61491570156';
my $test_mobile2 = '+61491570157';
-my $user_mob2 = FixMyStreet::App->model('DB::User')->create( {
+my $user_mob2 = FixMyStreet::DB->resultset('User')->create( {
phone => $test_mobile,
phone_verified => 1,
name => 'Aus Mobile user',
@@ -284,7 +291,7 @@ subtest "Test add/verify/change phone page" => sub {
with_fields => { code => $code }
}, 'submit correct code');
- my $user = FixMyStreet::App->model('DB::User')->find( { phone => $test_mobile } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { phone => $test_mobile } );
ok $user, "user exists";
is $user->email_verified, 1;
is $user->email, $test_email, 'email still same';
@@ -320,9 +327,9 @@ subtest "Test change phone to existing account" => sub {
my $code = $twilio->get_text_code;
$mech->submit_form_ok({ with_fields => { code => $code } }, 'submit correct code');
- my $user = FixMyStreet::App->model('DB::User')->find( { phone => $test_mobile } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { phone => $test_mobile } );
ok !$user, 'old user does not exist';
- $user = FixMyStreet::App->model('DB::User')->find( { phone => $test_mobile2 } );
+ $user = FixMyStreet::DB->resultset('User')->find( { phone => $test_mobile2 } );
ok $user, "new mobile user exists";
is $user->email_verified, 1;
is $user->email, $test_email, 'email still same';
@@ -335,7 +342,7 @@ subtest "Test change phone to existing account" => sub {
};
subtest "Test superuser can access generate token page" => sub {
- my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
ok $user->update({ is_superuser => 0 }), 'user not superuser';
$mech->log_out_ok;
@@ -359,8 +366,10 @@ subtest "Test superuser can access generate token page" => sub {
$mech->get_ok('/auth/generate_token');
};
+my $body = $mech->create_body_ok(2237, 'Oxfordshire');
+
subtest "Test staff user can access generate token page" => sub {
- my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
ok $user->update({ is_superuser => 0 }), 'user not superuser';
$mech->log_out_ok;
@@ -374,8 +383,6 @@ subtest "Test staff user can access generate token page" => sub {
$mech->content_lacks('Security');
- my $body = $mech->create_body_ok(2237, 'Oxfordshire');
-
$mech->get('/auth/generate_token');
is $mech->res->code, 403, "access denied";
@@ -387,7 +394,7 @@ subtest "Test staff user can access generate token page" => sub {
};
subtest "Test generate token page" => sub {
- my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
ok $user->update({ is_superuser => 1 }), 'user set to superuser';
$mech->log_out_ok;
@@ -425,28 +432,80 @@ subtest "Test generate token page" => sub {
$mech->log_out_ok;
$mech->add_header('Authorization', "Bearer $token");
$mech->logged_in_ok;
+ $mech->delete_header('Authorization');
};
subtest "Test two-factor authentication admin" => sub {
- my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
- ok $user->update({ is_superuser => 1 }), 'user set to superuser';
+ for (0, 1) {
+ my $user = $mech->log_in_ok($test_email);
+ if ($_) {
+ ok $user->update({ is_superuser => 1, from_body => undef }), 'user set to superuser';
+ } else {
+ ok $user->update({ is_superuser => 0, from_body => $body }), 'user set to staff user';
+ }
- $mech->log_in_ok($test_email);
$mech->get_ok('/auth/generate_token');
ok !$user->get_extra_metadata('2fa_secret');
- $mech->submit_form_ok({ button => 'toggle_2fa' }, "submit 2FA activation");
+ $mech->submit_form_ok({ button => '2fa_activate' }, "submit 2FA activation");
+ my ($token) = $mech->content =~ /name="secret32" value="([^"]*)">/;
+
+ use Auth::GoogleAuth;
+ my $auth = Auth::GoogleAuth->new({ secret32 => $token });
+ my $code = $auth->code;
+ my $wrong_code = $auth->code(undef, time() - 120);
+
+ $mech->submit_form_ok({ with_fields => { '2fa_code' => $wrong_code } }, "provide wrong 2FA code" );
+ $mech->content_contains('Try again');
+ $mech->submit_form_ok({ with_fields => { '2fa_code' => $code } }, "provide correct 2FA code" );
+
$mech->content_contains('has been activated', "2FA activated");
$user->discard_changes();
- my $token = $user->get_extra_metadata('2fa_secret');
- ok $token, '2FA secret set';
-
- $mech->content_contains($token, 'secret displayed');
+ my $user_token = $user->get_extra_metadata('2fa_secret');
+ is $token, $user_token, '2FA secret set';
$mech->get_ok('/auth/generate_token');
$mech->content_lacks($token, 'secret no longer displayed');
- $mech->submit_form_ok({ button => 'toggle_2fa' }, "submit 2FA deactivation");
+ $mech->submit_form_ok({ button => '2fa_deactivate' }, "submit 2FA deactivation");
$mech->content_contains('has been deactivated', "2FA deactivated");
+ }
};
+
+subtest "Test enforced two-factor authentication" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'dummy',
+ }, sub {
+ use Auth::GoogleAuth;
+ my $auth = Auth::GoogleAuth->new;
+ my $code = $auth->code;
+
+ # Sign in with 2FA
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
+ $user->password('password');
+ $user->set_extra_metadata('2fa_secret', $auth->secret32);
+ $user->update;
+
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok(
+ { with_fields => { username => $test_email, password_sign_in => 'password' } },
+ "sign in using form" );
+ $mech->content_contains('Please generate a two-factor code');
+ $mech->submit_form_ok({ with_fields => { '2fa_code' => $code } }, "provide correct 2FA code" );
+
+ $mech->get_ok('/auth/generate_token');
+ $mech->content_contains('Change two-factor');
+ $mech->content_lacks('Deactivate two-factor');
+
+ my ($csrf) = $mech->content =~ /meta content="([^"]*)" name="csrf-token"/;
+ $mech->post_ok('/auth/generate_token', {
+ '2fa_deactivate' => 1,
+ 'token' => $csrf,
+ });
+ $mech->content_lacks('has been deactivated', "2FA not deactivated");
+ $mech->content_contains('Please scan this image', 'Change 2FA page shown instead');
+ };
+};
+
+done_testing();
diff --git a/t/app/controller/auth_social.t b/t/app/controller/auth_social.t
index ac3d98b15..200863029 100644
--- a/t/app/controller/auth_social.t
+++ b/t/app/controller/auth_social.t
@@ -5,54 +5,133 @@ use JSON::MaybeXS;
use t::Mock::Facebook;
use t::Mock::Twitter;
+use t::Mock::OpenIDConnect;
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');
+my $body = $mech->create_body_ok(2504, 'Westminster City Council');
-FixMyStreet::override_config {
- FACEBOOK_APP_ID => 'facebook-app-id',
- TWITTER_KEY => 'twitter-key',
- ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
- MAPIT_URL => 'http://mapit.uk/',
-}, sub {
+my ($report) = $mech->create_problems_for_body(1, $body->id, 'My Test Report');
+my $test_email = $report->user->email;
-my $fb_email = 'facebook@example.org';
-my $fb_uid = 123456789;
+my $contact = $mech->create_contact_ok(
+ body_id => $body->id, category => 'Damaged bin', email => 'BIN',
+ extra => [
+ { code => 'bin_type', description => 'Type of bin', required => 'True' },
+ { code => 'bin_service', description => 'Service needed', required => 'False' },
+ ]
+);
+# Two options, incidentally, so that the template "Only one option, select it"
+# code doesn't kick in and make the tests pass
+my $contact2 = $mech->create_contact_ok(
+ body_id => $body->id, category => 'Whatever', email => 'WHATEVER',
+);
my $resolver = Test::MockModule->new('Email::Valid');
-$resolver->mock('address', sub { 'facebook@example.org' });
+my $social = Test::MockModule->new('FixMyStreet::App::Controller::Auth::Social');
+$social->mock('generate_nonce', sub { 'MyAwesomeRandomValue' });
+
+for my $test (
+ {
+ type => 'facebook',
+ config => {
+ FACEBOOK_APP_ID => 'facebook-app-id',
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ },
+ update => 1,
+ email => $mech->uniquify_email('facebook@example.org'),
+ uid => 123456789,
+ mock => 't::Mock::Facebook',
+ mock_hosts => ['www.facebook.com', 'graph.facebook.com'],
+ host => 'www.facebook.com',
+ error_callback => '/auth/Facebook?error_code=ERROR',
+ success_callback => '/auth/Facebook?code=response-code',
+ redirect_pattern => qr{facebook\.com.*dialog/oauth.*facebook-app-id},
+}, {
+ type => 'oidc',
+ config => {
+ ALLOWED_COBRANDS => 'westminster',
+ MAPIT_URL => 'http://mapit.uk/',
+ COBRAND_FEATURES => {
+ anonymous_account => {
+ westminster => 'test',
+ },
+ oidc_login => {
+ westminster => {
+ client_id => 'example_client_id',
+ secret => 'example_secret_key',
+ auth_uri => 'http://oidc.example.org/oauth2/v2.0/authorize',
+ token_uri => 'http://oidc.example.org/oauth2/v2.0/token',
+ logout_uri => 'http://oidc.example.org/oauth2/v2.0/logout',
+ password_change_uri => 'http://oidc.example.org/oauth2/v2.0/password_change',
+ display_name => 'MyWestminster'
+ }
+ }
+ }
+ },
+ email => $mech->uniquify_email('oidc@example.org'),
+ uid => "westminster:example_client_id:my_cool_user_id",
+ mock => 't::Mock::OpenIDConnect',
+ mock_hosts => ['oidc.example.org'],
+ host => 'oidc.example.org',
+ error_callback => '/auth/OIDC?error=ERROR',
+ success_callback => '/auth/OIDC?code=response-code&state=login',
+ redirect_pattern => qr{oidc\.example\.org/oauth2/v2\.0/authorize},
+ logout_redirect_pattern => qr{oidc\.example\.org/oauth2/v2\.0/logout},
+ password_change_pattern => qr{oidc\.example\.org/oauth2/v2\.0/password_change},
+ user_extras => [
+ [westminster_account_id => "1c304134-ef12-c128-9212-123908123901"],
+ ],
+}
+) {
+
+FixMyStreet::override_config $test->{config}, sub {
-for my $fb_state ( 'refused', 'no email', 'existing UID', 'okay' ) {
+$resolver->mock('address', sub { $test->{email} });
+
+for my $state ( 'refused', 'no email', 'existing UID', 'okay' ) {
for my $page ( 'my', 'report', 'update' ) {
- subtest "test FB '$fb_state' login for page '$page'" => sub {
+ next if $page eq 'update' && !$test->{update};
+
+ subtest "test $test->{type} '$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 });
+ if ($state eq 'existing UID') {
+ my $user = $mech->create_user_ok($test->{email});
+ if ($test->{type} eq 'facebook') {
+ $user->update({ facebook_id => $test->{uid} });
+ } elsif ($test->{type} eq 'oidc') {
+ $user->update({ oidc_ids => [ $test->{uid} ] });
+ }
+ } else {
+ $mech->delete_user($test->{email});
+ }
+ if ($page eq 'my' && $state eq 'existing UID') {
+ $report->update({ user_id => FixMyStreet::DB->resultset( 'User' )->find( { email => $test->{email} } )->id });
} else {
- $mech->delete_user($fb_email);
+ $report->update({ user_id => FixMyStreet::DB->resultset( 'User' )->find( { email => $test_email } )->id });
}
- # 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');
+ # Set up a mock to catch (most, see below) requests to the OAuth API
+ my $mock_api = $test->{mock}->new;
+ $mock_api->returns_email(0) if $state eq 'no email' || $state eq 'existing UID';
+ for my $host (@{ $test->{mock_hosts} }) {
+ LWP::Protocol::PSGI->register($mock_api->to_psgi_app, host => $host);
+ }
# 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
+ # the redirect to the OAuth page can mess up the session
+ # cookie. So let's pretend we're always on the API host, which
# sorts that out.
- $mech->host('www.facebook.com');
+ $mech->host($test->{host});
# Fetch the page with the form via which we wish to log in
my $fields;
@@ -62,9 +141,13 @@ for my $fb_state ( 'refused', 'no email', 'existing UID', 'okay' ) {
$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 = {
+ $mech->submit_form(with_fields => {
+ category => 'Damaged bin',
title => 'Test title',
detail => 'Test detail',
+ });
+ $fields = {
+ bin_type => 'Salt bin',
};
} else {
$mech->get_ok('/report/' . $report->id);
@@ -72,37 +155,41 @@ for my $fb_state ( 'refused', 'no email', 'existing UID', 'okay' ) {
update => 'Test update',
};
}
- $mech->submit_form(with_fields => $fields, button => 'facebook_sign_in');
+ $mech->submit_form(with_fields => $fields, button => 'social_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');
+ is $mech->res->previous->code, 302, "$test->{type} button redirected";
+ like $mech->res->previous->header('Location'), $test->{redirect_pattern}, "$test->{type} redirect to oauth URL";
+
+ # Okay, now call the callback we'd be sent to
+ # NB: for OIDC these should be post_ok, but that doesn't work because
+ # the session cookie doesn't seem to be included (related to the
+ # cookie issue above perhaps).
+ if ($state eq 'refused') {
+ $mech->get_ok($test->{error_callback});
} else {
- $mech->get_ok('/auth/Facebook?code=response-code');
+ $mech->get_ok($test->{success_callback});
}
# Check we're showing the right form, regardless of what came back
if ($page eq 'report') {
$mech->content_contains('/report/new');
+ $mech->content_contains('Salt bin');
} 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.');
+ if ($state eq 'refused') {
+ $mech->content_contains('Sorry, we could not log you in.');
$mech->not_logged_in_ok;
- } elsif ($fb_state eq 'no email') {
+ } elsif ($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
- $fields->{username} = $fb_email;
+ $fields->{username} = $test->{email};
$fields->{name} = 'Ffion Tester' unless $page eq 'my';
$mech->submit_form(with_fields => $fields, $page eq 'my' ? (button => 'sign_in_by_code') : ());
$mech->content_contains('Nearly done! Now check your email');
@@ -111,32 +198,86 @@ for my $fb_state ( 'refused', 'no email', 'existing UID', 'okay' ) {
$mech->clear_emails_ok;
ok $url, "extracted confirm url '$url'";
- my $user = FixMyStreet::App->model( 'DB::User' )->find( { email => $fb_email } );
+ my $user = FixMyStreet::DB->resultset( 'User' )->find( { email => $test->{email} } );
if ($page eq 'my') {
is $user, undef, 'No user yet exists';
} else {
- is $user->facebook_id, undef, 'User has no facebook ID';
+ if ($test->{type} eq 'facebook') {
+ is $user->facebook_id, undef, 'User has no facebook ID';
+ } elsif ($test->{type} eq 'oidc') {
+ is $user->oidc_ids, undef, 'User has no OIDC IDs';
+ }
}
$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';
+ $user = FixMyStreet::DB->resultset( 'User' )->find( { email => $test->{email} } );
+ if ($test->{type} eq 'facebook') {
+ is $user->facebook_id, $test->{uid}, 'User now has correct facebook ID';
+ } elsif ($test->{type} eq 'oidc') {
+ is_deeply $user->oidc_ids, [ $test->{uid} ], 'User now has correct OIDC IDs';
+ }
+ if ($test->{user_extras}) {
+ for my $extra (@{ $test->{user_extras} }) {
+ my ($k, $v) = @$extra;
+ is $user->get_extra_metadata($k), $v, "User has correct $k extra field";
+ }
+ }
} 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;
+ if ($test->{user_extras}) {
+ my $user = FixMyStreet::DB->resultset( 'User' )->find( { email => $test->{email} } );
+ for my $extra (@{ $test->{user_extras} }) {
+ my ($k, $v) = @$extra;
+ is $user->get_extra_metadata($k), $v, "User has correct $k extra field";
+ }
+ }
} else {
is $mech->uri->path, '/my', 'Successfully on /my page';
+ if ($test->{user_extras}) {
+ my $user = FixMyStreet::DB->resultset( 'User' )->find( { email => $test->{email} } );
+ for my $extra (@{ $test->{user_extras} }) {
+ my ($k, $v) = @$extra;
+ is $user->get_extra_metadata($k), $v, "User has correct $k extra field";
+ }
+ }
+ if ($state eq 'existing UID') {
+ my $report_id = $report->id;
+ $mech->content_contains( $report->title );
+ $mech->content_contains( "/report/$report_id" );
+ }
+ if ($test->{type} eq 'oidc') {
+ ok $mech->find_link( text => 'Change password', url_regex => $test->{password_change_pattern} );
+ }
}
+
+ $mech->get('/auth/sign_out');
+ if ($test->{type} eq 'oidc' && $state ne 'refused' && $state ne 'no email') {
+ # XXX the 'no email' situation is skipped because of some confusion
+ # with the hosts/sessions that I've not been able to get to the bottom of.
+ # The code does behave as expected when testing manually, however.
+ is $mech->res->previous->code, 302, "$test->{type} sign out redirected";
+ like $mech->res->previous->header('Location'), $test->{logout_redirect_pattern}, "$test->{type} sign out redirect to oauth logout URL";
+ }
+ $mech->not_logged_in_ok;
}
}
}
+}
+};
-$resolver->mock('address', sub { 'twitter@example.org' });
+FixMyStreet::override_config {
+ TWITTER_KEY => 'twitter-key',
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
-my $tw_email = 'twitter@example.org';
+my $tw_email = $mech->uniquify_email('twitter@example.org');
my $tw_uid = 987654321;
+$resolver->mock('address', sub { $tw_email });
+
# 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' ) {
@@ -170,9 +311,13 @@ for my $tw_state ( 'refused', 'existing UID', 'no email' ) {
$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 = {
+ $mech->submit_form(with_fields => {
+ category => 'Damaged bin',
title => 'Test title',
detail => 'Test detail',
+ });
+ $fields = {
+ bin_type => 'Salt bin',
};
} else {
$mech->get_ok('/report/' . $report->id);
@@ -180,7 +325,7 @@ for my $tw_state ( 'refused', 'existing UID', 'no email' ) {
update => 'Test update',
};
}
- $mech->submit_form(with_fields => $fields, button => 'twitter_sign_in');
+ $mech->submit_form(with_fields => $fields, button => 'social_sign_in');
# As well as the cookie issue above, caused by this external
# redirect rewriting the host, the redirect gets handled directly
@@ -199,6 +344,7 @@ for my $tw_state ( 'refused', 'existing UID', 'no email' ) {
# Check we're showing the right form, regardless of what came back
if ($page eq 'report') {
$mech->content_contains('/report/new');
+ $mech->content_contains('Salt bin');
} elsif ($page eq 'update') {
$mech->content_contains('/report/update');
}
@@ -219,14 +365,14 @@ for my $tw_state ( 'refused', 'existing UID', 'no email' ) {
$mech->clear_emails_ok;
ok $url, "extracted confirm url '$url'";
- my $user = FixMyStreet::App->model( 'DB::User' )->find( { email => $tw_email } );
+ my $user = FixMyStreet::DB->resultset( '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 } );
+ $user = FixMyStreet::DB->resultset( 'User' )->find( { email => $tw_email } );
is $user->twitter_id, $tw_uid, 'User now has correct twitter ID';
} elsif ($page ne 'my') {
@@ -242,6 +388,4 @@ for my $tw_state ( 'refused', 'existing UID', 'no email' ) {
};
-END {
- done_testing();
-}
+done_testing();
diff --git a/t/app/controller/contact.t b/t/app/controller/contact.t
index 842f27dd5..d6e56e7cc 100644
--- a/t/app/controller/contact.t
+++ b/t/app/controller/contact.t
@@ -6,6 +6,16 @@ sub abuse_reports_only { 1; }
1;
+package FixMyStreet::Cobrand::GeneralEnquiries;
+
+use base 'FixMyStreet::Cobrand::Default';
+
+sub abuse_reports_only { 1 }
+
+sub setup_general_enquiries_stash { 1 }
+
+1;
+
package main;
use FixMyStreet::TestMech;
@@ -104,7 +114,7 @@ for my $test (
subtest 'check reporting a problem displays correctly' => sub {
my $user = $mech->create_user_ok($test->{email}, name => $test->{name});
- my $problem = FixMyStreet::App->model('DB::Problem')->create(
+ my $problem = FixMyStreet::DB->resultset('Problem')->create(
{
title => $test->{title},
detail => $test->{detail},
@@ -128,7 +138,7 @@ for my $test (
my $update_user = $mech->create_user_ok($update_info->{email},
name => $update_info->{name});
- $update = FixMyStreet::App->model('DB::Comment')->create(
+ $update = FixMyStreet::DB->resultset('Comment')->create(
{
problem_id => $update_info->{other_problem} ? $problem_main->id : $problem->id,
user => $update_user,
@@ -327,6 +337,71 @@ for my $test (
}
for my $test (
+ { fields => \%common }
+ )
+{
+ subtest 'check email contains user details' => sub {
+ my $user = $mech->create_user_ok(
+ $test->{fields}->{em},
+ name => $test->{fields}->{name}
+ );
+
+ my $older_unhidden_problem = FixMyStreet::DB->resultset('Problem')->create(
+ {
+ title => 'Some problem or other',
+ detail => 'More detail on the problem',
+ postcode => 'EH99 1SP',
+ confirmed => '2011-05-04 10:44:28.145168',
+ anonymous => 0,
+ name => $test->{fields}->{name},
+ state => 'confirmed',
+ user => $user,
+ latitude => 0,
+ longitude => 0,
+ areas => 0,
+ used_map => 0,
+ }
+ );
+
+ my $newer_hidden_problem = FixMyStreet::DB->resultset('Problem')->create(
+ {
+ title => 'A hidden problem',
+ detail => 'Shhhh secret',
+ postcode => 'EH99 1SP',
+ confirmed => '2012-06-05 10:44:28.145168',
+ anonymous => 0,
+ name => $test->{fields}->{name},
+ state => 'hidden',
+ user => $user,
+ latitude => 0,
+ longitude => 0,
+ areas => 0,
+ used_map => 0,
+ }
+ );
+
+ $mech->clear_emails_ok;
+ $mech->get_ok('/contact');
+ $test->{fields}{em} = $user->email;
+ $mech->submit_form_ok( { with_fields => $test->{fields} } );
+
+ my $email = $mech->get_email;
+ my $body = $mech->get_text_body_from_email($email);
+
+ my $user_id = $user->id;
+ my $user_email = $user->email;
+ my $older_unhidden_problem_id = $older_unhidden_problem->id;
+ my $newer_hidden_problem_id = $newer_hidden_problem->id;
+
+ like $body, qr/admin\/users\/$user_id/, 'email contains admin link to edit user';
+ like $body, qr/admin\/reports\?search=$user_email/, 'email contains admin link to show users reports';
+ like $body, qr/admin\/report_edit\/$older_unhidden_problem_id/, 'email contains admin link for users latest unhidden report';
+ unlike $body, qr/admin\/report_edit\/$newer_hidden_problem_id/, 'email does not link to hidden reports';
+
+ };
+}
+
+for my $test (
{
fields => { %common, dest => undef },
page_errors =>
@@ -482,7 +557,28 @@ subtest 'check can limit contact to abuse reports' => sub {
is $mech->res->code, 404, 'cannot visit contact page';
$mech->get_ok( '/contact?id=' . $problem_main->id, 'can visit for abuse report' );
- my $token = FixMyStreet::App->model("DB::Token")->create({
+ my $token = FixMyStreet::DB->resultset("Token")->create({
+ scope => 'moderation',
+ data => { id => $problem_main->id }
+ });
+
+ $mech->get_ok( '/contact?m=' . $token->token, 'can visit for moderation complaint' );
+
+ }
+};
+
+subtest 'check redirected to correct form for general enquiries cobrand' => sub {
+ FixMyStreet::override_config {
+ 'ALLOWED_COBRANDS' => [ 'generalenquiries' ],
+ }, sub {
+ $mech->get( '/contact' );
+ is $mech->res->code, 200, "got 200 for final destination";
+ is $mech->res->previous->code, 302, "got 302 for redirect";
+ is $mech->uri->path, '/contact/enquiry';
+
+ $mech->get_ok( '/contact?id=' . $problem_main->id, 'can visit for abuse report' );
+
+ my $token = FixMyStreet::DB->resultset("Token")->create({
scope => 'moderation',
data => { id => $problem_main->id }
});
diff --git a/t/app/controller/contact_enquiry.t b/t/app/controller/contact_enquiry.t
new file mode 100644
index 000000000..af249ec6c
--- /dev/null
+++ b/t/app/controller/contact_enquiry.t
@@ -0,0 +1,267 @@
+use utf8;
+use Encode;
+use FixMyStreet::TestMech;
+use Path::Tiny;
+use File::Temp 'tempdir';
+use FixMyStreet::Script::Reports;
+use Test::MockModule;
+
+# 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( 2483, 'Hounslow Borough Council', {
+ send_method => 'Open311',
+ endpoint => 'endpoint',
+ api_key => 'key',
+ jurisdiction => 'hounslow',
+});
+my $contact = $mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'General Enquiry',
+ email => 'genenq@example.com',
+ non_public => 1,
+);
+my $contact2 = $mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'FOI Request',
+ email => 'foi@example.com',
+ non_public => 1,
+);
+my $contact3 = $mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'Other',
+ email => 'other@example.com',
+);
+my $contact4 = $mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'Carriageway Defect',
+ email => 'potholes@example.com',
+);
+$contact->update( { extra => { group => 'General Enquiries' } } );
+$contact2->update( { extra => { group => 'General Enquiries' } } );
+$contact3->update( { extra => { group => 'Other' } } );
+
+FixMyStreet::override_config { ALLOWED_COBRANDS => ['bromley'], }, sub {
+ subtest 'redirected to / if general enquiries not enabled' => sub {
+ $mech->get( '/contact/enquiry' );
+ is $mech->res->code, 200, "got 200 for final destination";
+ is $mech->res->previous->code, 302, "got 302 for redirect";
+ is $mech->uri->path, '/';
+ };
+};
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => ['hounslow'],
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ subtest 'Non-general enquiries category not shown' => sub {
+ $mech->get_ok( '/contact/enquiry' );
+ $mech->content_lacks('Carriageway Defect');
+ $mech->content_contains('FOI Request');
+ };
+
+ subtest 'Enquiry can be submitted when logged out' => sub {
+ my $problems = FixMyStreet::DB->resultset('Problem')->to_body( $body->id );
+
+ $mech->get_ok( '/contact/enquiry' );
+ $mech->submit_form_ok( {
+ with_fields => {
+ name => 'Test User',
+ username => 'testuser@example.org',
+ category => 'Other',
+ detail => 'This is a general enquiry',
+ }
+ } );
+ is $mech->uri->path, '/contact/enquiry/submit';
+ $mech->content_contains("Thank you for your enquiry");
+
+ is $problems->count, 1, 'problem created';
+ my $problem = $problems->first;
+ is $problem->category, 'Other', 'problem has correct category';
+ is $problem->detail, 'This is a general enquiry', 'problem has correct detail';
+ is $problem->non_public, 1, 'problem created non_public';
+ is $problem->postcode, '';
+ is $problem->used_map, 0;
+ is $problem->latitude, 51.469, 'Problem has correct latitude';
+ is $problem->longitude, -0.35, 'Problem has correct longitude';
+ ok $problem->confirmed, 'problem confirmed';
+ is $problem->user->name, undef, 'User created without name';
+ is $problem->name, 'Test User', 'Report created with correct name';
+ is $problem->user->email, 'testuser@example.org', 'User created with correct email';
+ };
+
+ subtest 'Enquiry can be submitted when logged in' => sub {
+ my $problems = FixMyStreet::DB->resultset('Problem')->to_body( $body->id );
+ my $prob_user = $problems->first->user;
+ $problems->delete_all;
+
+ my $user = $mech->log_in_ok( $prob_user->email );
+
+ $mech->get_ok( '/contact/enquiry' );
+ $mech->submit_form_ok( {
+ with_fields => {
+ name => 'Test User',
+ category => 'FOI Request',
+ detail => 'This is a general enquiry',
+ }
+ } );
+ is $mech->uri->path, '/contact/enquiry/submit';
+ $mech->content_contains("Thank you for your enquiry");
+
+ is $problems->count, 1, 'problem created';
+ my $problem = $problems->first;
+ is $problem->category, 'FOI Request', 'problem has correct category';
+ is $problem->detail, 'This is a general enquiry', 'problem has correct detail';
+ is $problem->non_public, 1, 'problem created non_public';
+ is $problem->postcode, '';
+ is $problem->used_map, 0;
+ is $problem->latitude, 51.469, 'Problem has correct latitude';
+ is $problem->longitude, -0.35, 'Problem has correct longitude';
+ ok $problem->confirmed, 'problem confirmed';
+ is $problem->name, 'Test User', 'Report created with correct name';
+ is $problem->user->name, 'Test User', 'User name updated in DB';
+ is $problem->user->email, $user->email, 'Report user has correct email';
+
+ $mech->log_out_ok;
+ };
+
+ subtest 'User name not changed if logged out when making report' => sub {
+ my $problems = FixMyStreet::DB->resultset('Problem')->to_body( $body->id );
+ my $user = $problems->first->user;
+ $problems->delete_all;
+
+ is $user->name, 'Test User', 'User has correct name';
+
+ $mech->get_ok( '/contact/enquiry' );
+ $mech->submit_form_ok( {
+ with_fields => {
+ name => 'Simon Neil',
+ username => $user->email,
+ category => 'General Enquiry',
+ detail => 'This is a general enquiry',
+ }
+ } );
+ is $mech->uri->path, '/contact/enquiry/submit';
+ $mech->content_contains("Thank you for your enquiry");
+
+ is $problems->count, 1, 'problem created';
+ my $problem = $problems->first;
+ is $problem->category, 'General Enquiry', 'problem has correct category';
+ is $problem->detail, 'This is a general enquiry', 'problem has correct detail';
+ is $problem->non_public, 1, 'problem created non_public';
+ is $problem->postcode, '';
+ is $problem->used_map, 0;
+ is $problem->latitude, 51.469, 'Problem has correct latitude';
+ is $problem->longitude, -0.35, 'Problem has correct longitude';
+ ok $problem->confirmed, 'problem confirmed';
+ is $problem->name, 'Simon Neil', 'Report created with correct name';
+ is $problem->user->email, $user->email, 'Report user has correct email';
+ $user->discard_changes;
+ is $user->name, 'Test User', 'User name in DB not changed';
+
+ $mech->log_out_ok;
+ };
+
+};
+
+my $sample_jpeg = path(__FILE__)->parent->child("sample.jpg");
+ok $sample_jpeg->exists, "sample image $sample_jpeg exists";
+my $sample_pdf = path(__FILE__)->parent->child("sample.pdf");
+ok $sample_pdf->exists, "sample PDF $sample_pdf exists";
+
+my $UPLOAD_DIR = tempdir( CLEANUP => 1 );
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ 'hounslow' ],
+ STAGING_FLAGS => { send_reports => 1 },
+ MAPIT_URL => 'http://mapit.uk/',
+ PHOTO_STORAGE_BACKEND => 'FileSystem',
+ PHOTO_STORAGE_OPTIONS => {
+ UPLOAD_DIR => $UPLOAD_DIR,
+ },
+}, sub {
+
+ my $pdf_hash = '90f7a64043fb458d58de1a0703a6355e2856b15e.pdf';
+ my $image_hash = '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg';
+
+ subtest "Check photo & file upload works" => sub {
+ my $problems = FixMyStreet::DB->resultset('Problem')->to_body( $body->id );
+ $problems->delete_all;
+
+
+ $mech->get_ok('/contact/enquiry');
+ my ($csrf) = $mech->content =~ /name="token" value="([^"]*)"/;
+
+ $mech->post( '/contact/enquiry/submit',
+ Content_Type => 'form-data',
+ Content =>
+ {
+ submit_problem => 1,
+ token => $csrf,
+ name => 'Test User',
+ username => 'testuser@example.org',
+ category => 'Other',
+ detail => encode_utf8('This is a general enquiry‽'),
+ photo1 => [ $sample_jpeg, undef, Content_Type => 'image/jpeg' ],
+ photo2 => [ $sample_pdf, undef, Content_Type => 'application/pdf' ],
+ }
+ );
+ ok $mech->success, 'Made request with two files uploaded';
+
+ is $problems->count, 1, 'problem created';
+ my $problem = $problems->first;
+ is $problem->detail, 'This is a general enquiry‽', 'problem has correct detail';
+ is $problem->non_public, 1, 'problem created non_public';
+ is $problem->postcode, '';
+ is $problem->used_map, 0;
+ is $problem->latitude, 51.469, 'Problem has correct latitude';
+ is $problem->longitude, -0.35, 'Problem has correct longitude';
+ ok $problem->confirmed, 'problem confirmed';
+
+ my $image_file = path($UPLOAD_DIR, $image_hash);
+ ok $image_file->exists, 'Photo uploaded to temp';
+
+ my $photoset = $problem->get_photoset();
+ is $photoset->num_images, 1, 'Found just 1 image';
+ is $photoset->data, $image_hash;
+
+ my $pdf_file = path($UPLOAD_DIR, 'enquiry_files', $pdf_hash);
+ ok $pdf_file->exists, 'PDF uploaded to temp';
+
+ is_deeply $problem->get_extra_metadata('enquiry_files'), {
+ $pdf_hash => 'sample.pdf'
+ }, 'enquiry file info stored OK';
+ };
+
+ subtest 'Check Open311 sending of the above report' => sub {
+ my $module = Test::MockModule->new('FixMyStreet::Cobrand::UKCouncils');
+ $module->mock(get => sub ($) { '{}' });
+ my $test_data = FixMyStreet::Script::Reports::send();
+ my $req = $test_data->{test_req_used};
+ my $found = 0;
+ foreach ($req->parts) {
+ my $cd = $_->header('Content-Disposition');
+ if ($cd =~ /attribute\[description\]/) {
+ is decode_utf8($_->content), 'This is a general enquiry‽', 'Correct description';
+ $found++;
+ }
+ if ($cd =~ /sample.pdf/) {
+ is $cd, 'form-data; name="file_' . $pdf_hash . '"; filename="sample.pdf"', 'Correct PDF header';
+ is $_->header('Content-Type'), 'application/pdf', 'Correct PDF content type';
+ $found++;
+ }
+ if ($cd =~ /jpeg/) {
+ is $cd, 'form-data; name="photo1"; filename="' . $image_hash . '"', 'Correct image header';
+ is $_->header('Content-Type'), 'image/jpeg', 'Correct image content type';
+ $found++;
+ }
+ }
+ is $found, 3, 'Found all tested headers';
+ };
+
+};
+
+done_testing();
diff --git a/t/app/controller/dashboard.t b/t/app/controller/dashboard.t
index ff8d1a9d5..72fc00128 100644
--- a/t/app/controller/dashboard.t
+++ b/t/app/controller/dashboard.t
@@ -1,5 +1,9 @@
use Test::MockTime ':all';
+package FixMyStreet::Cobrand::No2FA;
+use parent 'FixMyStreet::Cobrand::FixMyStreet';
+sub must_have_2fa { 0 }
+
package FixMyStreet::Cobrand::Tester;
use parent 'FixMyStreet::Cobrand::Default';
# Allow access if CSV export for a body, otherwise deny
@@ -26,7 +30,11 @@ my $other_body = $mech->create_body_ok(1234, 'Some Other Council');
my $body = $mech->create_body_ok(2651, 'City of Edinburgh Council');
my @cats = ('Litter', 'Other', 'Potholes', 'Traffic lights');
for my $contact ( @cats ) {
- $mech->create_contact_ok(body_id => $body->id, category => $contact, email => "$contact\@example.org");
+ my $c = $mech->create_contact_ok(body_id => $body->id, category => $contact, email => "$contact\@example.org");
+ if ($contact eq 'Potholes') {
+ $c->set_extra_metadata(group => ['Road']);
+ $c->update;
+ }
}
my $superuser = $mech->create_user_ok('superuser@example.com', name => 'Super User', is_superuser => 1);
@@ -38,17 +46,21 @@ my $area_id = '60705';
my $alt_area_id = '62883';
my $last_month = DateTime->now->subtract(months => 2);
-$mech->create_problems_for_body(2, $body->id, 'Title', { areas => ",$area_id,2651,", category => 'Potholes', cobrand => 'fixmystreet' });
-$mech->create_problems_for_body(3, $body->id, 'Title', { areas => ",$area_id,2651,", category => 'Traffic lights', cobrand => 'fixmystreet', dt => $last_month });
-$mech->create_problems_for_body(1, $body->id, 'Title', { areas => ",$alt_area_id,2651,", category => 'Litter', cobrand => 'fixmystreet' });
+$mech->create_problems_for_body(2, $body->id, 'Title', { areas => ",$area_id,2651,", category => 'Potholes', cobrand => 'no2fat' });
+$mech->create_problems_for_body(3, $body->id, 'Title', { areas => ",$area_id,2651,", category => 'Traffic lights', cobrand => 'no2fa', dt => $last_month });
+$mech->create_problems_for_body(1, $body->id, 'Title', { areas => ",$alt_area_id,2651,", category => 'Litter', cobrand => 'no2fa' });
-my @scheduled_problems = $mech->create_problems_for_body(7, $body->id, 'Title', { areas => ",$area_id,2651,", category => 'Traffic lights', cobrand => 'fixmystreet' });
-my @fixed_problems = $mech->create_problems_for_body(4, $body->id, 'Title', { areas => ",$area_id,2651,", category => 'Potholes', cobrand => 'fixmystreet' });
-my @closed_problems = $mech->create_problems_for_body(3, $body->id, 'Title', { areas => ",$area_id,2651,", category => 'Traffic lights', cobrand => 'fixmystreet' });
+my @scheduled_problems = $mech->create_problems_for_body(7, $body->id, 'Title', { areas => ",$area_id,2651,", category => 'Traffic lights', cobrand => 'no2fa' });
+my @fixed_problems = $mech->create_problems_for_body(4, $body->id, 'Title', { areas => ",$area_id,2651,", category => 'Potholes', cobrand => 'no2fa' });
+my @closed_problems = $mech->create_problems_for_body(3, $body->id, 'Title', { areas => ",$area_id,2651,", category => 'Traffic lights', cobrand => 'no2fa' });
+my $first_problem_id;
+my $first_update_id;
foreach my $problem (@scheduled_problems) {
$problem->update({ state => 'action scheduled' });
- $mech->create_comment_for_problem($problem, $counciluser, 'Title', 'text', 0, 'confirmed', 'action scheduled');
+ my ($update) = $mech->create_comment_for_problem($problem, $counciluser, 'Title', 'text', 0, 'confirmed', 'action scheduled');
+ $first_problem_id = $problem->id unless $first_problem_id;
+ $first_update_id = $update->id unless $first_update_id;
}
foreach my $problem (@fixed_problems) {
@@ -56,24 +68,20 @@ foreach my $problem (@fixed_problems) {
$mech->create_comment_for_problem($problem, $counciluser, 'Title', 'text', 0, 'confirmed', 'fixed');
}
-my $first_problem_id;
-my $first_update_id;
foreach my $problem (@closed_problems) {
$problem->update({ state => 'closed' });
- my ($update) = $mech->create_comment_for_problem($problem, $counciluser, 'Title', 'text', 0, 'confirmed', 'closed', { confirmed => \'current_timestamp' });
- $first_problem_id = $problem->id unless $first_problem_id;
- $first_update_id = $update->id unless $first_update_id;
+ $mech->create_comment_for_problem($problem, $counciluser, 'Title', 'text', 0, 'confirmed', 'closed');
}
my $categories = scraper {
- process "select[name=category] > option", 'cats[]' => 'TEXT',
+ process "select[name=category] option", 'cats[]' => 'TEXT',
process "table[id=overview] > tr", 'rows[]' => scraper {
process 'td', 'cols[]' => 'TEXT'
},
};
FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ ALLOWED_COBRANDS => 'no2fa',
MAPIT_URL => 'http://mapit.uk/',
}, sub {
@@ -131,8 +139,9 @@ FixMyStreet::override_config {
subtest 'The correct categories and totals shown by default' => sub {
$mech->get_ok("/dashboard");
- my $expected_cats = [ 'All', @cats ];
+ my $expected_cats = [ 'All', 'Litter', 'Other', 'Traffic lights', 'Potholes' ];
my $res = $categories->scrape( $mech->content );
+ $mech->content_contains('<optgroup label="Road">');
is_deeply( $res->{cats}, $expected_cats, 'correct list of categories' );
# Three missing as more than a month ago
test_table($mech->content, 1, 0, 0, 1, 0, 0, 0, 0, 2, 0, 4, 6, 7, 3, 0, 10, 10, 3, 4, 17);
@@ -218,7 +227,7 @@ FixMyStreet::override_config {
is $rows[1]->[0], $first_problem_id, 'Correct report ID';
is $rows[1]->[1], $first_update_id, 'Correct update ID';
is $rows[1]->[3], 'confirmed', 'Correct state';
- is $rows[1]->[4], 'closed', 'Correct problem state';
+ is $rows[1]->[4], 'action scheduled', 'Correct problem state';
is $rows[1]->[5], 'text', 'Correct text';
is $rows[1]->[6], 'Title', 'Correct name';
};
diff --git a/t/app/controller/index.t b/t/app/controller/index.t
index bd268b3d7..56f91ded7 100644
--- a/t/app/controller/index.t
+++ b/t/app/controller/index.t
@@ -58,7 +58,7 @@ subtest "does pc, (x,y), (e,n) or (lat,lon) go to /around" => sub {
}
};
-my $problem_rs = FixMyStreet::App->model('DB::Problem');
+my $problem_rs = FixMyStreet::DB->resultset('Problem');
my $num = $problem_rs->count;
my @edinburgh_problems = $mech->create_problems_for_body(5, 2651, 'Front page');
@@ -91,6 +91,13 @@ subtest "prefilters /around if user has categories" => sub {
$mech->content_contains("Cows,Potholes");
};
+subtest "prefilters /around if filter_category given in URL" => sub {
+ $mech->get_ok('/?filter_category=MyUniqueTestCategory&filter_group=MyUniqueTestGroup');
+ # NB can't use visible_form_values because fields are hidden
+ $mech->content_contains("MyUniqueTestCategory");
+ $mech->content_contains("MyUniqueTestGroup");
+};
+
END {
done_testing();
}
diff --git a/t/app/controller/moderate.t b/t/app/controller/moderate.t
index 7ef24bbe8..8e84bd392 100644
--- a/t/app/controller/moderate.t
+++ b/t/app/controller/moderate.t
@@ -12,9 +12,9 @@ sub moderate_permission_title { 0 }
package main;
+use Path::Tiny;
+use File::Temp 'tempdir';
use FixMyStreet::TestMech;
-use FixMyStreet::App;
-use Data::Dumper;
my $mech = FixMyStreet::TestMech->new;
$mech->host('www.example.org');
@@ -29,7 +29,7 @@ my $user = $mech->create_user_ok('test-moderation@example.com', name => 'Test Us
my $user2 = $mech->create_user_ok('test-moderation2@example.com', name => 'Test User 2');
sub create_report {
- FixMyStreet::App->model('DB::Problem')->create(
+ FixMyStreet::DB->resultset('Problem')->create(
{
postcode => 'BR1 3SB',
bodies_str => $body->id,
@@ -174,23 +174,42 @@ subtest 'Problem moderation' => sub {
};
subtest 'Hide photo' => sub {
- $mech->content_contains('Photo of this report');
+ my $UPLOAD_DIR = tempdir( CLEANUP => 1 );
- $mech->submit_form_ok({ with_fields => {
- %problem_prepopulated,
- problem_photo => 0,
- }});
- $mech->base_like( qr{\Q$REPORT_URL\E} );
+ FixMyStreet::override_config {
+ PHOTO_STORAGE_BACKEND => 'FileSystem',
+ PHOTO_STORAGE_OPTIONS => {
+ UPLOAD_DIR => $UPLOAD_DIR,
+ },
+ }, sub {
+ my $image_path = path('t/app/controller/sample.jpg');
+ $image_path->copy( path($UPLOAD_DIR, '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg') );
- $mech->content_lacks('Photo of this report');
+ $mech->get_ok('/photo/' . $report->id . '.0.jpeg');
- $mech->submit_form_ok({ with_fields => {
- %problem_prepopulated,
- problem_photo => 1,
- }});
- $mech->base_like( qr{\Q$REPORT_URL\E} );
+ $mech->get_ok($REPORT_URL);
+ $mech->content_contains('Photo of this report');
- $mech->content_contains('Photo of this report');
+ $mech->submit_form_ok({ with_fields => {
+ %problem_prepopulated,
+ problem_photo => 0,
+ }});
+ $mech->base_like( qr{\Q$REPORT_URL\E} );
+
+ my $res = $mech->get('/photo/' . $report->id . '.0.jpeg');
+ is $res->code, 404, 'got 404';
+
+ $mech->get_ok($REPORT_URL);
+ $mech->content_lacks('Photo of this report');
+
+ $mech->submit_form_ok({ with_fields => {
+ %problem_prepopulated,
+ problem_photo => 1,
+ }});
+ $mech->base_like( qr{\Q$REPORT_URL\E} );
+
+ $mech->content_contains('Photo of this report');
+ };
};
subtest 'Hide report' => sub {
@@ -206,7 +225,7 @@ subtest 'Problem moderation' => sub {
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';
+ is $email->header('To'), '"Test User 2" <' . $user2->email . '>', 'Sent to correct email';
my $url = $mech->get_link_from_email($email);
ok $url, "extracted complain url '$url'";
@@ -477,8 +496,6 @@ subtest 'updates' => sub {
}});
$mech->content_lacks('update good good bad good');
};
-
- $update->moderation_original_data->delete;
};
my $update2 = create_update();
@@ -517,4 +534,14 @@ subtest 'And do it as a superuser' => sub {
subtest 'Check moderation history in admin' => sub {
$mech->get_ok('/admin/report_edit/' . $report->id);
};
+
+subtest 'Check moderation in user log' => sub {
+ $mech->get_ok('/admin/users/' . $user->id . '/log');
+ my $report_id = $report->id;
+ $mech->content_like(qr/Moderated report.*?$report_id/);
+ my $update_id = $update->id;
+ $mech->content_like(qr/Moderated update.*?$update_id/);
+};
+
+
done_testing();
diff --git a/t/app/controller/my.t b/t/app/controller/my.t
index 8b4a25c26..673addf0c 100644
--- a/t/app/controller/my.t
+++ b/t/app/controller/my.t
@@ -23,7 +23,7 @@ $mech->content_lacks('Another Title');
my @update;
my $i = 0;
foreach ($user, $user, $other_user) {
- $update[$i] = FixMyStreet::App->model('DB::Comment')->create({
+ $update[$i] = FixMyStreet::DB->resultset('Comment')->create({
text => 'this is an update',
user => $_,
state => 'confirmed',
diff --git a/t/app/controller/my_planned.t b/t/app/controller/my_planned.t
index a6a47a798..67d59e148 100644
--- a/t/app/controller/my_planned.t
+++ b/t/app/controller/my_planned.t
@@ -1,5 +1,4 @@
use FixMyStreet::TestMech;
-use Test::MockModule;
my $mech = FixMyStreet::TestMech->new;
$mech->get_ok('/my/planned');
@@ -188,13 +187,6 @@ FixMyStreet::override_config {
ALLOWED_COBRANDS => [ 'oxfordshire' ],
BASE_URL => 'http://oxfordshire.fixmystreet.site',
}, sub {
- my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::Oxfordshire');
- $cobrand->mock('available_permissions', sub {
- my $self = shift;
-
- return FixMyStreet::Cobrand::Default->available_permissions;
- });
-
subtest "can remove problems not displayed in cobrand from shortlist" => sub {
$user->user_planned_reports->remove();
my ($problem1) = $mech->create_problems_for_body(2, $body->id, 'New Problem');
diff --git a/t/app/controller/offline.t b/t/app/controller/offline.t
new file mode 100644
index 000000000..876475264
--- /dev/null
+++ b/t/app/controller/offline.t
@@ -0,0 +1,67 @@
+use FixMyStreet::TestMech;
+use FixMyStreet::DB;
+use Path::Tiny;
+use Memcached;
+
+my $mech = FixMyStreet::TestMech->new;
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'test'
+}, sub {
+ my $theme_dir = path(FixMyStreet->path_to('web/theme/test'));
+ $theme_dir->mkpath;
+ my $image_path = path('t/app/controller/sample.jpg');
+ $image_path->copy($theme_dir->child('sample.jpg'));
+ subtest 'manifest' => sub {
+ Memcached::delete("manifest_theme:test");
+ my $j = $mech->get_ok_json('/.well-known/manifest.webmanifest');
+ is $j->{name}, 'FixMyStreet', 'correct name';
+ is $j->{theme_color}, '#ffd000', 'correct theme colour';
+ is_deeply $j->{icons}[0], {
+ type => 'image/jpeg',
+ src => '/theme/test/sample.jpg',
+ sizes => '133x100'
+ }, 'correct icon';
+ };
+ subtest 'themed manifest' => sub {
+ Memcached::delete("manifest_theme:test");
+ FixMyStreet::DB->resultset('ManifestTheme')->create({
+ cobrand => "test",
+ name => "My Test Cobrand FMS",
+ short_name => "Test FMS",
+ background_colour => "#ff00ff",
+ theme_colour => "#ffffff",
+ });
+
+ my $j = $mech->get_ok_json('/.well-known/manifest.webmanifest');
+ is $j->{name}, 'My Test Cobrand FMS', 'correctly overridden name';
+ is $j->{short_name}, 'Test FMS', 'correctly overridden short_name';
+ is $j->{background_color}, '#ff00ff', 'correctly overridden background colour';
+ is $j->{theme_color}, '#ffffff', 'correctly overridden theme colour';
+ };
+ $theme_dir->remove_tree;
+};
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet'
+}, sub {
+ subtest '.com manifest' => sub {
+ my $j = $mech->get_ok_json('/.well-known/manifest.webmanifest');
+ is $j->{related_applications}[0]{platform}, 'play', 'correct app';
+ is $j->{icons}[0]{sizes}, '192x192', 'correct fallback size';
+ };
+};
+
+subtest 'service worker' => sub {
+ $mech->get_ok('/service-worker.js');
+ $mech->content_contains('translation_strings');
+ $mech->content_contains('offline/fallback');
+};
+
+subtest 'offline fallback page' => sub {
+ $mech->get_ok('/offline/fallback');
+ $mech->content_contains('Offline');
+ $mech->content_contains('offline_list');
+};
+
+done_testing(); \ No newline at end of file
diff --git a/t/app/controller/open311.t b/t/app/controller/open311.t
index 79fe159a3..c052605c7 100644
--- a/t/app/controller/open311.t
+++ b/t/app/controller/open311.t
@@ -14,7 +14,7 @@ $mech->content_contains('<status>open</status>');
$mech->get_ok('/open311/v2/requests.json?jurisdiction_id=foo&status=open&agency_responsible=2237');
my $json = decode_json($mech->content);
-my $problems = $json->{requests}[0]{request};
+my $problems = $json->{service_requests};
is @$problems, 2;
like $problems->[0]{description}, qr/Around page Test/;
@@ -25,7 +25,7 @@ subtest "non_public reports aren't available" => sub {
});
$mech->get_ok('/open311/v2/requests.json?jurisdiction_id=foo');
$json = decode_json($mech->content);
- $problems = $json->{requests}[0]{request};
+ $problems = $json->{service_requests};
is @$problems, 1;
like $problems->[0]{description}, qr/Around page Test/;
$mech->content_lacks('This report is now private');
@@ -33,7 +33,7 @@ subtest "non_public reports aren't available" => sub {
my $problem_id = $problem1->id;
$mech->get_ok("/open311/v2/requests/$problem_id.json?jurisdiction_id=foo");
$json = decode_json($mech->content);
- $problems = $json->{requests}[0]{request};
+ $problems = $json->{service_requests};
is @$problems, 0;
};
@@ -45,7 +45,7 @@ subtest "hidden reports aren't available" => sub {
});
$mech->get_ok('/open311/v2/requests.json?jurisdiction_id=foo');
$json = decode_json($mech->content);
- $problems = $json->{requests}[0]{request};
+ $problems = $json->{service_requests};
is @$problems, 1;
like $problems->[0]{description}, qr/Around page Test/;
$mech->content_lacks('This report is now hidden');
@@ -53,7 +53,7 @@ subtest "hidden reports aren't available" => sub {
my $problem_id = $problem1->id;
$mech->get_ok("/open311/v2/requests/$problem_id.json?jurisdiction_id=foo");
$json = decode_json($mech->content);
- $problems = $json->{requests}[0]{request};
+ $problems = $json->{service_requests};
is @$problems, 0;
};
diff --git a/t/app/controller/open311_updates.t b/t/app/controller/open311_updates.t
new file mode 100644
index 000000000..f2db0a02b
--- /dev/null
+++ b/t/app/controller/open311_updates.t
@@ -0,0 +1,99 @@
+use XML::Simple;
+use FixMyStreet::TestMech;
+my $mech = FixMyStreet::TestMech->new;
+
+my $user = $mech->create_user_ok('commentuser@example.com');
+my $body = $mech->create_body_ok(2237, 'Oxfordshire County Council', {
+ comment_user => $user,
+ api_key => 'sending-key',
+ jurisdiction => 'none',
+ endpoint => 'endpoint',
+});
+my ($problem) = $mech->create_problems_for_body(1, $body->id, 'Open311 updates', { external_id => 'p123' });
+
+subtest 'bad requests do not get through' => sub {
+ $mech->get('/open311/v2/servicerequestupdates.xml');
+ is $mech->response->code, 400, 'Is bad request';
+ $mech->content_contains('<description>Bad request: POST</description>');
+
+ $mech->post('/open311/v2/servicerequestupdates.xml');
+ is $mech->response->code, 400, 'Is bad request';
+ my $xml = _get_xml_object($mech->content);
+ is $xml->{error}[0]{description}, 'Bad request: jurisdiction_id';
+};
+
+subtest 'cobrand gets jurisdiction, but needs a token' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'oxfordshire',
+ }, sub {
+ $mech->post('/open311/v2/servicerequestupdates.xml');
+ is $mech->response->code, 400, 'Is bad request';
+ my $xml = _get_xml_object($mech->content);
+ is $xml->{error}[0]{description}, 'Bad request: api_key';
+ };
+
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'oxfordshire',
+ COBRAND_FEATURES => { open311_token => { oxfordshire => 'wrong-token' } },
+ }, sub {
+ $mech->post('/open311/v2/servicerequestupdates.xml');
+ is $mech->response->code, 400, 'Is bad request';
+ my $xml = _get_xml_object($mech->content);
+ is $xml->{error}[0]{description}, 'Bad request: api_key';
+ };
+};
+
+subtest 'With all data, an update is added' => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'oxfordshire',
+ COBRAND_FEATURES => { open311_token => { oxfordshire => 'receiving-token' } },
+ }, sub {
+ $mech->post_ok('/open311/v2/servicerequestupdates.xml', {
+ api_key => 'receiving-token',
+ service_request_id => $problem->external_id,
+ update_id => 'c123',
+ updated_datetime => $problem->confirmed->clone->add(hours => 2),
+ status => 'CLOSED',
+ description => 'This report has been fixed',
+ });
+ };
+
+ $problem->discard_changes;
+ is $problem->state, 'fixed - council', 'problem updated';
+ is $problem->comments->count, 1, 'One comment created';
+
+ my $comment = $problem->comments->first;
+ is $comment->text, 'This report has been fixed', 'correct text';
+ is $comment->user_id, $user->id, 'correct user';
+ is $comment->problem_state, 'fixed - council', 'correct state';
+ is $comment->external_id, 'c123', 'correct external id';
+
+ my $xml = _get_xml_object($mech->content);
+ my $response = $xml->{request_update};
+ is $response->[0]->{update_id}, $comment->id, 'correct id in response';
+};
+
+done_testing();
+
+sub _get_xml_object {
+ my ($xml) = @_;
+
+ # Of these, services/service_requests/service_request_updates are root
+ # elements, so GroupTags has no effect, but this is used in ForceArray too.
+ my $group_tags = {
+ services => 'service',
+ attributes => 'attribute',
+ values => 'value',
+ service_requests => 'request',
+ errors => 'error',
+ service_request_updates => 'request_update',
+ };
+ my $simple = XML::Simple->new(
+ ForceArray => [ values %$group_tags ],
+ KeyAttr => {},
+ GroupTags => $group_tags,
+ SuppressEmpty => undef,
+ );
+ my $obj = $simple->parse_string($xml);
+ return $obj;
+}
diff --git a/t/app/controller/photo.t b/t/app/controller/photo.t
index 842daa0dc..8884d432c 100644
--- a/t/app/controller/photo.t
+++ b/t/app/controller/photo.t
@@ -1,5 +1,4 @@
use FixMyStreet::TestMech;
-use FixMyStreet::App;
use Web::Scraper;
use Path::Tiny;
use File::Temp 'tempdir';
@@ -13,7 +12,7 @@ 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');
+my $body = $mech->create_body_ok(2527, 'Liverpool City Council');
subtest "Check multiple upload worked" => sub {
$mech->get_ok('/around');
@@ -112,4 +111,73 @@ subtest "Check photo uploading URL and endpoints work" => sub {
};
};
+subtest "Check no access to update photos on hidden reports" => sub {
+ my $UPLOAD_DIR = tempdir( CLEANUP => 1 );
+
+ my ($report) = $mech->create_problems_for_body(1, $body->id, 'Title');
+ my $update = $mech->create_comment_for_problem($report, $report->user, $report->name, 'Text', $report->anonymous, 'confirmed', 'confirmed', { photo => $report->photo });
+
+ FixMyStreet::override_config {
+ PHOTO_STORAGE_BACKEND => 'FileSystem',
+ PHOTO_STORAGE_OPTIONS => {
+ UPLOAD_DIR => $UPLOAD_DIR,
+ },
+ }, sub {
+ my $image_path = path('t/app/controller/sample.jpg');
+ $image_path->copy( path($UPLOAD_DIR, '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg') );
+
+ $mech->get_ok('/photo/c/' . $update->id . '.0.jpeg');
+
+ $report->update({ state => 'hidden' });
+ $report->get_photoset->delete_cached(plus_updates => 1);
+
+ my $res = $mech->get('/photo/c/' . $update->id . '.0.jpeg');
+ is $res->code, 404, 'got 404';
+ };
+};
+
+subtest 'non_public photos only viewable by correct people' => sub {
+ my $UPLOAD_DIR = tempdir( CLEANUP => 1 );
+ path(FixMyStreet->path_to('web/photo'))->remove_tree({ keep_root => 1 });
+
+ my ($report) = $mech->create_problems_for_body(1, $body->id, 'Title', {
+ non_public => 1,
+ });
+
+ FixMyStreet::override_config {
+ PHOTO_STORAGE_BACKEND => 'FileSystem',
+ PHOTO_STORAGE_OPTIONS => {
+ UPLOAD_DIR => $UPLOAD_DIR,
+ },
+ }, sub {
+ my $image_path = path('t/app/controller/sample.jpg');
+ $image_path->copy( path($UPLOAD_DIR, '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg') );
+
+ $mech->log_out_ok;
+ my $i = '/photo/' . $report->id . '.0.jpeg';
+ my $res = $mech->get($i);
+ is $res->code, 404, 'got 404';
+
+ $mech->log_in_ok('test@example.com');
+ $i = '/photo/' . $report->id . '.0.jpeg';
+ $mech->get_ok($i);
+ my $image_file = FixMyStreet->path_to("web$i");
+ ok !-e $image_file, 'File not cached out';
+
+ my $user = $mech->log_in_ok('someoneelse@example.com');
+ $i = '/photo/' . $report->id . '.0.jpeg';
+ $res = $mech->get($i);
+ is $res->code, 404, 'got 404';
+
+ $user->update({ from_body => $body });
+ $user->user_body_permissions->create({ body => $body, permission_type => 'report_inspect' });
+ $i = '/photo/' . $report->id . '.0.jpeg';
+ $mech->get_ok($i);
+
+ $user->update({ from_body => undef, is_superuser => 1 });
+ $i = '/photo/' . $report->id . '.0.jpeg';
+ $mech->get_ok($i);
+ };
+};
+
done_testing();
diff --git a/t/app/controller/questionnaire.t b/t/app/controller/questionnaire.t
index 05aed7262..b561b271a 100644
--- a/t/app/controller/questionnaire.t
+++ b/t/app/controller/questionnaire.t
@@ -1,7 +1,6 @@
use DateTime;
use FixMyStreet::TestMech;
-use FixMyStreet::App::Controller::Questionnaire;
ok( my $mech = FixMyStreet::TestMech->new, 'Created mech object' );
@@ -12,7 +11,7 @@ my $report_time = $dt->ymd . ' ' . $dt->hms;
my $sent = $dt->add( minutes => 5 );
my $sent_time = $sent->ymd . ' ' . $sent->hms;
-my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
+my $report = FixMyStreet::DB->resultset('Problem')->find_or_create(
{
postcode => 'EH1 1BB',
bodies_str => '2651',
@@ -47,7 +46,7 @@ foreach my $state (
subtest "questionnaire not sent for $state state" => sub {
$report->update( { send_questionnaire => 1, state => $state } );
$report->questionnaires->delete;
- FixMyStreet::App->model('DB::Questionnaire')->send_questionnaires( {
+ FixMyStreet::DB->resultset('Questionnaire')->send_questionnaires( {
site => 'fixmystreet'
} );
@@ -61,7 +60,7 @@ $report->update( { send_questionnaire => 1, state => 'confirmed' } );
$report->questionnaires->delete;
# Call the questionaire sending function...
-FixMyStreet::App->model('DB::Questionnaire')->send_questionnaires( {
+FixMyStreet::DB->resultset('Questionnaire')->send_questionnaires( {
site => 'fixmystreet'
} );
my $email = $mech->get_email;
@@ -80,12 +79,12 @@ $mech->clear_emails_ok;
$report->discard_changes;
is $report->send_questionnaire, 0;
-$token = FixMyStreet::App->model("DB::Token")->find( {
+$token = FixMyStreet::DB->resultset("Token")->find( {
scope => 'questionnaire', token => $token
} );
ok $token, 'found token for questionnaire';
-my $questionnaire = FixMyStreet::App->model('DB::Questionnaire')->find( {
+my $questionnaire = FixMyStreet::DB->resultset('Questionnaire')->find( {
id => $token->data
} );
ok $questionnaire, 'found questionnaire';
@@ -317,7 +316,7 @@ foreach my $test (
is $questionnaire->new_state, $result;
is $questionnaire->ever_reported, $test->{fields}{reported} eq 'Yes' ? 1 : 0;
if ($test->{fields}{update} || $test->{comment}) {
- my $c = FixMyStreet::App->model("DB::Comment")->find(
+ my $c = FixMyStreet::DB->resultset("Comment")->find(
{ problem_id => $report->id }
);
is $c->text, $test->{fields}{update} || $test->{comment};
@@ -346,7 +345,7 @@ foreach my $test (
};
}
-my $comment = FixMyStreet::App->model('DB::Comment')->find_or_create(
+my $comment = FixMyStreet::DB->resultset('Comment')->find_or_create(
{
problem_id => $report->id,
user_id => $user->id,
@@ -436,7 +435,7 @@ FixMyStreet::override_config {
$report->update;
$questionnaire->delete;
- FixMyStreet::App->model('DB::Questionnaire')->send_questionnaires();
+ FixMyStreet::DB->resultset('Questionnaire')->send_questionnaires();
my $email = $mech->get_email;
my $body = $mech->get_text_body_from_email($email);
@@ -449,7 +448,7 @@ FixMyStreet::override_config {
# 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(
+ my $questionnaire2 = FixMyStreet::DB->resultset('Questionnaire')->find_or_create(
{
problem_id => $report->id,
whensent => $dt->ymd . ' ' . $dt->hms,
@@ -462,9 +461,9 @@ FixMyStreet::override_config {
$mech->content_contains( 'Has this problem been fixed?' );
$mech->content_lacks( 'ever reported' );
- $token = FixMyStreet::App->model("DB::Token")->find( { scope => 'questionnaire', token => $token } );
+ $token = FixMyStreet::DB->resultset("Token")->find( { scope => 'questionnaire', token => $token } );
ok $token, 'found token for questionnaire';
- $questionnaire = FixMyStreet::App->model('DB::Questionnaire')->find( { id => $token->data } );
+ $questionnaire = FixMyStreet::DB->resultset('Questionnaire')->find( { id => $token->data } );
ok $questionnaire, 'found questionnaire';
$questionnaire2->delete;
@@ -479,7 +478,7 @@ FixMyStreet::override_config {
$report->cobrand( 'fiksgatami' );
$report->update;
$questionnaire->delete;
- FixMyStreet::App->model('DB::Questionnaire')->send_questionnaires();
+ FixMyStreet::DB->resultset('Questionnaire')->send_questionnaires();
$email = $mech->get_email;
ok $email, "got an email";
$mech->clear_emails_ok;
diff --git a/t/app/controller/report_as_other.t b/t/app/controller/report_as_other.t
index 0c8b7d995..377de27bd 100644
--- a/t/app/controller/report_as_other.t
+++ b/t/app/controller/report_as_other.t
@@ -1,5 +1,4 @@
use FixMyStreet::TestMech;
-use FixMyStreet::App;
use FixMyStreet::Script::Reports;
# disable info logs for this test run
@@ -41,7 +40,6 @@ subtest "Body user, has permission to add report as council" => sub {
is $report->anonymous, 0, 'report not anonymous';
};
-my @users;
subtest "Body user, has permission to add report as another user with email" => sub {
my $report = add_report(
'contribute_as_another_user',
@@ -57,7 +55,6 @@ subtest "Body user, has permission to add report as another user with email" =>
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 user with mobile phone number" => sub {
@@ -78,7 +75,6 @@ subtest "Body user, has permission to add report as another user with mobile pho
is $report->user->email_verified, 0, 'user email not verified';
isnt $report->user->id, $user->id, 'user does not match';
$mech->email_count_is(0);
- push @users, $report->user;
};
subtest "Body user, has permission to add report as another user with landline number" => sub {
@@ -99,14 +95,30 @@ subtest "Body user, has permission to add report as another user with landline n
is $report->user->email_verified, 0, 'user email not verified';
isnt $report->user->id, $user->id, 'user does not match';
$mech->email_count_is(0);
- push @users, $report->user;
+};
+
+subtest "Body user, has permission to add report as another user with only name" => 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',
+ username => '',
+ may_show_name => undef,
+ );
+ is $report->name, 'Another User', 'report name is name given';
+ is $report->user->name, 'Body User', 'user name unchanged';
+ is $report->user->id, $user->id, 'user matches';
+ is $report->anonymous, 1, 'report anonymous';
};
subtest "Body user, has permission to add report as another (existing) user with email" => sub {
FixMyStreet::Script::Reports::send();
$mech->clear_emails_ok;
- $mech->create_user_ok('existing@example.net', name => 'Existing User');
+ my $existing = $mech->create_user_ok('existing@example.net', name => 'Existing User');
my $report = add_report(
'contribute_as_another_user',
form_as => 'another_user',
@@ -114,14 +126,13 @@ subtest "Body user, has permission to add report as another (existing) user with
detail => 'Test report details.',
category => 'Potholes',
name => 'Existing Yooser',
- username => 'existing@example.net',
+ username => $existing->email,
);
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';
+ is $report->user->email, $existing->email, '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;
my $send_confirmation_mail_override = Sub::Override->new(
"FixMyStreet::Cobrand::Default::report_sent_confirmation_email",
@@ -149,7 +160,6 @@ subtest "Body user, has permission to add report as another (existing) user with
is $report->user->phone, '+447906333333', 'user phone correct';
isnt $report->user->id, $user->id, 'user does not match';
$mech->email_count_is(0);
- push @users, $report->user;
};
subtest "Superuser, can add report as anonymous user" => sub {
@@ -168,6 +178,8 @@ subtest "Superuser, can add report as anonymous user" => sub {
is $report->user->name, 'Super', 'user name unchanged';
is $report->user->id, $user->id, 'user matches';
is $report->anonymous, 1, 'report anonymous';
+ is $report->get_extra_metadata('contributed_as'), 'anonymous_user';
+ is $report->get_extra_metadata('contributed_by'), undef;
my $send_confirmation_mail_override = Sub::Override->new(
"FixMyStreet::Cobrand::Default::report_sent_confirmation_email",
@@ -183,6 +195,28 @@ subtest "Superuser, can add report as anonymous user" => sub {
$mech->log_in_ok($test_email);
};
+subtest "Body user, can add report as anonymous user" => sub {
+ FixMyStreet::Script::Reports::send();
+ $mech->clear_emails_ok;
+
+ my $user = $mech->log_in_ok($user->email);
+ my $report = add_report(
+ 'contribute_as_anonymous_user',
+ form_as => 'anonymous_user',
+ title => "Test Report",
+ detail => 'Test report details.',
+ category => 'Street lighting',
+ );
+ is $report->name, $body->name, 'report name is OK';
+ is $report->user->name, 'Body User', 'user name unchanged';
+ is $report->user->id, $user->id, 'user matches';
+ is $report->anonymous, 1, 'report anonymous';
+ is $report->get_extra_metadata('contributed_as'), 'anonymous_user';
+ is $report->get_extra_metadata('contributed_by'), $user->id;
+
+ $mech->log_in_ok($test_email);
+};
+
subtest "Body user, has permission to add update as council" => sub {
my $update = add_update(
'contribute_as_body',
@@ -208,7 +242,6 @@ subtest "Body user, has permission to add update as another user with email" =>
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 user with mobile phone" => sub {
@@ -224,7 +257,6 @@ subtest "Body user, has permission to add update as another user with mobile pho
is $update->user->phone, '+447906444444', 'user phone correct';
isnt $update->user->id, $user->id, 'user does not match';
$mech->email_count_is(0);
- push @users, $update->user;
};
subtest "Body user, has permission to add update as another user with landline phone" => sub {
@@ -240,20 +272,20 @@ subtest "Body user, has permission to add update as another user with landline p
is $update->user->phone, '+441685555555', 'user phone correct';
isnt $update->user->id, $user->id, 'user does not match';
$mech->email_count_is(0);
- push @users, $update->user;
};
subtest "Body user, has permission to add update as another (existing) user with email" => sub {
+ my $existing = $mech->create_user_ok('existing@example.net', name => 'Existing User');
my $update = add_update(
'contribute_as_another_user',
form_as => 'another_user',
update => 'Test Update',
name => 'Existing Yooser',
- username => 'existing@example.net',
+ username => $existing->email,
);
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';
+ is $update->user->email, $existing->email, '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/;
};
diff --git a/t/app/controller/report_display.t b/t/app/controller/report_display.t
index bde090dd1..4bd0fc991 100644
--- a/t/app/controller/report_display.t
+++ b/t/app/controller/report_display.t
@@ -73,32 +73,6 @@ subtest "change report to hidden and check for 410 status" => sub {
ok $report->update( { state => 'confirmed' } ), 'confirm report again';
};
-subtest "change report to non_public and check for 403 status" => sub {
- ok $report->update( { non_public => 1 } ), 'make report non public';
- ok $mech->get("/report/$report_id"), "get '/report/$report_id'";
- is $mech->res->code, 403, "access denied";
- is $mech->uri->path, "/report/$report_id", "at /report/$report_id";
- $mech->content_contains('That report cannot be viewed on FixMyStreet.');
- ok $report->update( { non_public => 0 } ), 'make report public';
-};
-
-subtest "check owner of report can view non public reports" => sub {
- ok $report->update( { non_public => 1 } ), 'make report non public';
- $mech->log_in_ok( $report->user->email );
- ok $mech->get("/report/$report_id"), "get '/report/$report_id'";
- is $mech->res->code, 200, "report can be viewed";
- is $mech->uri->path, "/report/$report_id", "at /report/$report_id";
- $mech->log_out_ok;
-
- $mech->log_in_ok( $user2->email );
- ok $mech->get("/report/$report_id"), "get '/report/$report_id'";
- is $mech->res->code, 403, "access denied to user who is not report creator";
- is $mech->uri->path, "/report/$report_id", "at /report/$report_id";
- $mech->content_contains('That report cannot be viewed on FixMyStreet.');
- $mech->log_out_ok;
- ok $report->update( { non_public => 0 } ), 'make report public';
-};
-
subtest "duplicate reports are signposted correctly" => sub {
$report2->set_extra_metadata(duplicate_of => $report->id);
$report2->state('duplicate');
@@ -249,6 +223,39 @@ for my $test (
fixed => 0
},
{
+ cobrand => 'fixmystreet',
+ description => 'old open311 report',
+ date => DateTime->new(
+ year => 2009,
+ month => 6,
+ day => 12,
+ hour => 9,
+ minute => 43,
+ second => 12
+ ),
+ state => 'confirmed',
+ send_method => 'Open311',
+ banner_id => undef,
+ banner_text => undef,
+ fixed => 0
+ },
+ {
+ cobrand => 'westminster',
+ description => 'old westminster report',
+ date => DateTime->new(
+ year => 2009,
+ month => 6,
+ day => 12,
+ hour => 9,
+ minute => 43,
+ second => 12
+ ),
+ state => 'confirmed',
+ banner_id => undef,
+ banner_text => undef,
+ fixed => 0
+ },
+ {
description => 'old fixed report',
date => DateTime->new(
year => 2009,
@@ -364,9 +371,16 @@ for my $test (
$report->confirmed( $test->{date}->ymd . ' ' . $test->{date}->hms );
$report->lastupdate( $test->{date}->ymd . ' ' . $test->{date}->hms );
$report->state( $test->{state} );
+ $report->send_method_used( $test->{send_method} || undef );
$report->update;
- $mech->get_ok("/report/$report_id");
+ my $cobrands = $test->{cobrand} ? [ $test->{cobrand} ] : [];
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => $cobrands,
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $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} ) {
@@ -395,6 +409,20 @@ for my $test (
};
}
+subtest "Correct OpenGraph image is used when report has no photo" => sub {
+ $report->update({ photo => undef });
+ $mech->get_ok("/report/$report_id");
+ $mech->content_contains("/cobrands/fixmystreet/images/fms-og_image.jpg", "site image is used");
+ $mech->content_lacks("/photo/$report_id.0.og", "report image is not present");
+};
+
+subtest "Correct OpenGraph image is used when report has a photo" => sub {
+ $report->update({ photo => '74e3362283b6ef0c48686fb0e161da4043bbcc97.jpeg' });
+ $mech->get_ok("/report/$report_id");
+ $mech->content_contains("/photo/$report_id.0.og.jpeg", "report opengraph image is present");
+ $mech->content_lacks("/cobrands/fixmystreet/images/fms-og_image.jpg", "site image is not used");
+};
+
my $body_westminster = $mech->create_body_ok(2504, 'Westminster City Council');
my $body_camden = $mech->create_body_ok(2505, 'Camden Borough Council');
diff --git a/t/app/controller/report_import.t b/t/app/controller/report_import.t
index 223979d1b..b2e15330a 100644
--- a/t/app/controller/report_import.t
+++ b/t/app/controller/report_import.t
@@ -1,5 +1,4 @@
use FixMyStreet::TestMech;
-use FixMyStreet::App;
use Web::Scraper;
use Path::Class;
use LWP::Protocol::PSGI;
@@ -17,7 +16,7 @@ ok -e $sample_file, "sample file $sample_file exists";
FixMyStreet::App->log->disable('info');
END { FixMyStreet::App->log->enable('info'); }
-my $body = $mech->create_body_ok(2245, 'Wiltshire Council');
+my $body = $mech->create_body_ok(2608, 'Borsetshire Council');
$mech->create_contact_ok(
body_id => $body->id,
category => 'Street lighting',
@@ -227,7 +226,7 @@ subtest "Submit a correct entry" => sub {
# check that report has been created
my $user =
- FixMyStreet::App->model('DB::User')
+ FixMyStreet::DB->resultset('User')
->find( { email => 'test@example.com' } );
ok $user, "Found a user";
@@ -315,7 +314,7 @@ subtest "Submit a correct entry (with location)" => sub {
# check that report has been created
my $user =
- FixMyStreet::App->model('DB::User')
+ FixMyStreet::DB->resultset('User')
->find( { email => 'test-ll@example.com' } );
ok $user, "Found a user";
@@ -382,7 +381,7 @@ subtest "Submit a correct entry (with location) to cobrand" => sub {
"check imported fields are shown"
or diag Dumper( $mech->visible_form_values ); use Data::Dumper;
- my $user = FixMyStreet::App->model('DB::User')->find( { email => 'test-ll@example.com' } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => 'test-ll@example.com' } );
ok $user, "Found a user";
my $report = $user->problems->first;
diff --git a/t/app/controller/report_inspect.t b/t/app/controller/report_inspect.t
index ef05288c7..8deb2667e 100644
--- a/t/app/controller/report_inspect.t
+++ b/t/app/controller/report_inspect.t
@@ -8,14 +8,6 @@ my $oxon = $mech->create_body_ok(2237, 'Oxfordshire County Council', { can_be_de
my $contact = $mech->create_contact_ok( body_id => $oxon->id, category => 'Cows', email => 'cows@example.net' );
my $contact2 = $mech->create_contact_ok( body_id => $oxon->id, category => 'Sheep', email => 'SHEEP', send_method => 'Open311' );
my $contact3 = $mech->create_contact_ok( body_id => $oxon->id, category => 'Badgers', email => 'badgers@example.net' );
-my $dt = FixMyStreet::DB->resultset("DefectType")->create({
- body => $oxon,
- name => 'Small Defect', description => "Teeny",
-});
-FixMyStreet::DB->resultset("ContactDefectType")->create({
- contact => $contact,
- defect_type => $dt,
-});
my $rp = FixMyStreet::DB->resultset("ResponsePriority")->create({
body => $oxon,
name => 'High Priority',
@@ -87,6 +79,87 @@ FixMyStreet::override_config {
$mech->content_lacks('/admin/report_edit/'.$report_id.'">admin</a>)');
};
+ for my $test (
+ {
+ name => "categories only",
+ area_ids => [],
+ categories => [ $contact->id ],
+ destination => "/reports/Oxfordshire",
+ previous => "/my/inspector_redirect",
+ query_form => { filter_category => $contact->category },
+ good_link => "/my/inspector_redirect",
+ bad_link => "/reports",
+ },
+ {
+ name => "categories and areas",
+ area_ids => [60705],
+ categories => [ $contact->id ],
+ destination => "/reports/Oxfordshire/Trowbridge",
+ previous => "/my/inspector_redirect",
+ query_form => { filter_category => $contact->category },
+ good_link => "/my/inspector_redirect",
+ bad_link => "/reports",
+ },
+ {
+ name => "areas only",
+ area_ids => [60705],
+ categories => undef,
+ destination => "/reports/Oxfordshire/Trowbridge",
+ previous => "/my/inspector_redirect",
+ query_form => {},
+ good_link => "/my/inspector_redirect",
+ bad_link => "/reports",
+ },
+ {
+ name => "no categories or areas",
+ area_ids => undef,
+ categories => undef,
+ destination => "/my",
+ query_form => {},
+ good_link => "/reports",
+ bad_link => "/my/inspector_redirect",
+ },
+ {
+ name => "categories but no from_body",
+ area_ids => undef,
+ categories => [ $contact->id ],
+ destination => "/my",
+ query_form => {},
+ good_link => "/reports",
+ bad_link => "/my/inspector_redirect",
+ unset_from_body => 1,
+ },
+ ) {
+ subtest "login destination and top-level nav for inspectors with " . $test->{name} => sub {
+ $mech->log_out_ok;
+
+ $user->area_ids($test->{area_ids});
+ $user->set_extra_metadata('categories', $test->{categories});
+ $user->from_body(undef) if $test->{unset_from_body};
+ $user->update;
+
+ # Can't use log_in_ok, as the call to logged_in_ok clobbers our post-login
+ # redirect.
+ $mech->get_ok('/auth');
+ $mech->submit_form_ok(
+ { with_fields => { username => $user->email, password_sign_in => 'secret' } },
+ "sign in using form" );
+ is $mech->res->code, 200, "got 200";
+ is $mech->uri->path, $test->{destination}, 'redirected to correct destination';
+ is_deeply { $mech->uri->query_form }, $test->{query_form}, 'destination query params set correctly';
+ if ($test->{previous}) {
+ is $mech->res->previous->code, 302, "got 302 for post-login redirect";
+ is $mech->res->previous->base->path, $test->{previous}, "previous URI correct";
+ }
+
+ $mech->get_ok("/");
+ ok $mech->find_link( text => 'All reports', url => $test->{good_link} );
+ ok !$mech->find_link( text => 'All reports', url => $test->{bad_link} );
+
+ $user->update( { from_body => $oxon } ) if $test->{unset_from_body};
+ };
+ }
+
subtest "council staff can't see admin report edit link on FMS.com" => sub {
my $report_edit_permission = $user->user_body_permissions->create({
body => $oxon, permission_type => 'report_edit' });
@@ -109,7 +182,7 @@ FixMyStreet::override_config {
$mech->get_ok("/report/$report_id");
$mech->submit_form_ok({ button => 'save', with_fields => { non_public => 1 } });
$report->discard_changes;
- my $alert = FixMyStreet::App->model('DB::Alert')->find(
+ my $alert = FixMyStreet::DB->resultset('Alert')->find(
{ user => $user, alert_type => 'new_updates', confirmed => 1, }
);
@@ -126,7 +199,7 @@ FixMyStreet::override_config {
$mech->get_ok("/report/$report_id");
$mech->submit_form_ok({ button => 'save', with_fields => { traffic_information => 'Yes', state => 'Action scheduled', include_update => undef } });
$report->discard_changes;
- my $alert = FixMyStreet::App->model('DB::Alert')->find(
+ my $alert = FixMyStreet::DB->resultset('Alert')->find(
{ user => $user, alert_type => 'new_updates', confirmed => 1, }
);
@@ -140,11 +213,10 @@ FixMyStreet::override_config {
$user->user_body_permissions->create({ body => $oxon, permission_type => 'planned_reports' });
$report->state('confirmed');
$report->update;
- 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', raise_defect => 1,
+ state => 'action scheduled',
} });
$mech->get_ok("/report/$report_id");
$mech->submit_form_ok({ with_fields => {
@@ -153,28 +225,22 @@ FixMyStreet::override_config {
$report->discard_changes;
my $comment = ($report->comments( undef, { order_by => { -desc => 'id' } } )->all)[1]->text;
is $comment, "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";
$mech->get_ok("/report/$report_id");
my $meta = $mech->extract_update_metas;
like $meta->[0], qr/State changed to: Action scheduled/, 'First update mentions action scheduled';
- like $meta->[2], qr/Posted by .*defect raised/, 'Update mentions defect raised';
$user->unset_extra_metadata('categories');
$user->update;
};
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 {
@@ -305,7 +371,7 @@ FixMyStreet::override_config {
$mech->get_ok("/report/$report_id");
$mech->submit_form_ok({ button => 'save', with_fields => { state => 'Investigating', public_update => "We're investigating.", include_update => "1" } });
- my $alert_count = FixMyStreet::App->model('DB::Alert')->search(
+ my $alert_count = FixMyStreet::DB->resultset('Alert')->search(
{ user_id => $user->id, alert_type => 'new_updates', confirmed => 1, parameter => $report_id }
)->count();
@@ -448,24 +514,6 @@ FixMyStreet::override_config {
is $report->response_priority->id, $rp->id, 'response priority set';
};
- subtest "check can set defect type for category when changing from category with no defect types" => sub {
- $report->update({ category => 'Sheep', defect_type_id => undef });
- $user->user_body_permissions->delete;
- $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_inspect' });
- $mech->get_ok("/report/$report_id");
- $mech->submit_form_ok({
- button => 'save',
- with_fields => {
- include_update => 0,
- defect_type => $dt->id,
- category => 'Cows',
- }
- });
- $report->discard_changes;
- is $report->defect_type->id, $dt->id, 'defect type set';
- $report->update({ defect_type_id => undef });
- };
-
subtest "check can't set priority that isn't for a category" => sub {
$report->discard_changes;
$report->update({ category => 'Cows', response_priority_id => $rp->id });
@@ -614,47 +662,6 @@ FixMyStreet::override_config {
return $perms;
});
- 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 {
- $user->user_body_permissions->create({ body => $oxon, permission_type => 'report_instruct' });
- $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 => 'in progress', include_update => undef,
- } });
- $report->discard_changes;
- is $report->get_extra_metadata('inspected'), undef, 'report not marked as inspected';
-
- $mech->submit_form_ok({ button => 'save', with_fields => {
- state => 'action scheduled', include_update => undef,
- } });
- $report->discard_changes;
- is $report->get_extra_metadata('inspected'), undef, 'report not marked as inspected';
- is $report->user->get_extra_metadata('reputation'), $reputation+1, "User reputation was increased";
-
- $mech->submit_form_ok({ button => 'save', with_fields => {
- state => 'action scheduled', include_update => undef,
- raise_defect => 1,
- } });
- $report->discard_changes;
- is $report->get_extra_metadata('inspected'), 1, 'report marked as inspected';
- $mech->get_ok("/report/$report_id");
- my $meta = $mech->extract_update_metas;
- like $meta->[-1], qr/Updated by .*defect raised/, 'Update mentions defect raised';
- };
subtest "Oxfordshire-specific traffic management options are shown" => sub {
$report->update({ state => 'confirmed' });
@@ -697,7 +704,6 @@ FixMyStreet::override_config {
priority => $rp->id,
include_update => '1',
detailed_information => 'XXX164XXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
- defect_type => '',
traffic_information => ''
};
my $values = $mech->visible_form_values('report_inspect_form');
diff --git a/t/app/controller/report_interest_count.t b/t/app/controller/report_interest_count.t
index 330d844d0..a9911c4ba 100644
--- a/t/app/controller/report_interest_count.t
+++ b/t/app/controller/report_interest_count.t
@@ -26,7 +26,7 @@ my $dt = DateTime->new(
second => 23
);
-my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
+my $report = FixMyStreet::DB->resultset('Problem')->find_or_create(
{
postcode => 'SW1A 1AA',
bodies_str => '2504',
diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t
index af18c39b9..d2da75f2c 100644
--- a/t/app/controller/report_new.t
+++ b/t/app/controller/report_new.t
@@ -1,60 +1,32 @@
+package FixMyStreet::Cobrand::HounslowNoName;
+use base 'FixMyStreet::Cobrand::UK';
+
+sub council_area_id { 2483 };
+
+package main;
+
use Test::MockModule;
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');
-
-my $sample_file = file(__FILE__)->parent->file("sample.jpg")->stringify;
-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, '/', "went to /";
- is_deeply { $mech->uri->query_form }, {}, "query empty";
-
- 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";
-
- $mech->get_ok('/report/new?pc_override=SW1A%201AA&latitude=51&longitude=-2');
- is $mech->uri->path, '/around', "went to /around";
- is_deeply { $mech->uri->query_form }, { pc => 'SW1A 1AA' },
- "pc correctly transferred, lat/lon gone";
- };
-};
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' },
{ area_id => 2482, name => 'Bromley Council' },
{ area_id => 2227, name => 'Hampshire County Council' },
{ area_id => 2333, name => 'Hart Council' },
{ area_id => 2535, name => 'Sandwell Borough Council' },
{ area_id => 1000, name => 'Highways England' },
- { area_id => 2217, name => 'Buckinghamshire County Council' },
- { area_id => 2232, name => 'Lincolnshire County Council' },
- { area_id => 2237, name => 'Oxfordshire County Council' },
- { area_id => 2600, name => 'Rutland County Council' },
- { area_id => 2234, name => 'Northamptonshire County Council' },
+ { area_id => 2483, name => 'Hounslow Borough Council' },
) {
my $body_obj = $mech->create_body_ok($body->{area_id}, $body->{name});
- push @bodies, $body_obj;
$body_ids{$body->{area_id}} = $body_obj->id;
}
@@ -74,31 +46,26 @@ my $contact3 = $mech->create_contact_ok(
category => 'Trees',
email => 'trees@example.com',
);
-my $contact4 = $mech->create_contact_ok(
+$mech->create_contact_ok(
body_id => $body_ids{2482}, # Bromley
category => 'Trees',
email => 'trees@example.com',
);
-my $contact5 = $mech->create_contact_ok(
+$mech->create_contact_ok(
body_id => $body_ids{2651}, # Edinburgh
category => 'Trees',
email => 'trees@example.com',
);
-my $contact6 = $mech->create_contact_ok(
+$mech->create_contact_ok(
body_id => $body_ids{2333}, # Hart
category => 'Trees',
email => 'trees@example.com',
);
-my $contact7 = $mech->create_contact_ok(
+$mech->create_contact_ok(
body_id => $body_ids{2227}, # Hampshire
category => 'Street lighting',
email => 'highways@example.com',
);
-my $contact8 = $mech->create_contact_ok(
- body_id => $body_ids{2504},
- category => 'Street lighting',
- email => 'highways@example.com'
-);
my $contact9 = $mech->create_contact_ok(
body_id => $body_ids{2226}, # Gloucestershire
category => 'Street lighting',
@@ -109,573 +76,23 @@ my $contact10 = $mech->create_contact_ok(
category => 'Street lighting',
email => 'streetlights-2326@example.com',
);
-my $contact11 = $mech->create_contact_ok(
+$mech->create_contact_ok(
body_id => $body_ids{1000}, # Highways
category => 'Pothole',
email => 'pothole-1000@example.com',
);
-my $contact12 = $mech->create_contact_ok(
- body_id => $body_ids{2217}, # Buckinghamshire
- category => 'Street lighting',
- email => 'streetlights-2217@example.com',
-);
-my $contact13 = $mech->create_contact_ok(
- body_id => $body_ids{2232}, # Lincolnshire
+$mech->create_contact_ok(
+ body_id => $body_ids{2483}, # Hounslow
category => 'Trees',
- email => 'trees-2232@example.com',
+ email => 'trees-2483@example.com',
);
-my $contact14 = $mech->create_contact_ok(
- body_id => $body_ids{2237}, # Oxfordshire
- category => 'Trees',
- email => 'trees-2247@example.com',
-);
-my $contact15 = $mech->create_contact_ok(
- body_id => $body_ids{2600}, # Rutland
- category => 'Trees',
- email => 'trees-2600@example.com',
-);
-my $contact16 = $mech->create_contact_ok(
- body_id => $body_ids{2234}, # Northamptonshire
- category => 'Trees',
- email => 'trees-2234@example.com',
+$mech->create_contact_ok(
+ body_id => $body_ids{2483}, # Hounslow
+ category => 'General Enquiry',
+ email => 'general-enquiry-2483@example.com',
+ non_public => 1,
);
-# 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',
- username => '',
- phone => '',
- password_sign_in => '',
- password_register => '',
- },
- 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',
- username => '',
- phone => '',
- category => 'Something bad',
- password_sign_in => '',
- password_register => '',
- },
- 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 => '',
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => '',
- may_show_name => '1',
- username => '',
- phone => '',
- category => 'Street lighting',
- password_sign_in => '',
- password_register => '',
- },
- changes => {},
- errors => [
- 'Please enter a subject',
- 'Please enter some details',
- 'Please enter your email',
- 'Please enter your name',
- ],
- },
- {
- msg => 'may_show_name is remembered',
- pc => 'SW1A 1AA',
- fields => {
- title => '',
- detail => '',
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => '',
- may_show_name => undef,
- username => '',
- phone => '',
- category => 'Street lighting',
- password_sign_in => '',
- password_register => '',
- },
- changes => {},
- errors => [
- 'Please enter a subject',
- 'Please enter some details',
- 'Please enter your email',
- 'Please enter your name',
- ],
- },
- {
- msg => 'may_show_name unchanged if name is present (stays false)',
- pc => 'SW1A 1AA',
- fields => {
- title => '',
- detail => '',
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => 'Bob Jones',
- may_show_name => undef,
- username => '',
- phone => '',
- category => 'Street lighting',
- password_sign_in => '',
- password_register => '',
- },
- changes => {},
- errors => [
- 'Please enter a subject',
- 'Please enter some details',
- 'Please enter your email',
- ],
- },
- {
- msg => 'may_show_name unchanged if name is present (stays true)',
- pc => 'SW1A 1AA',
- fields => {
- title => '',
- detail => '',
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => 'Bob Jones',
- may_show_name => '1',
- username => '',
- phone => '',
- category => 'Street lighting',
- password_sign_in => '',
- password_register => '',
- },
- changes => {},
- errors => [
- 'Please enter a subject',
- 'Please enter some details',
- 'Please enter your email',
- ],
- },
- {
- msg => 'title and details tidied up',
- pc => 'SW1A 1AA',
- fields => {
- title => "DOG SHIT\r\nON WALLS",
- detail => "on this portakabin -\r\n\r\nmore of a portaloo HEH!!",
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => 'Bob Jones',
- may_show_name => '1',
- username => '',
- phone => '',
- category => 'Street lighting',
- password_sign_in => '',
- password_register => '',
- },
- changes => {
- title => 'Dog poo on walls',
- detail =>
- "On this [portable cabin] -\n\nMore of a [portable loo] HEH!!",
- },
- errors => [ 'Please enter your email', ],
- },
- {
- msg => 'name too short',
- pc => 'SW1A 1AA',
- fields => {
- title => 'Test title',
- detail => 'Test detail',
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => 'DUDE',
- may_show_name => '1',
- username => '',
- phone => '',
- category => 'Street lighting',
- password_sign_in => '',
- password_register => '',
- },
- changes => {},
- errors => [
- 'Please enter your email',
-'Please enter your full name, councils need this information – if you do not wish your name to be shown on the site, untick the box below',
- ],
- },
- {
- msg => 'name is anonymous',
- pc => 'SW1A 1AA',
- fields => {
- title => 'Test title',
- detail => 'Test detail',
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => 'anonymous',
- may_show_name => '1',
- username => '',
- phone => '',
- category => 'Street lighting',
- password_sign_in => '',
- password_register => '',
- },
- changes => {},
- errors => [
- 'Please enter your email',
-'Please enter your full name, councils need this information – if you do not wish your name to be shown on the site, untick the box below',
- ],
- },
- {
- msg => 'email invalid',
- pc => 'SW1A 1AA',
- fields => {
- title => 'Test title',
- detail => 'Test detail',
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => 'Joe Smith',
- may_show_name => '1',
- username => 'not an email',
- phone => '',
- category => 'Street lighting',
- password_sign_in => '',
- password_register => '',
- },
- changes => { username => 'notanemail' },
- errors => [ 'Please enter a valid email', ],
- },
- {
- msg => 'cleanup title and detail',
- pc => 'SW1A 1AA',
- fields => {
- title => " Test title ",
- detail => " first line \n\n second\nline\n\n ",
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => '',
- may_show_name => '1',
- username => '',
- phone => '',
- category => 'Street lighting',
- password_sign_in => '',
- password_register => '',
- },
- changes => {
- title => 'Test title',
- detail => "First line\n\nSecond line",
- },
- errors => [
- 'Please enter your email',
- 'Please enter your name',
- ],
- },
- {
- msg => 'clean up name and email',
- pc => 'SW1A 1AA',
- fields => {
- title => '',
- detail => '',
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => ' Bob Jones ',
- may_show_name => '1',
- username => ' BOB @ExAmplE.COM ',
- phone => '',
- category => 'Street lighting',
- password_sign_in => '',
- password_register => '',
- },
- changes => {
- name => 'Bob Jones',
- username => 'bob@example.com',
- },
- errors => [ 'Please enter a subject', 'Please enter some details', ],
- },
- {
- msg => 'non-photo upload gives error',
- pc => 'SW1A 1AA',
- fields => {
- title => 'Title',
- detail => 'Detail',
- photo1 => [ [ undef, 'bad.txt', Content => 'This is not a JPEG', Content_Type => 'text/plain' ], 1 ],
- photo2 => '',
- photo3 => '',
- name => 'Bob Jones',
- may_show_name => '1',
- username => 'bob@example.com',
- phone => '',
- category => 'Street lighting',
- password_sign_in => '',
- password_register => '',
- },
- changes => {
- photo1 => '',
- },
- errors => [ "Please upload an image only" ],
- },
- {
- msg => 'bad photo upload gives error',
- pc => 'SW1A 1AA',
- fields => {
- title => 'Title',
- detail => 'Detail',
- photo1 => [ [ undef, 'fake.jpeg', Content => 'This is not a JPEG', Content_Type => 'image/jpeg' ], 1 ],
- photo2 => '',
- photo3 => '',
- name => 'Bob Jones',
- may_show_name => '1',
- username => 'bob@example.com',
- phone => '',
- category => 'Street lighting',
- password_sign_in => '',
- password_register => '',
- },
- changes => {
- photo1 => '',
- },
- 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',
- pc => 'SW1A 1AA',
- fields => {
- title => '',
- detail => 'Detail',
- photo1 => [ [ $sample_file, undef, Content_Type => 'application/octet-stream' ], 1 ],
- photo2 => '',
- photo3 => '',
- name => 'Bob Jones',
- may_show_name => '1',
- username => 'bob@example.com',
- phone => '',
- category => 'Street lighting',
- password_sign_in => '',
- password_register => '',
- },
- changes => {
- photo1 => '',
- },
- errors => [ "Please enter a subject" ],
- },
- {
- msg => 'Bromley long detail',
- pc => 'BR1 3UH',
- fields => {
- fms_extra_title => 'MR',
- title => '',
- detail => 'X' . 'x' x 1751,
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => 'Bob Example',
- may_show_name => '1',
- username => 'bob@example.com',
- phone => '',
- category => 'Trees',
- password_sign_in => '',
- password_register => '',
- },
- changes => { },
- errors => [ 'Please enter a subject', 'Reports are limited to 1750 characters in length. Please shorten your report' ],
- },
- {
- msg => 'Oxfordshire long detail',
- pc => 'OX20 1SZ',
- fields => {
- title => '',
- detail => 'X' . 'x' x 1701,
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => 'Bob Example',
- may_show_name => '1',
- username => 'bob@example.com',
- phone => '',
- category => 'Trees',
- password_sign_in => '',
- password_register => '',
- },
- changes => { },
- errors => [ 'Please enter a subject', 'Reports are limited to 1700 characters in length. Please shorten your report' ],
- },
- {
- msg => 'Lincolnshire long phone',
- pc => 'PE9 2GX',
- fields => {
- title => '',
- detail => 'Detail',
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => 'Bob Example',
- may_show_name => '1',
- username => 'bob@example.com',
- phone => '123456789 12345678910',
- category => 'Trees',
- password_sign_in => '',
- password_register => '',
- },
- changes => { },
- errors => [ 'Please enter a subject', 'Phone numbers are limited to 20 characters in length.' ],
- },
- {
- msg => 'Buckinghamshire long name',
- pc => 'RG9 6TL',
- fields => {
- title => '',
- detail => '',
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => 'This is a very long name that should fail validation',
- may_show_name => '1',
- username => 'bob@example.com',
- phone => '',
- category => 'Street lighting',
- password_sign_in => '',
- password_register => '',
- },
- changes => { },
- errors => [ 'Please enter a subject', 'Please enter some details', 'Names are limited to 50 characters in length.' ],
- },
- {
- msg => 'Rutland long name',
- pc => 'LE15 0GJ',
- fields => {
- title => '',
- detail => '',
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => 'This is a very long name that should fail validation',
- may_show_name => '1',
- username => 'bob@example.com',
- phone => '',
- category => 'Trees',
- password_sign_in => '',
- password_register => '',
- },
- changes => { },
- errors => [ 'Please enter a subject', 'Please enter some details', 'Names are limited to 40 characters in length.' ],
- },
- {
- msg => 'Oxfordshire validation',
- pc => 'OX20 1SZ',
- fields => {
- title => '',
- detail => '',
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => 'This is a really extraordinarily long name that definitely should fail validation',
- may_show_name => '1',
- username => 'bob.has.a.very.long.email@thisisalonghostname.example.com',
- phone => '01234 5678910 09876 54321 ext 203',
- category => 'Trees',
- password_sign_in => '',
- password_register => '',
- },
- changes => { },
- errors => [ 'Please enter a subject', 'Please enter some details', 'Emails are limited to 50 characters in length.', 'Phone numbers are limited to 20 characters in length.', 'Names are limited to 50 characters in length.'],
- },
- {
- msg => 'Northamptonshire validation',
- pc => 'NN1 1NS',
- fields => {
- title => 'This is a very long title that should fail the validation as it is really much too long to pass the validation of 120 characters',
- detail => '',
- photo1 => '',
- photo2 => '',
- photo3 => '',
- name => 'A User',
- may_show_name => '1',
- username => 'user@example.org',
- phone => '',
- category => 'Trees',
- password_sign_in => '',
- password_register => '',
- },
- changes => { },
- errors => [ 'Summaries are limited to 120 characters in length. Please shorten your summary', 'Please enter some details'],
- },
- )
-{
- subtest "check form errors where $test->{msg}" => sub {
- $mech->get_ok('/around');
-
- # submit initial pc form
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { fixmystreet => '.' }, 'bromley', 'oxfordshire', 'rutland', 'lincolnshire', 'buckinghamshire', 'northamptonshire' ],
- 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 [ sort @{$mech->page_errors} ], [ sort @{$test->{errors}} ], "check errors";
-
- # check that fields have changed as expected
- my $new_values = {
- %{ $test->{fields} }, # values added to form
- %{ $test->{changes} }, # changes we expect
- };
- is_deeply $mech->visible_form_values, $new_values,
- "values correctly changed";
- };
-}
-
my $first_user;
foreach my $test (
{
@@ -702,14 +119,14 @@ foreach my $test (
# check that the user does not exist
my $test_email = 'test-1@example.com';
if ($test->{user}) {
- my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
ok $user, "test user does exist";
$user->problems->delete;
$user->name( 'Old Name' );
$user->password( 'old_password' );
$user->update;
} elsif (!$first_user) {
- ok !FixMyStreet::App->model('DB::User')->find( { email => $test_email } ),
+ ok !FixMyStreet::DB->resultset('User')->find( { email => $test_email } ),
"test user does not exist";
$first_user = 1;
} else {
@@ -754,7 +171,7 @@ foreach my $test (
# check that the user has been created/ not changed
my $user =
- FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
ok $user, "user found";
if ($test->{user}) {
is $user->name, 'Old Name', 'name unchanged';
@@ -799,7 +216,7 @@ foreach my $test (
}
# check that the reporter has an alert
- my $alert = FixMyStreet::App->model('DB::Alert')->find( {
+ my $alert = FixMyStreet::DB->resultset('Alert')->find( {
user => $report->user,
alert_type => 'new_updates',
parameter => $report->id,
@@ -815,65 +232,10 @@ foreach my $test (
};
}
-# this test to make sure that we don't see spurious error messages about
-# the name being blank when there is a sign in error
-subtest "test password errors for a user who is signing in as they report" => sub {
- $mech->log_out_ok;
- $mech->clear_emails_ok;
-
- # check that the user does not exist
- my $test_email = 'test-2@example.com';
-
- my $user = $mech->create_user_ok($test_email);
-
- # setup the user.
- ok $user->update( {
- name => 'Joe Bloggs',
- phone => '01234 567 890',
- password => 'secret2',
- phone_verified => 1,
- } ), "set user details";
-
- # submit initial pc form
- $mech->get_ok('/around');
- 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" );
-
- $mech->submit_form_ok(
- {
- button => 'submit_sign_in',
- with_fields => {
- title => 'Test Report',
- detail => 'Test report details.',
- photo1 => '',
- username => '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, [
- "There was a problem with your login information. If you cannot remember your password, or do not have one, please fill in the \x{2018}No\x{2019} section of the form.",
- ], "check there were errors";
-
- $mech->content_lacks('1234', 'phone number not shown');
-};
-
foreach my $test (
- { two_factor => 0, desc => '', },
- { two_factor => 1, desc => ' with two-factor', },
+ { two_factor => '', desc => '', },
+ { two_factor => 'yes', desc => ' with two-factor', },
+ { two_factor => 'new', desc => ' with mandated two-factor, not yet set up', },
) {
subtest "test report creation for a user who is signing in as they report$test->{desc}" => sub {
$mech->log_out_ok;
@@ -890,21 +252,25 @@ foreach my $test (
name => 'Joe Bloggs',
phone => '01234 567 890',
password => 'secret2',
+ $test->{two_factor} ? (is_superuser => 1) : (),
} ), "set user details";
my $auth;
- if ($test->{two_factor}) {
+ my $mock;
+ if ($test->{two_factor} eq 'yes') {
use Auth::GoogleAuth;
$auth = Auth::GoogleAuth->new;
- $user->is_superuser(1);
$user->set_extra_metadata('2fa_secret', $auth->generate_secret32);
$user->update;
+ } elsif ($test->{two_factor} eq 'new') {
+ $mock = Test::MockModule->new('FixMyStreet::Cobrand::FixMyStreet');
+ $mock->mock(must_have_2fa => sub { 1 });
}
# submit initial pc form
$mech->get_ok('/around');
FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ ALLOWED_COBRANDS => 'fixmystreet',
MAPIT_URL => 'http://mapit.uk/',
}, sub {
$mech->submit_form_ok( { with_fields => { pc => 'EH1 1BB', } },
@@ -921,7 +287,7 @@ foreach my $test (
title => 'Test Report',
detail => 'Test report details.',
photo1 => '',
- username => $test_email,
+ username => $user->email,
password_sign_in => 'secret2',
category => 'Street lighting',
}
@@ -929,13 +295,22 @@ foreach my $test (
"submit good details"
);
- if ($test->{two_factor}) {
+ if ($test->{two_factor} eq 'yes') {
my $code = $auth->code;
my $wrong_code = $auth->code(undef, time() - 120);
$mech->content_contains('Please generate a two-factor code');
$mech->submit_form_ok({ with_fields => { '2fa_code' => $wrong_code } }, "provide wrong 2FA code" );
$mech->content_contains('Try again');
$mech->submit_form_ok({ with_fields => { '2fa_code' => $code } }, "provide correct 2FA code" );
+ } elsif ($test->{two_factor} eq 'new') {
+ $mech->content_contains('requires two-factor');
+ $mech->submit_form_ok({ with_fields => { '2fa_action' => 'activate' } }, "submit 2FA activation");
+ my ($token) = $mech->content =~ /name="secret32" value="([^"]*)">/;
+
+ use Auth::GoogleAuth;
+ my $auth = Auth::GoogleAuth->new({ secret32 => $token });
+ my $code = $auth->code;
+ $mech->submit_form_ok({ with_fields => { '2fa_code' => $code } }, "provide correct 2FA code" );
}
# check that we got the message expected
@@ -956,7 +331,7 @@ foreach my $test (
my $report = $user->problems->first;
ok $report, "Found the report";
- if (!$test->{two_factor}) {
+ if ($test->{two_factor} eq '') {
# The superuser account will be immediately redirected
$mech->content_contains('Thank you for reporting this issue');
}
@@ -972,7 +347,7 @@ foreach my $test (
$mech->get_ok( '/report/' . $report->id );
# check that the reporter has an alert
- my $alert = FixMyStreet::App->model('DB::Alert')->find( {
+ my $alert = FixMyStreet::DB->resultset('Alert')->find( {
user => $report->user,
alert_type => 'new_updates',
parameter => $report->id,
@@ -1073,7 +448,7 @@ foreach my $test (
$mech->get_ok( '/report/' . $report->id );
# check that the reporter has an alert
- my $alert = FixMyStreet::App->model('DB::Alert')->find( {
+ my $alert = FixMyStreet::DB->resultset('Alert')->find( {
user => $report->user,
alert_type => 'new_updates',
parameter => $report->id,
@@ -1258,16 +633,18 @@ subtest "Test inactive categories" => sub {
};
subtest "category groups" => sub {
- my $cobrand = Test::MockModule->new('FixMyStreet::Cobrand::FixMyStreet');
- $cobrand->mock('enable_category_groups', sub { 1 });
FixMyStreet::override_config {
ALLOWED_COBRANDS => 'fixmystreet',
MAPIT_URL => 'http://mapit.uk/',
+ COBRAND_FEATURES => {
+ category_groups => { fixmystreet => 1 }
+ }
}, sub {
- $contact2->update( { extra => { group => 'Roads' } } );
+ $contact2->update( { extra => { group => ['Roads','Pavements'] } } );
$contact9->update( { extra => { group => 'Roads' } } );
$contact10->update( { extra => { group => 'Roads' } } );
$mech->get_ok("/report/new?lat=$saved_lat&lon=$saved_lon");
+ $mech->content_like(qr{<optgroup label="Pavements">\s*<option value='Potholes'>Potholes</option></optgroup>});
$mech->content_like(qr{<optgroup label="Roads">\s*<option value='Potholes'>Potholes</option>\s*<option value='Street lighting'>Street lighting</option></optgroup>});
};
};
@@ -1303,7 +680,7 @@ subtest "test report creation for a category that is non public" => sub {
title => 'Test Report',
detail => 'Test report details.',
photo1 => '',
- username => 'test-2@example.com',
+ username => $user->email,
name => 'Joe Bloggs',
category => 'Street lighting',
}
@@ -1343,7 +720,7 @@ subtest "test report creation for a category that is non public" => sub {
$contact1->update( { non_public => 0 } );
};
-$contact2->category( "Pothol\xc3\xa9s" );
+$contact2->category( "Pothol\x{00E9}s" );
$contact2->update;
subtest "check map click ajax response" => sub {
@@ -1387,48 +764,50 @@ subtest "check map click ajax response" => sub {
is $extra_details->{category}, '', 'category is empty for council with no contacts';
is_deeply $extra_details->{bodies}, [ "Sandwell Borough Council" ], 'correct bodies for council with no contacts';
ok !$extra_details->{extra_name_info}, 'no extra name info';
-};
-
-#### test uploading an image
-#### test completing a partial report (eq flickr upload)
-
-#### possibly manual testing
-# create report without using map
-# create report by clicking on map with javascript off
-# create report with images off
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'hounslow',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=51.482286&longitude=-0.328163' );
+ };
+ is_deeply $extra_details->{display_names}, { 'Hounslow Borough Council' => 'Hounslow Highways' }, 'council display name mapping correct';
-subtest "check that a lat/lon off coast leads to /around" => sub {
- my $off_coast_latitude = 50.78301;
- my $off_coast_longitude = -0.646929;
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'hounslownoname',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=51.482286&longitude=-0.328163' );
+ };
+ isnt defined $extra_details->{display_names}, 'no council display names if none defined';
FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'hounslow',
MAPIT_URL => 'http://mapit.uk/',
}, sub {
- $mech->get_ok( #
- "/report/new"
- . "?latitude=$off_coast_latitude"
- . "&longitude=$off_coast_longitude"
- );
+ $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=51.482286&longitude=-0.328163' );
};
+ ok $extra_details->{by_category}->{'General Enquiry'}->{non_public}, 'non_public set correctly for private category';
+ isnt defined $extra_details->{by_category}->{Tree}->{non_public}, 'non_public omitted for public category';
+};
- is $mech->uri->path, '/around', "redirected to '/around'";
+#### test uploading an image
- is_deeply #
- $mech->page_errors,
- [ 'That location does not appear to be covered by a council; perhaps it is offshore or outside the country. Please try again.' ],
- "Found location error";
+#### test completing a partial report (eq flickr upload)
-};
+#### possibly manual testing
+# create report without using map
+# create report by clicking on map with javascript off
+# create report with images off
subtest "check we load a partial report correctly" => sub {
- my $user = FixMyStreet::App->model('DB::User')->find_or_create(
+ my $user = FixMyStreet::DB->resultset('User')->find_or_create(
{
email => 'test-partial@example.com'
}
);
- my $report = FixMyStreet::App->model('DB::Problem')->create( {
+ my $report = FixMyStreet::DB->resultset('Problem')->create( {
name => '',
postcode => '',
category => 'Street lighting',
@@ -1447,7 +826,7 @@ subtest "check we load a partial report correctly" => sub {
my $report_id = $report->id;
- my $token = FixMyStreet::App->model("DB::Token")
+ my $token = FixMyStreet::DB->resultset("Token")
->create( { scope => 'partial', data => $report->id } );
my $token_code = $token->token;
@@ -1593,7 +972,7 @@ for my $test (
# confirm token in order to update the user details
$mech->get_ok($url);
- my $user = FixMyStreet::App->model('DB::User')->find( { email => 'firstlast@example.com' } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => 'firstlast@example.com' } );
my $report = $user->problems->first;
ok $report, "Found the report";
@@ -1732,7 +1111,7 @@ subtest "test Hart" => sub {
# check that the user has been created/ not changed
$user =
- FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ FixMyStreet::DB->resultset('User')->find( { email => $user ? $user->email : $test_email } );
ok $user, "user found";
# find the report
@@ -1822,151 +1201,6 @@ subtest "categories from deleted bodies shouldn't be visible for new reports" =>
};
};
-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' } );
- my $body_id = $contact1->body->id;
- my $extra_details = $mech->get_ok_json('/report/new/ajax?latitude=55.952055&longitude=-3.189579');
- like $extra_details->{top_message}, qr{Edinburgh.*accept reports.*/unresponsive\?body=$body_id};
- is_deeply $extra_details->{unresponsive}, { $body_id => 1 }, "unresponsive json set";
- $extra_details = $mech->get_ok_json('/report/new/category_extras?category=Street%20lighting&latitude=55.952055&longitude=-3.189579');
- is_deeply $extra_details->{unresponsive}, { $body_id => 1 }, "unresponsive json set";
-
- 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',
- username => $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' } );
- $extra_details = $mech->get_ok_json('/report/new/ajax?latitude=51.896268&longitude=-2.093063');
- like $extra_details->{by_category}{$contact3->category}{category_extra}, qr/Cheltenham.*Trees.*unresponsive.*category=Trees/s;
- $extra_details = $mech->get_ok_json('/report/new/category_extras?category=Trees&latitude=51.896268&longitude=-2.093063');
- is_deeply $extra_details->{unresponsive}, { $contact3->body->id => 1 }, "unresponsive json set";
-
- $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',
- username => $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 => '.' } ],
@@ -2066,7 +1300,7 @@ subtest "extra google analytics code displayed on email confirmation problem cre
$mech->get_ok($url);
# find the report
- my $user = FixMyStreet::App->model('DB::User')->find( { email => 'firstlast@example.com' } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => 'firstlast@example.com' } );
my $report = $user->problems->first;
ok $report, "Found the report";
@@ -2077,207 +1311,4 @@ subtest "extra google analytics code displayed on email confirmation problem cre
};
};
-
-my $private_perms = $mech->create_user_ok('private_perms@example.org', name => 'private', from_body => $bodies[0]);
-subtest "report_mark_private allows users to mark reports as private" => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
- BASE_URL => 'https://www.fixmystreet.com',
- MAPIT_URL => 'http://mapit.uk/',
- }, sub {
- $mech->log_out_ok;
-
- $private_perms->user_body_permissions->find_or_create({
- body => $bodies[0],
- permission_type => 'report_mark_private',
- });
-
- $mech->log_in_ok('private_perms@example.org');
- $mech->get_ok('/');
- $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 => "Private report",
- detail => 'Private report details.',
- photo1 => '',
- name => 'Joe Bloggs',
- may_show_name => '1',
- phone => '07903 123 456',
- category => 'Trees',
- non_public => 1,
- }
- },
- "submit good details"
- );
-
- $mech->content_contains('Great work. Now spread the word', 'shown confirmation page');
- }
-};
-
-my $inspector = $mech->create_user_ok('inspector@example.org', name => 'inspector', from_body => $bodies[0]);
-foreach my $test (
- { non_public => 0 },
- { non_public => 1 },
-) {
- subtest "inspectors get redirected directly to the report page, non_public=$test->{non_public}" => sub {
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
- BASE_URL => 'https://www.fixmystreet.com',
- MAPIT_URL => 'http://mapit.uk/',
- }, sub {
- $mech->log_out_ok;
-
- $inspector->user_body_permissions->find_or_create({
- body => $bodies[0],
- permission_type => 'planned_reports',
- });
- $inspector->user_body_permissions->find_or_create({
- body => $bodies[0],
- permission_type => 'report_inspect',
- });
-
- $mech->log_in_ok('inspector@example.org');
- $mech->get_ok('/');
- $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 => "Inspector report",
- detail => 'Inspector report details.',
- photo1 => '',
- name => 'Joe Bloggs',
- may_show_name => '1',
- phone => '07903 123 456',
- category => 'Trees',
- non_public => $test->{non_public},
- }
- },
- "submit good details"
- );
-
- like $mech->uri->path, qr/\/report\/[0-9]+/, 'Redirects directly to report';
- }
- };
-}
-
-subtest "check map click ajax response for inspector" => sub {
- $mech->log_out_ok;
-
- my $extra_details;
- $inspector->user_body_permissions->find_or_create({
- body => $bodies[0],
- permission_type => 'planned_reports',
- });
- $inspector->user_body_permissions->find_or_create({
- body => $bodies[0],
- permission_type => 'report_inspect',
- });
-
- $mech->log_in_ok('inspector@example.org');
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
- MAPIT_URL => 'http://mapit.uk/',
- }, sub {
- $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=55.952055&longitude=-3.189579' );
- };
- like $extra_details->{category}, qr/data-prefill="0/, 'inspector prefill not set';
- ok !$extra_details->{contribute_as}, 'no contribute as section';
-};
-
-subtest "check map click ajax response for inspector and uk cobrand" => sub {
- $mech->log_out_ok;
-
- my $extra_details;
- $inspector->user_body_permissions->find_or_create({
- body => $bodies[4],
- permission_type => 'planned_reports',
- });
- $inspector->user_body_permissions->find_or_create({
- body => $bodies[4],
- permission_type => 'report_inspect',
- });
-
- $mech->log_in_ok('inspector@example.org');
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { bromley => '.' } ],
- MAPIT_URL => 'http://mapit.uk/',
- }, sub {
- $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=51.402096&longitude=0.015784' );
- };
- like $extra_details->{category}, qr/data-prefill="0/, 'inspector prefill not set';
-};
-
-for my $test (
- {
- desc => 'map click ajax for contribute_as_another_user',
- permissions => {
- contribute_as_another_user => 1,
- contribute_as_anonymous_user => undef,
- contribute_as_body => undef,
- }
- },
- {
- desc => 'map click ajax for contribute_as_anonymous_user',
- permissions => {
- contribute_as_another_user => undef,
- contribute_as_anonymous_user => 1,
- contribute_as_body => undef,
- }
- },
- {
- desc => 'map click ajax for contribute_as_body',
- permissions => {
- contribute_as_another_user => undef,
- contribute_as_anonymous_user => undef,
- contribute_as_body => 1,
- }
- },
-) {
- subtest $test->{desc} => sub {
- $mech->log_out_ok;
- my $extra_details;
- (my $name = $test->{desc}) =~ s/.*(contri.*)/$1/;
- my $user = $mech->create_user_ok("$name\@example.org", name => 'test user', from_body => $bodies[0]);
- for my $p ( keys %{$test->{permissions}} ) {
- next unless $test->{permissions}->{$p};
- $user->user_body_permissions->find_or_create({
- body => $bodies[0],
- permission_type => $p,
- });
- }
- $mech->log_in_ok("$name\@example.org");
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
- MAPIT_URL => 'http://mapit.uk/',
- }, sub {
- $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=55.952055&longitude=-3.189579' );
- };
- for my $p ( keys %{$test->{permissions}} ) {
- (my $key = $p) =~ s/contribute_as_//;
- is $extra_details->{contribute_as}->{$key}, $test->{permissions}->{$p}, "$key correctly set";
- }
-
- FixMyStreet::override_config {
- ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
- MAPIT_URL => 'http://mapit.uk/',
- }, sub {
- $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=51.754926&longitude=-1.256179' );
- };
- ok !$extra_details->{contribute_as}, 'no contribute as section for other council';
- };
-}
-
done_testing();
diff --git a/t/app/controller/report_new_anon.t b/t/app/controller/report_new_anon.t
new file mode 100644
index 000000000..d86bc8134
--- /dev/null
+++ b/t/app/controller/report_new_anon.t
@@ -0,0 +1,272 @@
+package FixMyStreet::Cobrand::AnonAllowed;
+use parent 'FixMyStreet::Cobrand::FixMyStreet';
+sub allow_anonymous_reports { 1 }
+sub anonymous_account { { email => 'anon@example.org', name => 'Anonymous' } }
+
+package FixMyStreet::Cobrand::AnonAllowedByButton;
+use parent 'FixMyStreet::Cobrand::FixMyStreet';
+sub allow_anonymous_reports { 'button' }
+sub anonymous_account { { email => 'anonbutton@example.org', name => 'Anonymous Button' } }
+
+package FixMyStreet::Cobrand::AnonAllowedForCategory;
+use parent 'FixMyStreet::Cobrand::FixMyStreet';
+sub allow_anonymous_reports {
+ my ($self, $category) = @_;
+ $category ||= $self->{c}->stash->{category};
+ return 'button' if $category eq 'Trees';
+}
+sub anonymous_account { { email => 'anoncategory@example.org', name => 'Anonymous Category' } }
+
+package main;
+
+use FixMyStreet::TestMech;
+
+# 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(2651, 'Edinburgh');
+my $staffuser = $mech->create_user_ok('counciluser@example.com', name => 'Council User', from_body => $body);
+$staffuser->user_body_permissions->create({
+ body => $body,
+ permission_type => 'contribute_as_body',
+});
+$staffuser->user_body_permissions->create({
+ body => $body,
+ permission_type => 'default_to_body',
+});
+
+
+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 => 'Trees',
+ email => 'trees@example.com',
+);
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'anonallowed',
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+
+subtest "check form errors when anonymous account is on" => sub {
+ $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 => { category => "Street lighting" } }, "submit form" );
+
+ my @errors = (
+ 'Please enter a subject',
+ 'Please enter some details',
+ # No user errors
+ );
+ is_deeply [ sort @{$mech->page_errors} ], [ sort @errors ], "check errors";
+};
+
+subtest "test report creation anonymously" => sub {
+ $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(
+ {
+ button => 'submit_register',
+ with_fields => {
+ title => 'Test Report',
+ detail => 'Test report details.',
+ name => 'Joe Bloggs',
+ may_show_name => '1',
+ category => 'Street lighting',
+ }
+ },
+ "submit good details"
+ );
+ $mech->content_contains('Thank you');
+
+ is_deeply $mech->page_errors, [], "check there were no errors";
+
+ my $report = FixMyStreet::DB->resultset("Problem")->first;
+ ok $report, "Found the report";
+
+ is $report->state, 'confirmed', "report confirmed";
+ $mech->get_ok( '/report/' . $report->id );
+
+ is $report->bodies_str, $body->id;
+ is $report->name, 'Anonymous';
+ is $report->anonymous, 0; # Doesn't change behaviour here, but uses anon account's name always
+
+ my $alert = FixMyStreet::DB->resultset('Alert')->find( {
+ user => $report->user,
+ alert_type => 'new_updates',
+ parameter => $report->id,
+ } );
+ is $alert, undef, "no alert created";
+
+ $mech->not_logged_in_ok;
+};
+
+};
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'anonallowedbybutton',
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+
+subtest "test report creation anonymously by button" => sub {
+ $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(
+ {
+ button => 'submit_register',
+ with_fields => {
+ title => 'Test Report',
+ detail => 'Test report details.',
+ name => 'Joe Bloggs',
+ may_show_name => '1',
+ category => 'Street lighting',
+ }
+ },
+ "submit good details"
+ );
+
+ is_deeply $mech->page_errors, [
+ 'Please enter your email'
+ ], "check there were no errors";
+
+ $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(
+ {
+ button => 'report_anonymously',
+ with_fields => {
+ title => 'Test Report',
+ detail => 'Test report details.',
+ category => 'Street lighting',
+ }
+ },
+ "submit good details"
+ );
+ $mech->content_contains('Thank you');
+
+ is_deeply $mech->page_errors, [], "check there were no errors";
+
+ my $report = FixMyStreet::DB->resultset("Problem")->search({}, { order_by => { -desc => 'id' } })->first;
+ ok $report, "Found the report";
+
+ is $report->state, 'confirmed', "report confirmed";
+ $mech->get_ok( '/report/' . $report->id );
+
+ is $report->bodies_str, $body->id;
+ is $report->name, 'Anonymous Button';
+ is $report->anonymous, 1; # Doesn't change behaviour here, but uses anon account's name always
+ is $report->get_extra_metadata('contributed_as'), 'anonymous_user';
+
+ my $alert = FixMyStreet::DB->resultset('Alert')->find( {
+ user => $report->user,
+ alert_type => 'new_updates',
+ parameter => $report->id,
+ } );
+ is $alert, undef, "no alert created";
+
+ $mech->not_logged_in_ok;
+};
+
+subtest "test report creation anonymously by staff user" => sub {
+ FixMyStreet::DB->resultset("Problem")->delete_all;
+
+ $mech->log_in_ok( $staffuser->email );
+ $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(
+ {
+ button => 'report_anonymously',
+ with_fields => {
+ title => 'Test Report',
+ detail => 'Test report details.',
+ category => 'Street lighting',
+ }
+ },
+ "submit good details"
+ );
+ $mech->content_contains('Thank you');
+
+ is_deeply $mech->page_errors, [], "check there were no errors";
+
+ my $report = FixMyStreet::DB->resultset("Problem")->first;
+ ok $report, "Found the report";
+
+ is $report->state, 'confirmed', "report confirmed";
+ $mech->get_ok( '/report/' . $report->id );
+
+ is $report->bodies_str, $body->id;
+ is $report->name, 'Anonymous Button';
+ is $report->anonymous, 1;
+ is $report->get_extra_metadata('contributed_as'), 'anonymous_user';
+ is $report->get_extra_metadata('contributed_by'), $staffuser->id;
+
+ my $alert = FixMyStreet::DB->resultset('Alert')->find( {
+ user => $report->user,
+ alert_type => 'new_updates',
+ parameter => $report->id,
+ } );
+ is $alert, undef, "no alert created";
+
+ $mech->log_out_ok;
+};
+
+};
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'anonallowedforcategory',
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+
+subtest "test report creation anonymously by button, per category" => sub {
+ $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({
+ button => 'submit_category_part_only',
+ with_fields => {
+ category => 'Street lighting',
+ }
+ }, "submit category with no anonymous reporting");
+ $mech->content_lacks('<button name="report_anonymously" value="yes" class="btn btn--block">'); # non-JS button, JS button always there
+ $mech->submit_form_ok({
+ button => 'submit_register',
+ with_fields => {
+ category => 'Trees',
+ }
+ }, "submit category with anonymous reporting");
+
+ $mech->submit_form_ok({
+ button => 'report_anonymously',
+ with_fields => {
+ title => 'Test Report',
+ detail => 'Test report details.',
+ }
+ }, "submit good details");
+ $mech->content_contains('Thank you');
+
+ my $report = FixMyStreet::DB->resultset("Problem")->search({}, { order_by => { -desc => 'id' } })->first;
+ ok $report, "Found the report";
+
+ is $report->state, 'confirmed', "report confirmed";
+ is $report->bodies_str, $body->id;
+ is $report->name, 'Anonymous Category';
+ is $report->anonymous, 1; # Doesn't change behaviour here, but uses anon account's name always
+ is $report->get_extra_metadata('contributed_as'), 'anonymous_user';
+};
+
+};
+
+done_testing();
diff --git a/t/app/controller/report_new_errors.t b/t/app/controller/report_new_errors.t
new file mode 100644
index 000000000..f45f13c1e
--- /dev/null
+++ b/t/app/controller/report_new_errors.t
@@ -0,0 +1,745 @@
+use FixMyStreet::TestMech;
+use Path::Tiny;
+
+# 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 -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, '/', "went to /";
+ is_deeply { $mech->uri->query_form }, {}, "query empty";
+
+ 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";
+
+ $mech->get_ok('/report/new?pc_override=SW1A%201AA&latitude=51&longitude=-2');
+ is $mech->uri->path, '/around', "went to /around";
+ is_deeply { $mech->uri->query_form }, { pc => 'SW1A 1AA' },
+ "pc correctly transferred, lat/lon gone";
+ };
+};
+
+my %body_ids;
+for my $body (
+ { area_id => 2226, name => 'Gloucestershire County Council' },
+ { area_id => 2504, name => 'Westminster City Council' },
+ { area_id => 2482, name => 'Bromley Council' },
+ { area_id => 2217, name => 'Buckinghamshire Council' },
+ { area_id => 2232, name => 'Lincolnshire County Council' },
+ { area_id => 2237, name => 'Oxfordshire County Council' },
+ { area_id => 2600, name => 'Rutland County Council' },
+ { area_id => 2234, name => 'Northamptonshire County Council' },
+ { area_id => 2566, name => 'Peterborough City Council' },
+) {
+ my $body_obj = $mech->create_body_ok($body->{area_id}, $body->{name});
+ $body_ids{$body->{area_id}} = $body_obj->id;
+}
+
+# Let's make some contacts to send things to!
+$mech->create_contact_ok(
+ body_id => $body_ids{2226}, # Gloucestershire
+ category => 'Potholes',
+ email => 'potholes@example.com',
+);
+$mech->create_contact_ok(
+ body_id => $body_ids{2482}, # Bromley
+ category => 'Trees',
+ email => 'trees@example.com',
+);
+$mech->create_contact_ok(
+ body_id => $body_ids{2504},
+ category => 'Street lighting',
+ email => 'highways@example.com'
+);
+$mech->create_contact_ok(
+ body_id => $body_ids{2226}, # Gloucestershire
+ category => 'Street lighting',
+ email => 'streetlights-2226@example.com',
+);
+$mech->create_contact_ok(
+ body_id => $body_ids{2217}, # Buckinghamshire
+ category => 'Street lighting',
+ email => 'streetlights-2217@example.com',
+);
+$mech->create_contact_ok(
+ body_id => $body_ids{2232}, # Lincolnshire
+ category => 'Trees',
+ email => 'trees-2232@example.com',
+);
+$mech->create_contact_ok(
+ body_id => $body_ids{2237}, # Oxfordshire
+ category => 'Trees',
+ email => 'trees-2247@example.com',
+);
+$mech->create_contact_ok(
+ body_id => $body_ids{2600}, # Rutland
+ category => 'Trees',
+ email => 'trees-2600@example.com',
+);
+$mech->create_contact_ok(
+ body_id => $body_ids{2234}, # Northamptonshire
+ category => 'Trees',
+ email => 'trees-2234@example.com',
+);
+$mech->create_contact_ok(
+ body_id => $body_ids{2566}, # Peterborough
+ category => 'Trees',
+ email => 'trees-2566@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',
+ username => '',
+ phone => '',
+ password_sign_in => '',
+ password_register => '',
+ },
+ 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',
+ username => '',
+ phone => '',
+ category => 'Something bad',
+ password_sign_in => '',
+ password_register => '',
+ },
+ 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 => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => '',
+ may_show_name => '1',
+ username => '',
+ phone => '',
+ category => 'Street lighting',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => {},
+ errors => [
+ 'Please enter a subject',
+ 'Please enter some details',
+ 'Please enter your email',
+ 'Please enter your name',
+ ],
+ },
+ {
+ msg => 'may_show_name is remembered',
+ pc => 'SW1A 1AA',
+ fields => {
+ title => '',
+ detail => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => '',
+ may_show_name => undef,
+ username => '',
+ phone => '',
+ category => 'Street lighting',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => {},
+ errors => [
+ 'Please enter a subject',
+ 'Please enter some details',
+ 'Please enter your email',
+ 'Please enter your name',
+ ],
+ },
+ {
+ msg => 'may_show_name unchanged if name is present (stays false)',
+ pc => 'SW1A 1AA',
+ fields => {
+ title => '',
+ detail => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => 'Bob Jones',
+ may_show_name => undef,
+ username => '',
+ phone => '',
+ category => 'Street lighting',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => {},
+ errors => [
+ 'Please enter a subject',
+ 'Please enter some details',
+ 'Please enter your email',
+ ],
+ },
+ {
+ msg => 'may_show_name unchanged if name is present (stays true)',
+ pc => 'SW1A 1AA',
+ fields => {
+ title => '',
+ detail => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => 'Bob Jones',
+ may_show_name => '1',
+ username => '',
+ phone => '',
+ category => 'Street lighting',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => {},
+ errors => [
+ 'Please enter a subject',
+ 'Please enter some details',
+ 'Please enter your email',
+ ],
+ },
+ {
+ msg => 'title and details tidied up',
+ pc => 'SW1A 1AA',
+ fields => {
+ title => "DOG SHIT\r\nON WALLS",
+ detail => "on this portakabin -\r\n\r\nmore of a portaloo HEH!!",
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => 'Bob Jones',
+ may_show_name => '1',
+ username => '',
+ phone => '',
+ category => 'Street lighting',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => {
+ title => 'Dog poo on walls',
+ detail =>
+ "On this [portable cabin] -\n\nMore of a [portable loo] HEH!!",
+ },
+ errors => [ 'Please enter your email', ],
+ },
+ {
+ msg => 'name too short',
+ pc => 'SW1A 1AA',
+ fields => {
+ title => 'Test title',
+ detail => 'Test detail',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => 'DUDE',
+ may_show_name => '1',
+ username => '',
+ phone => '',
+ category => 'Street lighting',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => {},
+ errors => [
+ 'Please enter your email',
+'Please enter your full name, councils need this information – if you do not wish your name to be shown on the site, untick the box below',
+ ],
+ },
+ {
+ msg => 'name is anonymous',
+ pc => 'SW1A 1AA',
+ fields => {
+ title => 'Test title',
+ detail => 'Test detail',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => 'anonymous',
+ may_show_name => '1',
+ username => '',
+ phone => '',
+ category => 'Street lighting',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => {},
+ errors => [
+ 'Please enter your email',
+'Please enter your full name, councils need this information – if you do not wish your name to be shown on the site, untick the box below',
+ ],
+ },
+ {
+ msg => 'email invalid',
+ pc => 'SW1A 1AA',
+ fields => {
+ title => 'Test title',
+ detail => 'Test detail',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => 'Joe Smith',
+ may_show_name => '1',
+ username => 'not an email',
+ phone => '',
+ category => 'Street lighting',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => { username => 'notanemail' },
+ errors => [ 'Please enter a valid email', ],
+ },
+ {
+ msg => 'cleanup title and detail',
+ pc => 'SW1A 1AA',
+ fields => {
+ title => " Test title ",
+ detail => " first line \n\n second\nline\n\n ",
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => '',
+ may_show_name => '1',
+ username => '',
+ phone => '',
+ category => 'Street lighting',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => {
+ title => 'Test title',
+ detail => "First line\n\nSecond line",
+ },
+ errors => [
+ 'Please enter your email',
+ 'Please enter your name',
+ ],
+ },
+ {
+ msg => 'clean up name and email',
+ pc => 'SW1A 1AA',
+ fields => {
+ title => '',
+ detail => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => ' Bob Jones ',
+ may_show_name => '1',
+ username => ' BOB @ExAmplE.COM ',
+ phone => '',
+ category => 'Street lighting',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => {
+ name => 'Bob Jones',
+ username => 'bob@example.com',
+ },
+ errors => [ 'Please enter a subject', 'Please enter some details', ],
+ },
+ {
+ msg => 'non-photo upload gives error',
+ pc => 'SW1A 1AA',
+ fields => {
+ title => 'Title',
+ detail => 'Detail',
+ photo1 => [ [ undef, 'bad.txt', Content => 'This is not a JPEG', Content_Type => 'text/plain' ], 1 ],
+ photo2 => '',
+ photo3 => '',
+ name => 'Bob Jones',
+ may_show_name => '1',
+ username => 'bob@example.com',
+ phone => '',
+ category => 'Street lighting',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => {
+ photo1 => '',
+ },
+ errors => [ "Please upload an image only" ],
+ },
+ {
+ msg => 'bad photo upload gives error',
+ pc => 'SW1A 1AA',
+ fields => {
+ title => 'Title',
+ detail => 'Detail',
+ photo1 => [ [ undef, 'fake.jpeg', Content => 'This is not a JPEG', Content_Type => 'image/jpeg' ], 1 ],
+ photo2 => '',
+ photo3 => '',
+ name => 'Bob Jones',
+ may_show_name => '1',
+ username => 'bob@example.com',
+ phone => '',
+ category => 'Street lighting',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => {
+ photo1 => '',
+ },
+ 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',
+ pc => 'SW1A 1AA',
+ fields => {
+ title => '',
+ detail => 'Detail',
+ photo1 => [ [ $sample_file, undef, Content_Type => 'application/octet-stream' ], 1 ],
+ photo2 => '',
+ photo3 => '',
+ name => 'Bob Jones',
+ may_show_name => '1',
+ username => 'bob@example.com',
+ phone => '',
+ category => 'Street lighting',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => {
+ photo1 => '',
+ },
+ errors => [ "Please enter a subject" ],
+ },
+ {
+ msg => 'email in title',
+ pc => 'SW1A 1AA',
+ fields => {
+ title => 'user@example.com',
+ detail => 'Test detail',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => 'Joe Smith',
+ may_show_name => '1',
+ username => 'user@example.com',
+ phone => '',
+ category => 'Street lighting',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => {
+ username => 'user@example.com',
+ title => 'User@example.com'
+ },
+ errors => [ 'Please make sure you are not including an email address', ],
+ },
+ {
+ msg => 'Bromley long detail',
+ pc => 'BR1 3UH',
+ fields => {
+ fms_extra_title => 'MR',
+ title => '',
+ detail => 'X' . 'x' x 1751,
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => 'Bob Example',
+ may_show_name => '1',
+ username => 'bob@example.com',
+ phone => '',
+ category => 'Trees',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => { },
+ errors => [ 'Please enter a subject', 'Reports are limited to 1750 characters in length. Please shorten your report' ],
+ },
+ {
+ msg => 'Oxfordshire long detail',
+ pc => 'OX20 1SZ',
+ fields => {
+ title => '',
+ detail => 'X' . 'x' x 1701,
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => 'Bob Example',
+ may_show_name => '1',
+ username => 'bob@example.com',
+ phone => '',
+ category => 'Trees',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => { },
+ errors => [ 'Please enter a subject', 'Reports are limited to 1700 characters in length. Please shorten your report' ],
+ },
+ {
+ msg => 'Lincolnshire long phone',
+ pc => 'PE9 2GX',
+ fields => {
+ title => '',
+ detail => 'Detail',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => 'Bob Example',
+ may_show_name => '1',
+ username => 'bob@example.com',
+ phone => '123456789 12345678910',
+ category => 'Trees',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => { },
+ errors => [ 'Please enter a subject', 'Phone numbers are limited to 20 characters in length.' ],
+ },
+ {
+ msg => 'Buckinghamshire long name',
+ pc => 'RG9 6TL',
+ fields => {
+ title => '',
+ detail => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => 'This is a very long name that should fail validation',
+ may_show_name => '1',
+ username => 'bob@example.com',
+ phone => '',
+ category => 'Street lighting',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => { },
+ errors => [ 'Please enter a subject', 'Please enter some details', 'Names are limited to 50 characters in length.' ],
+ },
+ {
+ msg => 'Rutland long name',
+ pc => 'LE15 0GJ',
+ fields => {
+ title => '',
+ detail => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => 'This is a very long name that should fail validation',
+ may_show_name => '1',
+ username => 'bob@example.com',
+ phone => '',
+ category => 'Trees',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => { },
+ errors => [ 'Please enter a subject', 'Please enter some details', 'Names are limited to 40 characters in length.' ],
+ },
+ {
+ msg => 'Oxfordshire validation',
+ pc => 'OX20 1SZ',
+ fields => {
+ title => '',
+ detail => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => 'This is a really extraordinarily long name that definitely should fail validation',
+ may_show_name => '1',
+ username => 'bob.has.a.very.long.email@thisisalonghostname.example.com',
+ phone => '01234 5678910 09876 54321 ext 203',
+ category => 'Trees',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => { },
+ errors => [ 'Please enter a subject', 'Please enter some details', 'Emails are limited to 50 characters in length.', 'Phone numbers are limited to 20 characters in length.', 'Names are limited to 50 characters in length.'],
+ },
+ {
+ msg => 'Northamptonshire validation',
+ pc => 'NN1 1NS',
+ fields => {
+ title => 'This is a very long title that should fail the validation as it is really much too long to pass the validation of 120 characters',
+ detail => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => 'A User',
+ may_show_name => '1',
+ username => 'user@example.org',
+ phone => '',
+ category => 'Trees',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => { },
+ errors => [ 'Summaries are limited to 120 characters in length. Please shorten your summary', 'Please enter some details'],
+ },
+ {
+ msg => 'Peterborough validation',
+ pc => 'PE1 1HF',
+ fields => {
+ title => 'This is a very long title that should fail the validation',
+ detail => '',
+ photo1 => '',
+ photo2 => '',
+ photo3 => '',
+ name => 'A User',
+ may_show_name => '1',
+ username => 'user@example.org',
+ phone => '',
+ category => 'Trees',
+ password_sign_in => '',
+ password_register => '',
+ },
+ changes => { },
+ errors => [ 'Summaries are limited to 50 characters in length. Please shorten your summary', 'Please enter some details'],
+ },
+ )
+{
+ subtest "check form errors where $test->{msg}" => sub {
+ $mech->get_ok('/around');
+
+ # submit initial pc form
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' }, 'bromley', 'oxfordshire', 'rutland', 'lincolnshire', 'buckinghamshire', 'northamptonshire', 'peterborough' ],
+ 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 [ sort @{$mech->page_errors} ], [ sort @{$test->{errors}} ], "check errors";
+
+ # check that fields have changed as expected
+ my $new_values = {
+ %{ $test->{fields} }, # values added to form
+ %{ $test->{changes} }, # changes we expect
+ };
+ is_deeply $mech->visible_form_values, $new_values,
+ "values correctly changed";
+ };
+}
+
+# this test to make sure that we don't see spurious error messages about
+# the name being blank when there is a sign in error
+subtest "test password errors for a user who is signing in as they report" => sub {
+ my $user = $mech->create_user_ok('test-2@example.com',
+ name => 'Joe Bloggs',
+ phone => '01234 567 890',
+ password => 'secret2',
+ phone_verified => 1,
+ );
+
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok('/around?pc=GL50+2PR');
+ $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.',
+ photo1 => '',
+ username => '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, [
+ "There was a problem with your login information. If you cannot remember your password, or do not have one, please fill in the \x{2018}No\x{2019} section of the form.",
+ ], "check there were errors";
+
+ $mech->content_lacks('1234 567', 'phone number not shown');
+};
+
+subtest "check that a lat/lon off coast leads to /around" => sub {
+ my $off_coast_latitude = 50.78301;
+ my $off_coast_longitude = -0.646929;
+
+ 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'";
+
+ is_deeply
+ $mech->page_errors,
+ [ 'That location does not appear to be covered by a council; perhaps it is offshore or outside the country. Please try again.' ],
+ "Found location error";
+
+};
+
+done_testing;
diff --git a/t/app/controller/report_new_mobile.t b/t/app/controller/report_new_mobile.t
index 296007ce3..def140a72 100644
--- a/t/app/controller/report_new_mobile.t
+++ b/t/app/controller/report_new_mobile.t
@@ -15,21 +15,20 @@ subtest "Check signed up for alert when logged in" => sub {
MAPIT_URL => 'http://mapit.zurich',
MAPIT_TYPES => [ 'O08' ],
}, sub {
- $mech->log_in_ok('user@example.org');
+ my $user = $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',
+ email => $user->email,
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';
};
diff --git a/t/app/controller/report_new_open311.t b/t/app/controller/report_new_open311.t
index dc9a26791..08435fb2b 100644
--- a/t/app/controller/report_new_open311.t
+++ b/t/app/controller/report_new_open311.t
@@ -1,5 +1,4 @@
use FixMyStreet::TestMech;
-use FixMyStreet::App;
use Test::LongString;
use Web::Scraper;
@@ -9,7 +8,7 @@ END { FixMyStreet::App->log->enable('info'); }
my $mech = FixMyStreet::TestMech->new;
-my $body = $mech->create_body_ok(2245, 'Wiltshire Council');
+my $body = $mech->create_body_ok(2608, 'Borsetshire Council');
$body->update({
endpoint => 'http://example.com/open311',
jurisdiction => 'mySociety',
@@ -45,6 +44,7 @@ $mech->create_contact_ok(
category => 'Ball lighting',
email => '102',
extra => { _fields => [
+ { description => 'Message', code => 'message', required => 'false', variable => 'false', order => '0' },
{ description => 'Size', code => 'size', required => 'True', automated => '' },
{ description => 'Speed', code => 'speed', required => 'True', automated => 'server_set' },
{ description => 'Colour', code => 'colour', required => 'True', automated => 'hidden_field' },
@@ -61,6 +61,42 @@ my $contact4 = $mech->create_contact_ok(
{ description => 'Asset ID', code => 'central_asset_id', required => 'true', automated => 'hidden_field', variable => 'true', order => '2' },
] },
);
+# Another one to switch to in disable form test
+$mech->create_contact_ok(
+ body_id => $body2->id, # Edinburgh
+ category => 'Something Other',
+ email => '104',
+);
+$mech->create_contact_ok(
+ body_id => $body2->id, # Edinburgh
+ category => 'Abandoned vehicle',
+ email => '105',
+ extra => { _fields => [
+ { description => 'This is a warning message.', code => 'notice', required => 'false', variable => 'false', order => '0' },
+ { description => 'USRN', code => 'usrn', required => 'false', automated => 'hidden_field' },
+ ] },
+);
+$mech->create_contact_ok(
+ body_id => $body2->id, # Edinburgh
+ category => 'Traffic signals',
+ email => '106',
+ extra => { _fields => [
+ { description => 'This is a warning message for traffic signals.', code => 'notice', required => 'false', variable => 'false', order => '0' },
+ ] },
+);
+
+my $staff_user = $mech->create_user_ok('staff@example.org', name => 'staff', from_body => $body->id);
+
+my $body3 = $mech->create_body_ok(2234, 'Northamptonshire County Council');
+my $ncc_staff_user = $mech->create_user_ok('ncc_staff@example.org', name => 'ncc staff', from_body => $body3->id);
+$mech->create_contact_ok(
+ body_id => $body3->id,
+ category => 'Flooding',
+ email => '104',
+ extra => { _fields => [
+ { description => 'Please ring us!', code => 'ring', variable => 'false', order => '0', disable_form => 'true' }
+ ] },
+);
# test that the various bit of form get filled in and errors correctly
# generated.
@@ -166,7 +202,7 @@ foreach my $test (
# check that the user does not exist
my $test_email = $test->{submit_with}->{username};
- my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
if ( $user ) {
$user->problems->delete;
$user->comments->delete;
@@ -196,6 +232,8 @@ foreach my $test (
# check that we got the errors expected
is_deeply $mech->page_errors, $test->{errors}, "check errors";
+ $mech->content_contains('Help <strong>Borsetshire Council</strong> resolve your problem quicker');
+
# check that fields have changed as expected
my $new_values = {
%{ $test->{fields} }, # values added to form
@@ -230,7 +268,7 @@ foreach my $test (
$mech->submit_form_ok( { with_fields => $new_values } );
};
- $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } );
+ $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } );
ok $user, 'created user';
my $prob = $user->problems->first;
ok $prob, 'problem created';
@@ -262,6 +300,42 @@ subtest "Category extras omits description label when all fields are hidden" =>
};
};
+subtest "Category extras omits preamble when all fields are notices" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ for (
+ { url => '/report/new/ajax?' },
+ { url => '/report/new/category_extras?category=Traffic+signals' },
+ ) {
+ my $json = $mech->get_ok_json($_->{url} . '&latitude=55.952055&longitude=-3.189579');
+ my $category_extra = $json->{by_category} ? $json->{by_category}{'Traffic signals'}{category_extra} : $json->{category_extra};
+ contains_string($category_extra, "This is a warning message for traffic signals.");
+ lacks_string($category_extra, "resolve your problem quicker, by providing some extra detail", "Lacks description text");
+ }
+ };
+};
+
+subtest "Category extras omits preamble when fields are only notices and hidden" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ for (
+ { url => '/report/new/ajax?' },
+ { url => '/report/new/category_extras?category=Abandoned+vehicle' },
+ ) {
+ my $json = $mech->get_ok_json($_->{url} . '&latitude=55.952055&longitude=-3.189579');
+ my $category_extra = $json->{by_category} ? $json->{by_category}{'Abandoned vehicle'}{category_extra} : $json->{category_extra};
+ contains_string($category_extra, "This is a warning message.");
+ contains_string($category_extra, "usrn");
+ lacks_string($category_extra, "USRN", "Lacks 'USRN' label");
+ lacks_string($category_extra, "resolve your problem quicker, by providing some extra detail", "Lacks description text");
+ }
+ };
+};
+
subtest "Category extras includes description label for user" => sub {
FixMyStreet::override_config {
ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
@@ -286,4 +360,138 @@ subtest "Category extras includes description label for user" => sub {
};
};
+subtest "Category extras are correct even if category has an ampersand in it" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => [ { fixmystreet => '.' } ],
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ for (
+ { url => '/report/new/ajax?' },
+ { url => '/report/new/category_extras?category=Potholes+%26+Road+Defects' },
+ ) {
+ my $category = "Potholes & Road Defects";
+ $contact4->update({ category => $category });
+ my $json = $mech->get_ok_json($_->{url} . '&latitude=55.952055&longitude=-3.189579');
+ my $category_extra = $json->{by_category} ? $json->{by_category}{$category}{category_extra} : $json->{category_extra};
+ contains_string($category_extra, "usrn") or diag $mech->content;
+ contains_string($category_extra, "central_asset_id");
+ lacks_string($category_extra, "USRN", "Lacks 'USRN' label");
+ lacks_string($category_extra, "Asset ID", "Lacks 'Asset ID' label");
+ contains_string($category_extra, "Size?");
+ lacks_string($category_extra, '<option value=""');
+ contains_string($category_extra, "resolve your problem quicker, by providing some extra detail", "Contains description text");
+ $contact4->update({ category => "Pothole" });
+ }
+ };
+};
+
+subtest "Category extras includes form disabling string" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $contact4->push_extra_fields({ description => 'Please ring us!', code => 'ring', variable => 'false', order => '0', disable_form => 'true' });
+ $contact4->push_extra_fields({ datatype_description => 'Please please ring', description => 'Is it dangerous?', code => 'dangerous',
+ variable => 'true', order => '0', values => [ { name => 'Yes', key => 'yes', disable => 1 }, { name => 'No', key => 'no' } ]
+ });
+ $contact4->update;
+ for (
+ { url => '/report/new/ajax?' },
+ { url => '/report/new/category_extras?category=Pothole' },
+ ) {
+ my $json = $mech->get_ok_json($_->{url} . '&latitude=55.952055&longitude=-3.189579');
+ my $output = $json->{by_category} ? $json->{by_category}{Pothole}{disable_form} : $json->{disable_form};
+ is_deeply $output, {
+ all => 'Please ring us!',
+ questions => [
+ {
+ message => 'Please please ring',
+ code => 'dangerous',
+ answers => [ 'yes' ],
+ },
+ ],
+ };
+ }
+
+ # Test new non-JS form disabling flow
+ $mech->get_ok('/report/new?latitude=55.952055&longitude=-3.189579');
+ $mech->content_contains('name="submit_category_part_only"');
+ $mech->submit_form_ok({ with_fields => { category => 'Pothole' } });
+ $mech->content_contains('<div id="js-category-stopper" class="box-warning" role="alert" aria-live="assertive">');
+ $mech->content_contains('Please ring us!');
+ # Switch to another, okay, category
+ $mech->submit_form_ok({ with_fields => { category => 'Something Other' } });
+ $mech->content_lacks('<div id="js-category-stopper" class="box-warning" role="alert" aria-live="assertive">');
+ $mech->content_lacks('Please ring us!');
+
+ # Remove the required extra field so its error checking doesn't get in the way
+ my $extra = $contact4->get_extra_fields;
+ @$extra = grep { $_->{code} ne 'size' } @$extra;
+ $contact4->set_extra_fields(@$extra);
+ $contact4->update;
+
+ # Test submission of whole form, switching back to a blocked category at the same time
+ $mech->submit_form_ok({ with_fields => {
+ category => 'Pothole', title => 'Title', detail => 'Detail',
+ username => 'testing@example.org', name => 'Testing Example',
+ } });
+ $mech->content_contains('<div id="js-category-stopper" class="box-warning" role="alert" aria-live="assertive">');
+ $mech->content_contains('Please ring us!');
+
+ # Test special answer disabling of form
+ $extra = $contact4->get_extra_fields;
+ @$extra = grep { $_->{code} ne 'ring' } @$extra; # Remove that all-category one
+ $contact4->set_extra_fields(@$extra);
+ $contact4->update;
+ $mech->get_ok('/report/new?latitude=55.952055&longitude=-3.189579');
+ $mech->content_contains('name="submit_category_part_only"');
+ $mech->submit_form_ok({ with_fields => { category => 'Pothole' } });
+ $mech->content_contains('name="submit_category_part_only"');
+ $mech->submit_form_ok({ with_fields => { dangerous => 'no' } });
+ $mech->content_lacks('<div id="js-category-stopper" class="box-warning" role="alert" aria-live="assertive">');
+ $mech->content_lacks('Please please ring');
+ $mech->submit_form_ok({ with_fields => { dangerous => 'yes' } });
+ $mech->content_contains('<div id="js-category-stopper" class="box-warning" role="alert" aria-live="assertive">');
+ $mech->content_contains('Please please ring');
+ };
+};
+
+subtest "Staff users still see disable form categories" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'borsetshire',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+
+ $mech->log_in_ok($staff_user->email);
+
+ $contact2->push_extra_fields({ description => 'Please ring us!', code => 'ring', variable => 'false', order => '0', disable_form => 'true' });
+ $contact2->update;
+
+ # Test new non-JS form disabling flow
+ $mech->get_ok('/report/new?latitude=51.496194&longitude=-2.603439');
+ $mech->submit_form_ok({ with_fields => { category => 'Graffiti Removal' } });
+ $mech->content_contains('<div id="js-category-stopper" class="box-warning" role="alert" aria-live="assertive">');
+ $mech->content_contains('Please ring us!');
+ };
+};
+
+subtest "Staff users disable form categories" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'northamptonshire',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->log_out_ok;
+ $mech->log_in_ok($ncc_staff_user->email);
+
+ $mech->get_ok('/report/new?latitude=52.236251&longitude=-0.892052');
+ $mech->submit_form_ok({ with_fields => {
+ category => 'Flooding', title => 'Title', detail => 'Detail',
+ } });
+
+ my $prob = $ncc_staff_user->problems->first;
+ ok $prob, 'problem created';
+ is $prob->title, "Title", 'Report title correct';
+ };
+};
+
done_testing();
diff --git a/t/app/controller/report_new_staff.t b/t/app/controller/report_new_staff.t
new file mode 100644
index 000000000..3817cdf3a
--- /dev/null
+++ b/t/app/controller/report_new_staff.t
@@ -0,0 +1,268 @@
+use FixMyStreet::TestMech;
+
+# 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_ids;
+for my $body (
+ { area_id => 2651, name => 'City of Edinburgh Council' },
+ { area_id => 2482, name => 'Bromley Council' },
+ { area_id => 2237, name => 'Oxfordshire County Council' },
+) {
+ my $body_obj = $mech->create_body_ok($body->{area_id}, $body->{name});
+ $body_ids{$body->{area_id}} = $body_obj->id;
+}
+
+# Let's make some contacts to send things to!
+$mech->create_contact_ok( body_id => $body_ids{2651}, category => 'Street lighting', email => 'highways@example.com' );
+my $edin_trees = $mech->create_contact_ok( body_id => $body_ids{2651}, category => 'Trees', email => 'trees@example.com' );
+$mech->create_contact_ok( body_id => $body_ids{2482}, category => 'Trees', email => 'trees@example.com' );
+$mech->create_contact_ok( body_id => $body_ids{2237}, category => 'Trees', email => 'trees-2247@example.com' );
+
+my $private_perms = $mech->create_user_ok('private_perms@example.org', name => 'private', from_body => $body_ids{2651});
+subtest "report_mark_private allows users to mark reports as private" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ BASE_URL => 'https://www.fixmystreet.com',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->log_out_ok;
+
+ $private_perms->user_body_permissions->find_or_create({
+ body_id => $body_ids{2651},
+ permission_type => 'report_mark_private',
+ });
+
+ $mech->log_in_ok('private_perms@example.org');
+ $mech->get_ok('/');
+ $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 $edin_cats = $mech->create_contact_ok( body_id => $body_ids{2651}, category => 'Cats', email => 'cats@example.com', non_public => 1 );
+ $mech->submit_form_ok({
+ button => 'submit_category_part_only',
+ with_fields => { category => 'Cats' }
+ });
+ $mech->content_contains('id="form_non_public" value="1" checked disabled');
+ $edin_cats->delete;
+
+ $mech->submit_form_ok(
+ {
+ with_fields => {
+ title => "Private report",
+ detail => 'Private report details.',
+ photo1 => '',
+ name => 'Joe Bloggs',
+ may_show_name => '1',
+ phone => '07903 123 456',
+ category => 'Trees',
+ non_public => 1,
+ }
+ },
+ "submit good details"
+ );
+
+ $mech->content_contains('Great work. Now spread the word', 'shown confirmation page');
+ }
+};
+
+my $inspector = $mech->create_user_ok('inspector@example.org', name => 'inspector', from_body => $body_ids{2651});
+foreach my $test (
+ { non_public => 0 },
+ { non_public => 1 },
+) {
+ subtest "inspectors get redirected directly to the report page, non_public=$test->{non_public}" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ BASE_URL => 'https://www.fixmystreet.com',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->log_out_ok;
+
+ $inspector->user_body_permissions->find_or_create({
+ body_id => $body_ids{2651},
+ permission_type => 'planned_reports',
+ });
+ $inspector->user_body_permissions->find_or_create({
+ body_id => $body_ids{2651},
+ permission_type => 'report_inspect',
+ });
+
+ $mech->log_in_ok('inspector@example.org');
+ $mech->get_ok('/');
+ $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 => "Inspector report",
+ detail => 'Inspector report details.',
+ photo1 => '',
+ name => 'Joe Bloggs',
+ may_show_name => '1',
+ phone => '07903 123 456',
+ category => 'Trees',
+ non_public => $test->{non_public},
+ }
+ },
+ "submit good details"
+ );
+
+ like $mech->uri->path, qr/\/report\/[0-9]+/, 'Redirects directly to report';
+ }
+ };
+}
+
+subtest "check map click ajax response for inspector" => sub {
+ $mech->log_out_ok;
+
+ my $extra_details;
+ $inspector->user_body_permissions->find_or_create({
+ body_id => $body_ids{2651},
+ permission_type => 'planned_reports',
+ });
+ $inspector->user_body_permissions->find_or_create({
+ body_id => $body_ids{2651},
+ permission_type => 'report_inspect',
+ });
+
+ $mech->log_in_ok('inspector@example.org');
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=55.952055&longitude=-3.189579' );
+ };
+ like $extra_details->{category}, qr/data-prefill="0/, 'inspector prefill not set';
+ ok !$extra_details->{contribute_as}, 'no contribute as section';
+};
+
+subtest "check map click ajax response for inspector and uk cobrand" => sub {
+ $mech->log_out_ok;
+
+ my $extra_details;
+ $inspector->user_body_permissions->find_or_create({
+ body_id => $body_ids{2482},
+ permission_type => 'planned_reports',
+ });
+ $inspector->user_body_permissions->find_or_create({
+ body_id => $body_ids{2482},
+ permission_type => 'report_inspect',
+ });
+
+ $mech->log_in_ok('inspector@example.org');
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'bromley',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=51.402096&longitude=0.015784' );
+ };
+ like $extra_details->{category}, qr/data-prefill="0/, 'inspector prefill not set';
+};
+
+for my $test (
+ {
+ desc => 'map click ajax for contribute_as_another_user',
+ permissions => {
+ contribute_as_another_user => 1,
+ contribute_as_anonymous_user => undef,
+ contribute_as_body => undef,
+ }
+ },
+ {
+ desc => 'map click ajax for contribute_as_anonymous_user',
+ permissions => {
+ contribute_as_another_user => undef,
+ contribute_as_anonymous_user => 1,
+ contribute_as_body => undef,
+ }
+ },
+ {
+ desc => 'map click ajax for contribute_as_body',
+ permissions => {
+ contribute_as_another_user => undef,
+ contribute_as_anonymous_user => undef,
+ contribute_as_body => 1,
+ }
+ },
+) {
+ subtest $test->{desc} => sub {
+ $mech->log_out_ok;
+ my $extra_details;
+ (my $name = $test->{desc}) =~ s/.*(contri.*)/$1/;
+ my $user = $mech->create_user_ok("$name\@example.org", name => 'test user', from_body => $body_ids{2651});
+ for my $p ( keys %{$test->{permissions}} ) {
+ next unless $test->{permissions}->{$p};
+ $user->user_body_permissions->find_or_create({
+ body_id => $body_ids{2651},
+ permission_type => $p,
+ });
+ }
+ $mech->log_in_ok("$name\@example.org");
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=55.952055&longitude=-3.189579' );
+ };
+ for my $p ( keys %{$test->{permissions}} ) {
+ (my $key = $p) =~ s/contribute_as_//;
+ is $extra_details->{contribute_as}->{$key}, $test->{permissions}->{$p}, "$key correctly set";
+ }
+
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=51.754926&longitude=-1.256179' );
+ };
+ ok !$extra_details->{contribute_as}, 'no contribute as section for other council';
+ };
+}
+
+subtest 'staff-only categories when reporting' => sub {
+ FixMyStreet::override_config {
+ MAPIT_URL => 'http://mapit.uk/',
+ MAPIT_TYPES => ['UTA'],
+ }, sub {
+ $inspector->update({ is_superuser => 1 });
+ $mech->log_in_ok('inspector@example.org');
+
+ $mech->get_ok('/admin/body/' . $body_ids{2651} . '/Trees');
+ $mech->submit_form_ok({ with_fields => { state => 'staff' } }, 'mark Trees as staff-only');
+ $edin_trees->discard_changes;
+ is $edin_trees->state, 'staff', 'category is staff only';
+
+ $mech->get_ok('/admin/templates/' . $body_ids{2651} . '/new');
+ $mech->content_contains('Trees');
+
+ my $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=55.952055&longitude=-3.189579' );
+ is_deeply [ sort keys %{$extra_details->{by_category}} ], [ 'Street lighting', 'Trees' ], 'Superuser can see staff-only category';
+
+ $inspector->update({ is_superuser => 0 });
+ $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=55.952055&longitude=-3.189579' );
+ is_deeply [ sort keys %{$extra_details->{by_category}} ], [ 'Street lighting', 'Trees' ], 'Body staff user can see staff-only category';
+
+ $inspector->update({ from_body => $body_ids{2482} });
+ $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=55.952055&longitude=-3.189579' );
+ is_deeply [ sort keys %{$extra_details->{by_category}} ], [ 'Street lighting' ], 'Different body staff user cannot see staff-only category';
+
+ $mech->log_out_ok;
+ $extra_details = $mech->get_ok_json( '/report/new/ajax?latitude=55.952055&longitude=-3.189579' );
+ is_deeply [ sort keys %{$extra_details->{by_category}} ], [ 'Street lighting' ], 'Normal user cannot see staff-only category';
+ };
+};
+
+done_testing;
diff --git a/t/app/controller/report_new_text.t b/t/app/controller/report_new_text.t
index fad7fb6ab..852cdac76 100644
--- a/t/app/controller/report_new_text.t
+++ b/t/app/controller/report_new_text.t
@@ -110,14 +110,14 @@ foreach my $test (
$mech->log_out_ok;
if ($test->{user}) {
- my $user = FixMyStreet::App->model('DB::User')->find( { phone => $test_phone } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { phone => $test_phone } );
ok $user, "test user does exist";
$user->problems->delete;
$user->name( 'Old Name' );
$user->password( 'old_password' );
$user->update;
} elsif (!$first_user) {
- ok !FixMyStreet::App->model('DB::User')->find( { phone => $test_phone } ),
+ ok !FixMyStreet::DB->resultset('User')->find( { phone => $test_phone } ),
"test user does not exist";
$first_user = 1;
} else {
@@ -153,7 +153,7 @@ foreach my $test (
is_deeply $mech->page_errors, [], "check there were no errors";
- my $user = FixMyStreet::App->model('DB::User')->find( { phone => $test_phone } );
+ my $user = FixMyStreet::DB->resultset('User')->find( { phone => $test_phone } );
ok $user, "user found";
if ($test->{user}) {
is $user->name, 'Old Name', 'name unchanged';
@@ -189,7 +189,7 @@ foreach my $test (
}
# check that the reporter has an alert
- my $alert = FixMyStreet::App->model('DB::Alert')->find( {
+ my $alert = FixMyStreet::DB->resultset('Alert')->find( {
user => $report->user,
alert_type => 'new_updates',
parameter => $report->id,
@@ -300,7 +300,7 @@ subtest "test report creation for a user who is signing in as they report" => su
is $report->bodies_str, $body->id;
is $report->state, 'confirmed', "report is now confirmed";
$mech->get_ok( '/report/' . $report->id );
- my $alert = FixMyStreet::App->model('DB::Alert')->find( {
+ my $alert = FixMyStreet::DB->resultset('Alert')->find( {
user => $report->user,
alert_type => 'new_updates',
parameter => $report->id,
@@ -356,7 +356,7 @@ subtest "test report creation for a user who is logged in" => sub {
$mech->content_contains('Thank you for reporting this issue');
is $report->state, 'confirmed', "report is now confirmed";
$mech->get_ok( '/report/' . $report->id );
- my $alert = FixMyStreet::App->model('DB::Alert')->find( {
+ my $alert = FixMyStreet::DB->resultset('Alert')->find( {
user => $report->user,
alert_type => 'new_updates',
parameter => $report->id,
diff --git a/t/app/controller/report_new_unresponsive.t b/t/app/controller/report_new_unresponsive.t
new file mode 100644
index 000000000..033475c25
--- /dev/null
+++ b/t/app/controller/report_new_unresponsive.t
@@ -0,0 +1,122 @@
+use FixMyStreet::TestMech;
+
+# 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_edin = $mech->create_body_ok(2651, 'City of Edinburgh Council', { send_method => 'Refused' });
+my $body_chelt = $mech->create_body_ok(2326, 'Cheltenham Borough Council');
+$mech->create_contact_ok(body_id => $body_edin->id, category => 'Street lighting', email => 'highways@example.com');
+my $contact = $mech->create_contact_ok(body_id => $body_chelt->id, category => 'Trees', email => 'trees@example.org');
+$mech->create_contact_ok(body_id => $body_edin->id, category => 'Trees', email => 'trees@example.com');
+my $user = $mech->create_user_ok('test-2@example.com');
+
+FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ MAPIT_URL => 'http://mapit.uk/',
+}, sub {
+ subtest "unresponsive body handling, body-level send method" => sub {
+ my $body_id = $body_edin->id;
+ my $extra_details = $mech->get_ok_json('/report/new/ajax?latitude=55.952055&longitude=-3.189579');
+ like $extra_details->{top_message}, qr{Edinburgh.*accept reports.*/unresponsive\?body=$body_id};
+ is_deeply $extra_details->{unresponsive}, { $body_id => 1 }, "unresponsive json set";
+ $extra_details = $mech->get_ok_json('/report/new/category_extras?category=Street%20lighting&latitude=55.952055&longitude=-3.189579');
+ is_deeply $extra_details->{unresponsive}, { $body_id => 1 }, "unresponsive json set";
+
+ make_report('EH1 1BB');
+
+ like $mech->get_text_body_from_email, qr/despite not being sent/i, "correct email sent";
+
+ $user->problems->delete;
+ };
+
+ subtest "unresponsive body handling from mobile app" => sub {
+ $mech->log_out_ok;
+ $mech->post_ok( '/report/new/mobile', {
+ title => "Test Report at café",
+ detail => 'Test report details.',
+ photo1 => '',
+ name => 'Joe Bloggs',
+ email => $user->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';
+
+ 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";
+
+ $body_edin->update({ send_method => undef });
+ $user->problems->delete;
+ };
+
+ subtest "unresponsive body handling, per-category refusing" => sub {
+ $contact->update({ email => 'REFUSED' });
+ my $extra_details = $mech->get_ok_json('/report/new/ajax?latitude=51.896268&longitude=-2.093063');
+ like $extra_details->{by_category}{Trees}{category_extra}, qr/Cheltenham.*Trees.*unresponsive.*category=Trees/s;
+ $extra_details = $mech->get_ok_json('/report/new/category_extras?category=Trees&latitude=51.896268&longitude=-2.093063');
+ is_deeply $extra_details->{unresponsive}, { $body_chelt->id => 1 }, "unresponsive json set";
+
+ make_report('GL50 2PR');
+
+ $contact->update({ email => 'trees@example.org' });
+ };
+
+ subtest "unresponsive body page works" => sub {
+ my $url = "/unresponsive?body=" . $body_edin->id;
+ is $mech->get($url)->code, 404, "page not found";
+ $body_edin->update({ send_method => 'Refused' });
+ $mech->get_ok($url);
+ $mech->content_contains('Edinburgh');
+ $body_edin->update({ send_method => undef });
+
+ $url = "/unresponsive?body=" . $body_chelt->id . ";category=Trees";
+ is $mech->get($url)->code, 404, "page not found";
+ $contact->update({ email => 'REFUSED' });
+ $mech->get_ok($url);
+ $mech->content_contains('Cheltenham');
+ $mech->content_contains('Trees');
+ };
+};
+
+done_testing;
+
+sub make_report {
+ my $pc = shift;
+ $mech->get_ok('/around');
+ $mech->submit_form_ok( { with_fields => { pc => $pc } }, "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',
+ username => $user->email,
+ may_show_name => '1',
+ phone => '07903 123 456',
+ category => 'Trees',
+ }
+ },
+ "submit good details"
+ );
+
+ my $report = $user->problems->first;
+ ok $report, "Found the report";
+ is $report->bodies_str, undef, "Report not going anywhere";
+}
diff --git a/t/app/controller/report_new_update.t b/t/app/controller/report_new_update.t
new file mode 100644
index 000000000..cbb31cea4
--- /dev/null
+++ b/t/app/controller/report_new_update.t
@@ -0,0 +1,71 @@
+use FixMyStreet::TestMech;
+
+# disable info logs for this test run
+FixMyStreet::App->log->disable('info');
+END { FixMyStreet::App->log->enable('info'); }
+
+my $mech = FixMyStreet::TestMech->new;
+
+my $comment_user = $mech->create_user_ok('systemuser@example.org', name => 'Glos Council');
+my $body = $mech->create_body_ok(2226, 'Gloucestershire County Council', {
+ comment_user => $comment_user,
+});
+
+$mech->create_contact_ok(
+ body_id => $body->id,
+ category => 'Potholes',
+ email => 'potholes@example.com',
+);
+
+my $user = $mech->log_in_ok('test-2@example.com');
+
+subtest "test report creation with no initial auto-update" => sub {
+ my $report = make_report();
+ my $comment = FixMyStreet::DB->resultset('Comment')->count;
+ is $comment, 0, 'No comments left';
+ $report->delete;
+};
+
+my $template = FixMyStreet::DB->resultset("ResponseTemplate")->create({
+ body => $body,
+ state => 'confirmed',
+ title => 'Initial email response',
+ text => 'Thanks for your report. We will investigate within 5 working days.',
+ auto_response => 1,
+});
+ok $template, 'Template created';
+
+subtest "test report creation with initial auto-update" => sub {
+ my $report = make_report();
+ my $comment = FixMyStreet::DB->resultset('Comment')->single;
+ is $comment->text, 'Thanks for your report. We will investigate within 5 working days.';
+ is $comment->problem->id, $report->id;
+ is $comment->user->id, $comment_user->id;
+ is $comment->external_id, 'auto-internal';
+ is $comment->name, 'Glos Council';
+};
+
+done_testing;
+
+sub make_report {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->get_ok('/around?pc=GL50+2PR');
+ $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",
+ detail => 'Test report details.',
+ name => 'Joe Bloggs',
+ category => 'Potholes',
+ }
+ }, "submit good details");
+ };
+
+ my $report = $user->problems->first;
+ ok $report, "Found the report";
+
+ return $report;
+}
diff --git a/t/app/controller/report_non_public.t b/t/app/controller/report_non_public.t
new file mode 100644
index 000000000..d1aa1943c
--- /dev/null
+++ b/t/app/controller/report_non_public.t
@@ -0,0 +1,87 @@
+use FixMyStreet::TestMech;
+
+# 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');
+$mech->create_contact_ok( body_id => $body->id, category => 'Potholes', email => 'potholes@example.com' );
+
+my $staffuser = $mech->create_user_ok('body-user@example.net', name => 'Body User', from_body => $body->id);
+$staffuser->user_body_permissions->create({ body => $body, permission_type => 'contribute_as_another_user' });
+$staffuser->user_body_permissions->create({ body => $body, permission_type => 'report_mark_private' });
+
+my $user = $mech->create_user_ok('test@example.com', name => 'Test User');
+my $user2 = $mech->create_user_ok('test2@example.com', name => 'Other User');
+
+my ($report) = $mech->create_problems_for_body(1, $body->id, "Example", {
+ user => $user,
+ non_public => 1,
+});
+my $report_id = $report->id;
+
+subtest "check cannot view non_public report by default" => sub {
+ ok $mech->get("/report/$report_id"), "get '/report/$report_id'";
+ is $mech->res->code, 403, "access denied";
+ is $mech->uri->path, "/report/$report_id", "at /report/$report_id";
+ $mech->content_contains('permission to do that. If you are the problem reporter');
+ $mech->content_lacks('Report another problem here');
+ $mech->content_lacks($report->latitude);
+ $mech->content_lacks($report->longitude);
+};
+
+subtest "check owner of report can view non public reports" => sub {
+ $mech->log_in_ok( $report->user->email );
+ ok $mech->get("/report/$report_id"), "get '/report/$report_id'";
+ is $mech->res->code, 200, "report can be viewed";
+ is $mech->uri->path, "/report/$report_id", "at /report/$report_id";
+ $mech->log_out_ok;
+
+ $mech->log_in_ok( $user2->email );
+ ok $mech->get("/report/$report_id"), "get '/report/$report_id'";
+ is $mech->res->code, 403, "access denied to user who is not report creator";
+ is $mech->uri->path, "/report/$report_id", "at /report/$report_id";
+ $mech->content_contains('permission to do that. If you are the problem reporter');
+ $mech->content_lacks('Report another problem here');
+ $mech->content_lacks($report->latitude);
+ $mech->content_lacks($report->longitude);
+ $mech->log_out_ok;
+};
+
+subtest "Logged email working on private report" => sub {
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ MAPIT_URL => 'http://mapit.uk/',
+ }, sub {
+ $mech->log_in_ok($staffuser->email);
+ $mech->get_ok('/report/new?latitude=51.7549262252&longitude=-1.25617899435');
+ $mech->submit_form_ok({
+ with_fields => {
+ form_as => 'another_user',
+ title => "Test Report",
+ detail => 'Test report details.',
+ category => 'Potholes',
+ name => 'Another User',
+ username => 'another@example.net',
+ non_public => 1,
+ }
+ }, "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";
+ is $report->non_public, 1;
+
+ my $email = $mech->get_email;
+ my $body = $mech->get_text_body_from_email($email);
+ my $url = $mech->get_link_from_email($email);
+ like $body, qr/Your report to Oxfordshire County Council has been logged/;
+ $mech->get_ok($url);
+ $mech->content_lacks('Get updates');
+ $mech->content_contains('To provide an update, please');
+};
+
+done_testing();
diff --git a/t/app/controller/report_update_text.t b/t/app/controller/report_update_text.t
index 4ab8e4bae..52f221264 100644
--- a/t/app/controller/report_update_text.t
+++ b/t/app/controller/report_update_text.t
@@ -18,7 +18,7 @@ my $dt = DateTime->new(
second => 23
);
-my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
+my $report = FixMyStreet::DB->resultset('Problem')->find_or_create(
{
postcode => 'SW1A 1AA',
bodies_str => $body->id,
@@ -44,7 +44,7 @@ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
my $report_id = $report->id;
ok $report, "created test report - $report_id";
-my $comment = FixMyStreet::App->model('DB::Comment')->find_or_create( {
+my $comment = FixMyStreet::DB->resultset('Comment')->find_or_create( {
problem_id => $report_id,
user_id => $user2->id,
name => 'Other User',
@@ -181,7 +181,7 @@ for my $test (
}
my ($token) = $mech->content =~ /name="token" value="([^"]*)"/;
- $token = FixMyStreet::App->model('DB::Token')->find({
+ $token = FixMyStreet::DB->resultset('Token')->find({
token => $token,
scope => 'comment'
});
@@ -189,7 +189,7 @@ for my $test (
my $update_id = $token->data->{id};
my $add_alerts = $token->data->{add_alert};
- my $update = FixMyStreet::App->model('DB::Comment')->find( { id => $update_id } );
+ my $update = FixMyStreet::DB->resultset('Comment')->find( { id => $update_id } );
ok $update, 'found update in database';
is $update->state, 'unconfirmed', 'update unconfirmed';
@@ -211,11 +211,11 @@ for my $test (
ok $user->check_password( 'new_secret' ), 'password changed';
is $user->name, 'Reg User', 'name changed';
} else {
- $user = FixMyStreet::App->model( 'DB::User' )->find( { phone => $details->{username} } );
+ $user = FixMyStreet::DB->resultset( 'User' )->find( { phone => $details->{username} } );
ok $user, 'found user';
}
- my $alert = FixMyStreet::App->model( 'DB::Alert' )->find(
+ my $alert = FixMyStreet::DB->resultset( 'Alert' )->find(
{ user => $user, alert_type => 'new_updates', confirmed => 1, }
);
diff --git a/t/app/controller/report_updates.t b/t/app/controller/report_updates.t
index 8ff5b4d24..07ee48587 100644
--- a/t/app/controller/report_updates.t
+++ b/t/app/controller/report_updates.t
@@ -31,7 +31,7 @@ my $dt = DateTime->new(
second => 23
);
-my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
+my $report = FixMyStreet::DB->resultset('Problem')->find_or_create(
{
postcode => 'SW1A 1AA',
bodies_str => $body->id,
@@ -57,7 +57,7 @@ my $report = FixMyStreet::App->model('DB::Problem')->find_or_create(
my $report_id = $report->id;
ok $report, "created test report - $report_id";
-my $comment = FixMyStreet::App->model('DB::Comment')->find_or_create(
+my $comment = FixMyStreet::DB->resultset('Comment')->find_or_create(
{
problem_id => $report_id,
user_id => $user2->id,
@@ -201,7 +201,7 @@ subtest "several updates shown in correct order" => sub {
new_state => 'fixed - user',
},
) {
- my $q = FixMyStreet::App->model('DB::Questionnaire')->find_or_create(
+ my $q = FixMyStreet::DB->resultset('Questionnaire')->find_or_create(
$fields
);
push @qs, $q;
@@ -238,7 +238,7 @@ subtest "several updates shown in correct order" => sub {
confirmed => '2011-03-15 08:12:36',
}
) {
- my $comment = FixMyStreet::App->model('DB::Comment')->find_or_create(
+ my $comment = FixMyStreet::DB->resultset('Comment')->find_or_create(
$fields
);
if ($fields->{text} eq 'Second update') {
@@ -443,7 +443,7 @@ for my $test (
my ($url_token) = $url =~ m{/C/(\S+)};
ok $url, "extracted confirm url '$url'";
- my $token = FixMyStreet::App->model('DB::Token')->find(
+ my $token = FixMyStreet::DB->resultset('Token')->find(
{
token => $url_token,
scope => 'comment'
@@ -454,7 +454,7 @@ for my $test (
my $update_id = $token->data->{id};
my $add_alerts = $token->data->{add_alert};
my $update =
- FixMyStreet::App->model('DB::Comment')->find( { id => $update_id } );
+ FixMyStreet::DB->resultset('Comment')->find( { id => $update_id } );
my $details = {
%{ $test->{form_values} },
@@ -470,11 +470,11 @@ for my $test (
$mech->get_ok( $url );
$mech->content_contains("/report/$report_id#update_$update_id");
- my $unreg_user = FixMyStreet::App->model( 'DB::User' )->find( { email => $details->{username} } );
+ my $unreg_user = FixMyStreet::DB->resultset( 'User' )->find( { email => $details->{username} } );
ok $unreg_user, 'found user';
- my $alert = FixMyStreet::App->model( 'DB::Alert' )->find(
+ my $alert = FixMyStreet::DB->resultset( 'Alert' )->find(
{ user => $unreg_user, alert_type => 'new_updates', confirmed => 1, }
);
@@ -548,7 +548,7 @@ for my $test (
my $email = $mech->email_count_is(0);
my $update =
- FixMyStreet::App->model('DB::Comment')->find( { problem_id => $report_id, text => 'Update no email confirm' } );
+ FixMyStreet::DB->resultset('Comment')->find( { problem_id => $report_id, text => 'Update no email confirm' } );
my $update_id = $update->id;
$mech->content_contains('name="update_' . $update_id . '"');
@@ -563,7 +563,7 @@ for my $test (
is $update->user->email, $details->{username}, 'update email';
is $update->text, $details->{update}, 'update text';
- my $unreg_user = FixMyStreet::App->model( 'DB::User' )->find( { email => $details->{username} } );
+ my $unreg_user = FixMyStreet::DB->resultset( 'User' )->find( { email => $details->{username} } );
ok $unreg_user, 'found user';
@@ -790,7 +790,7 @@ for my $test (
subtest 'check meta correct for comments marked confirmed but not marked open' => sub {
$report->comments->delete;
- my $comment = FixMyStreet::App->model('DB::Comment')->create(
+ my $comment = FixMyStreet::DB->resultset('Comment')->create(
{
user => $user,
problem_id => $report->id,
@@ -911,7 +911,7 @@ subtest "check comment with no status change has not status in meta" => sub {
like $update_meta->[3], qr/investigating/i, 'third update meta says investigating';
my $dt = DateTime->now( time_zone => "local" )->add( seconds => 1 );
- $comment = FixMyStreet::App->model('DB::Comment')->find_or_create(
+ $comment = FixMyStreet::DB->resultset('Comment')->find_or_create(
{
problem_id => $report_id,
user_id => $user->id,
@@ -943,7 +943,7 @@ subtest "check comment with no status change has not status in meta" => sub {
subtest 'check meta correct for second comment marking as reopened' => sub {
$report->comments->delete;
- my $comment = FixMyStreet::App->model('DB::Comment')->create(
+ my $comment = FixMyStreet::DB->resultset('Comment')->create(
{
user => $user,
problem_id => $report->id,
@@ -961,7 +961,7 @@ subtest 'check meta correct for second comment marking as reopened' => sub {
my $update_meta = $mech->extract_update_metas;
like $update_meta->[0], qr/fixed/i, 'update meta says fixed';
- $comment = FixMyStreet::App->model('DB::Comment')->create(
+ $comment = FixMyStreet::DB->resultset('Comment')->create(
{
user => $user,
problem_id => $report->id,
@@ -982,7 +982,7 @@ subtest 'check meta correct for second comment marking as reopened' => sub {
subtest 'check meta correct for comment after mark_fixed with not problem_state' => sub {
$report->comments->delete;
- my $comment = FixMyStreet::App->model('DB::Comment')->create(
+ my $comment = FixMyStreet::DB->resultset('Comment')->create(
{
user => $user,
problem_id => $report->id,
@@ -1000,7 +1000,7 @@ subtest 'check meta correct for comment after mark_fixed with not problem_state'
my $update_meta = $mech->extract_update_metas;
like $update_meta->[0], qr/fixed/i, 'update meta says fixed';
- $comment = FixMyStreet::App->model('DB::Comment')->create(
+ $comment = FixMyStreet::DB->resultset('Comment')->create(
{
user => $user,
problem_id => $report->id,
@@ -1066,7 +1066,7 @@ subtest $test->{desc} => sub {
$report->comments->delete;
- my $comment = FixMyStreet::App->model('DB::Comment')->create(
+ my $comment = FixMyStreet::DB->resultset('Comment')->create(
{
user => $test->{user},
name => $test->{name},
@@ -1130,7 +1130,7 @@ subtest $test->{desc} => sub {
$report->comments->delete;
- my $comment = FixMyStreet::App->model('DB::Comment')->create(
+ my $comment = FixMyStreet::DB->resultset('Comment')->create(
{
user => $user2,
name => 'an administrator',
@@ -1182,7 +1182,7 @@ subtest $test->{desc} => sub {
$report->comments->delete;
for my $state (@{$test->{problem_states}}) {
- my $comment = FixMyStreet::App->model('DB::Comment')->create(
+ my $comment = FixMyStreet::DB->resultset('Comment')->create(
{
user => $user2,
name => 'an administrator',
@@ -1247,6 +1247,7 @@ for my $test (
subtest $test->{desc} => sub {
# Set things up
my $user = $mech->create_user_ok( $test->{form_values}->{username} );
+ $test->{form_values}{username} = $user->email;
my $pw = 'secret2';
$user->update( { name => 'Mr Reg', password => $pw } );
$report->comments->delete;
@@ -1303,7 +1304,7 @@ subtest 'submit an update for a registered user, creating update by email' => su
$mech->submit_form_ok( {
with_fields => {
submit_update => 1,
- username => 'registered@example.com',
+ username => $user->email,
update => 'Update from a user',
add_alert => undef,
name => 'New Name',
@@ -1326,7 +1327,7 @@ subtest 'submit an update for a registered user, creating update by email' => su
my ($url_token) = $url =~ m{/C/(\S+)};
ok $url, "extracted confirm url '$url'";
- my $token = FixMyStreet::App->model('DB::Token')->find( {
+ my $token = FixMyStreet::DB->resultset('Token')->find( {
token => $url_token,
scope => 'comment'
} );
@@ -1334,11 +1335,11 @@ subtest 'submit an update for a registered user, creating update by email' => su
my $update_id = $token->data->{id};
my $add_alerts = $token->data->{add_alert};
- my $update = FixMyStreet::App->model('DB::Comment')->find( { id => $update_id } );
+ my $update = FixMyStreet::DB->resultset('Comment')->find( { id => $update_id } );
ok $update, 'found update in database';
is $update->state, 'unconfirmed', 'update unconfirmed';
- is $update->user->email, 'registered@example.com', 'update email';
+ is $update->user->email, $user->email, 'update email';
is $update->text, 'Update from a user', 'update text';
$mech->get_ok( $url );
@@ -1505,7 +1506,7 @@ for my $test (
$mech->clear_emails_ok();
- $mech->log_in_ok( $test->{email} );
+ my $user = $mech->log_in_ok( $test->{email} );
$mech->get_ok("/report/$report_id");
my $values = $mech->visible_form_values( 'updateForm' );
@@ -1548,12 +1549,12 @@ for my $test (
};
is $update->text, $results->{update}, 'update text';
- is $update->user->email, $test->{email}, 'update user';
+ is $update->user->email, $user->email, 'update user';
is $update->state, 'confirmed', 'update confirmed';
is $update->anonymous, $test->{anonymous}, 'user anonymous';
my $alert =
- FixMyStreet::App->model('DB::Alert')
+ FixMyStreet::DB->resultset('Alert')
->find( { user => $update->user, alert_type => 'new_updates', confirmed => 1, whendisabled => undef } );
ok $test->{alert} ? $alert : !$alert, 'not signed up for alerts';
@@ -1663,7 +1664,7 @@ foreach my $test (
my $questionnaire;
if ( $test->{answered} ) {
$questionnaire =
- FixMyStreet::App->model('DB::Questionnaire')->create(
+ FixMyStreet::DB->resultset('Questionnaire')->create(
{
problem_id => $report_id,
ever_reported => 'y',
@@ -1678,7 +1679,7 @@ foreach my $test (
$mech->clear_emails_ok();
- $mech->log_in_ok( $test->{email} );
+ my $user = $mech->log_in_ok( $test->{email} );
$mech->get_ok("/report/$report_id");
my $values = $mech->visible_form_values('updateForm');
@@ -1708,7 +1709,7 @@ foreach my $test (
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->user->email, $user->email, 'update user';
is $update->state, 'confirmed', 'update confirmed';
is $update->anonymous, $test->{anonymous}, 'user anonymous';
@@ -1728,7 +1729,7 @@ foreach my $test (
$mech->content_contains( $report->title );
$mech->content_contains( 'Thank you for updating this issue' );
- $questionnaire = FixMyStreet::App->model( 'DB::Questionnaire' )->find(
+ $questionnaire = FixMyStreet::DB->resultset( 'Questionnaire' )->find(
{ problem_id => $report_id }
);
@@ -1752,7 +1753,7 @@ for my $test (
fields => {
submit_update => 1,
name => 'Test User',
- username => 'test@example.com',
+ username => $report->user->email,
may_show_name => 1,
update => 'update from owner',
add_alert => undef,
@@ -1774,7 +1775,7 @@ for my $test (
submit_update => 1,
name => 'Test User',
may_show_name => 1,
- username => 'test@example.com',
+ username => $report->user->email,
update => 'update from owner',
add_alert => undef,
fixed => 1,
@@ -1805,7 +1806,7 @@ for my $test (
my $questionnaire;
if ( $test->{answered} ) {
$questionnaire =
- FixMyStreet::App->model('DB::Questionnaire')->create(
+ FixMyStreet::DB->resultset('Questionnaire')->create(
{
problem_id => $report_id,
ever_reported => 'y',
@@ -1851,7 +1852,7 @@ for my $test (
my ($url_token) = $url =~ m{/C/(\S+)};
ok $url, "extracted confirm url '$url'";
- my $token = FixMyStreet::App->model('DB::Token')->find(
+ my $token = FixMyStreet::DB->resultset('Token')->find(
{
token => $url_token,
scope => 'comment'
@@ -1877,7 +1878,7 @@ for my $test (
$mech->content_contains( $report->title );
$mech->content_contains( 'Thank you for updating this issue' );
- $questionnaire = FixMyStreet::App->model( 'DB::Questionnaire' )->find(
+ $questionnaire = FixMyStreet::DB->resultset( 'Questionnaire' )->find(
{ problem_id => $report_id }
);
diff --git a/t/app/controller/reports.t b/t/app/controller/reports.t
index ac230ef95..1d9c8d216 100644
--- a/t/app/controller/reports.t
+++ b/t/app/controller/reports.t
@@ -18,6 +18,9 @@ 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;
+$mech->create_contact_ok(body_id => $body_edin_id, category => 'Potholes', email => 'potholes@example.org');
+$mech->create_contact_ok(body_id => $body_west_id, category => 'Graffiti', email => 'graffiti@example.org');
+$mech->create_contact_ok(body_id => $body_fife_id, category => 'Flytipping', email => 'flytipping@example.org');
my @edinburgh_problems = $mech->create_problems_for_body(3, $body_edin_id, 'All reports', { category => 'Potholes' });
my @westminster_problems = $mech->create_problems_for_body(5, $body_west_id, 'All reports', { category => 'Graffiti' });
my @fife_problems = $mech->create_problems_for_body(15, $body_fife_id, 'All reports', { category => 'Flytipping' });
@@ -128,9 +131,11 @@ $mech->content_contains('2,3,4,4');
FixMyStreet::override_config {
ALLOWED_COBRANDS => 'fixmystreet',
MAPIT_URL => 'http://mapit.uk/',
+ COBRAND_FEATURES => { category_groups => { fixmystreet => 1 } },
}, sub {
$mech->submit_form_ok( { with_fields => { body => $body_edin_id } }, 'Submitted dropdown okay' );
is $mech->uri->path, '/reports/City+of+Edinburgh';
+ $mech->content_contains('<optgroup label="">');
subtest "test ward pages" => sub {
$mech->get_ok('/reports/Birmingham/Bad-Ward');
@@ -139,7 +144,7 @@ FixMyStreet::override_config {
is $mech->uri->path, '/reports/Birmingham/Bordesley+and+Highgate';
$mech->get_ok('/reports/Birmingham/Bordesley+and+Highgate|Birchfield');
is $mech->uri->path, '/reports/Birmingham/Bordesley+and+Highgate%7CBirchfield';
- $mech->content_contains('Birchfield, Bordesley & Highgate');
+ $mech->content_contains('Birchfield, Bordesley &amp; Highgate');
};
$mech->get_ok('/reports/Westminster');
diff --git a/t/app/controller/root.t b/t/app/controller/root.t
index 85119da24..0263b65d7 100644
--- a/t/app/controller/root.t
+++ b/t/app/controller/root.t
@@ -60,18 +60,6 @@ FixMyStreet::override_config {
is $mech->res->previous, undef, 'No redirect';
}
};
-
- subtest 'LOGIN_REQUIRED = 1 404s blacklisted URLs' => sub {
- my @blacklist = (
- '/offline/appcache',
- );
-
- foreach my $url (@blacklist) {
- $mech->get($url);
- ok !$mech->res->is_success(), "want a bad response";
- is $mech->res->code, 404, "got 404";
- }
- };
};
subtest "check_login_disallowed cobrand hook" => sub {
diff --git a/t/app/controller/rss.t b/t/app/controller/rss.t
index a8101b593..37543ad4f 100644
--- a/t/app/controller/rss.t
+++ b/t/app/controller/rss.t
@@ -1,3 +1,4 @@
+use utf8;
use open ':std', ':locale';
use FixMyStreet::TestMech;
use FixMyStreet::App;
@@ -97,7 +98,7 @@ $report->geocode(
'estimatedTotal' => 1
}
],
- 'copyright' => "Copyright \x{a9} 2011 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.",
+ 'copyright' => "Copyright © 2011 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.",
'statusCode' => 200,
'authenticationResultCode' => 'ValidCredentials'
}
@@ -150,4 +151,21 @@ subtest "check RSS feeds on cobrand have correct URLs for non-cobrand reports" =
$mech->content_contains($expected2, 'cobrand area report point to cobrand url');
};
+subtest 'Check XSL' => sub {
+ $mech->host('www.fixmystreet.com');
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'fixmystreet',
+ }, sub {
+ $mech->get_ok('/rss/xsl');
+ };
+ $mech->content_contains('/cobrands/fixmystreet.com/images/email-logo.gif');
+ $mech->content_contains('FixMyStreet');
+ FixMyStreet::override_config {
+ ALLOWED_COBRANDS => 'bexley',
+ }, sub {
+ $mech->get_ok('/rss/xsl');
+ };
+ $mech->content_contains('/cobrands/bexley/images/logo.png');
+};
+
done_testing();
diff --git a/t/app/controller/sample.pdf b/t/app/controller/sample.pdf
new file mode 100644
index 000000000..9ac5be44b
--- /dev/null
+++ b/t/app/controller/sample.pdf
Binary files differ
diff --git a/t/app/controller/token.t b/t/app/controller/token.t
index 858838865..f7dec1a31 100644
--- a/t/app/controller/token.t
+++ b/t/app/controller/token.t
@@ -1,5 +1,4 @@
use FixMyStreet::TestMech;
-use FixMyStreet::App;
my $mech = FixMyStreet::TestMech->new;
my $user = $mech->create_user_ok('bob@example.com', name => 'Bob');
@@ -8,7 +7,6 @@ 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,
@@ -19,7 +17,7 @@ subtest 'Zurich special case for C::Tokens->problem_confirm' => sub {
});
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 });
+ my $token = FixMyStreet::DB->resultset('Token')->create({ scope => 'problem', data => $report->id });
$mech->get_ok('/P/' . $token->token);
$report->discard_changes;