fix ticketing system error on bootstrap of new install
[freeside.git] / rt / t / web / dashboards-groups.t
1 use strict;
2 use warnings;
3
4 use RT::Test nodata => 1, tests => 64;
5 my ($baseurl, $m) = RT::Test->started_ok;
6
7 my $url = $m->rt_base_url;
8
9 # create user and queue
10 my $user_obj = RT::User->new(RT->SystemUser);
11 my ($ok, $msg) = $user_obj->LoadOrCreateByEmail('customer@example.com');
12 ok($ok, 'ACL test user creation');
13 $user_obj->SetName('customer');
14 $user_obj->SetPrivileged(1);
15 ($ok, $msg) = $user_obj->SetPassword('customer');
16 $user_obj->PrincipalObj->GrantRight(Right => 'ModifySelf');
17 my $currentuser = RT::CurrentUser->new($user_obj);
18
19 my $queue = RT::Queue->new(RT->SystemUser);
20 $queue->Create(Name => 'SearchQueue'.$$);
21
22 $user_obj->PrincipalObj->GrantRight(Right => $_, Object => $queue)
23     for qw/SeeQueue ShowTicket OwnTicket/;
24
25 # grant the user all these rights so we can make sure that the group rights
26 # are checked and not these as well
27 $user_obj->PrincipalObj->GrantRight(Right => $_, Object => $RT::System)
28     for qw/SubscribeDashboard CreateOwnDashboard SeeOwnDashboard ModifyOwnDashboard DeleteOwnDashboard/;
29 # create and test groups (outer < inner < user)
30 my $inner_group = RT::Group->new(RT->SystemUser);
31 ($ok, $msg) = $inner_group->CreateUserDefinedGroup(Name => "inner", Description => "inner group");
32 ok($ok, "created inner group: $msg");
33
34 my $outer_group = RT::Group->new(RT->SystemUser);
35 ($ok, $msg) = $outer_group->CreateUserDefinedGroup(Name => "outer", Description => "outer group");
36 ok($ok, "created outer group: $msg");
37
38 ($ok, $msg) = $outer_group->AddMember($inner_group->PrincipalId);
39 ok($ok, "added inner as a member of outer: $msg");
40
41 ($ok, $msg) = $inner_group->AddMember($user_obj->PrincipalId);
42 ok($ok, "added user as a member of member: $msg");
43
44 ok($outer_group->HasMember($inner_group->PrincipalId), "outer has inner");
45 ok(!$outer_group->HasMember($user_obj->PrincipalId), "outer doesn't have user directly");
46 ok($outer_group->HasMemberRecursively($inner_group->PrincipalId), "outer has inner recursively");
47 ok($outer_group->HasMemberRecursively($user_obj->PrincipalId), "outer has user recursively");
48
49 ok(!$inner_group->HasMember($outer_group->PrincipalId), "inner doesn't have outer");
50 ok($inner_group->HasMember($user_obj->PrincipalId), "inner has user");
51 ok(!$inner_group->HasMemberRecursively($outer_group->PrincipalId), "inner doesn't have outer, even recursively");
52 ok($inner_group->HasMemberRecursively($user_obj->PrincipalId), "inner has user recursively");
53
54 ok $m->login(customer => 'customer'), "logged in";
55
56
57 $m->follow_link_ok({ id => 'home-dashboard_create'});
58 $m->form_name('ModifyDashboard');
59 is_deeply([$m->current_form->find_input('Privacy')->possible_values], ["RT::User-" . $user_obj->Id], "the only selectable privacy is user");
60 $m->content_lacks('Delete', "Delete button hidden because we are creating");
61
62 $user_obj->PrincipalObj->GrantRight(Right => 'CreateGroupDashboard', Object => $inner_group);
63
64 $m->follow_link_ok({ id => 'home-dashboard_create'});
65 $m->form_name('ModifyDashboard');
66 is_deeply([$m->current_form->find_input('Privacy')->possible_values], ["RT::User-" . $user_obj->Id, "RT::Group-" . $inner_group->Id], "the only selectable privacies are user and inner group (not outer group)");
67 $m->field("Name" => 'broken dashboard');
68 $m->field("Privacy" => "RT::Group-" . $inner_group->Id);
69 $m->content_lacks('Delete', "Delete button hidden because we are creating");
70 $m->click_button(value => 'Create');
71 $m->content_contains("saved", "we lack SeeGroupDashboard, so we end up back at the index.");
72
73 $user_obj->PrincipalObj->GrantRight(
74     Right  => 'SeeGroupDashboard',
75     Object => $inner_group,
76 );
77 $m->follow_link_ok({ id => 'home-dashboard_create'});
78 $m->form_name('ModifyDashboard');
79 $m->field("Name" => 'inner dashboard');
80 $m->field("Privacy" => "RT::Group-" . $inner_group->Id);
81 $m->click_button(value => 'Create');
82 $m->content_lacks("Permission Denied", "we now have SeeGroupDashboard");
83 $m->content_contains("Saved dashboard inner dashboard");
84 $m->content_lacks('Delete', "Delete button hidden because we lack DeleteDashboard");
85
86 my $dashboard = RT::Dashboard->new($currentuser);
87 my ($id) = $m->content =~ /name="id" value="(\d+)"/;
88 ok($id, "got an ID, $id");
89 $dashboard->LoadById($id);
90 is($dashboard->Name, "inner dashboard");
91
92 is($dashboard->Privacy, 'RT::Group-' . $inner_group->Id, "correct privacy");
93 is($dashboard->PossibleHiddenSearches, 0, "all searches are visible");
94
95
96 $m->get_ok("/Dashboards/Modify.html?id=$id");
97 $m->content_contains("inner dashboard", "we now have SeeGroupDashboard right");
98 $m->content_lacks("Permission Denied");
99 $m->content_contains('Subscription', "Subscription link not hidden because we have SubscribeDashboard");
100
101
102 $m->get_ok("/Dashboards/index.html");
103 $m->content_contains("inner dashboard", "We can see the inner dashboard from the UI");
104
105 $m->get_ok("/Prefs/DashboardsInMenu.html");
106 $m->content_contains("inner dashboard", "Can also see it in the menu options");
107
108 my ($group) = grep {$_->isa("RT::Group") and $_->Id == $inner_group->Id}
109     RT::Dashboard->new($currentuser)->_PrivacyObjects;
110 ok($group, "Found the group in  the privacy objects list");
111
112 my @loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading;
113 is_deeply(
114     \@loading,
115     ["RT::User-".$user_obj->Id, "RT::Group-".$inner_group->Id],
116     "We can load from ourselves (SeeOwnDashboard) and a group we are with SeeGroupDashboard"
117 );
118
119 # If you are granted SeeGroupDashboard globally, you can only see
120 # dashboards in groups you are in.
121 $user_obj->PrincipalObj->RevokeRight(
122     Right  => 'SeeGroupDashboard',
123     Object => $inner_group,
124 );
125 $user_obj->PrincipalObj->GrantRight(
126     Right  => 'SeeGroupDashboard',
127     Object => RT->System,
128 );
129 $m->get_ok("/Dashboards/index.html");
130 $m->content_contains("inner dashboard", "Having SeeGroupDashboard gobally is fine for groups you are in");
131 @loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading;
132 is_deeply(
133     \@loading,
134     ["RT::User-".$user_obj->Id, "RT::Group-".$inner_group->Id],
135     "SeeGroupDashboard globally still works for groups you are in"
136 );
137
138 $inner_group->DeleteMember($user_obj->PrincipalObj->Id);
139 ok(!$outer_group->HasMemberRecursively($user_obj->PrincipalId), "outer no longer has user recursively");
140 ok(!$inner_group->HasMemberRecursively($user_obj->PrincipalId), "inner no longer has user recursively");
141 $m->get_ok("/Dashboards/index.html");
142 $m->content_lacks("inner dashboard", "But global SeeGroupDashboard isn't enough for other groups");
143 $m->no_warnings_ok;
144 @loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading;
145 is_deeply(
146     \@loading,
147     ["RT::User-".$user_obj->Id],
148     "We only have our SeeOwnDashboard right, as we are no longer in inner"
149 );
150
151 # Similarly, if you're a SuperUser, you still only see dashboards for
152 # groups you belong to
153 $user_obj->PrincipalObj->RevokeRight(
154     Right  => 'SeeGroupDashboard',
155     Object => RT->System,
156 );
157 $user_obj->PrincipalObj->GrantRight(
158     Right  => 'SuperUser',
159     Object => RT->System,
160 );
161 $m->get_ok("/Dashboards/index.html");
162 $m->content_lacks("inner dashboard", "Superuser can't see dashboards in groups they're not in");
163 @loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading;
164 is_deeply(
165     \@loading,
166     ["RT::User-".$user_obj->Id, "RT::System-1"],
167     "We pick up the system-level SeeDashboard right from superuser"
168 );
169 @loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading(IncludeSuperuserGroups => 0);
170 is_deeply(
171     \@loading,
172     ["RT::User-".$user_obj->Id, "RT::System-1"],
173     "IncludeSuperusers only cuts out _group_ dashboard objects for loading, not user and system ones"
174 );
175
176 $inner_group->AddMember($user_obj->PrincipalId);
177 $m->get_ok("/Dashboards/index.html");
178 $m->content_contains("inner dashboard", "Superuser can see dashboards in groups they are in");
179 @loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading;
180 is_deeply(
181     \@loading,
182     ["RT::User-".$user_obj->Id, "RT::Group-".$inner_group->Id, "RT::System-1"],
183     "Becoming a member of the group makes it a possibility"
184 );
185 @loading = map {ref($_)."-".$_->Id} RT::Dashboard->new($currentuser)->ObjectsForLoading(IncludeSuperuserGroups => 0);
186 is_deeply(
187     \@loading,
188     ["RT::User-".$user_obj->Id, "RT::System-1"],
189     "But only via superuser"
190 );
191
192 $m->get_ok("/Dashboards/index.html");
193 $m->content_contains("inner dashboard", "The dashboards list includes superuser rights");
194 $m->get_ok("/Prefs/DashboardsInMenu.html");
195 $m->content_lacks("inner dashboard", "But the menu skips them");