fix: recycle local inventory with price

Phillip Davis created

note: in `test/test_admin_command`, the "-removal was to satisfy
rubocop, which my pre-commit hook caught because it only runs rubocop on
changed files.

Change summary

config-schema.dhall            |  2 
config.dhall.sample            |  2 
lib/bandwidth_tn_repo.rb       | 20 ++++++--
test/test_admin_command.rb     |  4 
test/test_bandwidth_tn_repo.rb | 84 ++++++++++++++++++++++++++++++++++++
test/test_helper.rb            |  5 +
6 files changed, 106 insertions(+), 11 deletions(-)

Detailed changes

config-schema.dhall 🔗

@@ -38,7 +38,7 @@
     forall (currency : Text) ->
       Text
 , interac : Text
-, keep_area_codes : List Text
+, keep_area_codes : List { area_code: Text, premium_price : Optional Natural }
 , keep_area_codes_in : { account : Text, sip_peer_id : Text, site_id : Text }
 , keepgo : Optional { access_token : Text, api_key : Text }
 , notify_admin : Text

config.dhall.sample 🔗

@@ -102,7 +102,7 @@ in
 	direct_sources = toMap {
 		`support@example.com` = "+15551234567"
 	},
-	keep_area_codes = ["555"],
+	keep_area_codes = [{ area_code = "555", premium_price = Some 10 }],
 	keep_area_codes_in = { account = "", site_id = "", sip_peer_id = "" },
 	snikket_hosting_api = "",
 	onboarding_domain = "",

lib/bandwidth_tn_repo.rb 🔗

@@ -9,13 +9,15 @@ class BandwidthTnRepo
 			region,
 			locality,
 			source,
-			available_after
+			available_after,
+			premium_price
 		) VALUES (
 			$1,
 			$2,
 			$3,
 			$4,
-			LOCALTIMESTAMP + '1 MONTH'
+			LOCALTIMESTAMP + '1 MONTH',
+			$5
 		)
 	SQL
 
@@ -46,20 +48,26 @@ class BandwidthTnRepo
 		raise "Could not set CNAM, please contact support"
 	end
 
-	def stash_for_later(tel, btn)
+	# @param [String] tel
+	# @param [BandwidthIris::Tn] btn
+	# @param [Numeric] premium_price
+	def stash_for_later(tel, btn, premium_price)
 		LOG.info "stash_for_later #{tel}\n#{caller}"
 		details = btn.get_details
 		region = details[:state]
 		locality = details[:city]
-		params = [tel, region, locality, CONFIG[:creds][:account]]
+		params = [tel, region, locality, CONFIG[:creds][:account], premium_price]
 		DB.exec(STASH_QUERY, params)
 	end
 
 	def disconnect(tel, order_name)
 		tn = tel.sub(/\A\+1/, "")
 		btn = BandwidthIris::Tn.new({ telephone_number: tn }, @move_client)
-		if CONFIG[:keep_area_codes].find { |area| tn.start_with?(area) }
-			stash_for_later(tel, btn)
+		code_and_price = CONFIG[:keep_area_codes].find { |keep|
+			tn.start_with?(keep[:area_code])
+		}
+		if code_and_price
+			stash_for_later(tel, btn, code_and_price[:premium_price] || 0)
 		else
 			BandwidthIris::Disconnect.create(order_name, tn)
 		end

test/test_admin_command.rb 🔗

@@ -342,7 +342,7 @@ class AdminCommandTest < Minitest::Test
 
 	def test_action_cancel_account_keep_number
 		details_response = {
-			"TelephoneNumberDetails": {
+			TelephoneNumberDetails: {
 				State: "NY",
 				City: "MANHATTEN"
 			}
@@ -382,7 +382,7 @@ class AdminCommandTest < Minitest::Test
 
 		sgx, admin = admin_command("+15566667777")
 
-		sql_params = ["+15566667777", "NY", "MANHATTEN", "test_bw_account"]
+		sql_params = ["+15566667777", "NY", "MANHATTEN", "test_bw_account", 10]
 
 		BandwidthTnRepo::DB.expect(
 			:exec,

test/test_bandwidth_tn_repo.rb 🔗

@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+require "test_helper"
+require "bandwidth_tn_repo"
+
+BandwidthTnRepo::DB = Minitest::Mock.new
+
+class BandwidthTnRepoTest < Minitest::Test
+	def test_local_inventory_recycled_with_price
+		stub_request(
+			:get,
+			"https://dashboard.bandwidth.com/v1.0/tns/5565555555/tndetails"
+		)
+			.with(
+				headers: {
+					"Accept" => "application/xml",
+					"Accept-Encoding" => "gzip, compressed",
+					"Authorization" => "Basic dGVzdF9id191c2VyOnRlc3RfYndfcGFzc3dvcmQ=",
+					"User-Agent" => "Ruby-Bandwidth-Iris"
+				}
+			).to_return(status: 200, body: <<~XML, headers: {})
+				<Response>
+					<TelephoneNumberDetails>
+						<City>Austin</City>
+						<State>TX</State>
+					</TelephoneNumberDetails>
+				</Response>
+			XML
+
+		tel = "+15565555555"
+
+		BandwidthTnRepo::DB.expect(
+			:exec,
+			nil,
+			[
+				BandwidthTnRepo::STASH_QUERY,
+				[tel, "TX", "Austin", "test_bw_account", 10]
+			]
+		)
+
+		BandwidthTnRepo.new.disconnect(tel, "test")
+
+		assert_mock BandwidthTnRepo::DB
+	end
+	em :test_local_inventory_recycled_with_price
+
+	def test_local_inventory_recycled_no_price
+		stub_request(
+			:get,
+			"https://dashboard.bandwidth.com/v1.0/tns/5575555555/tndetails"
+		)
+			.with(
+				headers: {
+					"Accept" => "application/xml",
+					"Accept-Encoding" => "gzip, compressed",
+					"Authorization" => "Basic dGVzdF9id191c2VyOnRlc3RfYndfcGFzc3dvcmQ=",
+					"User-Agent" => "Ruby-Bandwidth-Iris"
+				}
+			).to_return(status: 200, body: <<~XML, headers: {})
+				<Response>
+					<TelephoneNumberDetails>
+						<City>Austin</City>
+						<State>TX</State>
+					</TelephoneNumberDetails>
+				</Response>
+			XML
+
+		tel = "+15575555555"
+
+		BandwidthTnRepo::DB.expect(
+			:exec,
+			nil,
+			[
+				BandwidthTnRepo::STASH_QUERY,
+				[tel, "TX", "Austin", "test_bw_account", 0]
+			]
+		)
+
+		BandwidthTnRepo.new.disconnect(tel, "test")
+
+		assert_mock BandwidthTnRepo::DB
+	end
+	em :test_local_inventory_recycled_no_price
+end

test/test_helper.rb 🔗

@@ -157,7 +157,10 @@ CONFIG = {
 			CAD: { price: 400, plan: "500MB" }
 		}
 	},
-	keep_area_codes: ["556"],
+	keep_area_codes: [
+		{ area_code: "556", premium_price: 10 },
+		{ area_code: "557", premium_price: nil }
+	],
 	keep_area_codes_in: {
 		account: "moveto",
 		site_id: "movetosite",