Skip to content

Commit

Permalink
hotfix: allow for new signups (#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
nathanmsmith authored Jul 12, 2023
1 parent 9a95d85 commit f9ea278
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 23 deletions.
4 changes: 2 additions & 2 deletions app/controllers/omniauth_callbacks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController

sig { void }
def google_oauth2
auth = request.env["omniauth.auth"]
user = User.from_omniauth(auth, referral_code: cookies[:referral_code])
payload = User::AuthenticationPayload.from_omniauth(request.env["omniauth.auth"])
user = User.from_auth_payload(payload, referral_code: cookies[:referral_code])

remember_me(user)

Expand Down
38 changes: 28 additions & 10 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,29 +66,47 @@ def complete_referral!
T.must(referred_by).add_notification_token
end

sig { params(auth: T.untyped, referral_code: T.nilable(String)).returns(User) }
def self.from_omniauth(auth, referral_code:)
user = find_by(provider: auth.provider, uid: auth.uid)
# Type of the values we get from a Google Auth payload.
# Non-exhaustive, but feel free to modify this as we need additional fields!
# See an example payload here: https://github.com/zquestz/omniauth-google-oauth2#auth-hash
class AuthenticationPayload < T::Struct
extend T::Sig

const :provider, String
const :uid, String
const :name, String
const :email, String

sig { params(auth: T.untyped).returns(AuthenticationPayload) }
def self.from_omniauth(auth)
new(provider: auth.provider, uid: auth.uid, name: auth.info.name, email: auth.info.email)
end
end

sig { params(payload: AuthenticationPayload, referral_code: T.nilable(String)).returns(User) }
def self.from_auth_payload(payload, referral_code:)
user = find_by(provider: payload.provider, uid: payload.uid)

if user.nil?
user = new(
provider: auth.provider,
uid: auth.uid,
provider: payload.provider,
uid: payload.uid,
)

if referral_code.present?
referring_user = User.find_by(referral_code:)
user.referred_by = referring_user if referring_user.present?
end

user.email = auth.info.email
user.name = auth.info.name
user.email = payload.email
user.name = payload.name
user.save
user.subscribe("announcements")
else
user.email = auth.info.email
user.name = auth.info.name
user.email = payload.email
user.name = payload.name
user.save
end
user.save

user
end
Expand Down
6 changes: 6 additions & 0 deletions app/models/user.rbi
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,10 @@
class User
sig { params(list: String).void }
def subscribe(list); end

sig { params(list: String).void }
def unsubscribe(list); end

sig { params(list: String).returns(T::Boolean) }
def subscribed?(list); end
end
91 changes: 80 additions & 11 deletions test/models/user_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,19 +128,88 @@ class UserTest < ActiveSupport::TestCase
end
end

describe "#set_referral_code" do
it "generates a unique referral code" do
user = build(:user)
user.set_referral_code
assert_not_nil user.referral_code
describe "referral codes" do
describe "#set_referral_code" do
it "generates a unique referral code" do
user = build(:user)
user.set_referral_code
assert_not_nil user.referral_code
end

it "raises an error if it cannot generate a referral code for some reason" do
referral_code = "test-code"
T.unsafe(SecureRandom).stubs(:hex).returns(referral_code)
create(:user, referral_code:)
user = build(:user)
assert_raises(ActiveRecord::ActiveRecordError) { user.set_referral_code }
end
end
end

it "raises an error if it cannot generate a referral code for some reason" do
referral_code = "test-code"
T.unsafe(SecureRandom).stubs(:hex).returns(referral_code)
create(:user, referral_code:)
user = build(:user)
assert_raises(ActiveRecord::ActiveRecordError) { user.set_referral_code }
describe "login/out functionality" do
describe "#from_omniauth" do
it "creates a new user if one does not exist" do
payload = User::AuthenticationPayload.new(
provider: "google_oauth2",
uid: "100000000000000000000",
name: "Nathan Smith",
email: "[email protected]",
)
user = User.from_auth_payload(payload, referral_code: nil)

assert_not_nil(user)
assert_equal(payload.provider, user.provider)
assert_equal(payload.uid, user.uid)
assert_equal(payload.name, user.name)
assert_equal(payload.email, user.email)
assert_nil(user.referred_by)
assert(user.subscribed?("announcements"))
end

it "logs a user in if a user does exist" do
payload = User::AuthenticationPayload.new(
provider: "google_oauth2",
uid: "100000000000000000000",
name: "Nathan Smith",
email: "[email protected]",
)
user = create(
:user,
email: payload.email,
name: payload.name,
provider: payload.provider,
uid: payload.uid,
)
user_from_payload = User.from_auth_payload(payload, referral_code: nil)

assert_not_nil(user_from_payload)
assert_equal(payload.provider, user.provider)
assert_equal(payload.uid, user.uid)
assert_equal(payload.name, user.name)
assert_equal(payload.email, user.email)
assert_equal(user.id, user_from_payload.id)
assert_nil(user.referred_by)
assert_not(user.subscribed?("announcements"))
end

it "sets the referred by code if a user was referred" do
referring_user = create(:user)
payload = User::AuthenticationPayload.new(
provider: "google_oauth2",
uid: "100000000000000000000",
name: "Nathan Smith",
email: "[email protected]",
)
user = User.from_auth_payload(payload, referral_code: referring_user.referral_code)

assert_not_nil(user)
assert_equal(payload.provider, user.provider)
assert_equal(payload.uid, user.uid)
assert_equal(payload.name, user.name)
assert_equal(payload.email, user.email)
assert_equal(referring_user, user.referred_by)
assert(user.subscribed?("announcements"))
end
end
end

Expand Down

0 comments on commit f9ea278

Please sign in to comment.