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