refactor: fetch snikket invites from repo class

Phillip Davis created

Change summary

lib/snikket.rb       | 42 ++++++++++++++++++++++++++++++++----------
test/test_snikket.rb | 42 ++++++++++++++++++++++++++++++++----------
2 files changed, 64 insertions(+), 20 deletions(-)

Detailed changes

lib/snikket.rb 🔗

@@ -277,6 +277,37 @@ module Snikket
 	end
 
 	class CustomerInstance
+		class InviteRepo
+			def initialize(bootstrap_uri:)
+				@bootstrap_uri = bootstrap_uri
+			end
+
+			def fetch
+				url = bootstrap_uri
+				req(url).then { |res|
+					parse_invite(url, res)
+				}.catch { nil }
+			end
+
+		protected
+
+			attr_reader :bootstrap_uri
+
+			def req(url)
+				EM::HttpRequest.new(
+					url, tls: { verify_peer: true }
+				).ahead(redirects: 5)
+			end
+
+			def parse_invite(url, res)
+				LinkHeaderParser.parse(
+					Array(res.response_header["LINK"]), base_uri: url
+				).group_by_relation_type["alternate"]&.find do |header|
+					URI.parse(header.target_uri).scheme == "xmpp"
+				end&.target_uri
+			end
+		end
+
 		def self.for(customer, domain, launched)
 			new(
 				instance_id: launched.instance_id,
@@ -298,16 +329,7 @@ module Snikket
 		end
 
 		def fetch_invite
-			url = bootstrap_uri
-			EM::HttpRequest.new(
-				url, tls: { verify_peer: true }
-			).ahead(redirects: 5).then { |res|
-				LinkHeaderParser.parse(
-					Array(res.response_header["LINK"]), base_uri: url
-				).group_by_relation_type["alternate"]&.find do |header|
-					URI.parse(header.target_uri).scheme == "xmpp"
-				end&.target_uri
-			}.catch { nil }
+			InviteRepo.new(bootstrap_uri: bootstrap_uri).fetch
 		end
 	end
 

test/test_snikket.rb 🔗

@@ -52,6 +52,20 @@ class TestSnikket < Minitest::Test
 		)
 	end
 
+	def test_customer_instance_bootstrap_uri
+		instance = Snikket::CustomerInstance.new(
+			instance_id: "si-1234",
+			bootstrap_token: "fZLy6iTh",
+			customer_id: "test",
+			domain: "example.com"
+		)
+
+		assert_equal(
+			"https://example.com/invites_bootstrap?token=fZLy6iTh",
+			instance.bootstrap_uri
+		)
+	end
+
 	def test_instance_result
 		instance = Blather::XMPPNode.parse(<<~XML)
 			<iq type="result" from="hosting-api.snikket.net" id="000">
@@ -75,17 +89,25 @@ class TestSnikket < Minitest::Test
 		assert_equal :up, instance.status
 	end
 
-	def test_bootstrap_uri
-		instance = Snikket::CustomerInstance.new(
-			instance_id: "si-1234",
-			bootstrap_token: "fZLy6iTh",
-			customer_id: "test",
-			domain: "example.com"
+	def test_invite_repo_fetch_returns_xmpp_alternate_link
+		stub_request(
+			:head,
+			"https://example.com/invites_bootstrap?token=fZLy6iTh"
+		).to_return(
+			status: 200,
+			headers: {
+				"Link" => [
+					"<https://example.com/invite>; rel=\"alternate\"",
+					"<xmpp:test@example.com?join>; rel=\"alternate\""
+				].join(", ")
+			}
 		)
 
-		assert_equal(
-			"https://example.com/invites_bootstrap?token=fZLy6iTh",
-			instance.bootstrap_uri
-		)
+		invite = Snikket::CustomerInstance::InviteRepo.new(
+			bootstrap_uri: "https://example.com/invites_bootstrap?token=fZLy6iTh"
+		).fetch.sync
+
+		assert_equal "xmpp:test@example.com?join", invite
 	end
+	em :test_invite_repo_fetch_returns_xmpp_alternate_link
 end