Add test coverage for category hierarchy and account search

Model-level:
- Category::GroupTest (new): for() grouping and the new select_options
  helper (order + indent labels).
- CategoryTest: alphabetically_by_hierarchy scope ordering.
- Rule::ConditionFilter::TransactionCategoryTest (new)
- Rule::ActionExecutor::SetTransactionCategoryTest (new)
- Import::CategoryMappingTest (new): grouping + 'Add as new category'
  still prepends correctly.

Controller/integration-level (asserting actual rendered HTML order):
- SplitsControllerTest: category combobox data-value ordering.
- Transactions::CategorizesControllerTest: bulk-categorize <select>
  option ordering.
- TransactionsControllerTest:
  - search filter checkbox ordering (q[categories][])
  - new-transaction DS::Select category ordering (via trigger id +
    ancestor traversal)
  - new-transaction account select renders a search box

All new/modified test files verified with 'ruby -c' (syntax) and
cross-checked fixture names, family scoping, route helpers, and field
names against the actual fixtures/routes/views. Ruby/Bundler network
access to rubygems.org is unavailable in this sandbox, so the suite
itself has not been executed — run 'bin/rails test' before merging.
This commit is contained in:
Claude
2026-07-29 11:09:54 +00:00
parent 7329af287d
commit ea0b5fbd29
8 changed files with 213 additions and 0 deletions

View File

@@ -17,6 +17,21 @@ class SplitsControllerTest < ActionDispatch::IntegrationTest
assert_response :success
end
test "new groups subcategories immediately after their parent in the category selector" do
get new_transaction_split_path(@entry)
assert_response :success
doc = Nokogiri::HTML::Document.parse(response.body)
category_values = doc.css(".category-select-container [data-value]").map { |node| node["data-value"] }
parent_index = category_values.index(categories(:food_and_drink).id)
child_index = category_values.index(categories(:subcategory).id)
assert_not_nil parent_index
assert_not_nil child_index
assert_equal parent_index + 1, child_index
end
test "create with valid params splits transaction" do
assert_difference "Entry.count", 2 do
post transaction_split_path(@entry), params: {

View File

@@ -26,6 +26,23 @@ class Transactions::CategorizesControllerTest < ActionDispatch::IntegrationTest
assert_response :success
end
test "show groups subcategories immediately after their parent in the category select" do
create_transaction(account: @account, name: "Starbucks")
get transactions_categorize_url
assert_response :success
doc = Nokogiri::HTML::Document.parse(response.body)
option_values = doc.css("select[name='category_id'] option").map { |node| node["value"] }
parent_index = option_values.index(categories(:food_and_drink).id)
child_index = option_values.index(categories(:subcategory).id)
assert_not_nil parent_index
assert_not_nil child_index
assert_equal parent_index + 1, child_index
end
test "show renders full dates so multi-year lists are unambiguous" do
create_transaction(account: @account, name: "Starbucks", date: Date.new(2024, 7, 8))

View File

@@ -8,6 +8,21 @@ class TransactionsControllerTest < ActionDispatch::IntegrationTest
@entry = entries(:transaction)
end
test "index groups subcategories immediately after their parent in the category filter" do
get transactions_url
assert_response :success
doc = Nokogiri::HTML::Document.parse(response.body)
checkbox_values = doc.css("input[name='q[categories][]']").map { |node| node["value"] }
parent_index = checkbox_values.index(categories(:food_and_drink).name)
child_index = checkbox_values.index(categories(:subcategory).name)
assert_not_nil parent_index
assert_not_nil child_index
assert_equal parent_index + 1, child_index
end
test "creates with transaction details" do
assert_difference [ "Entry.count", "Transaction.count" ], 1 do
post transactions_url, params: {
@@ -467,6 +482,37 @@ end
assert_not entry.protected_from_sync?
end
test "new groups subcategories immediately after their parent in the category select" do
get new_transaction_url
assert_response :success
doc = Nokogiri::HTML::Document.parse(response.body)
trigger = doc.at_css("#category_id_trigger")
assert_not_nil trigger, "expected the category select trigger button to render"
wrapper = trigger.ancestors(".relative").first
category_values = wrapper.css("[data-value]").map { |node| node["data-value"] }
parent_index = category_values.index(categories(:food_and_drink).id)
child_index = category_values.index(categories(:subcategory).id)
assert_not_nil parent_index
assert_not_nil child_index
assert_equal parent_index + 1, child_index
end
test "new renders a search box for account selection" do
get new_transaction_url
assert_response :success
doc = Nokogiri::HTML::Document.parse(response.body)
trigger = doc.at_css("#account_id_trigger")
assert_not_nil trigger, "expected the account select trigger button to render"
wrapper = trigger.ancestors(".relative").first
assert_not_nil wrapper.at_css("input[type='search']"), "expected a search input inside the account select"
end
test "new with duplicate_entry_id pre-fills form from source transaction" do
@entry.reload