twilio_base 1.8.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 (179) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +82 -0
  5. data/.ruby-version +1 -0
  6. data/.tool-versions +1 -0
  7. data/Gemfile +8 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +142 -0
  10. data/Rakefile +12 -0
  11. data/app/controllers/twilio_base/base_controller.rb +32 -0
  12. data/app/models/twilio_base/global_config.rb +5 -0
  13. data/app/services/twilio_base/api_key.rb +15 -0
  14. data/app/services/twilio_base/application.rb +29 -0
  15. data/app/services/twilio_base/clients.rb +37 -0
  16. data/app/services/twilio_base/phone_number.rb +40 -0
  17. data/app/services/twilio_base/protocols/voice/base.rb +65 -0
  18. data/app/services/twilio_base/protocols/voice/pstn.rb +13 -0
  19. data/app/services/twilio_base/protocols/voice/sip.rb +48 -0
  20. data/app/services/twilio_base/protocols/voice.rb +24 -0
  21. data/app/services/twilio_base/request_verification_service.rb +21 -0
  22. data/app/services/twilio_base/routers/voice/base.rb +44 -0
  23. data/app/services/twilio_base/routers/voice/default.rb +24 -0
  24. data/app/services/twilio_base/routers/voice/direct_dial.rb +10 -0
  25. data/app/services/twilio_base/routers/voice/task_router.rb +34 -0
  26. data/app/services/twilio_base/sync/service.rb +18 -0
  27. data/app/services/twilio_base/task_router/activity.rb +49 -0
  28. data/app/services/twilio_base/task_router/base.rb +17 -0
  29. data/app/services/twilio_base/task_router/task.rb +33 -0
  30. data/app/services/twilio_base/task_router/task_queue.rb +40 -0
  31. data/app/services/twilio_base/task_router/worker.rb +27 -0
  32. data/app/services/twilio_base/task_router/workflow.rb +22 -0
  33. data/app/services/twilio_base/task_router/workspace.rb +51 -0
  34. data/bin/console +8 -0
  35. data/bin/rails +14 -0
  36. data/bin/setup +6 -0
  37. data/circle.yml +36 -0
  38. data/config/locales/en.yml +2 -0
  39. data/config/routes.rb +4 -0
  40. data/db/migrate/20171214105252_create_twilio_base_global_configs.rb +18 -0
  41. data/lib/twilio_base/engine.rb +7 -0
  42. data/lib/twilio_base/helpers/protocols.rb +12 -0
  43. data/lib/twilio_base/version.rb +5 -0
  44. data/lib/twilio_base.rb +11 -0
  45. data/spec/factories/channel_sid.rb +7 -0
  46. data/spec/factories/chat_member_id.rb +7 -0
  47. data/spec/factories/global_config/activity_sid.rb +7 -0
  48. data/spec/factories/global_config/api_key_secret.rb +7 -0
  49. data/spec/factories/global_config/api_key_sid.rb +7 -0
  50. data/spec/factories/global_config/application_sid.rb +7 -0
  51. data/spec/factories/global_config/chat_service_sid.rb +7 -0
  52. data/spec/factories/global_config/conference_sid.rb +7 -0
  53. data/spec/factories/global_config/message_sid.rb +7 -0
  54. data/spec/factories/global_config/phone_number.rb +7 -0
  55. data/spec/factories/global_config/recording_sid.rb +7 -0
  56. data/spec/factories/global_config/sync_service_sid.rb +7 -0
  57. data/spec/factories/global_config/task_sid.rb +7 -0
  58. data/spec/factories/global_config/voice_call_sid.rb +7 -0
  59. data/spec/factories/global_config/worker_sid.rb +7 -0
  60. data/spec/factories/global_config/workflow_sid.rb +7 -0
  61. data/spec/factories/global_config/workspace_sid.rb +7 -0
  62. data/spec/factories/global_configs.rb +28 -0
  63. data/spec/lib/twilio_base/helpers/protocols_spec.rb +49 -0
  64. data/spec/services/twilio_base/api_key_spec.rb +17 -0
  65. data/spec/services/twilio_base/application_spec.rb +31 -0
  66. data/spec/services/twilio_base/phone_number_spec.rb +49 -0
  67. data/spec/services/twilio_base/protocols/voice/base_spec.rb +134 -0
  68. data/spec/services/twilio_base/protocols/voice/pstn_spec.rb +13 -0
  69. data/spec/services/twilio_base/protocols/voice/sip_spec.rb +104 -0
  70. data/spec/services/twilio_base/protocols/voice_spec.rb +48 -0
  71. data/spec/services/twilio_base/request_verification_service_spec.rb +105 -0
  72. data/spec/services/twilio_base/routers/voice/base_spec.rb +91 -0
  73. data/spec/services/twilio_base/routers/voice/default_spec.rb +59 -0
  74. data/spec/services/twilio_base/routers/voice/task_router_spec.rb +63 -0
  75. data/spec/services/twilio_base/sync/service.rb +25 -0
  76. data/spec/services/twilio_base/task_router/activity_spec.rb +68 -0
  77. data/spec/services/twilio_base/task_router/task_queue_spec.rb +114 -0
  78. data/spec/services/twilio_base/task_router/worker_spec.rb +49 -0
  79. data/spec/services/twilio_base/task_router/workflow_spec.rb +37 -0
  80. data/spec/spec_helper.rb +68 -0
  81. data/spec/support/factory_bot.rb +9 -0
  82. data/spec/support/shared_contexts/global_config.rb +6 -0
  83. data/spec/support/shared_contexts/twilio_controller.rb +7 -0
  84. data/spec/support/twilio_base/fake/api_key.rb +26 -0
  85. data/spec/support/twilio_base/fake/application.rb +59 -0
  86. data/spec/support/twilio_base/fake/available_phone_number.rb +29 -0
  87. data/spec/support/twilio_base/fake/chat/channel.rb +63 -0
  88. data/spec/support/twilio_base/fake/chat/client.rb +40 -0
  89. data/spec/support/twilio_base/fake/chat/member.rb +27 -0
  90. data/spec/support/twilio_base/fake/chat/message.rb +47 -0
  91. data/spec/support/twilio_base/fake/chat/service.rb +52 -0
  92. data/spec/support/twilio_base/fake/clients/rest.rb +84 -0
  93. data/spec/support/twilio_base/fake/clients/sms.rb +27 -0
  94. data/spec/support/twilio_base/fake/conference.rb +48 -0
  95. data/spec/support/twilio_base/fake/flex_flow.rb +36 -0
  96. data/spec/support/twilio_base/fake/helpers.rb +38 -0
  97. data/spec/support/twilio_base/fake/incoming_phone_number.rb +46 -0
  98. data/spec/support/twilio_base/fake/lookup/client.rb +29 -0
  99. data/spec/support/twilio_base/fake/lookup/phone_number.rb +34 -0
  100. data/spec/support/twilio_base/fake/notify/binding.rb +41 -0
  101. data/spec/support/twilio_base/fake/notify/notification.rb +40 -0
  102. data/spec/support/twilio_base/fake/notify/segment_membership.rb +17 -0
  103. data/spec/support/twilio_base/fake/notify/user.rb +30 -0
  104. data/spec/support/twilio_base/fake/notify/v1.rb +33 -0
  105. data/spec/support/twilio_base/fake/proxy.rb +30 -0
  106. data/spec/support/twilio_base/fake/recording.rb +44 -0
  107. data/spec/support/twilio_base/fake/sync/client.rb +17 -0
  108. data/spec/support/twilio_base/fake/sync/service.rb +78 -0
  109. data/spec/support/twilio_base/fake/sync/services/document.rb +50 -0
  110. data/spec/support/twilio_base/fake/sync/services/list.rb +50 -0
  111. data/spec/support/twilio_base/fake/sync/services/lists/item.rb +48 -0
  112. data/spec/support/twilio_base/fake/sync/services/map.rb +50 -0
  113. data/spec/support/twilio_base/fake/sync/services/maps/item.rb +54 -0
  114. data/spec/support/twilio_base/fake/task_router/activity.rb +34 -0
  115. data/spec/support/twilio_base/fake/task_router/channel.rb +40 -0
  116. data/spec/support/twilio_base/fake/task_router/client.rb +31 -0
  117. data/spec/support/twilio_base/fake/task_router/statistic.rb +38 -0
  118. data/spec/support/twilio_base/fake/task_router/task.rb +80 -0
  119. data/spec/support/twilio_base/fake/task_router/task_queue.rb +46 -0
  120. data/spec/support/twilio_base/fake/task_router/worker.rb +64 -0
  121. data/spec/support/twilio_base/fake/task_router/workflow.rb +54 -0
  122. data/spec/support/twilio_base/fake/task_router/workspace.rb +83 -0
  123. data/spec/support/twilio_base/fake/voice_call.rb +54 -0
  124. data/spec/support/twilio_base/responses/twiml.rb +29 -0
  125. data/spec/twilio_base_dummy/.gitignore +21 -0
  126. data/spec/twilio_base_dummy/Rakefile +5 -0
  127. data/spec/twilio_base_dummy/app/assets/config/manifest.js +0 -0
  128. data/spec/twilio_base_dummy/app/channels/application_cable/channel.rb +6 -0
  129. data/spec/twilio_base_dummy/app/channels/application_cable/connection.rb +6 -0
  130. data/spec/twilio_base_dummy/app/controllers/application_controller.rb +5 -0
  131. data/spec/twilio_base_dummy/app/controllers/concerns/.keep +0 -0
  132. data/spec/twilio_base_dummy/app/helpers/application_helper.rb +4 -0
  133. data/spec/twilio_base_dummy/bin/bundle +5 -0
  134. data/spec/twilio_base_dummy/bin/rails +11 -0
  135. data/spec/twilio_base_dummy/bin/rake +11 -0
  136. data/spec/twilio_base_dummy/bin/setup +36 -0
  137. data/spec/twilio_base_dummy/bin/spring +18 -0
  138. data/spec/twilio_base_dummy/bin/update +31 -0
  139. data/spec/twilio_base_dummy/config/application.rb +13 -0
  140. data/spec/twilio_base_dummy/config/boot.rb +7 -0
  141. data/spec/twilio_base_dummy/config/cable.yml +5 -0
  142. data/spec/twilio_base_dummy/config/database.example.yml +13 -0
  143. data/spec/twilio_base_dummy/config/environment.rb +5 -0
  144. data/spec/twilio_base_dummy/config/environments/development.rb +28 -0
  145. data/spec/twilio_base_dummy/config/environments/test.rb +17 -0
  146. data/spec/twilio_base_dummy/config/initializers/application_controller_renderer.rb +1 -0
  147. data/spec/twilio_base_dummy/config/initializers/assets.rb +3 -0
  148. data/spec/twilio_base_dummy/config/initializers/backtrace_silencers.rb +1 -0
  149. data/spec/twilio_base_dummy/config/initializers/cookies_serializer.rb +3 -0
  150. data/spec/twilio_base_dummy/config/initializers/filter_parameter_logging.rb +3 -0
  151. data/spec/twilio_base_dummy/config/initializers/inflections.rb +1 -0
  152. data/spec/twilio_base_dummy/config/initializers/mime_types.rb +1 -0
  153. data/spec/twilio_base_dummy/config/initializers/new_framework_defaults.rb +9 -0
  154. data/spec/twilio_base_dummy/config/initializers/session_store.rb +3 -0
  155. data/spec/twilio_base_dummy/config/initializers/wrap_parameters.rb +5 -0
  156. data/spec/twilio_base_dummy/config/locales/en.yml +23 -0
  157. data/spec/twilio_base_dummy/config/puma.rb +7 -0
  158. data/spec/twilio_base_dummy/config/routes.rb +5 -0
  159. data/spec/twilio_base_dummy/config/secrets.yml +10 -0
  160. data/spec/twilio_base_dummy/config/spring.rb +8 -0
  161. data/spec/twilio_base_dummy/config.ru +7 -0
  162. data/spec/twilio_base_dummy/db/schema.rb +31 -0
  163. data/spec/twilio_base_dummy/db/seeds.rb +1 -0
  164. data/spec/twilio_base_dummy/lib/assets/.keep +0 -0
  165. data/spec/twilio_base_dummy/lib/tasks/.keep +0 -0
  166. data/spec/twilio_base_dummy/log/.keep +0 -0
  167. data/spec/twilio_base_dummy/public/404.html +67 -0
  168. data/spec/twilio_base_dummy/public/422.html +67 -0
  169. data/spec/twilio_base_dummy/public/500.html +66 -0
  170. data/spec/twilio_base_dummy/public/apple-touch-icon-precomposed.png +0 -0
  171. data/spec/twilio_base_dummy/public/apple-touch-icon.png +0 -0
  172. data/spec/twilio_base_dummy/public/favicon.ico +0 -0
  173. data/spec/twilio_base_dummy/public/robots.txt +5 -0
  174. data/spec/twilio_base_dummy/tmp/.keep +0 -0
  175. data/spec/twilio_base_dummy/vendor/assets/javascripts/.keep +0 -0
  176. data/spec/twilio_base_dummy/vendor/assets/stylesheets/.keep +0 -0
  177. data/spec/twilio_base_spec.rb +7 -0
  178. data/twilio_base.gemspec +45 -0
  179. metadata +580 -0
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Helpers::Protocols do
6
+ describe '#extract_mpoa' do
7
+ let(:correct_number) { '+442039605098' }
8
+
9
+ context 'the number can be matched' do
10
+ it 'returns the same number received through PSTN' do
11
+ examples = %w[
12
+ +442039605098
13
+ +442039605098
14
+ 442039605098
15
+ ]
16
+
17
+ examples.each do |eg|
18
+ expect(
19
+ Helpers::Protocols.extract_mpoa(eg)
20
+ ).to eq(correct_number)
21
+ end
22
+ end
23
+
24
+ it 'returns a number from SIP address' do
25
+ examples = %w[
26
+ sip:+442039605098@somedomain.com
27
+ sip:+442039605098@mns-interconnect-test.sip.ie1-ix.twilio.com
28
+ sip:442039605098@mns-interconnect-test.sip.ie1-ix.twilio.com
29
+ ]
30
+
31
+ examples.each do |eg|
32
+ expect(
33
+ Helpers::Protocols.extract_mpoa(eg)
34
+ ).to eq(correct_number)
35
+ end
36
+ end
37
+ end
38
+
39
+ context 'the number cannot be matched' do
40
+ it 'returns the same string' do
41
+ str = 'un_matchable'
42
+
43
+ expect(
44
+ Helpers::Protocols.extract_mpoa(str)
45
+ ).to eq(str)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TwilioBase::ApiKey do
4
+ describe '.create' do
5
+ it 'creates a new api key' do
6
+ expect { described_class.create }
7
+ .to change { TwilioBase::Fake::ApiKey.keys.count }.by(1)
8
+ end
9
+
10
+ it 'assigns friendly name to the key' do
11
+ described_class.create
12
+
13
+ expect(TwilioBase::Fake::ApiKey.keys.last.friendly_name)
14
+ .to eq TwilioBase::ApiKey::FRIENDLY_NAME
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TwilioBase::Application do
4
+ let(:attributes) do
5
+ {
6
+ friendly_name: 'Base Application',
7
+ sms_url: sms_url,
8
+ sms_method: 'POST',
9
+ voice_url: voice_url,
10
+ voice_method: 'POST'
11
+ }
12
+ end
13
+ let(:sms_url) { 'https://sms_url.com' }
14
+ let(:voice_url) { 'https://voice_url.com' }
15
+
16
+ describe '#create' do
17
+ it 'creates a new application on Twilio' do
18
+ expect { described_class.create(attributes) }
19
+ .to change { TwilioBase::Fake::Application.applications.count }.by(1)
20
+ end
21
+
22
+ it 'assigns correct values to the applcation' do
23
+ application = described_class.create(attributes)
24
+ expect(application.friendly_name).to eq 'Base Application'
25
+ expect(application.sms_url).to eq sms_url
26
+ expect(application.sms_method).to eq 'POST'
27
+ expect(application.voice_url).to eq voice_url
28
+ expect(application.voice_method).to eq 'POST'
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TwilioBase::PhoneNumber do
4
+ describe '.find_or_create' do
5
+ before do
6
+ ENV['COUNTRY_CODE'] = 'GB'
7
+ end
8
+
9
+ after do
10
+ ENV['COUNTRY_CODE'] = nil
11
+ end
12
+
13
+ context 'phone number exists' do
14
+ it 'does not create a new phone number' do
15
+ number = FactoryBot.generate(:phone_number)
16
+ phone_number = TwilioBase::Fake::IncomingPhoneNumber
17
+ .new.create(phone_number: number)
18
+
19
+ expect { described_class.find_or_create(phone_number.phone_number) }
20
+ .not_to(
21
+ change { TwilioBase::Fake::IncomingPhoneNumber.phone_numbers.count }
22
+ )
23
+ end
24
+
25
+ it 'returns the phone number' do
26
+ number = FactoryBot.generate(:phone_number)
27
+ phone_number = TwilioBase::Fake::IncomingPhoneNumber
28
+ .new.create(phone_number: number)
29
+
30
+ expect(described_class.find_or_create(phone_number.phone_number))
31
+ .to eq phone_number
32
+ end
33
+ end
34
+
35
+ context 'phone number does not exist' do
36
+ it 'does creates a new phone number' do
37
+ expect { described_class.find_or_create(nil) }
38
+ .to change {
39
+ TwilioBase::Fake::IncomingPhoneNumber.phone_numbers.count
40
+ }.by(1)
41
+ end
42
+
43
+ it 'returns the phone number' do
44
+ expect(described_class.find_or_create(nil))
45
+ .to eq TwilioBase::Fake::IncomingPhoneNumber.phone_numbers.last
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TwilioBase::Protocols::Voice::Base do
6
+ describe '#action_url' do
7
+ it 'returns params[:action_url]' do
8
+ action_url = 'https://url.com'
9
+ params = {
10
+ action_url: action_url
11
+ }
12
+ to = '+1234567890'
13
+ protocol = described_class.new(params: params, to: to)
14
+
15
+ expect(protocol.action_url).to eq(action_url)
16
+ end
17
+ end
18
+
19
+ describe '#action_url_attributes' do
20
+ it 'returns failover_contact_uri param' do
21
+ to = '+1234567890'
22
+ protocol = described_class.new(params: {}, to: to)
23
+
24
+ expected_result = { endpoint: to }
25
+
26
+ expect(protocol.action_url_attributes).to eq(expected_result)
27
+ end
28
+ end
29
+
30
+ describe '#caller_uuid' do
31
+ it 'returns caller uuid param' do
32
+ caller_uuid = '+447777777777'
33
+ params = {
34
+ caller_uuid: caller_uuid
35
+ }
36
+ protocol = described_class.new(
37
+ params: params,
38
+ to: '+1234567890'
39
+ )
40
+
41
+ caller_uuid = protocol.caller_uuid
42
+ expect(caller_uuid).to eq(caller_uuid)
43
+ end
44
+
45
+ it 'returns caller uuid param from sip_address' do
46
+ params = {
47
+ caller_uuid: 'sip:+447777777777@somedomain.com'
48
+ }
49
+ protocol = described_class.new(
50
+ params: params,
51
+ to: '+1234567890'
52
+ )
53
+
54
+ caller_uuid = protocol.caller_uuid
55
+ expect(caller_uuid).to eq('+447777777777')
56
+ end
57
+
58
+ context 'caller uuid is blank' do
59
+ it 'returns anonymous number' do
60
+ protocol = described_class.new(
61
+ params: {},
62
+ to: '+1234567890'
63
+ )
64
+ caller_uuid = protocol.caller_uuid
65
+
66
+ expected = TwilioBase::Protocols::Voice::Base::ANONYMOUS_NUMBER
67
+ expect(caller_uuid).to eq(expected)
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#endpoint' do
73
+ it 'returns "to" attribute' do
74
+ to = '+1234567890'
75
+ protocol = described_class.new(to: to)
76
+
77
+ expect(protocol.endpoint).to eq(to)
78
+ end
79
+ end
80
+
81
+ describe '#name' do
82
+ it 'returns :number' do
83
+ protocol = described_class.new(to: '+1234567890')
84
+
85
+ expect(protocol.name).to eq(:number)
86
+ end
87
+ end
88
+
89
+ describe '#status_callback_events' do
90
+ it 'returns STATUS_CALLBACK_EVENTS' do
91
+ protocol = described_class.new(to: '+1234567890')
92
+
93
+ expected =
94
+ TwilioBase::Protocols::Voice::Base::STATUS_CALLBACK_EVENTS.join(' ')
95
+ expect(protocol.status_callback_events).to eq(expected)
96
+ end
97
+ end
98
+
99
+ describe '#status_callback_url' do
100
+ it 'returns the status callback url param' do
101
+ status_callback_url = 'abc.com'
102
+ params = {
103
+ status_callback_url: status_callback_url
104
+ }
105
+ protocol = described_class.new(to: '+1234567890', params: params)
106
+
107
+ expect(protocol.status_callback_url).to eq(status_callback_url)
108
+ end
109
+ end
110
+
111
+ describe '#timeout' do
112
+ it 'returns the timeout params' do
113
+ timeout = 50
114
+ params = {
115
+ timeout: timeout
116
+ }
117
+ protocol = described_class.new(to: '+1234567890', params: params)
118
+
119
+ expect(protocol.timeout).to eq(timeout)
120
+ end
121
+ end
122
+
123
+ describe '#wait_url' do
124
+ it 'returns wait_url params' do
125
+ wait_url = 'http://abc.com'
126
+ params = {
127
+ wait_url: wait_url
128
+ }
129
+ protocol = described_class.new(to: '+1234567890', params: params)
130
+
131
+ expect(protocol.wait_url).to eq(wait_url)
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TwilioBase::Protocols::Voice::Pstn do
6
+ describe '#name' do
7
+ it 'returns :number' do
8
+ pstn = described_class.new(to: '+1234567890')
9
+
10
+ expect(pstn.name).to eq(:number)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TwilioBase::Protocols::Voice::Sip do
6
+ describe 'validations' do
7
+ context 'to is blank' do
8
+ it 'raises an error' do
9
+ expect { described_class.new(to: nil) }
10
+ .to raise_error('To cannot be blank')
11
+ end
12
+ end
13
+ end
14
+
15
+ describe '#endpoint' do
16
+ it 'returns the endpoint' do
17
+ endpoint = '53435@test.net'
18
+ params = {
19
+ headers: {
20
+ call_sid: 'CAsid'
21
+ }
22
+ }
23
+ sip = described_class.new(params: params, to: endpoint)
24
+
25
+ sip_headers = build_sip_headers(
26
+ headers: {
27
+ 'X-CallSid' => 'CAsid'
28
+ }
29
+ )
30
+
31
+ possible_results = build_possible_results(
32
+ headers: sip_headers,
33
+ sip_endpoints: endpoint
34
+ )
35
+ expect(possible_results).to include(sip.endpoint)
36
+ end
37
+
38
+ context 'to: is an array' do
39
+ it 'samples the array' do
40
+ endpoints = %w[53435@test.net 62424@test.net]
41
+ params = {
42
+ headers: {
43
+ call_sid: 'CAsid'
44
+ }
45
+ }
46
+ sip = described_class.new(params: params, to: endpoints)
47
+
48
+ sip_headers = build_sip_headers(
49
+ headers: {
50
+ 'X-CallSid' => 'CAsid'
51
+ }
52
+ )
53
+
54
+ possible_results = build_possible_results(
55
+ headers: sip_headers,
56
+ sip_endpoints: endpoints
57
+ )
58
+ expect(possible_results).to include(sip.endpoint)
59
+ end
60
+ end
61
+
62
+ context 'header has blank value' do
63
+ it 'returns -' do
64
+ endpoint = '3000@127.0.0.1'
65
+ params = {
66
+ headers: {
67
+ blank_value: '',
68
+ call_sid: 'CAsid'
69
+ }
70
+ }
71
+ sip = described_class.new(params: params, to: endpoint)
72
+
73
+ expected_result = build_sip_headers(
74
+ headers: {
75
+ 'X-BlankValue' => '-',
76
+ 'X-CallSid' => 'CAsid'
77
+ }
78
+ )
79
+
80
+ expect(sip.endpoint).to eq("sip:#{endpoint}?#{expected_result}")
81
+ end
82
+ end
83
+ end
84
+
85
+ describe '#name' do
86
+ it 'returns :sip' do
87
+ sip = described_class.new(params: {}, to: '+1234567890')
88
+
89
+ expect(sip.name).to eq(:sip)
90
+ end
91
+ end
92
+
93
+ def build_sip_headers(headers: {})
94
+ Addressable::URI.new(query_values: headers).query
95
+ end
96
+
97
+ def build_possible_results(headers:, sip_endpoints:)
98
+ sip_endpoints = Array(sip_endpoints)
99
+
100
+ sip_endpoints.map do |endpoint|
101
+ "sip:#{endpoint}?#{headers}"
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TwilioBase::Protocols::Voice::Default do
6
+ describe '.init' do
7
+ context 'with pstn voice protocol' do
8
+ before do
9
+ stub_const('ENV', ENV.to_h.merge('VOICE_PROTOCOL' => 'pstn'))
10
+ end
11
+
12
+ it 'inits Protocols::Voice::Pstn' do
13
+ allow(TwilioBase::Protocols::Voice::Pstn).to receive(:new)
14
+
15
+ described_class.init(protocol: 'pstn', to: '+1234567890')
16
+
17
+ expect(TwilioBase::Protocols::Voice::Pstn).to have_received(:new)
18
+ .with(params: {}, to: '+1234567890')
19
+ end
20
+ end
21
+
22
+ context 'with sip voice protocol' do
23
+ before do
24
+ stub_const('ENV', ENV.to_h.merge('VOICE_PROTOCOL' => 'sip'))
25
+ end
26
+
27
+ it 'inits Protocols::Voice::Sip' do
28
+ allow(TwilioBase::Protocols::Voice::Sip).to receive(:new)
29
+
30
+ described_class.init(to: '+1234567890')
31
+
32
+ expect(TwilioBase::Protocols::Voice::Sip).to have_received(:new)
33
+ .with(params: {}, to: '+1234567890')
34
+ end
35
+
36
+ context 'protocol is passed as a symbol' do
37
+ it 'inits Protocols::Voice::Sip' do
38
+ allow(TwilioBase::Protocols::Voice::Sip).to receive(:new)
39
+
40
+ described_class.init(protocol: :sip, to: '+1234567890')
41
+
42
+ expect(TwilioBase::Protocols::Voice::Sip).to have_received(:new)
43
+ .with(params: {}, to: '+1234567890')
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TwilioBase::RequestVerificationService do
4
+ describe '#verify' do
5
+ context 'when signature present' do
6
+ context 'when post' do
7
+ it 'validates validator with form hash params' do
8
+ validator_double = double(
9
+ 'validator',
10
+ validate: true
11
+ )
12
+
13
+ env = {
14
+ 'REQUEST_METHOD' => 'POST',
15
+ 'HTTP_X_TWILIO_SIGNATURE' => 'twilio_signature',
16
+ 'rack.request.form_hash' => {},
17
+ 'rack.request.query_hash' => ''
18
+ }
19
+
20
+ described_class.new(validator_double).verify(uri: '', env: env)
21
+
22
+ expect(validator_double).to have_received(:validate)
23
+ .with('', {}, 'twilio_signature')
24
+ end
25
+
26
+ it 'returns true' do
27
+ validator_double = double(
28
+ 'validator',
29
+ validate: true
30
+ )
31
+
32
+ env = {
33
+ 'REQUEST_METHOD' => 'POST',
34
+ 'HTTP_X_TWILIO_SIGNATURE' => 'twilio_signature',
35
+ 'rack.request.form_hash' => {},
36
+ 'rack.request.query_hash' => ''
37
+ }
38
+
39
+ expect(
40
+ described_class.new(validator_double).verify(uri: '', env: env)
41
+ ).to be_truthy
42
+ end
43
+ end
44
+
45
+ context 'when is not post' do
46
+ it 'validates validator with query hash params' do
47
+ validator_double = double(
48
+ 'validator',
49
+ validate: true
50
+ )
51
+
52
+ env = {
53
+ 'REQUEST_METHOD' => 'PUT',
54
+ 'HTTP_X_TWILIO_SIGNATURE' => 'twilio_signature',
55
+ 'rack.request.form_hash' => {},
56
+ 'rack.request.query_hash' => ''
57
+ }
58
+
59
+ described_class.new(validator_double).verify(uri: '', env: env)
60
+
61
+ expect(validator_double).to have_received(:validate)
62
+ .with('', '', 'twilio_signature')
63
+ end
64
+
65
+ it 'returns true' do
66
+ validator_double = double(
67
+ 'validator',
68
+ validate: true
69
+ )
70
+
71
+ env = {
72
+ 'REQUEST_METHOD' => 'PUT',
73
+ 'HTTP_X_TWILIO_SIGNATURE' => 'twilio_signature',
74
+ 'rack.request.form_hash' => {},
75
+ 'rack.request.query_hash' => ''
76
+ }
77
+
78
+ expect(
79
+ described_class.new(validator_double).verify(uri: '', env: env)
80
+ ).to be_truthy
81
+ end
82
+ end
83
+ end
84
+
85
+ context 'when signature is empty' do
86
+ it 'returns false' do
87
+ validator_double = double(
88
+ 'validator',
89
+ validate: true
90
+ )
91
+
92
+ env = {
93
+ 'REQUEST_METHOD' => 'POST',
94
+ 'HTTP_X_TWILIO_SIGNATURE' => nil,
95
+ 'rack.request.form_hash' => {},
96
+ 'rack.request.query_hash' => ''
97
+ }
98
+
99
+ expect(
100
+ described_class.new(validator_double).verify(uri: '', env: env)
101
+ ).to be_falsey
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TwilioBase::Routers::Voice::DirectDial do
6
+ include Rails.application.routes.url_helpers
7
+
8
+ describe '#route' do
9
+ context 'protocol is PSTN' do
10
+ it 'returns dial Twiml' do
11
+ protocol = TwilioBase::Protocols::Voice::Pstn.new(
12
+ to: '+1234567890',
13
+ params: {
14
+ action_url: 'https://someurl.com',
15
+ status_callback_url: 'https://somestatusurl.com'
16
+ }
17
+ )
18
+ direct_dial = described_class.new(protocol: protocol)
19
+
20
+ expected_result = dial_twiml(
21
+ params: {
22
+ action_url: protocol.action_url,
23
+ caller_id: protocol.caller_uuid,
24
+ endpoint: protocol.endpoint,
25
+ protocol: protocol.name,
26
+ status_callback_events: protocol.status_callback_events,
27
+ status_callback_url: protocol.status_callback_url
28
+ }
29
+ )
30
+
31
+ expect(direct_dial.route).to eq(expected_result)
32
+ end
33
+
34
+ context 'with yield block' do
35
+ it 'returns direct diall Twiml using yield block' do
36
+ protocol = TwilioBase::Protocols::Voice::Pstn.new(
37
+ params: {
38
+ action_url: 'https://someurl.com',
39
+ status_callback_url: 'https://somestatusurl.com'
40
+ },
41
+ to: '+1234567890'
42
+ )
43
+ direct_dial = described_class.new(protocol: protocol)
44
+ voice_response = Twilio::TwiML::VoiceResponse.new
45
+
46
+ expected_result = dial_twiml(
47
+ params: {
48
+ action_url: protocol.action_url,
49
+ caller_id: protocol.caller_uuid,
50
+ endpoint: protocol.endpoint,
51
+ play_urls: '/audio.wav',
52
+ protocol: protocol.name,
53
+ status_callback_events: protocol.status_callback_events,
54
+ status_callback_url: protocol.status_callback_url
55
+ }
56
+ )
57
+
58
+ result = direct_dial.route { voice_response.play(url: '/audio.wav') }
59
+ expect(result).to eq(expected_result)
60
+ end
61
+ end
62
+ end
63
+
64
+ context 'protocol is Sip' do
65
+ it 'returns sip dial Twiml' do
66
+ protocol = TwilioBase::Protocols::Voice::Sip.new(
67
+ params: {
68
+ action_url: 'https://someurl.com',
69
+ sip_endpoint: '124@abc.net',
70
+ status_callback_url: 'https://somestatusurl.com'
71
+ },
72
+ to: '+442039605098'
73
+ )
74
+ direct_dial = described_class.new(protocol: protocol)
75
+
76
+ expected_result = dial_twiml(
77
+ params: {
78
+ action_url: protocol.action_url,
79
+ caller_id: protocol.caller_uuid,
80
+ endpoint: protocol.endpoint,
81
+ protocol: protocol.name,
82
+ status_callback_url: protocol.status_callback_url,
83
+ status_callback_events: protocol.status_callback_events
84
+ }
85
+ )
86
+
87
+ expect(direct_dial.route).to eq(expected_result)
88
+ end
89
+ end
90
+ end
91
+ end