From 770d9fc1528e6528b07173db02a91f1461f61902 Mon Sep 17 00:00:00 2001 From: Aga Dufrat Date: Thu, 8 Aug 2024 12:39:41 +0100 Subject: [PATCH] Check if requester is suspended before creating Zendesk ticket It's not possible to create Zendesk ticket if a requester is suspended in Zendesk. The following error is raised: ZendeskAPI::Error::RecordInvalid: {"requester"=>[{"description"=>"Requester: is suspended."}]} (ZendeskAPI::Error::RecordInvalid) We don't want to rescue ZendeskAPI::Error::RecordInvalid as this error is raised for other issue such as incorrect formatting. Suspended users can be found https://govuk.zendesk.com/agent/user_filters --- app/models/support_ticket.rb | 16 +++++++ spec/helpers/zendesk_test_helpers.rb | 18 ++++++++ spec/models/support_ticket_spec.rb | 64 ++++++++++++++++++++++++++- spec/requests/support_tickets_spec.rb | 6 ++- 4 files changed, 100 insertions(+), 4 deletions(-) diff --git a/app/models/support_ticket.rb b/app/models/support_ticket.rb index 9c3fee05..f24bff87 100644 --- a/app/models/support_ticket.rb +++ b/app/models/support_ticket.rb @@ -3,6 +3,8 @@ class SupportTicket validates :subject, :description, presence: true + validate :requester_not_suspended, if: :requester_email? + def initialize(attributes) @subject = attributes.fetch(:subject, nil) @description = attributes.fetch(:description, nil) @@ -29,5 +31,19 @@ def zendesk_ticket_attributes private + def requester_not_suspended + errors.add(:requester, "is suspended in Zendesk") if suspended_in_zendesk? + end + + def suspended_in_zendesk? + user_search_result = GDS_ZENDESK_CLIENT.users.search(query: requester[:email]) + + user_search_result.empty? ? false : user_search_result.first["suspended"] + end + + def requester_email? + requester && requester[:email] + end + attr_reader :subject, :description, :priority, :requester, :collaborators, :tags, :custom_fields, :ticket_form_id end diff --git a/spec/helpers/zendesk_test_helpers.rb b/spec/helpers/zendesk_test_helpers.rb index a782390d..539b32f1 100644 --- a/spec/helpers/zendesk_test_helpers.rb +++ b/spec/helpers/zendesk_test_helpers.rb @@ -20,6 +20,24 @@ def expect_zendesk_to_receive_ticket(opts) stub_zendesk_ticket_creation_with_body("ticket" => hash_including(opts)) end + def zendesk_has_no_user_with_email(email) + stub_request(:get, "#{zendesk_endpoint}/users/search?query=#{email}") + .to_return(body: { users: [], previous_page: nil, next_page: nil, count: 0 }.to_json, + headers: { "Content-Type" => "application/json" }) + end + + def zendesk_has_suspended_user_with_email(email) + stub_request(:get, "#{zendesk_endpoint}/users/search?query=#{email}") + .to_return(body: { users: [{ email:, suspended: true }] }.to_json, + headers: { "Content-Type" => "application/json" }) + end + + def zendesk_has_valid_user_with_email(email) + stub_request(:get, "#{zendesk_endpoint}/users/search?query=#{email}") + .to_return(body: { users: [{ email:, suspended: false }] }.to_json, + headers: { "Content-Type" => "application/json" }) + end + def zendesk_endpoint "https://govuk.zendesk.com/api/v2" end diff --git a/spec/models/support_ticket_spec.rb b/spec/models/support_ticket_spec.rb index 735a7378..dcf36178 100644 --- a/spec/models/support_ticket_spec.rb +++ b/spec/models/support_ticket_spec.rb @@ -1,6 +1,13 @@ require "rails_helper" describe SupportTicket, "validations" do + let(:required_atrributes) do + { + subject: "Feedback for app", + description: "Ticket details go here.", + } + end + it "validates presence of subject" do support_ticket = described_class.new({}) support_ticket.valid? @@ -14,6 +21,59 @@ expect(support_ticket.errors.messages.to_h).to include(description: include("can't be blank")) end + + describe "#requester_not_suspended validation" do + it "is invalid if requester is suspended in Zendesk" do + zendesk_has_suspended_user_with_email("suspended-user@example.com") + + support_ticket = described_class.new( + required_atrributes.merge( + requester: { "locale_id" => 1, email: "suspended-user@example.com", "name" => "Naughtly user" }, + ), + ) + support_ticket.valid? + + expect(support_ticket.errors.messages.to_h).to include(requester: include("is suspended in Zendesk")) + end + + it "is valid if requester is not suspended in Zendesk" do + zendesk_has_valid_user_with_email("ok-user@example.com") + + support_ticket = described_class.new( + required_atrributes.merge( + { requester: { email: "ok-user@example.com" } }, + ), + ) + expect(support_ticket.valid?).to eq(true) + end + + it "is valid if Zendesk doesn't have user with this email address" do + zendesk_has_no_user_with_email("user@example.com") + + support_ticket = described_class.new( + required_atrributes.merge( + { requester: { "email" => "user@example.com", "name" => "User" } }, + ), + ) + + expect(support_ticket.valid?).to eq(true) + end + + it "doesn't validate if requester attribute is not provided" do + support_ticket = described_class.new(required_atrributes) + + expect(support_ticket.valid?).to eq(true) + end + + it "doesn't validate if requester email attribute is not provided" do + support_ticket = described_class.new( + required_atrributes.merge( + { requester: { "name" => "Some app" } }, + ), + ) + expect(support_ticket.valid?).to eq(true) + end + end end describe SupportTicket, "#zendesk_ticket_attributes" do @@ -22,7 +82,7 @@ subject: "Feedback for app", description: "Ticket details go here.", priority: "normal", - requester: { "locale_id" => 1, "email" => "someone@exampe.com", "name" => "Some user" }, + requester: { "locale_id" => 1, "email" => "someone@example.com", "name" => "Some user" }, collaborators: %w[a@b.com c@d.com], tags: %w[app_name], custom_fields: [ @@ -38,7 +98,7 @@ "body" => "Ticket details go here.", }, "priority" => "normal", - "requester" => { "locale_id" => 1, "email" => "someone@exampe.com", "name" => "Some user" }, + "requester" => { "locale_id" => 1, "email" => "someone@example.com", "name" => "Some user" }, "collaborators" => %w[a@b.com c@d.com], "tags" => %w[app_name], "custom_fields" => [ diff --git a/spec/requests/support_tickets_spec.rb b/spec/requests/support_tickets_spec.rb index a012a5ca..c9070995 100644 --- a/spec/requests/support_tickets_spec.rb +++ b/spec/requests/support_tickets_spec.rb @@ -3,6 +3,7 @@ describe "Support Tickets" do it "responds succesfully" do stub_zendesk_ticket_creation + zendesk_has_valid_user_with_email("someone@example.com") post "/support-tickets", params: { @@ -10,7 +11,7 @@ tags: %w[app_name], description: "Ticket details go here.", priority: "normal", - requester: { locale_id: 1, email: "someone@exampe.com", name: "Some user" }, + requester: { locale_id: 1, email: "someone@example.com", name: "Some user" }, collaborators: %w[a@b.com c@d.com], custom_fields: [ { id: 7_948_652_819_356, value: "cr_inaccuracy" }, @@ -24,6 +25,7 @@ end it "sends the feedback to Zendesk" do + zendesk_has_valid_user_with_email("someone@example.com") zendesk_request = expect_zendesk_to_receive_ticket( "subject" => "Feedback for app", "tags" => %w[app_name], @@ -36,7 +38,7 @@ params: { subject: "Feedback for app", tags: %w[app_name], - requester: { locale_id: 1, email: "someone@exampe.com", name: "Some user" }, + requester: { locale_id: 1, email: "someone@example.com", name: "Some user" }, description: "Ticket details go here.", }