[Rt-commit] rt branch, 4.4-trunk, updated. rt-4.4.0rc2-21-g83ecd2a

Shawn Moore shawn at bestpractical.com
Fri Dec 18 14:32:28 EST 2015


The branch, 4.4-trunk has been updated
       via  83ecd2afb553c2120668972d291c0fe7b5b56bcd (commit)
       via  5fce9d9b36951d1027fda6dfe41e200ac74dc5df (commit)
      from  dc3b22a04a465e1d7d834a5493575f5fa1bbf526 (commit)

Summary of changes:
 etc/upgrade/4.4.1/content                          |  53 +++++
 lib/RT/Dashboard/Mailer.pm                         |  62 ++++--
 .../Dashboards/Elements/SubscriptionRecipients     | 226 +++++++++++++++++++++
 share/html/Dashboards/Subscription.html            | 153 +++++++++-----
 share/static/css/base/misc.css                     |   7 +
 t/web/dashboards-basics.t                          |  33 +--
 t/web/dashboards-subscription.t                    | 129 ++++++++++++
 7 files changed, 570 insertions(+), 93 deletions(-)
 create mode 100644 etc/upgrade/4.4.1/content
 create mode 100644 share/html/Dashboards/Elements/SubscriptionRecipients
 create mode 100644 t/web/dashboards-subscription.t

- Log -----------------------------------------------------------------
commit 5fce9d9b36951d1027fda6dfe41e200ac74dc5df
Author: Dustin Graves <dustin at bestpractical.com>
Date:   Tue Nov 17 22:45:06 2015 +0000

    change dashboard subscription recipient input to robust user/group search
    
    Fixes:T#158520

diff --git a/etc/upgrade/4.4.1/content b/etc/upgrade/4.4.1/content
new file mode 100644
index 0000000..61f9327
--- /dev/null
+++ b/etc/upgrade/4.4.1/content
@@ -0,0 +1,53 @@
+use strict;
+use warnings;
+
+use List::MoreUtils 'uniq';
+
+our @Initial = (
+    # migrate old Recipient field to new Recipients format
+    sub {
+        $RT::Logger->debug("Going to migrate dashboard subscription recipients");
+
+        my $attrs = RT::Attributes->new( RT->SystemUser );
+        $attrs->Limit( FIELD => 'ObjectType', VALUE => 'RT::User' );
+        $attrs->Limit( FIELD => 'Name', VALUE => 'Subscription' );
+
+        while ( my $attr = $attrs->Next ) {
+            my %fields = ( Recipients => { Users => [], Groups => [] } );
+
+            my $recipient = $attr->SubValue('Recipient');
+            my @users;
+
+            if ($recipient) {
+                for ( RT::EmailParser->ParseEmailAddress($recipient) ) {
+                    my ( $email, $name ) = ( $_->address, $_->name );
+
+                    my $user = RT::User->new(RT->SystemUser);
+                    $user->LoadOrCreateByEmail(
+                        EmailAddress => $email,
+                        RealName     => $name,
+                        Comments     => 'Autocreated when added as a dashboard subscription recipient',
+                    );
+
+                    push @users, $user->id;
+                }
+            } else { # blank recipient represents dashboard creator subscription
+                push @users, $attr->ObjectId;
+            }
+
+            @{ $fields{Recipients}->{Users} } = uniq @users;
+
+            my ($ok, $msg) = $attr->SetSubValues(%fields);
+            unless ($ok) {
+                $RT::Logger->error("Couldn't update subscription: $msg");
+                $RT::Logger->error("Aborting dashboard subscription recipient migration");
+                exit;
+            }
+
+            ($ok, $msg) = $attr->DeleteSubValue('Recipient');
+            $RT::Logger->error("Couldn't delete Recipient field from subscription: $msg") unless $ok;
+        }
+        return 1;
+    },
+);
+
diff --git a/lib/RT/Dashboard/Mailer.pm b/lib/RT/Dashboard/Mailer.pm
index 276e93f..1786c06 100644
--- a/lib/RT/Dashboard/Mailer.pm
+++ b/lib/RT/Dashboard/Mailer.pm
@@ -61,6 +61,7 @@ use RT::Interface::Web;
 use File::Temp 'tempdir';
 use HTML::Scrubber;
 use URI::QueryParam;
+use List::MoreUtils 'uniq';
 
 sub MailDashboards {
     my $self = shift;
@@ -103,22 +104,53 @@ sub MailDashboards {
                 LocalTime    => [$hour, $dow, $dom],
             );
 
-            my $email = $subscription->SubValue('Recipient')
-                     || $user->EmailAddress;
-
-            eval {
-                $self->SendDashboard(
-                    %args,
-                    CurrentUser  => $currentuser,
-                    Email        => $email,
-                    Subscription => $subscription,
-                    From         => $from,
-                )
-            };
-            if ( $@ ) {
-                $RT::Logger->error("Caught exception: $@");
+            my $recipients = $subscription->SubValue('Recipients');
+            my $recipients_users = $recipients->{Users};
+            my $recipients_groups = $recipients->{Groups};
+
+            my @emails;
+
+            # add users' emails to email list
+            for my $user_id (@{ $recipients_users || [] }) {
+                my $user = RT::User->new(RT->SystemUser);
+                $user->Load($user_id);
+                next unless $user->id;
+
+                push @emails, $user->EmailAddress;
+            }
+
+            # add emails for every group's members
+            for my $group_id (@{ $recipients_groups || [] }) {
+                my $group = RT::Group->new(RT->SystemUser);
+                $group->Load($group_id);
+                next unless $group->id;
+
+                my $users = $group->UserMembersObj;
+                while (my $user = $users->Next) {
+                    push @emails, $user->EmailAddress;
+                }
+            }
+
+            my $email_success = 0;
+            for my $email (uniq @emails) {
+                eval {
+                    $self->SendDashboard(
+                        %args,
+                        CurrentUser  => $currentuser,
+                        Email        => $email,
+                        Subscription => $subscription,
+                        From         => $from,
+                    )
+                };
+                if ( $@ ) {
+                    $RT::Logger->error("Caught exception: $@");
+                }
+                else {
+                    $email_success = 1;
+                }
             }
-            else {
+
+            if ($email_success) {
                 my $counter = $subscription->SubValue('Counter') || 0;
                 $subscription->SetSubValues(Counter => $counter + 1)
                     unless $args{DryRun};
diff --git a/share/html/Dashboards/Elements/SubscriptionRecipients b/share/html/Dashboards/Elements/SubscriptionRecipients
new file mode 100644
index 0000000..f2e143d
--- /dev/null
+++ b/share/html/Dashboards/Elements/SubscriptionRecipients
@@ -0,0 +1,226 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%ARGS>
+$UserField      => 'Name'
+$UserOp         => '='
+$UserString     => undef
+$PrivilegedOnly => undef
+
+$GroupField     => 'Name'
+$GroupOp        => '='
+$GroupString    => undef
+
+$Recipients => undef
+$IsFirstSubscription => undef
+</%ARGS>
+
+<%INIT>
+my ($recipients_users, $recipients_groups);
+my ($Users, $Groups);
+
+if ($Recipients) {
+    $recipients_users = $Recipients->{Users};
+    $recipients_groups = $Recipients->{Groups};
+}
+
+if ($UserString) {
+    $Users = RT::Users->new($session{'CurrentUser'});
+    $Users->Limit(FIELD => $UserField, VALUE => $UserString, OPERATOR => $UserOp, CASESENSITIVE => 0);
+    $Users->LimitToPrivileged if $PrivilegedOnly;
+
+    my $excluded_users = [ $session{'CurrentUser'}->id ];
+    push @$excluded_users, @{ $recipients_users || [] };
+    $Users->Limit(FIELD => 'id', VALUE => $excluded_users, OPERATOR => 'NOT IN');
+}
+
+if ($GroupString) {
+    $Groups = RT::Groups->new($session{'CurrentUser'});
+    $Groups->LimitToUserDefinedGroups;
+    $Groups->Limit(FIELD => $GroupField, VALUE => $GroupString, OPERATOR => $GroupOp, CASESENSITIVE => 0);
+    $Groups->Limit(FIELD => 'id', VALUE => $recipients_groups, OPERATOR => 'NOT IN') if @{ $recipients_groups || [] };
+}
+</%INIT>
+
+<table>
+<tr>
+<td>
+
+<table width="100%">
+<tr>
+<td valign="top">
+<&|/l&>Find people whose</&><br />
+% if ($UserString) {
+<& /Elements/SelectUsers, UserString => $UserString, UserField => $UserField, UserOp => $UserOp &>
+% } else {
+<& /Elements/SelectUsers &>
+% }
+<input type="submit" class="button" name="OnlySearchForPeople" value="<&|/l&>Go!</&>" />
+
+<br />
+
+<&|/l&>Find groups whose</&><br />
+% if ($GroupString) {
+<& /Elements/SelectGroups, GroupString => $GroupString, GroupField => $GroupField, GroupOp => $GroupOp &>
+% } else {
+<& /Elements/SelectGroups &>
+% }
+<input type="submit" class="button" name="OnlySearchForGroup" value="<&|/l&>Go!</&>" />
+</td>
+</tr>
+</table>
+
+<br/>
+<&|/l&>Add New Recipients</&>:
+<table>
+
+% if ( $Users && $Users->Count ) {
+<tr><td></td><td>
+<&|/l&>User</&>
+</tr></td>
+% while ( my $u = $Users->Next ) {
+<tr><td>
+<input type="checkbox" class="checkbox" name="Dashboard-Subscription-Users-<%$u->id%>" value="1" />
+</td><td>
+<input type="hidden" name="Dashboard-Subscription-Users-<%$u->id%>" value="0" />
+<& '/Elements/ShowUser', User => $u, style=>'verbose' &>
+</td></tr>
+% }
+% }
+
+% if ( $Groups && $Groups->Count ) {
+<tr><td></td><td>
+<&|/l&>Group</&>
+</tr></td>
+% while ( my $g = $Groups->Next ) {
+<tr><td>
+<input type="checkbox" class="checkbox" name="Dashboard-Subscription-Groups-<%$g->id%>" value="1" />
+</td><td>
+<input type="hidden" name="Dashboard-Subscription-Groups-<%$g->id%>" value="0" />
+<%$g->Name%> (<%$g->Description%>)
+</td></tr>
+% }
+% }
+
+<tr><td></td><td>
+<&|/l&>Email</&>
+</tr></td>
+
+% for my $i (1 .. 3) {
+<tr><td></td><td>
+<& /Elements/EmailInput, Name => 'Dashboard-Subscription-Email-' . $i, Size => '20' &>
+</td></tr>
+% }
+
+</table>
+
+</td>
+<td class="current-recipients">
+
+<&|/l&>Current Recipients</&>:
+
+<ul>
+% my $current_user_id = $session{CurrentUser}->id;
+% my $current_user_subscribed = $recipients_users && grep { $_ == $current_user_id } @$recipients_users;
+<li>
+<input type="checkbox" class="checkbox" name="Dashboard-Subscription-Users-<%$current_user_id%>" value="1" <% $current_user_subscribed || $IsFirstSubscription ? 'checked' : '' %> />
+<input type="hidden" name="Dashboard-Subscription-Users-<%$current_user_id%>" value="0" />
+% if ( $session{CurrentUser}->HasRight( Right => 'AdminUsers', Object => $RT::System ) &&
+%      $session{CurrentUser}->HasRight( Right => 'ShowConfigTab', Object =>$RT::System ) ) {
+<a href="<% RT->Config->Get('WebPath') %>/Admin/Users/Modify.html?id=<% $current_user_id %>">
+<& /Elements/ShowUser, User => $session{CurrentUser} &></a>
+% } else {
+<& /Elements/ShowUser, User => $session{CurrentUser} &>
+% }
+<& /Elements/ShowUserEmailFrequency, User => $session{CurrentUser} &>
+</li>
+
+% for my $user_id (@{ $recipients_users || [] }) {
+% next if $user_id == $session{'CurrentUser'}->id; # already listed current user
+% my $user = RT::User->new( $session{'CurrentUser'} );
+% $user->Load($user_id);
+% next unless $user->id;
+<li>
+<input type="checkbox" class="checkbox" name="Dashboard-Subscription-Users-<%$user_id%>" value="1" checked />
+<input type="hidden" name="Dashboard-Subscription-Users-<%$user_id%>" value="0" />
+% if ( $session{CurrentUser}->HasRight( Right => 'AdminUsers', Object => $RT::System ) &&
+%      $session{CurrentUser}->HasRight( Right => 'ShowConfigTab', Object =>$RT::System ) ) {
+<a href="<% RT->Config->Get('WebPath') %>/Admin/Users/Modify.html?id=<% $user_id %>">
+<& /Elements/ShowUser, User => $user &></a>
+% } else {
+<& /Elements/ShowUser, User => $user &>
+% }
+<& /Elements/ShowUserEmailFrequency, User => $user &>
+</li>
+% }
+
+% for my $group_id (@{ $recipients_groups || [] }) {
+% my $group = RT::Group->new( $session{'CurrentUser'} );
+% $group->Load($group_id);
+% next unless $group->id;
+<li>
+<input type="checkbox" class="checkbox" name="Dashboard-Subscription-Groups-<%$group_id%>" value="1" checked />
+<input type="hidden" name="Dashboard-Subscription-Groups-<%$group_id%>" value="0" />
+
+
+% if ( $session{CurrentUser}->HasRight( Right => 'AdminGroup', Object => $RT::System ) &&
+%      $session{CurrentUser}->HasRight( Right => 'ShowConfigTab', Object =>$RT::System ) ) {
+<a href="<% RT->Config->Get('WebPath') %>/Admin/Groups/Modify.html?id=<% $group_id %>">
+<% $group->Name %>
+</a>
+% } else {
+<% $group->Name %>
+% }
+</li>
+% }
+
+</ul>
+
+</td>
+</tr>
+</table>
+
diff --git a/share/html/Dashboards/Subscription.html b/share/html/Dashboards/Subscription.html
index d55076d..cb45f1b 100644
--- a/share/html/Dashboards/Subscription.html
+++ b/share/html/Dashboards/Subscription.html
@@ -173,15 +173,17 @@
 %   }
 </select>
 </td></tr>
-
-<tr><td class="label">
-<&|/l&>Recipient</&>:
-</td><td class="value">
-<input name="Recipient" id="Recipient" size="30" value="<%$fields{Recipient} ? $fields{Recipient} : ''%>" />
-<div class="hints"><% loc("Leave blank to send to your current email address ([_1])", $session{'CurrentUser'}->EmailAddress) %></div>
-</td></tr>
 </table>
 </&>
+
+<&| /Widgets/TitleBox, title => loc('Recipients') &>
+<& Elements/SubscriptionRecipients,
+    UserField => $UserField, UserString => $UserString, UserOp => $UserOp,
+    GroupString => $GroupString, GroupOp => $GroupOp, GroupField => $GroupField,
+    Recipients => $fields{Recipients},
+    IsFirstSubscription => $SubscriptionObj ? 0 : 1 &>
+</&>
+
 </td>
 </tr>
 </table>
@@ -194,6 +196,7 @@
 </form>
 
 <%INIT>
+use List::MoreUtils 'uniq';
 
 my ($title, @results);
 my $Loaded = 0;
@@ -222,7 +225,7 @@ my %fields = (
     Dow         => 'Monday',
     Dom         => 1,
     Rows        => 20,
-    Recipient   => '',
+    Recipients  => { Users => [], Groups => [] },
     Fow         => 1,
     Counter     => 0,
 );
@@ -241,53 +244,105 @@ for my $field (keys %fields) {
         if defined($ARGS{$field}) || $ARGS{$field.'-Magic'};
 }
 
-
 # this'll be defined on submit
 if (defined $ARGS{Save}) {
-    my $ok = 1;
-
-    # validation
-    if ($fields{Recipient}) {
-        my @addresses = Email::Address->parse($fields{Recipient});
-        if (@addresses == 0) {
-            push @results, loc('Recipient must be an email address');
-            $ok = 0;
+    # update recipients
+    for my $key (keys %ARGS) {
+        my $val = $ARGS{$key};
+        if ( $key =~ /^Dashboard-Subscription-Email-\d+$/ && $val ) {
+            my @recipients = @{ $fields{Recipients}->{Users} };
+
+            for ( RT::EmailParser->ParseEmailAddress( $val ) ) {
+                my ( $email, $name ) = ( $_->address, $_->name );
+
+                my $user = RT::User->new($session{CurrentUser});
+                $user->LoadOrCreateByEmail(
+                    EmailAddress => $email,
+                    RealName     => $name,
+                    Comments     => 'Autocreated when added as a dashboard subscription recipient',
+                );
+
+                my $is_prev_recipient = grep { $_ == $user->id } @recipients;
+                if ( not $is_prev_recipient ) {
+                    push @recipients, $user->id;
+                    push @results, loc("[_1] added to dashboard subscription recipients", $email);
+                }
+            }
+            @{ $fields{Recipients}->{Users} } = uniq @recipients;
+
+        } elsif ($key =~ /^Dashboard-Subscription-(Users|Groups)-(\d+)$/) {
+            my ($mode, $type, $id) = ('', $1, $2);
+            my @recipients = @{ $fields{Recipients}->{$type} };
+
+            # find out proper value for user/group checkbox
+            my $add_keep_recipient = ref $ARGS{$key} eq 'ARRAY' ?
+                grep { $_ } @{ $ARGS{$key} } :
+                $ARGS{$key};
+
+            my $record; # hold user/group object
+            if ($type eq 'Users') {
+                my $user = RT::User->new($session{CurrentUser});
+                $user->Load( $id );
+                $record = $user;
+            } elsif ($type eq 'Groups') {
+                my $group = RT::Group->new($session{CurrentUser});
+                $group->Load( $id );
+                $record = $group;
+            }
+
+            my $is_prev_recipient = grep { $_ == $id } @recipients;
+
+            if ($add_keep_recipient and not $is_prev_recipient) { # Add User/Group
+                push @recipients, $id;
+                push @results, loc("[_1] added to dashboard subscription recipients", $record->Name);
+            } elsif (not $add_keep_recipient and $is_prev_recipient) { # Remove User/Group
+                @recipients = grep { $_ != $id } @recipients;
+                push @results, loc("[_1] removed from dashboard subscription recipients", $record->Name);
+            }
+
+            @{ $fields{Recipients}->{$type} } = uniq @recipients;
         }
     }
 
-    if ($ok) {
-        # update
-        if ($SubscriptionObj) {
-            $id = delete $fields{'DashboardId'}; # immutable
-            ($ok, $msg) = $SubscriptionObj->SetSubValues(%fields);
-            $fields{'DashboardId'} = $id;
+    # update
+    if ($SubscriptionObj) {
+        $id = delete $fields{'DashboardId'}; # immutable
+        ($ok, $msg) = $SubscriptionObj->SetSubValues(%fields);
+        $fields{'DashboardId'} = $id;
 
-            $msg = loc("Subscription updated") if $ok;
-            push @results, $msg;
+        $msg = loc("Subscription updated") if $ok;
+        push @results, $msg;
+    }
+    # create
+    else {
+        Abort(loc("Unable to subscribe to dashboard [_1]: Permission Denied", $id))
+            unless $Dashboard->CurrentUserCanSubscribe;
+
+        $SubscriptionObj = RT::Attribute->new($session{CurrentUser});
+        ($ok, $msg) = $SubscriptionObj->Create(
+            Name        => 'Subscription',
+            Description => 'Subscription to dashboard ' . $id,
+            ContentType => 'storable',
+            Object      => $session{'CurrentUser'}->UserObj,
+            Content     => \%fields,
+        );
+        if ($ok) {
+            push @results, loc("Subscribed to dashboard [_1]", $Dashboard->Name);
         }
-        # create
         else {
-            Abort(loc("Unable to subscribe to dashboard [_1]: Permission Denied", $id))
-                unless $Dashboard->CurrentUserCanSubscribe;
-
-            $SubscriptionObj = RT::Attribute->new($session{CurrentUser});
-            ($ok, $msg) = $SubscriptionObj->Create(
-                Name        => 'Subscription',
-                Description => 'Subscription to dashboard ' . $id,
-                ContentType => 'storable',
-                Object      => $session{'CurrentUser'}->UserObj,
-                Content     => \%fields,
-            );
-            if ($ok) {
-                push @results, loc("Subscribed to dashboard [_1]", $Dashboard->Name);
-                push @results, loc("Warning: you have no email address set, so you will not receive this dashboard until you have it set")
-                    unless $session{'CurrentUser'}->EmailAddress || $fields{Recipient};
-            }
-            else {
-                push @results, loc('Subscription could not be created: [_1]', $msg);
-            }
+            push @results, loc('Subscription could not be created: [_1]', $msg);
         }
     }
+    push @results, loc("Warning: This dashboard has no recipients")
+        unless @{ $fields{Recipients}->{Users} } || @{ $fields{Recipients}->{Groups} };
+} elsif (defined $ARGS{OnlySearchForPeople}) {
+    $GroupString = undef;
+    $GroupField = undef;
+    $GroupOp = undef;
+} elsif (defined $ARGS{OnlySearchForGroup}) {
+    $UserString = undef;
+    $UserField = undef;
+    $UserOp = undef;
 }
 
 if ($SubscriptionObj) {
@@ -305,6 +360,12 @@ $Hour        => undef
 $Dow         => undef
 $Dom         => undef
 $Rows        => undef
-$Recipient   => undef
+
+$UserField => undef
+$UserOp => undef
+$UserString => undef
+$GroupField => undef
+$GroupOp => undef
+$GroupString => undef
 </%ARGS>
 
diff --git a/share/static/css/base/misc.css b/share/static/css/base/misc.css
index 3d0fb0e..3b38d02 100644
--- a/share/static/css/base/misc.css
+++ b/share/static/css/base/misc.css
@@ -119,3 +119,10 @@ div.cke {
     text-decoration: underline !important;
     color: white !important;
 }
+
+/* dashboard subscription */
+
+td.current-recipients {
+    vertical-align: top;
+    padding-left: 50px;
+}
diff --git a/t/web/dashboards-basics.t b/t/web/dashboards-basics.t
index 1f7f630..f29e1d4 100644
--- a/t/web/dashboards-basics.t
+++ b/t/web/dashboards-basics.t
@@ -1,7 +1,7 @@
 use strict;
 use warnings;
 
-use RT::Test tests => 122;
+use RT::Test tests => 105;
 my ($baseurl, $m) = RT::Test->started_ok;
 
 my $url = $m->rt_base_url;
@@ -150,37 +150,6 @@ $m->content_unlike( qr/Bookmarked Tickets.*Bookmarked Tickets/s,
     'only dashboard queries show up' );
 $m->content_contains("dashboard test", "ticket subject");
 
-$m->get_ok("/Dashboards/Subscription.html?id=$id");
-$m->form_name('SubscribeDashboard');
-$m->click_button(name => 'Save');
-$m->content_contains("Permission Denied");
-$m->warning_like(qr/Unable to subscribe to dashboard.*Permission Denied/, "got a permission denied warning when trying to subscribe to a dashboard");
-
-$user_obj->Attributes->RedoSearch;
-is($user_obj->Attributes->Named('Subscription'), 0, "no subscriptions");
-
-$user_obj->PrincipalObj->GrantRight(Right => 'SubscribeDashboard', Object => $RT::System);
-
-$m->get_ok("/Dashboards/Modify.html?id=$id");
-$m->follow_link_ok({text => "Subscription"});
-$m->content_contains("Subscribe to dashboard different dashboard");
-$m->content_contains("Unowned Tickets");
-$m->content_contains("My Tickets");
-$m->content_unlike( qr/Bookmarked Tickets.*Bookmarked Tickets/s,
-    'only dashboard queries show up' );
-
-$m->form_name('SubscribeDashboard');
-$m->click_button(name => 'Save');
-$m->content_lacks("Permission Denied");
-$m->content_contains("Subscribed to dashboard different dashboard");
-
-$user_obj->Attributes->RedoSearch;
-is($user_obj->Attributes->Named('Subscription'), 1, "we have a subscription");
-
-$m->get_ok("/Dashboards/Modify.html?id=$id");
-$m->follow_link_ok({text => "Subscription"});
-$m->content_contains("Modify the subscription to dashboard different dashboard");
-
 $m->get_ok("/Dashboards/Modify.html?id=$id&Delete=1");
 $m->content_contains("Permission Denied", "unable to delete dashboard because we lack DeleteOwnDashboard");
 
diff --git a/t/web/dashboards-subscription.t b/t/web/dashboards-subscription.t
new file mode 100644
index 0000000..502650b
--- /dev/null
+++ b/t/web/dashboards-subscription.t
@@ -0,0 +1,129 @@
+use strict;
+use warnings;
+
+use RT::Test tests => undef;
+my ($baseurl, $m) = RT::Test->started_ok;
+
+my $url = $m->rt_base_url;
+
+# Create User
+my $user = RT::User->new(RT->SystemUser);
+my ($ret, $msg) = $user->LoadOrCreateByEmail('customer at example.com');
+ok($ret, 'ACL test user creation');
+$user->SetName('customer');
+$user->SetPrivileged(1);
+($ret, $msg) = $user->SetPassword('customer');
+$user->PrincipalObj->GrantRight(Right => 'ModifySelf');
+$user->PrincipalObj->GrantRight(Right => 'ModifyOwnDashboard', Object => $RT::System);
+$user->PrincipalObj->GrantRight(Right => 'CreateOwnDashboard', Object => $RT::System);
+$user->PrincipalObj->GrantRight(Right => 'SeeOwnDashboard', Object => $RT::System);
+$user->PrincipalObj->GrantRight(Right => 'SeeGroup', Object => $RT::System);
+my $currentuser = RT::CurrentUser->new($user);
+
+ok $m->login(customer => 'customer'), "logged in";
+
+$m->get_ok($url."Dashboards/Modify.html?Create=1");
+
+# Create Dashboard
+$m->follow_link_ok({ id => 'home-dashboard_create' });
+$m->form_name('ModifyDashboard');
+$m->field("Name" => 'test dashboard');
+$m->click_button(value => 'Create');
+$m->content_contains("Saved dashboard test dashboard");
+
+# Make sure dashboard exists
+my $dashboard = RT::Dashboard->new($currentuser);
+my ($id) = $m->content =~ /name="id" value="(\d+)"/;
+ok($id, "got an ID, $id");
+$dashboard->LoadById($id);
+is($dashboard->Name, "test dashboard");
+
+# Attempt subscription without right
+$m->get_ok("/Dashboards/Subscription.html?id=$id");
+$m->content_lacks('id="page-subscription"', "shouldn't have Subscription link since we don't have the SubscribeDashboard right");
+$m->form_name('SubscribeDashboard');
+$m->click_button(name => 'Save');
+$m->content_contains("Permission Denied");
+$m->warning_like(qr/Unable to subscribe to dashboard.*Permission Denied/, "got a permission denied warning when trying to subscribe to a dashboard");
+
+# Make sure subscription doesn't exist
+$user->Attributes->RedoSearch;
+is($user->Attributes->Named('Subscription'), 0, "no subscriptions");
+
+# Attempt subscription with right
+$user->PrincipalObj->GrantRight(Right => 'SubscribeDashboard', Object => $RT::System);
+$m->get_ok("/Dashboards/Subscription.html?id=$id");
+$m->content_contains('id="page-subscription"', "subscription link should be visible");
+$m->form_name('SubscribeDashboard');
+$m->click_button(name => 'Save');
+$m->content_lacks("Permission Denied");
+$m->content_contains("Subscribed to dashboard test dashboard");
+
+# Verify subscription exists
+$user->Attributes->RedoSearch;
+is($user->Attributes->Named('Subscription'), 1, "we have a subscription");
+
+# Test recipients missing warning
+$m->follow_link_ok({ id => 'page-subscription' });
+$m->form_name('SubscribeDashboard');
+$m->untick("Dashboard-Subscription-Users-".$user->id,1);
+$m->click_button(name => 'Save');
+$m->content_contains('customer removed from dashboard subscription recipients');
+$m->content_contains("Warning: This dashboard has no recipients");
+
+# Create new user to search for
+my $search_user = RT::User->new(RT->SystemUser);
+($ret, $msg) = $search_user->LoadOrCreateByEmail('customer2 at example.com');
+ok($ret, 'ACL test user creation');
+$search_user->SetName('customer2');
+
+# Search for customer2 user and subscribe
+$m->form_name('SubscribeDashboard');
+$m->field(UserString => 'customer');
+$m->click_button(name => 'OnlySearchForPeople');
+$m->content_contains('customer2 at example.com');
+
+# Subscribe customer2
+$m->form_name('SubscribeDashboard');
+$m->tick("Dashboard-Subscription-Users-".$search_user->id, 1);
+$m->click_button(name => 'Save');
+$m->content_contains('customer2 added to dashboard subscription recipients');
+
+# Make sure customer2 is listed as a recipient
+$m->follow_link_ok({ id => 'page-subscription' });
+$m->content_contains('customer2 at example.com');
+
+# Create new group to search for
+my $search_group = RT::Group->new(RT->SystemUser);
+($ret, $msg) = $search_group->CreateUserDefinedGroup(Name => 'customers test group');
+ok($ret, 'Test customers group creation');
+
+# Search for group
+$m->form_name('SubscribeDashboard');
+$m->field(GroupString => 'customers');
+$m->click_button(name => 'OnlySearchForGroup');
+
+$m->content_contains('customers test group');
+
+# Subscribe group
+$m->form_name('SubscribeDashboard');
+$m->tick("Dashboard-Subscription-Groups-".$search_group->id, 1);
+$m->click_button(name => 'Save');
+$m->content_contains('customers test group added to dashboard subscription recipients');
+
+# Make sure customers group is listed as a recipient
+$m->follow_link_ok({ id => 'page-subscription' });
+$m->content_contains('customers test group');
+
+# Unsubscribe group
+$m->form_name('SubscribeDashboard');
+$m->untick("Dashboard-Subscription-Groups-".$search_group->id, 1);
+$m->click_button(name => 'Save');
+$m->content_contains('customers test group removed from dashboard subscription recipients');
+
+# Make sure customers group is no longer listed as a recipient
+$m->follow_link_ok({ id => 'page-subscription' });
+$m->content_lacks('customers test group');
+
+undef $m;
+done_testing;

commit 83ecd2afb553c2120668972d291c0fe7b5b56bcd
Merge: dc3b22a 5fce9d9
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Fri Dec 18 14:32:24 2015 -0500

    Merge branch '4.4/dashboard-subscription-user-group' into 4.4-trunk


-----------------------------------------------------------------------


More information about the rt-commit mailing list