Allow updating existing user registration

Stephen Paul Weber created

Change summary

lib/registration_repo.rb | 20 ++++++++++---
test/test_component.rb   | 58 +++++++++++++++++++++++++++++++++++++++++
test/test_helper.rb      |  9 ++++++
3 files changed, 81 insertions(+), 6 deletions(-)

Detailed changes

lib/registration_repo.rb 🔗

@@ -22,20 +22,30 @@ class RegistrationRepo
 
 		EMPromise.all([
 			find(jid),
-			REDIS.exists(jid_key(tel))
+			REDIS.get(jid_key(tel))
 		]).then { |(oldcreds, oldjid)|
-			if oldjid == "1" || (!oldcreds.empty? && oldcreds != creds)
+			oldtel = oldcreds.last
+			next if creds == oldcreds && jid.to_s == oldjid.to_s
+
+			if oldjid && oldjid.to_s != jid.to_s
 				raise Conflict, "Another user exists for #{tel}"
 			end
 
-			EMPromise.all([
+			begin
+				REDIS.multi
+				REDIS.del(jid_key(oldtel)) if oldtel
 				REDIS.set(
 					jid_key(tel),
 					Blather::JID.new(jid).stripped.to_s,
 					"NX"
-				),
+				)
+				REDIS.del(cred_key(jid))
 				REDIS.rpush(cred_key(jid), *creds)
-			])
+				REDIS.exec
+			rescue StandardError
+				REDIS.discard
+				raise
+			end
 		}
 	end
 

test/test_component.rb 🔗

@@ -17,6 +17,8 @@ class ComponentTest < Minitest::Test
 		end
 
 		REDIS.reset!
+		REDIS.set("catapult_jid-", "HERE")
+		REDIS.set("catapult_jid-+15550000000", "test@example.com")
 		REDIS.set("catapult_cred-test@example.com", [
 			'account', 'user', 'password', '+15550000000'
 		])
@@ -239,7 +241,34 @@ class ComponentTest < Minitest::Test
 	end
 	em :test_ibr_other_error
 
-	def test_ibr_conflict
+	def test_ibr_new
+		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 = "test9@example.com"
+		iq.phone = "+15550000009"
+		iq.nick = "acct"
+		iq.username = "user"
+		iq.password = "pw"
+		process_stanza(iq)
+
+		assert_equal 1, written.length
+
+		stanza = Blather::XMPPNode.parse(written.first.to_xml)
+		refute stanza.error?
+		assert_equal(
+			["acct", "user", "pw", "+15550000009"],
+			REDIS.get("catapult_cred-test9@example.com").sync
+		)
+		assert_equal "test9@example.com", REDIS.get("catapult_jid-+15550000009").sync
+		assert REDIS.get("catapult_jid-").sync
+	end
+	em :test_ibr_new
+
+	def test_ibr_update
 		stub_request(
 			:get,
 			"https://messaging.bandwidth.com/api/v2/users/acct/media"
@@ -247,6 +276,33 @@ class ComponentTest < Minitest::Test
 
 		iq = Blather::Stanza::Iq::IBR.new(:set, "component")
 		iq.from = "test@example.com"
+		iq.phone = "+15550000009"
+		iq.nick = "acct"
+		iq.username = "user"
+		iq.password = "pw"
+		process_stanza(iq)
+
+		assert_equal 1, written.length
+
+		stanza = Blather::XMPPNode.parse(written.first.to_xml)
+		refute stanza.error?
+		assert_equal(
+			["acct", "user", "pw", "+15550000009"],
+			REDIS.get("catapult_cred-test@example.com").sync
+		)
+		assert_equal "test@example.com", REDIS.get("catapult_jid-+15550000009").sync
+		refute REDIS.get("catapult_jid-+15550000000").sync
+	end
+	em :test_ibr_update
+
+	def test_ibr_conflict
+		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 = "test2@example.com"
 		iq.phone = "+15550000000"
 		iq.nick = "acct"
 		iq.username = "user"

test/test_helper.rb 🔗

@@ -122,6 +122,15 @@ class FakeRedis
 		@values[key] ||= []
 		values.each { |v| @values[key].push(v) }
 	end
+
+	def multi
+	end
+
+	def exec
+	end
+
+	def discard
+	end
 end
 
 REDIS = FakeRedis.new