1# frozen_string_literal: true
2
3require "rack/test"
4require "test_helper"
5require "bwmsgsv2_repo"
6require "customer_repo"
7require_relative "../web"
8
9ExpiringLock::REDIS = Minitest::Mock.new
10Customer::BLATHER = Minitest::Mock.new
11CustomerFwd::BANDWIDTH_VOICE = Minitest::Mock.new
12Web::BANDWIDTH_VOICE = Minitest::Mock.new
13LowBalance::AutoTopUp::CreditCardSale = Minitest::Mock.new
14
15ReachableRedis = Minitest::Mock.new
16
17class WebTest < Minitest::Test
18 include Rack::Test::Methods
19
20 def app
21 Web.opts[:customer_repo] = CustomerRepo.new(
22 redis: FakeRedis.new(
23 "jmp_customer_jid-customerid" => "customer@example.com",
24 "catapult_jid-+15551234567" => "customer_customerid@component",
25 "jmp_customer_jid-customerid_low" => "customer@example.com",
26 "catapult_jid-+15551234560" => "customer_customerid_low@component",
27 "jmp_customer_jid-customerid_topup" => "customer@example.com",
28 "jmp_customer_auto_top_up_amount-customerid_topup" => "15",
29 "jmp_customer_monthly_overage_limit-customerid_topup" => "99999",
30 "catapult_jid-+15551234562" => "customer_customerid_topup@component",
31 "jmp_customer_jid-customerid_limit" => "customer@example.com",
32 "catapult_jid-+15551234561" => "customer_customerid_limit@component",
33 "jmp_customer_jid-customerid_reach" => "customerid_reach@example.com",
34 "catapult_jid-+15551234563" => "customer_customerid_reach@component",
35 "jmp_customer_jid-customerid2" => "customer2@example.com",
36 "catapult_jid-+15551230000" => "customer_customerid2@component"
37 ),
38 db: FakeDB.new(
39 ["customerid"] => [{
40 "balance" => BigDecimal(10),
41 "plan_name" => "test_usd",
42 "expires_at" => Time.now + 100
43 }],
44 ["customerid2"] => [{
45 "balance" => BigDecimal(10),
46 "plan_name" => "test_usd",
47 "expires_at" => Time.now + 100
48 }],
49 ["customerid_low"] => [{
50 "balance" => BigDecimal("0.01"),
51 "plan_name" => "test_usd",
52 "expires_at" => Time.now + 100
53 }],
54 ["customerid_topup"] => [{
55 "balance" => BigDecimal("0.01"),
56 "plan_name" => "test_usd",
57 "expires_at" => Time.now + 100
58 }],
59 ["customerid_reach"] => [{
60 "balance" => BigDecimal(10),
61 "plan_name" => "test_usd",
62 "expires_at" => Time.now + 100
63 }],
64 ["customerid_limit"] => [{
65 "balance" => BigDecimal(10),
66 "plan_name" => "test_usd",
67 "expires_at" => Time.now + 100
68 }]
69 ),
70 sgx_repo: Bwmsgsv2Repo.new(
71 redis: FakeRedis.new(
72 "catapult_fwd-+15551234567" => "xmpp:customer@example.com",
73 "catapult_fwd_timeout-customer_customerid@component" => "30",
74 "catapult_fwd-+15551234560" => "xmpp:customer@example.com",
75 "catapult_fwd_timeout-customer_customerid_low@component" => "30",
76 "catapult_fwd-+15551234561" => "xmpp:customer@example.com",
77 "catapult_fwd_timeout-customer_customerid_limit@component" => "30",
78 "catapult_fwd-+15551234563" => "xmpp:customer@example.com",
79 "catapult_fwd_timeout-customer_customerid_reach@component" => "30",
80 "catapult_fwd-+15551230000" => "xmpp:customer2@example.com",
81 "catapult_fwd_timeout-customer_customerid2@component" => "30"
82 ),
83 ibr_repo: FakeIBRRepo.new(
84 "sgx" => {
85 "customer_customerid@component" =>
86 Blather::Stanza::Iq::IBR.new.tap do |ibr|
87 ibr.phone = "+15551234567"
88 end,
89 "customer_customerid_low@component" =>
90 Blather::Stanza::Iq::IBR.new.tap do |ibr|
91 ibr.phone = "+15551234567"
92 end,
93 "customer_customerid_topup@component" =>
94 Blather::Stanza::Iq::IBR.new.tap do |ibr|
95 ibr.phone = "+15551234567"
96 end,
97 "customer_customerid_reach@component" =>
98 Blather::Stanza::Iq::IBR.new.tap do |ibr|
99 ibr.phone = "+15551234563"
100 end,
101 "customer_customerid_limit@component" =>
102 Blather::Stanza::Iq::IBR.new.tap do |ibr|
103 ibr.phone = "+15551234567"
104 end
105 }
106 )
107 )
108 )
109 Web.opts[:call_attempt_repo] = CallAttemptRepo.new(
110 redis: FakeRedis.new,
111 db: FakeDB.new(
112 ["test_usd", "+15557654321", :outbound] => [{ "rate" => 0.01 }],
113 ["test_usd", "+15557654321", :inbound] => [{ "rate" => 0.01 }],
114 ["test_usd", "+14445556666", :inbound] => [{ "rate" => 0.01 }],
115 ["test_usd", "+18001234567", :outbound] => [{ "rate" => 0.00 }],
116 ["customerid_limit"] => FakeDB::MultiResult.new(
117 [{ "a" => 1000 }],
118 [{ "settled_amount" => 15 }]
119 ),
120 ["customerid_low"] => FakeDB::MultiResult.new(
121 [{ "a" => 1000 }],
122 [{ "settled_amount" => 15 }]
123 ),
124 ["customerid_topup"] => FakeDB::MultiResult.new(
125 [{ "a" => 1000 }],
126 [{ "settled_amount" => 15 }]
127 )
128 )
129 )
130 Web.opts[:cdr_repo] = CDRRepo.new(db: FakeDB.new)
131 Web.opts[:common_logger] = FakeLog.new
132 Web.opts[:reachability_repo] = ReachabilityRepo::Voice.new(
133 redis: ReachableRedis,
134 senders: ["+14445556666"]
135 )
136 Web.instance_variable_set(:@outbound_transfers, { "bcall" => "oocall" })
137 Web.app
138 end
139
140 def test_outbound_forwards
141 post(
142 "/outbound/calls",
143 {
144 from: "ccustomerid",
145 to: "+15557654321",
146 callId: "acall"
147 }.to_json,
148 { "CONTENT_TYPE" => "application/json" }
149 )
150
151 assert last_response.ok?
152 assert_equal(
153 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
154 "<Transfer transferCallerId=\"+15551234567\">" \
155 "<PhoneNumber>+15557654321</PhoneNumber></Transfer></Response>",
156 last_response.body
157 )
158 end
159 em :test_outbound_forwards
160
161 def test_outbound_low_balance
162 ExpiringLock::REDIS.expect(
163 :set,
164 EMPromise.resolve(nil),
165 ["jmp_customer_low_balance-customerid_low", Time, "EX", 604800, "NX"]
166 )
167
168 post(
169 "/outbound/calls",
170 {
171 from: "ccustomerid_low",
172 to: "+15557654321",
173 callId: "acall"
174 }.to_json,
175 { "CONTENT_TYPE" => "application/json" }
176 )
177
178 assert last_response.ok?
179 assert_equal(
180 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
181 "<SpeakSentence>Your balance of $0.01 is not enough to " \
182 "complete this call.</SpeakSentence></Response>",
183 last_response.body
184 )
185 assert_mock ExpiringLock::REDIS
186 end
187 em :test_outbound_low_balance
188
189 def test_outbound_low_balance_top_up
190 LowBalance::AutoTopUp::CreditCardSale.expect(
191 :create,
192 EMPromise.resolve(
193 OpenStruct.new(total: 15)
194 ),
195 [Customer], amount: 15
196 )
197
198 ExpiringLock::REDIS.expect(
199 :set,
200 EMPromise.resolve("OK"),
201 ["jmp_customer_low_balance-customerid_topup", Time, "EX", 604800, "NX"]
202 )
203
204 CustomerFinancials::REDIS.expect(
205 :smembers,
206 EMPromise.resolve([]),
207 ["block_credit_cards"]
208 )
209 LowBalance::AutoTopUp::REDIS.expect(
210 :exists,
211 0,
212 ["jmp_auto_top_up_block-abcd"]
213 )
214 braintree_customer = Minitest::Mock.new
215 CustomerFinancials::BRAINTREE.expect(:customer, braintree_customer)
216 payment_methods = OpenStruct.new(payment_methods: [
217 OpenStruct.new(default?: true, unique_number_identifier: "abcd")
218 ])
219 braintree_customer.expect(
220 :find,
221 EMPromise.resolve(payment_methods),
222 ["customerid_topup"]
223 )
224
225 Customer::BLATHER.expect(
226 :<<,
227 nil,
228 [Blather::Stanza]
229 )
230
231 post(
232 "/outbound/calls",
233 {
234 from: "ccustomerid_topup",
235 to: "+15557654321",
236 callId: "acall"
237 }.to_json,
238 { "CONTENT_TYPE" => "application/json" }
239 )
240
241 assert last_response.ok?
242 assert_equal(
243 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
244 "<Transfer transferCallerId=\"+15551234567\">" \
245 "<PhoneNumber>+15557654321</PhoneNumber></Transfer></Response>",
246 last_response.body
247 )
248 assert_mock ExpiringLock::REDIS
249 assert_mock Customer::BLATHER
250 assert_mock LowBalance::AutoTopUp::CreditCardSale
251 end
252 em :test_outbound_low_balance_top_up
253
254 def test_outbound_unsupported
255 post(
256 "/outbound/calls",
257 {
258 from: "ccustomerid_limit",
259 to: "+95557654321",
260 callId: "acall"
261 }.to_json,
262 { "CONTENT_TYPE" => "application/json" }
263 )
264
265 assert last_response.ok?
266 assert_equal(
267 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
268 "<SpeakSentence>The number you have dialled is not " \
269 "supported on your account.</SpeakSentence></Response>",
270 last_response.body
271 )
272 end
273 em :test_outbound_unsupported
274
275 def test_outbound_atlimit
276 post(
277 "/outbound/calls",
278 {
279 from: "ccustomerid_limit",
280 to: "+15557654321",
281 callId: "acall"
282 }.to_json,
283 { "CONTENT_TYPE" => "application/json" }
284 )
285
286 assert last_response.ok?
287 assert_equal(
288 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
289 "<Gather gatherUrl=\"\/outbound/calls\" maxDigits=\"1\" " \
290 "repeatCount=\"3\"><SpeakSentence>This call will take you over " \
291 "your configured monthly overage limit.</SpeakSentence><SpeakSentence>" \
292 "Change your limit in your account settings or press 1 to accept the " \
293 "charges. You can hang up to cancel.</SpeakSentence></Gather></Response>",
294 last_response.body
295 )
296 end
297 em :test_outbound_atlimit
298
299 def test_outbound_no_customer
300 post(
301 "/outbound/calls",
302 {
303 from: "no_such_customer",
304 to: "+15557654321",
305 callId: "acall"
306 }.to_json,
307 { "CONTENT_TYPE" => "application/json" }
308 )
309
310 assert last_response.ok?
311 assert_equal(
312 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
313 "<SpeakSentence>Your credentials are invalid, please contact support." \
314 "</SpeakSentence></Response>",
315 last_response.body
316 )
317 end
318 em :test_outbound_no_customer
319
320 def test_outbound_atlimit_digits
321 post(
322 "/outbound/calls",
323 {
324 from: "ccustomerid_limit",
325 to: "+15557654321",
326 callId: "acall",
327 digits: "1"
328 }.to_json,
329 { "CONTENT_TYPE" => "application/json" }
330 )
331
332 assert last_response.ok?
333 assert_equal(
334 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
335 "<Transfer transferCallerId=\"+15551234567\">" \
336 "<PhoneNumber>+15557654321</PhoneNumber></Transfer></Response>",
337 last_response.body
338 )
339 end
340 em :test_outbound_atlimit_digits
341
342 def test_outbound_toll_free
343 post(
344 "/outbound/calls",
345 {
346 from: "ccustomerid",
347 to: "+18001234567",
348 callId: "acall"
349 }.to_json,
350 { "CONTENT_TYPE" => "application/json" }
351 )
352
353 assert last_response.ok?
354 assert_equal(
355 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
356 "<Transfer transferCallerId=\"+15551234567\">" \
357 "<PhoneNumber>+18001234567</PhoneNumber></Transfer></Response>",
358 last_response.body
359 )
360 end
361 em :test_outbound_toll_free
362
363 def test_outbound_disconnect
364 post(
365 "/outbound/calls/status",
366 {
367 eventType: "disconnect",
368 from: "ccustomerid",
369 to: "+15557654321",
370 callId: "acall",
371 startTime: Time.now.to_s,
372 endTime: Time.now.to_s,
373 cause: "hangup"
374 }.to_json,
375 { "CONTENT_TYPE" => "application/json" }
376 )
377
378 assert last_response.ok?
379 assert_equal("OK", last_response.body)
380 end
381 em :test_outbound_disconnect
382
383 def test_inbound
384 CustomerFwd::BANDWIDTH_VOICE.expect(
385 :create_call,
386 OpenStruct.new(data: OpenStruct.new(call_id: "ocall")),
387 ["test_bw_account"],
388 body: Matching.new do |arg|
389 assert_equal(
390 "http://example.org/inbound/calls/acall?customer_id=customerid",
391 arg.answer_url
392 )
393 end
394 )
395
396 post(
397 "/inbound/calls",
398 {
399 from: "+15557654321",
400 to: "+15551234567",
401 callId: "acall"
402 }.to_json,
403 { "CONTENT_TYPE" => "application/json" }
404 )
405
406 assert last_response.ok?
407 assert_equal(
408 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
409 "<Ring answerCall=\"false\" duration=\"300\" />" \
410 "</Response>",
411 last_response.body
412 )
413 assert_mock CustomerFwd::BANDWIDTH_VOICE
414 end
415 em :test_inbound
416
417 def test_inbound_from_reachability
418 CustomerFwd::BANDWIDTH_VOICE.expect(
419 :create_call,
420 OpenStruct.new(data: OpenStruct.new(call_id: "ocall")),
421 ["test_bw_account"],
422 body: Matching.new do |arg|
423 assert_equal(
424 "http://example.org/inbound/calls/acall?customer_id=customerid",
425 arg.answer_url
426 )
427 end
428 )
429
430 ReachableRedis.expect(
431 :exists,
432 EMPromise.resolve(0),
433 ["jmp_customer_reachability_voice-customerid"]
434 )
435
436 post(
437 "/inbound/calls",
438 {
439 from: "+14445556666",
440 to: "+15551234567",
441 callId: "acall"
442 }.to_json,
443 { "CONTENT_TYPE" => "application/json" }
444 )
445
446 assert last_response.ok?
447 assert_equal(
448 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
449 "<Ring answerCall=\"false\" duration=\"300\" />" \
450 "</Response>",
451 last_response.body
452 )
453 assert_mock CustomerFwd::BANDWIDTH_VOICE
454 assert_mock ReachableRedis
455 end
456 em :test_inbound_from_reachability
457
458 def test_inbound_no_bwmsgsv2
459 CustomerFwd::BANDWIDTH_VOICE.expect(
460 :create_call,
461 OpenStruct.new(data: OpenStruct.new(call_id: "ocall")),
462 ["test_bw_account"],
463 body: Matching.new do |arg|
464 assert_equal(
465 "http://example.org/inbound/calls/acall?customer_id=customerid2",
466 arg.answer_url
467 )
468 end
469 )
470
471 post(
472 "/inbound/calls",
473 {
474 from: "+15557654321",
475 to: "+15551230000",
476 callId: "acall"
477 }.to_json,
478 { "CONTENT_TYPE" => "application/json" }
479 )
480
481 assert last_response.ok?
482 assert_equal(
483 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
484 "<Ring answerCall=\"false\" duration=\"300\" />" \
485 "</Response>",
486 last_response.body
487 )
488 assert_mock CustomerFwd::BANDWIDTH_VOICE
489 end
490 em :test_inbound_no_bwmsgsv2
491
492 def test_inbound_low
493 ExpiringLock::REDIS.expect(
494 :set,
495 EMPromise.resolve(nil),
496 ["jmp_customer_low_balance-customerid_low", Time, "EX", 604800, "NX"]
497 )
498
499 post(
500 "/inbound/calls",
501 {
502 from: "+15557654321",
503 to: "+15551234560",
504 callId: "acall"
505 }.to_json,
506 { "CONTENT_TYPE" => "application/json" }
507 )
508
509 assert last_response.ok?
510 assert_equal(
511 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
512 "<Redirect redirectUrl=\"/inbound/calls/acall/voicemail\" />" \
513 "</Response>",
514 last_response.body
515 )
516 assert_mock CustomerFwd::BANDWIDTH_VOICE
517 assert_mock ExpiringLock::REDIS
518 end
519 em :test_inbound_low
520
521 def test_inbound_leg2
522 post(
523 "/inbound/calls/acall?customer_id=customerid",
524 {
525 from: "+15557654321",
526 to: "sip:boop@example.com",
527 callId: "ocall"
528 }.to_json,
529 { "CONTENT_TYPE" => "application/json" }
530 )
531
532 assert last_response.ok?
533 assert_equal(
534 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
535 "<Tag>connected</Tag><Bridge>acall</Bridge>" \
536 "</Response>",
537 last_response.body
538 )
539 end
540 em :test_inbound_leg2
541
542 def test_inbound_limit_leg2
543 path = "/inbound/calls/acall?customer_id=customerid_limit"
544
545 post(
546 path,
547 {
548 from: "+15557654321",
549 to: "sip:boop@example.com",
550 callId: "ocall"
551 }.to_json,
552 { "CONTENT_TYPE" => "application/json" }
553 )
554
555 assert last_response.ok?
556 assert_equal(
557 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
558 "<Gather gatherUrl=\"#{path}\" maxDigits=\"1\" " \
559 "repeatCount=\"3\"><SpeakSentence>This call will take you over " \
560 "your configured monthly overage limit.</SpeakSentence><SpeakSentence>" \
561 "Change your limit in your account settings or press 1 to accept the " \
562 "charges. You can hang up to send the caller to voicemail." \
563 "</SpeakSentence></Gather></Response>",
564 last_response.body
565 )
566 end
567 em :test_inbound_limit_leg2
568
569 def test_inbound_limit_digits_leg2
570 post(
571 "/inbound/calls/acall?customer_id=customerid_limit",
572 {
573 from: "+15557654321",
574 to: "sip:boop@example.com",
575 callId: "ocall",
576 digits: "1"
577 }.to_json,
578 { "CONTENT_TYPE" => "application/json" }
579 )
580
581 assert last_response.ok?
582 assert_equal(
583 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
584 "<Tag>connected</Tag><Bridge>acall</Bridge>" \
585 "</Response>",
586 last_response.body
587 )
588 end
589 em :test_inbound_limit_digits_leg2
590
591 def test_inbound_limit_hangup
592 Web::BANDWIDTH_VOICE.expect(
593 :modify_call,
594 nil,
595 [
596 "test_bw_account",
597 "bcall"
598 ],
599 body: Matching.new do |arg|
600 assert_equal(
601 "http://example.org/inbound/calls/oocall/voicemail",
602 arg.redirect_url
603 )
604 end
605 )
606
607 post(
608 "/inbound/calls/bcall/transfer_complete",
609 {
610 from: "+15557654321",
611 to: "+15551234561",
612 callId: "oocall",
613 cause: "hangup"
614 }.to_json,
615 { "CONTENT_TYPE" => "application/json" }
616 )
617
618 assert last_response.ok?
619 assert_mock Web::BANDWIDTH_VOICE
620 end
621 em :test_inbound_limit_hangup
622
623 def test_voicemail
624 language_id = stub_request(:post, "https://api.rev.ai/languageid/v1/jobs")
625 .with(body: {
626 metadata: {
627 media_url: "https://jmp.chat/media",
628 from_jid: "+15557654321@component",
629 customer_id: "customerid"
630 }.to_json,
631 source_config: {
632 url: "https://jmp.chat/media"
633 },
634 notification_config: {
635 url: "http://example.org/inbound/calls/CALLID/voicemail/language_id"
636 }
637 }.to_json)
638
639 Customer::BLATHER.expect(
640 :<<,
641 nil,
642 [Matching.new do |stanza|
643 assert_equal "+15557654321@component", stanza.from.to_s
644 assert_equal "customer@example.com", stanza.to.to_s
645 assert_equal "https://jmp.chat/media", OOB.find_or_create(stanza).url
646 end]
647 )
648
649 post(
650 "/inbound/calls/CALLID/voicemail/audio",
651 {
652 "startTime" => "2021-01-01T00:00:00Z",
653 "endTime" => "2021-01-01T00:00:06Z",
654 "mediaUrl" => "https://voice.bandwidth.com/api/v2/accounts/1/media",
655 "to" => "+15551234567",
656 "from" => "+15557654321"
657 }.to_json,
658 { "CONTENT_TYPE" => "application/json" }
659 )
660
661 assert last_response.ok?
662 assert_mock Customer::BLATHER
663 assert_requested language_id
664 end
665 em :test_voicemail
666
667 def test_anonymous_voicemail
668 language_id = stub_request(:post, "https://api.rev.ai/languageid/v1/jobs")
669 .with(body: {
670 metadata: {
671 media_url: "https://jmp.chat/media",
672 from_jid:
673 "16;phone-context=anonymous.phone-context.soprani.ca@component",
674 customer_id: "customerid"
675 }.to_json,
676 source_config: {
677 url: "https://jmp.chat/media"
678 },
679 notification_config: {
680 url: "http://example.org/inbound/calls/CALLID/voicemail/language_id"
681 }
682 }.to_json)
683
684 Customer::BLATHER.expect(
685 :<<,
686 nil,
687 [Matching.new do |stanza|
688 assert_equal(
689 "16;phone-context=anonymous.phone-context.soprani.ca@component",
690 stanza.from.to_s
691 )
692 assert_equal "customer@example.com", stanza.to.to_s
693 assert_equal "https://jmp.chat/media", OOB.find_or_create(stanza).url
694 end]
695 )
696
697 post(
698 "/inbound/calls/CALLID/voicemail/audio",
699 {
700 "startTime" => "2021-01-01T00:00:00Z",
701 "endTime" => "2021-01-01T00:00:06Z",
702 "mediaUrl" => "https://voice.bandwidth.com/api/v2/accounts/1/media",
703 "to" => "+15551234567",
704 "from" => "Anonymous"
705 }.to_json,
706 { "CONTENT_TYPE" => "application/json" }
707 )
708
709 assert last_response.ok?
710 assert_mock Customer::BLATHER
711 assert_requested language_id
712 end
713 em :test_anonymous_voicemail
714
715 def test_voicemail_short
716 post(
717 "/inbound/calls/CALLID/voicemail/audio",
718 {
719 "startTime" => "2021-01-01T00:00:00Z",
720 "endTime" => "2021-01-01T00:00:05Z"
721 }.to_json,
722 { "CONTENT_TYPE" => "application/json" }
723 )
724
725 assert last_response.ok?
726 assert_mock Customer::BLATHER
727 end
728 em :test_voicemail_short
729
730 def test_voicemail_no_customer
731 post(
732 "/inbound/calls/CALLID/voicemail",
733 {
734 "startTime" => "2021-01-01T00:00:00Z",
735 "endTime" => "2021-01-01T00:00:06Z",
736 "mediaUrl" => "https://voice.bandwidth.com/api/v2/accounts/1/media",
737 "to" => "+15551200000",
738 "from" => "+15557654321"
739 }.to_json,
740 { "CONTENT_TYPE" => "application/json" }
741 )
742
743 assert last_response.ok?
744 assert_equal(
745 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
746 "<SpeakSentence>The number you have dialled is not in service." \
747 "</SpeakSentence></Response>",
748 last_response.body
749 )
750 end
751 em :test_voicemail_no_customer
752
753 def test_inbound_from_reachability_during_reachability
754 ReachableRedis.expect(
755 :exists,
756 EMPromise.resolve(1),
757 ["jmp_customer_reachability_voice-customerid_reach"]
758 )
759 ReachableRedis.expect(
760 :incr,
761 EMPromise.resolve(1),
762 ["jmp_customer_reachability_voice-customerid_reach"]
763 )
764
765 post(
766 "/inbound/calls",
767 {
768 from: "+14445556666",
769 to: "+15551234563",
770 callId: "acall"
771 }.to_json,
772 { "CONTENT_TYPE" => "application/json" }
773 )
774
775 assert last_response.ok?
776 assert_equal(
777 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
778 "<Hangup />" \
779 "</Response>",
780 last_response.body
781 )
782 assert_mock CustomerFwd::BANDWIDTH_VOICE
783 assert_mock ReachableRedis
784 end
785 em :test_inbound_from_reachability_during_reachability
786end