1# frozen_string_literal: true
2
3require "pending_transaction_repo"
4
5class PendingTransactionRepo
6 def setup_mocks
7 @redis = Minitest::Mock.new
8 @electrum = Minitest::Mock.new
9 end
10end
11
12FakeElectrumTransaction = Struct.new(:tx_hash, :confirmations, :value) {
13 def amount_for(_addr)
14 value
15 end
16}
17
18class TestPendingTransactionRepo < Minitest::Test
19 def test_empty_map
20 repo = PendingTransactionRepo.new("key")
21 repo.setup_mocks
22 repo.redis.expect(
23 :hgetall,
24 [],
25 ["key"]
26 )
27 repo.map do |_pending, _customer_id|
28 flunk "Shouldn't yield when empty"
29 end
30
31 assert_mock repo.redis
32 assert_mock repo.electrum
33 end
34
35 def test_map
36 repo = PendingTransactionRepo.new("key")
37 repo.setup_mocks
38 repo.redis.expect(
39 :hgetall,
40 [["tx/addr", "1234"]],
41 ["key"]
42 )
43 repo.electrum.expect(
44 :gettransaction,
45 FakeElectrumTransaction.new("tx", 6, 0.5),
46 ["tx"]
47 )
48
49 v = repo.map { |pending, customer_id|
50 "#{pending.value} #{customer_id}"
51 }
52
53 assert_equal ["0.5 1234"], v, "Should have returned result of block"
54
55 assert_mock repo.redis
56 assert_mock repo.electrum
57 end
58
59 def test_error_handler
60 repo = PendingTransactionRepo.new("key")
61 repo.setup_mocks
62 repo.redis.expect(
63 :hgetall,
64 [["tx/addr", "1234"], ["missing/addr", "1234"]],
65 ["key"]
66 )
67 def repo.electrum
68 Class.new {
69 def gettransaction(txid)
70 if txid == "missing"
71 raise Electrum::NoTransaction, "Couldn't find"
72 end
73
74 FakeElectrumTransaction.new("tx", 6, 0.5)
75 end
76 }.new
77 end
78
79 repo.error_handler do |e|
80 case e
81 when Electrum::NoTransaction
82 true
83 end
84 end
85
86 v = repo.map { |pending, customer_id|
87 "#{pending.value} #{customer_id}"
88 }
89
90 assert_equal ["0.5 1234"], v, "Should have returned result of block"
91
92 assert_mock repo.redis
93 end
94
95 def test_other_errors
96 repo = PendingTransactionRepo.new("key")
97 repo.setup_mocks
98 repo.redis.expect(
99 :hgetall,
100 [["tx/addr", "1234"], ["error/addr", "1234"]],
101 ["key"]
102 )
103 def repo.electrum
104 Class.new {
105 def gettransaction(txid)
106 raise ArgumentError, "Oh no" if txid == "error"
107
108 FakeElectrumTransaction.new("tx", 6, 0.5)
109 end
110 }.new
111 end
112
113 repo.error_handler do |e|
114 case e
115 when Electrum::NoTransaction
116 true
117 end
118 end
119
120 assert_raises(ArgumentError) do
121 repo.map { |pending, customer_id|
122 "#{pending.value} #{customer_id}"
123 }
124 end
125
126 assert_mock repo.redis
127 end
128
129 def test_remove_transaction
130 repo = PendingTransactionRepo.new("key")
131 repo.setup_mocks
132
133 pending = PendingTransactionRepo::PendingTransaction.new(
134 FakeElectrumTransaction.new("tx", 6, 0.5),
135 "addr"
136 )
137
138 repo.redis.expect(:hdel, nil, ["key", "tx/addr"])
139
140 repo.remove_transaction(pending)
141
142 assert_mock repo.redis
143 assert_mock repo.electrum
144 end
145end