1# frozen_string_literal: true
2
3require "test_helper"
4
5require "ostruct"
6
7require_relative "../lib/sim_order"
8
9class SIMOrderTest < Minitest::Test
10 SIMOrder::DB = Minitest::Mock.new
11 Transaction::DB = Minitest::Mock.new
12
13 def setup
14 @price = 5000
15 @plan_name = "better than no plan"
16 @sim_repo = Minitest::Mock.new
17 @sim = SIM.new(
18 iccid: "123",
19 nickname: nil,
20 lpa_code: "LPA:abc",
21 remaining_usage_kb: 1025,
22 remaining_days: 3,
23 notes: "no notes"
24 )
25 end
26
27 def test_for_enough_balance
28 assert_kind_of(
29 SIMOrder,
30 SIMOrder.for(customer(balance: 60), price: @price, plan: @plan_name)
31 )
32 end
33
34 def test_for_insufficient_balance_with_top_up
35 customer = customer(balance: 40)
36
37 LowBalance::AutoTopUp.stub(
38 :for,
39 OpenStruct.new(can_top_up?: true),
40 [customer, @price]
41 ) do
42 assert_kind_of(
43 SIMOrder::WithTopUp,
44 SIMOrder.for(customer, price: @price, plan: @plan_name)
45 )
46 end
47 end
48
49 def test_for_insufficient_balance_please_top_up
50 customer = customer(balance: 40)
51
52 LowBalance::AutoTopUp.stub(
53 :for,
54 OpenStruct.new(can_top_up?: false),
55 [customer, @price]
56 ) do
57 assert_kind_of(
58 SIMOrder::PleaseTopUp,
59 SIMOrder.for(customer, price: @price, plan: @plan_name)
60 )
61 end
62 end
63
64 def test_complete_nil_nick
65 execute_command {
66 customer = Minitest::Mock.new(customer("123", balance: 100))
67 customer.expect(
68 :stanza_from,
69 EMPromise.resolve(nil),
70 [Blather::Stanza::Message]
71 )
72
73 SIMOrder::DB.expect(
74 :transaction,
75 EMPromise.resolve(@sim)
76 ) do |&blk|
77 blk.call
78 end
79
80 Transaction::DB.expect(
81 :exec,
82 nil,
83 [
84 String,
85 Matching.new { |params|
86 assert_equal "123", params[0]
87 assert_equal "tx123", params[1]
88 assert_kind_of Time, params[2]
89 assert_kind_of Time, params[3]
90 assert_in_delta(-(@price / 100).to_d, params[4], 0.05)
91 assert_equal "SIM Activation 123", params[5]
92 }
93 ]
94 )
95
96 @sim_repo.expect(:available, EMPromise.resolve(@sim), [])
97 @sim_repo.expect(:put_owner, nil, [@sim, customer, "SIM"])
98 @sim_repo.expect(
99 :refill,
100 EMPromise.resolve(
101 OpenStruct.new(ack: "success", transaction_id: "tx123")
102 )
103 ) do |refill_sim, amount_mb:|
104 @sim == refill_sim && amount_mb == 1024
105 end
106
107 order_form = Blather::Stanza::Iq::Command.new.tap { |iq|
108 iq.form.fields = [
109 { var: "addr", value: "123 Main St" },
110 { var: "nickname", value: nil }
111 ]
112 }
113
114 Command::COMMAND_MANAGER.expect(
115 :write,
116 EMPromise.reject(:test_result),
117 [Matching.new do |reply|
118 assert_equal :executing, reply.status
119 assert_equal :info, reply.note_type
120 assert_equal(
121 "You will receive a notice from support when your SIM ships.",
122 reply.note.content
123 )
124 end]
125 )
126
127 sim_order = SIMOrder.for(customer, price: @price, plan: @plan_name)
128 sim_order.instance_variable_set(:@sim_repo, @sim_repo)
129
130 assert_equal(
131 :test_result,
132 sim_order.complete(order_form).catch { |e| e }.sync
133 )
134
135 assert_mock Transaction::DB
136 assert_mock SIMOrder::DB
137 assert_mock customer
138 assert_mock @sim_repo
139 }
140 end
141 em :test_complete_nil_nick
142
143 def test_complete_nick_present
144 execute_command {
145 Command::COMMAND_MANAGER.expect(
146 :write,
147 EMPromise.reject(:test_result),
148 [Matching.new do |reply|
149 assert_equal :info, reply.note_type
150 assert_equal :executing, reply.status
151 assert_equal(
152 "You will receive a notice from support when your SIM ships.",
153 reply.note.content
154 )
155 end]
156 )
157
158 customer = Minitest::Mock.new(customer("123", balance: 100))
159 customer.expect(
160 :stanza_from,
161 EMPromise.resolve(nil),
162 [Blather::Stanza::Message]
163 )
164 Transaction::DB.expect(
165 :exec,
166 nil,
167 [
168 String,
169 Matching.new { |params|
170 assert_equal "123", params[0]
171 assert_equal "tx123", params[1]
172 assert_kind_of Time, params[2]
173 assert_kind_of Time, params[3]
174 assert_in_delta(-(@price / 100).to_d, params[4], 0.05)
175 assert_equal "SIM Activation 123", params[5]
176 }
177 ]
178 )
179
180 SIMOrder::DB.expect(
181 :transaction,
182 @sim
183 ) do |&blk|
184 blk.call
185 end
186
187 @sim_repo.expect(:available, EMPromise.resolve(@sim), [])
188 @sim_repo.expect(
189 :put_owner,
190 nil,
191 [@sim, customer, "test_nick"]
192 )
193 @sim_repo.expect(
194 :refill,
195 EMPromise.resolve(
196 OpenStruct.new(ack: "success", transaction_id: "tx123")
197 )
198 ) do |refill_sim, amount_mb:|
199 @sim == refill_sim && amount_mb == 1024
200 end
201
202 order_form = Blather::Stanza::Iq::Command.new.tap { |iq|
203 iq.form.fields = [
204 { var: "addr", value: "123 Main St" },
205 { var: "nickname", value: "test_nick" }
206 ]
207 }
208
209 sim_order =
210 SIMOrder.for(customer, price: @price, plan: @plan_name)
211 sim_order.instance_variable_set(:@sim_repo, @sim_repo)
212
213 assert_equal(
214 :test_result,
215 sim_order.complete(order_form).catch { |e| e }.sync
216 )
217
218 assert_mock Transaction::DB
219 assert_mock SIMOrder::DB
220 assert_mock customer
221 assert_mock @sim_repo
222 }
223 end
224 em :test_complete_nick_present
225
226 def test_please_top_up_process_with_insufficient_balanace
227 customer = customer(balance: 0)
228
229 execute_command {
230 LowBalance::AutoTopUp.stub(
231 :for,
232 OpenStruct.new(can_top_up?: false),
233 [customer, @price]
234 ) do
235 order = SIMOrder.for(customer, price: @price, plan: @plan_name)
236
237 assert_kind_of(
238 SIMOrder::PleaseTopUp,
239 order
240 )
241
242 Command::COMMAND_MANAGER.expect(
243 :write,
244 EMPromise.reject(:test_result),
245 [Matching.new do |iq|
246 assert iq.allowed_actions.include?(:complete)
247 end]
248 )
249
250 order.process.catch { |e| e }.sync
251 end
252 }
253 end
254 em :test_please_top_up_process_with_insufficient_balanace
255end