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 %> -
- <%= render "accounts/account_sidebar_tabs", family: Current.family, active_account_group_tab: params[:account_group_tab] || "assets" %> +
+
+ <%= render "accounts/account_sidebar_tabs", family: Current.family, active_account_group_tab: params[:account_group_tab] || "assets" %> +
+ + <% if Current.family.trialing? && !self_hosted? %> +
+
+
+

Free trial

+

<%= Current.family.trial_remaining_days %> days remaining

+
+ + <%= render LinkComponent.new( + text: "Upgrade", + href: upgrade_subscription_path, + ) %> +
+ +
+
+
+
+
+ <% end %>
<% end %> <% end %> diff --git a/app/views/onboardings/_onboarding_nav.html.erb b/app/views/onboardings/_onboarding_nav.html.erb index 903a0f6b..7a2e010a 100644 --- a/app/views/onboardings/_onboarding_nav.html.erb +++ b/app/views/onboardings/_onboarding_nav.html.erb @@ -4,7 +4,7 @@ { name: "Setup", path: onboarding_path, is_complete: user.first_name.present?, step_number: 1 }, { name: "Preferences", path: preferences_onboarding_path, is_complete: user.set_onboarding_preferences_at.present?, step_number: 2 }, { name: "Goals", path: goals_onboarding_path , is_complete: user.set_onboarding_goals_at.present?, step_number: 3 }, - { name: "Start", path: trial_onboarding_path, is_complete: user.onboarded_at.present?, step_number: 4 }, + { name: "Start", path: trial_onboarding_path, is_complete: user.onboarded?, step_number: 4 }, ] %> <%# Don't show last step if self hosted %> diff --git a/app/views/onboardings/trial.html.erb b/app/views/onboardings/trial.html.erb index 0454da3e..19c7310f 100644 --- a/app/views/onboardings/trial.html.erb +++ b/app/views/onboardings/trial.html.erb @@ -32,7 +32,8 @@ <%= render ButtonComponent.new( text: "Try Maybe for 14 days", href: start_trial_subscription_path, - full_width: true + full_width: true, + data: { turbo: false } ) %>
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