mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-24 15:49:39 +02:00
Allow CSV file upload in import flow (#986)
* Add .tool-versions to gitignore * Add dropzone js for drag and drop file uploads * UI for csv file uploads for import * dropzone controller and use lucide_icon instead of svg * Preview for file chosen * File upload * Remove dropzone * Normalize I18n keys and fix lint issues * Add system tests * Cleanup * Remove unwanted
This commit is contained in:
parent
41f9e23f8c
commit
cdbca5aff3
13 changed files with 307 additions and 41 deletions
|
@ -65,6 +65,18 @@ class ImportsControllerTest < ActionDispatch::IntegrationTest
|
|||
assert_equal "Import CSV loaded", flash[:notice]
|
||||
end
|
||||
|
||||
test "should upload CSV file if valid" do
|
||||
Tempfile.open([ "transactions.csv", ".csv" ]) do |temp|
|
||||
CSV.open(temp, "wb", headers: true) do |csv|
|
||||
valid_csv_str.split("\n").each { |row| csv << row.split(",") }
|
||||
end
|
||||
|
||||
patch upload_import_url(@empty_import), params: { import: { raw_csv_str: Rack::Test::UploadedFile.new(temp, ".csv") } }
|
||||
assert_redirected_to configure_import_path(@empty_import)
|
||||
assert_equal "CSV File loaded", flash[:notice]
|
||||
end
|
||||
end
|
||||
|
||||
test "should flash error message if invalid CSV input" do
|
||||
patch load_import_url(@empty_import), params: { import: { raw_csv_str: malformed_csv_str } }
|
||||
|
||||
|
@ -72,6 +84,23 @@ class ImportsControllerTest < ActionDispatch::IntegrationTest
|
|||
assert_equal "Raw csv str is not a valid CSV format", flash[:error]
|
||||
end
|
||||
|
||||
test "should flash error message if invalid CSV file upload" do
|
||||
Tempfile.open([ "transactions.csv", ".csv" ]) do |temp|
|
||||
temp.write(malformed_csv_str)
|
||||
temp.rewind
|
||||
|
||||
patch upload_import_url(@empty_import), params: { import: { raw_csv_str: Rack::Test::UploadedFile.new(temp, ".csv") } }
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal "Raw csv str is not a valid CSV format", flash[:error]
|
||||
end
|
||||
end
|
||||
|
||||
test "should flash error message if no fileprovided for upload" do
|
||||
patch upload_import_url(@empty_import), params: { import: { raw_csv_str: nil } }
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal "Please select a file to upload", flash[:error]
|
||||
end
|
||||
|
||||
test "should get configure" do
|
||||
get configure_import_url(@loaded_import)
|
||||
assert_response :success
|
||||
|
|
3
test/fixtures/files/transactions.csv
vendored
Normal file
3
test/fixtures/files/transactions.csv
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
date,Custom Name Column,category,amount
|
||||
invalid_date,Starbucks drink,Food,-20.50
|
||||
2024-01-01,Amazon purchase,Shopping,-89.50
|
|
|
@ -1,6 +1,6 @@
|
|||
module ImportTestHelper
|
||||
def valid_csv_str
|
||||
<<-ROWS
|
||||
<<~ROWS
|
||||
date,name,category,tags,amount
|
||||
2024-01-01,Starbucks drink,Food & Drink,Tag1|Tag2,-8.55
|
||||
2024-01-01,Etsy,Shopping,Tag1,-80.98
|
||||
|
@ -10,14 +10,14 @@ module ImportTestHelper
|
|||
end
|
||||
|
||||
def valid_csv_with_invalid_values
|
||||
<<-ROWS
|
||||
<<~ROWS
|
||||
date,name,category,tags,amount
|
||||
invalid_date,Starbucks drink,Food,,invalid_amount
|
||||
ROWS
|
||||
end
|
||||
|
||||
def valid_csv_with_missing_data
|
||||
<<-ROWS
|
||||
<<~ROWS
|
||||
date,name,category,"optional id",amount
|
||||
2024-01-01,Drink,Food,1234,-200
|
||||
2024-01-02,,,,-100
|
||||
|
@ -25,7 +25,7 @@ module ImportTestHelper
|
|||
end
|
||||
|
||||
def malformed_csv_str
|
||||
<<-ROWS
|
||||
<<~ROWS
|
||||
name,age
|
||||
"John Doe,23
|
||||
"Jane Doe",25
|
||||
|
|
|
@ -51,6 +51,8 @@ class ImportsTest < ApplicationSystemTestCase
|
|||
|
||||
click_button "Next"
|
||||
|
||||
click_button "Copy & Paste"
|
||||
|
||||
# 2) Load Step
|
||||
assert_selector "h1", text: "Load import"
|
||||
|
||||
|
@ -94,6 +96,60 @@ class ImportsTest < ApplicationSystemTestCase
|
|||
assert_selector "h1", text: "Imports"
|
||||
end
|
||||
|
||||
test "can perform import by CSV upload" do
|
||||
trigger_import_from_settings
|
||||
verify_import_modal
|
||||
|
||||
within "#modal" do
|
||||
click_link "New import from CSV"
|
||||
end
|
||||
|
||||
# 1) Create import step
|
||||
assert_selector "h1", text: "New import"
|
||||
|
||||
within "form" do
|
||||
select "Checking Account", from: "import_account_id"
|
||||
end
|
||||
|
||||
click_button "Next"
|
||||
|
||||
click_button "Upload CSV"
|
||||
|
||||
find(".csv-drop-box").drop File.join(file_fixture_path, "transactions.csv")
|
||||
assert_selector "div.csv-preview", text: "transactions.csv"
|
||||
|
||||
click_button "Next"
|
||||
|
||||
# 3) Configure step
|
||||
assert_selector "h1", text: "Configure import"
|
||||
|
||||
within "form" do
|
||||
select "Custom Name Column", from: "import_column_mappings_name"
|
||||
end
|
||||
|
||||
click_button "Next"
|
||||
|
||||
# 4) Clean step
|
||||
assert_selector "h1", text: "Clean import"
|
||||
|
||||
# We have an invalid value, so user cannot click next yet
|
||||
assert_no_text "Next"
|
||||
|
||||
# Replace invalid date with valid date
|
||||
fill_in "cell-0-0", with: "2024-01-02"
|
||||
|
||||
# Trigger blur event so value saves
|
||||
find("body").click
|
||||
|
||||
click_link "Next"
|
||||
|
||||
# 5) Confirm step
|
||||
assert_selector "h1", text: "Confirm import"
|
||||
assert_selector "#new_account_entry", count: 2
|
||||
click_button "Import 2 transactions"
|
||||
assert_selector "h1", text: "Imports"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def trigger_import_from_settings
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue