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 customer = Minitest::Mock.new(customer("123", balance: 100))
66 customer.expect(
67 :stanza_from,
68 EMPromise.resolve(nil),
69 [Blather::Stanza::Message]
70 )
71
72 SIMOrder::DB.expect(
73 :transaction,
74 EMPromise.resolve(@sim)
75 ) do |&blk|
76 blk.call
77 end
78
79 Transaction::DB.expect(
80 :exec,
81 nil,
82 [
83 String,
84 Matching.new { |params|
85 assert_equal "123", params[0]
86 assert_equal "tx123", params[1]
87 assert_kind_of Time, params[2]
88 assert_kind_of Time, params[3]
89 assert_in_delta(-(@price / 100).to_d, params[4], 0.05)
90 assert_equal "SIM Activation 123", params[5]
91 }
92 ]
93 )
94
95 @sim_repo.expect(:available, EMPromise.resolve(@sim), [])
96 @sim_repo.expect(:put_owner, nil, [@sim, customer, "SIM"])
97 @sim_repo.expect(
98 :refill,
99 EMPromise.resolve(OpenStruct.new(ack: "success", transaction_id: "tx123"))
100 ) do |refill_sim, amount_mb:|
101 @sim == refill_sim && amount_mb == 1024
102 end
103
104 order_form = Blather::Stanza::Iq::Command.new.tap { |iq|
105 iq.form.fields = [
106 { var: "addr", value: "123 Main St" },
107 { var: "nickname", value: nil }
108 ]
109 }
110
111 blather = Minitest::Mock.new
112 blather.expect(
113 :<<,
114 EMPromise.resolve(:test_result),
115 [Matching.new do |reply|
116 assert_equal :completed, reply.status
117 assert_equal :info, reply.note_type
118 assert_equal(
119 "You will receive an notice from support when your SIM ships.",
120 reply.note.content
121 )
122 end]
123 )
124 sim_order = SIMOrder.for(customer, price: @price, plan: @plan_name)
125 sim_order.instance_variable_set(:@sim_repo, @sim_repo)
126
127 assert_equal(
128 :test_result,
129 execute_command(blather: blather) { sim_order.complete(order_form) }
130 )
131
132 assert_mock Transaction::DB
133 assert_mock SIMOrder::DB
134 assert_mock customer
135 assert_mock @sim_repo
136 assert_mock blather
137 end
138 em :test_complete_nil_nick
139
140 def test_complete_nick_present
141 customer = Minitest::Mock.new(customer("123", balance: 100))
142 customer.expect(
143 :stanza_from,
144 EMPromise.resolve(nil),
145 [Blather::Stanza::Message]
146 )
147 Transaction::DB.expect(
148 :exec,
149 nil,
150 [
151 String,
152 Matching.new { |params|
153 assert_equal "123", params[0]
154 assert_equal "tx123", params[1]
155 assert_kind_of Time, params[2]
156 assert_kind_of Time, params[3]
157 assert_in_delta(-(@price / 100).to_d, params[4], 0.05)
158 assert_equal "SIM Activation 123", params[5]
159 }
160 ]
161 )
162
163 SIMOrder::DB.expect(
164 :transaction,
165 @sim
166 ) do |&blk|
167 blk.call
168 end
169
170 @sim_repo.expect(:available, EMPromise.resolve(@sim), [])
171 @sim_repo.expect(
172 :put_owner,
173 nil,
174 [@sim, customer, "test_nick"]
175 )
176 @sim_repo.expect(
177 :refill,
178 EMPromise.resolve(OpenStruct.new(ack: "success", transaction_id: "tx123"))
179 ) do |refill_sim, amount_mb:|
180 @sim == refill_sim && amount_mb == 1024
181 end
182
183 order_form = Blather::Stanza::Iq::Command.new.tap { |iq|
184 iq.form.fields = [
185 { var: "addr", value: "123 Main St" },
186 { var: "nickname", value: "test_nick" }
187 ]
188 }
189
190 blather = Minitest::Mock.new
191 blather.expect(
192 :<<,
193 EMPromise.resolve(:test_result),
194 [Matching.new do |reply|
195 assert_equal :completed, reply.status
196 assert_equal :info, reply.note_type
197 assert_equal(
198 "You will receive an notice from support when your SIM ships.",
199 reply.note.content
200 )
201 end]
202 )
203 sim_order = SIMOrder.for(customer, price: @price, plan: @plan_name)
204 sim_order.instance_variable_set(:@sim_repo, @sim_repo)
205
206 assert_equal(
207 :test_result,
208 execute_command(blather: blather) { sim_order.complete(order_form) }
209 )
210
211 assert_mock Transaction::DB
212 assert_mock SIMOrder::DB
213 assert_mock customer
214 assert_mock @sim_repo
215 assert_mock blather
216 end
217 em :test_complete_nick_present
218end