Skip to content

Commit 5fa2345

Browse files
committed
UI to assign space admins. Update space policy to allow admins to do stuff
1 parent ff0b716 commit 5fa2345

File tree

11 files changed

+144
-19
lines changed

11 files changed

+144
-19
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<li data-id="{{ item.id }}">
2+
<input type="hidden" name="{{ prefix }}[]" value="{{ item.id }}" />
3+
{{ item.name }}
4+
<a href="#" class="delete-list-item btn btn-icon">
5+
<i class="icon cross-icon icon-sm icon-greyscale"></i>
6+
</a>
7+
</li>

app/controllers/spaces_controller.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def set_space
7676
end
7777

7878
def space_params
79-
permitted = [:title, :description, :theme, :image, :image_url]
79+
permitted = [:title, :description, :theme, :image, :image_url, { administrator_ids: [] }]
8080
permitted += [:host] if current_user.is_admin?
8181
params.require(:space).permit(*permitted)
8282
end

app/models/space.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ class Space < ApplicationRecord
1111
has_many :learning_path_topics, dependent: :nullify
1212
has_many :space_roles, dependent: :destroy
1313
has_many :space_role_users, through: :space_roles, source: :user, class_name: 'User'
14+
has_many :administrator_roles, -> { where(key: :admin) }, class_name: 'SpaceRole'
15+
has_many :administrators, through: :administrator_roles, source: :user, class_name: 'User'
1416

1517
has_image(placeholder: TeSS::Config.placeholder['content_provider'])
1618

@@ -38,7 +40,7 @@ def default?
3840
false
3941
end
4042

41-
def with_space_role?(role)
43+
def users_with_role(role)
4244
space_role_users.joins(:space_roles).where(space_roles: { key: role })
4345
end
4446
end

app/policies/space_policy.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ def create?
55
end
66

77
def edit?
8-
@user && (@user.is_owner?(@record) || manage?)
8+
@user && (@user.is_owner?(@record) || @user.has_space_role?(@record, :admin) || manage?)
99
end
1010

1111
def update?

app/views/spaces/_form.html.erb

+6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@
99
<%= render partial: 'common/image_form', locals: { form: f } %>
1010
</div>
1111

12+
<%= f.autocompleter :administrators, url: users_path, transform_function: 'users', template: 'autocompleter/user_id',
13+
form_field_name: 'space[administrator_ids]',
14+
label_field: :name,
15+
id_field: :id,
16+
existing_items_method: :administrators %>
17+
1218
<div class="form-group">
1319
<%= f.submit ( f.object.new_record? ? "Register" : "Update") + " space", class: 'btn btn-primary' %>
1420
<%= link_to t('.cancel', default: t("helpers.links.cancel")),

config/data/space_roles.yml

-4
This file was deleted.

test/controllers/spaces_controller_test.rb

+74-8
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class SpacesControllerTest < ActionController::TestCase
2424
assert_not_empty assigns(:spaces), 'spaces is empty'
2525
end
2626

27-
test 'admin should get index' do
27+
test 'site admin should get index' do
2828
sign_in users(:admin)
2929
get :index
3030
assert_response :success
@@ -48,7 +48,16 @@ class SpacesControllerTest < ActionController::TestCase
4848
assert_select 'a.btn[href=?]', space_path(@space), text: 'Delete', count: 0
4949
end
5050

51-
test 'admin should show space' do
51+
test 'space admin should show space' do
52+
sign_in users(:space_admin)
53+
get :show, params: { id: @space }
54+
assert_response :success
55+
assert assigns(:space)
56+
assert_select 'a.btn[href=?]', edit_space_path(@space), count: 1
57+
assert_select 'a.btn[href=?]', space_path(@space), text: 'Delete', count: 0
58+
end
59+
60+
test 'site admin should show space' do
5261
sign_in users(:admin)
5362
get :show, params: { id: @space }
5463
assert_response :success
@@ -63,12 +72,18 @@ class SpacesControllerTest < ActionController::TestCase
6372
assert_redirected_to new_user_session_path
6473
end
6574

66-
test 'admin should get new' do
75+
test 'site admin should get new' do
6776
sign_in users(:admin)
68-
get :new, params: { content_provider_id: content_providers(:goblet) }
77+
get :new
6978
assert_response :success
7079
end
7180

81+
test 'space admin should not get new' do
82+
sign_in users(:space_admin)
83+
get :new
84+
assert_response :forbidden
85+
end
86+
7287
# EDIT Tests
7388
test 'public should not get edit' do
7489
get :edit, params: { id: @space }
@@ -87,7 +102,19 @@ class SpacesControllerTest < ActionController::TestCase
87102
assert_response :forbidden
88103
end
89104

90-
test 'admin should get edit' do
105+
test 'space admin should get edit' do
106+
sign_in users(:space_admin)
107+
get :edit, params: { id: @space }
108+
assert_response :success
109+
end
110+
111+
test 'space admin should not get edit for other space' do
112+
sign_in users(:space_admin)
113+
get :edit, params: { id: spaces(:other) }
114+
assert_response :forbidden
115+
end
116+
117+
test 'site admin should get edit' do
91118
sign_in users(:admin)
92119
get :edit, params: { id: @space }
93120
assert_response :success
@@ -110,7 +137,16 @@ class SpacesControllerTest < ActionController::TestCase
110137
assert_response :forbidden
111138
end
112139

113-
test 'admin can create space' do
140+
test 'space admin cannot create new space' do
141+
sign_in users(:space_admin)
142+
refute_permitted SpacePolicy, @space.user, :create?, Space
143+
assert_no_difference 'Space.count' do
144+
post :create, params: @space_params
145+
end
146+
assert_response :forbidden
147+
end
148+
149+
test 'site admin can create space' do
114150
sign_in users(:admin)
115151
assert_difference 'Space.count', 1 do
116152
post :create, params: @space_params
@@ -138,7 +174,15 @@ class SpacesControllerTest < ActionController::TestCase
138174
assert_equal 'plants.mytess.training', assigns(:space).host, 'Non-admin user should not be able to modify host'
139175
end
140176

141-
test 'admin should update space' do
177+
test 'space admin should update owned space' do
178+
sign_in users(:space_admin)
179+
patch :update, params: { id: @space, space: { title: 'New Title', host: 'newhost.mytess.golf' } }
180+
assert_redirected_to space_path(assigns(:space))
181+
assert_equal 'New Title', assigns(:space).title
182+
assert_equal 'plants.mytess.training', assigns(:space).host, 'Non-admin user should not be able to modify host'
183+
end
184+
185+
test 'site admin should update space' do
142186
sign_in users(:admin)
143187
assert_no_difference 'Space.count' do
144188
patch :update, params: { id: @space, space: { title: 'New Title', host: 'newhost.mytess.golf' } }
@@ -164,12 +208,34 @@ class SpacesControllerTest < ActionController::TestCase
164208
end
165209
end
166210

167-
test 'admin can destroy space' do
211+
test 'space admin cannot destroy space' do
212+
sign_in users(:space_admin)
213+
assert_no_difference 'Space.count' do
214+
delete :destroy, params: { id: @space }
215+
assert_response :forbidden
216+
end
217+
end
218+
219+
test 'site admin can destroy space' do
168220
sign_in users(:admin)
169221
assert_difference 'Space.count', -1 do
170222
post :destroy, params: { id: @space }
171223
assert_redirected_to spaces_path
172224
assert_equal 'Space was successfully deleted.', flash[:notice]
173225
end
174226
end
227+
228+
test 'space admin can assign new space admins' do
229+
existing_admin = users(:space_admin)
230+
sign_in existing_admin
231+
new_admin = users(:regular_user)
232+
assert_difference('SpaceRole.count', 1) do # space_admin is already an admin, so only increases by 1
233+
patch :update, params: { id: @space, space: { title: 'New Title', administrator_ids: [existing_admin.id, new_admin.id] } }
234+
assert_redirected_to space_path(assigns(:space))
235+
end
236+
237+
admins = assigns(:space).administrators
238+
assert_includes admins, existing_admin
239+
assert_includes admins, new_admin
240+
end
175241
end

test/fixtures/space_roles.yml

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
space_admin:
2+
key: admin
3+
space: plants
4+
user: space_admin

test/fixtures/users.yml

+6
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,9 @@ learning_path_curator:
157157
encrypted_password: 'learning_paths_curator_encrypted_password'
158158
confirmed_at: <%= Time.zone.now %>
159159
role: learning_path_curator
160+
161+
space_admin:
162+
username: 'plant_boss'
163+
email: 'plantboss@example.com'
164+
encrypted_password: <%= Devise::Encryptor.digest(User, 'plantsrule') %>
165+
confirmed_at: <%= Time.zone.now %>

test/models/space_role_test.rb

+8-4
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,21 @@ class SpaceRoleTest < ActiveSupport::TestCase
1717
test 'can retrieve list of users with a given role in a space' do
1818
user = users(:regular_user)
1919
another_user = users(:another_regular_user)
20+
existing_admin = users(:space_admin)
21+
assert_equal [existing_admin], @space.users_with_role(:admin).to_a
22+
2023
@space.space_roles.create!(user: user, key: :admin)
2124
@space.space_roles.create!(user: another_user, key: :admin)
2225

23-
admins = @space.with_space_role?(:admin)
24-
assert_equal 2, admins.length
26+
admins = @space.users_with_role(:admin)
27+
assert_equal 3, admins.length
2528
assert_includes admins, user
2629
assert_includes admins, another_user
30+
assert_includes admins, existing_admin
2731

28-
assert_equal 2, @space.with_space_role?('admin').length
32+
assert_equal 3, @space.users_with_role('admin').length
2933

30-
assert_empty @space.with_space_role?(:badmin)
34+
assert_empty @space.users_with_role(:badmin)
3135
end
3236

3337
test 'can check if a user has a given role in a space' do

test/models/space_test.rb

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
require 'test_helper'
2+
3+
class SpaceTest < ActiveSupport::TestCase
4+
setup do
5+
@space = spaces(:plants)
6+
end
7+
8+
test 'get administrators' do
9+
admins = @space.administrators
10+
assert_equal 1, admins.length
11+
assert_includes admins, users(:space_admin)
12+
end
13+
14+
test 'set administrators' do
15+
user = users(:regular_user)
16+
another_user = users(:another_regular_user)
17+
18+
assert_difference('SpaceRole.count', 1) do
19+
@space.administrators = [user, another_user]
20+
end
21+
22+
admins = @space.administrators
23+
assert_equal 2, admins.length
24+
assert_includes admins, user
25+
assert_includes admins, another_user
26+
assert_not_includes admins, users(:space_admin)
27+
28+
assert_difference('SpaceRole.count', -2) do
29+
@space.administrators = []
30+
end
31+
32+
assert_empty @space.administrators
33+
end
34+
end

0 commit comments

Comments
 (0)