test_sim_order.rb

  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