Factor out Catapult connection

Stephen Paul Weber created

So that every object which needs to talk to Catapult does not need to know
everthing about it.

Change summary

Gemfile                             |  1 
lib/bandwidth_tn_order.rb           | 31 +++-----------------
lib/catapult.rb                     | 45 +++++++++++++++++++++++++++++++
test/data/catapult_import_body.json |  2 
4 files changed, 52 insertions(+), 27 deletions(-)

Detailed changes

Gemfile 🔗

@@ -14,6 +14,7 @@ gem "eventmachine"
 gem "money-open-exchange-rates"
 gem "ruby-bandwidth-iris"
 gem "sentry-ruby"
+gem "value_semantics", git: "https://github.com/singpolyma/value_semantics"
 
 group(:development) do
 	gem "pry-reload"

lib/bandwidth_tn_order.rb 🔗

@@ -4,6 +4,8 @@ require "forwardable"
 require "ruby-bandwidth-iris"
 Faraday.default_adapter = :em_synchrony
 
+require_relative "./catapult"
+
 class BandwidthTNOrder
 	def self.get(id)
 		EM.promise_fiber do
@@ -86,35 +88,12 @@ class BandwidthTNOrder
 
 		# After buying, import to catapult and set v1 voice app
 		def catapult_import
-			catapult_request.apost(
-				head: catapult_headers,
-				body: {
-					number: tel,
-					applicationId: catapult[:application_id],
-					provider: dashboard_provider
-				}.to_json
-			)
-		end
-
-		def catapult
-			CONFIG[:catapult]
-		end
-
-		def catapult_request
-			EM::HttpRequest.new(
-				"https://api.catapult.inetwork.com/v1/users/" \
-				"#{catapult[:user]}/phoneNumbers",
-				tls: { verify_peer: true }
+			CATAPULT.import(
+				number: tel,
+				provider: dashboard_provider
 			)
 		end
 
-		def catapult_headers
-			{
-				"Authorization" => [catapult[:token], catapult[:secret]],
-				"Content-Type" => "application/json"
-			}
-		end
-
 		def dashboard_provider
 			{
 				providerName: "bandwidth-dashboard",

lib/catapult.rb 🔗

@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require "value_semantics/monkey_patched"
+
+class Catapult
+	value_semantics do
+		user String
+		token String
+		secret String
+		application_id String
+	end
+
+	def import(body)
+		post(
+			"phoneNumbers",
+			body: { applicationId: application_id }.merge(body)
+		)
+	end
+
+	def post(path, body:, head: {})
+		EM::HttpRequest.new(
+			mkurl(path), tls: { verify_peer: true }
+		).apost(
+			head: catapult_headers.merge(head),
+			body: body.to_json
+		)
+	end
+
+	def mkurl(path)
+		base = "https://api.catapult.inetwork.com/v1/users/#{@user}/"
+		return path if path.start_with?(base)
+		"#{base}#{path}"
+	end
+
+protected
+
+	def catapult_headers
+		{
+			"Authorization" => [@token, @secret],
+			"Content-Type" => "application/json"
+		}
+	end
+end
+
+CATAPULT = Catapult.new(**CONFIG[:catapult])

test/data/catapult_import_body.json 🔗

@@ -1 +1 @@
-{"number":"+15555550000","applicationId":"catapult_app","provider":{"providerName":"bandwidth-dashboard","properties":{"accountId":"test_bw_account","userName":"test_bw_user","password":"test_bw_password"}}}
+{"applicationId":"catapult_app","number":"+15555550000","provider":{"providerName":"bandwidth-dashboard","properties":{"accountId":"test_bw_account","userName":"test_bw_user","password":"test_bw_password"}}}