~singpolyma/sgx-jmp

a498f9c81e3550551b3a8cd9aa9c8ba71b877082 — Stephen Paul Weber 2 years ago c2d2a7d + 6acb4d2
Merge branch 'no-15-spin'

* no-15-spin:
  Auto top up enough to get to auto_top_up_amount
  Remove Customer knowledge of all presenter objects
M lib/admin_command.rb => lib/admin_command.rb +1 -1
@@ 57,7 57,7 @@ class AdminCommand
	end

	def start(command_action=:execute)
		@target_customer.admin_info.then { |info|
		AdminInfo.for(@target_customer).then { |info|
			if command_action == :complete
				Command.finish { |iq| iq.command << info.form }
			else

M lib/customer.rb => lib/customer.rb +11 -19
@@ 2,12 2,10 @@

require "forwardable"

require_relative "./api"
require_relative "./blather_ext"
require_relative "./customer_usage"
require_relative "./customer_plan"
require_relative "./customer_ogm"
require_relative "./customer_info"
require_relative "./customer_finacials"
require_relative "./backend_sgx"
require_relative "./invites_repo"


@@ 25,8 23,8 @@ class Customer

	def_delegators :@plan, :active?, :activate_plan_starting_now, :bill_plan,
	               :currency, :merchant_account, :plan_name, :minute_limit,
	               :message_limit, :auto_top_up_amount, :monthly_overage_limit,
	               :monthly_price, :save_plan!
	               :message_limit, :monthly_overage_limit, :activation_date,
	               :expires_at, :monthly_price, :save_plan!
	def_delegators :@sgx, :deregister!, :register!, :registered?, :set_ogm_url,
	               :fwd, :transcription_enabled
	def_delegators :@usage, :usage_report, :message_usage, :incr_message_usage


@@ 86,6 84,15 @@ class Customer
		EMPromise.resolve(self)
	end

	def auto_top_up_amount
		if @plan.auto_top_up_amount.positive? &&
		   balance < -@plan.auto_top_up_amount + 5
			-balance + @plan.auto_top_up_amount
		else
			@plan.auto_top_up_amount
		end
	end

	def unused_invites
		InvitesRepo.new(DB).unused_invites(customer_id)
	end


@@ 125,21 132,6 @@ class Customer
		CONFIG[:admins].include?(jid.to_s)
	end

	def api
		API.for(self)
	end

	# kwargs are passed through for dependency injection from tests
	def admin_info(**kwargs)
		AdminInfo.for(self, @plan, **kwargs)
	end

	def info
		CustomerInfo.for(self, @plan)
	end

	protected def_delegator :@plan, :expires_at

	class ChildCustomer < Customer
		def initialize(*args, parent_customer_id:, **kwargs)
			super(*args, **kwargs)

M lib/customer_info.rb => lib/customer_info.rb +14 -11
@@ 4,21 4,24 @@ require "bigdecimal"
require "forwardable"
require "relative_time"
require "value_semantics/monkey_patched"
require_relative "proxied_jid"

require_relative "api"
require_relative "customer"
require_relative "customer_plan"
require_relative "form_template"
require_relative "promise_hash"
require_relative "proxied_jid"

class PlanInfo
	extend Forwardable

	def_delegators :plan, :expires_at, :auto_top_up_amount

	def self.for(plan)
		return EMPromise.resolve(NoPlan.new) unless plan&.plan_name
	def self.for(plan_or_customer)
		return EMPromise.resolve(NoPlan.new) unless plan_or_customer&.plan_name

		plan.activation_date.then do |adate|
			new(plan: plan, start_date: adate)
		plan_or_customer.activation_date.then do |adate|
			new(plan: plan_or_customer, start_date: adate)
		end
	end



@@ 37,7 40,7 @@ class PlanInfo
	end

	value_semantics do
		plan CustomerPlan
		plan Either(CustomerPlan, Customer)
		start_date Time
	end



@@ 78,9 81,9 @@ class CustomerInfo
		cnam Either(String, nil)
	end

	def self.for(customer, plan)
	def self.for(customer)
		PromiseHash.all(
			plan_info: PlanInfo.for(plan),
			plan_info: PlanInfo.for(customer),
			tel: customer.registered? ? customer.registered?.phone : nil,
			balance: customer.balance,
			cnam: customer.tndetails.dig(:features, :lidb, :subscriber_information)


@@ 104,7 107,7 @@ class AdminInfo
	end

	def self.for(
		customer, plan,
		customer,
		trust_level_repo: TrustLevelRepo.new,
		call_attempt_repo: CallAttemptRepo.new
	)


@@ 112,8 115,8 @@ class AdminInfo
			jid: customer.jid,
			customer_id: customer.customer_id,
			fwd: customer.fwd,
			info: CustomerInfo.for(customer, plan),
			api: customer.api,
			info: CustomerInfo.for(customer),
			api: API.for(customer),
			call_info: call_info(customer, call_attempt_repo),
			trust_level: trust_level_repo.find(customer).then(&:to_s)
		).then(&method(:new))

M sgx_jmp.rb => sgx_jmp.rb +2 -1
@@ 81,6 81,7 @@ require_relative "lib/configure_calls_form"
require_relative "lib/command"
require_relative "lib/command_list"
require_relative "lib/customer"
require_relative "lib/customer_info"
require_relative "lib/customer_info_form"
require_relative "lib/customer_repo"
require_relative "lib/dummy_command"


@@ 471,7 472,7 @@ Command.new(
	list_for: ->(*) { true },
	customer_repo: CustomerRepo.new(sgx_repo: Bwmsgsv2Repo.new)
) {
	Command.customer.then(&:info).then do |info|
	Command.customer.then(&CustomerInfo.method(:for)).then do |info|
		Command.finish do |reply|
			reply.command << info.form
		end

M test/test_customer_info.rb => test/test_customer_info.rb +9 -9
@@ 29,7 29,7 @@ class CustomerInfoTest < Minitest::Test

		cust = customer(sgx: sgx, plan_name: "test_usd")

		assert cust.info.sync.form
		assert CustomerInfo.for(cust).sync.form
		assert_mock sgx
	end
	em :test_info_does_not_crash


@@ 52,7 52,7 @@ class CustomerInfoTest < Minitest::Test
		trust_repo = Minitest::Mock.new
		trust_repo.expect(:find, TrustLevel::Basement, [cust])

		assert cust.admin_info(trust_level_repo: trust_repo).sync.form
		assert AdminInfo.for(cust, trust_level_repo: trust_repo).sync.form
		assert_mock sgx
		assert_mock trust_repo
	end


@@ 81,11 81,11 @@ class CustomerInfoTest < Minitest::Test
		trust_repo = Minitest::Mock.new
		trust_repo.expect(:find, TrustLevel::Basement, [cust])

		assert cust
			.admin_info(
				trust_level_repo: trust_repo,
				call_attempt_repo: call_attempt_repo
			).sync.form
		assert AdminInfo.for(
			cust,
			trust_level_repo: trust_repo,
			call_attempt_repo: call_attempt_repo
		).sync.form
		assert_mock call_attempt_repo
		assert_mock trust_repo
	end


@@ 102,7 102,7 @@ class CustomerInfoTest < Minitest::Test
			plan: plan,
			sgx: sgx
		)
		assert cust.info.sync.form
		assert CustomerInfo.for(cust).sync.form
		assert_mock sgx
	end
	em :test_inactive_info_does_not_crash


@@ 124,7 124,7 @@ class CustomerInfoTest < Minitest::Test
		trust_repo = Minitest::Mock.new
		trust_repo.expect(:find, TrustLevel::Basement, [cust])

		assert cust.admin_info(trust_level_repo: trust_repo).sync.form
		assert AdminInfo.for(cust, trust_level_repo: trust_repo).sync.form
		assert_mock sgx
		assert_mock trust_repo
	end

M test/test_low_balance.rb => test/test_low_balance.rb +38 -0
@@ 138,6 138,44 @@ class LowBalanceTest < Minitest::Test
		end
		em :test_notify!

		def test_very_low_balance_notify!
			customer = Minitest::Mock.new(customer(
				balance: -100,
				auto_top_up_amount: 15
			))
			auto_top_up = LowBalance::AutoTopUp.new(customer)

			tx = PromiseMock.new
			tx.expect(:insert, EMPromise.resolve(nil))
			LowBalance::AutoTopUp::Transaction.expect(
				:sale,
				tx,
				[customer, { amount: 110 }]
			)
			auto_top_up.notify!
			assert_mock tx
		end
		em :test_very_low_balance_notify!

		def test_border_low_balance_notify!
			customer = Minitest::Mock.new(customer(
				balance: -11,
				auto_top_up_amount: 15
			))
			auto_top_up = LowBalance::AutoTopUp.new(customer)

			tx = PromiseMock.new
			tx.expect(:insert, EMPromise.resolve(nil))
			LowBalance::AutoTopUp::Transaction.expect(
				:sale,
				tx,
				[customer, { amount: 21 }]
			)
			auto_top_up.notify!
			assert_mock tx
		end
		em :test_border_low_balance_notify!

		def test_decline_notify!
			@customer.expect(
				:stanza_to,