mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-25 08:09:38 +02:00
Create tagging system (#792)
* Repro * Fix * Update signage * Create tagging system * Add tags to transaction imports * Build tagging UI * Cleanup * More cleanup
This commit is contained in:
parent
41c991384a
commit
457247da8e
38 changed files with 607 additions and 90 deletions
|
@ -6,7 +6,10 @@ class ImportsControllerTest < ActionDispatch::IntegrationTest
|
|||
setup do
|
||||
sign_in @user = users(:family_admin)
|
||||
@empty_import = imports(:empty_import)
|
||||
@loaded_import = imports(:loaded_import)
|
||||
|
||||
@loaded_import = @empty_import.dup
|
||||
@loaded_import.update! raw_csv_str: valid_csv_str
|
||||
|
||||
@completed_import = imports(:completed_import)
|
||||
end
|
||||
|
||||
|
|
36
test/controllers/tags/deletions_controller_test.rb
Normal file
36
test/controllers/tags/deletions_controller_test.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
require "test_helper"
|
||||
|
||||
class Tags::DeletionsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in @user = users(:family_admin)
|
||||
@user_tags = @user.family.tags
|
||||
@tag = tags(:hawaii_trip)
|
||||
end
|
||||
|
||||
test "should get new" do
|
||||
get new_tag_deletion_url(@tag)
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "create with replacement" do
|
||||
replacement_tag = tags(:trips)
|
||||
|
||||
affected_transaction_count = @tag.transactions.count
|
||||
|
||||
assert affected_transaction_count > 0
|
||||
|
||||
assert_difference -> { Tag.count } => -1, -> { replacement_tag.transactions.count } => affected_transaction_count do
|
||||
post tag_deletions_url(@tag), params: { replacement_tag_id: replacement_tag.id }
|
||||
end
|
||||
end
|
||||
|
||||
test "create without replacement" do
|
||||
affected_transactions = @tag.transactions
|
||||
|
||||
assert affected_transactions.count > 0
|
||||
|
||||
assert_difference -> { Tag.count } => -1, -> { Tagging.count } => affected_transactions.count * -1 do
|
||||
post tag_deletions_url(@tag)
|
||||
end
|
||||
end
|
||||
end
|
42
test/controllers/tags_controller_test.rb
Normal file
42
test/controllers/tags_controller_test.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
require "test_helper"
|
||||
|
||||
class TagsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in @user = users(:family_admin)
|
||||
end
|
||||
|
||||
test "should get index" do
|
||||
get tags_url
|
||||
assert_response :success
|
||||
|
||||
@user.family.tags.each do |tag|
|
||||
assert_select "#" + dom_id(tag), count: 1
|
||||
end
|
||||
end
|
||||
|
||||
test "should get new" do
|
||||
get new_tag_url
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "should create tag" do
|
||||
assert_difference("Tag.count") do
|
||||
post tags_url, params: { tag: { name: "Test Tag" } }
|
||||
end
|
||||
|
||||
assert_redirected_to tags_url
|
||||
assert_equal "Tag created", flash[:notice]
|
||||
end
|
||||
|
||||
test "should get edit" do
|
||||
get edit_tag_url(tags.first)
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "should update tag" do
|
||||
patch tag_url(tags.first), params: { tag: { name: "Test Tag" } }
|
||||
|
||||
assert_redirected_to tags_url
|
||||
assert_equal "Tag updated", flash[:notice]
|
||||
end
|
||||
end
|
24
test/fixtures/imports.yml
vendored
24
test/fixtures/imports.yml
vendored
|
@ -2,22 +2,6 @@ empty_import:
|
|||
account: checking
|
||||
created_at: <%= 1.minute.ago %>
|
||||
|
||||
loaded_import:
|
||||
account: checking
|
||||
raw_csv_str: |
|
||||
date,name,category,amount
|
||||
2024-01-01,Starbucks drink,Food & Drink,-8.55
|
||||
2024-01-01,Etsy,Shopping,-80.98
|
||||
2024-01-02,Amazon stuff,Shopping,-200
|
||||
2024-01-03,Paycheck,Income,1000
|
||||
normalized_csv_str: |
|
||||
date,name,category,amount
|
||||
2024-01-01,Starbucks drink,Food & Drink,-8.55
|
||||
2024-01-01,Etsy,Shopping,-80.98
|
||||
2024-01-02,Amazon stuff,Shopping,-200
|
||||
2024-01-03,Paycheck,Income,1000
|
||||
created_at: <%= 2.days.ago %>
|
||||
|
||||
completed_import:
|
||||
account: checking
|
||||
column_mappings:
|
||||
|
@ -26,11 +10,11 @@ completed_import:
|
|||
category: category
|
||||
amount: amount
|
||||
raw_csv_str: |
|
||||
date,name,category,amount
|
||||
2024-01-01,Starbucks drink,Food & Drink,-20
|
||||
date,name,category,tags,amount
|
||||
2024-01-01,Starbucks drink,Food & Drink,Test Tag,-20
|
||||
normalized_csv_str: |
|
||||
date,name,category,amount
|
||||
2024-01-01,Starbucks drink,Food & Drink,-20
|
||||
date,name,category,tags,amount
|
||||
2024-01-01,Starbucks drink,Food & Drink,Test Tag,-20
|
||||
created_at: <%= 2.days.ago %>
|
||||
|
||||
|
||||
|
|
10
test/fixtures/taggings.yml
vendored
Normal file
10
test/fixtures/taggings.yml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
one:
|
||||
tag: hawaii_trip
|
||||
taggable: checking_one
|
||||
taggable_type: Transaction
|
||||
|
||||
two:
|
||||
tag: emergency_fund
|
||||
taggable: checking_two
|
||||
taggable_type: Transaction
|
||||
|
11
test/fixtures/tags.yml
vendored
Normal file
11
test/fixtures/tags.yml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
trips:
|
||||
name: Trips
|
||||
family: dylan_family
|
||||
|
||||
hawaii_trip:
|
||||
name: Hawaii Trip
|
||||
family: dylan_family
|
||||
|
||||
emergency_fund:
|
||||
name: Emergency Fund
|
||||
family: dylan_family
|
|
@ -5,7 +5,9 @@ class ImportTest < ActiveSupport::TestCase
|
|||
|
||||
setup do
|
||||
@empty_import = imports(:empty_import)
|
||||
@loaded_import = imports(:loaded_import)
|
||||
|
||||
@loaded_import = @empty_import.dup
|
||||
@loaded_import.update! raw_csv_str: valid_csv_str
|
||||
end
|
||||
|
||||
test "raw csv input must conform to csv spec" do
|
||||
|
@ -42,7 +44,11 @@ class ImportTest < ActiveSupport::TestCase
|
|||
# Import has 3 unique categories: "Food & Drink", "Income", and "Shopping" (x2)
|
||||
# Fixtures already define "Food & Drink" and "Income", so these should not be created
|
||||
# "Shopping" is a new category, but should only be created 1x during import
|
||||
assert_difference -> { Transaction.count } => 4, -> { Transaction::Category.count } => 1 do
|
||||
assert_difference \
|
||||
-> { Transaction.count } => 4,
|
||||
-> { Transaction::Category.count } => 1,
|
||||
-> { Tagging.count } => 4,
|
||||
-> { Tag.count } => 2 do
|
||||
@loaded_import.publish
|
||||
end
|
||||
|
||||
|
|
18
test/models/tag_test.rb
Normal file
18
test/models/tag_test.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
require "test_helper"
|
||||
|
||||
class TagTest < ActiveSupport::TestCase
|
||||
test "replace and destroy" do
|
||||
old_tag = tags(:hawaii_trip)
|
||||
new_tag = tags(:trips)
|
||||
|
||||
assert_difference "Tag.count", -1 do
|
||||
old_tag.replace_and_destroy!(new_tag)
|
||||
end
|
||||
|
||||
old_tag.transactions.each do |txn|
|
||||
txn.reload
|
||||
assert_includes txn.tags, new_tag
|
||||
assert_not_includes txn.tags, old_tag
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,17 +1,18 @@
|
|||
module ImportTestHelper
|
||||
def valid_csv_str
|
||||
<<-ROWS
|
||||
date,name,category,amount
|
||||
2024-01-01,Starbucks drink,Food,-20
|
||||
2024-01-02,Amazon stuff,Shopping,-200
|
||||
2024-01-03,Paycheck,Income,1000
|
||||
date,name,category,tags,amount
|
||||
2024-01-01,Starbucks drink,Food & Drink,Tag1|Tag2,-8.55
|
||||
2024-01-01,Etsy,Shopping,Tag1,-80.98
|
||||
2024-01-02,Amazon stuff,Shopping,Tag2,-200
|
||||
2024-01-03,Paycheck,Income,,1000
|
||||
ROWS
|
||||
end
|
||||
|
||||
def valid_csv_with_invalid_values
|
||||
<<-ROWS
|
||||
date,name,category,amount
|
||||
invalid_date,Starbucks drink,Food,invalid_amount
|
||||
date,name,category,tags,amount
|
||||
invalid_date,Starbucks drink,Food,,invalid_amount
|
||||
ROWS
|
||||
end
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ class SettingsTest < ApplicationSystemTestCase
|
|||
[ "Security", "Security", settings_security_path ],
|
||||
[ "Billing", "Billing", settings_billing_path ],
|
||||
[ "Accounts", "Accounts", accounts_path ],
|
||||
[ "Tags", "Tags", tags_path ],
|
||||
[ "Categories", "Categories", transaction_categories_path ],
|
||||
[ "Merchants", "Merchants", transaction_merchants_path ],
|
||||
[ "Rules", "Rules", transaction_rules_path ],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue