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,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TwilioBase::Routers::Voice::Default do
6
+ let(:protocol) do
7
+ TwilioBase::Protocols::Voice::Pstn.new(to: '+1234567890')
8
+ end
9
+
10
+ describe '.init' do
11
+ context 'with set routing_method' do
12
+ it 'overwrites ENV variable' do
13
+ stub_const('ENV', ENV.to_h.merge('ROUTING_METHOD' => 'direct_dial'))
14
+
15
+ allow(TwilioBase::Routers::Voice::DirectDial).to receive(:new)
16
+ allow(TwilioBase::Routers::Voice::TaskRouter).to receive(:new)
17
+
18
+ described_class.init(protocol: protocol, routing_method: 'task_router')
19
+
20
+ expect(TwilioBase::Routers::Voice::DirectDial)
21
+ .to_not have_received(:new)
22
+ expect(TwilioBase::Routers::Voice::TaskRouter).to have_received(:new)
23
+ .with(protocol: protocol)
24
+ end
25
+ end
26
+
27
+ context 'with not set routing_method' do
28
+ context 'with direct dial routing method' do
29
+ before do
30
+ stub_const('ENV', ENV.to_h.merge('ROUTING_METHOD' => 'direct_dial'))
31
+ end
32
+
33
+ it 'inits Routers::Voice::DirectDial' do
34
+ allow(TwilioBase::Routers::Voice::DirectDial).to receive(:new)
35
+
36
+ described_class.init(protocol: protocol)
37
+
38
+ expect(TwilioBase::Routers::Voice::DirectDial).to have_received(:new)
39
+ .with(protocol: protocol)
40
+ end
41
+ end
42
+
43
+ context 'with task router routing method' do
44
+ before do
45
+ stub_const('ENV', ENV.to_h.merge('ROUTING_METHOD' => 'task_router'))
46
+ end
47
+
48
+ it 'inits Routers::Voice::TaskRouter' do
49
+ allow(TwilioBase::Routers::Voice::TaskRouter).to receive(:new)
50
+
51
+ described_class.init(protocol: protocol)
52
+
53
+ expect(TwilioBase::Routers::Voice::TaskRouter).to have_received(:new)
54
+ .with(protocol: protocol)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TwilioBase::Routers::Voice::TaskRouter do
6
+ let!(:config) { create(:global_config) }
7
+
8
+ describe '#route' do
9
+ context 'with pstn protocol' do
10
+ it 'enqueue the task using plain phone number' do
11
+ protocol = TwilioBase::Protocols::Voice::Pstn.new(
12
+ params: {
13
+ action_url: 'https://someurl.com',
14
+ status_callback_url: 'https://somestatusurl.com',
15
+ wait_url: 'https://somewaiturl.com'
16
+ },
17
+ to: '+1234567890'
18
+ )
19
+
20
+ direct_dial = described_class.new(protocol: protocol)
21
+ expected_result = enqueue_twiml(protocol: protocol)
22
+
23
+ expect(direct_dial.route).to eq(expected_result)
24
+ end
25
+ end
26
+
27
+ context 'with sip protocol' do
28
+ it 'enqueue the task using sip endpoint' do
29
+ protocol = TwilioBase::Protocols::Voice::Sip.new(
30
+ params: {
31
+ action_url: 'https://someurl.com',
32
+ sip_endpoint: '124@abc.net',
33
+ status_callback_url: 'https://somestatusurl.com',
34
+ wait_url: 'https://somewaiturl.com'
35
+ },
36
+ to: '+1234567890'
37
+ )
38
+
39
+ direct_dial = described_class.new(protocol: protocol)
40
+ expected_result = enqueue_twiml(protocol: protocol)
41
+
42
+ expect(direct_dial.route).to eq(expected_result)
43
+ end
44
+ end
45
+ end
46
+
47
+ def enqueue_twiml(protocol:)
48
+ action_url = protocol.action_url
49
+ endpoint = protocol.endpoint
50
+ wait_url = protocol.wait_url
51
+ workflow_sid = config.workflow_sid
52
+
53
+ '<?xml version="1.0" encoding="UTF-8"?>' \
54
+ "\n<Response>\n" \
55
+ "<Enqueue action=\"#{action_url}\" waitUrl=\"#{wait_url}\" " \
56
+ "workflowSid=\"#{workflow_sid}\">" \
57
+ "\n<Task>" \
58
+ "{\"outbound_contact_uri\":\"#{endpoint}\"}" \
59
+ "</Task>\n" \
60
+ '</Enqueue>' \
61
+ "\n</Response>\n"
62
+ end
63
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TwilioBase::Sync::Service do
4
+ describe '.create' do
5
+ it 'creates a new sync service' do
6
+ expect { described_class.create }
7
+ .to change { TwilioBase::Fake::Sync.sync_services.count }.by(1)
8
+ end
9
+
10
+ it 'assigns default friendly name to the service' do
11
+ described_class.create
12
+
13
+ expect(TwilioBase::Fake::Sync.sync_services.last.friendly_name)
14
+ .to eq Twilio::Sync::Service::DEFAULT_FRIENDLY_NAME
15
+ end
16
+
17
+ it 'assigns spcified friendly name to the service' do
18
+ name = 'Test name'
19
+
20
+ described_class.create(friendly_name: name)
21
+
22
+ expect(TwilioBase::Fake::Sync.sync_services.last.friendly_name).to eq name
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TwilioBase::TaskRouter::Activity do
4
+ include_context :global_config
5
+
6
+ describe '.available' do
7
+ it 'returns object of activity with friendly name "Available"' do
8
+ available_activity = TwilioBase::Fake::TaskRouter::Activity.new.create(
9
+ friendly_name: described_class::AVAILABLE_ACTIVITY_NAME
10
+ )
11
+
12
+ expect(described_class.available).to eq(available_activity)
13
+ end
14
+ end
15
+
16
+ describe '.busy' do
17
+ it 'returns object of activity with friendly name "Busy"' do
18
+ busy_activity = TwilioBase::Fake::TaskRouter::Activity.new.create(
19
+ friendly_name: described_class::ASSIGNMENT_ACTIVITY_NAME
20
+ )
21
+
22
+ expect(described_class.busy).to eq(busy_activity)
23
+ end
24
+ end
25
+
26
+ describe '.idle' do
27
+ it 'returns object of activity with friendly name "Idle"' do
28
+ idle_activity = TwilioBase::Fake::TaskRouter::Activity.new.create(
29
+ friendly_name: described_class::IDLE_ACTIVITY_NAME
30
+ )
31
+
32
+ expect(described_class.idle).to eq(idle_activity)
33
+ end
34
+ end
35
+
36
+ describe '.list' do
37
+ it 'shows list of activities' do
38
+ 4.times do |i|
39
+ TwilioBase::Fake::TaskRouter::Activity.new
40
+ .create(friendly_name: "activity #{i}")
41
+ end
42
+
43
+ expect(
44
+ described_class.list.count
45
+ ).to eq 4
46
+ end
47
+ end
48
+
49
+ describe '.offline' do
50
+ it 'returns object of activity with friendly name "Offline' do
51
+ offline_activity = TwilioBase::Fake::TaskRouter::Activity.new.create(
52
+ friendly_name: described_class::OFFLINE_ACTIVITY_NAME
53
+ )
54
+
55
+ expect(described_class.offline).to eq(offline_activity)
56
+ end
57
+ end
58
+
59
+ describe '.reserved' do
60
+ it 'returns object of activity with friendly name "Reserved"' do
61
+ reserved_activity = TwilioBase::Fake::TaskRouter::Activity.new.create(
62
+ friendly_name: described_class::RESERVATION_ACTIVITY_NAME
63
+ )
64
+
65
+ expect(described_class.reserved).to eq(reserved_activity)
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TwilioBase::TaskRouter::TaskQueue do
4
+ describe '.find_or_create_by' do
5
+ context 'taskqueue already exists with params' do
6
+ it 'does not create a task queue' do
7
+ workspace = TwilioBase::Fake::TaskRouter::Workspace.new.create({})
8
+ friendly_name = 'Name'
9
+ _task_queue = TwilioBase::Fake::TaskRouter::TaskQueue.new.create(
10
+ workspace: workspace,
11
+ friendly_name: friendly_name
12
+ )
13
+
14
+ expect do
15
+ described_class.find_or_create_by(
16
+ workspace: workspace,
17
+ friendly_name: friendly_name
18
+ )
19
+ end.not_to(
20
+ change { TwilioBase::Fake::TaskRouter::TaskQueue.task_queues.count }
21
+ )
22
+ end
23
+
24
+ it 'returns the task queue' do
25
+ workspace = TwilioBase::Fake::TaskRouter::Workspace.new.create({})
26
+ friendly_name = 'Name'
27
+ task_queue = TwilioBase::Fake::TaskRouter::TaskQueue.new.create(
28
+ workspace: workspace,
29
+ friendly_name: friendly_name
30
+ )
31
+
32
+ expect(
33
+ described_class.find_or_create_by(
34
+ workspace: workspace, friendly_name: friendly_name
35
+ )
36
+ ).to eq task_queue
37
+ end
38
+ end
39
+
40
+ context 'taskqueue does not exist with params' do
41
+ let!(:reserved_activity) do
42
+ TwilioBase::Fake::TaskRouter::Activity
43
+ .new.create(friendly_name: 'Reserved')
44
+ end
45
+ let!(:busy_activity) do
46
+ TwilioBase::Fake::TaskRouter::Activity.new.create(friendly_name: 'Busy')
47
+ end
48
+
49
+ it 'creates a task queue' do
50
+ workspace = TwilioBase::Fake::TaskRouter::Workspace.new.create({})
51
+ friendly_name = 'Name'
52
+
53
+ expect do
54
+ described_class.find_or_create_by(
55
+ workspace: workspace,
56
+ friendly_name: friendly_name
57
+ )
58
+ end.to change {
59
+ TwilioBase::Fake::TaskRouter::TaskQueue.task_queues.count
60
+ }.by(1)
61
+ end
62
+
63
+ it 'returns the task queue' do
64
+ workspace = TwilioBase::Fake::TaskRouter::Workspace.new.create({})
65
+ friendly_name = 'Name'
66
+
67
+ expect(
68
+ described_class.find_or_create_by(
69
+ workspace: workspace, friendly_name: friendly_name
70
+ )
71
+ ).to eq TwilioBase::Fake::TaskRouter::TaskQueue.task_queues.last
72
+ end
73
+
74
+ it 'assigns the friendly name to the task queue' do
75
+ workspace = TwilioBase::Fake::TaskRouter::Workspace.new.create({})
76
+ friendly_name = 'Name'
77
+
78
+ described_class.find_or_create_by(
79
+ workspace: workspace, friendly_name: friendly_name
80
+ )
81
+
82
+ task_queue_name = TwilioBase::Fake::TaskRouter::TaskQueue
83
+ .task_queues.last.friendly_name
84
+ expect(task_queue_name).to eq friendly_name
85
+ end
86
+
87
+ it 'assigns the busy activity to the task queue assignment activity' do
88
+ workspace = TwilioBase::Fake::TaskRouter::Workspace.new.create({})
89
+ friendly_name = 'Name'
90
+
91
+ described_class.find_or_create_by(
92
+ workspace: workspace, friendly_name: friendly_name
93
+ )
94
+
95
+ assignment_activity_sid = TwilioBase::Fake::TaskRouter::TaskQueue
96
+ .task_queues.last.assignment_activity_sid
97
+ expect(assignment_activity_sid).to eq busy_activity.sid
98
+ end
99
+
100
+ it 'assigns the reserved activity to task queue reservation activity' do
101
+ workspace = TwilioBase::Fake::TaskRouter::Workspace.new.create({})
102
+ friendly_name = 'Name'
103
+
104
+ described_class.find_or_create_by(
105
+ workspace: workspace, friendly_name: friendly_name
106
+ )
107
+
108
+ reservation_activity_sid = TwilioBase::Fake::TaskRouter::TaskQueue
109
+ .task_queues.last.reservation_activity_sid
110
+ expect(reservation_activity_sid).to eq reserved_activity.sid
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TwilioBase::TaskRouter::Worker do
4
+ include_context :global_config
5
+
6
+ describe '.create' do
7
+ it 'creates a new worker' do
8
+ _idle_activity = TwilioBase::Fake::TaskRouter::Activity.new
9
+ .create(friendly_name: 'Idle')
10
+
11
+ expect { described_class.create(name: 'Name', attributes: {}) }
12
+ .to change { TwilioBase::Fake::TaskRouter::Worker.workers.count }
13
+ .by(1)
14
+ end
15
+
16
+ it 'creates worker with correct attributes' do
17
+ friendly_name = 'Name'
18
+ idle_activity = TwilioBase::Fake::TaskRouter::Activity.new
19
+ .create(friendly_name: 'Idle')
20
+
21
+ described_class.create(name: friendly_name, attributes: {})
22
+ new_worker = TwilioBase::Fake::TaskRouter::Worker.workers.last
23
+
24
+ expect(new_worker.friendly_name).to eq friendly_name
25
+ expect(new_worker.activity_sid).to eq idle_activity.sid
26
+ end
27
+ end
28
+
29
+ describe '.find' do
30
+ it 'returns the relevant worker' do
31
+ _idle_activity = TwilioBase::Fake::TaskRouter::Activity.new
32
+ .create(friendly_name: 'Idle')
33
+ found_worker = TwilioBase::Fake::TaskRouter::Worker.new.create({})
34
+ _not_found_worker = TwilioBase::Fake::TaskRouter::Worker.new.create({})
35
+
36
+ expect(described_class.find(found_worker.sid)).to eq found_worker
37
+ end
38
+
39
+ context 'non-matching worker' do
40
+ it 'returns nil' do
41
+ _idle_activity = TwilioBase::Fake::TaskRouter::Activity.new
42
+ .create(friendly_name: 'Idle')
43
+ _not_found_worker = TwilioBase::Fake::TaskRouter::Worker.new.create({})
44
+
45
+ expect(described_class.find(FactoryBot.generate(:worker_sid))).to be_nil
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe TwilioBase::TaskRouter::Workflow do
4
+ let(:attributes) do
5
+ {
6
+ configuration: {},
7
+ friendly_name: 'Test Workspace'
8
+ }
9
+ end
10
+
11
+ describe '#create' do
12
+ it 'should create a new workflow' do
13
+ workspace = TwilioBase::Fake::TaskRouter::Workspace.new.create({})
14
+ expect do
15
+ described_class.create(
16
+ attributes: attributes,
17
+ workspace: workspace
18
+ )
19
+ end.to change {
20
+ TwilioBase::Fake::TaskRouter::Workflow.workflows.count
21
+ }.by(1)
22
+ end
23
+
24
+ it 'assigns the config to the workflow' do
25
+ workspace = TwilioBase::Fake::TaskRouter::Workspace.new.create({})
26
+
27
+ described_class.create(
28
+ attributes: attributes,
29
+ workspace: workspace
30
+ )
31
+
32
+ workflow_name = TwilioBase::Fake::TaskRouter::Workflow
33
+ .workflows.last.friendly_name
34
+ expect(workflow_name).to eq attributes[:friendly_name]
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
4
+
5
+ ENV['RAILS_ENV'] ||= 'test'
6
+ ENV['APP_NAME'] = 'Test app'
7
+ ENV['COUNTRY_CODE'] = 'GB'
8
+ ENV['TWILIO_ACCOUNT_SID'] = 'account_sid'
9
+ ENV['TWILIO_AUTH_TOKEN'] = 'auth_token'
10
+
11
+ require 'active_record'
12
+ require 'factory_bot'
13
+ require 'rails'
14
+ require 'twilio_base'
15
+
16
+ require File.expand_path('twilio_base_dummy/config/environment.rb', __dir__)
17
+ Dir[File.join(__dir__, 'support', '**', '*.rb')].each { |file| require file }
18
+
19
+ require 'bundler/setup'
20
+ require 'byebug'
21
+ require 'database_cleaner'
22
+ require 'shoulda/matchers'
23
+ require 'shoulda/callback/matchers'
24
+ require 'timecop'
25
+ require 'rspec/rails'
26
+
27
+ ActiveRecord::Migration.maintain_test_schema!
28
+
29
+ Shoulda::Matchers.configure do |config|
30
+ config.integrate do |with|
31
+ with.test_framework :rspec
32
+ with.library :active_record
33
+ end
34
+ end
35
+
36
+ TwilioBase::Engine.routes.default_url_options[:host] = 'localhost:3000'
37
+
38
+ RSpec.configure do |config|
39
+ config.include(Shoulda::Matchers::ActiveModel, type: :model)
40
+ config.include(Shoulda::Matchers::ActiveRecord, type: :model)
41
+ config.include(Shoulda::Callback::Matchers::ActiveModel)
42
+ config.include(TwilioBase::Responses::Twiml)
43
+ config.example_status_persistence_file_path = '.rspec_status'
44
+ config.disable_monkey_patching!
45
+ config.infer_spec_type_from_file_location!
46
+
47
+ config.expect_with :rspec do |c|
48
+ c.syntax = :expect
49
+ end
50
+
51
+ config.before(:each) do
52
+ TwilioBase::Fake::Helpers.clean_cache
53
+ Rails.cache.clear
54
+ end
55
+
56
+ config.before(:suite) do
57
+ DatabaseCleaner.strategy = :transaction
58
+ DatabaseCleaner.clean_with(:truncation, except: %w[ar_internal_metadata])
59
+ end
60
+
61
+ config.around(:each) do |example|
62
+ DatabaseCleaner.cleaning do
63
+ example.run
64
+ end
65
+ end
66
+
67
+ Twilio::REST::Client = TwilioBase::Fake::Clients::Rest
68
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.configure do |config|
4
+ config.include FactoryBot::Syntax::Methods
5
+
6
+ config.before(:suite) do
7
+ FactoryBot.find_definitions
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_context :global_config do
4
+ before(:each) { FactoryBot.create(:global_config) }
5
+ let(:config) { TwilioBase::GlobalConfig.first }
6
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.shared_context :twilio_controller do
6
+ before(:each) { expect(controller).to receive(:validate_request) }
7
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TwilioBase
4
+ module Fake
5
+ class ApiKey
6
+ Key = Struct.new(:friendly_name) do
7
+ def sid
8
+ @sid ||= FactoryBot.generate(:api_key_sid)
9
+ end
10
+
11
+ def secret
12
+ @secret ||= FactoryBot.generate(:api_key_secret)
13
+ end
14
+ end
15
+
16
+ cattr_accessor :keys
17
+ self.keys = []
18
+
19
+ def create(friendly_name:)
20
+ key = Key.new(friendly_name)
21
+ self.class.keys << key
22
+ key
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TwilioBase
4
+ module Fake
5
+ class Application
6
+ Application = Struct.new(:attributes) do
7
+ def sid
8
+ @sid ||= TwilioBase::GlobalConfig.first&.application_sid ||
9
+ FactoryBot.generate(:application_sid)
10
+ end
11
+
12
+ def friendly_name
13
+ attributes[:friendly_name]
14
+ end
15
+
16
+ def sms_url
17
+ attributes[:sms_url]
18
+ end
19
+
20
+ def sms_method
21
+ attributes[:sms_method]
22
+ end
23
+
24
+ def voice_url
25
+ attributes[:voice_url]
26
+ end
27
+
28
+ def voice_method
29
+ attributes[:voice_method]
30
+ end
31
+
32
+ def update(attributes)
33
+ self.attributes = attributes
34
+ end
35
+ end
36
+
37
+ cattr_accessor :applications, :sid
38
+ self.applications = []
39
+
40
+ def initialize(sid = nil)
41
+ self.sid = sid
42
+ end
43
+
44
+ def create(attributes)
45
+ application = Application.new(attributes)
46
+ self.class.applications << application
47
+ application
48
+ end
49
+
50
+ def list
51
+ applications
52
+ end
53
+
54
+ def fetch
55
+ applications.detect { |application| application.sid == sid }
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TwilioBase
4
+ module Fake
5
+ class AvailablePhoneNumber
6
+ PhoneNumber = Struct.new(:phone_number)
7
+
8
+ cattr_accessor :phone_numbers
9
+ self.phone_numbers = []
10
+
11
+ def initialize(_country_code = nil); end
12
+
13
+ def local
14
+ self
15
+ end
16
+
17
+ def list(*)
18
+ available_numbers
19
+ end
20
+
21
+ def available_numbers
22
+ [
23
+ PhoneNumber.new(FactoryBot.generate(:phone_number)),
24
+ PhoneNumber.new(FactoryBot.generate(:phone_number))
25
+ ]
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TwilioBase
4
+ module Fake
5
+ module Chat
6
+ class Channel
7
+ Channel = Struct.new(:attributes) do
8
+ def friendly_name
9
+ attributes[:friendly_name]
10
+ end
11
+
12
+ def messages
13
+ TwilioBase::Fake::Chat::Message.new
14
+ end
15
+
16
+ def members
17
+ TwilioBase::Fake::Chat::Member.new
18
+ end
19
+
20
+ def sid
21
+ @sid ||= FactoryBot.generate(:channel_sid)
22
+ end
23
+
24
+ def delete
25
+ TwilioBase::Fake::Chat::Channel.channels.pop
26
+ end
27
+
28
+ def update(update_attributes)
29
+ attributes.merge! update_attributes
30
+ end
31
+ end
32
+
33
+ cattr_accessor :channels
34
+ self.channels = []
35
+
36
+ def initialize(channel_sid = nil)
37
+ self.channel_sid = channel_sid
38
+ end
39
+
40
+ def create(attributes)
41
+ self.class.channels << Channel.new(attributes)
42
+ channels.last
43
+ end
44
+
45
+ def fetch
46
+ raise ArgumentError unless matched_channel?
47
+
48
+ self.class.channels.last
49
+ end
50
+
51
+ private
52
+
53
+ attr_accessor :channel_sid
54
+
55
+ def matched_channel?
56
+ self.class.channels.detect do |channel|
57
+ channel.sid == channel_sid
58
+ end.present?
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end