1# frozen_string_literal: true
2
3require "rack/test"
4require "test_helper"
5require_relative "../web"
6
7Customer::BLATHER = Minitest::Mock.new
8
9class WebTest < Minitest::Test
10 include Rack::Test::Methods
11
12 def app
13 Web.opts[:customer_repo] = CustomerRepo.new(
14 redis: FakeRedis.new(
15 "jmp_customer_jid-customerid" => "customer@example.com",
16 "catapult_jid-+15551234567" => "customer_customerid@component",
17 "jmp_customer_jid-customerid_low" => "customer@example.com",
18 "jmp_customer_jid-customerid_limit" => "customer@example.com"
19 ),
20 db: FakeDB.new(
21 ["customerid"] => [{
22 "balance" => BigDecimal(10),
23 "plan_name" => "test_usd",
24 "expires_at" => Time.now + 100
25 }],
26 ["customerid_low"] => [{
27 "balance" => BigDecimal("0.01"),
28 "plan_name" => "test_usd",
29 "expires_at" => Time.now + 100
30 }],
31 ["customerid_limit"] => [{
32 "balance" => BigDecimal(10),
33 "plan_name" => "test_usd",
34 "expires_at" => Time.now + 100
35 }]
36 ),
37 sgx_repo: Bwmsgsv2Repo.new(
38 redis: FakeRedis.new,
39 ibr_repo: FakeIBRRepo.new(
40 "sgx" => {
41 "customer_customerid@component" => IBR.new.tap do |ibr|
42 ibr.phone = "+15551234567"
43 end,
44 "customer_customerid_limit@component" => IBR.new.tap do |ibr|
45 ibr.phone = "+15551234567"
46 end
47 }
48 )
49 )
50 )
51 Web.opts[:call_attempt_repo] = CallAttemptRepo.new(
52 db: FakeDB.new(
53 ["test_usd", "+15557654321", :outbound] => [{ "rate" => 0.01 }],
54 ["customerid_limit"] => [{ "a" => -1000 }],
55 ["customerid_low"] => [{ "a" => -1000 }]
56 )
57 )
58 Web.app
59 end
60
61 def test_outbound_forwards
62 post(
63 "/outbound/calls",
64 { from: "customerid", to: "+15557654321" }.to_json,
65 { "CONTENT_TYPE" => "application/json" }
66 )
67
68 assert last_response.ok?
69 assert_equal(
70 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
71 "<Forward from=\"+15551234567\" to=\"+15557654321\" />" \
72 "</Response>",
73 last_response.body
74 )
75 end
76 em :test_outbound_forwards
77
78 def test_outbound_low_balance
79 post(
80 "/outbound/calls",
81 { from: "customerid_low", to: "+15557654321" }.to_json,
82 { "CONTENT_TYPE" => "application/json" }
83 )
84
85 assert last_response.ok?
86 assert_equal(
87 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
88 "<SpeakSentence>Your balance of $0.01 is not enough to " \
89 "complete this call.</SpeakSentence></Response>",
90 last_response.body
91 )
92 end
93 em :test_outbound_low_balance
94
95 def test_outbound_unsupported
96 post(
97 "/outbound/calls",
98 { from: "customerid", to: "+95557654321" }.to_json,
99 { "CONTENT_TYPE" => "application/json" }
100 )
101
102 assert last_response.ok?
103 assert_equal(
104 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
105 "<SpeakSentence>The number you have dialled is not " \
106 "supported on your account.</SpeakSentence></Response>",
107 last_response.body
108 )
109 end
110 em :test_outbound_unsupported
111
112 def test_outbound_atlimit
113 post(
114 "/outbound/calls",
115 { from: "customerid_limit", to: "+15557654321" }.to_json,
116 { "CONTENT_TYPE" => "application/json" }
117 )
118
119 assert last_response.ok?
120 assert_equal(
121 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
122 "<Gather gatherUrl=\"\/outbound/calls\" maxDigits=\"1\" " \
123 "repeatCount=\"3\"><SpeakSentence>This call will take you over " \
124 "your configured monthly overage limit.</SpeakSentence><SpeakSentence>" \
125 "Change your limit in your account settings or press 1 to accept the " \
126 "charges. You can hang up to cancel.</SpeakSentence></Gather></Response>",
127 last_response.body
128 )
129 end
130 em :test_outbound_atlimit
131
132 def test_outbound_atlimit_digits
133 post(
134 "/outbound/calls",
135 { from: "customerid_limit", to: "+15557654321", digits: "1" }.to_json,
136 { "CONTENT_TYPE" => "application/json" }
137 )
138
139 assert last_response.ok?
140 assert_equal(
141 "<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
142 "<Forward from=\"+15551234567\" to=\"+15557654321\" />" \
143 "</Response>",
144 last_response.body
145 )
146 end
147 em :test_outbound_atlimit_digits
148
149 def test_voicemail
150 Customer::BLATHER.expect(
151 :<<,
152 nil,
153 [Matching.new do |stanza|
154 assert_equal "+15557654321@component", stanza.from.to_s
155 assert_equal "customer@example.com", stanza.to.to_s
156 assert_equal "https://jmp.chat/media", OOB.find_or_create(stanza).url
157 end]
158 )
159
160 post(
161 "/inbound/calls/CALLID/voicemail/audio",
162 {
163 "startTime" => "2021-01-01T00:00:00Z",
164 "endTime" => "2021-01-01T00:00:06Z",
165 "mediaUrl" => "https://voice.bandwidth.com/api/v2/accounts/1/media",
166 "to" => "+15551234567",
167 "from" => "+15557654321"
168 }.to_json,
169 { "CONTENT_TYPE" => "application/json" }
170 )
171
172 assert last_response.ok?
173 assert_mock Customer::BLATHER
174 end
175 em :test_voicemail
176
177 def test_anonymous_voicemail
178 Customer::BLATHER.expect(
179 :<<,
180 nil,
181 [Matching.new do |stanza|
182 assert_equal(
183 "16;phone-context=anonymous.phone-context.soprani.ca@component",
184 stanza.from.to_s
185 )
186 assert_equal "customer@example.com", stanza.to.to_s
187 assert_equal "https://jmp.chat/media", OOB.find_or_create(stanza).url
188 end]
189 )
190
191 post(
192 "/inbound/calls/CALLID/voicemail/audio",
193 {
194 "startTime" => "2021-01-01T00:00:00Z",
195 "endTime" => "2021-01-01T00:00:06Z",
196 "mediaUrl" => "https://voice.bandwidth.com/api/v2/accounts/1/media",
197 "to" => "+15551234567",
198 "from" => "Anonymous"
199 }.to_json,
200 { "CONTENT_TYPE" => "application/json" }
201 )
202
203 assert last_response.ok?
204 assert_mock Customer::BLATHER
205 end
206 em :test_anonymous_voicemail
207
208 def test_voicemail_short
209 post(
210 "/inbound/calls/CALLID/voicemail/audio",
211 {
212 "startTime" => "2021-01-01T00:00:00Z",
213 "endTime" => "2021-01-01T00:00:05Z"
214 }.to_json,
215 { "CONTENT_TYPE" => "application/json" }
216 )
217
218 assert last_response.ok?
219 assert_mock Customer::BLATHER
220 end
221 em :test_voicemail_short
222end