Allow discussion user roles to be retrieved without extra variable

refs VICE-4101
flag=react_discussion

Test Plan
1. In graphiql you should be able to get
a discussion author's or editor's course roles
without passing in the course_id

Change-Id: I2f8be036f6a145211a78829cfe2e49b3041cd8ad
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/341158
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Omar Soto-Fortuño <omar.soto@instructure.com>
Product-Review: Omar Soto-Fortuño <omar.soto@instructure.com>
QA-Review: Caleb Guanzon <cguanzon@instructure.com>
This commit is contained in:
Jason Gillett 2024-02-23 10:08:10 -07:00
parent ccf5eec83c
commit 7679d5b3b9
5 changed files with 46 additions and 13 deletions

View File

@ -77,6 +77,9 @@ module Types
end
def author(course_id: nil, role_types: nil, built_in_only: false)
load_association(:discussion_topic).then do |topic|
course_id = topic&.course&.id if course_id.nil?
# Set the graphql context so it can be used downstream
context[:course_id] = course_id
if topic.anonymous? && object.is_anonymous_author
nil
else
@ -84,7 +87,6 @@ module Types
if !topic.anonymous? || !user
user
else
course_id = topic.course.id if course_id.nil?
Loaders::CourseRoleLoader.for(course_id:, role_types:, built_in_only:).load(user).then do |roles|
if roles&.include?("TeacherEnrollment") || roles&.include?("TaEnrollment") || roles&.include?("DesignerEnrollment") || (topic.anonymous_state == "partial_anonymity" && !object.is_anonymous_author)
user
@ -127,6 +129,9 @@ module Types
end
def editor(course_id: nil, role_types: nil, built_in_only: false)
load_association(:discussion_topic).then do |topic|
course_id = topic&.course&.id if course_id.nil?
# Set the graphql context so it can be used downstream
context[:course_id] = course_id
if topic.anonymous? && !course_id
nil
else

View File

@ -182,14 +182,19 @@ module Types
argument :built_in_only, Boolean, "Only return default/built_in roles", required: false
end
def author(course_id: nil, role_types: nil, built_in_only: false)
if object.anonymous? && !course_id
# Conditionally set course_id based on whether it's provided or should be inferred from the object
resolved_course_id = course_id.nil? ? object&.course&.id : course_id
# Set the graphql context so it can be used downstream
context[:course_id] = resolved_course_id
if object.anonymous? && resolved_course_id.nil?
nil
else
load_association(:user).then do |user|
if !object.anonymous? || !user
if !object.anonymous? || user.nil?
user
else
Loaders::CourseRoleLoader.for(course_id:, role_types:, built_in_only:).load(user).then do |roles|
Loaders::CourseRoleLoader.for(course_id: resolved_course_id, role_types:, built_in_only:).load(user).then do |roles|
if roles&.include?("TeacherEnrollment") || roles&.include?("TaEnrollment") || roles&.include?("DesignerEnrollment") || (object.anonymous_state == "partial_anonymity" && !object.is_anonymous_author)
user
end
@ -224,7 +229,11 @@ module Types
argument :built_in_only, Boolean, "Only return default/built_in roles", required: false
end
def editor(course_id: nil, role_types: nil, built_in_only: false)
if object.anonymous? && !course_id
# Conditionally set course_id based on whether it's provided or should be inferred from the object
resolved_course_id = course_id.nil? ? object&.course&.id : course_id
# Set the graphql context so it can be used downstream
context[:course_id] = resolved_course_id
if object.anonymous? && !resolved_course_id
nil
else
load_association(:editor).then do |user|

View File

@ -470,13 +470,11 @@ module Types
argument :built_in_only, Boolean, "Only return default/built_in roles", required: false
end
def course_roles(course_id: nil, role_types: nil, built_in_only: true)
# The discussion only role "Author" will be handled with a front-end check because graphql
# currently does not support type inheritance. If graphql starts supporting type inheritance
# this field can be replaced by a discussionAuthor type that inherits from User type and
# contains a discussionRoles field
return if course_id.nil?
# This graphql execution context can be used to set course_id if you are calling course_role from a nested query
resolved_course_id = course_id.nil? ? context[:course_id] : course_id
return if resolved_course_id.nil?
Loaders::CourseRoleLoader.for(course_id:, role_types:, built_in_only:).load(object)
Loaders::CourseRoleLoader.for(course_id: resolved_course_id, role_types:, built_in_only:).load(object)
end
field :inbox_labels, [String], null: true

View File

@ -60,7 +60,9 @@ describe Types::DiscussionEntryType do
expect(type.resolve("ratingCount")).to eq parent_entry.rating_count
expect(type.resolve("deleted")).to eq parent_entry.deleted?
expect(type.resolve("author { _id }")).to eq parent_entry.user_id.to_s
expect(type.resolve("author { courseRoles }")).to eq ["TeacherEnrollment"]
expect(type.resolve("editor { _id }")).to eq parent_entry.editor_id.to_s
expect(type.resolve("editor { courseRoles }")).to eq ["TeacherEnrollment"]
expect(type.resolve("discussionTopic { _id }")).to eq parent_entry.discussion_topic.id.to_s
expect(type.resolve("depth")).to eq parent_entry.depth
end

View File

@ -411,8 +411,8 @@ RSpec.shared_examples "DiscussionType" do
)
end
it "author is nil" do
expect(@anon_discussion_type.resolve("author { shortName }")).to be_nil
it "teacher author is not nil" do
expect(@anon_discussion_type.resolve("author { shortName }")).to eq @teacher.short_name
end
it "editor is nil" do
@ -745,6 +745,25 @@ describe Types::DiscussionType do
expect(@past_delayed_type_with_student.resolve("discussionEntriesConnection { nodes { message } }").count).to eq 1
end
end
describe "discussion user roles" do
before do
authored_discussion = DiscussionTopic.create!(title: "Welcome whoever you are",
message: "authored",
context: @course,
user: @teacher,
editor: @teacher)
@discusion_teacher_author = GraphQLTypeTester.new(authored_discussion, current_user: @teacher)
end
it "finds author course roles without extra variables" do
expect(@discusion_teacher_author.resolve("author { courseRoles }")).to eq(["TeacherEnrollment"])
end
it "finds editor course roles without extra variables" do
expect(@discusion_teacher_author.resolve("editor { courseRoles }")).to eq(["TeacherEnrollment"])
end
end
end
context "group discussion" do