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