Detailed changes
@@ -3,8 +3,9 @@
class InvitesRepo
class Invalid < StandardError; end
- def initialize(db=DB)
+ def initialize(db=DB, redis=REDIS)
@db = db
+ @redis = redis
end
def unused_invites(customer_id)
@@ -15,13 +16,13 @@ class InvitesRepo
end
def claim_code(customer_id, code, &blk)
- EMPromise.resolve(nil).then do
+ guard_too_many_tries(customer_id).then do
@db.transaction do
valid = @db.exec(<<~SQL, [customer_id, code]).cmd_tuples.positive?
UPDATE invites SET used_by_id=$1, used_at=LOCALTIMESTAMP
WHERE code=$2 AND used_by_id IS NULL
SQL
- raise Invalid, "Not a valid invite code: #{code}" unless valid
+ invalid_code(customer_id, code).sync unless valid
blk.call
end
@@ -76,4 +77,20 @@ class InvitesRepo
SQL
}
end
+
+protected
+
+ def guard_too_many_tries(customer_id)
+ @redis.get("jmp_invite_tries-#{customer_id}").then do |t|
+ raise Invalid, "Too many wrong attempts" if t.to_i > 10
+ end
+ end
+
+ def invalid_code(customer_id, code)
+ @redis.incr("jmp_invite_tries-#{customer_id}").then {
+ @redis.expire("jmp_invite_tries-#{customer_id}", 60 * 60)
+ }.then do
+ raise Invalid, "Not a valid invite code: #{code}"
+ end
+ end
end
@@ -434,28 +434,15 @@ class Registration
def parse(iq)
return Activation.for(@customer, nil, @tel).then(&:write) if iq.prev?
- guard_too_many_tries.then {
- verify(iq.form.field("code")&.value&.to_s)
- }.then {
+ verify(iq.form.field("code")&.value&.to_s).then {
Finish.new(@customer, @tel)
}.catch_only(InvitesRepo::Invalid, &method(:invalid_code)).then(&:write)
end
protected
- def guard_too_many_tries
- REDIS.get("jmp_invite_tries-#{customer_id}").then do |t|
- raise InvitesRepo::Invalid, "Too many wrong attempts" if t.to_i > 10
- end
- end
-
def invalid_code(e)
- EMPromise.all([
- REDIS.incr("jmp_invite_tries-#{customer_id}").then do
- REDIS.expire("jmp_invite_tries-#{customer_id}", 60 * 60)
- end,
- InviteCode.new(@customer, @tel, error: e.message)
- ]).then(&:last)
+ InviteCode.new(@customer, @tel, error: e.message)
end
def customer_id
@@ -463,7 +450,7 @@ class Registration
end
def verify(code)
- InvitesRepo.new(DB).claim_code(customer_id, code) do
+ InvitesRepo.new(DB, REDIS).claim_code(customer_id, code) do
@customer.activate_plan_starting_now
end
end
@@ -628,9 +628,15 @@ class RegistrationTest < Minitest::Test
EMPromise.resolve(0),
["jmp_invite_tries-test"]
)
- Registration::Payment::InviteCode::DB.expect(:transaction, []) do
- raise InvitesRepo::Invalid, "wut"
- end
+ Registration::Payment::InviteCode::DB.expect(
+ :transaction,
+ []
+ ) { |&blk| blk.call }
+ Registration::Payment::InviteCode::DB.expect(
+ :exec,
+ OpenStruct.new(cmd_tuples: 0),
+ [String, ["test", "abc"]]
+ )
Registration::Payment::InviteCode::REDIS.expect(
:incr,
EMPromise.resolve(nil),
@@ -658,7 +664,10 @@ class RegistrationTest < Minitest::Test
EMPromise.reject(:test_result),
[Matching.new do |reply|
assert_equal :form, reply.form.type
- assert_equal "wut", reply.form.instructions
+ assert_equal(
+ "Not a valid invite code: abc",
+ reply.form.instructions
+ )
end]
)
@@ -694,16 +703,6 @@ class RegistrationTest < Minitest::Test
assert_nil reply.form.instructions
end]
)
- Registration::Payment::InviteCode::REDIS.expect(
- :incr,
- EMPromise.resolve(nil),
- ["jmp_invite_tries-test"]
- )
- Registration::Payment::InviteCode::REDIS.expect(
- :expire,
- EMPromise.resolve(nil),
- ["jmp_invite_tries-test", 60 * 60]
- )
Command::COMMAND_MANAGER.expect(
:write,
EMPromise.reject(:test_result),