simple_wallet 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/services/simple_wallet/account_crediting_service.rb +55 -0
- data/app/services/simple_wallet/account_debiting_service.rb +81 -0
- data/app/services/simple_wallet/service.rb +35 -0
- data/config/locales/simple_wallet.en.yml +4 -0
- data/lib/simple_wallet/version.rb +1 -1
- data/test/dummy/log/test.log +10726 -0
- data/test/services/account_crediting_service_test.rb +113 -0
- data/test/services/account_debiting_service_test.rb +158 -0
- data/test/test_helper.rb +1 -0
- metadata +10 -2
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
describe SimpleWallet::AccountCreditingService do
|
|
6
|
+
let(:account) { create(:simple_wallet_account) }
|
|
7
|
+
let(:amount) { 35 }
|
|
8
|
+
let(:note) { "My custom transaction note" }
|
|
9
|
+
|
|
10
|
+
let(:crediting) do
|
|
11
|
+
SimpleWallet::AccountCreditingService.new(
|
|
12
|
+
account: account,
|
|
13
|
+
amount: amount,
|
|
14
|
+
note: note,
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "Validation" do
|
|
19
|
+
describe "when account is blank" do
|
|
20
|
+
let(:account) { nil }
|
|
21
|
+
|
|
22
|
+
it "returns false and adds an error" do
|
|
23
|
+
refute crediting.credit
|
|
24
|
+
assert_includes crediting.errors[:account], "can't be blank"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "when amount is zero" do
|
|
29
|
+
let(:amount) { 0 }
|
|
30
|
+
|
|
31
|
+
it "returns false and adds an error" do
|
|
32
|
+
refute crediting.credit
|
|
33
|
+
assert_includes crediting.errors[:amount], "must be greater than 0"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe "when amount is negative" do
|
|
38
|
+
let(:amount) { -35 }
|
|
39
|
+
|
|
40
|
+
it "returns false and adds an error" do
|
|
41
|
+
refute crediting.credit
|
|
42
|
+
assert_includes crediting.errors[:amount], "must be greater than 0"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe "when note is blank along with source" do
|
|
47
|
+
let(:note) { "" }
|
|
48
|
+
|
|
49
|
+
it "returns false and adds an error" do
|
|
50
|
+
refute crediting.credit
|
|
51
|
+
assert_includes crediting.errors[:note], "can't be blank"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe "#credit" do
|
|
57
|
+
describe "when operation is valid" do
|
|
58
|
+
it "creates new Credit transaction for given account" do
|
|
59
|
+
assert_difference -> { account.transactions.count }, 1 do
|
|
60
|
+
assert crediting.credit
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
account.transactions.last.tap do |transaction|
|
|
64
|
+
assert_equal "SimpleWallet::Transaction::Credit", transaction.type
|
|
65
|
+
assert_nil transaction.source
|
|
66
|
+
assert_equal 35, transaction.amount
|
|
67
|
+
assert_equal 0, transaction.pre_account_balance
|
|
68
|
+
assert_equal "My custom transaction note", transaction.note
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "tells account to recalculate its balance" do
|
|
73
|
+
assert_equal 0, account.reload.balance
|
|
74
|
+
assert crediting.credit
|
|
75
|
+
assert_equal 35, account.reload.balance
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
describe "when operation is not valid" do
|
|
80
|
+
let(:note) { "" }
|
|
81
|
+
|
|
82
|
+
it "doesn't create new Credit transaction for given account" do
|
|
83
|
+
assert_no_difference(-> { account.transactions.count }) do
|
|
84
|
+
refute crediting.credit
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "doesn't change account's balance" do
|
|
89
|
+
assert_no_difference(-> { account.reload.balance }) do
|
|
90
|
+
refute crediting.credit
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe "when unexpected error happens" do
|
|
96
|
+
it "doesn't create new Credit transaction for given account" do
|
|
97
|
+
crediting.stub(:after_operation, ->(*args) { raise "Oops" }) do
|
|
98
|
+
assert_no_difference(-> { account.transactions.count }) do
|
|
99
|
+
assert_raises(RuntimeError) { crediting.credit }
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
it "doesn't change account's balance" do
|
|
105
|
+
crediting.stub(:after_operation, ->(*args) { raise "Oops" }) do
|
|
106
|
+
assert_no_changes(-> { account.reload.balance }) do
|
|
107
|
+
assert_raises(RuntimeError) { crediting.credit }
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "test_helper"
|
|
4
|
+
|
|
5
|
+
describe SimpleWallet::AccountDebitingService do
|
|
6
|
+
let(:account) { create(:simple_wallet_account) }
|
|
7
|
+
let(:amount) { 35 }
|
|
8
|
+
let(:note) { "My custom transaction note" }
|
|
9
|
+
|
|
10
|
+
let(:debiting) do
|
|
11
|
+
SimpleWallet::AccountDebitingService.new(
|
|
12
|
+
account: account,
|
|
13
|
+
amount: amount,
|
|
14
|
+
note: note,
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
before do
|
|
19
|
+
SimpleWallet::AccountCreditingService.new(
|
|
20
|
+
account: account,
|
|
21
|
+
amount: +100,
|
|
22
|
+
note: "Bonus!"
|
|
23
|
+
).credit
|
|
24
|
+
|
|
25
|
+
account&.reload
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "Validation" do
|
|
29
|
+
describe "when account is blank" do
|
|
30
|
+
let(:account) { nil }
|
|
31
|
+
|
|
32
|
+
it "returns false and adds an error" do
|
|
33
|
+
refute debiting.debit
|
|
34
|
+
assert_includes debiting.errors[:account], "can't be blank"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe "when account has no sufficient funds" do
|
|
39
|
+
let(:amount) { 500 }
|
|
40
|
+
|
|
41
|
+
it "returns false and adds an error" do
|
|
42
|
+
refute debiting.debit
|
|
43
|
+
assert_includes debiting.errors[:amount], "exceeds available balance"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe "when amount is zero" do
|
|
48
|
+
let(:amount) { 0 }
|
|
49
|
+
|
|
50
|
+
it "returns false and adds an error" do
|
|
51
|
+
refute debiting.debit
|
|
52
|
+
assert_includes debiting.errors[:amount], "must be greater than 0"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe "when amount is negative" do
|
|
57
|
+
let(:amount) { -35 }
|
|
58
|
+
|
|
59
|
+
it "returns false and adds an error" do
|
|
60
|
+
refute debiting.debit
|
|
61
|
+
assert_includes debiting.errors[:amount], "must be greater than 0"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe "when note is blank along with source" do
|
|
66
|
+
let(:note) { "" }
|
|
67
|
+
|
|
68
|
+
it "returns false and adds an error" do
|
|
69
|
+
refute debiting.debit
|
|
70
|
+
assert_includes debiting.errors[:note], "can't be blank"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
describe "#debit" do
|
|
76
|
+
describe "when operation is valid" do
|
|
77
|
+
it "creates new debit transaction for given account and source" do
|
|
78
|
+
assert_difference -> { account.transactions.count }, 1 do
|
|
79
|
+
assert debiting.debit
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
assert debiting.debit
|
|
83
|
+
account.transactions.last.tap do |transaction|
|
|
84
|
+
assert_equal "SimpleWallet::Transaction::Debit", transaction.type
|
|
85
|
+
assert_nil transaction.source
|
|
86
|
+
assert_equal -35, transaction.amount
|
|
87
|
+
assert_equal 100, transaction.pre_account_balance
|
|
88
|
+
assert_equal "My custom transaction note", transaction.note
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "tells account to recalculate its balance" do
|
|
93
|
+
assert_equal 100, account.reload.balance
|
|
94
|
+
assert debiting.debit
|
|
95
|
+
assert_equal 65, account.reload.balance
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
describe "when :up_to_account_balance option is set and we try to debit more than account's balance" do
|
|
99
|
+
let(:debiting) do
|
|
100
|
+
SimpleWallet::AccountDebitingService.new(
|
|
101
|
+
account: account,
|
|
102
|
+
amount: 250,
|
|
103
|
+
note: "Penalty for cheating!",
|
|
104
|
+
up_to_account_balance: true
|
|
105
|
+
)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
it "creates new debit transaction with amount up to SimpleWallet's balance" do
|
|
109
|
+
assert_difference -> { account.transactions.count }, 1 do
|
|
110
|
+
assert debiting.debit
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
account.transactions.last.tap do |transaction|
|
|
114
|
+
assert_equal "SimpleWallet::Transaction::Debit", transaction.type
|
|
115
|
+
assert_nil transaction.source
|
|
116
|
+
assert_equal -100, transaction.amount
|
|
117
|
+
assert_equal 100, transaction.pre_account_balance
|
|
118
|
+
assert_equal "Penalty for cheating!", transaction.note
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
describe "when operation is not valid" do
|
|
126
|
+
let(:amount) { 500 }
|
|
127
|
+
|
|
128
|
+
it "doesn't create new debit transaction for given account" do
|
|
129
|
+
assert_no_difference(-> { account.transactions.count }) do
|
|
130
|
+
refute debiting.debit
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "doesn't change account's balance" do
|
|
135
|
+
assert_no_difference(-> { account.reload.balance }) do
|
|
136
|
+
refute debiting.debit
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
describe "when unexpected error happens" do
|
|
142
|
+
it "doesn't create new debit transaction for given account" do
|
|
143
|
+
debiting.stub(:after_operation, ->(*args) { raise "Oops" }) do
|
|
144
|
+
assert_no_difference(-> { account.transactions.count }) do
|
|
145
|
+
assert_raises(RuntimeError) { debiting.debit }
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it "doesn't change account's balance" do
|
|
151
|
+
debiting.stub(:after_operation, ->(*args) { raise "Oops" }) do
|
|
152
|
+
assert_no_changes(-> { account.reload.balance }) do
|
|
153
|
+
assert_raises(RuntimeError) { debiting.debit }
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: simple_wallet
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Marcin Urbanski
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-04-
|
|
11
|
+
date: 2026-04-06 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -38,6 +38,10 @@ files:
|
|
|
38
38
|
- app/models/simple_wallet/transaction.rb
|
|
39
39
|
- app/models/simple_wallet/transaction/credit.rb
|
|
40
40
|
- app/models/simple_wallet/transaction/debit.rb
|
|
41
|
+
- app/services/simple_wallet/account_crediting_service.rb
|
|
42
|
+
- app/services/simple_wallet/account_debiting_service.rb
|
|
43
|
+
- app/services/simple_wallet/service.rb
|
|
44
|
+
- config/locales/simple_wallet.en.yml
|
|
41
45
|
- db/migrate/20260329170901_create_simple_wallet_account.rb
|
|
42
46
|
- db/migrate/20260329181402_create_simple_wallet_transactions.rb
|
|
43
47
|
- lib/simple_wallet.rb
|
|
@@ -90,6 +94,8 @@ files:
|
|
|
90
94
|
- test/models/account_test.rb
|
|
91
95
|
- test/models/transaction/credit_test.rb
|
|
92
96
|
- test/models/transaction/debit_test.rb
|
|
97
|
+
- test/services/account_crediting_service_test.rb
|
|
98
|
+
- test/services/account_debiting_service_test.rb
|
|
93
99
|
- test/test_helper.rb
|
|
94
100
|
homepage: https://github.com/murbanski/simple_wallet
|
|
95
101
|
licenses:
|
|
@@ -163,4 +169,6 @@ test_files:
|
|
|
163
169
|
- test/models/account_test.rb
|
|
164
170
|
- test/models/transaction/credit_test.rb
|
|
165
171
|
- test/models/transaction/debit_test.rb
|
|
172
|
+
- test/services/account_crediting_service_test.rb
|
|
173
|
+
- test/services/account_debiting_service_test.rb
|
|
166
174
|
- test/test_helper.rb
|