Back to Repositories

Testing Securities Trading Workflow in Maybe Finance

This test suite validates trading functionality in a financial application, focusing on buy and sell transactions for securities. It implements system-level testing with robust setup and verification of trade operations through the UI.

Test Coverage Overview

The test suite provides comprehensive coverage of trading operations, specifically buy and sell transactions for securities like AAPL. Key functionality includes:

  • Buy transaction workflow with quantity and price validation
  • Sell transaction processing with existing holdings
  • Trade confirmation and verification
  • UI interaction patterns for trade modal operations

Implementation Analysis

The testing approach utilizes Minitest’s system testing capabilities with ActiveJob integration. The implementation follows page object patterns with helper methods for common operations and leverages stubs for external security data. Key technical aspects include:

  • Modular test setup with user authentication
  • Stubbed security search functionality
  • DOM interaction helpers for combobox and modal operations
  • Isolated test scenarios for each transaction type

Technical Details

Testing infrastructure includes:

  • ApplicationSystemTestCase as the base test class
  • ActiveJob test helpers for background job handling
  • Fixture data for users and accounts
  • Custom DOM helpers for UI element interaction
  • Security stub implementation for consistent test data

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Isolated test setup with clear separation of concerns
  • Helper method extraction for common operations
  • Consistent assertion patterns for trade verification
  • Proper use of fixtures and stubs
  • Clear test naming and organization

maybe-finance/maybe

test/system/trades_test.rb

            
require "application_system_test_case"

class TradesTest < ApplicationSystemTestCase
  include ActiveJob::TestHelper

  setup do
    sign_in @user = users(:family_admin)

    @account = accounts(:investment)

    visit_account_portfolio

    Security.stubs(:search).returns([
      Security.new(
        ticker: "AAPL",
        name: "Apple Inc.",
        logo_url: "https://logo.synthfinance.com/ticker/AAPL",
        exchange_acronym: "NASDAQ",
        exchange_mic: "XNAS",
        country_code: "US"
      )
    ])
  end

  test "can create buy transaction" do
    shares_qty = 25

    open_new_trade_modal

    fill_in "Ticker symbol", with: "AAPL"
    select_combobox_option("Apple")
    fill_in "Date", with: Date.current
    fill_in "Quantity", with: shares_qty
    fill_in "account_entry[price]", with: 214.23

    click_button "Add transaction"

    visit_account_trades

    within_trades do
      assert_text "Purchase 10 shares of AAPL"
      assert_text "Buy #{shares_qty} shares of AAPL"
    end
  end

  test "can create sell transaction" do
    aapl = @account.holdings.find { |h| h.security.ticker == "AAPL" }

    open_new_trade_modal

    select "Sell", from: "Type"
    fill_in "Ticker symbol", with: aapl.ticker
    select_combobox_option(aapl.security.name)
    fill_in "Date", with: Date.current
    fill_in "Quantity", with: aapl.qty
    fill_in "account_entry[price]", with: 215.33

    click_button "Add transaction"

    visit_account_trades

    within_trades do
      assert_text "Sell #{aapl.qty.round} shares of AAPL"
    end
  end

  private

    def open_new_trade_modal
      click_on "New transaction"
    end

    def within_trades(&block)
      within "#" + dom_id(@account, "entries"), &block
    end

    def visit_account_trades
      visit account_path(@account, tab: "activity")
    end

    def visit_account_portfolio
      visit account_path(@account)
    end

    def select_combobox_option(text)
      within "#account_entry_ticker-hw-listbox" do
        find("li", text: text).click
      end
    end
end