diff --git a/app/controllers/api/v1/user_groups_controller.rb b/app/controllers/api/v1/user_groups_controller.rb index 08a3dc48e..1234d486b 100644 --- a/app/controllers/api/v1/user_groups_controller.rb +++ b/app/controllers/api/v1/user_groups_controller.rb @@ -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(" ")) diff --git a/app/models/user_group.rb b/app/models/user_group.rb index 9d51da007..a9a81882b 100644 --- a/app/models/user_group.rb +++ b/app/models/user_group.rb @@ -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, @@ -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 diff --git a/spec/controllers/api/v1/user_groups_controller_spec.rb b/spec/controllers/api/v1/user_groups_controller_spec.rb index 3b22a6d43..a1c22ce26 100644 --- a/spec/controllers/api/v1/user_groups_controller_spec.rb +++ b/spec/controllers/api/v1/user_groups_controller_spec.rb @@ -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 @@ -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 diff --git a/spec/models/user_group_spec.rb b/spec/models/user_group_spec.rb index 350cbbad4..6b8b847d9 100644 --- a/spec/models/user_group_spec.rb +++ b/spec/models/user_group_spec.rb @@ -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) }