mirror of
https://github.com/we-promise/sure.git
synced 2026-05-31 16:29:03 +00:00
* optimize net_category_totals() by using memoized cache * fix issue - net_category_totals cache is never populated - suggested by coderabbitAI * fix 422 error for service-worker * remove warning of [assigned but unused variables] - income_statement.rb * remove warnings of [assigned but unused] from Prism - income_statement_test.rb * add some measurements to improve docstring coverage, follow CodeRabbit recommendation * attach Skylight monitoring for dev env as well - use my own Skylight auth token * integrate Skylight with my own account auth token for local benchmark * fix PR review suggestion - Move fallback release-note copy to i18n keys * follow PR review - Fix changelog GitHub fetch timeout bounding * FIX - Variable shadowing; Prefer stubbing the specific instance over any_instance.expects * fix CodeRabbit feedback - Reusing the same stub for both classifications hides a contract mismatch * fix CodeRabbit FEEDBACK - Reconsider enabling Skylight by default in development * fix CodeRabbitAI FEEDBACK - reconsider unconditionally enabling Skylight in development * fix Security scan FEEDBACK before PR merge * fix jjmata feedback
136 lines
4.4 KiB
Ruby
136 lines
4.4 KiB
Ruby
require "test_helper"
|
|
|
|
class PagesControllerTest < ActionDispatch::IntegrationTest
|
|
include EntriesTestHelper
|
|
|
|
setup do
|
|
sign_in @user = users(:family_admin)
|
|
@intro_user = users(:intro_user)
|
|
@family = @user.family
|
|
end
|
|
|
|
test "dashboard" do
|
|
get root_path
|
|
assert_response :ok
|
|
end
|
|
|
|
test "dashboard memoizes income statement period totals while rendering" do
|
|
income_statement = IncomeStatement.new(@family)
|
|
IncomeStatement.stubs(:new).returns(income_statement)
|
|
|
|
fake_expense_period_total = IncomeStatement::PeriodTotal.new(
|
|
classification: "expense",
|
|
total: 0,
|
|
currency: @family.currency,
|
|
category_totals: []
|
|
)
|
|
|
|
fake_income_period_total = IncomeStatement::PeriodTotal.new(
|
|
classification: "income",
|
|
total: 0,
|
|
currency: @family.currency,
|
|
category_totals: []
|
|
)
|
|
|
|
income_statement.expects(:build_period_total)
|
|
.with(classification: "expense", period: kind_of(Period))
|
|
.once
|
|
.returns(fake_expense_period_total)
|
|
|
|
income_statement.expects(:build_period_total)
|
|
.with(classification: "income", period: kind_of(Period))
|
|
.once
|
|
.returns(fake_income_period_total)
|
|
|
|
get root_path
|
|
|
|
assert_response :ok
|
|
end
|
|
|
|
test "intro page requires guest role" do
|
|
get intro_path
|
|
|
|
assert_redirected_to root_path
|
|
assert_equal "Intro is only available to guest users.", flash[:alert]
|
|
end
|
|
|
|
test "intro page is accessible for guest users" do
|
|
sign_in @intro_user
|
|
|
|
get intro_path
|
|
|
|
assert_response :ok
|
|
end
|
|
|
|
test "dashboard renders sankey chart with subcategories" do
|
|
# Create parent category with subcategory
|
|
parent_category = @family.categories.create!(name: "Shopping", color: "#FF5733")
|
|
subcategory = @family.categories.create!(name: "Groceries", parent: parent_category, color: "#33FF57")
|
|
|
|
# Create transactions using helper
|
|
create_transaction(account: @family.accounts.first, name: "General shopping", amount: 100, category: parent_category)
|
|
create_transaction(account: @family.accounts.first, name: "Grocery store", amount: 50, category: subcategory)
|
|
|
|
get root_path
|
|
assert_response :ok
|
|
assert_select "[data-controller='sankey-chart']"
|
|
end
|
|
|
|
test "dashboard renders sankey chart zoom controls and stable node ids" do
|
|
parent_category = @family.categories.create!(name: "Shopping", color: "#FF5733")
|
|
subcategory = @family.categories.create!(name: "Groceries", parent: parent_category, color: "#33FF57")
|
|
|
|
create_transaction(account: @family.accounts.first, name: "General shopping", amount: 100, category: parent_category)
|
|
create_transaction(account: @family.accounts.first, name: "Grocery store", amount: 50, category: subcategory)
|
|
|
|
get root_path
|
|
|
|
assert_response :ok
|
|
assert_select "[data-sankey-chart-target='zoomOutButton'][hidden]", count: 2
|
|
|
|
chart = css_select("[data-controller='sankey-chart']").first
|
|
sankey_data = JSON.parse(chart["data-sankey-chart-data-value"])
|
|
|
|
assert_includes sankey_data.fetch("nodes").map { |node| node.fetch("id") }, "cash_flow_node"
|
|
assert sankey_data.fetch("nodes").any? { |node| node.fetch("id").start_with?("expense_") }
|
|
end
|
|
|
|
test "changelog" do
|
|
VCR.use_cassette("git_repository_provider/fetch_latest_release_notes") do
|
|
get changelog_path
|
|
assert_response :ok
|
|
end
|
|
end
|
|
|
|
test "changelog with nil release notes" do
|
|
# Mock the GitHub provider to return nil (simulating API failure or no releases)
|
|
github_provider = mock
|
|
github_provider.expects(:fetch_latest_release_notes).returns(nil)
|
|
Provider::Registry.stubs(:get_provider).with(:github).returns(github_provider)
|
|
|
|
get changelog_path
|
|
assert_response :ok
|
|
assert_select "h2", text: "Release notes unavailable"
|
|
assert_select "a[href='https://github.com/we-promise/sure/releases']"
|
|
end
|
|
|
|
test "changelog with incomplete release notes" do
|
|
# Mock the GitHub provider to return incomplete data (missing some fields)
|
|
github_provider = mock
|
|
incomplete_data = {
|
|
avatar: nil,
|
|
username: "maybe-finance",
|
|
name: "Test Release",
|
|
published_at: nil,
|
|
body: nil
|
|
}
|
|
github_provider.expects(:fetch_latest_release_notes).returns(incomplete_data)
|
|
Provider::Registry.stubs(:get_provider).with(:github).returns(github_provider)
|
|
|
|
get changelog_path
|
|
assert_response :ok
|
|
assert_select "h2", text: "Test Release"
|
|
# Should not crash even with nil values
|
|
end
|
|
end
|