diff --git a/Gemfile b/Gemfile index 2f5d85e9..0995f11f 100644 --- a/Gemfile +++ b/Gemfile @@ -11,7 +11,6 @@ gem "aws-sdk-s3" gem "bootsnap", require: false gem "gds-api-adapters" gem "gds-sso" -gem "gds_zendesk" gem "govuk_app_config" gem "govuk_sidekiq" gem "kaminari" @@ -22,6 +21,7 @@ gem "plek" gem "sentry-sidekiq" gem "user_agent_parser" gem "whenever", require: false +gem "zendesk_api" group :development do gem "listen" diff --git a/Gemfile.lock b/Gemfile.lock index 29bd506f..7f3e931d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -156,9 +156,6 @@ GEM rails (>= 7) warden (~> 1.2) warden-oauth2 (~> 0.0.1) - gds_zendesk (3.7.0) - null_logger (~> 0) - zendesk_api (>= 1.37, < 4.0) globalid (1.2.1) activesupport (>= 6.1) google-protobuf (4.27.2) @@ -738,7 +735,6 @@ DEPENDENCIES factory_bot_rails gds-api-adapters gds-sso - gds_zendesk govuk_app_config govuk_sidekiq kaminari @@ -762,6 +758,7 @@ DEPENDENCIES user_agent_parser webmock whenever + zendesk_api BUNDLED WITH 2.5.9 diff --git a/config/initializers/gds_zendesk.rb b/config/initializers/gds_zendesk.rb index eec76a55..ac891fb0 100644 --- a/config/initializers/gds_zendesk.rb +++ b/config/initializers/gds_zendesk.rb @@ -1,15 +1,17 @@ require "yaml" -require "gds_zendesk/client" -require "gds_zendesk/dummy_client" +require "zendesk_api" +require "zendesk/dummy_client" +GDS_ZENDESK_URL = "https://govuk.zendesk.com/api/v2/".freeze ZENDESK_ANONYMOUS_TICKETS_REQUESTER_EMAIL = ENV["ZENDESK_ANONYMOUS_TICKET_EMAIL"] || "api-user@example.com" GDS_ZENDESK_CLIENT = if Rails.env.development? - GDSZendesk::DummyClient.new(logger: Rails.logger) + Zendesk::DummyClient.new(logger: Rails.logger) else - GDSZendesk::Client.new( - username: ENV["ZENDESK_CLIENT_USERNAME"] || "abc", - password: ENV["ZENDESK_CLIENT_PASSWORD"] || "def", - logger: Rails.logger, - ) + ZendeskAPI::Client.new do |config| + config.url = GDS_ZENDESK_URL + config.username = ENV["ZENDESK_CLIENT_USERNAME"] || "abc" + config.password = ENV["ZENDESK_CLIENT_PASSWORD"] || "def" + config.logger = Rails.logger + end end diff --git a/lib/zendesk/dummy_client.rb b/lib/zendesk/dummy_client.rb new file mode 100644 index 00000000..3638633d --- /dev/null +++ b/lib/zendesk/dummy_client.rb @@ -0,0 +1,63 @@ +require "zendesk_api/error" + +module Zendesk + class DummyClient + attr_reader :ticket, :users + + def initialize(options) + @logger = options[:logger] + @ticket = DummyTicket.new(@logger) + @users = DummyUsers.new(@logger) + end + end + + class DummyTicket + attr_reader :options + + def initialize(logger) + @logger = logger + end + + def create!(options) + @options = options + if should_raise_error? + @logger.info("Simulating Zendesk ticket creation failure: #{options.inspect}") + raise ZendeskAPI::Error::RecordInvalid.new(body: { "details" => "sample error message from Zendesk" }) + else + @logger.info("Zendesk ticket created: #{options.inspect}") + end + end + + protected + + def should_raise_error? + description =~ /break_zendesk/ or comment =~ /break_zendesk/ + end + + def description + @options[:description] + end + + def comment + @options[:comment][:value] unless @options[:comment].nil? + end + end + + class DummyUsers + def initialize(logger) + @logger = logger + end + + def search(_attributes) + [] + end + + def suspended?(_user_email) + false + end + + def create_or_update_user(new_attributes) + @logger.info("Zendesk user created or updated: #{new_attributes.inspect}") + end + end +end diff --git a/spec/helpers/zendesk_test_helpers.rb b/spec/helpers/zendesk_test_helpers.rb new file mode 100644 index 00000000..a782390d --- /dev/null +++ b/spec/helpers/zendesk_test_helpers.rb @@ -0,0 +1,27 @@ +require "json" + +module Zendesk + module TestHelpers + def stub_zendesk_ticket_creation(ticket_properties = nil) + stub = stub_request(:post, "#{zendesk_endpoint}/tickets") + stub.with(body: { ticket: ticket_properties }) unless ticket_properties.nil? + stub.to_return(status: 201, body: { ticket: { id: 12_345 } }.to_json, + headers: { "Content-Type" => "application/json" }) + end + + def stub_zendesk_ticket_creation_with_body(body) + stub_request(:post, "#{zendesk_endpoint}/tickets") + .with(body:) + .to_return(status: 201, body: { ticket: { id: 12_345 } }.to_json, + headers: { "Content-Type" => "application/json" }) + end + + def expect_zendesk_to_receive_ticket(opts) + stub_zendesk_ticket_creation_with_body("ticket" => hash_including(opts)) + end + + def zendesk_endpoint + "https://govuk.zendesk.com/api/v2" + end + end +end diff --git a/spec/lib/zendesk_dummy_client_spec.rb b/spec/lib/zendesk_dummy_client_spec.rb new file mode 100644 index 00000000..6cf02a82 --- /dev/null +++ b/spec/lib/zendesk_dummy_client_spec.rb @@ -0,0 +1,43 @@ +require "zendesk/dummy_client" + +module Zendesk + describe DummyClient do + context "when a ticket has been raised" do + let(:ticket_options) { { opt1: "val1" } } + + it "logs the ticket details" do + logger = instance_double(Logger) + expect(logger).to receive(:info).with("Zendesk ticket created: #{ticket_options.inspect}") + + client = described_class.new(logger:) + client.ticket.create!(ticket_options) + end + + it "can simulate failures, triggered by a specific description or comment" do + logger = instance_double(Logger) + client = described_class.new(logger:) + expect(logger).to receive(:info).with(/Simulating Zendesk ticket creation failure/).twice + + expect { + client.ticket.create!(description: "break_zendesk") + }.to raise_error(ZendeskAPI::Error::RecordInvalid) + + expect { + client.ticket.create!(comment: { value: "break_zendesk" }) + }.to raise_error(ZendeskAPI::Error::RecordInvalid) + end + end + + context "when a user has been created" do + let(:options) { { email: "a@b.com" } } + + it "logs the user details" do + logger = instance_double(Logger) + expect(logger).to receive(:info).with("Zendesk user created or updated: #{options.inspect}") + + client = described_class.new(logger:) + client.users.create_or_update_user(options) + end + end + end +end diff --git a/spec/support/gds_zendesk_helpers.rb b/spec/support/gds_zendesk_helpers.rb index 474d4d42..54c48834 100644 --- a/spec/support/gds_zendesk_helpers.rb +++ b/spec/support/gds_zendesk_helpers.rb @@ -1,12 +1,5 @@ -require "gds_zendesk/test_helpers" - -module ZendeskRequestMockingExtensions - def expect_zendesk_to_receive_ticket(opts) - stub_zendesk_ticket_creation_with_body("ticket" => hash_including(opts)) - end -end +require "helpers/zendesk_test_helpers" RSpec.configure do |c| - c.include GDSZendesk::TestHelpers - c.include ZendeskRequestMockingExtensions + c.include Zendesk::TestHelpers end