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