mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-19 13:19:39 +02:00
Remove trend initialization from Series model to streamline value calculations.
Added initial pass at onboarding system tests.
This commit is contained in:
parent
07ca33f2f4
commit
6dae236fe0
3 changed files with 359 additions and 4 deletions
|
@ -33,10 +33,6 @@ class Series
|
||||||
start_date: start_date,
|
start_date: start_date,
|
||||||
end_date: end_date,
|
end_date: end_date,
|
||||||
interval: interval,
|
interval: interval,
|
||||||
trend: Trend.new(
|
|
||||||
current: ordered.last[:value],
|
|
||||||
previous: ordered.first[:value]
|
|
||||||
),
|
|
||||||
values: [ nil, *ordered ].each_cons(2).map do |prev_value, curr_value|
|
values: [ nil, *ordered ].each_cons(2).map do |prev_value, curr_value|
|
||||||
Value.new(
|
Value.new(
|
||||||
date: curr_value[:date],
|
date: curr_value[:date],
|
||||||
|
|
167
test/controllers/onboardings_controller_test.rb
Normal file
167
test/controllers/onboardings_controller_test.rb
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
class OnboardingsControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
setup do
|
||||||
|
@user = users(:family_admin)
|
||||||
|
@family = @user.family
|
||||||
|
|
||||||
|
# Reset onboarding state
|
||||||
|
@user.update!(set_onboarding_preferences_at: nil)
|
||||||
|
|
||||||
|
sign_in @user
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should get show" do
|
||||||
|
get onboarding_url
|
||||||
|
assert_response :success
|
||||||
|
assert_select "h1", text: /set up your account/i
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should get preferences" do
|
||||||
|
get preferences_onboarding_url
|
||||||
|
assert_response :success
|
||||||
|
assert_select "h1", text: /preferences/i
|
||||||
|
end
|
||||||
|
|
||||||
|
test "preferences page renders Series chart data without errors" do
|
||||||
|
get preferences_onboarding_url
|
||||||
|
assert_response :success
|
||||||
|
|
||||||
|
# This test specifically targets the Series model bug
|
||||||
|
# The page should render without throwing the "unknown keyword: :trend" error
|
||||||
|
assert_select "[data-controller='time-series-chart']"
|
||||||
|
assert_select "#previewChart"
|
||||||
|
|
||||||
|
# Verify that the Series.from_raw_values call in the view works
|
||||||
|
# If the Series bug existed, this would raise an ActionView::Template::Error
|
||||||
|
assert_no_match /unknown keyword: :trend/, response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
test "preferences page includes chart with valid JSON data" do
|
||||||
|
get preferences_onboarding_url
|
||||||
|
assert_response :success
|
||||||
|
|
||||||
|
# Extract the chart data from the response
|
||||||
|
chart_data_match = response.body.match(/data-time-series-chart-data-value="([^"]*)"/)
|
||||||
|
assert chart_data_match, "Chart data attribute should be present"
|
||||||
|
|
||||||
|
# Decode HTML entities and parse JSON
|
||||||
|
chart_data_json = CGI.unescapeHTML(chart_data_match[1])
|
||||||
|
|
||||||
|
# Should be valid JSON
|
||||||
|
assert_nothing_raised do
|
||||||
|
chart_data = JSON.parse(chart_data_json)
|
||||||
|
|
||||||
|
# Verify expected structure
|
||||||
|
assert chart_data.key?("start_date")
|
||||||
|
assert chart_data.key?("end_date")
|
||||||
|
assert chart_data.key?("interval")
|
||||||
|
assert chart_data.key?("trend")
|
||||||
|
assert chart_data.key?("values")
|
||||||
|
|
||||||
|
# Verify trend has expected structure
|
||||||
|
trend = chart_data["trend"]
|
||||||
|
assert trend.key?("value")
|
||||||
|
assert trend.key?("percent")
|
||||||
|
assert trend.key?("current")
|
||||||
|
assert trend.key?("previous")
|
||||||
|
|
||||||
|
# Verify values array has expected structure
|
||||||
|
values = chart_data["values"]
|
||||||
|
assert values.is_a?(Array)
|
||||||
|
assert values.length > 0
|
||||||
|
|
||||||
|
values.each do |value|
|
||||||
|
assert value.key?("date")
|
||||||
|
assert value.key?("value")
|
||||||
|
assert value.key?("trend")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should get goals" do
|
||||||
|
get goals_onboarding_url
|
||||||
|
assert_response :success
|
||||||
|
assert_select "h1", text: /What brings you to Maybe/i
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should get trial" do
|
||||||
|
get trial_onboarding_url
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
|
||||||
|
test "preferences page shows currency formatting example" do
|
||||||
|
get preferences_onboarding_url
|
||||||
|
assert_response :success
|
||||||
|
|
||||||
|
# Should show formatted currency example
|
||||||
|
assert_select "p", text: /\$2,325\.25/
|
||||||
|
assert_select "span", text: /\+\$78\.90/
|
||||||
|
end
|
||||||
|
|
||||||
|
test "preferences page shows date formatting example" do
|
||||||
|
get preferences_onboarding_url
|
||||||
|
assert_response :success
|
||||||
|
|
||||||
|
# Should show formatted date example (checking for the specific format shown)
|
||||||
|
assert_match /10-23-2024/, response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
test "preferences page includes all required form fields" do
|
||||||
|
get preferences_onboarding_url
|
||||||
|
assert_response :success
|
||||||
|
|
||||||
|
# Verify all form fields are present
|
||||||
|
assert_select "select[name='user[family_attributes][locale]']"
|
||||||
|
assert_select "select[name='user[family_attributes][currency]']"
|
||||||
|
assert_select "select[name='user[family_attributes][date_format]']"
|
||||||
|
assert_select "select[name='user[theme]']"
|
||||||
|
assert_select "button[type='submit']"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "preferences page includes JavaScript controllers" do
|
||||||
|
get preferences_onboarding_url
|
||||||
|
assert_response :success
|
||||||
|
|
||||||
|
# Should include onboarding controller for dynamic updates
|
||||||
|
assert_select "[data-controller*='onboarding']"
|
||||||
|
assert_select "[data-controller*='time-series-chart']"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "all onboarding pages set correct layout" do
|
||||||
|
# Test that all onboarding pages use the wizard layout
|
||||||
|
get onboarding_url
|
||||||
|
assert_response :success
|
||||||
|
|
||||||
|
get preferences_onboarding_url
|
||||||
|
assert_response :success
|
||||||
|
|
||||||
|
get goals_onboarding_url
|
||||||
|
assert_response :success
|
||||||
|
|
||||||
|
get trial_onboarding_url
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
|
||||||
|
test "onboarding pages require authentication" do
|
||||||
|
sign_out
|
||||||
|
|
||||||
|
get onboarding_url
|
||||||
|
assert_redirected_to new_session_url
|
||||||
|
|
||||||
|
get preferences_onboarding_url
|
||||||
|
assert_redirected_to new_session_url
|
||||||
|
|
||||||
|
get goals_onboarding_url
|
||||||
|
assert_redirected_to new_session_url
|
||||||
|
|
||||||
|
get trial_onboarding_url
|
||||||
|
assert_redirected_to new_session_url
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def sign_out
|
||||||
|
delete session_path(@user.sessions.last) if @user.sessions.any?
|
||||||
|
end
|
||||||
|
end
|
192
test/system/onboardings_test.rb
Normal file
192
test/system/onboardings_test.rb
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
require "application_system_test_case"
|
||||||
|
|
||||||
|
class OnboardingsTest < ApplicationSystemTestCase
|
||||||
|
setup do
|
||||||
|
@user = users(:family_admin)
|
||||||
|
@family = @user.family
|
||||||
|
|
||||||
|
# Reset onboarding state
|
||||||
|
@user.update!(set_onboarding_preferences_at: nil)
|
||||||
|
|
||||||
|
sign_in @user
|
||||||
|
end
|
||||||
|
|
||||||
|
test "can complete the full onboarding flow" do
|
||||||
|
# Start at the main onboarding page
|
||||||
|
visit onboarding_path
|
||||||
|
|
||||||
|
assert_text "Let's set up your account"
|
||||||
|
assert_button "Get started"
|
||||||
|
|
||||||
|
# Navigate to preferences
|
||||||
|
click_button "Get started"
|
||||||
|
|
||||||
|
assert_current_path preferences_onboarding_path
|
||||||
|
assert_text "Set your preferences"
|
||||||
|
|
||||||
|
# Test that the chart renders without errors (this would catch the Series bug)
|
||||||
|
assert_selector "[data-controller='time-series-chart']"
|
||||||
|
|
||||||
|
# Fill out preferences form
|
||||||
|
select "English", from: "user_family_attributes_locale"
|
||||||
|
select "United States Dollar (USD)", from: "user_family_attributes_currency"
|
||||||
|
select "MM/DD/YYYY", from: "user_family_attributes_date_format"
|
||||||
|
select "Light", from: "user_theme"
|
||||||
|
|
||||||
|
# Submit preferences
|
||||||
|
click_button "Continue"
|
||||||
|
|
||||||
|
# Should redirect to goals page
|
||||||
|
assert_current_path goals_onboarding_path
|
||||||
|
assert_text "What brings you to Maybe?"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "preferences page renders chart without errors" do
|
||||||
|
visit preferences_onboarding_path
|
||||||
|
|
||||||
|
# This test specifically targets the Series model bug
|
||||||
|
# The chart should render without throwing JavaScript errors
|
||||||
|
assert_selector "[data-controller='time-series-chart']"
|
||||||
|
assert_selector "#previewChart"
|
||||||
|
|
||||||
|
# Verify the chart data is properly formatted JSON
|
||||||
|
chart_element = find("[data-controller='time-series-chart']")
|
||||||
|
chart_data = chart_element["data-time-series-chart-data-value"]
|
||||||
|
|
||||||
|
# Should be valid JSON
|
||||||
|
assert_nothing_raised do
|
||||||
|
JSON.parse(chart_data)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Verify the preview example shows
|
||||||
|
assert_text "Example"
|
||||||
|
assert_text "$2,325.25"
|
||||||
|
assert_text "+$78.90"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "can change currency and see preview update" do
|
||||||
|
visit preferences_onboarding_path
|
||||||
|
|
||||||
|
# Change currency
|
||||||
|
select "Euro (EUR)", from: "user_family_attributes_currency"
|
||||||
|
|
||||||
|
# The preview should update (this tests the JavaScript controller)
|
||||||
|
# Note: This would require the onboarding controller to handle currency changes
|
||||||
|
assert_text "Example"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "can change date format and see preview update" do
|
||||||
|
visit preferences_onboarding_path
|
||||||
|
|
||||||
|
# Change date format
|
||||||
|
select "DD/MM/YYYY", from: "user_family_attributes_date_format"
|
||||||
|
|
||||||
|
# The preview should update
|
||||||
|
assert_text "Example"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "can change theme" do
|
||||||
|
visit preferences_onboarding_path
|
||||||
|
|
||||||
|
# Change theme
|
||||||
|
select "Dark", from: "user_theme"
|
||||||
|
|
||||||
|
# Theme should be applied (this tests the JavaScript controller)
|
||||||
|
assert_text "Example"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "preferences form validation" do
|
||||||
|
visit preferences_onboarding_path
|
||||||
|
|
||||||
|
# Clear required fields and try to submit
|
||||||
|
select "", from: "user_family_attributes_locale"
|
||||||
|
click_button "Continue"
|
||||||
|
|
||||||
|
# Should stay on preferences page with validation errors
|
||||||
|
assert_current_path preferences_onboarding_path
|
||||||
|
end
|
||||||
|
|
||||||
|
test "preferences form saves data correctly" do
|
||||||
|
visit preferences_onboarding_path
|
||||||
|
|
||||||
|
# Fill out form with specific values
|
||||||
|
select "Spanish", from: "user_family_attributes_locale"
|
||||||
|
select "Euro (EUR)", from: "user_family_attributes_currency"
|
||||||
|
select "DD/MM/YYYY", from: "user_family_attributes_date_format"
|
||||||
|
select "Dark", from: "user_theme"
|
||||||
|
|
||||||
|
click_button "Continue"
|
||||||
|
|
||||||
|
# Verify data was saved
|
||||||
|
@family.reload
|
||||||
|
@user.reload
|
||||||
|
|
||||||
|
assert_equal "es", @family.locale
|
||||||
|
assert_equal "EUR", @family.currency
|
||||||
|
assert_equal "DD/MM/YYYY", @family.date_format
|
||||||
|
assert_equal "dark", @user.theme
|
||||||
|
assert_not_nil @user.set_onboarding_preferences_at
|
||||||
|
end
|
||||||
|
|
||||||
|
test "goals page renders correctly" do
|
||||||
|
# Complete preferences first
|
||||||
|
@user.update!(set_onboarding_preferences_at: Time.current)
|
||||||
|
|
||||||
|
visit goals_onboarding_path
|
||||||
|
|
||||||
|
assert_text "What brings you to Maybe?"
|
||||||
|
assert_button "Continue"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "trial page renders correctly" do
|
||||||
|
visit trial_onboarding_path
|
||||||
|
|
||||||
|
assert_text "trial" # Adjust based on actual content
|
||||||
|
end
|
||||||
|
|
||||||
|
test "navigation between onboarding steps" do
|
||||||
|
# Start at main onboarding
|
||||||
|
visit onboarding_path
|
||||||
|
click_button "Get started"
|
||||||
|
|
||||||
|
# Should be at preferences
|
||||||
|
assert_current_path preferences_onboarding_path
|
||||||
|
|
||||||
|
# Complete preferences
|
||||||
|
select "English", from: "user_family_attributes_locale"
|
||||||
|
select "United States Dollar (USD)", from: "user_family_attributes_currency"
|
||||||
|
select "MM/DD/YYYY", from: "user_family_attributes_date_format"
|
||||||
|
click_button "Continue"
|
||||||
|
|
||||||
|
# Should be at goals
|
||||||
|
assert_current_path goals_onboarding_path
|
||||||
|
end
|
||||||
|
|
||||||
|
test "onboarding nav shows correct steps" do
|
||||||
|
visit preferences_onboarding_path
|
||||||
|
|
||||||
|
# Check that navigation shows current step
|
||||||
|
assert_selector ".onboarding-nav" # Adjust selector based on actual implementation
|
||||||
|
end
|
||||||
|
|
||||||
|
test "logout option is available during onboarding" do
|
||||||
|
visit preferences_onboarding_path
|
||||||
|
|
||||||
|
# Should have logout option
|
||||||
|
assert_link "Sign out" # Adjust based on actual implementation
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def sign_in(user)
|
||||||
|
visit new_session_path
|
||||||
|
within "form" do
|
||||||
|
fill_in "Email", with: user.email
|
||||||
|
fill_in "Password", with: user_password_test
|
||||||
|
click_on "Log in"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Wait for successful login
|
||||||
|
assert_current_path root_path
|
||||||
|
end
|
||||||
|
end
|
Loading…
Add table
Add a link
Reference in a new issue