1# frozen_string_literal: true
2
3require "test_helper"
4require "customer"
5require "registration"
6
7BandwidthTnReservationRepo::REDIS = FakeRedis.new
8
9class RegistrationTest < Minitest::Test
10 def test_for_registered
11 sgx = OpenStruct.new(
12 registered?: OpenStruct.new(phone: "+15555550000")
13 )
14 iq = Blather::Stanza::Iq::Command.new
15 iq.from = "test@example.com"
16 result = execute_command(iq) do
17 Registration.for(
18 customer(sgx: sgx),
19 nil,
20 Minitest::Mock.new
21 )
22 end
23 assert_kind_of Registration::Registered, result
24 end
25 em :test_for_registered
26
27 def test_for_activated
28 reservation_req = stub_request(
29 :post,
30 "https://dashboard.bandwidth.com/v1.0/accounts//tnreservation"
31 )
32 web_manager = TelSelections.new(redis: FakeRedis.new)
33 web_manager.set("test@example.net", "+15555550000")
34 result = execute_command do
35 sgx = OpenStruct.new(registered?: false)
36 Registration.for(
37 customer(
38 plan_name: "test_usd",
39 expires_at: Time.now + 999,
40 sgx: sgx
41 ),
42 nil,
43 web_manager
44 )
45 end
46 assert_kind_of Registration::Finish, result
47 assert_requested reservation_req
48 end
49 em :test_for_activated
50
51 def test_for_not_activated_approved
52 sgx = OpenStruct.new(registered?: false)
53 web_manager = TelSelections.new(redis: FakeRedis.new)
54 web_manager.set("test\\40approved.example.com@component", "+15555550000")
55 iq = Blather::Stanza::Iq::Command.new
56 iq.from = "test@approved.example.com"
57 result = execute_command(iq) do
58 Registration::Activation.for(
59 customer(
60 sgx: sgx,
61 jid: Blather::JID.new("test\\40approved.example.com@component")
62 ),
63 nil,
64 web_manager
65 )
66 end
67 assert_kind_of Registration::Activation::Allow, result
68 end
69 em :test_for_not_activated_approved
70
71 def test_for_not_activated_googleplay
72 sgx = OpenStruct.new(registered?: false)
73 web_manager = TelSelections.new(redis: FakeRedis.new)
74 web_manager.set("test@example.net", "+15555550000")
75 iq = Blather::Stanza::Iq::Command.new
76 iq.from = "test@approved.example.com"
77 result = execute_command(iq) do
78 Registration::Activation.for(
79 customer(sgx: sgx),
80 "GARBLEDYGOOK==",
81 web_manager
82 )
83 end
84 assert_kind_of Registration::Activation::GooglePlay, result
85 end
86 em :test_for_not_activated_googleplay
87
88 def test_for_not_activated_with_customer_id
89 sgx = OpenStruct.new(registered?: false)
90 web_manager = TelSelections.new(redis: FakeRedis.new)
91 web_manager.set("test@example.net", "+15555550000")
92 iq = Blather::Stanza::Iq::Command.new
93 iq.from = "test@example.com"
94 result = execute_command(iq) do
95 Registration::Activation.for(
96 customer(sgx: sgx),
97 nil,
98 web_manager
99 )
100 end
101 assert_kind_of Registration::Activation, result
102 end
103 em :test_for_not_activated_with_customer_id
104
105 class ActivationTest < Minitest::Test
106 Registration::Activation::DB = Minitest::Mock.new
107 Registration::Activation::REDIS = FakeRedis.new
108 Registration::Activation::Payment = Minitest::Mock.new
109 Registration::Activation::Finish = Minitest::Mock.new
110 Command::COMMAND_MANAGER = Minitest::Mock.new
111
112 def setup
113 @customer = Minitest::Mock.new(customer)
114 @activation = Registration::Activation.new(@customer, "+15555550000")
115 end
116
117 def test_write
118 Command::COMMAND_MANAGER.expect(
119 :write,
120 EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
121 iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
122 }),
123 [Matching.new do |iq|
124 assert_equal :form, iq.form.type
125 assert_equal(
126 "You've selected +15555550000 as your JMP number.",
127 iq.form.instructions.lines.first.chomp
128 )
129 end]
130 )
131 @customer.expect(:with_plan, @customer, ["test_usd"])
132 @customer.expect(:save_plan!, EMPromise.resolve(nil), [])
133 Registration::Activation::Payment.expect(
134 :for,
135 EMPromise.reject(:test_result),
136 [Blather::Stanza::Iq, @customer, "+15555550000"]
137 )
138 assert_equal(
139 :test_result,
140 execute_command { @activation.write.catch { |e| e } }
141 )
142 assert_mock Command::COMMAND_MANAGER
143 assert_mock @customer
144 assert_mock Registration::Activation::Payment
145 end
146 em :test_write
147
148 def test_write_with_code
149 Command::COMMAND_MANAGER.expect(
150 :write,
151 EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
152 iq.form.fields = [
153 { var: "plan_name", value: "test_usd" },
154 { var: "code", value: "123" }
155 ]
156 }),
157 [Matching.new do |iq|
158 assert_equal :form, iq.form.type
159 assert_equal(
160 "You've selected +15555550000 as your JMP number.",
161 iq.form.instructions.lines.first.chomp
162 )
163 end]
164 )
165 @customer.expect(:with_plan, @customer, ["test_usd"])
166 @customer.expect(:save_plan!, EMPromise.resolve(nil), [])
167 @customer.expect(:activate_plan_starting_now, EMPromise.resolve(nil), [])
168 Registration::Activation::DB.expect(:transaction, []) { |&blk| blk.call }
169 Registration::Activation::DB.expect(
170 :exec,
171 OpenStruct.new(cmd_tuples: 1),
172 [String, ["test", "123"]]
173 )
174 Registration::Activation::Finish.expect(
175 :new,
176 OpenStruct.new(write: EMPromise.reject(:test_result)),
177 [@customer, "+15555550000"]
178 )
179 assert_equal(
180 :test_result,
181 execute_command { @activation.write.catch { |e| e } }
182 )
183 assert_mock Command::COMMAND_MANAGER
184 assert_mock @customer
185 assert_mock Registration::Activation::Payment
186 assert_mock Registration::Activation::DB
187 end
188 em :test_write_with_code
189
190 def test_write_with_group_code
191 Command::COMMAND_MANAGER.expect(
192 :write,
193 EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
194 iq.form.fields = [
195 { var: "plan_name", value: "test_usd" },
196 { var: "code", value: "123" }
197 ]
198 }),
199 [Matching.new do |iq|
200 assert_equal :form, iq.form.type
201 assert_equal(
202 "You've selected +15555550000 as your JMP number.",
203 iq.form.instructions.lines.first.chomp
204 )
205 end]
206 )
207 @customer.expect(:with_plan, @customer, ["test_usd"])
208 @customer.expect(:save_plan!, EMPromise.resolve(nil), [])
209 Registration::Activation::DB.expect(:transaction, []) { |&blk| blk.call }
210 Registration::Activation::DB.expect(
211 :exec,
212 OpenStruct.new(cmd_tuples: 0),
213 [String, ["test", "123"]]
214 )
215 Registration::Activation::Payment.expect(
216 :for,
217 EMPromise.reject(:test_result),
218 [Blather::Stanza::Iq, @customer, "+15555550000"]
219 )
220 assert_equal(
221 :test_result,
222 execute_command { @activation.write.catch { |e| e } }
223 )
224 assert_equal(
225 "123",
226 Registration::Activation::REDIS.get(
227 "jmp_customer_pending_invite-test"
228 ).sync
229 )
230 assert_mock Command::COMMAND_MANAGER
231 assert_mock @customer
232 assert_mock Registration::Activation::Payment
233 assert_mock Registration::Activation::DB
234 end
235 em :test_write_with_group_code
236 end
237
238 class AllowTest < Minitest::Test
239 Command::COMMAND_MANAGER = Minitest::Mock.new
240 Registration::Activation::Allow::DB = Minitest::Mock.new
241
242 def test_write_credit_to_nil
243 cust = Minitest::Mock.new(customer("test"))
244 allow = Registration::Activation::Allow.new(cust, "+15555550000", nil)
245
246 Command::COMMAND_MANAGER.expect(
247 :write,
248 EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
249 iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
250 }),
251 [Matching.new do |iq|
252 assert_equal :form, iq.form.type
253 assert_equal(
254 "You've selected +15555550000 as your JMP number.",
255 iq.form.instructions.lines.first.chomp
256 )
257 assert_equal 1, iq.form.fields.length
258 end]
259 )
260 Registration::Activation::Allow::DB.expect(
261 :transaction,
262 EMPromise.reject(:test_result)
263 ) do |&blk|
264 blk.call
265 true
266 end
267 cust.expect(:with_plan, cust, ["test_usd"])
268 cust.expect(:activate_plan_starting_now, nil)
269 assert_equal(
270 :test_result,
271 execute_command { allow.write.catch { |e| e } }
272 )
273 assert_mock Command::COMMAND_MANAGER
274 end
275 em :test_write_credit_to_nil
276
277 def test_write_credit_to_refercust
278 cust = Minitest::Mock.new(customer("test"))
279 allow = Registration::Activation::Allow.new(
280 cust, "+15555550000", "refercust"
281 )
282
283 Command::COMMAND_MANAGER.expect(
284 :write,
285 EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
286 iq.form.fields = [{ var: "plan_name", value: "test_usd" }]
287 }),
288 [Matching.new do |iq|
289 assert_equal :form, iq.form.type
290 assert_equal(
291 "You've selected +15555550000 as your JMP number.",
292 iq.form.instructions.lines.first.chomp
293 )
294 assert_equal 1, iq.form.fields.length
295 end]
296 )
297 Registration::Activation::Allow::DB.expect(
298 :transaction,
299 EMPromise.reject(:test_result)
300 ) do |&blk|
301 blk.call
302 true
303 end
304 Registration::Activation::Allow::DB.expect(
305 :exec,
306 nil,
307 [String, ["refercust", "test"]]
308 )
309 cust.expect(:with_plan, cust, ["test_usd"])
310 cust.expect(:activate_plan_starting_now, nil)
311 assert_equal(
312 :test_result,
313 execute_command { allow.write.catch { |e| e } }
314 )
315 assert_mock Command::COMMAND_MANAGER
316 end
317 em :test_write_credit_to_refercust
318 end
319
320 class PaymentTest < Minitest::Test
321 CustomerFinancials::BRAINTREE = Minitest::Mock.new
322
323 def test_for_bitcoin
324 iq = Blather::Stanza::Iq::Command.new
325 iq.form.fields = [
326 { var: "activation_method", value: "bitcoin" },
327 { var: "plan_name", value: "test_usd" }
328 ]
329 result = Registration::Payment.for(iq, customer, "+15555550000")
330 assert_kind_of Registration::Payment::Bitcoin, result
331 end
332
333 def test_for_credit_card
334 braintree_customer = Minitest::Mock.new
335 CustomerFinancials::BRAINTREE.expect(
336 :customer,
337 braintree_customer
338 )
339 CustomerFinancials::REDIS.expect(:smembers, [], ["block_credit_cards"])
340 braintree_customer.expect(
341 :find,
342 EMPromise.resolve(OpenStruct.new(payment_methods: [])),
343 ["test"]
344 )
345 iq = Blather::Stanza::Iq::Command.new
346 iq.from = "test@example.com"
347 iq.form.fields = [
348 { var: "activation_method", value: "credit_card" },
349 { var: "plan_name", value: "test_usd" }
350 ]
351 cust = customer
352 result = execute_command do
353 Command.execution.customer_repo.expect(:find, cust, ["test"])
354 Registration::Payment.for(
355 iq,
356 cust,
357 ""
358 ).sync
359 end
360 assert_kind_of Registration::Payment::CreditCard, result
361 end
362 em :test_for_credit_card
363
364 def test_for_code
365 iq = Blather::Stanza::Iq::Command.new
366 iq.form.fields = [
367 { var: "activation_method", value: "code" },
368 { var: "plan_name", value: "test_usd" }
369 ]
370 result = Registration::Payment.for(
371 iq,
372 customer,
373 "+15555550000"
374 )
375 assert_kind_of Registration::Payment::InviteCode, result
376 end
377
378 class BitcoinTest < Minitest::Test
379 Registration::Payment::Bitcoin::BTC_SELL_PRICES = Minitest::Mock.new
380 CustomerFinancials::REDIS = Minitest::Mock.new
381
382 def setup
383 @customer = Minitest::Mock.new(
384 customer(plan_name: "test_usd")
385 )
386 @customer.expect(
387 :add_btc_address,
388 EMPromise.resolve("testaddr")
389 )
390 @bitcoin = Registration::Payment::Bitcoin.new(
391 @customer,
392 "+15555550000"
393 )
394 end
395
396 def test_write
397 CustomerFinancials::REDIS.expect(
398 :smembers,
399 EMPromise.resolve([]),
400 ["jmp_customer_btc_addresses-test"]
401 )
402 blather = Minitest::Mock.new
403 Command::COMMAND_MANAGER.expect(
404 :write,
405 EMPromise.reject(SessionManager::Timeout.new),
406 [Matching.new do |reply|
407 assert_equal :canceled, reply.status
408 assert_equal "1.000000", reply.form.field("amount").value
409 assert_equal "testaddr", reply.form.field("btc_addresses").value
410 true
411 end]
412 )
413 Registration::Payment::Bitcoin::BTC_SELL_PRICES.expect(
414 :usd,
415 EMPromise.resolve(BigDecimal(1))
416 )
417 @bitcoin.stub(:save, EMPromise.resolve(nil)) do
418 execute_command(blather: blather) do
419 @bitcoin.write
420 end
421 end
422 assert_mock blather
423 end
424 em :test_write
425 end
426
427 class CreditCardTest < Minitest::Test
428 def setup
429 @credit_card = Registration::Payment::CreditCard.new(
430 customer,
431 "+15555550000"
432 )
433 end
434
435 def test_for
436 cust = Minitest::Mock.new(customer)
437 cust.expect(
438 :payment_methods,
439 EMPromise.resolve(OpenStruct.new(default_payment_method: :test))
440 )
441 execute_command do
442 Command.execution.customer_repo.expect(:find, cust, ["test"])
443 assert_kind_of(
444 Registration::Payment::CreditCard::Activate,
445 Registration::Payment::CreditCard.for(
446 cust,
447 "+15555550000"
448 ).sync
449 )
450 end
451 end
452 em :test_for
453
454 def test_for_has_balance
455 cust = Minitest::Mock.new(customer)
456 cust.expect(:balance, 100)
457 cust.expect(:payment_methods, EMPromise.resolve(nil))
458 execute_command do
459 Command.execution.customer_repo.expect(:find, cust, ["test"])
460 assert_kind_of(
461 Registration::BillPlan,
462 Registration::Payment::CreditCard.for(
463 cust,
464 "+15555550000"
465 ).sync
466 )
467 end
468 end
469 em :test_for_has_balance
470
471 def test_write
472 result = execute_command do
473 Command::COMMAND_MANAGER.expect(
474 :write,
475 EMPromise.reject(:test_result),
476 [Matching.new do |reply|
477 assert_equal [:execute, :next, :prev], reply.allowed_actions
478 assert_equal(
479 "Add credit card, save, then next here to continue: " \
480 "http://creditcard.example.com?&amount=1",
481 reply.note.content
482 )
483 end]
484 )
485
486 @credit_card.write.catch { |e| e }
487 end
488
489 assert_equal :test_result, result
490 end
491 em :test_write
492 end
493
494 class MailTest < Minitest::Test
495 def setup
496 @mail = Registration::Payment::Mail.new(
497 customer(plan_name: "test_cad"),
498 "+15555550000"
499 )
500 end
501
502 def test_write
503 result = execute_command do
504 Command::COMMAND_MANAGER.expect(
505 :write,
506 EMPromise.reject(:test_result),
507 [Matching.new do |reply|
508 assert_equal [:execute, :prev], reply.allowed_actions
509 refute reply.form.instructions.empty?
510 assert_equal(
511 "A Mailing Address",
512 reply.form.field("adr").value
513 )
514 assert_equal(
515 "interac@example.com",
516 reply.form.field("interac_email").value
517 )
518 end]
519 )
520
521 @mail.write.catch { |e| e }
522 end
523
524 assert_equal :test_result, result
525 end
526 em :test_write
527 end
528
529 class ActivateTest < Minitest::Test
530 Registration::Payment::CreditCard::Activate::Finish =
531 Minitest::Mock.new
532 Registration::Payment::CreditCard::Activate::CreditCardSale =
533 Minitest::Mock.new
534 Command::COMMAND_MANAGER = Minitest::Mock.new
535
536 def test_write
537 customer = Minitest::Mock.new(
538 customer(plan_name: "test_usd")
539 )
540 Registration::Payment::CreditCard::Activate::CreditCardSale.expect(
541 :create,
542 EMPromise.resolve(nil)
543 ) do |acustomer, amount:, payment_method:|
544 assert_operator customer, :===, acustomer
545 assert_equal CONFIG[:activation_amount], amount
546 assert_equal :test_default_method, payment_method
547 end
548 customer.expect(
549 :bill_plan,
550 nil,
551 note: "Bill +15555550000 for first month"
552 )
553 Registration::Payment::CreditCard::Activate::Finish.expect(
554 :new,
555 OpenStruct.new(write: nil),
556 [customer, "+15555550000"]
557 )
558 execute_command do
559 Registration::Payment::CreditCard::Activate.new(
560 customer,
561 :test_default_method,
562 "+15555550000"
563 ).write
564 end
565 Registration::Payment::CreditCard::Activate::CreditCardSale.verify
566 customer.verify
567 Registration::Payment::CreditCard::Activate::Finish.verify
568 end
569 em :test_write
570
571 def test_write_declines
572 customer = Minitest::Mock.new(
573 customer(plan_name: "test_usd")
574 )
575 iq = Blather::Stanza::Iq::Command.new
576 iq.from = "test@example.com"
577 msg = Registration::Payment::CreditCard::Activate::DECLINE_MESSAGE
578 Command::COMMAND_MANAGER.expect(
579 :write,
580 EMPromise.reject(:test_result),
581 [Matching.new do |reply|
582 assert_equal :error, reply.note_type
583 assert_equal(
584 "#{msg}: http://creditcard.example.com?&amount=1",
585 reply.note.content
586 )
587 end]
588 )
589 result = execute_command do
590 Registration::Payment::CreditCard::Activate::CreditCardSale.expect(
591 :create,
592 EMPromise.reject("declined")
593 ) do |acustomer, amount:, payment_method:|
594 assert_operator customer, :===, acustomer
595 assert_equal CONFIG[:activation_amount], amount
596 assert_equal :test_default_method, payment_method
597 end
598
599 Registration::Payment::CreditCard::Activate.new(
600 customer,
601 :test_default_method,
602 "+15555550000"
603 ).write.catch { |e| e }
604 end
605 assert_equal :test_result, result
606 Registration::Payment::CreditCard::Activate::CreditCardSale.verify
607 end
608 em :test_write_declines
609 end
610
611 class InviteCodeTest < Minitest::Test
612 Registration::Payment::InviteCode::DB =
613 Minitest::Mock.new
614 Registration::Payment::InviteCode::REDIS =
615 Minitest::Mock.new
616 Command::COMMAND_MANAGER = Minitest::Mock.new
617 Registration::Payment::InviteCode::Finish =
618 Minitest::Mock.new
619 def test_write
620 customer = customer(plan_name: "test_usd")
621 Registration::Payment::InviteCode::DB.expect(:transaction, true, [])
622 Registration::Payment::InviteCode::Finish.expect(
623 :new,
624 OpenStruct.new(write: nil),
625 [
626 customer,
627 "+15555550000"
628 ]
629 )
630 execute_command do
631 Registration::Payment::InviteCode::REDIS.expect(
632 :get,
633 EMPromise.resolve(nil),
634 ["jmp_invite_tries-test"]
635 )
636 Command::COMMAND_MANAGER.expect(
637 :write,
638 EMPromise.resolve(
639 Blather::Stanza::Iq::Command.new.tap { |iq|
640 iq.form.fields = [{ var: "code", value: "abc" }]
641 }
642 ),
643 [Matching.new do |reply|
644 assert_equal :form, reply.form.type
645 assert_nil reply.form.instructions
646 end]
647 )
648
649 Registration::Payment::InviteCode.new(
650 customer,
651 "+15555550000"
652 ).write
653 end
654 assert_mock Command::COMMAND_MANAGER
655 assert_mock Registration::Payment::InviteCode::DB
656 assert_mock Registration::Payment::InviteCode::REDIS
657 assert_mock Registration::Payment::InviteCode::Finish
658 end
659 em :test_write
660
661 def test_write_bad_code
662 result = execute_command do
663 customer = customer(plan_name: "test_usd")
664 Registration::Payment::InviteCode::REDIS.expect(
665 :get,
666 EMPromise.resolve(0),
667 ["jmp_invite_tries-test"]
668 )
669 Registration::Payment::InviteCode::DB.expect(
670 :transaction,
671 []
672 ) { |&blk| blk.call }
673 Registration::Payment::InviteCode::DB.expect(
674 :exec,
675 OpenStruct.new(cmd_tuples: 0),
676 [String, ["test", "abc"]]
677 )
678 Registration::Payment::InviteCode::REDIS.expect(
679 :incr,
680 EMPromise.resolve(nil),
681 ["jmp_invite_tries-test"]
682 )
683 Registration::Payment::InviteCode::REDIS.expect(
684 :expire,
685 EMPromise.resolve(nil),
686 ["jmp_invite_tries-test", 60 * 60]
687 )
688 Command::COMMAND_MANAGER.expect(
689 :write,
690 EMPromise.resolve(
691 Blather::Stanza::Iq::Command.new.tap { |iq|
692 iq.form.fields = [{ var: "code", value: "abc" }]
693 }
694 ),
695 [Matching.new do |reply|
696 assert_equal :form, reply.form.type
697 assert_nil reply.form.instructions
698 end]
699 )
700 Command::COMMAND_MANAGER.expect(
701 :write,
702 EMPromise.reject(:test_result),
703 [Matching.new do |reply|
704 assert_equal :form, reply.form.type
705 assert_equal(
706 "Not a valid invite code: abc",
707 reply.form.instructions
708 )
709 end]
710 )
711
712 Registration::Payment::InviteCode.new(
713 customer,
714 "+15555550000"
715 ).write.catch { |e| e }
716 end
717 assert_equal :test_result, result
718 assert_mock Command::COMMAND_MANAGER
719 assert_mock Registration::Payment::InviteCode::DB
720 assert_mock Registration::Payment::InviteCode::REDIS
721 end
722 em :test_write_bad_code
723
724 def test_write_bad_code_over_limit
725 result = execute_command do
726 customer = customer(plan_name: "test_usd")
727 Registration::Payment::InviteCode::REDIS.expect(
728 :get,
729 EMPromise.resolve(11),
730 ["jmp_invite_tries-test"]
731 )
732 Command::COMMAND_MANAGER.expect(
733 :write,
734 EMPromise.resolve(
735 Blather::Stanza::Iq::Command.new.tap { |iq|
736 iq.form.fields = [{ var: "code", value: "abc" }]
737 }
738 ),
739 [Matching.new do |reply|
740 assert_equal :form, reply.form.type
741 assert_nil reply.form.instructions
742 end]
743 )
744 Command::COMMAND_MANAGER.expect(
745 :write,
746 EMPromise.reject(:test_result),
747 [Matching.new do |reply|
748 assert_equal :form, reply.form.type
749 assert_equal "Too many wrong attempts", reply.form.instructions
750 end]
751 )
752 Registration::Payment::InviteCode.new(
753 customer,
754 "+15555550000"
755 ).write.catch { |e| e }
756 end
757 assert_equal :test_result, result
758 assert_mock Command::COMMAND_MANAGER
759 assert_mock Registration::Payment::InviteCode::REDIS
760 end
761 em :test_write_bad_code_over_limit
762 end
763 end
764
765 class FinishTest < Minitest::Test
766 Customer::BLATHER = Minitest::Mock.new
767 Command::COMMAND_MANAGER = Minitest::Mock.new
768 Registration::Finish::TEL_SELECTIONS = FakeTelSelections.new
769 Registration::Finish::REDIS = Minitest::Mock.new
770 Registration::Finish::DB = Minitest::Mock.new
771 Bwmsgsv2Repo::REDIS = Minitest::Mock.new
772 Registration::FinishOnboarding::DB = FakeDB.new
773
774 def setup
775 @sgx = Minitest::Mock.new(TrivialBackendSgxRepo.new.get("test"))
776 iq = Blather::Stanza::Iq::Command.new
777 iq.from = "test\\40example.com@cheogram.com"
778 @finish = Registration::Finish.new(
779 customer(sgx: @sgx),
780 "+15555550000"
781 )
782 end
783
784 def test_write
785 create_order = stub_request(
786 :post,
787 "https://dashboard.bandwidth.com/v1.0/accounts//orders"
788 ).to_return(status: 201, body: <<~RESPONSE)
789 <OrderResponse>
790 <Order>
791 <id>test_order</id>
792 </Order>
793 </OrderResponse>
794 RESPONSE
795 stub_request(
796 :get,
797 "https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
798 ).to_return(status: 201, body: <<~RESPONSE)
799 <OrderResponse>
800 <OrderStatus>COMPLETE</OrderStatus>
801 <CompletedNumbers>
802 <TelephoneNumber>
803 <FullNumber>5555550000</FullNumber>
804 </TelephoneNumber>
805 </CompletedNumbers>
806 </OrderResponse>
807 RESPONSE
808 stub_request(
809 :post,
810 "https://dashboard.bandwidth.com/v1.0/accounts//sites//sippeers//movetns"
811 )
812 Registration::Finish::REDIS.expect(
813 :del,
814 nil,
815 ["pending_tel_for-test@example.net"]
816 )
817 Registration::Finish::REDIS.expect(
818 :get,
819 nil,
820 ["jmp_customer_pending_invite-test"]
821 )
822 Registration::Finish::REDIS.expect(
823 :del,
824 nil,
825 ["jmp_customer_pending_invite-test"]
826 )
827 Registration::Finish::REDIS.expect(
828 :hget,
829 nil,
830 ["jmp_group_codes", nil]
831 )
832 Bwmsgsv2Repo::REDIS.expect(
833 :set,
834 nil,
835 [
836 "catapult_fwd-+15555550000",
837 "xmpp:test@example.net"
838 ]
839 )
840 Bwmsgsv2Repo::REDIS.expect(
841 :set,
842 nil,
843 ["catapult_fwd_timeout-customer_test@component", 25]
844 )
845 Customer::BLATHER.expect(
846 :<<,
847 nil,
848 [Matching.new do |m|
849 assert_equal :chat, m.type
850 assert m.body =~ /^Welcome to JMP/
851 end]
852 )
853 blather = Minitest::Mock.new
854 blather.expect(
855 :<<,
856 nil,
857 [Matching.new do |reply|
858 assert_equal :completed, reply.status
859 assert_equal :info, reply.note_type
860 assert_equal(
861 "Your JMP account has been activated as +15555550000",
862 reply.note.content
863 )
864 end]
865 )
866 execute_command(blather: blather) do
867 @sgx.expect(
868 :register!,
869 EMPromise.resolve(@sgx.with(
870 registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
871 ibr.phone = "+15555550000"
872 end
873 )),
874 ["+15555550000"]
875 )
876
877 @finish.write
878 end
879 assert_requested create_order
880 assert_mock @sgx
881 assert_mock Registration::Finish::REDIS
882 assert_mock Bwmsgsv2Repo::REDIS
883 assert_mock Customer::BLATHER
884 assert_mock blather
885 end
886 em :test_write
887
888 def test_write_onboarding
889 create_order = stub_request(
890 :post,
891 "https://dashboard.bandwidth.com/v1.0/accounts//orders"
892 ).to_return(status: 201, body: <<~RESPONSE)
893 <OrderResponse>
894 <Order>
895 <id>test_order</id>
896 </Order>
897 </OrderResponse>
898 RESPONSE
899 stub_request(
900 :get,
901 "https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
902 ).to_return(status: 201, body: <<~RESPONSE)
903 <OrderResponse>
904 <OrderStatus>COMPLETE</OrderStatus>
905 <CompletedNumbers>
906 <TelephoneNumber>
907 <FullNumber>5555550000</FullNumber>
908 </TelephoneNumber>
909 </CompletedNumbers>
910 </OrderResponse>
911 RESPONSE
912 stub_request(
913 :post,
914 "https://dashboard.bandwidth.com/v1.0/accounts//sites//sippeers//movetns"
915 )
916 Registration::Finish::REDIS.expect(
917 :del,
918 nil,
919 ["pending_tel_for-test\\40onboarding.example.com@proxy"]
920 )
921 Registration::Finish::REDIS.expect(
922 :get,
923 nil,
924 ["jmp_customer_pending_invite-test"]
925 )
926 Registration::Finish::REDIS.expect(
927 :del,
928 nil,
929 ["jmp_customer_pending_invite-test"]
930 )
931 Registration::Finish::REDIS.expect(
932 :hget,
933 nil,
934 ["jmp_group_codes", nil]
935 )
936 Bwmsgsv2Repo::REDIS.expect(
937 :set,
938 nil,
939 [
940 "catapult_fwd-+15555550000",
941 "xmpp:test\\40onboarding.example.com@proxy"
942 ]
943 )
944 Bwmsgsv2Repo::REDIS.expect(
945 :set,
946 nil,
947 ["catapult_fwd_timeout-customer_test@component", 25]
948 )
949 result = execute_command do
950 @sgx.expect(
951 :register!,
952 EMPromise.resolve(@sgx.with(
953 registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
954 ibr.phone = "+15555550000"
955 end
956 )),
957 ["+15555550000"]
958 )
959
960 Command::COMMAND_MANAGER.expect(
961 :write,
962 EMPromise.reject(:test_result),
963 [Matching.new do |iq|
964 assert_equal :form, iq.form.type
965 assert iq.form.field("subdomain")
966 end]
967 )
968
969 Registration::Finish.new(
970 customer(
971 sgx: @sgx,
972 jid: Blather::JID.new("test\\40onboarding.example.com@proxy")
973 ),
974 "+15555550000"
975 ).write.catch { |e| e }
976 end
977 assert_equal :test_result, result
978 assert_requested create_order
979 assert_mock @sgx
980 assert_mock Registration::Finish::REDIS
981 assert_mock Bwmsgsv2Repo::REDIS
982 assert_mock Command::COMMAND_MANAGER
983 end
984 em :test_write_onboarding
985
986 def test_write_tn_fail
987 create_order = stub_request(
988 :post,
989 "https://dashboard.bandwidth.com/v1.0/accounts//orders"
990 ).to_return(status: 201, body: <<~RESPONSE)
991 <OrderResponse>
992 <Order>
993 <id>test_order</id>
994 </Order>
995 </OrderResponse>
996 RESPONSE
997 stub_request(
998 :get,
999 "https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
1000 ).to_return(status: 201, body: <<~RESPONSE)
1001 <OrderResponse>
1002 <OrderStatus>FAILED</OrderStatus>
1003 </OrderResponse>
1004 RESPONSE
1005
1006 result = execute_command do
1007 Command::COMMAND_MANAGER.expect(
1008 :write,
1009 EMPromise.reject(:test_result),
1010 [Matching.new do |iq|
1011 assert_equal :form, iq.form.type
1012 assert_equal(
1013 "The JMP number +15555550000 is no longer available.",
1014 iq.form.instructions
1015 )
1016 end]
1017 )
1018
1019 @finish.write.catch { |e| e }
1020 end
1021
1022 assert_equal :test_result, result
1023 assert_mock Command::COMMAND_MANAGER
1024 assert_instance_of(
1025 TelSelections::ChooseTel,
1026 Registration::Finish::TEL_SELECTIONS["test@example.com"]
1027 )
1028 assert_requested create_order
1029 end
1030 em :test_write_tn_fail
1031 end
1032
1033 class SnikketTest < Minitest::Test
1034 Command::COMMAND_MANAGER = Minitest::Mock.new
1035 Registration::FinishOnboarding::Snikket::IQ_MANAGER = Minitest::Mock.new
1036
1037 def setup
1038 @sgx = Minitest::Mock.new(TrivialBackendSgxRepo.new.get("test"))
1039 @snikket = Registration::FinishOnboarding::Snikket.new(
1040 customer,
1041 "+15555550000",
1042 db: FakeDB.new
1043 )
1044 end
1045
1046 def test_write
1047 xmpp_uri = "xmpp:test.snikket.chat?register;preauth=NEWTOKEN"
1048
1049 subdomain_form = Blather::Stanza::Iq::Command.new
1050 subdomain_form.form.fields = [
1051 { var: "subdomain", value: "test" }
1052 ]
1053
1054 launched = Snikket::Launched.new
1055 launched << Niceogiri::XML::Node.new(
1056 :launched, launched.document, "xmpp:snikket.org/hosting/v1"
1057 ).tap { |inner|
1058 inner << Niceogiri::XML::Node.new(
1059 :'instance-id', launched.document, "xmpp:snikket.org/hosting/v1"
1060 ).tap { |id|
1061 id.content = "si-1234"
1062 }
1063 inner << Niceogiri::XML::Node.new(
1064 :bootstrap, launched.document, "xmpp:snikket.org/hosting/v1"
1065 ).tap { |bootstrap|
1066 bootstrap << Niceogiri::XML::Node.new(
1067 :token, launched.document, "xmpp:snikket.org/hosting/v1"
1068 ).tap { |token|
1069 token.content = "TOKEN"
1070 }
1071 }
1072 }
1073
1074 blather = Minitest::Mock.new
1075 blather.expect(
1076 :<<,
1077 nil,
1078 [Matching.new do |reply|
1079 assert_equal :completed, reply.status
1080 assert_equal(
1081 xmpp_uri,
1082 OOB.find_or_create(reply.command).url
1083 )
1084 end]
1085 )
1086
1087 execute_command(blather: blather) do
1088 Command::COMMAND_MANAGER.expect(
1089 :write,
1090 EMPromise.resolve(subdomain_form),
1091 [Matching.new do |iq|
1092 assert_equal :form, iq.form.type
1093 assert iq.form.field("subdomain")
1094 end]
1095 )
1096
1097 Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
1098 :write,
1099 EMPromise.resolve(launched),
1100 [Matching.new do |iq|
1101 assert_equal :set, iq.type
1102 assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
1103 assert_equal(
1104 "test.snikket.chat",
1105 iq.xpath(
1106 "./ns:launch/ns:domain",
1107 ns: "xmpp:snikket.org/hosting/v1"
1108 ).text
1109 )
1110 end]
1111 )
1112
1113 # Webmock doesn't support redirects properly, but they work live
1114 stub_request(
1115 :head, "https://test.snikket.chat/invites_bootstrap?token=TOKEN"
1116 ).to_return(
1117 status: 200,
1118 headers: {
1119 "link" => "<#{xmpp_uri}>; rel=\"alternate\""
1120 }
1121 )
1122
1123 @snikket.write
1124 end
1125
1126 assert_mock Command::COMMAND_MANAGER
1127 assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
1128 assert_mock blather
1129 end
1130 em :test_write
1131
1132 def test_write_not_yet
1133 subdomain_form = Blather::Stanza::Iq::Command.new
1134 subdomain_form.form.fields = [
1135 { var: "subdomain", value: "test" }
1136 ]
1137
1138 launched = Snikket::Launched.new
1139 launched << Niceogiri::XML::Node.new(
1140 :launched, launched.document, "xmpp:snikket.org/hosting/v1"
1141 ).tap { |inner|
1142 inner << Niceogiri::XML::Node.new(
1143 :'instance-id', launched.document, "xmpp:snikket.org/hosting/v1"
1144 ).tap { |id|
1145 id.content = "si-1234"
1146 }
1147 inner << Niceogiri::XML::Node.new(
1148 :bootstrap, launched.document, "xmpp:snikket.org/hosting/v1"
1149 ).tap { |bootstrap|
1150 bootstrap << Niceogiri::XML::Node.new(
1151 :token, launched.document, "xmpp:snikket.org/hosting/v1"
1152 ).tap { |token|
1153 token.content = "TOKEN"
1154 }
1155 }
1156 }
1157
1158 result = execute_command do
1159 Command::COMMAND_MANAGER.expect(
1160 :write,
1161 EMPromise.resolve(subdomain_form),
1162 [Matching.new do |iq|
1163 assert_equal :form, iq.form.type
1164 assert iq.form.field("subdomain")
1165 end]
1166 )
1167
1168 Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
1169 :write,
1170 EMPromise.resolve(launched),
1171 [Matching.new do |iq|
1172 assert_equal :set, iq.type
1173 assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
1174 assert_equal(
1175 "test.snikket.chat",
1176 iq.xpath(
1177 "./ns:launch/ns:domain",
1178 ns: "xmpp:snikket.org/hosting/v1"
1179 ).text
1180 )
1181 end]
1182 )
1183
1184 stub_request(
1185 :head, "https://test.snikket.chat/invites_bootstrap?token=TOKEN"
1186 ).to_timeout
1187
1188 Command::COMMAND_MANAGER.expect(
1189 :write,
1190 EMPromise.reject(:test_result),
1191 [Matching.new do |iq|
1192 assert_equal :result, iq.form.type
1193 assert iq.form.instructions =~ / test\.snikket\.chat /
1194 assert_equal "jid-single", iq.form.field("support").type
1195 end]
1196 )
1197
1198 @snikket.write.catch { |e| e }
1199 end
1200
1201 assert_equal :test_result, result
1202 assert_mock Command::COMMAND_MANAGER
1203 assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
1204 end
1205 em :test_write_not_yet
1206
1207 def test_write_already_taken
1208 subdomain_form = Blather::Stanza::Iq::Command.new
1209 subdomain_form.form.fields = [
1210 { var: "subdomain", value: "test" }
1211 ]
1212
1213 launched = Snikket::Launched.new.as_error(
1214 "internal-server-error",
1215 :wait,
1216 "This is an error"
1217 )
1218
1219 result = execute_command do
1220 Command::COMMAND_MANAGER.expect(
1221 :write,
1222 EMPromise.resolve(subdomain_form),
1223 [Matching.new do |iq|
1224 assert_equal :form, iq.form.type
1225 assert iq.form.field("subdomain")
1226 end]
1227 )
1228
1229 Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
1230 :write,
1231 EMPromise.reject(launched),
1232 [Matching.new do |iq|
1233 assert_equal :set, iq.type
1234 assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
1235 assert_equal(
1236 "test.snikket.chat",
1237 iq.xpath(
1238 "./ns:launch/ns:domain",
1239 ns: "xmpp:snikket.org/hosting/v1"
1240 ).text
1241 )
1242 end]
1243 )
1244
1245 stub_request(
1246 :head, "https://test.snikket.chat/invites_bootstrap?token=TOKEN"
1247 ).to_timeout
1248
1249 Command::COMMAND_MANAGER.expect(
1250 :write,
1251 EMPromise.reject(:test_result),
1252 [Matching.new do |iq|
1253 assert iq.executing?
1254 assert_equal(
1255 "This is an error",
1256 iq.form.field("subdomain").desc
1257 )
1258 end]
1259 )
1260
1261 @snikket.write.catch { |e| e }
1262 end
1263
1264 assert_equal :test_result, result
1265 assert_mock Command::COMMAND_MANAGER
1266 assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
1267 end
1268 em :test_write_already_taken
1269 end
1270end