# test_integration.rb # # A simple integration test against Bandwidth's APIs require 'test/unit' require 'securerandom' require_relative '../../lib/bandwidth.rb' include Bandwidth include Bandwidth::Voice include Bandwidth::Messaging include Bandwidth::MultiFactorAuth include Bandwidth::WebRtc begin BW_USERNAME = ENV.fetch("BW_USERNAME") BW_PASSWORD = ENV.fetch("BW_PASSWORD") BW_ACCOUNT_ID = ENV.fetch("BW_ACCOUNT_ID") BW_VOICE_APPLICATION_ID = ENV.fetch("BW_VOICE_APPLICATION_ID") BW_MESSAGING_APPLICATION_ID = ENV.fetch("BW_MESSAGING_APPLICATION_ID") BASE_CALLBACK_URL = ENV.fetch("BASE_CALLBACK_URL") BW_NUMBER = ENV.fetch("BW_NUMBER") USER_NUMBER = ENV.fetch("USER_NUMBER") rescue puts "Environmental variables not found" exit(-1) end class IntegrationTest < Test::Unit::TestCase def setup @bandwidth_client = Bandwidth::Client.new( voice_basic_auth_user_name: BW_USERNAME, voice_basic_auth_password: BW_PASSWORD, messaging_basic_auth_user_name: BW_USERNAME, messaging_basic_auth_password: BW_PASSWORD, multi_factor_auth_basic_auth_user_name: BW_USERNAME, multi_factor_auth_basic_auth_password: BW_PASSWORD, phone_number_lookup_basic_auth_user_name: BW_USERNAME, phone_number_lookup_basic_auth_password: BW_PASSWORD ) @bandwidth_client_invalid_auth = Bandwidth::Client.new( voice_basic_auth_user_name: "bad_username", voice_basic_auth_password: "bad_password", messaging_basic_auth_user_name: "bad_username", messaging_basic_auth_password: "bad_password", multi_factor_auth_basic_auth_user_name: "bad_username", multi_factor_auth_basic_auth_password: "bad_password", phone_number_lookup_basic_auth_user_name: "bad_username", phone_number_lookup_basic_auth_password: "bad_password" ) end def test_create_message body = MessageRequest.new body.application_id = BW_MESSAGING_APPLICATION_ID body.to = [USER_NUMBER] body.from = BW_NUMBER body.text = "Ruby Integration" response = @bandwidth_client.messaging_client.client.create_message(BW_ACCOUNT_ID, body) assert(response.data.id.length > 0, "id value not set") #validate that _some_ id was returned end def test_create_message_invalid_phone_number body = MessageRequest.new body.application_id = BW_MESSAGING_APPLICATION_ID body.to = ["+1invalid"] body.from = BW_NUMBER body.text = "Ruby Integration" begin @bandwidth_client.messaging_client.client.create_message(BW_ACCOUNT_ID, body) #workaround to make sure that if the above error is not raised, the build will fail assert(false, "Expected exception not raised") rescue MessagingException => e assert(e.description.length > 0, "description value not set") end end def test_upload_download_media #define constants for upload media and download media media_id = "text-media-id-" + SecureRandom.uuid media = "Hello world" #media upload @bandwidth_client.messaging_client.client.upload_media(BW_ACCOUNT_ID, media_id, media, :content_type => "application/octet-stream", :cache_control => "no-cache") #media download downloaded_media = @bandwidth_client.messaging_client.client.get_media(BW_ACCOUNT_ID, media_id).data assert_equal(downloaded_media, media, "Downloaded media file not equal to upload") end def test_get_message # Send a successful request to the GET messages API response = @bandwidth_client.messaging_client.client.get_messages(BW_ACCOUNT_ID, :message_id => "abc123") assert_equal(response.status_code, 200, "API did not return a 200 OK") end def test_get_message_invalid_auth # Send an unsuccessful request to the GET messages API assert_raise MessagingException do response = @bandwidth_client_invalid_auth.messaging_client.client.get_messages(BW_ACCOUNT_ID) end end def test_create_call_and_get_call_state body = CreateCallRequest.new body.from = BW_NUMBER body.to = USER_NUMBER body.application_id = BW_VOICE_APPLICATION_ID body.answer_url = BASE_CALLBACK_URL response = @bandwidth_client.voice_client.client.create_call(BW_ACCOUNT_ID, body) assert(response.data.call_id.length > 0, "call_id value not set") assert_not_nil(response.data.enqueued_time, "enqueued time is nil") assert(response.data.enqueued_time.is_a?(DateTime), "enqueued time is not a DateTime object") #Get phone call information sleep 1 response = @bandwidth_client.voice_client.client.get_call(BW_ACCOUNT_ID, response.data.call_id) assert(response.data.state.length > 0, "state value not set") assert_not_nil(response.data.enqueued_time, "enqueued time is nil") assert(response.data.enqueued_time.is_a?(DateTime), "enqueued time is not a DateTime object") end def test_create_call_with_amd_and_get_call_state machine_detection = MachineDetectionConfiguration.new machine_detection.mode = 'async' machine_detection.detection_timeout = 5.0 machine_detection.silence_timeout = 5.0 machine_detection.speech_threshold = 5.0 machine_detection.speech_end_threshold = 5.0 machine_detection.delay_result = true machine_detection.callback_url = BASE_CALLBACK_URL + '/machineDetection' machine_detection.callback_method = 'POST' machine_detection.machine_speech_end_threshold = 3.2 body = CreateCallRequest.new body.from = BW_NUMBER body.to = USER_NUMBER body.application_id = BW_VOICE_APPLICATION_ID body.answer_url = BASE_CALLBACK_URL body.machine_detection = machine_detection response = @bandwidth_client.voice_client.client.create_call(BW_ACCOUNT_ID, body) assert(response.data.call_id.length > 0, "call_id value not set") #Get phone call information response = @bandwidth_client.voice_client.client.get_call(BW_ACCOUNT_ID, response.data.call_id) assert(response.data.state.length > 0, "state value not set") end def test_create_call_with_priority body = CreateCallRequest.new body.from = BW_NUMBER body.to = USER_NUMBER body.application_id = BW_VOICE_APPLICATION_ID body.answer_url = BASE_CALLBACK_URL body.priority = 1 response = @bandwidth_client.voice_client.client.create_call(BW_ACCOUNT_ID, body) assert(response.data.call_id.length > 0, "call_id value not set") assert(response.data.priority == 1, "priority not set") end def test_create_call_invalid_phone_number body = CreateCallRequest.new body.from = BW_NUMBER body.to = "+1invalid" body.application_id = BW_VOICE_APPLICATION_ID body.answer_url = BASE_CALLBACK_URL begin @bandwidth_client.voice_client.client.create_call(BW_ACCOUNT_ID, :body => body) #workaround to make sure that if the above error is not raised, the build will fail assert(false, "Expected exception not raised") rescue ApiErrorException => e assert(e.description.length > 0, "description value not set") end end def test_forward forward = Bandwidth::Voice::Forward.new({ :to => "+15554443333", :from => "+13334445555", :call_timeout => 25, :diversion_treatment => "none", :diversion_reason => "away" }) response = Bandwidth::Voice::Response.new() response.push(forward) expected = '' actual = response.to_bxml() assert_equal(expected, actual) end def test_gather gather = Bandwidth::Voice::Gather.new({ :gather_url => "https://test.com", :gather_method => "POST", :username => "user", :password => "pass", :tag => "tag", :terminating_digits => "#", :max_digits => 3, :inter_digit_timeout => 5, :first_digit_timeout => "10", :repeat_count => 1, :gather_fallback_url => "https://test.com", :gather_fallback_method => "GET", :fallback_username => "fuser", :fallback_password => "fpass" }) response = Bandwidth::Voice::Response.new() response.push(gather) expected = '' actual = response.to_bxml() assert_equal(expected, actual) end def test_gather_nested_speak_sentence speak_sentence = Bandwidth::Voice::SpeakSentence.new({ :sentence => "test" }) gather = Bandwidth::Voice::Gather.new({ :speak_sentence => speak_sentence }) response = Bandwidth::Voice::Response.new() response.push(gather) expected = 'test' actual = response.to_bxml() assert_equal(expected, actual) end def test_gather_nested_play_audio play_audio = Bandwidth::Voice::PlayAudio.new({ :url => "https://test.com" }) gather = Bandwidth::Voice::Gather.new({ :play_audio => play_audio }) response = Bandwidth::Voice::Response.new() response.push(gather) expected = 'https://test.com' actual = response.to_bxml() assert_equal(expected, actual) end def test_gather_multiple_nested_verbs play_audio = Bandwidth::Voice::PlayAudio.new({ :url => "https://test.com" }) speak_sentence = Bandwidth::Voice::SpeakSentence.new({ :sentence => "test" }) gather = Bandwidth::Voice::Gather.new({ :nested_verbs => [play_audio, speak_sentence] }) response = Bandwidth::Voice::Response.new() response.push(gather) expected = 'https://test.comtest' actual = response.to_bxml() assert_equal(expected, actual) end def test_empty_bxml_verb bxml = Bandwidth::Voice::Bxml.new() expected = '' actual = bxml.to_bxml() assert_equal(expected, actual) end def test_bxml_speak_sentence_pause bxml = Bandwidth::Voice::Bxml.new() speak_sentence = Bandwidth::Voice::SpeakSentence.new({ :sentence => "new modify call bxml is pog", :voice => "Julie" }) pause = Bandwidth::Voice::Pause.new({ :duration => 6 }) bxml.push(speak_sentence) bxml.push(pause) expected = 'new modify call bxml is pog' actual = bxml.to_bxml() assert_equal(expected, actual) end def test_hangup hangup = Bandwidth::Voice::Hangup.new() response = Bandwidth::Voice::Response.new() response.push(hangup) expected = '' actual = response.to_bxml() assert_equal(expected, actual) end def test_pause pause = Bandwidth::Voice::Pause.new({ :duration => 2 }) response = Bandwidth::Voice::Response.new() response.push(pause) expected = '' actual = response.to_bxml() assert_equal(expected, actual) end def test_pause_recording pause_recording = Bandwidth::Voice::PauseRecording.new() response = Bandwidth::Voice::Response.new() response.push(pause_recording) expected = '' actual = response.to_bxml() assert_equal(expected, actual) end def test_play_audio play_audio = Bandwidth::Voice::PlayAudio.new({ :url => "https://test.com", :username => "user", :password => "pass" }) response = Bandwidth::Voice::Response.new() response.push(play_audio) expected = 'https://test.com' actual = response.to_bxml() assert_equal(expected, actual) end def test_record record = Bandwidth::Voice::Record.new({ :record_complete_url => "https://complete.com", :record_complete_method => "POST", :recording_available_url => "https://available.com", :recording_available_method => "GET", :transcribe => false, :transcription_available_url => "https://transcribe.com", :transcription_available_method => "POST", :username => "user", :password => "pass", :tag => "tag", :terminating_digits => "#", :max_duration => 3, :silence_timeout => 5, :file_format => "wav", :record_complete_fallback_url => "https://test.com", :record_complete_fallback_method => "GET", :fallback_username => "fuser", :fallback_password => "fpass" }) response = Bandwidth::Voice::Response.new() response.push(record) expected = '' actual = response.to_bxml() assert_equal(expected, actual) end def test_redirect redirect = Bandwidth::Voice::Redirect.new({ :redirect_url => "https://redirect.com", :redirect_method => "GET", :username => "user", :password => "pass", :tag => "tag", :redirect_fallback_url => "https://test.com", :redirect_fallback_method => "GET", :fallback_username => "fuser", :fallback_password => "fpass" }) response = Bandwidth::Voice::Response.new() response.push(redirect) expected = '' actual = response.to_bxml() assert_equal(expected, actual) end def test_resume_recording resume_recording = Bandwidth::Voice::ResumeRecording.new() response = Bandwidth::Voice::Response.new() response.push(resume_recording) expected = '' actual = response.to_bxml() assert_equal(expected, actual) end def test_send_dtmf send_dtmf = Bandwidth::Voice::SendDtmf.new({ :dtmf => "12w34", :tone_duration => 75, :tone_interval => 65 }) response = Bandwidth::Voice::Response.new() response.push(send_dtmf) expected = '12w34' actual = response.to_bxml() assert_equal(expected, actual) end def test_speak_sentence speak_sentence = Bandwidth::Voice::SpeakSentence.new({ :sentence => "test", :voice => "julie", :gender => "female", :locale => "en_US" }) response = Bandwidth::Voice::Response.new() response.push(speak_sentence) expected = 'test' actual = response.to_bxml() assert_equal(expected, actual) end def test_speak_sentence_ssml speak_sentence = Bandwidth::Voice::SpeakSentence.new({ :sentence => 'Hello, you have reached the home of Antonio Mendoza.Please leave a message.', }) response = Bandwidth::Voice::Response.new() response.push(speak_sentence) expected = 'Hello, you have reached the home of Antonio Mendoza.Please leave a message.' actual = response.to_bxml() assert_equal(expected, actual) end def test_start_recording start_recording = Bandwidth::Voice::StartRecording.new({ :recording_available_url => "https://available.com", :recording_available_method => "POST", :transcribe => false, :transcription_available_url => "https://transcribe.com", :transcription_available_method => "GET", :username => "user", :password => "pass", :tag => "tag", :file_format => "mp3", :multi_channel => true }) response = Bandwidth::Voice::Response.new() response.push(start_recording) expected = '' actual = response.to_bxml() assert_equal(expected, actual) end def test_stop_recording stop_recording = Bandwidth::Voice::StopRecording.new() response = Bandwidth::Voice::Response.new() response.push(stop_recording) expected = '' actual = response.to_bxml() assert_equal(expected, actual) end def test_transfer phone_number = Bandwidth::Voice::PhoneNumber.new({ :number => "+15554443333", :transfer_answer_url => "https://phoneanswer.com", :transfer_answer_method => "GET", :transfer_disconnect_url => "https://phonedisconnect.com", :transfer_disconnect_method => "POST", :username => "phoneuser", :password => "phonepassword", :tag => "phonetag", :transfer_answer_fallback_url => "https://test.com", :transfer_answer_fallback_method => "GET", :fallback_username => "fuser", :fallback_password => "fpass" }) transfer = Bandwidth::Voice::Transfer.new({ :transfer_caller_id => "+13334445555", :call_timeout => 3, :transfer_complete_url => "https://transfercomplete.com", :transfer_complete_method => "POST", :username => "transferuser", :password => "transferpass", :tag => "transfertag", :diversion_treatment => "none", :diversion_reason => "away", :phone_numbers => [phone_number], :transfer_complete_fallback_url => "https://test.com", :transfer_complete_fallback_method => "GET", :fallback_username => "fusern", :fallback_password => "fpassw" }) response = Bandwidth::Voice::Response.new() response.push(transfer) expected = '+15554443333' actual = response.to_bxml() assert_equal(expected, actual) end def test_conference conference = Bandwidth::Voice::Conference.new({ :conference_name => 'my-conference', :mute => false, :hold => true, :call_ids_to_coach => "c-123,c-234", :conference_event_url => "https://test.com", :conference_event_method => "POST", :username => "user", :password => "pass", :tag => "tag", :conference_event_fallback_url => "https://test2.com", :conference_event_fallback_method => "POST", :fallback_username => "fuser", :fallback_password => "fpass" }) response = Bandwidth::Voice::Response.new() response.push(conference) expected = 'my-conference' actual = response.to_bxml() assert_equal(expected, actual) end def test_conference_coach_ids_array conference = Bandwidth::Voice::Conference.new({ :conference_name => 'my-conference', :call_ids_to_coach => ["c-123", "c-234"], }) response = Bandwidth::Voice::Response.new() response.push(conference) expected = 'my-conference' actual = response.to_bxml() assert_equal(expected, actual) end def test_conference_no_coach conference = Bandwidth::Voice::Conference.new({ :conference_name => 'my-conference' }) response = Bandwidth::Voice::Response.new() response.push(conference) expected = 'my-conference' actual = response.to_bxml() assert_equal(expected, actual) end def test_mfa_messaging body = TwoFactorCodeRequestSchema.new body.from = BW_NUMBER body.to = USER_NUMBER body.application_id = BW_MESSAGING_APPLICATION_ID body.scope = "scope" body.digits = 6 body.message = "Your temporary {NAME} {SCOPE} code is {CODE}" response = @bandwidth_client.multi_factor_auth_client.mfa.create_messaging_two_factor(BW_ACCOUNT_ID, body) assert(response.data.message_id.length > 0, "message id value not set") end def test_mfa_voice body = TwoFactorCodeRequestSchema.new body.from = BW_NUMBER body.to = USER_NUMBER body.application_id = BW_VOICE_APPLICATION_ID body.scope = "scope" body.digits = 6 body.message = "Your temporary {NAME} {SCOPE} code is {CODE}" response = @bandwidth_client.multi_factor_auth_client.mfa.create_voice_two_factor(BW_ACCOUNT_ID, body) assert(response.data.call_id.length > 0, "call id value not set") end def test_mfa_verify body = TwoFactorVerifyRequestSchema.new body.to = "+1000" + rand(1111111..9999999).to_s body.application_id = BW_VOICE_APPLICATION_ID body.scope = "scope" body.code = "123456" body.expiration_time_in_minutes = 3 response = @bandwidth_client.multi_factor_auth_client.mfa.create_verify_two_factor(BW_ACCOUNT_ID, body) #Ruby has no check to see if variables are of type boolean #An explicit true/false check is required assert(response.data.valid == true || response.data.valid == false, "'valid' variable is not a boolean") end def test_bridge bridge = Bandwidth::Voice::Bridge.new({ :call_id => "c-c-95ac8d6e-1a31c52e-b38f-4198-93c1-51633ec68f8d", :bridge_complete_url => "https://test.com", :bridge_complete_method => "POST", :bridge_target_complete_url => "https://test2.com", :bridge_target_complete_method => "GET", :username => "user", :password => "pass", :tag => "custom tag", :bridge_complete_fallback_url => "https://test3.com", :bridge_complete_fallback_method => "GET", :bridge_target_complete_fallback_url => "https://test4.com", :bridge_target_complete_fallback_method => "POST", :fallback_username => "fuser", :fallback_password => "fpass" }) response = Bandwidth::Voice::Response.new() response.push(bridge) expected = 'c-c-95ac8d6e-1a31c52e-b38f-4198-93c1-51633ec68f8d' actual = response.to_bxml() assert_equal(expected, actual) end def test_ring ring = Bandwidth::Voice::Ring.new({ :duration => 5, :answer_call => false }) response = Bandwidth::Voice::Response.new() response.push(ring) expected = '' actual = response.to_bxml() assert_equal(expected, actual) end def test_start_gather start_gather = Bandwidth::Voice::StartGather.new({ :username => "user", :password => "pass", :tag => "custom tag", :dtmf_url => "https://test.com", :dtmf_method => "GET" }) response = Bandwidth::Voice::Response.new() response.push(start_gather) expected = '' actual = response.to_bxml() assert_equal(expected, actual) end def test_stop_gather stop_gather = Bandwidth::Voice::StopGather.new() response = Bandwidth::Voice::Response.new() response.push(stop_gather) expected = '' actual = response.to_bxml() assert_equal(expected, actual) end def test_tn_lookup body = OrderRequest.new body.tns = [BW_NUMBER] create_response = @bandwidth_client.phone_number_lookup_client.client.create_lookup_request(BW_ACCOUNT_ID, body) assert(create_response.data.request_id.length > 0, "request_id value not set") request_id = create_response.data.request_id get_response = @bandwidth_client.phone_number_lookup_client.client.get_lookup_request_status(BW_ACCOUNT_ID, request_id) assert(get_response.data.status.length > 0, "status value not set") end def test_webrtc_generate_bxml expected = 'sip:sipx.webrtc.bandwidth.com:5060' actual = Bandwidth::WebRtc.generate_bxml('asdf', 'c-93d6f3c0-be584596-0b74-4fa2-8015-d8ede84bd1a4') assert_equal(expected, actual) end def test_webrtc_generate_transfer_bxml_verb expected = 'sip:sipx.webrtc.bandwidth.com:5060' actual = Bandwidth::WebRtc.generate_transfer_bxml_verb('asdf', 'c-93d6f3c0-be584596-0b74-4fa2-8015-d8ede84bd1a4') assert_equal(expected, actual) end end