diff --git a/lib/invites_repo.rb b/lib/invites_repo.rb index dac00bd6a91929d2f8aeeca01640cf25a53021d3..023a06bb4aad43c5722f3dc63db0c198e99a3d09 100644 --- a/lib/invites_repo.rb +++ b/lib/invites_repo.rb @@ -135,8 +135,12 @@ protected 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 + }.then { + @redis.hexists("jmp_group_codes", code) + }.then { |is_group| + raise Invalid, "#{code} is a post-payment referral" if is_group.to_i == 1 + raise Invalid, "Not a valid invite code: #{code}" - end + } end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 6978753ce6f61ab9a9cb3b87106207ef632cf146..8aec8f80932d69d83a474e838522e7961d414097 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -257,6 +257,10 @@ class FakeRedis @values.dig(key, field) end + def hexists(key, field) + hget(key, field).nil? ? 0 : 1 + end + def hincrby(key, field, incrby) @values[key] ||= {} @values[key][field] ||= 0 diff --git a/test/test_registration.rb b/test/test_registration.rb index 1fe64ca87dd070cdd0c26d1a703eb1f19f0e743b..1b194c0c8a4e47e31b8eb4227ed5fd2efbbf170e 100644 --- a/test/test_registration.rb +++ b/test/test_registration.rb @@ -736,6 +736,11 @@ class RegistrationTest < Minitest::Test EMPromise.resolve(nil), ["jmp_invite_tries-test", 60 * 60] ) + Registration::Payment::InviteCode::REDIS.expect( + :hexists, + EMPromise.resolve(0), + ["jmp_group_codes", "abc"] + ) Command::COMMAND_MANAGER.expect( :write, EMPromise.resolve( @@ -772,6 +777,74 @@ class RegistrationTest < Minitest::Test end em :test_write_bad_code + def test_write_group_code + result = execute_command do + customer = customer(plan_name: "test_usd") + Registration::Payment::InviteCode::REDIS.expect( + :get, + EMPromise.resolve(0), + ["jmp_invite_tries-test"] + ) + 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), + ["jmp_invite_tries-test"] + ) + Registration::Payment::InviteCode::REDIS.expect( + :expire, + EMPromise.resolve(nil), + ["jmp_invite_tries-test", 60 * 60] + ) + Registration::Payment::InviteCode::REDIS.expect( + :hexists, + EMPromise.resolve(1), + ["jmp_group_codes", "abc"] + ) + Command::COMMAND_MANAGER.expect( + :write, + EMPromise.resolve( + Blather::Stanza::Iq::Command.new.tap { |iq| + iq.form.fields = [{ var: "code", value: "abc" }] + } + ), + [Matching.new do |reply| + assert_equal :form, reply.form.type + assert_nil reply.form.instructions + end] + ) + Command::COMMAND_MANAGER.expect( + :write, + EMPromise.reject(:test_result), + [Matching.new do |reply| + assert_equal :form, reply.form.type + assert_equal( + "abc is a post-payment referral", + reply.form.instructions + ) + end] + ) + + Registration::Payment::InviteCode.new( + customer, + "+15555550000" + ).write.catch { |e| e } + end + assert_equal :test_result, result + assert_mock Command::COMMAND_MANAGER + assert_mock Registration::Payment::InviteCode::DB + assert_mock Registration::Payment::InviteCode::REDIS + end + em :test_write_group_code + def test_write_bad_code_over_limit result = execute_command do customer = customer(plan_name: "test_usd")