@@ -3,17 +3,23 @@
require "multibases"
require "securerandom"
+require_relative "customer"
+require_relative "trust_level_repo"
+
class ParentCodeRepo
- def initialize(redis=REDIS)
+ def initialize(
+ redis: REDIS,
+ db: DB,
+ trust_level_repo: TrustLevelRepo.new(redis: redis, db: db)
+ )
@redis = redis
+ @db = db
+ @trust_level_repo = trust_level_repo
end
def find(code)
@redis.hget("jmp_parent_codes", code).then do |parent_id|
- (parent_id ? @redis.get("jmp_customer_trust_level-#{parent_id}") : nil)
- .then do |tl|
- tl == "Tomb" ? nil : parent_id
- end
+ trust_level_guard(parent_id).then { parent_id }
end
end
@@ -28,4 +34,22 @@ class ParentCodeRepo
]).then { code }
end
end
+
+ def existing_subaccounts(parent_id)
+ @db.query_one(<<~SQL, parent_id, default: { c: 0 }).then { |r| r[:c] }
+ SELECT COUNT(*) AS c FROM customer_plans WHERE parent_customer_id=$1
+ SQL
+ end
+
+ def trust_level_guard(parent_id)
+ return unless parent_id
+
+ @trust_level_repo.find(Customer.new(parent_id, "")).then { |tl|
+ existing_subaccounts(parent_id).then { |c| [tl, c] }
+ }.then do |(tl, number_of_subaccounts)|
+ unless tl.create_subaccount?(number_of_subaccounts)
+ raise "Please contact support to create a subaccount"
+ end
+ end
+ end
end
@@ -126,7 +126,7 @@ class Registration
end
def save_customer_plan(iq, code)
- ParentCodeRepo.new(REDIS).find(code).then do |parent|
+ ParentCodeRepo.new(redis: REDIS, db: DB).find(code).then do |parent|
plan = Plan.for_registration(iq.form.field("plan_name").value.to_s)
@customer = @customer.with_plan(plan.name, parent_customer_id: parent)
@customer.save_plan!
@@ -139,7 +139,7 @@ class Registration
@google_play_userid = google_play_userid
@tel = tel
@invites = InvitesRepo.new(DB, REDIS)
- @parent_code_repo = ParentCodeRepo.new(REDIS)
+ @parent_code_repo = ParentCodeRepo.new(redis: REDIS, db: DB)
end
def used
@@ -449,7 +449,7 @@ class Registration
@tel = tel
@error = error
@finish = finish
- @parent_code_repo = ParentCodeRepo.new(REDIS)
+ @parent_code_repo = ParentCodeRepo.new(redis: REDIS, db: DB)
end
def add_form(reply)
@@ -44,6 +44,10 @@ module TrustLevel
false
end
+ def create_subaccount?(*)
+ false
+ end
+
def to_s
"Tomb"
end
@@ -66,6 +70,10 @@ module TrustLevel
amount <= 35 && declines <= 2
end
+ def create_subaccount?(already_have)
+ already_have < 2
+ end
+
def to_s
"Basement"
end
@@ -88,6 +96,10 @@ module TrustLevel
amount <= 500 && declines <= 3
end
+ def create_subaccount?(already_have)
+ already_have < 10
+ end
+
def to_s
"Paragon"
end
@@ -110,6 +122,10 @@ module TrustLevel
true
end
+ def create_subaccount?(*)
+ true
+ end
+
def to_s
"Olympias"
end
@@ -147,6 +163,10 @@ module TrustLevel
amount <= 130 && declines <= 2
end
+ def create_subaccount?(already_have)
+ already_have < 2
+ end
+
def to_s
"Customer"
end
@@ -113,7 +113,12 @@ class RegistrationTest < Minitest::Test
class ActivationTest < Minitest::Test
Registration::Activation::DB = Minitest::Mock.new
Registration::Activation::REDIS = FakeRedis.new(
- "jmp_parent_codes" => { "PARENT_CODE" => 1 }
+ "jmp_parent_codes" => {
+ "PARENT_CODE" => "1",
+ "PARENT_TOMB" => "2",
+ "PARENT_MANY_SUBACCOUNTS" => "many_subaccounts"
+ },
+ "jmp_customer_trust_level-2" => "Tomb"
)
Registration::Activation::Payment = Minitest::Mock.new
Registration::Activation::Finish = Minitest::Mock.new
@@ -290,9 +295,15 @@ class RegistrationTest < Minitest::Test
)
end]
)
+ Registration::Activation::DB.expect(
+ :query_one, {}, [String, "1"], default: {}
+ )
+ Registration::Activation::DB.expect(
+ :query_one, { c: 0 }, [String, "1"], default: { c: 0 }
+ )
@customer.expect(:with_plan, @customer) do |*args, **kwargs|
assert_equal ["test_usd"], args
- assert_equal({ parent_customer_id: 1 }, kwargs)
+ assert_equal({ parent_customer_id: "1" }, kwargs)
end
@customer.expect(:save_plan!, EMPromise.resolve(nil), [])
Registration::Activation::DB.expect(:transaction, []) { |&blk| blk.call }
@@ -316,6 +327,74 @@ class RegistrationTest < Minitest::Test
assert_mock Registration::Activation::DB
end
em :test_write_with_parent_code
+
+ def test_write_with_parent_code_tombed_parent
+ Command::COMMAND_MANAGER.expect(
+ :write,
+ EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
+ iq.form.fields = [
+ { var: "plan_name", value: "test_usd" },
+ { var: "code", value: "PARENT_TOMB" }
+ ]
+ }),
+ [Matching.new do |iq|
+ assert_equal :form, iq.form.type
+ assert_equal(
+ "You've selected +15555550000 as your JMP number.",
+ iq.form.instructions.lines.first.chomp
+ )
+ end]
+ )
+ Registration::Activation::DB.expect(
+ :query_one, {}, [String, "2"], default: {}
+ )
+ Registration::Activation::DB.expect(
+ :query_one, { c: 0 }, [String, "2"], default: { c: 0 }
+ )
+ assert_equal(
+ "Please contact support to create a subaccount",
+ execute_command { @activation.write.catch(&:to_s) }
+ )
+ assert_mock Command::COMMAND_MANAGER
+ assert_mock @customer
+ assert_mock Registration::Activation::Payment
+ assert_mock Registration::Activation::DB
+ end
+ em :test_write_with_parent_code_tombed_parent
+
+ def test_write_with_parent_code_too_many
+ Command::COMMAND_MANAGER.expect(
+ :write,
+ EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
+ iq.form.fields = [
+ { var: "plan_name", value: "test_usd" },
+ { var: "code", value: "PARENT_MANY_SUBACCOUNTS" }
+ ]
+ }),
+ [Matching.new do |iq|
+ assert_equal :form, iq.form.type
+ assert_equal(
+ "You've selected +15555550000 as your JMP number.",
+ iq.form.instructions.lines.first.chomp
+ )
+ end]
+ )
+ Registration::Activation::DB.expect(
+ :query_one, {}, [String, "many_subaccounts"], default: {}
+ )
+ Registration::Activation::DB.expect(
+ :query_one, { c: 2 }, [String, "many_subaccounts"], default: { c: 0 }
+ )
+ assert_equal(
+ "Please contact support to create a subaccount",
+ execute_command { @activation.write.catch(&:to_s) }
+ )
+ assert_mock Command::COMMAND_MANAGER
+ assert_mock @customer
+ assert_mock Registration::Activation::Payment
+ assert_mock Registration::Activation::DB
+ end
+ em :test_write_with_parent_code_too_many
end
class AllowTest < Minitest::Test
@@ -811,6 +890,12 @@ class RegistrationTest < Minitest::Test
:new,
OpenStruct.new(write: nil)
) { |*| true }
+ Registration::Payment::InviteCode::DB.expect(
+ :query_one, {}, [String, "parent_customer"], default: {}
+ )
+ Registration::Payment::InviteCode::DB.expect(
+ :query_one, { c: 0 }, [String, "parent_customer"], default: { c: 0 }
+ )
execute_command do
Registration::Payment::InviteCode::REDIS.expect(
:hget,