Refactor IBR set code to use the IBR helpers

Stephen Paul Weber created

Change summary

sgx-bwmsgsv2.rb        | 62 +++++++++++--------------------------------
test/test_component.rb | 61 +++++++++++++++++++++++++++++++++++++++++++
test/test_helper.rb    | 13 +++++++++
3 files changed, 90 insertions(+), 46 deletions(-)

Detailed changes

sgx-bwmsgsv2.rb 🔗

@@ -524,58 +524,28 @@ module SGXbwmsgsv2
 			}
 	end
 
-	def self.creds_from_registration_query(qn)
-		xn = qn.children.find { |v| v.element_name == "x" }
-
-		if xn
-			xn.children.each_with_object({}) do |field, h|
-				next if field.element_name != "field"
-
-				val = field.children.find { |v|
-					v.element_name == "value"
-				}
-
-				case field['var']
-				when 'nick'
-					h[:user_id] = val.text
-				when 'username'
-					h[:api_token] = val.text
-				when 'password'
-					h[:api_secret] = val.text
-				when 'phone'
-					h[:phone_num] = val.text
-				else
-					# TODO: error
-					puts "?: #{field['var']}"
-				end
-			end
+	def self.creds_from_registration_query(i)
+		if i.query.find_first("./ns:x", ns: "jabber:x:data")
+			[
+				i.form.field("nick")&.value,
+				i.form.field("username")&.value,
+				i.form.field("password")&.value,
+				i.form.field("phone")&.value
+			]
 		else
-			qn.children.each_with_object({}) do |field, h|
-				case field.element_name
-				when "nick"
-					h[:user_id] = field.text
-				when "username"
-					h[:api_token] = field.text
-				when "password"
-					h[:api_secret] = field.text
-				when "phone"
-					h[:phone_num] = field.text
-				end
-			end
-		end.values_at(:user_id, :api_token, :api_secret, :phone_num)
+			[i.nick, i.username, i.password, i.phone]
+		end
 	end
 
-	def self.process_registration(i, qn)
-		EMPromise.resolve(
-			qn.children.find { |v| v.element_name == "remove" }
-		).then { |rn|
-			if rn
+	def self.process_registration(i)
+		EMPromise.resolve(nil).then {
+			if i.remove?
 				@registration_repo.delete(i.from).then do
 					write_to_stream i.reply
 					EMPromise.reject(:done)
 				end
 			else
-				creds_from_registration_query(qn)
+				creds_from_registration_query(i)
 			end
 		}.then { |user_id, api_token, api_secret, phone_num|
 			if phone_num && phone_num[0] == '+'
@@ -690,12 +660,12 @@ module SGXbwmsgsv2
 		return orig
 	end
 
-	iq '/iq/ns:query', ns: 'jabber:iq:register' do |i, qn|
+	ibr do |i|
 		puts "IQ: #{i.inspect}"
 
 		case i.type
 		when :set
-			process_registration(i, qn)
+			process_registration(i)
 		when :get
 			bare_jid = i.from.stripped
 			@registration_repo.find(bare_jid).then { |creds|

test/test_component.rb 🔗

@@ -16,6 +16,7 @@ class ComponentTest < Minitest::Test
 			@written << s
 		end
 
+		REDIS.reset!
 		REDIS.set("catapult_cred-test@example.com", [
 			'account', 'user', 'password', '+15550000000'
 		])
@@ -265,4 +266,64 @@ class ComponentTest < Minitest::Test
 		)
 	end
 	em :test_ibr_conflict
+
+	def test_ibr_remove
+		iq = Blather::Stanza::Iq::IBR.new(:set, "component")
+		iq.from = "test@example.com"
+		iq.remove!
+		process_stanza(iq)
+
+		refute REDIS.get("catapult_cred-test@example.com").sync
+
+		assert_equal 1, written.length
+
+		stanza = Blather::XMPPNode.parse(written.first.to_xml)
+		assert stanza.result?
+	end
+	em :test_ibr_remove
+
+	def test_ibr_form
+		stub_request(
+			:get,
+			"https://messaging.bandwidth.com/api/v2/users/acct/media"
+		).with(basic_auth: ["user", "pw"]).to_return(status: 200, body: "[]")
+
+		iq = Blather::Stanza::Iq::IBR.new(:set, "component")
+		iq.from = "formuser@example.com"
+		form = Blather::Stanza::X.find_or_create(iq.query)
+		form.fields = [
+			{
+				var: "nick",
+				value: "acct"
+			},
+			{
+				var: "username",
+				value: "user"
+			},
+			{
+				var: "password",
+				value: "pw"
+			},
+			{
+				var: "phone",
+				value: "+15551234567"
+			}
+		]
+		process_stanza(iq)
+
+		assert_equal(
+			["acct", "user", "pw", "+15551234567"],
+			REDIS.get("catapult_cred-formuser@example.com").sync
+		)
+
+		assert_equal(
+			"formuser@example.com",
+			REDIS.get("catapult_jid-+15551234567").sync
+		)
+
+		assert_equal 1, written.length
+		stanza = Blather::XMPPNode.parse(written.first.to_xml)
+		assert stanza.result?
+	end
+	em :test_ibr_form
 end

test/test_helper.rb 🔗

@@ -38,6 +38,10 @@ class FakeRedis
 		@values = values
 	end
 
+	def reset!(values={})
+		@values = values
+	end
+
 	def set(key, value, *)
 		@values[key] = value
 		EMPromise.resolve("OK")
@@ -47,6 +51,10 @@ class FakeRedis
 		set(key, value)
 	end
 
+	def del(*keys)
+		keys.each { |key| @values.delete(key) }
+	end
+
 	def mget(*keys)
 		EMPromise.all(keys.map(&method(:get)))
 	end
@@ -109,6 +117,11 @@ class FakeRedis
 	def lrange(key, sindex, eindex)
 		get(key).then { |v| v ? v[sindex..eindex] : [] }
 	end
+
+	def rpush(key, *values)
+		@values[key] ||= []
+		values.each { |v| @values[key].push(v) }
+	end
 end
 
 REDIS = FakeRedis.new