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