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