diff options
author | Matthew Somerville <matthew@mysociety.org> | 2020-02-17 17:43:54 +0000 |
---|---|---|
committer | Matthew Somerville <matthew@mysociety.org> | 2020-02-26 11:40:15 +0000 |
commit | 18adbe946c1104338e6abff159b4f9877154969c (patch) | |
tree | 5bae6c894981d3d90724f75c241c9d1e4c848dc2 | |
parent | 97133a07a181e6cccc207cc6598a08e8028ad7ca (diff) |
Add a new "staff" contact state.
This state will appear when reporting if you are logged in as a staff
member of the relevant body, but otherwise not appear on the site.
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rwxr-xr-x | bin/update-schema | 1 | ||||
-rw-r--r-- | db/downgrade_0072---0071.sql | 21 | ||||
-rw-r--r-- | db/schema.sql | 2 | ||||
-rw-r--r-- | db/schema_0072-add-staff-contact-state.sql | 23 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Report/New.pm | 6 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/ResultSet/Contact.pm | 27 | ||||
-rw-r--r-- | t/app/controller/report_new_staff.t | 32 | ||||
-rw-r--r-- | templates/web/base/admin/bodies/contact-form.html | 5 |
9 files changed, 111 insertions, 7 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 38cafc2ad..fd60691d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ - Allow report as another user with only name. - Allow staff users to sign other people up for alerts. - Group categories on body page. #2850 + - Add a new "staff" contact state. - New features: - Categories can be listed under more than one group #2475 - OpenID Connect login support. #2523 diff --git a/bin/update-schema b/bin/update-schema index 7941bc542..8f31085c9 100755 --- a/bin/update-schema +++ b/bin/update-schema @@ -212,6 +212,7 @@ else { # (assuming schema change files are never half-applied, which should be the case) sub get_db_version { return 'EMPTY' if ! table_exists('problem'); + return '0072' if constraint_contains('contacts_state_check', 'staff'); return '0071' if table_exists('manifest_theme'); return '0070' if column_like('alert_type', "ref='new_problems'", 'head_title', '{{SITE_NAME}}'); return '0069' if constraint_contains('admin_log_object_type_check', 'template'); diff --git a/db/downgrade_0072---0071.sql b/db/downgrade_0072---0071.sql new file mode 100644 index 000000000..aa649f63d --- /dev/null +++ b/db/downgrade_0072---0071.sql @@ -0,0 +1,21 @@ +BEGIN; + +ALTER TABLE contacts DROP CONSTRAINT contacts_state_check; + +ALTER TABLE contacts ADD CONSTRAINT contacts_state_check CHECK ( + state = 'unconfirmed' + or state = 'confirmed' + or state = 'inactive' + or state = 'deleted' +); + +ALTER TABLE contacts_history DROP CONSTRAINT contacts_history_state_check; + +ALTER TABLE contacts_history ADD CONSTRAINT contacts_history_state_check CHECK ( + state = 'unconfirmed' + or state = 'confirmed' + or state = 'inactive' + or state = 'deleted' +); + +COMMIT; diff --git a/db/schema.sql b/db/schema.sql index 0e38ad862..ed21aded6 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -100,6 +100,7 @@ create table contacts ( state = 'unconfirmed' or state = 'confirmed' or state = 'inactive' + or state = 'staff' or state = 'deleted' ), @@ -137,6 +138,7 @@ create table contacts_history ( state = 'unconfirmed' or state = 'confirmed' or state = 'inactive' + or state = 'staff' or state = 'deleted' ), diff --git a/db/schema_0072-add-staff-contact-state.sql b/db/schema_0072-add-staff-contact-state.sql new file mode 100644 index 000000000..efaac2d20 --- /dev/null +++ b/db/schema_0072-add-staff-contact-state.sql @@ -0,0 +1,23 @@ +BEGIN; + +ALTER TABLE contacts DROP CONSTRAINT contacts_state_check; + +ALTER TABLE contacts ADD CONSTRAINT contacts_state_check CHECK ( + state = 'unconfirmed' + or state = 'confirmed' + or state = 'inactive' + or state = 'staff' + or state = 'deleted' +); + +ALTER TABLE contacts_history DROP CONSTRAINT contacts_history_state_check; + +ALTER TABLE contacts_history ADD CONSTRAINT contacts_history_state_check CHECK ( + state = 'unconfirmed' + or state = 'confirmed' + or state = 'inactive' + or state = 'staff' + or state = 'deleted' +); + +COMMIT; diff --git a/perllib/FixMyStreet/App/Controller/Report/New.pm b/perllib/FixMyStreet/App/Controller/Report/New.pm index 14aa7b83e..ef1905c98 100644 --- a/perllib/FixMyStreet/App/Controller/Report/New.pm +++ b/perllib/FixMyStreet/App/Controller/Report/New.pm @@ -690,11 +690,7 @@ sub setup_categories_and_bodies : Private { $c->cobrand->call_hook(munge_report_new_bodies => \%bodies); - my $contacts # - = $c # - ->model('DB::Contact') # - ->active - ->search( { 'me.body_id' => [ keys %bodies ] }, { prefetch => 'body' } ); + my $contacts = $c->model('DB::Contact')->for_new_reports($c, \%bodies); my @contacts = $c->cobrand->categories_restriction($contacts)->all_sorted; $c->cobrand->call_hook(munge_report_new_contacts => \@contacts); diff --git a/perllib/FixMyStreet/DB/ResultSet/Contact.pm b/perllib/FixMyStreet/DB/ResultSet/Contact.pm index 1643f9931..eb502c190 100644 --- a/perllib/FixMyStreet/DB/ResultSet/Contact.pm +++ b/perllib/FixMyStreet/DB/ResultSet/Contact.pm @@ -17,7 +17,7 @@ Filter down to not deleted contacts (so active or inactive). sub not_deleted { my $rs = shift; - return $rs->search( { $rs->me('state') => { '!=' => 'deleted' } } ); + return $rs->search( { $rs->me('state') => { -not_in => [ 'deleted', 'staff' ] } } ); } sub active { @@ -25,6 +25,31 @@ sub active { $rs->search( { $rs->me('state') => [ 'unconfirmed', 'confirmed' ] } ); } +sub for_new_reports { + my ($rs, $c, $bodies) = @_; + my $params = { + $rs->me('body_id') => [ keys %$bodies ], + }; + + if ($c->user_exists && $c->user->from_body) { + # Everything normal OR staff state in the user body + $params->{'-or'} = [ + $rs->me('state') => [ 'unconfirmed', 'confirmed' ], + { + $rs->me('body_id') => $c->user->from_body->id, + $rs->me('state') => 'staff', + }, + ]; + } elsif ($c->user_exists && $c->user->is_superuser) { + # Everything normal OR any staff states + $params->{$rs->me('state')} = [ 'unconfirmed', 'confirmed', 'staff' ]; + } else { + $params->{$rs->me('state')} = [ 'unconfirmed', 'confirmed' ]; + } + + $rs->search($params, { prefetch => 'body' }); +} + sub translated { my $rs = shift; my $schema = $rs->result_source->schema; diff --git a/t/app/controller/report_new_staff.t b/t/app/controller/report_new_staff.t index 5d4d05e52..ee9dff9e4 100644 --- a/t/app/controller/report_new_staff.t +++ b/t/app/controller/report_new_staff.t @@ -18,7 +18,7 @@ for my $body ( # 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' ); -$mech->create_contact_ok( body_id => $body_ids{2651}, category => 'Trees', email => 'trees@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' ); @@ -224,4 +224,34 @@ for my $test ( }; } +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'; + + 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/templates/web/base/admin/bodies/contact-form.html b/templates/web/base/admin/bodies/contact-form.html index 921cb1380..b698fcea2 100644 --- a/templates/web/base/admin/bodies/contact-form.html +++ b/templates/web/base/admin/bodies/contact-form.html @@ -40,6 +40,11 @@ <label for="state-deleted">[% loc('Deleted') %]</label> <p class="form-hint" id="state-deleted-hint">[% loc('Prevent new reports from using this category, <em>and</em> also remove it from map filters.') %]</p> </div> + <div class="form-check form-check--inline"> + <input type="radio" name="state" id="state-staff" aria-describedby="state-staff-hint" value="staff"[% ' checked' IF contact.state == 'staff' %]> + <label for="state-staff">[% loc('Staff only') %]</label> + <p class="form-hint" id="state-staff-hint">[% loc('Only staff users will be able to add reports in this category.') %]</p> + </div> </fieldset> <p class="form-check"> |