enable prounoun changes via api v1 users
fixes VICE-963 setting a user's pronouns via the api will now work if the root account has can_change_pronouns enabled when a request passes "he/him", it gets stored as he_him: "He/Him" (official) if a request passes an unapproved pronoun, it will not get used if a request passes an empty string, users pronouns will get cleared out flag=none TEST PLAN: - shortcut: look at the new specs, make sure they cover cases you care about long version: - make sure can_add_pronouns and can_change pronouns are enabled in account settings - as an admin, make a PUT request to one of your users i.e. PUT /api/v1/users/:user_id_of_someone_in_your_account body: {users: {pronouns: 'anypronounyouwant'}} - verify that you were able to change the pronoun - repeat for a regular user but this time, for your own id - verify you were able to change your pronoun Change-Id: I9e72efe68833a5c77e6baec47e4918df5541f179 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/251478 Reviewed-by: Rob Orton <rob@instructure.com> Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> QA-Review: Rob Orton <rob@instructure.com> Product-Review: Rob Orton <rob@instructure.com>
This commit is contained in:
parent
4aa5d67d3a
commit
e36709adb1
|
@ -1776,6 +1776,8 @@ class UsersController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
include Pronouns
|
||||
|
||||
# @API Edit a user
|
||||
# Modify an existing user. To modify a user's login, see the documentation for logins.
|
||||
#
|
||||
|
@ -1822,6 +1824,12 @@ class UsersController < ApplicationController
|
|||
# Sets a bio on the user profile. (See {api:ProfileController#settings Get user profile}.)
|
||||
# Profiles must be enabled on the root account.
|
||||
#
|
||||
# @argument user[pronouns] [String]
|
||||
# Sets pronouns on the user profile.
|
||||
# Passing an empty string will empty the user's pronouns
|
||||
# Only Available Pronouns set on the root account are allowed
|
||||
# Adding and changing pronouns must be enabled on the root account.
|
||||
#
|
||||
# @example_request
|
||||
#
|
||||
# curl 'https://<canvas>/api/v1/users/133.json' \
|
||||
|
@ -1854,6 +1862,10 @@ class UsersController < ApplicationController
|
|||
managed_attributes << :title if @user.grants_right?(@current_user, :rename)
|
||||
end
|
||||
|
||||
if @domain_root_account.can_change_pronouns? && @user.grants_right?(@current_user, :manage_user_details)
|
||||
managed_attributes << :pronouns
|
||||
end
|
||||
|
||||
if @user.grants_right?(@current_user, :manage_user_details)
|
||||
managed_attributes.concat([:time_zone, :locale])
|
||||
end
|
||||
|
@ -1895,6 +1907,14 @@ class UsersController < ApplicationController
|
|||
includes << "bio"
|
||||
end
|
||||
|
||||
if (pronouns = user_params.delete(:pronouns))
|
||||
updated_pronoun = match_pronoun(pronouns, @domain_root_account.pronouns)
|
||||
if updated_pronoun || pronouns&.empty?
|
||||
@user.pronouns = updated_pronoun
|
||||
end
|
||||
includes << "pronouns"
|
||||
end
|
||||
|
||||
if admin_avatar_update
|
||||
old_avatar_state = @user.avatar_state
|
||||
@user.avatar_state = 'submitted'
|
||||
|
|
|
@ -45,4 +45,11 @@ module Pronouns
|
|||
pronouns
|
||||
end
|
||||
|
||||
def match_pronoun(supplied_pronouns_str, account_pronouns_arr)
|
||||
pronoun = clean_pronouns(supplied_pronouns_str)
|
||||
account_pronouns_arr.each do |ap|
|
||||
return ap if ap.casecmp(pronoun) == 0
|
||||
end
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1657,6 +1657,89 @@ describe "Users API", type: :request do
|
|||
end
|
||||
end
|
||||
|
||||
context 'pronouns' do
|
||||
context 'when can_change_pronouns=true' do
|
||||
before :once do
|
||||
Account.default.tap do |a|
|
||||
a.settings[:can_add_pronouns] = true
|
||||
a.settings[:can_change_pronouns] = true
|
||||
a.save!
|
||||
end
|
||||
end
|
||||
|
||||
it "should clear attribute when empty string is passed" do
|
||||
@student.pronouns = "He/Him"
|
||||
@student.save!
|
||||
json = api_call(:put, @path, @path_options, {:user => {:pronouns => ""}})
|
||||
expect(json['pronouns']).to be_nil
|
||||
expect(@student.reload.pronouns).to be_nil
|
||||
end
|
||||
|
||||
it "should update with a default pronoun" do
|
||||
approved_pronoun = "He/Him"
|
||||
json = api_call(:put, @path, @path_options, {:user => {:pronouns => approved_pronoun}})
|
||||
expect(json['pronouns']).to eq approved_pronoun
|
||||
expect(@student.reload.pronouns).to eq approved_pronoun
|
||||
expect(@student.read_attribute(:pronouns)).to eq "he_him"
|
||||
end
|
||||
|
||||
it "should fix the case when pronoun does not match default pronoun case" do
|
||||
wrong_case_pronoun = "he/him"
|
||||
expected_pronoun = "He/Him"
|
||||
json = api_call(:put, @path, @path_options, {:user => {:pronouns => wrong_case_pronoun}})
|
||||
expect(json['pronouns']).to eq expected_pronoun
|
||||
expect(@student.reload.pronouns).to eq expected_pronoun
|
||||
expect(@student.read_attribute(:pronouns)).to eq "he_him"
|
||||
end
|
||||
|
||||
it "should fix the case when pronoun does not match custom pronoun case" do
|
||||
Account.default.tap do |a|
|
||||
a.pronouns = ["Siya/Siya", "Ito/Iyan"]
|
||||
a.save!
|
||||
end
|
||||
wrong_case_pronoun = "ito/iyan"
|
||||
expected_pronoun = "Ito/Iyan"
|
||||
json = api_call(:put, @path, @path_options, {:user => {:pronouns => wrong_case_pronoun}})
|
||||
expect(json['pronouns']).to eq expected_pronoun
|
||||
expect(@student.reload.pronouns).to eq expected_pronoun
|
||||
expect(@student.read_attribute(:pronouns)).to eq expected_pronoun
|
||||
end
|
||||
|
||||
it "should not update when pronoun is not approved" do
|
||||
@student.pronouns = "She/Her"
|
||||
@student.save!
|
||||
original_pronoun = @student.pronouns
|
||||
unapproved_pronoun = "Unapproved/Unapproved"
|
||||
json = api_call(:put, @path, @path_options, {:user => {:pronouns => unapproved_pronoun}})
|
||||
expect(json['pronouns']).to eq original_pronoun
|
||||
expect(@student.reload.pronouns).to eq original_pronoun
|
||||
end
|
||||
end
|
||||
|
||||
context 'when can_change_pronouns=false' do
|
||||
before :once do
|
||||
Account.default.tap do |a|
|
||||
a.settings[:can_add_pronouns] = true
|
||||
a.settings[:can_change_pronouns] = false
|
||||
a.save!
|
||||
end
|
||||
end
|
||||
|
||||
it "errors" do
|
||||
@student.pronouns = "She/Her"
|
||||
@student.save!
|
||||
original_pronoun = @student.pronouns
|
||||
test_pronoun = "He/Him"
|
||||
raw_api_call(:put, @path, @path_options, {:user => {:pronouns => test_pronoun}})
|
||||
json = JSON.parse(response.body)
|
||||
expect(response.code).to eq '401'
|
||||
expect(json['status']).to eq 'unauthorized'
|
||||
expect(json['errors'][0]['message']).to eq 'user not authorized to perform that action'
|
||||
expect(@student.reload.pronouns).to eq original_pronoun
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "should be able to update a user's profile" do
|
||||
Account.default.tap{|a| a.settings[:enable_profiles] = true; a.save!}
|
||||
new_title = "Burninator"
|
||||
|
@ -1781,6 +1864,27 @@ describe "Users API", type: :request do
|
|||
course_with_teacher user: @user, active_all: true
|
||||
end
|
||||
|
||||
context 'pronouns' do
|
||||
it "returns an error when user does not have manage rights" do
|
||||
Account.default.tap do |a|
|
||||
a.settings[:can_add_pronouns] = true
|
||||
a.settings[:can_change_pronouns] = true
|
||||
a.save!
|
||||
end
|
||||
|
||||
@student.pronouns = "She/Her"
|
||||
@student.save!
|
||||
original_pronoun = @student.pronouns
|
||||
test_pronoun = "He/Him"
|
||||
raw_api_call(:put, @path, @path_options, {:user => {:pronouns => test_pronoun}})
|
||||
json = JSON.parse(response.body)
|
||||
expect(response.code).to eq '401'
|
||||
expect(json['status']).to eq 'unauthorized'
|
||||
expect(json['errors'][0]['message']).to eq 'user not authorized to perform that action'
|
||||
expect(@student.reload.pronouns).to eq original_pronoun
|
||||
end
|
||||
end
|
||||
|
||||
context "with users_can_edit_name enabled" do
|
||||
before :once do
|
||||
@course.root_account.settings = { users_can_edit_name: true }
|
||||
|
|
Loading…
Reference in New Issue