mirror of
https://github.com/we-promise/sure.git
synced 2026-04-07 22:34:47 +00:00
fix: locale-dependent category duplication bug (#956)
* fix: locale-dependent category duplication bug * fix: use family locale for investment contributions category to prevent duplicates and handle legacy data * Remove v* tag trigger from flutter-build to fix double-runs publish.yml already calls flutter-build via workflow_call on v* tags, so the direct push trigger was causing duplicate workflow runs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Refactor mobile release asset flow * fix: category uniqueness and workflow issues * fix: fix test issue * fix: solve test issue * fix: resolve legacy problem * fix: solve lint test issue * fix: revert unrelated changes --------- Co-authored-by: Juan José Mata <juanjo.mata@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -30,4 +30,14 @@ class CategoryTest < ActiveSupport::TestCase
|
||||
|
||||
assert_equal "Validation failed: Parent can't have more than 2 levels of subcategories", error.message
|
||||
end
|
||||
|
||||
test "all_investment_contributions_names returns all locale variants" do
|
||||
names = Category.all_investment_contributions_names
|
||||
|
||||
assert_includes names, "Investment Contributions" # English
|
||||
assert_includes names, "Contributions aux investissements" # French
|
||||
assert_includes names, "Investeringsbijdragen" # Dutch
|
||||
assert names.all? { |name| name.is_a?(String) }
|
||||
assert_equal names, names.uniq # No duplicates
|
||||
end
|
||||
end
|
||||
|
||||
@@ -36,6 +36,127 @@ class FamilyTest < ActiveSupport::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
test "investment_contributions_category uses family locale consistently" do
|
||||
family = families(:dylan_family)
|
||||
family.update!(locale: "fr")
|
||||
family.categories.where(name: [ "Investment Contributions", "Contributions aux investissements" ]).destroy_all
|
||||
|
||||
# Simulate different request locales (e.g., from Accept-Language header)
|
||||
# The category should always be created with the family's locale (French)
|
||||
category_from_english_request = I18n.with_locale(:en) do
|
||||
family.investment_contributions_category
|
||||
end
|
||||
|
||||
assert_equal "Contributions aux investissements", category_from_english_request.name
|
||||
|
||||
# Second request with different locale should find the same category
|
||||
assert_no_difference "Category.count" do
|
||||
category_from_dutch_request = I18n.with_locale(:nl) do
|
||||
family.investment_contributions_category
|
||||
end
|
||||
|
||||
assert_equal category_from_english_request.id, category_from_dutch_request.id
|
||||
assert_equal "Contributions aux investissements", category_from_dutch_request.name
|
||||
end
|
||||
end
|
||||
|
||||
test "investment_contributions_category prevents duplicate categories across locales" do
|
||||
family = families(:dylan_family)
|
||||
family.update!(locale: "en")
|
||||
family.categories.where(name: [ "Investment Contributions", "Contributions aux investissements" ]).destroy_all
|
||||
|
||||
# Create category under English family locale
|
||||
english_category = family.investment_contributions_category
|
||||
assert_equal "Investment Contributions", english_category.name
|
||||
|
||||
# Simulate a request with French locale (e.g., from browser Accept-Language)
|
||||
# Should still return the English category, not create a French one
|
||||
assert_no_difference "Category.count" do
|
||||
I18n.with_locale(:fr) do
|
||||
french_request_category = family.investment_contributions_category
|
||||
assert_equal english_category.id, french_request_category.id
|
||||
assert_equal "Investment Contributions", french_request_category.name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "investment_contributions_category reuses legacy category with wrong locale" do
|
||||
family = families(:dylan_family)
|
||||
family.update!(locale: "fr")
|
||||
family.categories.where(name: [ "Investment Contributions", "Contributions aux investissements" ]).destroy_all
|
||||
|
||||
# Simulate legacy: category was created with English name (old bug behavior)
|
||||
legacy_category = family.categories.create!(
|
||||
name: "Investment Contributions",
|
||||
color: "#0d9488",
|
||||
classification: "expense",
|
||||
lucide_icon: "trending-up"
|
||||
)
|
||||
|
||||
# Should find and reuse the legacy category, updating its name to French
|
||||
assert_no_difference "Category.count" do
|
||||
result = family.investment_contributions_category
|
||||
assert_equal legacy_category.id, result.id
|
||||
assert_equal "Contributions aux investissements", result.name
|
||||
end
|
||||
end
|
||||
|
||||
test "investment_contributions_category merges multiple locale variants" do
|
||||
family = families(:dylan_family)
|
||||
family.update!(locale: "en")
|
||||
family.categories.where(name: [ "Investment Contributions", "Contributions aux investissements" ]).destroy_all
|
||||
|
||||
# Simulate legacy: multiple categories created under different locales
|
||||
english_category = family.categories.create!(
|
||||
name: "Investment Contributions",
|
||||
color: "#0d9488",
|
||||
classification: "expense",
|
||||
lucide_icon: "trending-up"
|
||||
)
|
||||
|
||||
french_category = family.categories.create!(
|
||||
name: "Contributions aux investissements",
|
||||
color: "#0d9488",
|
||||
classification: "expense",
|
||||
lucide_icon: "trending-up"
|
||||
)
|
||||
|
||||
# Create transactions pointing to both categories
|
||||
account = family.accounts.first
|
||||
txn1 = Transaction.create!(category: english_category)
|
||||
Entry.create!(
|
||||
account: account,
|
||||
entryable: txn1,
|
||||
amount: 100,
|
||||
currency: "USD",
|
||||
date: Date.current,
|
||||
name: "Test 1"
|
||||
)
|
||||
|
||||
txn2 = Transaction.create!(category: french_category)
|
||||
Entry.create!(
|
||||
account: account,
|
||||
entryable: txn2,
|
||||
amount: 200,
|
||||
currency: "USD",
|
||||
date: Date.current,
|
||||
name: "Test 2"
|
||||
)
|
||||
|
||||
# Should merge both categories into one, keeping the oldest
|
||||
assert_difference "Category.count", -1 do
|
||||
result = family.investment_contributions_category
|
||||
assert_equal english_category.id, result.id
|
||||
assert_equal "Investment Contributions", result.name
|
||||
|
||||
# Both transactions should now point to the keeper
|
||||
assert_equal english_category.id, txn1.reload.category_id
|
||||
assert_equal english_category.id, txn2.reload.category_id
|
||||
|
||||
# French category should be deleted
|
||||
assert_nil Category.find_by(id: french_category.id)
|
||||
end
|
||||
end
|
||||
|
||||
test "moniker helpers return expected singular and plural labels" do
|
||||
family = families(:dylan_family)
|
||||
|
||||
Reference in New Issue
Block a user