Files
sure/test/controllers/goal_pledges_controller_test.rb
Guillem Arias 51fca464b5 fix(goals): reconciler logs to Sentry + rename :extend route to :renew
Two Ruby idiom audit fixes.

The Reconciler's outer `rescue StandardError` was logging at error
level and moving on. Pipeline-protective (we don't want a Goal
reconcile failure to break the Plaid/SimpleFIN/etc importer it's
hooked into) but invisible — real bugs hid behind a warn log
forever. Add `Sentry.capture_exception(e) if defined?(Sentry)`
alongside the log, matching the pattern in `Account::Syncer`,
`Sync`, `PlaidItem`, and the chart-series rescues this branch
already added. Keep the rescue's protective function.

`member do patch :extend end` shadows `Module#extend` — the
controller action name competes with Ruby's most-common
mixin entry point. `before_action :foo, only: %i[extend destroy]`
reads as "extend this controller with :foo, only: …" to a casual
reader, and stack traces against `def extend` look misleading.
Rename to `:renew` (matches the existing copy: the button says
"Extend 7 days," but the API verb is "renew the watching window"):

  - config/routes.rb: `patch :renew`
  - GoalPledgesController#extend → #renew
  - locale `goal_pledges.extend` → `goal_pledges.renew`
  - banner `extend_goal_pledge_path` → `renew_goal_pledge_path`
  - test refs updated

The user-facing button text is unchanged.
2026-05-14 21:50:01 +02:00

79 lines
2.5 KiB
Ruby

require "test_helper"
class GoalPledgesControllerTest < ActionDispatch::IntegrationTest
setup do
sign_in users(:family_admin)
@goal = goals(:vacation_italy)
@account = accounts(:depository)
@pledge = goal_pledges(:open_transfer)
ensure_tailwind_build
end
test "new renders the pledge form" do
get new_goal_pledge_url(@goal)
assert_response :success
end
test "create opens a pledge with default kind" do
assert_difference -> { GoalPledge.count } => 1 do
post goal_pledges_url(@goal), params: {
goal_pledge: {
amount: "150",
account_id: @account.id
}
}
end
pledge = GoalPledge.order(created_at: :desc).first
assert_equal "open", pledge.status
assert_equal @goal.id, pledge.goal_id
assert_redirected_to goal_path(@goal)
end
test "create rejects amount <= 0" do
assert_no_difference "GoalPledge.count" do
post goal_pledges_url(@goal), params: {
goal_pledge: { amount: "0", account_id: @account.id }
}
end
assert_response :unprocessable_entity
end
test "extend pushes expires_at forward" do
before = @pledge.expires_at
patch renew_goal_pledge_url(@goal, @pledge)
assert_redirected_to goal_path(@goal)
assert @pledge.reload.expires_at > before
end
test "extend on non-open pledge flashes alert" do
pledge = goal_pledges(:matched_transfer)
patch renew_goal_pledge_url(@goal, pledge)
assert_redirected_to goal_path(@goal)
assert flash[:alert].present?
end
test "destroy cancels an open pledge" do
delete goal_pledge_url(@goal, @pledge)
assert_redirected_to goal_path(@goal)
assert @pledge.reload.status_cancelled?
end
test "destroy on non-open pledge flashes alert" do
pledge = goal_pledges(:matched_transfer)
delete goal_pledge_url(@goal, pledge)
assert_redirected_to goal_path(@goal)
assert flash[:alert].present?
end
test "another family's goal returns redirect" do
other_family = Family.create!(name: "Other", currency: "USD", locale: "en", country: "US", timezone: "UTC")
other_account = Account.create!(family: other_family, accountable: Depository.new, name: "Foreign", currency: "USD", balance: 100)
other_goal = other_family.goals.new(name: "Foreign goal", target_amount: 100, currency: "USD")
other_goal.goal_accounts.build(account: other_account)
other_goal.save!
get new_goal_pledge_url(other_goal)
assert_redirected_to goals_path
end
end