mirror of
https://github.com/we-promise/sure.git
synced 2026-08-04 08:02:15 +00:00
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:
@@ -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: {
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
52
test/models/category/group_test.rb
Normal file
52
test/models/category/group_test.rb
Normal file
@@ -0,0 +1,52 @@
|
||||
require "test_helper"
|
||||
|
||||
class Category::GroupTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
@family = families(:dylan_family)
|
||||
end
|
||||
|
||||
test "for groups categories by parent, root categories without children get an empty subcategories array" do
|
||||
groups = Category::Group.for(@family.categories)
|
||||
|
||||
food_group = groups.find { |g| g.category == categories(:food_and_drink) }
|
||||
assert_equal [ categories(:subcategory) ], food_group.subcategories
|
||||
|
||||
income_group = groups.find { |g| g.category == categories(:income) }
|
||||
assert_equal [], income_group.subcategories
|
||||
end
|
||||
|
||||
test "for does not include a category as its own root when it is a subcategory" do
|
||||
groups = Category::Group.for(@family.categories)
|
||||
|
||||
assert_nil groups.find { |g| g.category == categories(:subcategory) }
|
||||
end
|
||||
|
||||
test "select_options orders parent immediately followed by its children" do
|
||||
options = Category::Group.select_options(@family.categories)
|
||||
|
||||
parent_index = options.index { |label, id| id == categories(:food_and_drink).id }
|
||||
child_index = options.index { |label, id| id == categories(:subcategory).id }
|
||||
|
||||
assert_not_nil parent_index
|
||||
assert_not_nil child_index
|
||||
assert_equal parent_index + 1, child_index, "subcategory should immediately follow its parent in the options list"
|
||||
end
|
||||
|
||||
test "select_options indents subcategory labels so they're visually distinguishable from parents" do
|
||||
options = Category::Group.select_options(@family.categories)
|
||||
|
||||
parent_label, = options.find { |label, id| id == categories(:food_and_drink).id }
|
||||
child_label, = options.find { |label, id| id == categories(:subcategory).id }
|
||||
|
||||
assert_equal categories(:food_and_drink).name, parent_label
|
||||
assert_not_equal categories(:subcategory).name, child_label
|
||||
assert_includes child_label, categories(:subcategory).name
|
||||
end
|
||||
|
||||
test "select_options returns [label, id] pairs usable directly by options_for_select / form.select" do
|
||||
options = Category::Group.select_options(@family.categories)
|
||||
|
||||
assert options.all? { |pair| pair.is_a?(Array) && pair.size == 2 }
|
||||
assert options.all? { |_label, id| id.present? }
|
||||
end
|
||||
end
|
||||
@@ -159,4 +159,15 @@ class CategoryTest < ActiveSupport::TestCase
|
||||
assert lookup.key?(category.id)
|
||||
assert_not lookup.key?(0)
|
||||
end
|
||||
|
||||
test "alphabetically_by_hierarchy orders a category's subcategories immediately after it" do
|
||||
ordered = @family.categories.alphabetically_by_hierarchy.to_a
|
||||
|
||||
parent_index = ordered.index(categories(:food_and_drink))
|
||||
child_index = ordered.index(categories(:subcategory))
|
||||
|
||||
assert_not_nil parent_index
|
||||
assert_not_nil child_index
|
||||
assert_equal parent_index + 1, child_index
|
||||
end
|
||||
end
|
||||
|
||||
25
test/models/import/category_mapping_test.rb
Normal file
25
test/models/import/category_mapping_test.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
require "test_helper"
|
||||
|
||||
class Import::CategoryMappingTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
@mapping = import_mappings(:one)
|
||||
end
|
||||
|
||||
test "selectable_values groups subcategories immediately after their parent" do
|
||||
options = @mapping.selectable_values
|
||||
|
||||
parent_index = options.index { |_label, id| id == categories(:food_and_drink).id }
|
||||
child_index = options.index { |_label, id| id == categories(:subcategory).id }
|
||||
|
||||
assert_not_nil parent_index
|
||||
assert_not_nil child_index
|
||||
assert_equal parent_index + 1, child_index
|
||||
end
|
||||
|
||||
test "selectable_values still prepends 'Add as new category' when key is present" do
|
||||
options = @mapping.selectable_values
|
||||
|
||||
assert_equal "Add as new category", options.first.first
|
||||
assert_equal Import::Mapping::CREATE_NEW_KEY, options.first.last
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,19 @@
|
||||
require "test_helper"
|
||||
|
||||
class Rule::ActionExecutor::SetTransactionCategoryTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
@rule = rules(:one)
|
||||
@executor = Rule::ActionExecutor::SetTransactionCategory.new(@rule)
|
||||
end
|
||||
|
||||
test "options groups subcategories immediately after their parent" do
|
||||
options = @executor.options
|
||||
|
||||
parent_index = options.index { |_label, id| id == categories(:food_and_drink).id }
|
||||
child_index = options.index { |_label, id| id == categories(:subcategory).id }
|
||||
|
||||
assert_not_nil parent_index
|
||||
assert_not_nil child_index
|
||||
assert_equal parent_index + 1, child_index
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,28 @@
|
||||
require "test_helper"
|
||||
|
||||
class Rule::ConditionFilter::TransactionCategoryTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
@rule = rules(:one)
|
||||
@filter = Rule::ConditionFilter::TransactionCategory.new(@rule)
|
||||
end
|
||||
|
||||
test "options groups subcategories immediately after their parent" do
|
||||
options = @filter.options
|
||||
|
||||
parent_index = options.index { |_label, id| id == categories(:food_and_drink).id }
|
||||
child_index = options.index { |_label, id| id == categories(:subcategory).id }
|
||||
|
||||
assert_not_nil parent_index
|
||||
assert_not_nil child_index
|
||||
assert_equal parent_index + 1, child_index
|
||||
end
|
||||
|
||||
test "options indents subcategory labels" do
|
||||
options = @filter.options
|
||||
|
||||
child_label, = options.find { |_label, id| id == categories(:subcategory).id }
|
||||
|
||||
assert_not_equal categories(:subcategory).name, child_label
|
||||
assert_includes child_label, categories(:subcategory).name
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user