Back to Repositories

Testing CSV Import Workflows in Maybe Finance Application

This test suite validates the data import functionality in the Maybe Finance application, covering transaction, trade, account, and Mint import workflows. It ensures reliable data ingestion through various CSV formats while maintaining data integrity and proper user interaction flow.

Test Coverage Overview

The test suite provides comprehensive coverage of four critical import paths:
  • Transaction imports with field mapping and categorization
  • Investment trade imports with date formatting
  • Account imports with type assignment
  • Mint-specific CSV import integration
Each path validates the complete workflow from file upload through successful import confirmation.

Implementation Analysis

The testing approach utilizes Minitest’s system testing capabilities with ActiveJob integration for background processing validation. The implementation follows a user-centric flow, simulating actual user interactions through Capybara’s DSL for form submissions, dropdown selections, and navigation sequences.

Key patterns include staged import validation, asynchronous job handling, and consistent UI state verification.

Technical Details

Testing tools and configuration:
  • ApplicationSystemTestCase as the base test class
  • ActiveJob::TestHelper for background job testing
  • Fixture-based test data for various CSV formats
  • Capybara selectors for DOM interaction
  • User authentication setup via sign_in helper

Best Practices Demonstrated

The test suite exemplifies robust system testing practices through comprehensive workflow validation, proper setup and teardown management, and explicit waiting for asynchronous operations. It demonstrates effective use of fixtures for test data, clear test organization by import type, and thorough UI state verification at each step of the import process.

maybe-finance/maybe

test/system/imports_test.rb

            
require "application_system_test_case"

class ImportsTest < ApplicationSystemTestCase
  include ActiveJob::TestHelper

  setup do
    sign_in @user = users(:family_admin)
  end

  test "transaction import" do
    visit new_import_path

    click_on "Import transactions"

    fill_in "import[raw_file_str]", with: file_fixture("imports/transactions.csv").read

    find('input[type="submit"][value="Upload CSV"]').click

    select "Date", from: "Date*"
    select "YYYY-MM-DD", from: "Date format"
    select "Amount", from: "Amount"
    select "Account", from: "Account (optional)"
    select "Name", from: "Name (optional)"
    select "Category", from: "Category (optional)"
    select "Tags", from: "Tags (optional)"
    select "Notes", from: "Notes (optional)"

    click_on "Apply configuration"

    click_on "Next step"

    assert_selector "h1", text: "Assign your categories"
    click_on "Next"

    assert_selector "h1", text: "Assign your tags"
    click_on "Next"

    assert_selector "h1", text: "Assign your accounts"
    click_on "Next"

    click_on "Publish import"

    assert_text "Import in progress"

    perform_enqueued_jobs

    click_on "Check status"

    assert_text "Import successful"

    click_on "Back to dashboard"
  end

  test "trade import" do
    visit new_import_path

    click_on "Import investments"

    fill_in "import[raw_file_str]", with: file_fixture("imports/trades.csv").read

    find('input[type="submit"][value="Upload CSV"]').click

    select "YYYY-MM-DD", from: "Date format"

    click_on "Apply configuration"

    click_on "Next step"

    assert_selector "h1", text: "Assign your accounts"
    click_on "Next"

    click_on "Publish import"

    assert_text "Import in progress"

    perform_enqueued_jobs

    click_on "Check status"

    assert_text "Import successful"

    click_on "Back to dashboard"
  end

  test "account import" do
    visit new_import_path

    click_on "Import accounts"

    fill_in "import[raw_file_str]", with: file_fixture("imports/accounts.csv").read

    find('input[type="submit"][value="Upload CSV"]').click

    click_on "Apply configuration"

    click_on "Next step"

    assert_selector "h1", text: "Assign your account types"

    all("form").each do |form|
      within(form) do
        select = form.find("select")
        select "Depository", from: select["id"]
        sleep 0.5
      end
    end

    click_on "Next"

    click_on "Publish import"

    assert_text "Import in progress"

    perform_enqueued_jobs

    click_on "Check status"

    assert_text "Import successful"

    click_on "Back to dashboard"
  end

  test "mint import" do
    visit new_import_path

    click_on "Import from Mint"

    fill_in "import[raw_file_str]", with: file_fixture("imports/mint.csv").read

    find('input[type="submit"][value="Upload CSV"]').click

    click_on "Apply configuration"

    click_on "Next step"

    assert_selector "h1", text: "Assign your categories"
    click_on "Next"

    assert_selector "h1", text: "Assign your tags"
    click_on "Next"

    assert_selector "h1", text: "Assign your accounts"
    click_on "Next"

    click_on "Publish import"

    assert_text "Import in progress"

    perform_enqueued_jobs

    click_on "Check status"

    assert_text "Import successful"

    click_on "Back to dashboard"
  end
end