From e5c41f16b5ea31f9b9896b04c9e92c8770a6a1be Mon Sep 17 00:00:00 2001 From: Karl Lingiah Date: Thu, 22 Aug 2024 10:44:08 +0100 Subject: [PATCH] DEVX-8677: Voice NCCO updates (#315) * Adding new properties to talk action * Fixing implement for talk action URL handling * Adding new properties to NCCO stream action * Adding transcription property to record action * Adding mode prepoerty to input NCCO * Tidy up URL implementation --- lib/vonage/voice/actions/connect.rb | 8 +- lib/vonage/voice/actions/conversation.rb | 10 +- lib/vonage/voice/actions/input.rb | 22 +++- lib/vonage/voice/actions/notify.rb | 11 +- lib/vonage/voice/actions/record.rb | 56 ++++++++- lib/vonage/voice/actions/stream.rb | 52 ++++++++- lib/vonage/voice/actions/talk.rb | 49 +++++++- test/vonage/voice/actions/connect_test.rb | 12 +- .../vonage/voice/actions/conversation_test.rb | 12 +- test/vonage/voice/actions/input_test.rb | 78 ++++++++++++- test/vonage/voice/actions/notify_test.rb | 14 ++- test/vonage/voice/actions/record_test.rb | 108 +++++++++++++++++- test/vonage/voice/actions/stream_test.rb | 70 ++++++++++-- test/vonage/voice/actions/talk_test.rb | 62 +++++++++- 14 files changed, 509 insertions(+), 55 deletions(-) diff --git a/lib/vonage/voice/actions/connect.rb b/lib/vonage/voice/actions/connect.rb index 3b2b04fa..01154f9f 100644 --- a/lib/vonage/voice/actions/connect.rb +++ b/lib/vonage/voice/actions/connect.rb @@ -107,9 +107,13 @@ def verify_advanced_machine_detection_beep_timeout end def verify_event_url - uri = URI.parse(self.eventUrl) + unless self.eventUrl.is_a?(Array) && self.eventUrl.length == 1 && self.eventUrl[0].is_a?(String) + raise ClientError.new("Expected 'eventUrl' parameter to be an Array containing a single string item") + end + + uri = URI.parse(self.eventUrl[0]) - raise ClientError.new("Invalid 'eventUrl' value, must be a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS) + raise ClientError.new("Invalid 'eventUrl' value, array must contain a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS) self.eventUrl end diff --git a/lib/vonage/voice/actions/conversation.rb b/lib/vonage/voice/actions/conversation.rb index f00d9a48..f3f337ff 100644 --- a/lib/vonage/voice/actions/conversation.rb +++ b/lib/vonage/voice/actions/conversation.rb @@ -49,9 +49,15 @@ def after_initialize! end def verify_music_on_hold_url - uri = URI.parse(self.musicOnHoldUrl) + music_on_hold_url = self.musicOnHoldUrl - raise ClientError.new("Invalid 'musicOnHoldUrl' value, must be a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS) + unless music_on_hold_url.is_a?(Array) && music_on_hold_url.length == 1 && music_on_hold_url[0].is_a?(String) + raise ClientError.new("Expected 'musicOnHoldUrl' parameter to be an Array containing a single string item") + end + + uri = URI.parse(music_on_hold_url[0]) + + raise ClientError.new("Invalid 'musicOnHoldUrl' value, array must contain a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS) self.musicOnHoldUrl end diff --git a/lib/vonage/voice/actions/input.rb b/lib/vonage/voice/actions/input.rb index 774f5b29..08a6ee37 100644 --- a/lib/vonage/voice/actions/input.rb +++ b/lib/vonage/voice/actions/input.rb @@ -3,7 +3,7 @@ module Vonage class Voice::Actions::Input - attr_accessor :type, :dtmf, :speech, :eventUrl, :eventMethod + attr_accessor :type, :dtmf, :speech, :eventUrl, :eventMethod, :mode def initialize(attributes = {}) @type = attributes.fetch(:type) @@ -11,6 +11,7 @@ def initialize(attributes = {}) @speech = attributes.fetch(:speech, nil) @eventUrl = attributes.fetch(:eventUrl, nil) @eventMethod = attributes.fetch(:eventMethod, nil) + @mode = attributes.fetch(:mode, nil) after_initialize! end @@ -33,6 +34,10 @@ def after_initialize! if self.eventMethod validate_event_method end + + if self.mode + validate_mode + end end def validate_type @@ -83,9 +88,13 @@ def validate_speech end def validate_event_url - uri = URI.parse(self.eventUrl) + unless self.eventUrl.is_a?(Array) && self.eventUrl.length == 1 && self.eventUrl[0].is_a?(String) + raise ClientError.new("Expected 'eventUrl' parameter to be an Array containing a single string item") + end + + uri = URI.parse(self.eventUrl[0]) - raise ClientError.new("Invalid 'eventUrl' value, must be a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS) + raise ClientError.new("Invalid 'eventUrl' value, array must contain a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS) self.eventUrl end @@ -96,6 +105,12 @@ def validate_event_method raise ClientError.new("Invalid 'eventMethod' value. must be either: 'GET' or 'POST'") unless valid_methods.include?(self.eventMethod.upcase) end + def validate_mode + valid_modes = ['asyncronous'] + + raise ClientError.new("Invalid 'mode' value, must be asyncronous'") unless valid_modes.include?(self.mode) + end + def action create_input!(self) end @@ -112,6 +127,7 @@ def create_input!(builder) ncco[0].merge!(speech: builder.speech) if builder.speech ncco[0].merge!(eventUrl: builder.eventUrl) if builder.eventUrl ncco[0].merge!(eventMethod: builder.eventMethod) if builder.eventMethod + ncco[0].merge!(mode: builder.mode) if builder.mode ncco end diff --git a/lib/vonage/voice/actions/notify.rb b/lib/vonage/voice/actions/notify.rb index 5fb775f5..c7d916a0 100644 --- a/lib/vonage/voice/actions/notify.rb +++ b/lib/vonage/voice/actions/notify.rb @@ -22,10 +22,15 @@ def after_initialize! end def validate_event_url - uri = URI.parse(self.eventUrl[0]) + event_url = self.eventUrl - raise ClientError.new("Expected 'eventUrl' value to be an Array with a single string") unless self.eventUrl.is_a?(Array) - raise ClientError.new("Invalid 'eventUrl' value, must be a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS) + unless event_url.is_a?(Array) && event_url.length == 1 && event_url[0].is_a?(String) + raise ClientError.new("Expected 'eventUrl' parameter to be an Array containing a single string item") + end + + uri = URI.parse(event_url[0]) + + raise ClientError.new("Invalid 'eventUrl' value, array must contain a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS) self.eventUrl end diff --git a/lib/vonage/voice/actions/record.rb b/lib/vonage/voice/actions/record.rb index 094e2644..9846d143 100644 --- a/lib/vonage/voice/actions/record.rb +++ b/lib/vonage/voice/actions/record.rb @@ -3,7 +3,7 @@ module Vonage class Voice::Actions::Record - attr_accessor :format, :split, :channels, :endOnSilence, :endOnKey, :timeOut, :beepStart, :eventUrl, :eventMethod + attr_accessor :format, :split, :channels, :endOnSilence, :endOnKey, :timeOut, :beepStart, :eventUrl, :eventMethod, :transcription def initialize(attributes = {}) @format = attributes.fetch(:format, nil) @@ -15,6 +15,7 @@ def initialize(attributes = {}) @beepStart = attributes.fetch(:beepStart, nil) @eventUrl = attributes.fetch(:eventUrl, nil) @eventMethod = attributes.fetch(:eventMethod, nil) + @transcription = attributes.fetch(:transcription, nil) after_initialize! end @@ -55,6 +56,10 @@ def after_initialize! if self.eventMethod validate_event_method end + + if self.transcription + validate_transcription + end end def validate_format @@ -90,9 +95,13 @@ def validate_beep_start end def validate_event_url - uri = URI.parse(self.eventUrl) + unless self.eventUrl.is_a?(Array) && self.eventUrl.length == 1 && self.eventUrl[0].is_a?(String) + raise ClientError.new("Expected 'eventUrl' parameter to be an Array containing a single string item") + end - raise ClientError.new("Invalid 'eventUrl' value, must be a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS) + uri = URI.parse(self.eventUrl[0]) + + raise ClientError.new("Invalid 'eventUrl' value, array must contain a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS) self.eventUrl end @@ -100,7 +109,45 @@ def validate_event_url def validate_event_method valid_methods = ['GET', 'POST'] - raise ClientError.new("Invalid 'eventMethod' value. must be either: 'GET' or 'POST'") unless valid_methods.include?(self.eventMethod.upcase) + raise ClientError.new("Invalid 'eventMethod' value. Must be either: 'GET' or 'POST'") unless valid_methods.include?(self.eventMethod.upcase) + end + + def validate_transcription + raise ClientError.new("Expected 'transcription' parameter to be a Hash") unless self.transcription.is_a?(Hash) + + if self.transcription[:language] + raise ClientError.new("Invalid 'language' value, must be a String") unless self.transcription[:language].is_a?(String) + end + + if self.transcription[:eventUrl] + event_url = self.transcription[:eventUrl] + + unless event_url.is_a?(Array) && event_url.length == 1 && event_url[0].is_a?(String) + raise ClientError.new("Expected 'eventUrl' parameter to be an Array containing a single string item") + end + + uri = URI.parse(event_url[0]) + + raise ClientError.new("Invalid 'eventUrl' value, array must contain a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS) + end + + if self.transcription[:eventMethod] + event_method = self.transcription[:eventMethod] + raise ClientError.new("Invalid 'eventMethod' value, must be either: 'GET' or 'POST'") unless ['GET', 'POST'].include?(event_method.upcase) + end + + if self.transcription[:sentimentAnalysis] + sentiment_analysis = self.transcription[:sentimentAnalysis] + raise ClientError.new("Invalid 'sentimentAnalysis' value, must be a Boolean") unless sentiment_analysis == true || sentiment_analysis == false + end + + # if self.dtmf[:maxDigits] + # raise ClientError.new("Expected 'maxDigits' to not be more than 22") if self.dtmf[:maxDigits] > 22 + # end + + # if self.dtmf[:submitOnHash] + # raise ClientError.new("Invalid 'submitOnHash' value, must be a Boolean") unless self.dtmf[:submitOnHash] == true || self.dtmf[:submitOnHash] == false + # end end def action @@ -123,6 +170,7 @@ def create_record!(builder) ncco[0].merge!(beepStart: builder.beepStart) if builder.beepStart ncco[0].merge!(eventUrl: builder.eventUrl) if builder.eventUrl ncco[0].merge!(eventMethod: builder.eventMethod) if builder.eventMethod + ncco[0].merge!(transcription: builder.transcription) if builder.transcription ncco end diff --git a/lib/vonage/voice/actions/stream.rb b/lib/vonage/voice/actions/stream.rb index f4374e79..7b6a93ab 100644 --- a/lib/vonage/voice/actions/stream.rb +++ b/lib/vonage/voice/actions/stream.rb @@ -3,13 +3,16 @@ module Vonage class Voice::Actions::Stream - attr_accessor :streamUrl, :level, :bargeIn, :loop + attr_accessor :streamUrl, :level, :bargeIn, :loop, :eventOnCompletion, :eventUrl, :eventMethod def initialize(attributes = {}) @streamUrl = attributes.fetch(:streamUrl) @level = attributes.fetch(:level, nil) @bargeIn = attributes.fetch(:bargeIn, nil) @loop = attributes.fetch(:loop, nil) + @eventOnCompletion = attributes.fetch(:eventOnCompletion, nil) + @eventUrl = attributes.fetch(:eventUrl, nil) + @eventMethod = attributes.fetch(:eventMethod, nil) after_initialize! end @@ -28,12 +31,28 @@ def after_initialize! if self.loop verify_loop end + + if self.eventOnCompletion || self.eventOnCompletion == false + verify_event_on_completion + end + + if self.eventUrl + verify_event_url + end + + if self.eventMethod + verify_event_method + end end def verify_stream_url - raise ClientError.new("Expected 'streamUrl' parameter to be an Array containing a single string item") unless self.streamUrl.is_a?(Array) + stream_url = self.streamUrl + + unless stream_url.is_a?(Array) && stream_url.length == 1 && stream_url[0].is_a?(String) + raise ClientError.new("Expected 'streamUrl' parameter to be an Array containing a single string item") + end - uri = URI.parse(self.streamUrl[0]) + uri = URI.parse(stream_url[0]) raise ClientError.new("Invalid 'streamUrl' value, must be a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS) end @@ -47,7 +66,29 @@ def verify_barge_in end def verify_loop - raise ClientError.new("Expected 'loop' value to be either 1 or 0") unless self.loop == 1 || self.loop == 0 + raise ClientError.new("Expected 'loop' value to be either 0 or a positive integer") unless self.loop >= 0 + end + + def verify_event_on_completion + raise ClientError.new("Expected 'eventOnCompletion' value to be a Boolean") unless self.eventOnCompletion == true || self.eventOnCompletion == false + end + + def verify_event_url + unless self.eventUrl.is_a?(Array) && self.eventUrl.length == 1 && self.eventUrl[0].is_a?(String) + raise ClientError.new("Expected 'eventUrl' parameter to be an Array containing a single string item") + end + + uri = URI.parse(self.eventUrl[0]) + + raise ClientError.new("Invalid 'eventUrl' value, array must contain a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS) + + self.eventUrl + end + + def verify_event_method + valid_methods = ['GET', 'POST'] + + raise ClientError.new("Invalid 'eventMethod' value. must be either: 'GET' or 'POST'") unless valid_methods.include?(self.eventMethod.upcase) end def action @@ -65,6 +106,9 @@ def create_stream!(builder) ncco[0].merge!(level: builder.level) if builder.level ncco[0].merge!(bargeIn: builder.bargeIn) if (builder.bargeIn || builder.bargeIn == false) ncco[0].merge!(loop: builder.loop) if builder.loop + ncco[0].merge!(eventOnCompletion: builder.eventOnCompletion) if (builder.eventOnCompletion || builder.eventOnCompletion == false) + ncco[0].merge!(eventUrl: builder.eventUrl) if builder.eventUrl + ncco[0].merge!(eventMethod: builder.eventMethod) if builder.eventMethod ncco end diff --git a/lib/vonage/voice/actions/talk.rb b/lib/vonage/voice/actions/talk.rb index 43e08412..fc72524f 100644 --- a/lib/vonage/voice/actions/talk.rb +++ b/lib/vonage/voice/actions/talk.rb @@ -2,7 +2,7 @@ # frozen_string_literal: true module Vonage class Voice::Actions::Talk - attr_accessor :text, :bargeIn, :loop, :level, :language, :style, :premium + attr_accessor :text, :bargeIn, :loop, :level, :language, :style, :premium, :eventOnCompletion, :eventUrl, :eventMethod def initialize(attributes= {}) @text = attributes.fetch(:text) @@ -12,12 +12,15 @@ def initialize(attributes= {}) @language = attributes.fetch(:language, nil) @style = attributes.fetch(:style, nil) @premium = attributes.fetch(:premium, nil) + @eventOnCompletion = attributes.fetch(:eventOnCompletion, nil) + @eventUrl = attributes.fetch(:eventUrl, nil) + @eventMethod = attributes.fetch(:eventMethod, nil) after_initialize! end def after_initialize! - if self.bargeIn + if self.bargeIn || self.bargeIn == false verify_barge_in end @@ -33,9 +36,21 @@ def after_initialize! verify_style end - if self.premium + if self.premium || self.premium == false verify_premium end + + if self.eventOnCompletion || self.eventOnCompletion == false + verify_event_on_completion + end + + if self.eventUrl + verify_event_url + end + + if self.eventMethod + verify_event_method + end end def verify_barge_in @@ -43,7 +58,7 @@ def verify_barge_in end def verify_loop - raise ClientError.new("Expected 'loop' value to be either 1 or 0") unless self.loop == 1 || self.loop == 0 + raise ClientError.new("Expected 'loop' value to be either 0 or a positive integer") unless self.loop >= 0 end def verify_level @@ -58,6 +73,28 @@ def verify_premium raise ClientError.new("Expected 'premium' value to be a Boolean") unless self.premium == true || self.premium == false end + def verify_event_on_completion + raise ClientError.new("Expected 'eventOnCompletion' value to be a Boolean") unless self.eventOnCompletion == true || self.eventOnCompletion == false + end + + def verify_event_url + unless self.eventUrl.is_a?(Array) && self.eventUrl.length == 1 && self.eventUrl[0].is_a?(String) + raise ClientError.new("Expected 'eventUrl' parameter to be an Array containing a single string item") + end + + uri = URI.parse(self.eventUrl[0]) + + raise ClientError.new("Invalid 'eventUrl' value, array must contain a valid URL") unless uri.kind_of?(URI::HTTP) || uri.kind_of?(URI::HTTPS) + + self.eventUrl + end + + def verify_event_method + valid_methods = ['GET', 'POST'] + + raise ClientError.new("Invalid 'eventMethod' value. must be either: 'GET' or 'POST'") unless valid_methods.include?(self.eventMethod.upcase) + end + def action create_talk!(self) end @@ -75,6 +112,10 @@ def create_talk!(builder) ncco[0].merge!(level: builder.level) if builder.level ncco[0].merge!(language: builder.language) if builder.language ncco[0].merge!(style: builder.style) if builder.style + ncco[0].merge!(premium: builder.premium) if (builder.bargeIn || builder.bargeIn == false) + ncco[0].merge!(eventOnCompletion: builder.eventOnCompletion) if (builder.eventOnCompletion || builder.eventOnCompletion == false) + ncco[0].merge!(eventUrl: builder.eventUrl) if builder.eventUrl + ncco[0].merge!(eventMethod: builder.eventMethod) if builder.eventMethod ncco end diff --git a/test/vonage/voice/actions/connect_test.rb b/test/vonage/voice/actions/connect_test.rb index 80d9adfa..b7f7961d 100644 --- a/test/vonage/voice/actions/connect_test.rb +++ b/test/vonage/voice/actions/connect_test.rb @@ -86,10 +86,16 @@ def test_verify_with_invalid_advanced_machine_detection_beep_timeout assert_match "Invalid 'advanced_machine_detection[:beep_timeout]' value, must be between 45 and 120", exception.message end - def test_verify_with_invalid_event_url - exception = assert_raises { Vonage::Voice::Actions::Connect.new(endpoint: { type: 'phone', number: '12122222222' }, eventUrl: 'invalid') } + def test_connect_with_invalid_event_url_type + exception = assert_raises { Vonage::Voice::Actions::Connect.new(endpoint: { type: 'phone', number: '12122222222' }, eventUrl: 'https://example.com/event') } - assert_match "Invalid 'eventUrl' value, must be a valid URL", exception.message + assert_match "Expected 'eventUrl' parameter to be an Array containing a single string item", exception.message + end + + def test_connect_with_invalid_event_url + exception = assert_raises { Vonage::Voice::Actions::Connect.new(endpoint: { type: 'phone', number: '12122222222' }, eventUrl: ['foo.bar'] ) } + + assert_match "Invalid 'eventUrl' value, array must contain a valid URL", exception.message end def test_verify_with_invalid_event_method diff --git a/test/vonage/voice/actions/conversation_test.rb b/test/vonage/voice/actions/conversation_test.rb index b561846f..50ac404b 100644 --- a/test/vonage/voice/actions/conversation_test.rb +++ b/test/vonage/voice/actions/conversation_test.rb @@ -23,10 +23,16 @@ def test_create_conversation_with_optional_params assert_equal expected, conversation.create_conversation!(conversation) end - def test_conversation_with_invalid_music_on_hold_url - exception = assert_raises { Vonage::Voice::Actions::Conversation.new(name: 'test123', musicOnHoldUrl: 'invalid') } + def test_conversation_with_invalid_music_on_hold_url_type + exception = assert_raises { Vonage::Voice::Actions::Conversation.new(name: 'test123', musicOnHoldUrl: 'https://example.com/event') } - assert_match "Invalid 'musicOnHoldUrl' value, must be a valid URL", exception.message + assert_match "Expected 'musicOnHoldUrl' parameter to be an Array containing a single string item", exception.message + end + + def test_conversation_with_invalid_music_on_hold_url_value + exception = assert_raises { Vonage::Voice::Actions::Conversation.new(name: 'test123', musicOnHoldUrl: ['foo.bar']) } + + assert_match "Invalid 'musicOnHoldUrl' value, array must contain a valid URL", exception.message end def test_conversation_with_invalid_start_on_enter diff --git a/test/vonage/voice/actions/input_test.rb b/test/vonage/voice/actions/input_test.rb index e078b3e1..04b88e95 100644 --- a/test/vonage/voice/actions/input_test.rb +++ b/test/vonage/voice/actions/input_test.rb @@ -17,8 +17,64 @@ def test_create_input end def test_create_input_with_optional_params - expected = [{ action: 'input', type: [ 'dtmf' ], dtmf: { maxDigits: 1 } }] - input = Vonage::Voice::Actions::Input.new(type: [ 'dtmf' ], dtmf: { maxDigits: 1 }) + expected = [ + { + action: 'input', + type: [ + 'dtmf', + 'speech' + ], + dtmf: { + timeOut: 5, + maxDigits: 1, + submitOnHash: true + }, + speech: { + uuid: [ + "aaaaaaaa-bbbb-cccc-dddd-0123456789ab" + ], + endOnSilence: 5, + context: [ "order" ], + startTimeout: 5, + maxDuration: 50, + saveAudio: true, + sensitivity: 50 + }, + eventUrl: [ + 'https://example.com/webhooks/events', + ], + eventMethod: 'GET', + mode: "asyncronous" + } + ] + + input = Vonage::Voice::Actions::Input.new( + type: [ + 'dtmf', + 'speech' + ], + dtmf: { + timeOut: 5, + maxDigits: 1, + submitOnHash: true + }, + speech: { + uuid: [ + "aaaaaaaa-bbbb-cccc-dddd-0123456789ab" + ], + endOnSilence: 5, + context: [ "order" ], + startTimeout: 5, + maxDuration: 50, + saveAudio: true, + sensitivity: 50 + }, + eventUrl: [ + 'https://example.com/webhooks/events', + ], + eventMethod: 'GET', + mode: "asyncronous" + ) assert_equal expected, input.create_input!(input) end @@ -95,10 +151,16 @@ def test_input_with_invalid_speech_max_duration_value assert_match "Expected 'maxDuration' to not be more than 60 seconds", exception.message end - def test_input_with_invalid_event_url_value - exception = assert_raises { Vonage::Voice::Actions::Input.new(type: ['speech'], speech: { maxDuration: 10 }, eventUrl: 'invalid') } + def test_input_with_invalid_event_url_type + exception = assert_raises { Vonage::Voice::Actions::Input.new(type: ['speech'], eventUrl: 'https://example.com/event') } - assert_match "Invalid 'eventUrl' value, must be a valid URL", exception.message + assert_match "Expected 'eventUrl' parameter to be an Array containing a single string item", exception.message + end + + def test_input_with_invalid_event_url + exception = assert_raises { Vonage::Voice::Actions::Input.new(type: ['speech'], eventUrl: ['foo.bar']) } + + assert_match "Invalid 'eventUrl' value, array must contain a valid URL", exception.message end def test_input_with_invalid_event_method_value @@ -106,4 +168,10 @@ def test_input_with_invalid_event_method_value assert_match "Invalid 'eventMethod' value. must be either: 'GET' or 'POST'", exception.message end + + def test_input_with_invalid_mode_value + exception = assert_raises { Vonage::Voice::Actions::Input.new(type: ['speech'], mode: 'syncronous') } + + assert_match "Invalid 'mode' value, must be asyncronous'", exception.message + end end \ No newline at end of file diff --git a/test/vonage/voice/actions/notify_test.rb b/test/vonage/voice/actions/notify_test.rb index 047a6f42..238d20f0 100644 --- a/test/vonage/voice/actions/notify_test.rb +++ b/test/vonage/voice/actions/notify_test.rb @@ -26,13 +26,19 @@ def test_create_notify_with_optional_params def test_notify_with_invalid_event_url_invalid_type exception = assert_raises { Vonage::Voice::Actions::Notify.new(payload: { foo: 'bar' }, eventUrl: 'https://example.com') } - assert_match "Expected 'eventUrl' value to be an Array with a single string", exception.message + assert_match "Expected 'eventUrl' parameter to be an Array containing a single string item", exception.message end - def test_notify_with_invalid_event_url - exception = assert_raises { Vonage::Voice::Actions::Notify.new(payload: { foo: 'bar' }, eventUrl: ['invalid']) } + def test_notify_with_invalid_event_url_type + exception = assert_raises { Vonage::Voice::Actions::Notify.new(payload: { foo: 'bar' }, eventUrl: 'https://example.com/event') } - assert_match "Invalid 'eventUrl' value, must be a valid URL", exception.message + assert_match "Expected 'eventUrl' parameter to be an Array containing a single string item", exception.message + end + + def test_notify_with_invalid_event_url_value + exception = assert_raises { Vonage::Voice::Actions::Notify.new(payload: { foo: 'bar' }, eventUrl: ['foo.bar']) } + + assert_match "Invalid 'eventUrl' value, array must contain a valid URL", exception.message end def test_notify_with_invalid_event_method diff --git a/test/vonage/voice/actions/record_test.rb b/test/vonage/voice/actions/record_test.rb index b5829287..63db83d9 100644 --- a/test/vonage/voice/actions/record_test.rb +++ b/test/vonage/voice/actions/record_test.rb @@ -16,8 +16,44 @@ def test_create_record end def test_create_record_with_optional_params - expected = [{ action: 'record', format: 'mp3' }] - record = Vonage::Voice::Actions::Record.new(format: 'mp3') + expected = [ + { + action: 'record', + format: 'mp3', + split: 'conversation', + channels: 2, + endOnSilence: 3, + endOnKey: '#', + timeOut: 7200, + beepStart: true, + eventUrl: ['https://example.com/event'], + eventMethod: 'GET', + transcription: { + language: 'en-GB', + eventUrl: ['https://example.com/transcription'], + eventMethod: 'GET', + sentimentAnalysis: true + } + } + ] + + record = Vonage::Voice::Actions::Record.new( + format: 'mp3', + split: 'conversation', + channels: 2, + endOnSilence: 3, + endOnKey: '#', + timeOut: 7200, + beepStart: true, + eventUrl: ['https://example.com/event'], + eventMethod: 'GET', + transcription: { + language: 'en-GB', + eventUrl: ['https://example.com/transcription'], + eventMethod: 'GET', + sentimentAnalysis: true + } + ) assert_equal expected, record.create_record!(record) end @@ -84,15 +120,77 @@ def test_record_with_invalid_beep_start_value assert_match "Expected 'beepStart' value to be a Boolean", exception.message end + def test_record_with_invalid_event_url_type + exception = assert_raises { Vonage::Voice::Actions::Record.new({ action: 'record', eventUrl: 'https://example.com/event' }) } + + assert_match "Expected 'eventUrl' parameter to be an Array containing a single string item", exception.message + end + def test_record_with_invalid_event_url_value - exception = assert_raises { Vonage::Voice::Actions::Record.new({ action: 'record', eventUrl: 'invalid'}) } + exception = assert_raises { Vonage::Voice::Actions::Record.new({ action: 'record', eventUrl: ['invalid.url']}) } - assert_match "Invalid 'eventUrl' value, must be a valid URL", exception.message + assert_match "Invalid 'eventUrl' value, array must contain a valid URL", exception.message end def test_record_with_invalid_event_method_value exception = assert_raises { Vonage::Voice::Actions::Record.new({ action: 'record', eventMethod: 'invalid'}) } - assert_match "Invalid 'eventMethod' value. must be either: 'GET' or 'POST'", exception.message + assert_match "Invalid 'eventMethod' value. Must be either: 'GET' or 'POST'", exception.message + end + + def test_record_with_invalid_transcription_type + exception = assert_raises { Vonage::Voice::Actions::Record.new({ action: 'record', transcription: [] }) } + + assert_match "Expected 'transcription' parameter to be a Hash", exception.message + end + + def test_record_with_invalid_transcription_language_type + exception = assert_raises { Vonage::Voice::Actions::Record.new({ action: 'record', transcription: { language: :en } }) } + + assert_match "Invalid 'language' value, must be a String", exception.message + end + + def test_record_with_invalid_transcription_event_url_type + exception = assert_raises do + Vonage::Voice::Actions::Record.new( + { + action: 'record', + transcription: { + eventUrl: 'https://example.com/event' + } + } + ) + end + + assert_match "Expected 'eventUrl' parameter to be an Array containing a single string item", exception.message + end + + def test_record_with_invalid_transcription_event_url_value + exception = assert_raises do + Vonage::Voice::Actions::Record.new( + { + action: 'record', + transcription: { + eventUrl: [ + 'invalid.url' + ] + } + } + ) + end + + assert_match "Invalid 'eventUrl' value, array must contain a valid URL", exception.message + end + + def test_record_with_invalid_transcription_event_method_value + exception = assert_raises { Vonage::Voice::Actions::Record.new(action: 'record', transcription: { eventMethod: 'PATCH' }) } + + assert_match "Invalid 'eventMethod' value, must be either: 'GET' or 'POST'", exception.message + end + + def test_record_with_invalid_transcription_sentiment_analysis_value + exception = assert_raises { Vonage::Voice::Actions::Record.new(action: 'record', transcription: { sentimentAnalysis: 'true' }) } + + assert_match "Invalid 'sentimentAnalysis' value, must be a Boolean", exception.message end end \ No newline at end of file diff --git a/test/vonage/voice/actions/stream_test.rb b/test/vonage/voice/actions/stream_test.rb index 709ad687..9d382e6e 100644 --- a/test/vonage/voice/actions/stream_test.rb +++ b/test/vonage/voice/actions/stream_test.rb @@ -17,45 +17,97 @@ def test_create_stream end def test_create_stream_with_optional_params - expected = [{ action: 'stream', streamUrl: [ 'https://example.com/example.mp3' ], bargeIn: true }] - stream = Vonage::Voice::Actions::Stream.new(streamUrl: [ 'https://example.com/example.mp3' ], bargeIn: true) + expected = [ + { + action: 'stream', + streamUrl: [ + 'https://example.com/example.mp3' + ], + level: 0.5, + bargeIn: true, + loop: 2, + eventOnCompletion: true, + eventUrl: [ + 'https://example.com/event' + ], + eventMethod: 'GET' + } + ] + + stream = Vonage::Voice::Actions::Stream.new( + streamUrl: [ + 'https://example.com/example.mp3' + ], + level: 0.5, + bargeIn: true, + loop: 2, + eventOnCompletion: true, + eventUrl: [ + 'https://example.com/event' + ], + eventMethod: 'GET' + ) assert_equal expected, stream.create_stream!(stream) end def test_stream_with_invalid_stream_url_type - exception = assert_raises { Vonage::Voice::Actions::Stream.new({ streamUrl: 'https://example.com/example.mp3' }) } + exception = assert_raises { Vonage::Voice::Actions::Stream.new(streamUrl: 'https://example.com/example.mp3') } assert_match "Expected 'streamUrl' parameter to be an Array containing a single string item", exception.message end def test_stream_with_invalid_stream_url - exception = assert_raises { Vonage::Voice::Actions::Stream.new({ streamUrl: ['invalid'] }) } + exception = assert_raises { Vonage::Voice::Actions::Stream.new(streamUrl: ['invalid.url']) } assert_match "Invalid 'streamUrl' value, must be a valid URL", exception.message end def test_stream_with_invalid_level_integer - exception = assert_raises { Vonage::Voice::Actions::Stream.new({ streamUrl: [ 'https://example.com/example.mp3' ], level: -2 }) } + exception = assert_raises { Vonage::Voice::Actions::Stream.new(streamUrl: [ 'https://example.com/example.mp3' ], level: -2) } assert_match "Expected 'level' value to be a number between -1 and 1", exception.message end def test_stream_with_invalid_level_float - exception = assert_raises { Vonage::Voice::Actions::Stream.new({ streamUrl: [ 'https://example.com/example.mp3' ], level: -2.3 }) } + exception = assert_raises { Vonage::Voice::Actions::Stream.new(streamUrl: [ 'https://example.com/example.mp3' ], level: -2.3) } assert_match "Expected 'level' value to be a number between -1 and 1", exception.message end def test_stream_with_invalid_barge_in_value - exception = assert_raises { Vonage::Voice::Actions::Stream.new({ streamUrl: [ 'https://example.com/example.mp3' ], bargeIn: 'yes' }) } + exception = assert_raises { Vonage::Voice::Actions::Stream.new(streamUrl: [ 'https://example.com/example.mp3' ], bargeIn: 'yes') } assert_match "Expected 'bargeIn' value to be a Boolean", exception.message end def test_stream_with_invalid_loop_value - exception = assert_raises { Vonage::Voice::Actions::Stream.new({ streamUrl: [ 'https://example.com/example.mp3' ], loop: 3 }) } + exception = assert_raises { Vonage::Voice::Actions::Stream.new(streamUrl: [ 'https://example.com/example.mp3' ], loop: -1) } - assert_match "Expected 'loop' value to be either 1 or 0", exception.message + assert_match "Expected 'loop' value to be either 0 or a positive integer", exception.message + end + + def test_stream_with_invalid_event_on_completion_value + exception = assert_raises { Vonage::Voice::Actions::Stream.new(streamUrl: [ 'https://example.com/example.mp3' ], eventOnCompletion: 'true') } + + assert_match "Expected 'eventOnCompletion' value to be a Boolean", exception.message + end + + def test_stream_with_invalid_event_url_type + exception = assert_raises { Vonage::Voice::Actions::Stream.new(streamUrl: [ 'https://example.com/example.mp3' ], eventUrl: 'https://example.com/event') } + + assert_match "Expected 'eventUrl' parameter to be an Array containing a single string item", exception.message + end + + def test_stream_with_invalid_event_url + exception = assert_raises { Vonage::Voice::Actions::Stream.new(streamUrl: [ 'https://example.com/example.mp3' ], eventUrl: ['foo.bar']) } + + assert_match "Invalid 'eventUrl' value, array must contain a valid URL", exception.message + end + + def test_stream_with_invalid_event_method + exception = assert_raises { Vonage::Voice::Actions::Stream.new(streamUrl: [ 'https://example.com/example.mp3' ], eventMethod: 'PATCH') } + + assert_match "Invalid 'eventMethod' value. must be either: 'GET' or 'POST'", exception.message end end \ No newline at end of file diff --git a/test/vonage/voice/actions/talk_test.rb b/test/vonage/voice/actions/talk_test.rb index e9539cf9..0d311287 100644 --- a/test/vonage/voice/actions/talk_test.rb +++ b/test/vonage/voice/actions/talk_test.rb @@ -17,8 +17,38 @@ def test_create_talk end def test_create_talk_with_optional_params - expected = [{ action: 'talk', text: 'Sample Text', bargeIn: true }] - talk = Vonage::Voice::Actions::Talk.new(text: 'Sample Text', bargeIn: true) + expected = [ + { + action: 'talk', + text: 'Sample Text', + bargeIn: true, + loop: 3, + level: 0.5, + language: 'en-GB', + style: 1, + premium: true, + eventOnCompletion: true, + eventUrl: [ + 'https://example.com/event' + ], + eventMethod: 'GET' + } + ] + + talk = Vonage::Voice::Actions::Talk.new( + text: 'Sample Text', + bargeIn: true, + loop: 3, + level: 0.5, + language: 'en-GB', + style: 1, + premium: true, + eventOnCompletion: true, + eventUrl: [ + 'https://example.com/event' + ], + eventMethod: 'GET' + ) assert_equal expected, talk.create_talk!(talk) end @@ -30,9 +60,9 @@ def test_talk_with_invalid_barge_in_value end def test_talk_with_invalid_loop_value - exception = assert_raises { Vonage::Voice::Actions::Talk.new({ text: 'Sample Text', loop: 3 }) } + exception = assert_raises { Vonage::Voice::Actions::Talk.new({ text: 'Sample Text', loop: -1 }) } - assert_match "Expected 'loop' value to be either 1 or 0", exception.message + assert_match "Expected 'loop' value to be either 0 or a positive integer", exception.message end def test_talk_with_invalid_level @@ -52,4 +82,28 @@ def test_talk_with_invalid_premium_value assert_match "Expected 'premium' value to be a Boolean", exception.message end + + def test_talk_with_invalid_event_on_completion_value + exception = assert_raises { Vonage::Voice::Actions::Talk.new({ text: 'Sample Text', eventOnCompletion: 'true' }) } + + assert_match "Expected 'eventOnCompletion' value to be a Boolean", exception.message + end + + def test_talk_with_invalid_event_url_type + exception = assert_raises { Vonage::Voice::Actions::Talk.new({ text: 'Sample Text', eventUrl: 'https://example.com/event' }) } + + assert_match "Expected 'eventUrl' parameter to be an Array containing a single string item", exception.message + end + + def test_talk_with_invalid_event_url + exception = assert_raises { Vonage::Voice::Actions::Talk.new({ text: 'Sample Text', eventUrl: ['foo.bar'] }) } + + assert_match "Invalid 'eventUrl' value, array must contain a valid URL", exception.message + end + + def test_talk_with_invalid_event_method + exception = assert_raises { Vonage::Voice::Actions::Talk.new({ text: 'Sample Text', eventMethod: 'PATCH' }) } + + assert_match "Invalid 'eventMethod' value. must be either: 'GET' or 'POST'", exception.message + end end