allow observers to reply to observee chats

fixes VICE-978
flag=none

the reply button only shows when the controller
sends a falsy cannot_reply or does not send it at all

this makes sure replies_locked_for? - which
determines whether to send cannot_reply,
evaluates to false if the observer is
observing everyone else from participants

test plan:
- have a course with a student who has a linked observer
- as the student, message your observer
- as the observer go to inbox
- click on your message from student
- verify that you now see the reply button
- click reply button and send reply
- verify that reply was sent successfully

Change-Id: I6d579b44098e3e5310b5846ff867929041023887
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/253013
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Rob Orton <rob@instructure.com>
QA-Review: Rob Orton <rob@instructure.com>
Product-Review: Rob Orton <rob@instructure.com>
This commit is contained in:
Caleb Guanzon 2020-11-17 12:54:14 -07:00
parent 601438f634
commit 41583b7bad
2 changed files with 48 additions and 0 deletions

View File

@ -751,11 +751,20 @@ class Conversation < ActiveRecord::Base
# can still reply if a teacher is involved # can still reply if a teacher is involved
if course.is_a?(Course) && self.conversation_participants.where(:user_id => course.admin_enrollments.active.select(:user_id)).exists? if course.is_a?(Course) && self.conversation_participants.where(:user_id => course.admin_enrollments.active.select(:user_id)).exists?
false false
# can still reply if observing all the other participants
elsif course.is_a?(Course) && observing_all_other_participants(user, self.conversation_participants, course)
false
else else
!self.context.grants_any_right?(user, :send_messages, :send_messages_all) !self.context.grants_any_right?(user, :send_messages, :send_messages_all)
end end
end end
def observing_all_other_participants(user, participants, course)
observee_ids = user.observer_enrollments.active.where(course: course).pluck(:associated_user_id)
return false if observee_ids.empty?
(conversation_participants.pluck(:user_id) - observee_ids - [user.id]).empty?
end
protected protected
def maybe_update_timestamp(col, val, additional_conditions=[]) def maybe_update_timestamp(col, val, additional_conditions=[])

View File

@ -50,8 +50,10 @@ describe ConversationsController, type: :request do
def observer_in_course(options = {}) def observer_in_course(options = {})
section = options.delete(:section) section = options.delete(:section)
associated_user = options.delete(:associated_user)
u = User.create(options) u = User.create(options)
enrollment = @course.enroll_user(u, 'ObserverEnrollment', :section => section) enrollment = @course.enroll_user(u, 'ObserverEnrollment', :section => section)
enrollment.associated_user = associated_user
enrollment.workflow_state = 'active' enrollment.workflow_state = 'active'
enrollment.save enrollment.save
u u
@ -1340,6 +1342,43 @@ describe ConversationsController, type: :request do
expect(json["cannot_reply"]).to eq true expect(json["cannot_reply"]).to eq true
end end
context "as an observer" do
before :once do
@bobs_mom = observer_in_course(:name => "bob's mom", :associated_user => @bob)
@user = @bobs_mom
end
it "should not set cannot_reply for observer observee relationship" do
conversation = conversation(@bobs_mom, :sender => @bob, :context_type => "Course", :context_id => @course.id)
json = api_call(
:get,
"/api/v1/conversations/#{conversation.conversation_id}",
{ controller: 'conversations',
action: 'show',
id: conversation.conversation_id.to_s,
format: 'json' }
)
expect(json["cannot_reply"]).to be_nil
end
it "should set cannot_reply to true if non-observed student" do
conversation = conversation(@bobs_mom, :sender => @billy, :context_type => "Course", :context_id => @course.id)
json = api_call(
:get,
"/api/v1/conversations/#{conversation.conversation_id}",
{ controller: 'conversations',
action: 'show',
id: conversation.conversation_id.to_s,
format: 'json' }
)
expect(json["cannot_reply"]).to eq true
end
end
it "should not explode on account group conversations" do it "should not explode on account group conversations" do
@user = @billy @user = @billy
group group