test_web.rb

  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