Move signup code back to the app, leave only queenbee hooks

This commit is contained in:
Jorge Manrubia
2025-11-27 12:52:12 +01:00
parent 68b6bdf8ad
commit 3d849a202a
9 changed files with 73 additions and 176 deletions
@@ -1,24 +0,0 @@
class Signup::CompletionsController < ApplicationController
layout "public"
disallow_account_scope
def new
@signup = Signup.new(identity: Current.identity)
end
def create
@signup = Signup.new(signup_params)
if @signup.complete
redirect_to landing_url(script_name: @signup.account.slug)
else
render :new, status: :unprocessable_entity
end
end
private
def signup_params
params.expect(signup: %i[ full_name ]).with_defaults(identity: Current.identity)
end
end
-4
View File
@@ -1,9 +1,5 @@
Fizzy::Saas::Engine.routes.draw do
get "/signup/new", to: redirect("/session/new")
namespace :signup do
resource :completion, only: %i[ new create ]
end
Queenbee.routes(self)
end
+3
View File
@@ -1,5 +1,6 @@
require_relative "metrics"
require_relative "transaction_pinning"
require_relative "signup"
module Fizzy
module Saas
@@ -50,6 +51,8 @@ module Fizzy
end
config.to_prepare do
::Signup.prepend(Fizzy::Saas::Signup)
Queenbee::Subscription.short_names = Subscription::SHORT_NAMES
# Default to local dev QB token if not set
+44
View File
@@ -0,0 +1,44 @@
module Fizzy
module Saas
module Signup
extend ActiveSupport::Concern
included do
attr_reader :queenbee_account
end
private
def create_tenant
@queenbee_account = Queenbee::Remote::Account.create!(queenbee_account_attributes)
@queenbee_account.id.to_s
end
def handle_account_creation_error(error)
@queenbee_account&.cancel
@queenbee_account = nil
end
def queenbee_account_attributes
{}.tap do |attributes|
attributes[:product_name] = "fizzy"
attributes[:name] = generate_account_name
attributes[:owner_name] = full_name
attributes[:owner_email] = email_address
attributes[:trial] = true
attributes[:subscription] = subscription_attributes
attributes[:remote_request] = request_attributes
# # TODO: Terms of Service
# attributes[:terms_of_service] = true
# We've confirmed the email
attributes[:auto_allow] = true
# Tell Queenbee to skip the request to create a local account. We've created it ourselves.
attributes[:skip_remote] = true
end
end
end
end
end
@@ -1,23 +1,17 @@
require "test_helper"
class SaasSessionsControllerTest < ActionDispatch::IntegrationTest
class Fizzy::Saas::SessionsControllerTest < ActionDispatch::IntegrationTest
test "create for a new user" do
untenanted do
assert_difference -> { Identity.count }, +1 do
assert_difference -> { MagicLink.count }, +1 do
post session_path,
params: { email_address: "nonexistent-#{SecureRandom.hex(6)}@example.com" },
headers: http_basic_auth_headers("testname", "testpassword")
params: { email_address: "nonexistent-#{SecureRandom.hex(6)}@example.com" }
end
end
assert_redirected_to session_magic_link_path
end
end
private
def http_basic_auth_headers(user, password)
{ "Authorization" => ActionController::HttpAuthentication::Basic.encode_credentials(user, password) }
end
end
@@ -1,43 +0,0 @@
require "test_helper"
class Signup::CompletionsControllerTest < ActionDispatch::IntegrationTest
setup do
@signup = Signup.new(email_address: "newuser@example.com", full_name: "New User")
@signup.create_identity || raise("Failed to create identity")
sign_in_as @signup.identity
end
test "new" do
untenanted do
get saas.new_signup_completion_path
end
assert_response :success
end
test "create" do
untenanted do
post saas.signup_completion_path, params: {
signup: {
full_name: @signup.full_name
}
}
end
assert_response :redirect, "Valid params should redirect"
end
test "create with invalid params" do
untenanted do
post saas.signup_completion_path, params: {
signup: {
full_name: ""
}
}
end
assert_response :unprocessable_entity, "Invalid params should return unprocessable entity"
end
end
View File
@@ -1,61 +0,0 @@
require "test_helper"
class Signup::AccountNameGeneratorTest < ActiveSupport::TestCase
setup do
@identity = ::Identity.create!(email_address: "newart.userbaum@example.com")
@name = "Newart userbaum"
@generator = Signup::AccountNameGenerator.new(identity: @identity, name: @name)
end
test "generate" do
account_name = @generator.generate
assert_equal "Newart's Fizzy", account_name, "The 1st account doesn't have 1st in the name"
first_account = ::Account.create!(external_account_id: "1st", name: account_name)
::Current.without_account do
@identity.users.create!(account: first_account, name: @name)
@identity.reload
end
account_name = @generator.generate
assert_equal "Newart's 2nd Fizzy", account_name
second_account = ::Account.create!(external_account_id: "2nd", name: account_name)
::Current.without_account do
@identity.users.create!(account: second_account, name: @name)
@identity.reload
end
account_name = @generator.generate
assert_equal "Newart's 3rd Fizzy", account_name
third_account = ::Account.create!(external_account_id: "3rd", name: account_name)
::Current.without_account do
@identity.users.create!(account: third_account, name: @name)
@identity.reload
end
account_name = @generator.generate
assert_equal "Newart's 4th Fizzy", account_name
fourth_account = ::Account.create!(external_account_id: "4th", name: account_name)
::Current.without_account do
@identity.users.create!(account: fourth_account, name: @name)
@identity.reload
end
account_name = @generator.generate
assert_equal "Newart's 5th Fizzy", account_name
end
test "generate continues from the previous highest index" do
account = ::Account.create!(external_account_id: "12th", name: "Newart's 12th Fizzy")
::Current.without_account do
@identity.users.create!(account: account, name: @name)
@identity.reload
end
account_name = @generator.generate
assert_equal "Newart's 13th Fizzy", account_name
end
end
+24 -36
View File
@@ -1,37 +1,14 @@
require "test_helper"
class SignupTest < ActiveSupport::TestCase
test "#create_identity" do
signup = Signup.new(email_address: "brian@example.com")
class Fizzy::Saas::SignupTest < ActiveSupport::TestCase
test "#complete creates queenbee account and uses its id as tenant" do
queenbee_account = mock("queenbee_account")
queenbee_account.stubs(:id).returns(123456)
assert_difference -> { ::Identity.count }, 1 do
assert_difference -> { ::MagicLink.count }, 1 do
assert signup.create_identity
end
end
Queenbee::Remote::Account.expects(:create!).once.returns(queenbee_account)
Account.any_instance.expects(:setup_customer_template).once
assert_empty signup.errors
assert signup.identity
assert signup.identity.persisted?
signup_existing = Signup.new(email_address: "brian@example.com")
assert_no_difference -> { ::Identity.count } do
assert_difference -> { ::MagicLink.count }, 1 do
assert signup_existing.create_identity, "Should send magic link for existing identity"
end
end
signup_invalid = Signup.new(email_address: "")
assert_raises do
signup_invalid.create_identity
end
end
test "#complete" do
::Account.any_instance.expects(:setup_customer_template).once
::Current.without_account do
Current.without_account do
signup = Signup.new(
full_name: "Kevin",
identity: identities(:kevin)
@@ -40,15 +17,26 @@ class SignupTest < ActiveSupport::TestCase
assert signup.complete
assert signup.account
assert signup.user
assert_equal "Kevin", signup.user.name
assert_equal "123456", signup.account.external_account_id.to_s
end
end
signup_invalid = Signup.new(
full_name: "",
test "#complete calls cancel on queenbee account when account creation fails" do
queenbee_account = mock("queenbee_account")
queenbee_account.stubs(:id).returns(789012)
queenbee_account.expects(:cancel).once
Queenbee::Remote::Account.expects(:create!).once.returns(queenbee_account)
Account.any_instance.stubs(:setup_customer_template).raises(StandardError.new("Account setup failed"))
Current.without_account do
signup = Signup.new(
full_name: "Kevin",
identity: identities(:kevin)
)
assert_not signup_invalid.complete
assert_not_empty signup_invalid.errors[:full_name]
assert_not signup.complete
assert_includes signup.errors[:base], "Something went wrong, and we couldn't create your account. Please give it another try."
end
end
end