add mutation for deleting Conversations

fixes VICE-871
flag=react_inbox

test plan:
  - create a conversation with messages between two users
  - as a user not in the conversation
    - navigate to /graphiql
    - add a new mutation
    - use the deleteConversation to attempt to delete
      all messages from the conversation
      - this should fail due to insufficient permissions
  - as a user in the conversation
    - navigate to /graphiql
    - attempt to delete a conversation that doesn't exist
      - this should fail to unfound Conversation
    - attempt to delete a conversation that does exist
      - this should succeed

qa risk: low

Change-Id: Iea7a02fa9e22e0ebd122dd4bab6e52f91bc3004d
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/254756
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Caleb Guanzon <cguanzon@instructure.com>
QA-Review: Caleb Guanzon <cguanzon@instructure.com>
Product-Review: Caleb Guanzon <cguanzon@instructure.com>
This commit is contained in:
Davis Hyer 2020-12-09 12:49:51 -07:00
parent d53319aba1
commit d133a9d96e
4 changed files with 127 additions and 0 deletions

View File

@ -140,6 +140,7 @@ class AuditLogFieldExtension < GraphQL::Schema::FieldExtension
next if mutation == Mutations::UpdateNotificationPreferences
next if mutation == Mutations::CreateConversation
next if mutation == Mutations::DeleteConversationMessage
next if mutation == Mutations::DeleteConversation
logger = Logger.new(mutation, context, arguments)

View File

@ -0,0 +1,42 @@
# frozen_string_literal: true
#
# Copyright (C) 2020 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
class Mutations::DeleteConversation < Mutations::BaseMutation
graphql_name "DeleteConversation"
# input arguments
argument :id, ID, required: true, prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func('Conversation')
field :conversation_id, ID, null: false
def resolve(input:)
conversation = Conversation.find_by(id: input[:id])
raise GraphQL::ExecutionError, "Unable to find Conversation" if conversation.nil?
participant_record = current_user.all_conversations.find_by(conversation_id: conversation.id)
raise GraphQL::ExecutionError, "insufficient permissions" if participant_record.nil?
participant_record.remove_messages(:all)
{conversation_id: conversation.id}
rescue ActiveRecord::RecordInvalid => invalid
errors_for(invalid.record)
end
end

View File

@ -69,6 +69,7 @@ class Types::MutationType < Types::ApplicationObjectType
field :create_module, mutation: Mutations::CreateModule
field :update_notification_preferences, mutation: Mutations::UpdateNotificationPreferences
field :delete_conversation_message, mutation: Mutations::DeleteConversationMessage
field :delete_conversation, mutation: Mutations::DeleteConversation
# TODO: Remove the in active development string from here once this is more
# finalized.

View File

@ -0,0 +1,83 @@
# frozen_string_literal: true
#
# Copyright (C) 2020 - present Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
require "spec_helper"
require_relative "../graphql_spec_helper"
describe Mutations::DeleteConversation do
before :once do
@sender = user_model
@conversation = conversation(@sender, user_model).conversation
end
def execute_with_input(delete_input, user_executing: @sender)
mutation_command = <<~GQL
mutation {
deleteConversation(input: {
#{delete_input}
}) {
conversationId
errors {
attribute
message
}
}
}
GQL
context = {current_user: user_executing, request: ActionDispatch::TestRequest.create}
CanvasSchema.execute(mutation_command, context: context)
end
it "removes all messages from the participant's view" do
query = <<~QUERY
id: #{@conversation.id}
QUERY
expect(@sender.all_conversations.find_by(conversation: @conversation).messages.length).to eq 1
result = execute_with_input(query)
expect(result.dig('errors')).to be_nil
expect(result.dig('data', 'deleteConversation', 'errors')).to be_nil
expect(result.dig('data', 'deleteConversation', 'conversationId')).to eq @conversation.id.to_s
expect(@sender.all_conversations.find_by(conversation: @conversation).messages.length).to eq 0
end
context "errors" do
def expect_error(result, message)
errors = result.dig('errors') || result.dig('data', 'deleteConversation', 'errors')
expect(errors).not_to be_nil
expect(errors[0]['message']).to match(/#{message}/)
end
it "fails if the conversation doesn't exist" do
query = <<~QUERY
id: #{Conversation.maximum(:id).next}
QUERY
result = execute_with_input(query)
expect_error(result, 'Unable to find Conversation')
end
it "fails if the requesting user is not a participant" do
query = <<~QUERY
id: #{@conversation.id}
QUERY
result = execute_with_input(query, user_executing: user_model)
expect_error(result, 'insufficient permissions')
end
end
end