Back to Repositories

Testing Upgrade Controller Workflows in Maybe Finance

This test suite validates the upgrade management functionality in the Maybe Finance application, focusing on version control and deployment workflows. It ensures proper handling of upgrade acknowledgments, deployments, and rollback scenarios through comprehensive integration tests.

Test Coverage Overview

The test suite provides thorough coverage of the UpgradesController functionality, including upgrade acknowledgment, deployment, and error handling.

Key areas tested include:
  • Upgrade availability validation
  • User acknowledgment of upgrade prompts and alerts
  • Deployment process verification
  • Rollback mechanism for failed upgrades
  • Environment-specific behavior with disabled upgrades

Implementation Analysis

The testing approach utilizes ActionDispatch::IntegrationTest for end-to-end validation of upgrade workflows. It employs stub methods to simulate different upgrade states and versions.

Notable patterns include:
  • Environment variable overrides for conditional testing
  • Mock objects for upgrade state management
  • User session handling with sign_in helper
  • Semantic versioning implementation

Technical Details

Testing tools and configuration:
  • Minitest framework with ActionDispatch integration
  • Mocha for method stubbing
  • Custom Upgrader::Upgrade class implementation
  • Environment variable management helpers
  • Semver version handling
  • User fixtures for authentication

Best Practices Demonstrated

The test suite exemplifies several testing best practices for Rails applications. It includes proper setup and teardown management, isolation of test cases, and comprehensive state verification.

Notable practices:
  • Explicit state verification after actions
  • Clean separation of concerns
  • Proper error case handling
  • Environment-aware testing
  • Consistent assertion patterns

maybe-finance/maybe

test/controllers/upgrades_controller_test.rb

            
require "test_helper"

class UpgradesControllerTest < ActionDispatch::IntegrationTest
  setup do
    sign_in @user = users(:family_admin)

    @completed_upgrade = Upgrader::Upgrade.new(
      "commit",
      commit_sha: "47bb430954292d2fdcc81082af731a16b9587da3",
      version: Semver.new("0.0.0"),
      url: ""
    )

    @completed_upgrade.stubs(:complete?).returns(true)
    @completed_upgrade.stubs(:available?).returns(false)

    @available_upgrade = Upgrader::Upgrade.new(
      "commit",
      commit_sha: "47bb430954292d2fdcc81082af731a16b9587da4",
      version: Semver.new("0.1.0"),
      url: ""
    )

    @available_upgrade.stubs(:available?).returns(true)
    @available_upgrade.stubs(:complete?).returns(false)
  end

  test "controller not available when upgrades are disabled" do
    MOCK_COMMIT = "47bb430954292d2fdcc81082af731a16b9587da3"

    post acknowledge_upgrade_url(MOCK_COMMIT)
    assert_response :not_found

    post deploy_upgrade_url(MOCK_COMMIT)
    assert_response :not_found
  end

  test "should acknowledge an upgrade prompt" do
    with_env_overrides UPGRADES_ENABLED: "true" do
      Upgrader.stubs(:find_upgrade).returns(@available_upgrade)

      post acknowledge_upgrade_url(@available_upgrade.commit_sha)

      @user.reload
      assert_equal @user.last_prompted_upgrade_commit_sha, @available_upgrade.commit_sha
      assert :redirect
    end
  end

  test "should acknowledge an upgrade alert" do
    with_env_overrides UPGRADES_ENABLED: "true" do
      Upgrader.stubs(:find_upgrade).returns(@completed_upgrade)

      post acknowledge_upgrade_url(@completed_upgrade.commit_sha)

      @user.reload
      assert_equal @user.last_alerted_upgrade_commit_sha, @completed_upgrade.commit_sha
      assert :redirect
    end
  end

  test "should deploy an upgrade" do
    with_env_overrides UPGRADES_ENABLED: "true" do
      Upgrader.stubs(:find_upgrade).returns(@available_upgrade)

      post deploy_upgrade_path(@available_upgrade.commit_sha)

      @user.reload
      assert_equal @user.last_prompted_upgrade_commit_sha, @available_upgrade.commit_sha
      assert :redirect
    end
  end

  test "should rollback user state if upgrade fails" do
    with_env_overrides UPGRADES_ENABLED: "true" do
      PRIOR_COMMIT = "47bb430954292d2fdcc81082af731a16b9587da2"
      @user.update!(last_prompted_upgrade_commit_sha: PRIOR_COMMIT)

      Upgrader.stubs(:find_upgrade).returns(@available_upgrade)
      Upgrader.stubs(:upgrade_to).returns({ success: false })

      post deploy_upgrade_path(@available_upgrade.commit_sha)

      @user.reload
      assert_equal @user.last_prompted_upgrade_commit_sha, PRIOR_COMMIT
      assert :redirect
    end
  end
end