test_porting_step.rb

  1# frozen_string_literal: true
  2
  3require "date"
  4require "ostruct"
  5require "test_helper"
  6
  7require "customer_info"
  8require "form_template"
  9require "form_to_h"
 10require "porting_step"
 11
 12MINS = 1.0 / (24 * 60)
 13
 14class BlatherNotifyMock < Minitest::Mock
 15	def initialize
 16		super
 17		@exes = []
 18	end
 19
 20	def expect_execution(server, node, *args)
 21		exe = Execution.new(args)
 22		expect(
 23			:command_execution,
 24			exe,
 25			[server, node]
 26		)
 27		@exes << exe
 28	end
 29
 30	def verify
 31		super
 32		@exes.each(&:verify)
 33	end
 34
 35	class Execution < Minitest::Mock
 36		def initialize(args)
 37			super()
 38			args.each_slice(2) do |(submission, result)|
 39				expect(
 40					:fetch_and_submit,
 41					EMPromise.resolve(to_response(result)),
 42					**submission
 43				)
 44			end
 45		end
 46
 47		using FormToH
 48
 49		def to_response(form)
 50			OpenStruct.new(form.to_h)
 51		end
 52	end
 53end
 54
 55def info(tel)
 56	CustomerInfo.new(
 57		plan_info: PlanInfo::NoPlan.new,
 58		tel: tel,
 59		balance: 0.to_d,
 60		cnam: nil
 61	)
 62end
 63
 64def admin_info(customer_id, tel)
 65	AdminInfo.new(
 66		jid: Blather::JID.new("#{customer_id}@example.com"),
 67		customer_id: customer_id,
 68		fwd: nil,
 69		info: info(tel),
 70		api: API::V2.new,
 71		call_info: "",
 72		trust_level: "",
 73		backend_jid: "customer_#{customer_id}@example.com"
 74	)
 75end
 76
 77def menu
 78	FormTemplate.render("admin_menu")
 79end
 80
 81class PortingStepTest < Minitest::Test
 82	Port = Struct.new(
 83		:order_id,
 84		:processing_status,
 85		:actual_foc_date,
 86		:last_modified_date,
 87		:customer_order_id,
 88		:billing_telephone_number
 89	)
 90
 91	def test_ignore_submitted_ports
 92		redis = Minitest::Mock.new
 93		redis.expect(:exists, EMPromise.resolve(0), ["jmp_port_freeze-01"])
 94
 95		step = PortingStepRepo.new(redis: redis).find(Port.new(
 96			"01",
 97			"SUBMITTED",
 98			nil,
 99			DateTime.now - 1 * MINS,
100			"ignored",
101			"9998887777"
102		)).sync
103
104		assert_kind_of PortingStepRepo::Wait, step
105	end
106	em :test_ignore_submitted_ports
107
108	def test_ignore_recent_foc
109		redis = Minitest::Mock.new
110		redis.expect(:exists, EMPromise.resolve(0), ["jmp_port_freeze-01"])
111
112		step = PortingStepRepo.new(redis: redis).find(Port.new(
113			"01",
114			"FOC",
115			DateTime.now - 5 * MINS,
116			DateTime.now - 1 * MINS,
117			"ignored",
118			"9998887777"
119		)).sync
120
121		assert_kind_of PortingStepRepo::Wait, step
122	end
123	em :test_ignore_recent_foc
124
125	def test_warn_for_late_foc
126		redis = Minitest::Mock.new
127		redis.expect(:exists, EMPromise.resolve(0), ["jmp_port_freeze-01"])
128
129		step = PortingStepRepo.new(redis: redis).find(Port.new(
130			"01",
131			"FOC",
132			DateTime.now - 25 * MINS,
133			DateTime.now - 1 * MINS,
134			"ignored",
135			"9998887777"
136		)).sync
137
138		assert_kind_of PortingStepRepo::Alert, step
139		assert_equal :late_foc, step.key
140		assert_kind_of PortingStepRepo::Wait, step.real_step
141	end
142	em :test_warn_for_late_foc
143
144	def test_already_complete
145		redis = Minitest::Mock.new
146		redis.expect(:exists, EMPromise.resolve(0), ["jmp_port_freeze-01"])
147		redis.expect(:exists, 1, ["jmp_port_complete-01"])
148
149		step = PortingStepRepo.new(redis: redis).find(Port.new(
150			"01",
151			"COMPLETE",
152			DateTime.now - 25 * MINS,
153			DateTime.now - 1 * MINS,
154			"completed",
155			"9998887777"
156		)).sync
157
158		assert_kind_of PortingStepRepo::Done, step
159		assert_mock redis
160	end
161	em :test_already_complete
162
163	def test_change_number
164		redis = Minitest::Mock.new
165		redis.expect(:exists, EMPromise.resolve(0), ["jmp_port_freeze-01"])
166		redis.expect(:exists, "0", ["jmp_port_complete-01"])
167
168		notify = BlatherNotifyMock.new
169		notify.expect_execution(
170			"sgx", "customer info",
171			{ q: "starting" }, admin_info("starting", "+19998881111").form
172		)
173
174		step = PortingStepRepo.new(
175			redis: redis,
176			blather_notify: notify,
177			admin_server: "sgx"
178		).find(Port.new(
179			"01",
180			"COMPLETE",
181			DateTime.now - 25 * MINS,
182			DateTime.now - 1 * MINS,
183			"starting",
184			"9998887777"
185		)).sync
186
187		assert_kind_of PortingStepRepo::Complete::AdminCommand::WrongNumber, step
188		assert_mock redis
189		assert_mock notify
190	end
191	em :test_change_number
192
193	def test_first_reachability
194		redis = Minitest::Mock.new
195		redis.expect(:exists, EMPromise.resolve(0), ["jmp_port_freeze-01"])
196		redis.expect(:exists, "0", ["jmp_port_complete-01"])
197
198		notify = BlatherNotifyMock.new
199		notify.expect_execution(
200			"sgx", "customer info",
201			{ q: "starting" }, admin_info("starting", "+19998887777").form
202		)
203
204		notify.expect_execution(
205			"sgx", "reachability",
206			{ tel: "9998887777", type: "voice" },
207			FormTemplate.render("reachability_result", count: 0)
208		)
209
210		step = PortingStepRepo.new(
211			redis: redis,
212			blather_notify: notify,
213			admin_server: "sgx"
214		).find(Port.new(
215			"01",
216			"COMPLETE",
217			DateTime.now - 25 * MINS,
218			DateTime.now - 1 * MINS,
219			"starting",
220			"9998887777"
221		)).sync
222
223		assert_kind_of(
224			PortingStepRepo::Complete::AdminCommand::GoodNumber::
225				Reachability::RunTest,
226			step
227		)
228		assert_equal "voice", step.type
229		assert_mock redis
230		assert_mock notify
231	end
232	em :test_first_reachability
233
234	def test_reach_sms_reachability
235		redis = Minitest::Mock.new
236		redis.expect(:exists, EMPromise.resolve(0), ["jmp_port_freeze-01"])
237		redis.expect(:exists, "0", ["jmp_port_complete-01"])
238
239		notify = BlatherNotifyMock.new
240		notify.expect_execution(
241			"sgx", "customer info",
242			{ q: "starting" }, admin_info("starting", "+19998887777").form
243		)
244
245		notify.expect_execution(
246			"sgx", "reachability",
247			{ tel: "9998887777", type: "voice" },
248			FormTemplate.render("reachability_result", count: 1)
249		)
250
251		notify.expect_execution(
252			"sgx", "reachability",
253			{ tel: "9998887777", type: "sms" },
254			FormTemplate.render("reachability_result", count: 0)
255		)
256
257		step = PortingStepRepo.new(
258			redis: redis,
259			blather_notify: notify,
260			admin_server: "sgx"
261		).find(Port.new(
262			"01",
263			"COMPLETE",
264			DateTime.now - 25 * MINS,
265			DateTime.now - 1 * MINS,
266			"starting",
267			"9998887777"
268		)).sync
269
270		assert_kind_of(
271			PortingStepRepo::Complete::AdminCommand::GoodNumber::
272				Reachability::RunTest,
273			step
274		)
275		assert_equal "sms", step.type
276		assert_mock redis
277		assert_mock notify
278	end
279	em :test_reach_sms_reachability
280
281	def test_all_reachable
282		redis = Minitest::Mock.new
283		redis.expect(:exists, EMPromise.resolve(0), ["jmp_port_freeze-01"])
284		redis.expect(:exists, "0", ["jmp_port_complete-01"])
285
286		notify = BlatherNotifyMock.new
287		notify.expect_execution(
288			"sgx", "customer info",
289			{ q: "starting" }, admin_info("starting", "+19998887777").form
290		)
291
292		notify.expect_execution(
293			"sgx", "reachability",
294			{ tel: "9998887777", type: "voice" },
295			FormTemplate.render("reachability_result", count: 1)
296		)
297
298		notify.expect_execution(
299			"sgx", "reachability",
300			{ tel: "9998887777", type: "sms" },
301			FormTemplate.render("reachability_result", count: 1)
302		)
303
304		step = PortingStepRepo.new(
305			redis: redis,
306			blather_notify: notify,
307			admin_server: "sgx"
308		).find(Port.new(
309			"01",
310			"COMPLETE",
311			DateTime.now - 25 * MINS,
312			DateTime.now - 1 * MINS,
313			"starting",
314			"9998887777"
315		)).sync
316
317		assert_kind_of(
318			PortingStepRepo::Complete::AdminCommand::GoodNumber::FinishUp,
319			step
320		)
321		assert_mock redis
322		assert_mock notify
323	end
324	em :test_all_reachable
325
326	def test_not_done_in_time
327		redis = Minitest::Mock.new
328		redis.expect(:exists, EMPromise.resolve(0), ["jmp_port_freeze-01"])
329		redis.expect(:exists, "0", ["jmp_port_complete-01"])
330
331		notify = BlatherNotifyMock.new
332		notify.expect_execution(
333			"sgx", "customer info",
334			{ q: "starting" }, admin_info("starting", "+19998887777").form
335		)
336
337		notify.expect_execution(
338			"sgx", "reachability",
339			{ tel: "9998887777", type: "voice" },
340			FormTemplate.render("reachability_result", count: 0)
341		)
342
343		step = PortingStepRepo.new(
344			redis: redis,
345			blather_notify: notify,
346			admin_server: "sgx"
347		).find(Port.new(
348			"01",
349			"COMPLETE",
350			DateTime.now - 55 * MINS,
351			DateTime.now - 50 * MINS,
352			"starting",
353			"9998887777"
354		)).sync
355
356		assert_kind_of PortingStepRepo::Alert, step
357		assert_equal :late_finish, step.key
358		assert_kind_of(
359			PortingStepRepo::Complete::AdminCommand::GoodNumber::
360				Reachability::RunTest,
361			step.real_step
362		)
363		assert_mock redis
364		assert_mock notify
365	end
366	em :test_not_done_in_time
367
368	def test_ignore_frozen_ports
369		# This tests that we ignore ports in various states
370		[
371			Port.new(
372				"01",
373				"SUBMITTED",
374				nil,
375				DateTime.now - 1 * MINS,
376				"ignored",
377				"9998887777"
378			),
379			Port.new(
380				"01",
381				"FOC",
382				DateTime.now - 300 * MINS,
383				DateTime.now - 300 * MINS,
384				"ignored",
385				"9998887777"
386			),
387			Port.new(
388				"01",
389				"COMPLETED",
390				DateTime.now - 10 * MINS,
391				DateTime.now - 10 * MINS,
392				"ignored",
393				"9998887777"
394			),
395			Port.new(
396				"01",
397				"COMPLETED",
398				DateTime.now - 300 * MINS,
399				DateTime.now - 300 * MINS,
400				"ignored",
401				"9998887777"
402			)
403		].each do |port|
404			redis = Minitest::Mock.new
405			redis.expect(:exists, EMPromise.resolve(1), ["jmp_port_freeze-01"])
406
407			step = PortingStepRepo.new(redis: redis).find(port).sync
408			assert_kind_of PortingStepRepo::Frozen, step
409		end
410	end
411	em :test_ignore_frozen_ports
412end