aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm79
-rw-r--r--t/app/controller/admin.t92
-rw-r--r--templates/web/default/admin/search_users.html29
-rw-r--r--templates/web/default/admin/user_edit.html21
4 files changed, 221 insertions, 0 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm
index ae4154e98..f0790cbff 100644
--- a/perllib/FixMyStreet/App/Controller/Admin.pm
+++ b/perllib/FixMyStreet/App/Controller/Admin.pm
@@ -586,6 +586,83 @@ sub report_edit : Path('report_edit') : Args(1) {
return 1;
}
+
+sub search_users: Path('search_users') : Args(0) {
+ my ( $self, $c ) = @_;
+
+ $c->forward('check_page_allowed');
+
+ if (my $search = $c->req->param('search')) {
+ $c->stash->{searched} = 1;
+
+ my $search = $c->req->param('search');
+ my $isearch = '%' . $search . '%';
+
+ my $search_n = 0;
+ $search_n = int($search) if $search =~ /^\d+$/;
+
+ my $users = $c->model('DB::User')->search(
+ {
+ -or => [
+ email => { ilike => $isearch },
+ name => { ilike => $isearch },
+ from_council => $search_n,
+ ]
+ }
+ );
+
+ $c->stash->{users} = [ $users->all ];
+ }
+
+ return 1;
+}
+
+sub user_edit : Path('user_edit') : Args(1) {
+ my ( $self, $c, $id ) = @_;
+
+ $c->forward('check_page_allowed');
+ $c->forward('get_token');
+
+ my $user = $c->model('DB::User')->find( { id => $id } );
+ $c->stash->{user} = $user;
+
+ my @area_types = $c->cobrand->area_types;
+ my $areas = mySociety::MaPit::call('areas', \@area_types);
+
+ my @councils_ids = sort { strcoll($areas->{$a}->{name}, $areas->{$b}->{name}) } keys %$areas;
+ @councils_ids = $c->cobrand->filter_all_council_ids_list( @councils_ids );
+
+ $c->stash->{council_ids} = \@councils_ids;
+ $c->stash->{council_details} = $areas;
+
+ if ( $c->req->param('submit') ) {
+ $c->forward('check_token');
+
+ my $edited = 0;
+
+ if ( $user->email ne $c->req->param('email') ||
+ $user->name ne $c->req->param('name' ) ||
+ $user->from_council != $c->req->param('council') ) {
+ $edited = 1;
+ }
+
+ $user->name( $c->req->param('name') );
+ $user->email( $c->req->param('email') );
+ $user->from_council( $c->req->param('council') || undef );
+ $user->update;
+
+ if ($edited) {
+ $c->forward( 'log_edit', [ $id, 'user', 'edit' ] );
+ }
+
+ $c->stash->{status_message} =
+ '<p><em>' . _('Updated!') . '</em></p>';
+ }
+
+ return 1;
+}
+
+
=head2 set_allowed_pages
Sets up the allowed_pages stash entry for checking if the current page is
@@ -605,10 +682,12 @@ sub set_allowed_pages : Private {
'search_reports' => [_('Search Reports'), 2],
'timeline' => [_('Timeline'), 3],
'questionnaire' => [_('Survey Results'), 4],
+ 'search_users' => [_('Search Users'), 5],
'council_contacts' => [undef, undef],
'council_edit' => [undef, undef],
'report_edit' => [undef, undef],
'update_edit' => [undef, undef],
+ 'user_edit' => [undef, undef],
}
}
diff --git a/t/app/controller/admin.t b/t/app/controller/admin.t
index 51c55c323..2ada0d2ea 100644
--- a/t/app/controller/admin.t
+++ b/t/app/controller/admin.t
@@ -721,6 +721,98 @@ subtest 'report search' => sub {
$mech->content_like( qr{<tr [^>]*hidden[^>]*> \s* <td> \s* $r_id \s* </td>}xs );
};
+subtest 'user search' => sub {
+ $mech->get_ok('/admin/search_users');
+ $mech->get_ok('/admin/search_users?search=' . $user->name);
+
+ $mech->content_contains( $user->name);
+ my $u_id = $user->id;
+ $mech->content_like( qr{user_edit/$u_id">Edit</a>} );
+
+ $mech->get_ok('/admin/search_users?search=' . $user->email);
+
+ $mech->content_like( qr{user_edit/$u_id">Edit</a>} );
+
+ $user->from_council(2509);
+ $user->update;
+ $mech->get_ok('/admin/search_users?search=2509' );
+ $mech->content_contains(2509);
+};
+
+$log_entries = FixMyStreet::App->model('DB::AdminLog')->search(
+ {
+ object_type => 'user',
+ object_id => $user->id
+ },
+ {
+ order_by => { -desc => 'id' },
+ }
+);
+
+is $log_entries->count, 0, 'no admin log entries';
+
+for my $test (
+ {
+ desc => 'edit user name',
+ fields => {
+ name => 'Test User',
+ email => 'test@example.com',
+ council => 2509,
+ },
+ changes => {
+ name => 'Changed User',
+ },
+ log_count => 1,
+ log_entries => [qw/edit/],
+ },
+ {
+ desc => 'edit user email',
+ fields => {
+ name => 'Changed User',
+ email => 'test@example.com',
+ council => 2509,
+ },
+ changes => {
+ email => 'changed@example.com',
+ },
+ log_count => 2,
+ log_entries => [qw/edit edit/],
+ },
+ {
+ desc => 'edit user council',
+ fields => {
+ name => 'Changed User',
+ email => 'changed@example.com',
+ council => 2509,
+ },
+ changes => {
+ council => 2607,
+ },
+ log_count => 3,
+ log_entries => [qw/edit edit edit/],
+ },
+) {
+ subtest $test->{desc} => sub {
+ $mech->get_ok( '/admin/user_edit/' . $user->id );
+
+ my $visible = $mech->visible_form_values;
+ is_deeply $visible, $test->{fields}, 'expected user';
+
+ my $expected = {
+ %{ $test->{fields} },
+ %{ $test->{changes} }
+ };
+
+ $mech->submit_form_ok( { with_fields => $expected } );
+
+ $visible = $mech->visible_form_values;
+ is_deeply $visible, $expected, 'user updated';
+
+ $mech->content_contains( 'Updated!' );
+ };
+}
+
+
$mech->delete_user( $user );
$mech->delete_user( $user2 );
$mech->delete_user( $user3 );
diff --git a/templates/web/default/admin/search_users.html b/templates/web/default/admin/search_users.html
new file mode 100644
index 000000000..43fdebf2b
--- /dev/null
+++ b/templates/web/default/admin/search_users.html
@@ -0,0 +1,29 @@
+[% INCLUDE 'admin/header.html' title=loc('Search Users') %]
+[% PROCESS 'admin/report_blocks.html' %]
+
+<form method="get" action="[% c.uri_for('search_users') %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+ <label for="search">[% loc('Search:') %]</label> <input type="text" name="search" size="30" id="search">
+</form>
+
+
+[% IF searched %]
+<table cellspacing="0" cellpadding="2" border="1">
+ <tr>
+ <th>[% loc('Name') %]</th>
+ <th>[% loc('Email') %]</th>
+ <th>[% loc('Council') %]</th>
+ <th>*</th>
+ </tr>
+[%- FOREACH user IN users %]
+ <tr>
+ <td>[% PROCESS value_or_nbsp value=user.name %]</td>
+ <td>[% PROCESS value_or_nbsp value=user.email %]</td>
+ <td>[% PROCESS value_or_nbsp value=user.from_council %]</td>
+ <td><a href="[% c.uri_for( 'user_edit', user.id ) %]">[% loc('Edit') %]</a></td>
+ </tr>
+[%- END -%]
+</table>
+
+[% END %]
+
+[% INCLUDE 'admin/footer.html' %]
diff --git a/templates/web/default/admin/user_edit.html b/templates/web/default/admin/user_edit.html
new file mode 100644
index 000000000..7db8f5c63
--- /dev/null
+++ b/templates/web/default/admin/user_edit.html
@@ -0,0 +1,21 @@
+[% INCLUDE 'admin/header.html' title=tprintf(loc('Editing user %d'), user.id ) -%]
+[% PROCESS 'admin/report_blocks.html' %]
+
+[% status_message %]
+
+<form method="post" action="[% c.uri_for( 'user_edit', user.id ) %]" enctype="application/x-www-form-urlencoded" accept-charset="utf-8">
+ <input type="hidden" name="token" value="[% token %]" >
+ <input type="hidden" name="submit" value="1" >
+<ul>
+<li>[% loc('Name:') %] <input type='text' name='name' id='name' value='[% user.name | html %]'></li>
+<li>[% loc('Email:') %] <input type='text' id='email' name='email' value='[% user.email | html %]'></li>
+<li>[% loc('Council:') %] <select id='council' name='council'>
+ <option value=''>[% loc('No council') %]</option>
+[% FOR council IN council_ids %]
+ <option value="[% council %]"[% ' selected' IF council == user.from_council %]>[% council_details.$council.name %]</option>
+[% END %]
+</select>
+</ul>
+<input type="submit" name="Submit changes" value="[% loc('Submit changes') %]" ></form>
+
+[% INCLUDE 'admin/footer.html' %]