bandwidth-sdk 18.3.1 → 19.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +13 -13
  3. data/README.md +1 -10
  4. data/Rakefile +1 -1
  5. data/bandwidth.yml +285 -109
  6. data/coverage/.last_run.json +1 -1
  7. data/coverage/.resultset.json +1400 -1051
  8. data/coverage/index.html +20186 -16225
  9. data/custom_templates/api_client.mustache +3 -1
  10. data/custom_templates/configuration.mustache +18 -12
  11. data/custom_templates/gem.mustache +2 -2
  12. data/docs/Callback.md +1 -0
  13. data/docs/CallsApi.md +5 -25
  14. data/docs/ConferencesApi.md +9 -45
  15. data/docs/DisconnectCallback.md +6 -2
  16. data/docs/EndpointsApi.md +5 -25
  17. data/docs/InboundCallback.md +1 -1
  18. data/docs/InboundCallbackMessage.md +2 -0
  19. data/docs/InitiateCallback.md +1 -1
  20. data/docs/LookupResult.md +2 -2
  21. data/docs/MFAApi.md +3 -15
  22. data/docs/MediaApi.md +4 -20
  23. data/docs/Message.md +1 -1
  24. data/docs/MessagesApi.md +2 -10
  25. data/docs/MultiChannelAction.md +3 -3
  26. data/docs/MultiChannelActionCalendarEvent.md +3 -3
  27. data/docs/MultiChannelApi.md +1 -5
  28. data/docs/PhoneNumberLookupApi.md +3 -15
  29. data/docs/RbmActionBase.md +3 -3
  30. data/docs/RbmActionDial.md +3 -3
  31. data/docs/RbmActionOpenUrl.md +3 -3
  32. data/docs/RbmActionViewLocation.md +3 -3
  33. data/docs/RbmSession.md +26 -0
  34. data/docs/RbmSuggestionResponse.md +4 -4
  35. data/docs/RecordingsApi.md +10 -50
  36. data/docs/StatisticsApi.md +1 -5
  37. data/docs/StatusCallback.md +2 -2
  38. data/docs/StatusCallbackMessage.md +3 -1
  39. data/docs/TollFreeVerificationApi.md +9 -45
  40. data/docs/TranscriptionsApi.md +3 -15
  41. data/docs/TransferDisconnectCallback.md +7 -1
  42. data/lib/bandwidth-sdk/api/calls_api.rb +5 -5
  43. data/lib/bandwidth-sdk/api/conferences_api.rb +9 -9
  44. data/lib/bandwidth-sdk/api/endpoints_api.rb +5 -5
  45. data/lib/bandwidth-sdk/api/media_api.rb +4 -4
  46. data/lib/bandwidth-sdk/api/messages_api.rb +2 -2
  47. data/lib/bandwidth-sdk/api/mfa_api.rb +3 -3
  48. data/lib/bandwidth-sdk/api/multi_channel_api.rb +1 -1
  49. data/lib/bandwidth-sdk/api/phone_number_lookup_api.rb +3 -3
  50. data/lib/bandwidth-sdk/api/recordings_api.rb +10 -10
  51. data/lib/bandwidth-sdk/api/statistics_api.rb +1 -1
  52. data/lib/bandwidth-sdk/api/toll_free_verification_api.rb +9 -9
  53. data/lib/bandwidth-sdk/api/transcriptions_api.rb +3 -3
  54. data/lib/bandwidth-sdk/api_client.rb +3 -1
  55. data/lib/bandwidth-sdk/configuration.rb +18 -19
  56. data/lib/bandwidth-sdk/models/callback.rb +1 -0
  57. data/lib/bandwidth-sdk/models/disconnect_callback.rb +27 -5
  58. data/lib/bandwidth-sdk/models/inbound_callback_message.rb +10 -1
  59. data/lib/bandwidth-sdk/models/initiate_callback.rb +1 -1
  60. data/lib/bandwidth-sdk/models/list_message_item.rb +1 -0
  61. data/lib/bandwidth-sdk/models/multi_channel_action_calendar_event.rb +1 -1
  62. data/lib/bandwidth-sdk/models/rbm_action_base.rb +1 -1
  63. data/lib/bandwidth-sdk/models/rbm_action_dial.rb +1 -1
  64. data/lib/bandwidth-sdk/models/rbm_action_open_url.rb +1 -1
  65. data/lib/bandwidth-sdk/models/rbm_action_view_location.rb +1 -1
  66. data/lib/bandwidth-sdk/models/rbm_session.rb +208 -0
  67. data/lib/bandwidth-sdk/models/rbm_suggestion_response.rb +2 -2
  68. data/lib/bandwidth-sdk/models/status_callback_message.rb +13 -4
  69. data/lib/bandwidth-sdk/models/status_callback_type_enum.rb +2 -1
  70. data/lib/bandwidth-sdk/models/transfer_disconnect_callback.rb +37 -5
  71. data/lib/bandwidth-sdk/version.rb +1 -1
  72. data/lib/bandwidth-sdk.rb +3 -2
  73. data/spec/smoke/calls_api_spec.rb +46 -46
  74. data/spec/smoke/conferences_api_spec.rb +1 -1
  75. data/spec/smoke/endpoints_api_spec.rb +2 -31
  76. data/spec/smoke/media_api_spec.rb +2 -0
  77. data/spec/smoke/messages_api_spec.rb +2 -24
  78. data/spec/smoke/mfa_api_spec.rb +4 -27
  79. data/spec/smoke/multi_channel_api_spec.rb +4 -2
  80. data/spec/smoke/phone_number_lookup_api_spec.rb +2 -0
  81. data/spec/smoke/recordings_api_spec.rb +1 -1
  82. data/spec/smoke/smoke_helper.rb +41 -0
  83. data/spec/smoke/statistics_api_spec.rb +2 -37
  84. data/spec/smoke/toll_free_verification_api_spec.rb +2 -0
  85. data/spec/smoke/transcriptions_api_spec.rb +1 -1
  86. data/spec/spec_helper.rb +0 -48
  87. data/spec/unit/api/calls_api_spec.rb +3 -1
  88. data/spec/unit/api/conferences_api_spec.rb +2 -0
  89. data/spec/unit/api/endpoints_api_spec.rb +2 -0
  90. data/spec/unit/api/media_api_spec.rb +2 -0
  91. data/spec/unit/api/messages_api_spec.rb +2 -0
  92. data/spec/unit/api/mfa_api_spec.rb +2 -0
  93. data/spec/unit/api/multi_channel_api_spec.rb +2 -0
  94. data/spec/unit/api/phone_number_lookup_api_spec.rb +2 -0
  95. data/spec/unit/api/recordings_api_spec.rb +2 -0
  96. data/spec/unit/api/statistics_api_spec.rb +2 -0
  97. data/spec/unit/api/toll_free_verification_api_spec.rb +2 -0
  98. data/spec/unit/api/transcriptions_api_spec.rb +2 -0
  99. data/spec/unit/client/api_client_spec.rb +70 -206
  100. data/spec/unit/client/configuration_spec.rb +22 -17
  101. data/spec/unit/constants.rb +6 -0
  102. data/spec/unit/models/callback_spec.rb +1 -0
  103. data/spec/unit/models/disconnect_callback_spec.rb +10 -2
  104. data/spec/unit/models/inbound_callback_message_spec.rb +20 -5
  105. data/spec/unit/models/list_message_item_spec.rb +1 -0
  106. data/spec/unit/models/rbm_session_spec.rb +95 -0
  107. data/spec/unit/models/status_callback_message_spec.rb +20 -5
  108. data/spec/unit/models/status_callback_type_enum_spec.rb +7 -1
  109. data/spec/unit/models/transfer_disconnect_callback_spec.rb +16 -4
  110. metadata +9 -1
@@ -1,3 +1,5 @@
1
+ require_relative '../constants'
2
+
1
3
  # Unit tests for Bandwidth::RecordingsApi
2
4
  describe 'RecordingsApi' do
3
5
  let(:call_id) { 'c-1234' }
@@ -1,3 +1,5 @@
1
+ require_relative '../constants'
2
+
1
3
  # Unit tests for Bandwidth::StatisticsApi
2
4
  describe 'StatisticsApi' do
3
5
  before(:all) do
@@ -1,3 +1,5 @@
1
+ require_relative '../constants'
2
+
1
3
  # Unit tests for Bandwidth::TollFreeVerificationApi
2
4
  describe 'TollFreeVerificationApi' do
3
5
  let (:webhook_subscription_request_schema) { Bandwidth::WebhookSubscriptionRequestSchema.new(
@@ -1,3 +1,5 @@
1
+ require_relative '../constants'
2
+
1
3
  # Unit tests for Bandwidth::TranscriptionsApi
2
4
  describe 'TranscriptionsApi' do
3
5
  let(:call_id) { 'c-1234' }
@@ -12,199 +12,6 @@ describe Bandwidth::ApiClient do
12
12
  let(:form_encoded_headers) { { 'Content-Type' => 'application/x-www-form-urlencoded' } }
13
13
  let(:error_data) { '{"error": true}' }
14
14
 
15
- describe '#call_api' do
16
- it 'calls api and returns a tempfile with name from content-disposition header' do
17
- stub_request(:get, 'https://messaging.bandwidth.com/api/v2/path').
18
- to_return(status: 200, headers: media_headers, body: media_data)
19
-
20
- opts = {
21
- operation: :"MediaApi.get_media",
22
- header_params: {},
23
- query_params: {},
24
- form_params: {},
25
- body: nil,
26
- auth_names: ['Basic'],
27
- return_type: 'File'
28
- }
29
- data, status_code, headers = api_client.call_api(:GET, 'path', opts)
30
-
31
- expect(status_code).to eq(200)
32
- expect(headers).to eq(media_headers)
33
- expect(data).to be_a(Tempfile)
34
- end
35
-
36
- it 'calls api and returns a tempfile' do
37
- stub_request(:get, 'https://messaging.bandwidth.com/api/v2/path').
38
- to_return(status: 200, headers: named_media_headers, body: media_data)
39
-
40
- opts = {
41
- operation: :"MediaApi.get_media",
42
- header_params: {},
43
- query_params: {},
44
- form_params: {},
45
- body: nil,
46
- auth_names: ['Basic'],
47
- return_type: 'File'
48
- }
49
- data, status_code, headers = api_client.call_api(:GET, 'path', opts)
50
-
51
- expect(status_code).to eq(200)
52
- expect(headers).to eq(named_media_headers)
53
- expect(data).to be_a(Tempfile)
54
- end
55
-
56
- it 'calls api and returns binary data' do
57
- stub_request(:get, 'https://messaging.bandwidth.com/api/v2/path').
58
- to_return(status: 200, headers: media_headers, body: media_data)
59
-
60
- api_client.config.return_binary_data = true
61
- api_client.config.debugging = true
62
-
63
- opts = {
64
- operation: :"MediaApi.get_media",
65
- header_params: {},
66
- query_params: {},
67
- form_params: {},
68
- body: nil,
69
- auth_names: ['Basic'],
70
- return_type: 'File'
71
- }
72
- data, status_code, headers = api_client.call_api(:GET, 'path', opts)
73
-
74
- expect(status_code).to eq(200)
75
- expect(headers).to eq(media_headers)
76
- expect(data).to eq(media_data)
77
- end
78
-
79
- it 'calls api and returns a hash' do
80
- stub_request(:get, 'https://messaging.bandwidth.com/api/v2/path').
81
- to_return(status: 200, headers: json_headers, body: '{"id": 1}')
82
-
83
- opts = {
84
- operation: :"MessagesApi.list_messages",
85
- header_params: {},
86
- query_params: {},
87
- form_params: {},
88
- body: nil,
89
- auth_names: ['Basic'],
90
- return_type: 'Hash<String, Integer>'
91
- }
92
- data, status_code, headers = api_client.call_api(:GET, 'path', opts)
93
-
94
- expect(status_code).to eq(200)
95
- expect(headers).to eq(json_headers)
96
- expect(data).to eq({ id: 1 })
97
- end
98
-
99
- it 'posts data and returns nothing' do
100
- stub_request(:post, 'https://messaging.bandwidth.com/api/v2/path').
101
- to_return(status: 204)
102
-
103
- api_client.config.debugging = true
104
-
105
- opts = {
106
- operation: :"MediaApi.upload_media",
107
- header_params: {},
108
- query_params: {},
109
- form_params: {},
110
- body: { id: 1 },
111
- auth_names: ['Basic'],
112
- return_type: nil
113
- }
114
- data, status_code = api_client.call_api(:POST, 'path', opts)
115
-
116
- expect(status_code).to eq(204)
117
- expect(data).to be nil
118
- end
119
-
120
- it 'posts multipart/form-data and returns nothing' do
121
- stub_request(:post, 'https://messaging.bandwidth.com/api/v2/path').
122
- to_return(status: 204)
123
-
124
- opts = {
125
- operation: :"MediaApi.upload_media",
126
- header_params: multipart_headers,
127
- query_params: {},
128
- form_params: { file: Tempfile.new('filename'), array: [1, 2, 3], string: '123' },
129
- body: nil,
130
- auth_names: ['Basic'],
131
- return_type: nil
132
- }
133
- data, status_code = api_client.call_api(:POST, 'path', opts)
134
-
135
- expect(status_code).to eq(204)
136
- expect(data).to be nil
137
- end
138
-
139
- it 'calls api and handles HTTP error' do
140
- stub_request(:post, 'https://messaging.bandwidth.com/api/v2/path').
141
- to_return(status: 400, headers: json_headers, body: error_data)
142
-
143
- opts = {
144
- operation: :"MediaApi.upload_media",
145
- header_params: {},
146
- query_params: {},
147
- form_params: {},
148
- body: { id: 1 },
149
- auth_names: ['Basic'],
150
- return_type: nil
151
- }
152
-
153
- expect {
154
- api_client.call_api(:POST, 'path', opts)
155
- }.to raise_error { |e|
156
- expect(e).to be_instance_of(Bandwidth::ApiError)
157
- expect(e.code).to eq(400)
158
- expect(e.response_headers).to eq(json_headers)
159
- expect(e.response_body).to eq('{"error": true}')
160
- }
161
- end
162
-
163
- it 'calls api and handles timeout error' do
164
- stub_request(:post, 'https://messaging.bandwidth.com/api/v2/path').
165
- to_raise(Faraday::TimeoutError)
166
-
167
- opts = {
168
- operation: :"MediaApi.upload_media",
169
- header_params: {},
170
- query_params: {},
171
- form_params: {},
172
- body: { id: 1 },
173
- auth_names: ['Basic'],
174
- return_type: nil
175
- }
176
-
177
- expect {
178
- api_client.call_api(:POST, 'path', opts)
179
- }.to raise_error { |e|
180
- expect(e).to be_instance_of(Bandwidth::ApiError)
181
- expect(e.message).to eq('Connection timed out')
182
- }
183
- end
184
-
185
- it 'calls api and handles connection error' do
186
- stub_request(:post, 'https://messaging.bandwidth.com/api/v2/path').
187
- to_raise(Faraday::ConnectionFailed)
188
-
189
- opts = {
190
- operation: :"MediaApi.upload_media",
191
- header_params: {},
192
- query_params: {},
193
- form_params: {},
194
- body: { id: 1 },
195
- auth_names: ['Basic'],
196
- return_type: nil
197
- }
198
-
199
- expect {
200
- api_client.call_api(:POST, 'path', opts)
201
- }.to raise_error { |e|
202
- expect(e).to be_instance_of(Bandwidth::ApiError)
203
- expect(e.message).to eq('Connection failed')
204
- }
205
- end
206
- end if false # not needed since the api unit tests cover this
207
-
208
15
  describe '#build_request_body' do
209
16
  it 'builds application/x-www-form-urlencoded' do
210
17
  expect(api_client_default.build_request_body(form_encoded_headers, { id: 1 }, nil)).to eq('id=1')
@@ -232,16 +39,6 @@ describe Bandwidth::ApiClient do
232
39
  end
233
40
  end
234
41
 
235
- describe '#basic_auth' do
236
- it 'sets basic auth for the connection' do
237
- api_client.config.username = 'username'
238
- api_client.config.password = 'password'
239
- api_client.basic_auth(faraday_connection)
240
- expect(api_client.config.username).to eq('username')
241
- expect(api_client.config.password).to eq('password')
242
- end
243
- end
244
-
245
42
  describe '#json_mime?' do
246
43
  it 'checks if the given MIME is a JSON MIME' do
247
44
  expect(api_client_default.json_mime?(nil)).to eq false
@@ -292,9 +89,76 @@ describe Bandwidth::ApiClient do
292
89
  end
293
90
  end
294
91
 
295
- describe '#update_params_for_auth' do
296
- it 'updates header and query params based on authentication settings' do
297
-
92
+ describe 'request authentication' do
93
+ let(:messages_api) { Bandwidth::MessagesApi.new(api_client) }
94
+ let(:stubs) { Faraday::Adapter::Test::Stubs.new }
95
+ let(:token_requests) { [] }
96
+ let(:authorization_headers) { [] }
97
+ let(:expires_in) { 3600 }
98
+ let(:now) { Time.utc(2026, 1, 1) }
99
+
100
+ before do
101
+ allow(Time).to receive(:now).and_return(now)
102
+ allow(Faraday).to receive(:new).and_wrap_original do |original, *args, &block|
103
+ original.call(*args, &block).tap { |connection| connection.adapter :test, stubs }
104
+ end
105
+ config.client_id = 'client_id'
106
+ config.client_secret = 'client_secret'
107
+ stubs.post('https://api.bandwidth.com/api/v1/oauth2/token') do |request|
108
+ token_requests << request
109
+ [200, { 'Content-Type' => 'application/json' },
110
+ { access_token: "token_#{token_requests.length}", expires_in: expires_in }.to_json]
111
+ end
112
+ stubs.get('https://messaging.bandwidth.com/api/v2/users/account/messages') do |request|
113
+ authorization_headers << request.request_headers['Authorization']
114
+ [200, { 'Content-Type' => 'application/json' }, '{"data":[]}']
115
+ end
116
+ end
117
+
118
+ [1, 30, 60].each do |lifetime|
119
+ context "with a #{lifetime}-second token" do
120
+ let(:expires_in) { lifetime }
121
+
122
+ it 'acquires once per request and checks expiration again on the next request' do
123
+ messages_api.list_messages('account')
124
+ expect(token_requests.length).to eq(1)
125
+ expect(authorization_headers).to eq(['Bearer token_1'])
126
+
127
+ messages_api.list_messages('account')
128
+ expect(token_requests.length).to eq(2)
129
+ expect(authorization_headers).to eq(['Bearer token_1', 'Bearer token_2'])
130
+ end
131
+ end
132
+ end
133
+
134
+ it 'reuses a token until it reaches the 60-second expiration buffer' do
135
+ messages_api.list_messages('account')
136
+ allow(Time).to receive(:now).and_return(now + 3539)
137
+ messages_api.list_messages('account')
138
+ expect(token_requests.length).to eq(1)
139
+ expect(authorization_headers).to eq(['Bearer token_1', 'Bearer token_1'])
140
+
141
+ allow(Time).to receive(:now).and_return(now + 3540)
142
+ messages_api.list_messages('account')
143
+ expect(token_requests.length).to eq(2)
144
+ expect(authorization_headers.last).to eq('Bearer token_2')
145
+ end
146
+
147
+ it 'sends no Authorization header when OAuth credentials are absent' do
148
+ config.client_id = nil
149
+ config.client_secret = nil
150
+ messages_api.list_messages('account')
151
+ expect(token_requests).to be_empty
152
+ expect(authorization_headers).to eq([nil])
153
+ end
154
+
155
+ [nil, []].each do |auth_names|
156
+ it "does not acquire a token when auth_names is #{auth_names.inspect}" do
157
+ api_client.call_api(:GET, '/users/account/messages',
158
+ operation: :'MessagesApi.list_messages', auth_names: auth_names, header_params: {})
159
+ expect(token_requests).to be_empty
160
+ expect(authorization_headers).to eq([nil])
161
+ end
298
162
  end
299
163
  end
300
164
 
@@ -1,4 +1,5 @@
1
1
  require 'uri'
2
+ require_relative '../constants'
2
3
 
3
4
  # Unit tests for Bandwidth::Configuration
4
5
  describe Bandwidth::Configuration do
@@ -105,11 +106,21 @@ describe Bandwidth::Configuration do
105
106
  end
106
107
  end
107
108
 
108
- describe '#basic_auth_token' do
109
- it 'gets Basic Auth token string' do
110
- config.username = 'username'
111
- config.password = 'password'
112
- expect(config.basic_auth_token).to eq('Basic dXNlcm5hbWU6cGFzc3dvcmQ=')
109
+ describe '#username=' do
110
+ it 'raises because basic auth is no longer supported' do
111
+ expect {
112
+ config.username = 'username'
113
+ }.to raise_error(ArgumentError, 'HTTP basic authentication is no longer supported. Use client_id and client_secret instead.')
114
+ expect(config.username).to be_nil
115
+ end
116
+ end
117
+
118
+ describe '#password=' do
119
+ it 'raises because basic auth is no longer supported' do
120
+ expect {
121
+ config.password = 'password'
122
+ }.to raise_error(ArgumentError, 'HTTP basic authentication is no longer supported. Use client_id and client_secret instead.')
123
+ expect(config.password).to be_nil
113
124
  end
114
125
  end
115
126
 
@@ -121,8 +132,10 @@ describe Bandwidth::Configuration do
121
132
  end
122
133
 
123
134
  it 'returns the Bearer string using access_token_getter when defined' do
124
- config.access_token_getter = proc { token }
125
- expect(config.oauth_bearer_token).to eq("Bearer #{token}")
135
+ tokens = ['first_token', 'second_token']
136
+ config.access_token_getter = proc { tokens.shift }
137
+ expect(config.oauth_bearer_token).to eq('Bearer first_token')
138
+ expect(config.oauth_bearer_token).to eq('Bearer second_token')
126
139
  end
127
140
 
128
141
  it 'returns nil when no access_token is available' do
@@ -191,14 +204,6 @@ describe Bandwidth::Configuration do
191
204
  end
192
205
 
193
206
  describe '#auth_settings' do
194
- it 'returns Basic auth entry for api client' do
195
- basic_auth = config.auth_settings['Basic']
196
- expect(basic_auth[:type]).to eq('basic')
197
- expect(basic_auth[:in]).to eq('header')
198
- expect(basic_auth[:key]).to eq('Authorization')
199
- expect(basic_auth[:value]).to eq('Basic Og==')
200
- end
201
-
202
207
  it 'returns OAuth2 auth entry for api client' do
203
208
  config.access_token = token
204
209
  config.access_token_getter = nil
@@ -231,10 +236,10 @@ describe Bandwidth::Configuration do
231
236
  describe 'configure faraday connection' do
232
237
  it '#configure_faraday_connection #configure_connection' do
233
238
  config.configure_faraday_connection do |c|
234
- config.username = 'username'
239
+ config.client_id = 'client_id'
235
240
  end
236
241
  config.configure_connection(faraday_connection)
237
- expect(config.username).to eq('username')
242
+ expect(config.client_id).to eq('client_id')
238
243
  end
239
244
  end
240
245
 
@@ -0,0 +1,6 @@
1
+ BW_ACCOUNT_ID = '9900000'
2
+ BW_NUMBER = '+19195551234'
3
+ USER_NUMBER = '+19195554321'
4
+ BW_VOICE_APPLICATION_ID = 'abc12345-6def-abc1-2345-6defabc12345'
5
+ BW_MESSAGING_APPLICATION_ID = 'abc12345-6def-abc1-2345-6defabc12345'
6
+ BASE_CALLBACK_URL = 'https://example.com'
@@ -25,6 +25,7 @@ describe Bandwidth::Callback do
25
25
  :'message-sending' => :'StatusCallback',
26
26
  :'message-sent' => :'StatusCallback',
27
27
  :'requested-location-response' => :'InboundCallback',
28
+ :'session-started' => :'StatusCallback',
28
29
  :'suggestion-response' => :'InboundCallback'
29
30
  })
30
31
  end
@@ -21,6 +21,8 @@ describe Bandwidth::DisconnectCallback do
21
21
  tag: 'custom tag',
22
22
  sip_call_id: 'sip-call-id-12345',
23
23
  sip_response_code: '486',
24
+ sip_status_line: 'SIP/2.0 486 Busy Here',
25
+ sip_headers: { 'reason' => 'v=analytics1' }
24
26
  }) }
25
27
 
26
28
  describe '#initialize' do
@@ -77,6 +79,8 @@ describe Bandwidth::DisconnectCallback do
77
79
  tag: 'custom tag',
78
80
  sipCallId: 'sip-call-id-12345',
79
81
  sipResponseCode: 486,
82
+ sipStatusLine: 'SIP/2.0 486 Busy Here',
83
+ sipHeaders: { 'reason' => 'v=analytics1' }
80
84
  })
81
85
  expect(disconnect_callback_from_hash).to be_instance_of(Bandwidth::DisconnectCallback)
82
86
  expect(disconnect_callback_from_hash.event_type).to eq('disconnect')
@@ -98,12 +102,14 @@ describe Bandwidth::DisconnectCallback do
98
102
  expect(disconnect_callback_from_hash.tag).to eq('custom tag')
99
103
  expect(disconnect_callback_from_hash.sip_call_id).to eq('sip-call-id-12345')
100
104
  expect(disconnect_callback_from_hash.sip_response_code).to eq(486)
105
+ expect(disconnect_callback_from_hash.sip_status_line).to eq('SIP/2.0 486 Busy Here')
106
+ expect(disconnect_callback_from_hash.sip_headers).to eq({ 'reason' => 'v=analytics1' })
101
107
  end
102
108
  end
103
109
 
104
110
  describe '#to_s' do
105
111
  it 'returns a string representation of the object' do
106
- expect(disconnect_callback_values.to_s).to eq({ :eventType => 'disconnect', :eventTime => '2022-06-16T13:15:07.160Z', :accountId => '9900000', :applicationId => '04e88489-df02-4e34-a0ee-27a91849555f', :from => '+19195554321', :to => '+19195551234', :callId => 'c-15ac29a2-1331029c-2cb0-4a07-b215-b22865662d85', :direction => 'inbound', :callUrl => 'https://voice.bandwidth.com/api/v2/accounts/9900000/calls/c-15ac29a2-1331029c-2cb0-4a07-b215-b22865662d85', :enqueuedTime => '2022-06-16T13:15:07.160Z', :startTime => '2022-06-16T13:15:07.160Z', :answerTime => '2022-06-16T13:15:18.126Z', :endTime => '2022-06-16T13:16:18.126Z', :cause => 'hangup', :errorMessage => 'call rejected', :errorId => '4642074b-7b58-478b-96e4-3a60955c6765', :tag => 'custom tag', :sipCallId => 'sip-call-id-12345', :sipResponseCode => '486' }.to_s)
112
+ expect(disconnect_callback_values.to_s).to eq({ :eventType => 'disconnect', :eventTime => '2022-06-16T13:15:07.160Z', :accountId => '9900000', :applicationId => '04e88489-df02-4e34-a0ee-27a91849555f', :from => '+19195554321', :to => '+19195551234', :callId => 'c-15ac29a2-1331029c-2cb0-4a07-b215-b22865662d85', :direction => 'inbound', :callUrl => 'https://voice.bandwidth.com/api/v2/accounts/9900000/calls/c-15ac29a2-1331029c-2cb0-4a07-b215-b22865662d85', :enqueuedTime => '2022-06-16T13:15:07.160Z', :startTime => '2022-06-16T13:15:07.160Z', :answerTime => '2022-06-16T13:15:18.126Z', :endTime => '2022-06-16T13:16:18.126Z', :cause => 'hangup', :errorMessage => 'call rejected', :errorId => '4642074b-7b58-478b-96e4-3a60955c6765', :tag => 'custom tag', :sipCallId => 'sip-call-id-12345', :sipResponseCode => '486', :sipStatusLine => 'SIP/2.0 486 Busy Here', :sipHeaders => { 'reason' => 'v=analytics1' } }.to_s)
107
113
  end
108
114
  end
109
115
 
@@ -135,7 +141,9 @@ describe Bandwidth::DisconnectCallback do
135
141
  errorId: '4642074b-7b58-478b-96e4-3a60955c6765',
136
142
  tag: 'custom tag',
137
143
  sipCallId: 'sip-call-id-12345',
138
- sipResponseCode: '486'
144
+ sipResponseCode: '486',
145
+ sipStatusLine: 'SIP/2.0 486 Busy Here',
146
+ sipHeaders: { 'reason' => 'v=analytics1' }
139
147
  })
140
148
  end
141
149
  end
@@ -23,7 +23,11 @@ describe Bandwidth::InboundCallbackMessage do
23
23
  tag: 'custom tag',
24
24
  media: ['https://dev.bandwidth.com/images/bandwidth-logo.png'],
25
25
  priority: Bandwidth::PriorityEnum::DEFAULT,
26
- channel: Bandwidth::MultiChannelMessageChannelEnum::SMS
26
+ channel: Bandwidth::MultiChannelMessageChannelEnum::RBM,
27
+ session: Bandwidth::RbmSession.new({
28
+ can_initiate: false,
29
+ id: '0f5a3b9c-2d4e-4f6a-8b1c-7e9d0a2b3c4d'
30
+ })
27
31
  }) }
28
32
 
29
33
  describe '#initialize' do
@@ -67,7 +71,11 @@ describe Bandwidth::InboundCallbackMessage do
67
71
  tag: 'custom tag',
68
72
  media: ['https://dev.bandwidth.com/images/bandwidth-logo.png'],
69
73
  priority: Bandwidth::PriorityEnum::DEFAULT,
70
- channel: Bandwidth::MultiChannelMessageChannelEnum::SMS
74
+ channel: Bandwidth::MultiChannelMessageChannelEnum::RBM,
75
+ session: {
76
+ canInitiate: false,
77
+ id: '0f5a3b9c-2d4e-4f6a-8b1c-7e9d0a2b3c4d'
78
+ }
71
79
  })
72
80
  expect(inbound_callback_message_from_hash).to be_instance_of(Bandwidth::InboundCallbackMessage)
73
81
  expect(inbound_callback_message_from_hash.id).to eq('1589228074636lm4k2je7j7jklbn2')
@@ -82,13 +90,16 @@ describe Bandwidth::InboundCallbackMessage do
82
90
  expect(inbound_callback_message_from_hash.tag).to eq('custom tag')
83
91
  expect(inbound_callback_message_from_hash.media).to eq(['https://dev.bandwidth.com/images/bandwidth-logo.png'])
84
92
  expect(inbound_callback_message_from_hash.priority).to eq(Bandwidth::PriorityEnum::DEFAULT)
85
- expect(inbound_callback_message_from_hash.channel).to eq(Bandwidth::MultiChannelMessageChannelEnum::SMS)
93
+ expect(inbound_callback_message_from_hash.channel).to eq(Bandwidth::MultiChannelMessageChannelEnum::RBM)
94
+ expect(inbound_callback_message_from_hash.session).to be_instance_of(Bandwidth::RbmSession)
95
+ expect(inbound_callback_message_from_hash.session.can_initiate).to be false
96
+ expect(inbound_callback_message_from_hash.session.id).to eq('0f5a3b9c-2d4e-4f6a-8b1c-7e9d0a2b3c4d')
86
97
  end
87
98
  end
88
99
 
89
100
  describe '#to_s' do
90
101
  it 'returns a string representation of the object' do
91
- expect(inbound_callback_message_values.to_s).to eq({ :id => '1589228074636lm4k2je7j7jklbn2', :owner => '+19195554321', :applicationId => '93de2206-9669-4e07-948d-329f4b722ee2', :time => '2022-06-16T13:15:07.160Z', :segmentCount => 2, :direction => 'in', :to => ['+19195551234'], :from => '+19195554321', :text => 'Hello world', :tag => 'custom tag', :media => ['https://dev.bandwidth.com/images/bandwidth-logo.png'], :priority => 'default', :channel => 'SMS' }.to_s)
102
+ expect(inbound_callback_message_values.to_s).to eq({ :id => '1589228074636lm4k2je7j7jklbn2', :owner => '+19195554321', :applicationId => '93de2206-9669-4e07-948d-329f4b722ee2', :time => '2022-06-16T13:15:07.160Z', :segmentCount => 2, :direction => 'in', :to => ['+19195551234'], :from => '+19195554321', :text => 'Hello world', :tag => 'custom tag', :media => ['https://dev.bandwidth.com/images/bandwidth-logo.png'], :priority => 'default', :channel => 'RBM', :session => { :canInitiate => false, :id => '0f5a3b9c-2d4e-4f6a-8b1c-7e9d0a2b3c4d' } }.to_s)
92
103
  end
93
104
  end
94
105
 
@@ -124,7 +135,11 @@ describe Bandwidth::InboundCallbackMessage do
124
135
  tag: 'custom tag',
125
136
  media: ['https://dev.bandwidth.com/images/bandwidth-logo.png'],
126
137
  priority: Bandwidth::PriorityEnum::DEFAULT,
127
- channel: Bandwidth::MultiChannelMessageChannelEnum::SMS
138
+ channel: Bandwidth::MultiChannelMessageChannelEnum::RBM,
139
+ session: {
140
+ canInitiate: false,
141
+ id: '0f5a3b9c-2d4e-4f6a-8b1c-7e9d0a2b3c4d'
142
+ }
128
143
  })
129
144
  end
130
145
  end
@@ -52,6 +52,7 @@ describe Bandwidth::ListMessageItem do
52
52
  expect(Bandwidth::ListMessageItem.openapi_nullable).to eq(Set.new([
53
53
  :'carrier_name',
54
54
  :'message_size',
55
+ :'message_length',
55
56
  :'attachment_count',
56
57
  :'recipient_count',
57
58
  :'campaign_class',
@@ -0,0 +1,95 @@
1
+ # Unit tests for Bandwidth::RbmSession
2
+ describe Bandwidth::RbmSession do
3
+ let(:rbm_session_default) { Bandwidth::RbmSession.new({
4
+ can_initiate: true
5
+ }) }
6
+ let(:rbm_session_values) { Bandwidth::RbmSession.new({
7
+ can_initiate: false,
8
+ id: '0f5a3b9c-2d4e-4f6a-8b1c-7e9d0a2b3c4d',
9
+ type: 'INTERACTIVE_SESSION',
10
+ start_time: '2026-08-06T09:59:55Z',
11
+ end_time: '2026-08-07T09:59:55Z'
12
+ }) }
13
+
14
+ describe '#initialize' do
15
+ it 'causes an ArgumentError by passing an Array to the initialize method' do
16
+ expect {
17
+ Bandwidth::RbmSession.new([])
18
+ }.to raise_error(ArgumentError)
19
+ end
20
+
21
+ it 'causes an ArgumentError by passing an invalid attribute to the initialize method' do
22
+ expect {
23
+ Bandwidth::RbmSession.new({ invalid: true })
24
+ }.to raise_error(ArgumentError)
25
+ end
26
+ end
27
+
28
+ describe '#acceptable_attributes' do
29
+ it 'expects acceptable JSON attributes to be those in the attribute map' do
30
+ expect(Bandwidth::RbmSession.acceptable_attributes).to eq(Bandwidth::RbmSession.attribute_map.values)
31
+ end
32
+ end
33
+
34
+ describe '#openapi_nullable' do
35
+ it 'expects nullable attributes to be the set of nullable fields' do
36
+ expect(Bandwidth::RbmSession.openapi_nullable).to eq(Set.new([
37
+ :'id',
38
+ :'type',
39
+ :'start_time',
40
+ :'end_time'
41
+ ]))
42
+ end
43
+ end
44
+
45
+ describe '#build_from_hash' do
46
+ it 'validates instance of RbmSession created by the build_from_hash method' do
47
+ rbm_session_from_hash = Bandwidth::RbmSession.build_from_hash({
48
+ canInitiate: false,
49
+ id: '0f5a3b9c-2d4e-4f6a-8b1c-7e9d0a2b3c4d',
50
+ type: 'INTERACTIVE_SESSION',
51
+ startTime: '2026-08-06T09:59:55Z',
52
+ endTime: '2026-08-07T09:59:55Z'
53
+ })
54
+ expect(rbm_session_from_hash).to be_instance_of(Bandwidth::RbmSession)
55
+ expect(rbm_session_from_hash.can_initiate).to be false
56
+ expect(rbm_session_from_hash.id).to eq('0f5a3b9c-2d4e-4f6a-8b1c-7e9d0a2b3c4d')
57
+ expect(rbm_session_from_hash.type).to eq('INTERACTIVE_SESSION')
58
+ expect(rbm_session_from_hash.start_time).to eq(Time.parse('2026-08-06T09:59:55Z'))
59
+ expect(rbm_session_from_hash.end_time).to eq(Time.parse('2026-08-07T09:59:55Z'))
60
+ end
61
+ end
62
+
63
+ describe '#to_s' do
64
+ it 'returns a string representation of the object' do
65
+ expect(rbm_session_values.to_s).to eq({ :canInitiate => false, :id => '0f5a3b9c-2d4e-4f6a-8b1c-7e9d0a2b3c4d', :type => 'INTERACTIVE_SESSION', :startTime => '2026-08-06T09:59:55Z', :endTime => '2026-08-07T09:59:55Z' }.to_s)
66
+ end
67
+ end
68
+
69
+ describe '#eq? #==' do
70
+ it 'returns true/false when comparing objects' do
71
+ expect(rbm_session_default.eql?(Bandwidth::RbmSession.new({ can_initiate: true }))).to be true
72
+ expect(rbm_session_default.eql?(rbm_session_values)).to be false
73
+ end
74
+ end
75
+
76
+ describe '#to_body #to_hash' do
77
+ it 'returns a hash representation of the object' do
78
+ expect(rbm_session_values.to_body).to eq({
79
+ canInitiate: false,
80
+ id: '0f5a3b9c-2d4e-4f6a-8b1c-7e9d0a2b3c4d',
81
+ type: 'INTERACTIVE_SESSION',
82
+ startTime: '2026-08-06T09:59:55Z',
83
+ endTime: '2026-08-07T09:59:55Z'
84
+ })
85
+ end
86
+ end
87
+
88
+ describe 'custom attribute writers' do
89
+ it '#can_initiate=' do
90
+ expect {
91
+ rbm_session_values.can_initiate = nil
92
+ }.to raise_error(ArgumentError, 'can_initiate cannot be nil')
93
+ end
94
+ end
95
+ end