~singpolyma/sgx-jmp

74afc0e8c850af878e00b2440eced36429cce890 — Amolith 9 months ago b0ed80e
"Order" numbers from local inventory

- Add methods necessary for actually assigning numbers to customers and
  deleting those numbers from the local database
- Add accompanying test

Signed-off-by: Amolith <amolith@secluded.site>
M .rubocop.yml => .rubocop.yml +1 -0
@@ 42,6 42,7 @@ Naming/MethodParameterName:
    - iq
    - db
    - to
    - tn

Layout/IndentationStyle:
  Enabled: false

M lib/bandwidth_tn_repo.rb => lib/bandwidth_tn_repo.rb +10 -0
@@ 40,4 40,14 @@ class BandwidthTnRepo
			BandwidthIris::Disconnect.create(order_name, tn)
		end
	end

	def move(tel, order_name, source_account_id)
		tn = tel.sub(/\A\+1/, "")
		BandwidthIris::Tn.new({ telephone_number: tn }, @move_client).move(
			customer_order_id: order_name,
			source_account_id: source_account_id,
			site_id: CONFIG[:bandwidth_site],
			sip_peer_id: CONFIG[:bandwidth_peer]
		)
	end
end

M lib/registration.rb => lib/registration.rb +4 -10
@@ 597,16 597,10 @@ class Registration
		end

		def write
			BandwidthTnReservationRepo.new.get(@customer, @tel.tel).then do |rid|
				BandwidthTNOrder.create(
					@tel.tel,
					customer_order_id: @customer.customer_id,
					reservation_id: rid
				).then(&:poll).then(
					->(_) { customer_active_tel_purchased },
					method(:number_purchase_error)
				)
			end
			@tel.order(DB, @customer).then(
				->(_) { customer_active_tel_purchased },
				method(:number_purchase_error)
			)
		end

	protected

M lib/tel_selections.rb => lib/tel_selections.rb +49 -3
@@ 22,6 22,15 @@ class TelSelections
		@redis.setex("pending_tel_for-#{jid}", THIRTY_DAYS, tel.pending_value)
	end

	def set_tel(jid, tel)
		ChooseTel::Tn::LocalInventory.fetch(tel).then do |local_inv|
			set(
				jid,
				local_inv || ChooseTel::Tn::Bandwidth.new(tel)
			)
		end
	end

	def delete(jid)
		@redis.del("pending_tel_for-#{jid}")
	end


@@ 138,7 147,7 @@ class TelSelections
							full_number: row["tel"].sub(/\A\+1/, ""),
							city: row["locality"],
							state: row["region"]
						))
						), row["bandwidth_account_id"])
					}
				}
			end


@@ 205,7 214,9 @@ class TelSelections

			def self.for_pending_value(value)
				if value.start_with?("LocalInventory/")
					LocalInventory.new(Tn.new(value.sub(/\ALocalInventory\//, "")))
					LocalInventory.new(
						*Tn.new(value.sub(/\ALocalInventory\//, "")).split("/", 2)
					)
				else
					Bandwidth.new(Tn.new(value))
				end


@@ 262,16 273,51 @@ class TelSelections
				def reserve(customer)
					BandwidthTnReservationRepo.new.ensure(customer, tel)
				end

				def order(_, customer)
					BandwidthTnReservationRepo.new.get(customer, tel).then do |rid|
						BandwidthTNOrder.create(
							tel,
							customer_order_id: customer.customer_id,
							reservation_id: rid
						).then(&:poll)
					end
				end
			end

			class LocalInventory < SimpleDelegator
				def self.fetch(tn, db: DB)
					db.query_defer("SELECT * FROM tel_inventory WHERE tel = $1", [tn])
						.then { |rows|
						rows.first&.then { |row|
							new(Tn::Option.new(
								full_number: row["tel"].sub(/\A\+1/, ""),
								city: row["locality"],
								state: row["region"]
							), row["bandwidth_account_id"])
						}
					}
				end

				def initialize(tn, bandwidth_account_id)
					super(tn)
					@bandwidth_account_id = bandwidth_account_id
				end

				def pending_value
					"LocalInventory/#{tel}"
					"LocalInventory/#{tel}/#{@bandwidth_account_id}"
				end

				def reserve(*)
					EMPromise.resolve(nil)
				end

				def order(db, customer)
					BandwidthTnRepo.new.move(
						tel, customer.customer_id, @bandwidth_account_id
					)
					db.exec_defer("DELETE FROM tel_inventory WHERE tel = $1", [tel])
				end
			end
		end


M sgx_jmp.rb => sgx_jmp.rb +1 -1
@@ 1019,7 1019,7 @@ Command.new(
				cmd.form.fields = [{ var: "to", value: jid }]
				cmd.form.type = "submit"
			}).then { |result|
				TEL_SELECTIONS.set(result.form.field("from")&.value.to_s.strip, tel)
				TEL_SELECTIONS.set_tel(result.form.field("from")&.value.to_s.strip, tel)
			}.then { Command.finish }
		end
	end

M test/test_registration.rb => test/test_registration.rb +86 -0
@@ 1501,6 1501,92 @@ class RegistrationTest < Minitest::Test
		end
		em :test_write_onboarding

		def test_write_local_inventory
			stub_request(
				:post,
				"https://dashboard.bandwidth.com/v1.0/accounts/moveto/moveTns"
			).with(
				body: {
					CustomerOrderId: "test",
					SourceAccountId: "bandwidth_account_id",
					SiteId: "test_site",
					SipPeerId: "test_peer",
					TelephoneNumbers: { TelephoneNumber: "5555550000" }
				}.to_xml(indent: 0, root: "MoveTnsOrder")
			).to_return(status: 200, body: "", headers: {})

			Registration::Finish::REDIS.expect(
				:get,
				nil,
				["jmp_customer_pending_invite-test"]
			)
			Registration::Finish::REDIS.expect(
				:del,
				nil,
				["jmp_customer_pending_invite-test"]
			)
			Registration::Finish::REDIS.expect(
				:hget,
				nil,
				["jmp_group_codes", nil]
			)
			Registration::Finish::DB.expect(
				:exec_defer,
				EMPromise.resolve(nil),
				[String, ["+15555550000"]]
			)
			Bwmsgsv2Repo::REDIS.expect(
				:set,
				nil,
				[
					"catapult_fwd-+15555550000",
					"xmpp:test\\40onboarding.example.com@proxy"
				]
			)
			Bwmsgsv2Repo::REDIS.expect(
				:set,
				nil,
				["catapult_fwd_timeout-customer_test@component", 25]
			)
			result = execute_command do
				@sgx.expect(
					:register!,
					EMPromise.resolve(@sgx.with(
						registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
							ibr.phone = "+15555550000"
						end
					)),
					["+15555550000"]
				)

				Command::COMMAND_MANAGER.expect(
					:write,
					EMPromise.reject(:test_result),
					[Matching.new do |iq|
						assert_equal :form, iq.form.type
						assert iq.form.field("subdomain")
					end]
				)

				Registration::Finish.new(
					customer(
						sgx: @sgx,
						jid: Blather::JID.new("test\\40onboarding.example.com@proxy")
					),
					TelSelections::ChooseTel::Tn::LocalInventory.new(
						TelSelections::ChooseTel::Tn.new("+15555550000"),
						"bandwidth_account_id"
					)
				).write.catch { |e| e }
			end
			assert_equal :test_result, result
			assert_mock @sgx
			assert_mock Registration::Finish::REDIS
			assert_mock Bwmsgsv2Repo::REDIS
			assert_mock Command::COMMAND_MANAGER
		end
		em :test_write_local_inventory

		def test_write_tn_fail
			create_order = stub_request(
				:post,