diff --git a/app/controllers/concerns/onboardable.rb b/app/controllers/concerns/onboardable.rb index a5297345..9e7dd144 100644 --- a/app/controllers/concerns/onboardable.rb +++ b/app/controllers/concerns/onboardable.rb @@ -18,11 +18,7 @@ module Onboardable return unless Current.user return unless redirectable_path?(request.path) - # Check if trial was started VERY recently (e.g., within the last few seconds) - # If so, assume onboarding was just completed in the previous request, even if onboarded_at appears blank momentarily. - trial_just_started = Current.family.trial_started_at.present? && Current.family.trial_started_at > 10.seconds.ago - - if Current.user.onboarded_at.blank? && !trial_just_started + if !Current.user.onboarded? redirect_to onboarding_path elsif !Current.family.subscribed? && !Current.family.trialing? && !self_hosted? redirect_to upgrade_subscription_path diff --git a/app/controllers/onboardings_controller.rb b/app/controllers/onboardings_controller.rb index 9b98be3b..0f616ce4 100644 --- a/app/controllers/onboardings_controller.rb +++ b/app/controllers/onboardings_controller.rb @@ -14,7 +14,6 @@ class OnboardingsController < ApplicationController end private - def set_user @user = Current.user end diff --git a/app/controllers/subscriptions_controller.rb b/app/controllers/subscriptions_controller.rb index 895c7192..45f4548a 100644 --- a/app/controllers/subscriptions_controller.rb +++ b/app/controllers/subscriptions_controller.rb @@ -8,16 +8,14 @@ class SubscriptionsController < ApplicationController end def start_trial - if Current.family.trial_started_at.present? - redirect_to root_path, alert: "You've already started or completed your trial" - else - Family.transaction do - Current.family.update(trial_started_at: Time.current) - Current.user.update(onboarded_at: Time.current) + unless Current.family.trialing? + ActiveRecord::Base.transaction do + Current.user.update!(onboarded_at: Time.current) + Current.family.update!(trial_started_at: Time.current) end - - redirect_to root_path, notice: "Your trial has started" end + + redirect_to root_path, notice: "Welcome to Maybe!" end def new diff --git a/app/models/user.rb b/app/models/user.rb index 00dfd5af..d211878a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -152,6 +152,10 @@ class User < ApplicationRecord totp.provisioning_uri(email) end + def onboarded? + onboarded_at.present? + end + private def ensure_valid_profile_image return unless profile_image.attached? diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index e77f1916..25432ff0 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -79,8 +79,31 @@ <% if content_for?(:sidebar) %> <%= yield :sidebar %> <% else %> -
diff --git a/test/controllers/concerns/onboardable_test.rb b/test/controllers/concerns/onboardable_test.rb new file mode 100644 index 00000000..c4d313ae --- /dev/null +++ b/test/controllers/concerns/onboardable_test.rb @@ -0,0 +1,43 @@ +require "test_helper" + +class OnboardableTest < ActionDispatch::IntegrationTest + setup do + sign_in @user = users(:empty) + end + + test "must complete onboarding before any other action" do + @user.update!(onboarded_at: nil) + + get root_path + assert_redirected_to onboarding_path + + @user.family.update!(trial_started_at: 1.day.ago, stripe_subscription_status: "active") + + get root_path + assert_redirected_to onboarding_path + end + + test "must subscribe if onboarding complete and no trial or subscription is active" do + @user.update!(onboarded_at: 1.day.ago) + @user.family.update!(trial_started_at: nil, stripe_subscription_status: "incomplete") + + get root_path + assert_redirected_to upgrade_subscription_path + end + + test "onboarded trial user can visit dashboard" do + @user.update!(onboarded_at: 1.day.ago) + @user.family.update!(trial_started_at: 1.day.ago, stripe_subscription_status: "incomplete") + + get root_path + assert_response :success + end + + test "onboarded subscribed user can visit dashboard" do + @user.update!(onboarded_at: 1.day.ago) + @user.family.update!(stripe_subscription_status: "active") + + get root_path + assert_response :success + end +end diff --git a/test/controllers/subscriptions_controller_test.rb b/test/controllers/subscriptions_controller_test.rb index 952aed3b..abd7473f 100644 --- a/test/controllers/subscriptions_controller_test.rb +++ b/test/controllers/subscriptions_controller_test.rb @@ -5,6 +5,34 @@ class SubscriptionsControllerTest < ActionDispatch::IntegrationTest sign_in @user = users(:family_admin) end + test "can start trial" do + @user.update!(onboarded_at: nil) + @user.family.update!(trial_started_at: nil, stripe_subscription_status: "incomplete") + + assert_nil @user.onboarded_at + assert_nil @user.family.trial_started_at + + post start_trial_subscription_path + assert_redirected_to root_path + assert_equal "Welcome to Maybe!", flash[:notice] + + assert @user.reload.onboarded? + assert @user.family.reload.trial_started_at.present? + end + + test "if user re-enters onboarding, don't restart trial" do + onboard_time = 1.day.ago + trial_start_time = 1.day.ago + + @user.update!(onboarded_at: onboard_time) + @user.family.update!(trial_started_at: trial_start_time, stripe_subscription_status: "incomplete") + + post start_trial_subscription_path + assert_redirected_to root_path + + assert @user.reload.family.trial_started_at < Date.current + end + test "redirects to settings if self hosting" do Rails.application.config.app_mode.stubs(:self_hosted?).returns(true) get subscription_path