Files
sure/test/models/category_import_test.rb
Nelluk 8c528c1b24 Handle missing category import headers and accept name* (#487)
* Handle missing headers in category import

* Hoist category import header lookups
2025-12-22 20:41:37 +01:00

98 lines
3.2 KiB
Ruby

require "test_helper"
class CategoryImportTest < ActiveSupport::TestCase
setup do
@family = families(:dylan_family)
@csv = <<~CSV
name,color,parent_category,classification,icon
Food & Drink,#f97316,,expense,carrot
Groceries,#407706,Food & Drink,expense,shopping-basket
Salary,#22c55e,,income,briefcase
CSV
end
test "imports categories from Sure export" do
import = @family.imports.create!(type: "CategoryImport", raw_file_str: @csv, col_sep: ",")
import.generate_rows_from_csv
assert_equal 3, import.rows.count
tracked_categories = Category.where(family: @family, name: [ "Food & Drink", "Groceries", "Salary" ])
assert_difference -> { tracked_categories.count }, 2 do
import.send(:import!)
end
food = Category.find_by!(family: @family, name: "Food & Drink")
groceries = Category.find_by!(family: @family, name: "Groceries")
salary = Category.find_by!(family: @family, name: "Salary")
assert_equal "expense", food.classification
assert_equal "carrot", food.lucide_icon
assert_equal food, groceries.parent
assert_equal "shopping-basket", groceries.lucide_icon
assert_equal "income", salary.classification
assert_equal "briefcase", salary.lucide_icon
end
test "imports subcategories even when parent row comes later" do
csv = <<~CSV
name,color,parent_category,classification,icon
Utilities,#407706,Household,expense,plug
Household,#f97316,,expense,house
CSV
import = @family.imports.create!(type: "CategoryImport", raw_file_str: csv, col_sep: ",")
import.generate_rows_from_csv
import.send(:import!)
household = Category.find_by!(family: @family, name: "Household")
utilities = Category.find_by!(family: @family, name: "Utilities")
assert_equal household, utilities.parent
assert_equal "#f97316", household.color
end
test "updates categories when duplicate rows are provided" do
csv = <<~CSV
name,color,parent_category,classification,icon
Snacks,#aaaaaa,,expense,cookie
Snacks,#bbbbbb,,expense,pizza
CSV
import = @family.imports.create!(type: "CategoryImport", raw_file_str: csv, col_sep: ",")
import.generate_rows_from_csv
import.send(:import!)
snacks = Category.find_by!(family: @family, name: "Snacks")
assert_equal "#bbbbbb", snacks.color
assert_equal "pizza", snacks.lucide_icon
end
test "accepts required headers with an asterisk suffix" do
csv = <<~CSV
name*,color,parent_category,classification,icon
Food & Drink,#f97316,,expense,carrot
CSV
import = @family.imports.create!(type: "CategoryImport", raw_file_str: csv, col_sep: ",")
import.generate_rows_from_csv
assert_equal 1, import.rows.count
assert_equal "Food & Drink", import.rows.first.name
end
test "fails fast when required headers are missing" do
csv = <<~CSV
title,color,parent_category,classification,icon
Food & Drink,#f97316,,expense,carrot
CSV
import = @family.imports.create!(type: "CategoryImport", raw_file_str: csv, col_sep: ",")
error = assert_raises(ActiveRecord::RecordInvalid) { import.generate_rows_from_csv }
assert_includes error.message, "Missing required columns: name"
end
end