Invites Repo
Christopher Vollick
created 3 years ago
In preparation for another command I'd like to make I've first got to
make a place where Invites live.
There's probably other parts of the code that interact with Invites that
I've missed, but this is a good start at least.
Change summary
lib/customer.rb | 6 ++----
lib/invites_repo.rb | 30 ++++++++++++++++++++++++++++++
lib/registration.rb | 19 +++++--------------
test/test_registration.rb | 2 +-
4 files changed, 38 insertions(+), 19 deletions(-)
Detailed changes
@@ -10,6 +10,7 @@ require_relative "./customer_ogm"
require_relative "./customer_info"
require_relative "./customer_finacials"
require_relative "./backend_sgx"
+require_relative "./invites_repo"
require_relative "./payment_methods"
require_relative "./plan"
require_relative "./proxied_jid"
@@ -75,10 +76,7 @@ class Customer
end
def unused_invites
- promise = DB.query_defer(<<~SQL, [customer_id])
- SELECT code FROM unused_invites WHERE creator_id=$1
- SQL
- promise.then { |result| result.map { |row| row["code"] } }
+ InvitesRepo.new(DB).unused_invites(customer_id)
end
def stanza_to(stanza)
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class InvitesRepo
+ class Invalid < StandardError; end
+
+ def initialize(db=DB)
+ @db = db
+ end
+
+ def unused_invites(customer_id)
+ promise = @db.query_defer(<<~SQL, [customer_id])
+ SELECT code FROM unused_invites WHERE creator_id=$1
+ SQL
+ promise.then { |result| result.map { |row| row["code"] } }
+ end
+
+ def claim_code(customer_id, code, &blk)
+ EMPromise.resolve(nil).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
+
+ blk.call
+ end
+ end
+ end
+end
@@ -8,6 +8,7 @@ require_relative "./alt_top_up_form"
require_relative "./bandwidth_tn_order"
require_relative "./command"
require_relative "./em"
+require_relative "./invites_repo"
require_relative "./oob"
require_relative "./proxied_jid"
require_relative "./tel_selections"
@@ -318,8 +319,6 @@ class Registration
class InviteCode
Payment.kinds[:code] = method(:new)
- class Invalid < StandardError; end
-
FIELDS = [{
var: "code",
type: "text-single",
@@ -353,14 +352,14 @@ class Registration
verify(iq.form.field("code")&.value&.to_s)
}.then {
Finish.new(@customer, @tel)
- }.catch_only(Invalid, &method(:invalid_code)).then(&:write)
+ }.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 Invalid, "Too many wrong attempts" if t.to_i > 10
+ raise InvitesRepo::Invalid, "Too many wrong attempts" if t.to_i > 10
end
end
@@ -378,16 +377,8 @@ class Registration
end
def verify(code)
- EMPromise.resolve(nil).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
-
- @customer.activate_plan_starting_now
- end
+ InvitesRepo.new(DB).claim_code(customer_id, code) do
+ @customer.activate_plan_starting_now
end
end
end
@@ -551,7 +551,7 @@ class RegistrationTest < Minitest::Test
["jmp_invite_tries-test"]
)
Registration::Payment::InviteCode::DB.expect(:transaction, []) do
- raise Registration::Payment::InviteCode::Invalid, "wut"
+ raise InvitesRepo::Invalid, "wut"
end
Registration::Payment::InviteCode::REDIS.expect(
:incr,