~singpolyma/sgx-jmp

cea1bbe900f4393999e68aa23562696001badbfa — Stephen Paul Weber 3 months ago 0874c1b
Initial tests for web routes
4 files changed, 136 insertions(+), 2 deletions(-)

M Gemfile
M test/test_helper.rb
A test/test_web.rb
M web.rb
M Gemfile => Gemfile +1 -0
@@ 35,6 35,7 @@ end

group(:test) do
	gem "minitest"
	gem "rack-test"
	gem "rake"
	gem "rantly"
	gem "rubocop", "= 0.89.1"

M test/test_helper.rb => test/test_helper.rb +11 -1
@@ 196,7 196,7 @@ class FakeRedis
end

class FakeDB
	def initialize(items)
	def initialize(items={})
		@items = items
	end



@@ 205,6 205,16 @@ class FakeDB
	end
end

class FakeIBRRepo
	def initialize(registrations={})
		@registrations = registrations
	end

	def registered?(jid, from:)
		@registrations.dig(jid.to_s, from.to_s) || false
	end
end

module EventMachine
	class << self
		# Patch EM.add_timer to be instant in tests

A test/test_web.rb => test/test_web.rb +123 -0
@@ 0,0 1,123 @@
# frozen_string_literal: true

require "rack/test"
require "test_helper"
require_relative "../web"

Customer::BLATHER = Minitest::Mock.new

class WebTest < Minitest::Test
	include Rack::Test::Methods

	def app
		Web.opts[:customer_repo] = CustomerRepo.new(
			redis: FakeRedis.new(
				"jmp_customer_jid-customerid" => "customer@example.com",
				"catapult_jid-+15551234567" => "customer_customerid@component"
			),
			db: FakeDB.new,
			sgx_repo: Bwmsgsv2Repo.new(
				redis: FakeRedis.new,
				ibr_repo: FakeIBRRepo.new(
					"sgx" => {
						"customer_customerid@component" => IBR.new.tap do |ibr|
							ibr.phone = "+15551234567"
						end
					}
				)
			)
		)
		Web.app
	end

	def test_outbound_forwards
		post(
			"/outbound/calls",
			{ from: "customerid", to: "+15557654321" }.to_json,
			{ "CONTENT_TYPE" => "application/json" }
		)

		assert last_response.ok?
		assert_equal(
			"<?xml version=\"1.0\" encoding=\"utf-8\" ?><Response>" \
			"<Forward from=\"+15551234567\" to=\"+15557654321\" />" \
			"</Response>",
			last_response.body
		)
	end
	em :test_outbound_forwards

	def test_voicemail
		Customer::BLATHER.expect(
			:<<,
			nil,
			[Matching.new do |stanza|
				assert_equal "+15557654321@component", stanza.from.to_s
				assert_equal "customer@example.com", stanza.to.to_s
				assert_equal "https://jmp.chat/media", OOB.find_or_create(stanza).url
			end]
		)

		post(
			"/inbound/calls/CALLID/voicemail/audio",
			{
				"startTime" => "2021-01-01T00:00:00Z",
				"endTime" => "2021-01-01T00:00:06Z",
				"mediaUrl" => "https://voice.bandwidth.com/api/v2/accounts/1/media",
				"to" => "+15551234567",
				"from" => "+15557654321"
			}.to_json,
			{ "CONTENT_TYPE" => "application/json" }
		)

		assert last_response.ok?
		assert_mock Customer::BLATHER
	end
	em :test_voicemail

	def test_anonymous_voicemail
		Customer::BLATHER.expect(
			:<<,
			nil,
			[Matching.new do |stanza|
				assert_equal(
					"16;phone-context=anonymous.phone-context.soprani.ca@component",
					stanza.from.to_s
				)
				assert_equal "customer@example.com", stanza.to.to_s
				assert_equal "https://jmp.chat/media", OOB.find_or_create(stanza).url
			end]
		)

		post(
			"/inbound/calls/CALLID/voicemail/audio",
			{
				"startTime" => "2021-01-01T00:00:00Z",
				"endTime" => "2021-01-01T00:00:06Z",
				"mediaUrl" => "https://voice.bandwidth.com/api/v2/accounts/1/media",
				"to" => "+15551234567",
				"from" => "Anonymous"
			}.to_json,
			{ "CONTENT_TYPE" => "application/json" }
		)

		assert last_response.ok?
		assert_mock Customer::BLATHER
	end
	em :test_anonymous_voicemail

	def test_voicemail_short
		post(
			"/inbound/calls/CALLID/voicemail/audio",
			{
				"startTime" => "2021-01-01T00:00:00Z",
				"endTime" => "2021-01-01T00:00:05Z"
			}.to_json,
			{ "CONTENT_TYPE" => "application/json" }
		)

		assert last_response.ok?
		assert_mock Customer::BLATHER
	end
	em :test_voicemail_short
end

M web.rb => web.rb +1 -1
@@ 46,7 46,7 @@ end

# rubocop:disable Metrics/ClassLength
class Web < Roda
	use Rack::Fiber # Must go first!
	use Rack::Fiber unless ENV["ENV"] == "test" # Must go first!
	use Sentry::Rack::CaptureExceptions
	plugin :json_parser
	plugin :public