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(:transaction, []) do
632 raise InvitesRepo::Invalid, "wut"
633 end
634 Registration::Payment::InviteCode::REDIS.expect(
635 :incr,
636 EMPromise.resolve(nil),
637 ["jmp_invite_tries-test"]
638 )
639 Registration::Payment::InviteCode::REDIS.expect(
640 :expire,
641 EMPromise.resolve(nil),
642 ["jmp_invite_tries-test", 60 * 60]
643 )
644 Command::COMMAND_MANAGER.expect(
645 :write,
646 EMPromise.resolve(
647 Blather::Stanza::Iq::Command.new.tap { |iq|
648 iq.form.fields = [{ var: "code", value: "abc" }]
649 }
650 ),
651 [Matching.new do |reply|
652 assert_equal :form, reply.form.type
653 assert_nil reply.form.instructions
654 end]
655 )
656 Command::COMMAND_MANAGER.expect(
657 :write,
658 EMPromise.reject(:test_result),
659 [Matching.new do |reply|
660 assert_equal :form, reply.form.type
661 assert_equal "wut", reply.form.instructions
662 end]
663 )
664
665 Registration::Payment::InviteCode.new(
666 customer,
667 "+15555550000"
668 ).write.catch { |e| e }
669 end
670 assert_equal :test_result, result
671 assert_mock Command::COMMAND_MANAGER
672 assert_mock Registration::Payment::InviteCode::DB
673 assert_mock Registration::Payment::InviteCode::REDIS
674 end
675 em :test_write_bad_code
676
677 def test_write_bad_code_over_limit
678 result = execute_command do
679 customer = customer(plan_name: "test_usd")
680 Registration::Payment::InviteCode::REDIS.expect(
681 :get,
682 EMPromise.resolve(11),
683 ["jmp_invite_tries-test"]
684 )
685 Command::COMMAND_MANAGER.expect(
686 :write,
687 EMPromise.resolve(
688 Blather::Stanza::Iq::Command.new.tap { |iq|
689 iq.form.fields = [{ var: "code", value: "abc" }]
690 }
691 ),
692 [Matching.new do |reply|
693 assert_equal :form, reply.form.type
694 assert_nil reply.form.instructions
695 end]
696 )
697 Registration::Payment::InviteCode::REDIS.expect(
698 :incr,
699 EMPromise.resolve(nil),
700 ["jmp_invite_tries-test"]
701 )
702 Registration::Payment::InviteCode::REDIS.expect(
703 :expire,
704 EMPromise.resolve(nil),
705 ["jmp_invite_tries-test", 60 * 60]
706 )
707 Command::COMMAND_MANAGER.expect(
708 :write,
709 EMPromise.reject(:test_result),
710 [Matching.new do |reply|
711 assert_equal :form, reply.form.type
712 assert_equal "Too many wrong attempts", reply.form.instructions
713 end]
714 )
715 Registration::Payment::InviteCode.new(
716 customer,
717 "+15555550000"
718 ).write.catch { |e| e }
719 end
720 assert_equal :test_result, result
721 assert_mock Command::COMMAND_MANAGER
722 assert_mock Registration::Payment::InviteCode::REDIS
723 end
724 em :test_write_bad_code_over_limit
725 end
726 end
727
728 class FinishTest < Minitest::Test
729 Customer::BLATHER = Minitest::Mock.new
730 Command::COMMAND_MANAGER = Minitest::Mock.new
731 Registration::Finish::TEL_SELECTIONS = FakeTelSelections.new
732 Registration::Finish::REDIS = Minitest::Mock.new
733 Bwmsgsv2Repo::REDIS = Minitest::Mock.new
734 Registration::FinishOnboarding::DB = FakeDB.new
735
736 def setup
737 @sgx = Minitest::Mock.new(TrivialBackendSgxRepo.new.get("test"))
738 iq = Blather::Stanza::Iq::Command.new
739 iq.from = "test\\40example.com@cheogram.com"
740 @finish = Registration::Finish.new(
741 customer(sgx: @sgx),
742 "+15555550000"
743 )
744 end
745
746 def test_write
747 create_order = stub_request(
748 :post,
749 "https://dashboard.bandwidth.com/v1.0/accounts//orders"
750 ).to_return(status: 201, body: <<~RESPONSE)
751 <OrderResponse>
752 <Order>
753 <id>test_order</id>
754 </Order>
755 </OrderResponse>
756 RESPONSE
757 stub_request(
758 :get,
759 "https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
760 ).to_return(status: 201, body: <<~RESPONSE)
761 <OrderResponse>
762 <OrderStatus>COMPLETE</OrderStatus>
763 <CompletedNumbers>
764 <TelephoneNumber>
765 <FullNumber>5555550000</FullNumber>
766 </TelephoneNumber>
767 </CompletedNumbers>
768 </OrderResponse>
769 RESPONSE
770 stub_request(
771 :post,
772 "https://dashboard.bandwidth.com/v1.0/accounts//sites//sippeers//movetns"
773 )
774 Registration::Finish::REDIS.expect(
775 :del,
776 nil,
777 ["pending_tel_for-test@example.net"]
778 )
779 Bwmsgsv2Repo::REDIS.expect(
780 :set,
781 nil,
782 [
783 "catapult_fwd-+15555550000",
784 "xmpp:test@example.net"
785 ]
786 )
787 Bwmsgsv2Repo::REDIS.expect(
788 :set,
789 nil,
790 ["catapult_fwd_timeout-customer_test@component", 25]
791 )
792 Customer::BLATHER.expect(
793 :<<,
794 nil,
795 [Matching.new do |m|
796 assert_equal :chat, m.type
797 assert m.body =~ /^Welcome to JMP/
798 end]
799 )
800 blather = Minitest::Mock.new
801 blather.expect(
802 :<<,
803 nil,
804 [Matching.new do |reply|
805 assert_equal :completed, reply.status
806 assert_equal :info, reply.note_type
807 assert_equal(
808 "Your JMP account has been activated as +15555550000",
809 reply.note.content
810 )
811 end]
812 )
813 execute_command(blather: blather) do
814 @sgx.expect(
815 :register!,
816 EMPromise.resolve(@sgx.with(
817 registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
818 ibr.phone = "+15555550000"
819 end
820 )),
821 ["+15555550000"]
822 )
823
824 @finish.write
825 end
826 assert_requested create_order
827 assert_mock @sgx
828 assert_mock Registration::Finish::REDIS
829 assert_mock Bwmsgsv2Repo::REDIS
830 assert_mock Customer::BLATHER
831 assert_mock blather
832 end
833 em :test_write
834
835 def test_write_onboarding
836 create_order = stub_request(
837 :post,
838 "https://dashboard.bandwidth.com/v1.0/accounts//orders"
839 ).to_return(status: 201, body: <<~RESPONSE)
840 <OrderResponse>
841 <Order>
842 <id>test_order</id>
843 </Order>
844 </OrderResponse>
845 RESPONSE
846 stub_request(
847 :get,
848 "https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
849 ).to_return(status: 201, body: <<~RESPONSE)
850 <OrderResponse>
851 <OrderStatus>COMPLETE</OrderStatus>
852 <CompletedNumbers>
853 <TelephoneNumber>
854 <FullNumber>5555550000</FullNumber>
855 </TelephoneNumber>
856 </CompletedNumbers>
857 </OrderResponse>
858 RESPONSE
859 stub_request(
860 :post,
861 "https://dashboard.bandwidth.com/v1.0/accounts//sites//sippeers//movetns"
862 )
863 Registration::Finish::REDIS.expect(
864 :del,
865 nil,
866 ["pending_tel_for-test\\40onboarding.example.com@proxy"]
867 )
868 Bwmsgsv2Repo::REDIS.expect(
869 :set,
870 nil,
871 [
872 "catapult_fwd-+15555550000",
873 "xmpp:test\\40onboarding.example.com@proxy"
874 ]
875 )
876 Bwmsgsv2Repo::REDIS.expect(
877 :set,
878 nil,
879 ["catapult_fwd_timeout-customer_test@component", 25]
880 )
881 result = execute_command do
882 @sgx.expect(
883 :register!,
884 EMPromise.resolve(@sgx.with(
885 registered?: Blather::Stanza::Iq::IBR.new.tap do |ibr|
886 ibr.phone = "+15555550000"
887 end
888 )),
889 ["+15555550000"]
890 )
891
892 Command::COMMAND_MANAGER.expect(
893 :write,
894 EMPromise.reject(:test_result),
895 [Matching.new do |iq|
896 assert_equal :form, iq.form.type
897 assert iq.form.field("subdomain")
898 end]
899 )
900
901 Registration::Finish.new(
902 customer(
903 sgx: @sgx,
904 jid: Blather::JID.new("test\\40onboarding.example.com@proxy")
905 ),
906 "+15555550000"
907 ).write.catch { |e| e }
908 end
909 assert_equal :test_result, result
910 assert_requested create_order
911 assert_mock @sgx
912 assert_mock Registration::Finish::REDIS
913 assert_mock Bwmsgsv2Repo::REDIS
914 assert_mock Command::COMMAND_MANAGER
915 end
916 em :test_write_onboarding
917
918 def test_write_tn_fail
919 create_order = stub_request(
920 :post,
921 "https://dashboard.bandwidth.com/v1.0/accounts//orders"
922 ).to_return(status: 201, body: <<~RESPONSE)
923 <OrderResponse>
924 <Order>
925 <id>test_order</id>
926 </Order>
927 </OrderResponse>
928 RESPONSE
929 stub_request(
930 :get,
931 "https://dashboard.bandwidth.com/v1.0/accounts//orders/test_order"
932 ).to_return(status: 201, body: <<~RESPONSE)
933 <OrderResponse>
934 <OrderStatus>FAILED</OrderStatus>
935 </OrderResponse>
936 RESPONSE
937
938 result = execute_command do
939 Command::COMMAND_MANAGER.expect(
940 :write,
941 EMPromise.reject(:test_result),
942 [Matching.new do |iq|
943 assert_equal :form, iq.form.type
944 assert_equal(
945 "The JMP number +15555550000 is no longer available.",
946 iq.form.instructions
947 )
948 end]
949 )
950
951 @finish.write.catch { |e| e }
952 end
953
954 assert_equal :test_result, result
955 assert_mock Command::COMMAND_MANAGER
956 assert_instance_of(
957 TelSelections::ChooseTel,
958 Registration::Finish::TEL_SELECTIONS["test@example.com"]
959 )
960 assert_requested create_order
961 end
962 em :test_write_tn_fail
963 end
964
965 class SnikketTest < Minitest::Test
966 Command::COMMAND_MANAGER = Minitest::Mock.new
967 Registration::FinishOnboarding::Snikket::IQ_MANAGER = Minitest::Mock.new
968
969 def setup
970 @sgx = Minitest::Mock.new(TrivialBackendSgxRepo.new.get("test"))
971 @snikket = Registration::FinishOnboarding::Snikket.new(
972 customer,
973 "+15555550000",
974 db: FakeDB.new
975 )
976 end
977
978 def test_write
979 xmpp_uri = "xmpp:test.snikket.chat?register;preauth=NEWTOKEN"
980
981 subdomain_form = Blather::Stanza::Iq::Command.new
982 subdomain_form.form.fields = [
983 { var: "subdomain", value: "test" }
984 ]
985
986 launched = Snikket::Launched.new
987 launched << Niceogiri::XML::Node.new(
988 :launched, launched.document, "xmpp:snikket.org/hosting/v1"
989 ).tap { |inner|
990 inner << Niceogiri::XML::Node.new(
991 :'instance-id', launched.document, "xmpp:snikket.org/hosting/v1"
992 ).tap { |id|
993 id.content = "si-1234"
994 }
995 inner << Niceogiri::XML::Node.new(
996 :bootstrap, launched.document, "xmpp:snikket.org/hosting/v1"
997 ).tap { |bootstrap|
998 bootstrap << Niceogiri::XML::Node.new(
999 :token, launched.document, "xmpp:snikket.org/hosting/v1"
1000 ).tap { |token|
1001 token.content = "TOKEN"
1002 }
1003 }
1004 }
1005
1006 blather = Minitest::Mock.new
1007 blather.expect(
1008 :<<,
1009 nil,
1010 [Matching.new do |reply|
1011 assert_equal :completed, reply.status
1012 assert_equal(
1013 xmpp_uri,
1014 OOB.find_or_create(reply.command).url
1015 )
1016 end]
1017 )
1018
1019 execute_command(blather: blather) do
1020 Command::COMMAND_MANAGER.expect(
1021 :write,
1022 EMPromise.resolve(subdomain_form),
1023 [Matching.new do |iq|
1024 assert_equal :form, iq.form.type
1025 assert iq.form.field("subdomain")
1026 end]
1027 )
1028
1029 Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
1030 :write,
1031 EMPromise.resolve(launched),
1032 [Matching.new do |iq|
1033 assert_equal :set, iq.type
1034 assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
1035 assert_equal(
1036 "test.snikket.chat",
1037 iq.xpath(
1038 "./ns:launch/ns:domain",
1039 ns: "xmpp:snikket.org/hosting/v1"
1040 ).text
1041 )
1042 end]
1043 )
1044
1045 # Webmock doesn't support redirects properly, but they work live
1046 stub_request(
1047 :head, "https://test.snikket.chat/invites_bootstrap?token=TOKEN"
1048 ).to_return(
1049 status: 200,
1050 headers: {
1051 "link" => "<#{xmpp_uri}>; rel=\"alternate\""
1052 }
1053 )
1054
1055 @snikket.write
1056 end
1057
1058 assert_mock Command::COMMAND_MANAGER
1059 assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
1060 assert_mock blather
1061 end
1062 em :test_write
1063
1064 def test_write_not_yet
1065 subdomain_form = Blather::Stanza::Iq::Command.new
1066 subdomain_form.form.fields = [
1067 { var: "subdomain", value: "test" }
1068 ]
1069
1070 launched = Snikket::Launched.new
1071 launched << Niceogiri::XML::Node.new(
1072 :launched, launched.document, "xmpp:snikket.org/hosting/v1"
1073 ).tap { |inner|
1074 inner << Niceogiri::XML::Node.new(
1075 :'instance-id', launched.document, "xmpp:snikket.org/hosting/v1"
1076 ).tap { |id|
1077 id.content = "si-1234"
1078 }
1079 inner << Niceogiri::XML::Node.new(
1080 :bootstrap, launched.document, "xmpp:snikket.org/hosting/v1"
1081 ).tap { |bootstrap|
1082 bootstrap << Niceogiri::XML::Node.new(
1083 :token, launched.document, "xmpp:snikket.org/hosting/v1"
1084 ).tap { |token|
1085 token.content = "TOKEN"
1086 }
1087 }
1088 }
1089
1090 result = execute_command do
1091 Command::COMMAND_MANAGER.expect(
1092 :write,
1093 EMPromise.resolve(subdomain_form),
1094 [Matching.new do |iq|
1095 assert_equal :form, iq.form.type
1096 assert iq.form.field("subdomain")
1097 end]
1098 )
1099
1100 Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
1101 :write,
1102 EMPromise.resolve(launched),
1103 [Matching.new do |iq|
1104 assert_equal :set, iq.type
1105 assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
1106 assert_equal(
1107 "test.snikket.chat",
1108 iq.xpath(
1109 "./ns:launch/ns:domain",
1110 ns: "xmpp:snikket.org/hosting/v1"
1111 ).text
1112 )
1113 end]
1114 )
1115
1116 stub_request(
1117 :head, "https://test.snikket.chat/invites_bootstrap?token=TOKEN"
1118 ).to_timeout
1119
1120 Command::COMMAND_MANAGER.expect(
1121 :write,
1122 EMPromise.reject(:test_result),
1123 [Matching.new do |iq|
1124 assert_equal :result, iq.form.type
1125 assert iq.form.instructions =~ / test\.snikket\.chat /
1126 assert_equal "jid-single", iq.form.field("support").type
1127 end]
1128 )
1129
1130 @snikket.write.catch { |e| e }
1131 end
1132
1133 assert_equal :test_result, result
1134 assert_mock Command::COMMAND_MANAGER
1135 assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
1136 end
1137 em :test_write_not_yet
1138
1139 def test_write_already_taken
1140 subdomain_form = Blather::Stanza::Iq::Command.new
1141 subdomain_form.form.fields = [
1142 { var: "subdomain", value: "test" }
1143 ]
1144
1145 launched = Snikket::Launched.new.as_error(
1146 "internal-server-error",
1147 :wait,
1148 "This is an error"
1149 )
1150
1151 result = execute_command do
1152 Command::COMMAND_MANAGER.expect(
1153 :write,
1154 EMPromise.resolve(subdomain_form),
1155 [Matching.new do |iq|
1156 assert_equal :form, iq.form.type
1157 assert iq.form.field("subdomain")
1158 end]
1159 )
1160
1161 Registration::FinishOnboarding::Snikket::IQ_MANAGER.expect(
1162 :write,
1163 EMPromise.reject(launched),
1164 [Matching.new do |iq|
1165 assert_equal :set, iq.type
1166 assert_equal CONFIG[:snikket_hosting_api], iq.to.to_s
1167 assert_equal(
1168 "test.snikket.chat",
1169 iq.xpath(
1170 "./ns:launch/ns:domain",
1171 ns: "xmpp:snikket.org/hosting/v1"
1172 ).text
1173 )
1174 end]
1175 )
1176
1177 stub_request(
1178 :head, "https://test.snikket.chat/invites_bootstrap?token=TOKEN"
1179 ).to_timeout
1180
1181 Command::COMMAND_MANAGER.expect(
1182 :write,
1183 EMPromise.reject(:test_result),
1184 [Matching.new do |iq|
1185 assert iq.executing?
1186 assert_equal(
1187 "This is an error",
1188 iq.form.field("subdomain").desc
1189 )
1190 end]
1191 )
1192
1193 @snikket.write.catch { |e| e }
1194 end
1195
1196 assert_equal :test_result, result
1197 assert_mock Command::COMMAND_MANAGER
1198 assert_mock Registration::FinishOnboarding::Snikket::IQ_MANAGER
1199 end
1200 em :test_write_already_taken
1201 end
1202end