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