~singpolyma/sgx-jmp

dbf8df70705bce09ae7ab67ba400b8ea918a1d84 — Christopher Vollick 3 months ago fd7951d
Show Callability State in Customer Info

This shows relatively easily which class a given user finds themselves
in.

Whether they can't call because they have no balance, or if they have
lots of room, or if they're being asked.

Hopefully this will make it easier to tell at a glance if a calling
issue is due to a few things.
4 files changed, 50 insertions(+), 3 deletions(-)

M forms/admin_info.rb
M lib/call_attempt.rb
M lib/customer_info.rb
M test/test_customer_info.rb
M forms/admin_info.rb => forms/admin_info.rb +6 -0
@@ 46,6 46,12 @@ if @admin_info.fwd.uri
end

field(
	var: "call_info",
	label: "Call Status",
	value: @admin_info.call_info
)

field(
	var: "api",
	label: "API",
	value: @admin_info.api.to_s

M lib/call_attempt.rb => lib/call_attempt.rb +19 -2
@@ 48,6 48,10 @@ class CallAttempt
		["#{direction}/connect", { locals: to_h }]
	end

	def to_s
		"Allowed(max_minutes: #{max_minutes}, limit_remaining: #{limit_remaining})"
	end

	def create_call(fwd, *args, &block)
		fwd.create_call(*args, &block)
	end


@@ 119,6 123,10 @@ class CallAttempt
			[view]
		end

		def to_s
			"Unsupported"
		end

		def create_call(*); end

		def as_json(*)


@@ 135,8 143,8 @@ class CallAttempt
			self.for(rate: rate, **kwargs) if credit < rate * 10
		end

		def self.for(customer:, direction:, **kwargs)
			LowBalance.for(customer).then(&:notify!).then do |amount|
		def self.for(customer:, direction:, low_balance: LowBalance, **kwargs)
			low_balance.for(customer).then(&:notify!).then do |amount|
				if amount&.positive?
					CallAttempt.for(
						customer: customer.with_balance(customer.balance + amount),


@@ 165,6 173,10 @@ class CallAttempt
			[view, { locals: to_h }]
		end

		def to_s
			"NoBalance"
		end

		def create_call(*); end

		def as_json(*)


@@ 211,6 223,11 @@ class CallAttempt
			[view, { locals: to_h }]
		end

		def to_s
			"AtLimit(max_minutes: #{max_minutes}, "\
			"limit_remaining: #{limit_remaining})"
		end

		def create_call(fwd, *args, &block)
			fwd.create_call(*args, &block)
		end

M lib/customer_info.rb => lib/customer_info.rb +23 -1
@@ 99,6 99,7 @@ class AdminInfo
		fwd Either(CustomerFwd, nil)
		info CustomerInfo
		api API
		call_info String
	end

	def self.for(customer, plan)


@@ 107,10 108,31 @@ class AdminInfo
			customer_id: customer.customer_id,
			fwd: customer.fwd,
			info: CustomerInfo.for(customer, plan),
			api: customer.api
			api: customer.api,
			call_info: call_info(customer)
		).then(&method(:new))
	end

	class FakeLowBalance
		def self.for(_)
			self
		end

		def self.notify!
			EMPromise.resolve(0)
		end
	end

	def self.call_info(customer)
		if customer.registered?
			CallAttemptRepo.new
				.find_outbound(customer, "+1", call_id: "", low_balance: FakeLowBalance)
				.then(&:to_s)
		else
			EMPromise.resolve("No calling")
		end
	end

	def form
		FormTemplate.render("admin_info", admin_info: self)
	end

M test/test_customer_info.rb => test/test_customer_info.rb +2 -0
@@ 37,6 37,7 @@ class CustomerInfoTest < Minitest::Test
		sgx.expect(:registered?, false)
		fwd = CustomerFwd.for(uri: "tel:+12223334444", timeout: 15)
		sgx.expect(:fwd, fwd)
		sgx.expect(:registered?, false)

		CustomerPlan::DB.expect(
			:query_one,


@@ 69,6 70,7 @@ class CustomerInfoTest < Minitest::Test
	def test_inactive_admin_info_does_not_crash
		sgx = Minitest::Mock.new
		sgx.expect(:registered?, false)
		sgx.expect(:registered?, false)
		sgx.expect(:fwd, CustomerFwd::None.new(uri: nil, timeout: nil))

		plan = CustomerPlan.new("test", plan: nil, expires_at: nil)