Skip to content

Commit

Permalink
allow setting and updating stats_visibility on update and create (#4260)
Browse files Browse the repository at this point in the history
* allow setting and updating stats visibility

also adding error if stats visibility is invalid to bypass Rails enum attribute validation that returns ArgumentError

* hounded " to  and remove extra spaces, and .freeze constants

* missed hound review. update validate stats visibility to single line

* update update specs to ensure group_admins/admin users can update but not group_members
  • Loading branch information
yuenmichelle1 authored Nov 6, 2023
1 parent d742f89 commit 99a3a0c
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 4 deletions.
4 changes: 2 additions & 2 deletions app/controllers/api/v1/user_groups_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ class Api::V1::UserGroupsController < Api::ApiController

alias_method :user_group, :controlled_resource

allowed_params :create, :name, :display_name, links: [ users: [] ]
allowed_params :update, :name, :display_name
allowed_params :create, :name, :display_name, :stats_visibility, links: [users: []]
allowed_params :update, :name, :stats_visibility, :display_name

search_by do |name, query|
query.search_name(name.join(" "))
Expand Down
17 changes: 15 additions & 2 deletions app/models/user_group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,18 @@ class UserGroup < ApplicationRecord
#
# public_show_all: Anyone can view aggregate stats of the user group and can view individual stats of the user group.
##
enum stats_visibility: {
STATS_VISIBILITY_LEVELS = {
private_agg_only: 0,
private_show_agg_and_ind: 1,
public_agg_only: 2,
public_agg_show_ind_if_member: 3,
public_show_all: 4
}
}.freeze
enum stats_visibility: STATS_VISIBILITY_LEVELS

validate do
errors.add(:stats_visibility, "Not valid stats_visibility type, please select from the list: #{STATS_VISIBILITY_LEVELS.keys}") if @invalid_stats_visibility
end

validates :display_name, presence: true
validates :name, presence: true,
Expand Down Expand Up @@ -86,6 +91,14 @@ def verify_join_token(token_to_verify)
join_token.present? && join_token == token_to_verify
end

def stats_visibility=(value)
if STATS_VISIBILITY_LEVELS.stringify_keys.keys.exclude?(value) && STATS_VISIBILITY_LEVELS.values.exclude?(value)
@invalid_stats_visibility = true
else
super value
end
end

private

def default_display_name
Expand Down
83 changes: 83 additions & 0 deletions spec/controllers/api/v1/user_groups_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,60 @@
end

it_behaves_like 'is updatable'

describe 'updating stats_visibility' do
let(:params) {
{
id: resource.id,
user_groups: {
display_name: 'A-Different-Name',
stats_visibility: 'public_agg_only'
}
}
}

describe 'as group_admin' do
it 'updates stats_visibility' do
default_request scopes: scopes, user_id: authorized_user.id
put :update, params: params
expect(response.status).to eq(200)

group = UserGroup.find(resource.id)
expect(group.stats_visibility).to eq('public_agg_only')
end

it 'does not update user_group if invalid stats_visibility' do
default_request scopes: scopes, user_id: authorized_user.id
user_groups = {
display_name: 'A-Different-Name',
stats_visibility: 'fake_stats_visibility'
}
params[:user_groups] = user_groups
put :update, params: params
expect(response.status).to eq(400)
end
end

describe 'as admin' do
it 'updates user_group_stats_visibility' do
admin_user = create(:user, admin: true)
default_request scopes: scopes, user_id: admin_user.id
params[:admin] = true
put :update, params: params
expect(response.status).to eq(200)
end
end

describe 'as group_member' do
it 'does not update user_group stats_visibility' do
group_member_user = create(:user)
create(:membership, user: group_member_user, user_group: resource, roles: ['group_member'])
default_request scopes: scopes, user_id: group_member_user.id
put :update, params: params
expect(response.status).to eq(404)
end
end
end
end

describe '#show' do
Expand Down Expand Up @@ -120,6 +174,35 @@
end
end

describe 'setting stats_visibility' do
describe 'as group_admin' do
it 'sets the stats_visiblity when sending in stats_visiblity as string' do
default_request scopes: scopes, user_id: authorized_user.id
post :create, params: { user_groups: { name: 'GalaxyZoo', stats_visibility: 'public_agg_show_ind_if_member' } }
expect(response.status).to eq(201)
group = UserGroup.find(created_instance_id('user_groups'))

expect(group.stats_visibility).to eq('public_agg_show_ind_if_member')
end

it 'sets the stats_visibility when sending related integer corresponding to visibility level' do
default_request scopes: scopes, user_id: authorized_user.id
post :create, params: { user_groups: { name: 'GalaxyZoo', stats_visibility: 3 } }
expect(response.status).to eq(201)

# see app/models/user_group.rb L22-L40 for explanations of stats_visibliity levels
group = UserGroup.find(created_instance_id('user_groups'))
expect(group.stats_visibility).to eq('public_agg_show_ind_if_member')
end

it 'does not create group if stats_visibility is invalid' do
default_request scopes: scopes, user_id: authorized_user.id
post :create, params: { user_groups: { name: 'GalaxyZoo', stats_visibility: 7 } }
expect(response.status).to eq(400)
end
end
end

describe 'when only a name is provided' do
it 'sets the display name' do
default_request scopes: scopes, user_id: authorized_user.id
Expand Down
26 changes: 26 additions & 0 deletions spec/models/user_group_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,32 @@
end
end

describe '#stats_visibility' do
it 'validates that it is one of the STATS_VISIBILITY levels' do
ug = build(:user_group, name: 'abc')
ug.stats_visibility = 'public_agg_only'
expect(ug).to be_valid
end

it 'allows stats_visibility to be integer corresponding to STATS_VISIBILITY level' do
ug = build(:user_group, name: 'abc')
ug.stats_visibility = 4
expect(ug).to be_valid
end

it 'does not allow stats_visibility to be outside STATS_VISIBILITY levels' do
ug = build(:user_group, name: 'abc')
ug.stats_visibility = 'fake_stats_level'
expect(ug).not_to be_valid
end

it 'does not allow stats_visibility to be outside STATS_VISIBILITY range' do
ug = build(:user_group, name: 'abc')
ug.stats_visibility = 9
expect(ug).not_to be_valid
end
end

describe "#users" do
let(:user_group) { create(:user_group_with_users) }

Expand Down

0 comments on commit 99a3a0c

Please sign in to comment.