telephony 1.0.3

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 (365) hide show
  1. checksums.yaml +15 -0
  2. data/README.md +105 -0
  3. data/Rakefile +39 -0
  4. data/app/assets/fonts/telephony/zest-telephony.eot +0 -0
  5. data/app/assets/fonts/telephony/zest-telephony.svg +73 -0
  6. data/app/assets/fonts/telephony/zest-telephony.ttf +0 -0
  7. data/app/assets/fonts/telephony/zest-telephony.woff +0 -0
  8. data/app/assets/images/telephony/backspace.png +0 -0
  9. data/app/assets/images/telephony/icon-spinner.gif +0 -0
  10. data/app/assets/javascripts/telephony/application.js +12 -0
  11. data/app/assets/javascripts/telephony/collections/agents.js +4 -0
  12. data/app/assets/javascripts/telephony/config.js.erb +11 -0
  13. data/app/assets/javascripts/telephony/models/agent.js +103 -0
  14. data/app/assets/javascripts/telephony/models/conversation.js +226 -0
  15. data/app/assets/javascripts/telephony/models/device.js +30 -0
  16. data/app/assets/javascripts/telephony/models/transfer.js +65 -0
  17. data/app/assets/javascripts/telephony/namespace.js +6 -0
  18. data/app/assets/javascripts/telephony/push.js +80 -0
  19. data/app/assets/javascripts/telephony/vendor/backbone.js +1159 -0
  20. data/app/assets/javascripts/telephony/vendor/chosen.jquery.js +1018 -0
  21. data/app/assets/javascripts/telephony/vendor/jquery.form.js +1117 -0
  22. data/app/assets/javascripts/telephony/vendor/pusher.js +1304 -0
  23. data/app/assets/javascripts/telephony/vendor/test_dependencies.js +18 -0
  24. data/app/assets/javascripts/telephony/vendor/underscore.js +839 -0
  25. data/app/assets/javascripts/telephony/views/agents_view.js +69 -0
  26. data/app/assets/javascripts/telephony/views/application_view.js +78 -0
  27. data/app/assets/javascripts/telephony/views/call_queue_view.js +21 -0
  28. data/app/assets/javascripts/telephony/views/conversation_buttons_view.js +15 -0
  29. data/app/assets/javascripts/telephony/views/conversation_view.js +322 -0
  30. data/app/assets/javascripts/telephony/views/status_view.js +36 -0
  31. data/app/assets/javascripts/telephony/views/transfer_view.js +87 -0
  32. data/app/assets/javascripts/telephony/views/twilio_client_view.js +117 -0
  33. data/app/assets/javascripts/telephony/views/widget_view.js +55 -0
  34. data/app/assets/javascripts/telephony/widget.js +5 -0
  35. data/app/assets/javascripts/templates/telephony/agents_view.jst.ejs +8 -0
  36. data/app/assets/javascripts/templates/telephony/call_queue_view.jst.ejs +2 -0
  37. data/app/assets/javascripts/templates/telephony/conversation_buttons_view.jst.ejs +23 -0
  38. data/app/assets/javascripts/templates/telephony/conversation_view.jst.ejs +10 -0
  39. data/app/assets/javascripts/templates/telephony/status_view.jst.ejs +4 -0
  40. data/app/assets/javascripts/templates/telephony/transfer_view.jst.ejs +38 -0
  41. data/app/assets/javascripts/templates/telephony/twilio_client_view.jst.ejs +10 -0
  42. data/app/assets/stylesheets/telephony/font.css +43 -0
  43. data/app/assets/stylesheets/telephony/reset.css.scss +10 -0
  44. data/app/assets/stylesheets/telephony/widget.css.scss +512 -0
  45. data/app/controllers/telephony/agents_controller.rb +46 -0
  46. data/app/controllers/telephony/application_controller.rb +4 -0
  47. data/app/controllers/telephony/call_centers_controller.rb +9 -0
  48. data/app/controllers/telephony/conversations_controller.rb +74 -0
  49. data/app/controllers/telephony/inbound/conversation_queues_controller.rb +21 -0
  50. data/app/controllers/telephony/playable_listeners_controller.rb +43 -0
  51. data/app/controllers/telephony/providers/twilio/application_controller.rb +26 -0
  52. data/app/controllers/telephony/providers/twilio/calls_controller.rb +130 -0
  53. data/app/controllers/telephony/providers/twilio/inbound_calls_controller.rb +54 -0
  54. data/app/controllers/telephony/providers/twilio/musics_controller.rb +12 -0
  55. data/app/controllers/telephony/providers/twilio/voicemails_controller.rb +29 -0
  56. data/app/controllers/telephony/signals/agents/presences_controller.rb +64 -0
  57. data/app/controllers/telephony/transfers_controller.rb +18 -0
  58. data/app/controllers/telephony/twilio_client_controller.rb +37 -0
  59. data/app/controllers/telephony/voicemails_controller.rb +13 -0
  60. data/app/controllers/telephony/widget_controller.rb +10 -0
  61. data/app/helpers/telephony/application_helper.rb +4 -0
  62. data/app/helpers/telephony/calls_helper.rb +13 -0
  63. data/app/models/telephony/agent.rb +186 -0
  64. data/app/models/telephony/agent_state_machine.rb +54 -0
  65. data/app/models/telephony/base.rb +7 -0
  66. data/app/models/telephony/blacklisted_number.rb +5 -0
  67. data/app/models/telephony/call.rb +94 -0
  68. data/app/models/telephony/call_center.rb +26 -0
  69. data/app/models/telephony/call_state_machine.rb +98 -0
  70. data/app/models/telephony/conversation.rb +273 -0
  71. data/app/models/telephony/conversation_state_machine.rb +109 -0
  72. data/app/models/telephony/conversations_presenter.rb +83 -0
  73. data/app/models/telephony/events.rb +6 -0
  74. data/app/models/telephony/events/answer.rb +6 -0
  75. data/app/models/telephony/events/base.rb +118 -0
  76. data/app/models/telephony/events/busy.rb +6 -0
  77. data/app/models/telephony/events/call_answered.rb +22 -0
  78. data/app/models/telephony/events/call_fail.rb +6 -0
  79. data/app/models/telephony/events/complete_hold.rb +28 -0
  80. data/app/models/telephony/events/complete_one_step_transfer.rb +17 -0
  81. data/app/models/telephony/events/complete_resume.rb +28 -0
  82. data/app/models/telephony/events/complete_two_step_transfer.rb +6 -0
  83. data/app/models/telephony/events/conference.rb +6 -0
  84. data/app/models/telephony/events/connect.rb +22 -0
  85. data/app/models/telephony/events/customer_left_two_step_transfer.rb +6 -0
  86. data/app/models/telephony/events/dial_agent.rb +6 -0
  87. data/app/models/telephony/events/ended.rb +19 -0
  88. data/app/models/telephony/events/enqueue.rb +6 -0
  89. data/app/models/telephony/events/fail_one_step_transfer.rb +9 -0
  90. data/app/models/telephony/events/fail_two_step_transfer.rb +6 -0
  91. data/app/models/telephony/events/initialize_widget.rb +15 -0
  92. data/app/models/telephony/events/initiate_hold.rb +6 -0
  93. data/app/models/telephony/events/initiate_one_step_transfer.rb +6 -0
  94. data/app/models/telephony/events/initiate_resume.rb +6 -0
  95. data/app/models/telephony/events/initiate_two_step_transfer.rb +6 -0
  96. data/app/models/telephony/events/leave_two_step_transfer.rb +17 -0
  97. data/app/models/telephony/events/leave_voicemail.rb +22 -0
  98. data/app/models/telephony/events/no_answer.rb +6 -0
  99. data/app/models/telephony/events/play_closed_greeting.rb +6 -0
  100. data/app/models/telephony/events/play_message.rb +6 -0
  101. data/app/models/telephony/events/reject.rb +6 -0
  102. data/app/models/telephony/events/rona.rb +6 -0
  103. data/app/models/telephony/events/start.rb +17 -0
  104. data/app/models/telephony/events/straight_to_voicemail.rb +6 -0
  105. data/app/models/telephony/events/terminate.rb +6 -0
  106. data/app/models/telephony/events/transfer.rb +35 -0
  107. data/app/models/telephony/inbound_conversation_queue.rb +101 -0
  108. data/app/models/telephony/playable.rb +7 -0
  109. data/app/models/telephony/playable_listener.rb +42 -0
  110. data/app/models/telephony/pusher_event_publisher.rb +26 -0
  111. data/app/models/telephony/recording.rb +4 -0
  112. data/app/models/telephony/voicemail.rb +36 -0
  113. data/app/observers/telephony/agent_observer.rb +8 -0
  114. data/app/observers/telephony/call_observer.rb +15 -0
  115. data/app/observers/telephony/conversation_observer.rb +9 -0
  116. data/app/observers/telephony/event_observer.rb +9 -0
  117. data/app/views/layouts/telephony/application.html.erb +14 -0
  118. data/app/views/telephony/providers/twilio/calls/child_detached.builder +5 -0
  119. data/app/views/telephony/providers/twilio/calls/complete_hold.builder +6 -0
  120. data/app/views/telephony/providers/twilio/calls/connect.builder +13 -0
  121. data/app/views/telephony/providers/twilio/calls/dial.builder +14 -0
  122. data/app/views/telephony/providers/twilio/calls/done.builder +5 -0
  123. data/app/views/telephony/providers/twilio/calls/join_conference.builder +7 -0
  124. data/app/views/telephony/providers/twilio/calls/whisper_tone.builder +3 -0
  125. data/app/views/telephony/providers/twilio/inbound_calls/closed_hours.builder +7 -0
  126. data/app/views/telephony/providers/twilio/inbound_calls/create.builder +8 -0
  127. data/app/views/telephony/providers/twilio/inbound_calls/enqueue.builder +8 -0
  128. data/app/views/telephony/providers/twilio/inbound_calls/reject.builder +5 -0
  129. data/app/views/telephony/providers/twilio/inbound_calls/wait_music.builder +5 -0
  130. data/app/views/telephony/providers/twilio/musics/hold.builder +5 -0
  131. data/app/views/telephony/providers/twilio/voicemails/new.builder +6 -0
  132. data/app/views/telephony/twilio_client/index.html.erb +74 -0
  133. data/app/views/telephony/widget/index.erb +3 -0
  134. data/config/cucumber.yml +8 -0
  135. data/config/database.yml +57 -0
  136. data/config/environment.rb +67 -0
  137. data/config/initializers/pusher.rb +21 -0
  138. data/config/initializers/telephony.rb +44 -0
  139. data/config/routes.rb +94 -0
  140. data/config/wopr.yml.example +38 -0
  141. data/db/migrate/20130806213053_bootstrap_db.rb +105 -0
  142. data/db/migrate/20131009204026_create_telephony_blacklisted_numbers.rb +11 -0
  143. data/lib/agent_generator.rb +24 -0
  144. data/lib/tasks/cucumber.rake +65 -0
  145. data/lib/tasks/jasmine.rake +8 -0
  146. data/lib/tasks/telephony_tasks.rake +4 -0
  147. data/lib/telephony.rb +34 -0
  148. data/lib/telephony/concerns/controllers/twilio_request_verifier.rb +39 -0
  149. data/lib/telephony/conversation_data.rb +67 -0
  150. data/lib/telephony/engine.rb +19 -0
  151. data/lib/telephony/error.rb +8 -0
  152. data/lib/telephony/error/agent_on_a_call.rb +2 -0
  153. data/lib/telephony/error/base.rb +3 -0
  154. data/lib/telephony/error/connection.rb +2 -0
  155. data/lib/telephony/error/not_in_progress.rb +2 -0
  156. data/lib/telephony/error/queue_empty.rb +2 -0
  157. data/lib/telephony/helper.rb +11 -0
  158. data/lib/telephony/jobs/agent_offline.rb +28 -0
  159. data/lib/telephony/jobs/pusher_event.rb +21 -0
  160. data/lib/telephony/providers/twilio_provider.rb +162 -0
  161. data/lib/telephony/version.rb +3 -0
  162. data/spec/controllers/telephony/agents_controller_spec.rb +117 -0
  163. data/spec/controllers/telephony/call_centers_controller_spec.rb +25 -0
  164. data/spec/controllers/telephony/conversations_controller_spec.rb +229 -0
  165. data/spec/controllers/telephony/playable_listeners_controller_spec.rb +138 -0
  166. data/spec/controllers/telephony/providers/twilio/calls_controller_spec.rb +33 -0
  167. data/spec/controllers/telephony/providers/twilio/musics_controller_spec.rb +20 -0
  168. data/spec/controllers/telephony/signals/agents/presences_controller_spec.rb +154 -0
  169. data/spec/controllers/telephony/twilio_client_controller_spec.rb +58 -0
  170. data/spec/controllers/telephony/widget_controller_spec.rb +25 -0
  171. data/spec/dummy/Rakefile +7 -0
  172. data/spec/dummy/app/assets/javascripts/application.js +6 -0
  173. data/spec/dummy/app/assets/javascripts/lib/event_logger.js +82 -0
  174. data/spec/dummy/app/assets/javascripts/vendor/backbone.js +1159 -0
  175. data/spec/dummy/app/assets/javascripts/vendor/chosen.jquery.js +1018 -0
  176. data/spec/dummy/app/assets/javascripts/vendor/jquery.form.js +1117 -0
  177. data/spec/dummy/app/assets/javascripts/vendor/underscore.js +839 -0
  178. data/spec/dummy/app/assets/stylesheets/application.css +23 -0
  179. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  180. data/spec/dummy/app/controllers/widget_host_controller.rb +2 -0
  181. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  182. data/spec/dummy/app/views/layouts/application.html.erb +12 -0
  183. data/spec/dummy/app/views/widget_host/index.html.erb +53 -0
  184. data/spec/dummy/config.ru +4 -0
  185. data/spec/dummy/config/application.rb +61 -0
  186. data/spec/dummy/config/boot.rb +10 -0
  187. data/spec/dummy/config/call_centers.yml +35 -0
  188. data/spec/dummy/config/call_centers.yml.example +35 -0
  189. data/spec/dummy/config/database.yml +56 -0
  190. data/spec/dummy/config/environment.rb +5 -0
  191. data/spec/dummy/config/environments/cucumber.rb +39 -0
  192. data/spec/dummy/config/environments/development.rb +39 -0
  193. data/spec/dummy/config/environments/production.rb +67 -0
  194. data/spec/dummy/config/environments/test.rb +39 -0
  195. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  196. data/spec/dummy/config/initializers/inflections.rb +15 -0
  197. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  198. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  199. data/spec/dummy/config/initializers/session_store.rb +8 -0
  200. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  201. data/spec/dummy/config/locales/en.yml +5 -0
  202. data/spec/dummy/config/pusher.yml +14 -0
  203. data/spec/dummy/config/pusher.yml.example +14 -0
  204. data/spec/dummy/config/routes.rb +5 -0
  205. data/spec/dummy/config/sms_whitelist.json.example +4 -0
  206. data/spec/dummy/config/twilio.yml +57 -0
  207. data/spec/dummy/config/twilio.yml.example +57 -0
  208. data/spec/dummy/db/schema.rb +122 -0
  209. data/spec/dummy/db/seeds.rb +6 -0
  210. data/spec/dummy/log/production.log +156 -0
  211. data/spec/dummy/log/test.log +13812 -0
  212. data/spec/dummy/public/404.html +26 -0
  213. data/spec/dummy/public/422.html +26 -0
  214. data/spec/dummy/public/500.html +25 -0
  215. data/spec/dummy/public/assets/application-628309db7ce8c0abdd91f8f796881599.js +32 -0
  216. data/spec/dummy/public/assets/application-628309db7ce8c0abdd91f8f796881599.js.gz +0 -0
  217. data/spec/dummy/public/assets/application-6c551430f3bdd32ba57c9c41e5f91846.css +24 -0
  218. data/spec/dummy/public/assets/application-6c551430f3bdd32ba57c9c41e5f91846.css.gz +0 -0
  219. data/spec/dummy/public/assets/telephony/backspace-9f5b195e049ed90eb20ecdda6e264b0a.png +0 -0
  220. data/spec/dummy/public/assets/telephony/icon-spinner-ddbae473a70c5425810aeee31d4a8ad7.gif +0 -0
  221. data/spec/dummy/public/assets/telephony/zest-telephony-0e6b13673634da80de9ae09bcca253e3.eot +0 -0
  222. data/spec/dummy/public/assets/telephony/zest-telephony-37f394757ccb11b978f16d9fd32cb3b5.ttf +0 -0
  223. data/spec/dummy/public/assets/telephony/zest-telephony-e7efdbc60c0a1c8404951bc79c7fb3a8.woff +0 -0
  224. data/spec/dummy/public/assets/telephony/zest-telephony-f34287df626936908408f53a33db9e83.svg +73 -0
  225. data/spec/dummy/public/favicon.ico +0 -0
  226. data/spec/dummy/script/rails +6 -0
  227. data/spec/dummy/tmp/cache/assets/C98/020/sprockets%2Fa83f8254d688334ff179984e423f502f +0 -0
  228. data/spec/dummy/tmp/cache/assets/CA4/550/sprockets%2F407f9191fe573f2435c55c017cb0d022 +0 -0
  229. data/spec/dummy/tmp/cache/assets/CAA/6A0/sprockets%2F3265550e2d2c7f5a864ca85d255504c2 +0 -0
  230. data/spec/dummy/tmp/cache/assets/CB0/F60/sprockets%2F462f9efed31e6710732376ae06c27208 +0 -0
  231. data/spec/dummy/tmp/cache/assets/CB6/E20/sprockets%2Fa7092cd9f16917099d754f1380af13e1 +0 -0
  232. data/spec/dummy/tmp/cache/assets/CC7/9F0/sprockets%2F0517100815cd45c43fec1d8510fcb630 +0 -0
  233. data/spec/dummy/tmp/cache/assets/CCA/BF0/sprockets%2F16ea15e0b5d367c34b812612a4207e3e +0 -0
  234. data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  235. data/spec/dummy/tmp/cache/assets/CF1/960/sprockets%2F36ef26985821ec702c74dae4af789903 +0 -0
  236. data/spec/dummy/tmp/cache/assets/D07/F30/sprockets%2Fd12862f20df0c9ef7aa2b4216d247079 +0 -0
  237. data/spec/dummy/tmp/cache/assets/D09/BF0/sprockets%2F5c8595efaa8cc5235a09801c60e25a16 +0 -0
  238. data/spec/dummy/tmp/cache/assets/D0D/250/sprockets%2F5e759d66e374910dae5a51b221e6e3a4 +0 -0
  239. data/spec/dummy/tmp/cache/assets/D0D/E30/sprockets%2Fa282879e0788ba133f5bdc211cf134e8 +0 -0
  240. data/spec/dummy/tmp/cache/assets/D11/8E0/sprockets%2F2a193a8af29963f1113bef05788e02ff +0 -0
  241. data/spec/dummy/tmp/cache/assets/D14/270/sprockets%2F7f95a752910ed33d728532f8fabd340d +0 -0
  242. data/spec/dummy/tmp/cache/assets/D17/BE0/sprockets%2F58749d7aea4ca766c2520801f0f96b9b +0 -0
  243. data/spec/dummy/tmp/cache/assets/D18/270/sprockets%2Fbb2d88813b1795a97e9a7c14100eef77 +0 -0
  244. data/spec/dummy/tmp/cache/assets/D22/310/sprockets%2Fbae9148ce1229214dfbb0c425b0054d0 +0 -0
  245. data/spec/dummy/tmp/cache/assets/D30/EB0/sprockets%2F2c668b88beb4c9805d91ed4587f549e7 +0 -0
  246. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  247. data/spec/dummy/tmp/cache/assets/D3C/690/sprockets%2F681ba175fdd2da8d590b7e624b6135a6 +0 -0
  248. data/spec/dummy/tmp/cache/assets/D44/BC0/sprockets%2F7214f66dd91fdd51f00c3882293f5eea +0 -0
  249. data/spec/dummy/tmp/cache/assets/D46/FA0/sprockets%2F4f9543cd9e68ba3141fd488afb13681b +0 -0
  250. data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  251. data/spec/dummy/tmp/cache/assets/D51/9A0/sprockets%2Fb6e4cbcf30f6f611671695f79ea846d5 +0 -0
  252. data/spec/dummy/tmp/cache/assets/D55/920/sprockets%2F0a02242aa4c4febcc796419aba103c69 +0 -0
  253. data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  254. data/spec/dummy/tmp/cache/assets/D5F/6F0/sprockets%2F155e7bc44f326371cce0ca8bc5b2414e +0 -0
  255. data/spec/dummy/tmp/cache/assets/D6B/250/sprockets%2Fe4eecce7a3371b11038c92f07cb28e67 +0 -0
  256. data/spec/dummy/tmp/cache/assets/D6B/E70/sprockets%2F103a456ae3692e3cca20b7696fdee8f0 +0 -0
  257. data/spec/dummy/tmp/cache/assets/D7F/AD0/sprockets%2Fb1c02d12303b1fe2f981771cbb0c4cbd +0 -0
  258. data/spec/dummy/tmp/cache/assets/D81/D00/sprockets%2F0c68b6d9dce98681a2a710d9fc3f7e39 +0 -0
  259. data/spec/dummy/tmp/cache/assets/D94/4D0/sprockets%2F4608a5bdf27ddf11bcaed1375911e9a2 +0 -0
  260. data/spec/dummy/tmp/cache/assets/D9A/580/sprockets%2F433005b19aaf7ed5cba9c7f8cd30b775 +0 -0
  261. data/spec/dummy/tmp/cache/assets/DA4/270/sprockets%2F860ab3bd30204e02c0a5d82bd4bbabe1 +0 -0
  262. data/spec/dummy/tmp/cache/assets/DA4/480/sprockets%2F53e39285bb57a2ddb6ff856b2eb491da +0 -0
  263. data/spec/dummy/tmp/cache/assets/DA6/3C0/sprockets%2F587c7e35f47442eadaa530acc5e9f5e6 +0 -0
  264. data/spec/dummy/tmp/cache/assets/DAB/DA0/sprockets%2Fb8fb5e8518ed3d38a7f6a8f18a9208aa +0 -0
  265. data/spec/dummy/tmp/cache/assets/DB2/700/sprockets%2Ffa85cb79b94fce1b8344d983ea863d2e +0 -0
  266. data/spec/dummy/tmp/cache/assets/DCC/4F0/sprockets%2Fbc0f3c61e16afb5a285ba8b39846ed8b +0 -0
  267. data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  268. data/spec/dummy/tmp/cache/assets/DDC/BE0/sprockets%2F2c0a4d4675a61b014aedbbabb3f071fc +0 -0
  269. data/spec/dummy/tmp/cache/assets/E04/640/sprockets%2F3c5ddf2bbefd9d70f1b506b519cf856e +0 -0
  270. data/spec/dummy/tmp/cache/assets/E04/7F0/sprockets%2F35f1b2ff729a5ec21f6dc5f7d6faa67b +0 -0
  271. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  272. data/spec/dummy/tmp/cache/assets/E07/230/sprockets%2Febd4f2dd708879d593aff008ccb75acc +0 -0
  273. data/spec/dummy/tmp/cache/assets/E17/9D0/sprockets%2F8db2b79f6c4eabe7a9ebe7a7898ec066 +0 -0
  274. data/spec/dummy/tmp/cache/assets/E31/F10/sprockets%2Fcebacf56667da1cc2961b59fd922eafb +0 -0
  275. data/spec/factories/agent.rb +26 -0
  276. data/spec/factories/calls.rb +106 -0
  277. data/spec/factories/conversations.rb +171 -0
  278. data/spec/factories/events.rb +250 -0
  279. data/spec/factories/playable_listeners.rb +6 -0
  280. data/spec/factories/recordings.rb +6 -0
  281. data/spec/factories/voicemails.rb +8 -0
  282. data/spec/fixtures/vcr_cassettes/Authenticating_an_online_user.yml +90 -0
  283. data/spec/fixtures/vcr_cassettes/Creating_a_conversation/creates_a_new_call.yml +42 -0
  284. data/spec/fixtures/vcr_cassettes/Creating_a_conversation/creates_a_new_conversation.yml +42 -0
  285. data/spec/fixtures/vcr_cassettes/Creating_a_conversation/returns_the_conversation_as_JSON.yml +42 -0
  286. data/spec/fixtures/vcr_cassettes/Pusher_channel_as_JSON.yml +90 -0
  287. data/spec/fixtures/vcr_cassettes/Pusher_to_publish_the_event.yml +32 -0
  288. data/spec/fixtures/vcr_cassettes/Reloading_the_widget_during_a_call/_create/during_a_call/after_a_failed_transfer/pushes_the_event_for_the_active_call.yml +1110 -0
  289. data/spec/fixtures/vcr_cassettes/Telephony_ConversationsController/_create/by_default/creates_a_new_call.yml +45 -0
  290. data/spec/fixtures/vcr_cassettes/Telephony_ConversationsController/_create/by_default/creates_a_new_conversation.yml +43 -0
  291. data/spec/fixtures/vcr_cassettes/Telephony_ConversationsController/_create/by_default/returns_the_conversation_as_JSON.yml +44 -0
  292. data/spec/fixtures/vcr_cassettes/Telephony_Providers_TwilioProvider/_call/allows_the_phone_to_ring_for_60_seconds.yml +42 -0
  293. data/spec/fixtures/vcr_cassettes/Telephony_Providers_TwilioProvider/_call/includes_a_status_change_callback_url.yml +42 -0
  294. data/spec/fixtures/vcr_cassettes/Telephony_Providers_TwilioProvider/_call/places_a_call.yml +42 -0
  295. data/spec/fixtures/vcr_cassettes/Telephony_Providers_TwilioProvider/_dial_into_conference/allows_the_phone_to_ring_for_15_seconds.yml +42 -0
  296. data/spec/fixtures/vcr_cassettes/Telephony_Providers_TwilioProvider/_dial_into_conference/places_a_call_to_redirect_the_participant_to_a_conference.yml +42 -0
  297. data/spec/fixtures/vcr_cassettes/Telephony_Providers_TwilioProvider/_hangup/by_default/hangs_up_the_call.yml +42 -0
  298. data/spec/fixtures/vcr_cassettes/buying_number_for_an_area_code.yml +42 -0
  299. data/spec/fixtures/vcr_cassettes/returns_success.yml +90 -0
  300. data/spec/javascripts/helpers/jasmine-jquery.js +546 -0
  301. data/spec/javascripts/helpers/mock-ajax.js +207 -0
  302. data/spec/javascripts/support/jasmine.yml +80 -0
  303. data/spec/javascripts/telephony/models/agent_spec.js +40 -0
  304. data/spec/javascripts/telephony/models/conversation_spec.js +515 -0
  305. data/spec/javascripts/telephony/models/device_spec.js +80 -0
  306. data/spec/javascripts/telephony/models/transfer_spec.js +22 -0
  307. data/spec/javascripts/telephony/push_spec.js +427 -0
  308. data/spec/javascripts/telephony/views/agents_view_spec.js +101 -0
  309. data/spec/javascripts/telephony/views/application_view_spec.js +74 -0
  310. data/spec/javascripts/telephony/views/conversation_view_spec.js +626 -0
  311. data/spec/javascripts/telephony/views/status_view_spec.js +30 -0
  312. data/spec/javascripts/telephony/views/transfer_view_spec.js +187 -0
  313. data/spec/javascripts/telephony/views/twilio_client_view_spec.js +77 -0
  314. data/spec/javascripts/telephony/views/widget_view_spec.js +20 -0
  315. data/spec/lib/telephony/concerns/controllers/twilio_request_verifier_spec.rb +77 -0
  316. data/spec/lib/telephony/conversation_data_spec.rb +342 -0
  317. data/spec/lib/telephony/helper_spec.rb +24 -0
  318. data/spec/lib/telephony/jobs/agent_offline_spec.rb +37 -0
  319. data/spec/lib/telephony/jobs/pusher_event_spec.rb +39 -0
  320. data/spec/lib/telephony/providers/twilio_provider_spec.rb +439 -0
  321. data/spec/lib/telephony_spec.rb +104 -0
  322. data/spec/models/telephony/agent_spec.rb +479 -0
  323. data/spec/models/telephony/agent_state_machine_spec.rb +131 -0
  324. data/spec/models/telephony/call_center_spec.rb +32 -0
  325. data/spec/models/telephony/call_spec.rb +597 -0
  326. data/spec/models/telephony/call_state_machine_spec.rb +472 -0
  327. data/spec/models/telephony/conversation_spec.rb +751 -0
  328. data/spec/models/telephony/conversation_state_machine_spec.rb +387 -0
  329. data/spec/models/telephony/conversations_presenter_spec.rb +40 -0
  330. data/spec/models/telephony/event_spec.rb +716 -0
  331. data/spec/models/telephony/inbound_conversation_queue_spec.rb +243 -0
  332. data/spec/models/telephony/playable_listener_spec.rb +43 -0
  333. data/spec/models/telephony/pusher_event_publisher_spec.rb +36 -0
  334. data/spec/models/telephony/recording_spec.rb +6 -0
  335. data/spec/models/telephony/voicemail_spec.rb +96 -0
  336. data/spec/observers/telephony/agent_observer_spec.rb +21 -0
  337. data/spec/observers/telephony/event_observer_spec.rb +19 -0
  338. data/spec/requests/create_conversation_spec.rb +39 -0
  339. data/spec/requests/dequeue_call_spec.rb +42 -0
  340. data/spec/requests/list_conversations_spec.rb +33 -0
  341. data/spec/requests/presences_spec.rb +51 -0
  342. data/spec/requests/providers/twilio/calls/child_answered_spec.rb +24 -0
  343. data/spec/requests/providers/twilio/calls/child_detached_spec.rb +249 -0
  344. data/spec/requests/providers/twilio/calls/dial_spec.rb +132 -0
  345. data/spec/requests/providers/twilio/calls/done_spec.rb +69 -0
  346. data/spec/requests/providers/twilio/calls/join_conference_spec.rb +56 -0
  347. data/spec/requests/providers/twilio/calls/leave_queue_spec.rb +44 -0
  348. data/spec/requests/providers/twilio/calls/parent_answered_spec.rb +59 -0
  349. data/spec/requests/providers/twilio/inbound/connect_dequeued_call_spec.rb +124 -0
  350. data/spec/requests/providers/twilio/inbound/enqueue_inbound_call_spec.rb +108 -0
  351. data/spec/requests/providers/twilio/inbound/enqueued_call_wait_music_spec.rb +13 -0
  352. data/spec/requests/providers/twilio/voicemails/leave_voicemail_spec.rb +78 -0
  353. data/spec/requests/search_conversations_spec.rb +101 -0
  354. data/spec/requests/transfer_spec.rb +65 -0
  355. data/spec/requests/voicemail_api_spec.rb +58 -0
  356. data/spec/spec_helper.rb +27 -0
  357. data/spec/support/factory_girl.rb +5 -0
  358. data/spec/support/matchers/be_complete_hold.rb +20 -0
  359. data/spec/support/matchers/be_whisper_tone.rb +35 -0
  360. data/spec/support/matchers/join_conference.rb +23 -0
  361. data/spec/support/nokogiri.rb +1 -0
  362. data/spec/support/pusher_helper.rb +24 -0
  363. data/spec/support/vcr.rb +12 -0
  364. data/spec/support/webmock.rb +1 -0
  365. metadata +692 -0
@@ -0,0 +1,131 @@
1
+ require 'spec_helper'
2
+
3
+ module Telephony
4
+ describe AgentStateMachine do
5
+ describe '#status' do
6
+ before do
7
+ @agent = create :agent
8
+ end
9
+
10
+ it 'defaults to "offline"' do
11
+ @agent.status.should == Agent::OFFLINE
12
+ end
13
+ end
14
+
15
+ describe '#available!' do
16
+ context 'given an offline agent' do
17
+ before do
18
+ @agent = create :agent
19
+
20
+ @agent.available!
21
+
22
+ @agent.reload
23
+ end
24
+
25
+ it 'transitions into available status' do
26
+ @agent.status.should == Agent::AVAILABLE
27
+ end
28
+ end
29
+ end
30
+
31
+ describe '#offline!' do
32
+ context "given an available agent" do
33
+ before do
34
+ @agent = create :available_agent
35
+
36
+ @agent.offline!
37
+
38
+ @agent.reload
39
+ end
40
+
41
+ it 'transitions into offline status' do
42
+ @agent.status.should == Agent::OFFLINE
43
+ end
44
+ end
45
+ end
46
+
47
+ describe '#on_a_call!' do
48
+ context 'given an available agent' do
49
+ before do
50
+ @agent = create :available_agent
51
+
52
+ @agent.on_a_call!
53
+
54
+ @agent.reload
55
+ end
56
+
57
+ it 'transitions into on a call status' do
58
+ @agent.status.should == Agent::ON_A_CALL
59
+ end
60
+ end
61
+ end
62
+
63
+ describe '#not_available!' do
64
+ context 'given a agent on a call' do
65
+ before do
66
+ @agent = create :on_a_call_agent
67
+
68
+ @agent.not_available
69
+
70
+ @agent.reload
71
+ end
72
+
73
+ it 'does not transition to not available' do
74
+ @agent.status.should == Agent::ON_A_CALL
75
+ end
76
+ end
77
+
78
+ context 'given an available agent' do
79
+ before do
80
+ @agent = create :available_agent
81
+
82
+ @agent.not_available
83
+
84
+ @agent.reload
85
+ end
86
+
87
+ it 'transitions to not available' do
88
+ @agent.status.should == Agent::NOT_AVAILABLE
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ describe '#after_transition' do
95
+ before do
96
+ @subscriber = ActiveSupport::Notifications.subscribe("telephony.agent_status_change") do |*args|
97
+ @event = ActiveSupport::Notifications::Event.new(*args)
98
+ end
99
+ end
100
+
101
+ after do
102
+ ActiveSupport::Notifications.unsubscribe(@subscriber)
103
+ end
104
+
105
+ context "when the status changes" do
106
+ before do
107
+ @agent = create :offline_agent
108
+ @agent.available
109
+ end
110
+
111
+ it "publishes the status change" do
112
+ @event.should_not be_nil
113
+ @event.payload[:agent_id].should == @agent.id
114
+ @event.payload[:csr_id].should == @agent.csr_id
115
+ @event.payload[:status].should == @agent.status
116
+ @event.payload.should include(:timestamp)
117
+ end
118
+ end
119
+
120
+ context "when status doesn't change" do
121
+ before do
122
+ agent = create :available_agent
123
+ agent.available
124
+ end
125
+
126
+ it "does not publish the status change" do
127
+ @event.should be_nil
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,32 @@
1
+ require_relative File.join __FILE__, '../../../../app/models/telephony/call_center'
2
+
3
+ module Telephony
4
+ describe CallCenter do
5
+ before do
6
+ @development_config = CallCenter.load "test", "spec/dummy/config/call_centers.yml"
7
+ end
8
+
9
+ describe "#load" do
10
+ it "load a config for a given environment" do
11
+ call_center = @development_config.first
12
+ call_center['name'].should == 'hollywood'
13
+ call_center['host'].should == '192.168.1.1'
14
+ end
15
+ end
16
+
17
+ describe "#all" do
18
+ before { CallCenter.load "development" }
19
+ it "retuns all call centers" do
20
+ CallCenter.all.count.should == 2
21
+ CallCenter.all.first.name.should == 'hollywood'
22
+ end
23
+ end
24
+
25
+ describe "#find_by_name" do
26
+ it "returns first matching call center" do
27
+ call_center = CallCenter.find_by_name 'other_location'
28
+ call_center.name.should == "other_location"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,597 @@
1
+ require 'spec_helper'
2
+
3
+ module Telephony
4
+ describe Call do
5
+ describe '#make!' do
6
+ context 'when calling the initiator' do
7
+ before do
8
+ @call = create(:call, number: '222-222-2222')
9
+
10
+ @sid = '2'
11
+ call = double 'call', sid: @sid
12
+ provider = double('Provider')
13
+ provider.stub(:call).with(@call.id, @call.number, @call.caller_id).and_return(call)
14
+ Telephony.stub(:provider).and_return(provider)
15
+
16
+ @call.make!
17
+ end
18
+
19
+ it 'calls the initiator using a telephony provider' do
20
+ @call.reload
21
+ @call.sid.should == @sid
22
+ end
23
+ end
24
+
25
+ context 'when calling a non-whitelisted number' do
26
+ before do
27
+ @existing_whitelist = Telephony.whitelist
28
+ Telephony.whitelist = []
29
+ @call = create :call, number: '555-555-5555'
30
+
31
+ @sid = '1'
32
+ call = double 'call',
33
+ sid: @sid
34
+ provider = double 'provider'
35
+ provider
36
+ .should_receive(:call)
37
+ .and_return(call)
38
+ provider.stub(:uncallable_number)
39
+ Telephony.stub(:provider).and_return(provider)
40
+
41
+ @call.make!
42
+ end
43
+
44
+ after do
45
+ Telephony.whitelist = @existing_whitelist
46
+ end
47
+
48
+ it "uses the number's non-whitelisted area code when determining the caller id" do
49
+ @call.reload
50
+ @call.sid.should == @sid
51
+ end
52
+ end
53
+
54
+ after do
55
+ Telephony.unstub :provider
56
+ end
57
+ end
58
+
59
+ describe '#dial_into_conference!' do
60
+ context "when calling the transferred to agent" do
61
+ before do
62
+ @caller_id = '1234567890'
63
+ @participant = create(:transferred_participant, number: '222-222-2222')
64
+ @participant.stub(:caller_id).and_return(@caller_id)
65
+
66
+ @sid = '1'
67
+ call = double 'call', sid: @sid
68
+ provider = double('Provider')
69
+ provider
70
+ .stub(:dial_into_conference)
71
+ .with(@participant.id, @participant.number, @caller_id)
72
+ .and_return(call)
73
+ Telephony
74
+ .stub(:provider)
75
+ .and_return(provider)
76
+
77
+ @participant.dial_into_conference!
78
+ end
79
+
80
+ it 'dials the agent into the conference' do
81
+ @participant.reload
82
+ @participant.sid.should == @sid
83
+ end
84
+ end
85
+
86
+ context 'when calling a non-whitelisted number' do
87
+ before do
88
+ @existing_whitelist = Telephony.whitelist
89
+ Telephony.whitelist = []
90
+ @call = create :call
91
+
92
+ @sid = '1'
93
+ call = double 'call'
94
+ call.stub(:sid).and_return(@sid)
95
+ provider = double 'provider'
96
+ provider
97
+ .stub(:dial_into_conference)
98
+ .and_return(call)
99
+ provider.stub(:uncallable_number)
100
+ Telephony
101
+ .stub(:provider)
102
+ .and_return(provider)
103
+
104
+ @call.dial_into_conference!
105
+ end
106
+
107
+ after do
108
+ Telephony.whitelist = @existing_whitelist
109
+ end
110
+
111
+ it "uses the number's non-whitelisted area code when determining the caller id" do
112
+ @call.reload
113
+ @call.sid.should == @sid
114
+ end
115
+ end
116
+
117
+ after do
118
+ Telephony.unstub :provider
119
+ end
120
+ end
121
+
122
+ describe "#recorded?" do
123
+ context "given an initiator call" do
124
+ let(:agent) {create :agent}
125
+ before do
126
+ @call = create :call, agent: agent
127
+ end
128
+
129
+ it 'returns false' do
130
+ @call.should_not be_recorded
131
+ end
132
+ end
133
+
134
+ context "given a transferred call" do
135
+ let(:agent) {create :agent}
136
+ before do
137
+ @call = create :transferred_participant, agent: agent
138
+ end
139
+
140
+ it 'returns false' do
141
+ @call.should_not be_recorded
142
+ end
143
+ end
144
+
145
+ context "given any other call" do
146
+ before do
147
+ call = create :call
148
+ @call = create :participant, :conversation => call.conversation
149
+ end
150
+
151
+ it 'returns true' do
152
+ @call.should be_recorded
153
+ end
154
+ end
155
+ end
156
+
157
+ describe '#save' do
158
+ context 'on create' do
159
+ context 'and with no initial state' do
160
+ before do
161
+ @call = build :call
162
+ @call.save
163
+ end
164
+
165
+ it 'defaults its state to "not_initiated"' do
166
+ @call.reload
167
+ @call.state.should == 'not_initiated'
168
+ end
169
+ end
170
+
171
+ context 'and with an initial state' do
172
+ before do
173
+ @call = build :call, state: 'terminated'
174
+ @call.save
175
+ end
176
+
177
+ it 'does not reset its state to not_initiated' do
178
+ @call.reload
179
+ @call.state.should_not == 'not_initiated'
180
+ end
181
+ end
182
+ end
183
+ end
184
+
185
+ describe '#answer!' do
186
+ before do
187
+ @call = create :call, :state => :connecting
188
+ @expected_time = Time.zone.now
189
+ Time.zone.stub(:now).and_return(@expected_time)
190
+
191
+ @call.answer!
192
+
193
+ @call.reload
194
+ end
195
+
196
+ it 'updates its state to "in_progress"' do
197
+ @call.state.should == 'in_progress'
198
+ end
199
+
200
+ it 'sets its connected at timestamp' do
201
+ @call.connected_at.to_s.should == @expected_time.to_s
202
+ end
203
+ end
204
+
205
+ describe '#terminate!' do
206
+ context 'by default' do
207
+ before do
208
+ @call = create :call
209
+
210
+ @expected_time = Time.zone.now
211
+ Time.zone.stub(:now => @expected_time)
212
+
213
+ @call.terminate!
214
+ @call.reload
215
+ end
216
+
217
+ it 'sets its state to "terminated"' do
218
+ @call.state.should == 'terminated'
219
+ end
220
+
221
+ it 'sets its terminated timestamp' do
222
+ @call.terminated_at.to_s.should == @expected_time.to_s
223
+ end
224
+
225
+ end
226
+
227
+ context 'In a conversation, customer leg hangs up' do
228
+
229
+ before do
230
+ ActiveRecord::Base.observers.enable :all
231
+ Telephony::PusherEventPublisher.stub(:push)
232
+ @convo = create :in_progress_conversation
233
+ @call1 = create :active_agent_leg, conversation_id: @convo.id
234
+ @call2 = create :customer_leg, conversation_id: @convo.id
235
+ @call1.agent.update_attribute(:status, 'on_a_call')
236
+ end
237
+
238
+ after do
239
+ ActiveRecord::Base.observers.disable :all
240
+ end
241
+
242
+ it 'Agent should be not available' do
243
+ @call2.terminate!
244
+ @call1.agent.reload
245
+ @call1.agent.should be_not_available
246
+ end
247
+
248
+ end
249
+
250
+
251
+ context 'given a one step transfer call' do
252
+ before do
253
+ @call = create :one_step_transfer_call
254
+ end
255
+
256
+ it 'does not hangup on the initiator' do
257
+ Telephony
258
+ .provider
259
+ .should_not_receive(:hangup)
260
+
261
+ @call.terminate!
262
+ end
263
+ end
264
+
265
+ context 'given a two step transfer call' do
266
+ before do
267
+ @call = create :two_step_transfer_call, state: :in_conference
268
+ end
269
+
270
+ after do
271
+ Telephony.unstub :provider
272
+ end
273
+
274
+ context 'with two participants' do
275
+ context 'and the initiator hangs up' do
276
+ before do
277
+ @participant = create :call, conversation: @call.conversation, state: :in_conference
278
+ @call.reload
279
+ end
280
+
281
+ it "hangs up the other participant" do
282
+ provider = double 'Provider'
283
+ provider.should_receive(:hangup).with(@participant.sid)
284
+ Telephony.stub(:provider).and_return(provider)
285
+
286
+ @call.terminate!
287
+ end
288
+ end
289
+
290
+ context 'and the participant hangs up' do
291
+ before do
292
+ @participant = create :participant, conversation: @call.conversation
293
+ @call.reload
294
+ end
295
+
296
+ it "hangs up on the initiator" do
297
+ provider = double 'Provider'
298
+ provider.should_receive(:hangup).with(@call.sid)
299
+ Telephony.stub(:provider).and_return(provider)
300
+
301
+ @participant.terminate!
302
+ end
303
+ end
304
+ end
305
+
306
+ context 'with three participants' do
307
+ context 'and the initiator hangs up' do
308
+ before do
309
+ create :call, conversation: @call.conversation
310
+ create :active_agent_leg, conversation: @call.conversation
311
+ @call.reload
312
+ end
313
+
314
+ it "does not hang up the other participants" do
315
+ provider = double 'Provider'
316
+ provider.should_not_receive(:hangup)
317
+ Telephony.stub(:provider).and_return(provider)
318
+
319
+ @call.terminate!
320
+ end
321
+ end
322
+
323
+ context 'and the initiator hangs up, then a participant hangs up' do
324
+ before do
325
+ @participants = [
326
+ create(:call, conversation: @call.conversation, state: :in_conference),
327
+ create(:active_agent_leg, conversation: @call.conversation, state: :in_conference)
328
+ ]
329
+ @call.reload
330
+ end
331
+
332
+ it "hangs up the other participant" do
333
+ first_participant, second_participant = @participants
334
+ provider = double 'Provider'
335
+ provider.should_receive(:hangup).with(second_participant.sid)
336
+ Telephony.stub(:provider).and_return(provider)
337
+
338
+ @call.terminate!
339
+ first_participant.terminate!
340
+ end
341
+ end
342
+
343
+ context 'and one of the participants hangs up' do
344
+ before do
345
+ @participant = create :call, conversation: @call.conversation
346
+ create :active_agent_leg, conversation: @call.conversation
347
+ @call.reload
348
+ end
349
+
350
+ it "does not hang up the initiator or the other participant" do
351
+ provider = double 'Provider'
352
+ provider.should_not_receive(:hangup)
353
+ Telephony.stub(:provider).and_return(provider)
354
+
355
+ @participant.terminate!
356
+ end
357
+ end
358
+ end
359
+ end
360
+
361
+ context 'given an attempted transfer' do
362
+ before do
363
+ @conversation = create :conversation, state: :two_step_transferring
364
+ @agent1 = create :call,
365
+ conversation: @conversation,
366
+ state: :in_conference,
367
+ agent: create(:agent)
368
+ @customer = create :call,
369
+ conversation: @conversation,
370
+ state: :in_conference
371
+ @agent2 = create :call,
372
+ conversation: @conversation,
373
+ state: :connecting,
374
+ agent: create(:agent)
375
+ end
376
+
377
+
378
+ context 'when the transferred participant does not answer' do
379
+ before do
380
+ @agent2.no_answer!
381
+ @conversation.reload
382
+ end
383
+
384
+ context 'and the customer hangs up' do
385
+ after do
386
+ Telephony.unstub :provider
387
+ end
388
+
389
+ it 'hangs up on the initiator' do
390
+ provider = double 'Provider'
391
+ provider.should_receive(:hangup).with(@agent1.sid)
392
+ Telephony.stub(:provider).and_return(provider)
393
+
394
+ @customer.terminate!
395
+ end
396
+ end
397
+ end
398
+ end
399
+ end
400
+
401
+ describe '#number' do
402
+ before do
403
+ @call = build :call
404
+ @whitelisted_number = '1234567890'
405
+ @existing_whitelist = Telephony.whitelist
406
+ Telephony.whitelist = [@whitelisted_number]
407
+ end
408
+
409
+ subject { @call.number }
410
+
411
+ after { Telephony.whitelist = @existing_whitelist }
412
+
413
+ context 'given a call to a whitelisted number' do
414
+ before { @call.number = @whitelisted_number }
415
+ it { should == @whitelisted_number }
416
+ end
417
+
418
+ context 'given a call to a non-whitelisted number' do
419
+ before { @call.number = '9999999999' }
420
+ it { should == 'this-number-is-not-whitelisted' }
421
+ end
422
+
423
+ context 'given an agents call' do
424
+ before { @call.agent = build :agent, phone_number: '1231231234' }
425
+ it { should == @call.agent.phone_number }
426
+ end
427
+ end
428
+
429
+ describe '#whitelisted_number?' do
430
+ before do
431
+ @existing_whitelist = Telephony.whitelist
432
+ end
433
+
434
+ after do
435
+ Telephony.whitelist = @existing_whitelist
436
+ end
437
+
438
+ context 'given a call to a whitelisted number' do
439
+ before do
440
+ phone_number = '555-555-5555'
441
+ Telephony.whitelist = [phone_number]
442
+ @call = create :call, number: phone_number
443
+ end
444
+
445
+ it 'returns true' do
446
+ @call.should be_whitelisted_number
447
+ end
448
+ end
449
+
450
+ context 'given a call to a non-whitelisted number' do
451
+ before do
452
+ @call = create :call
453
+ Telephony.whitelist = []
454
+ end
455
+
456
+ it 'returns false' do
457
+ @call.should_not be_whitelisted_number
458
+ end
459
+ end
460
+
461
+ context 'given an agents leg' do
462
+ before do
463
+ Telephony.whitelist = []
464
+ agent = create :agent
465
+ @call = create :call, agent: agent
466
+ end
467
+
468
+ it 'returns true' do
469
+ @call.should be_whitelisted_number
470
+ end
471
+ end
472
+
473
+ context 'given a customers leg' do
474
+ before do
475
+ Telephony.whitelist = []
476
+ @call = create :call, agent: nil
477
+ end
478
+
479
+ it 'returns false' do
480
+ @call.should_not be_whitelisted_number
481
+ end
482
+ end
483
+ end
484
+
485
+ describe '#record!' do
486
+ context 'given a recording url and duration' do
487
+ before do
488
+ @call = create :call
489
+ @recording_url = 'recording_url'
490
+ @recording_duration = 0
491
+
492
+ @call.record! RecordingUrl: @recording_url,
493
+ RecordingDuration: @recording_duration
494
+
495
+ @call.reload
496
+ end
497
+
498
+ it 'updates its recording url' do
499
+ @call.recordings.last.url.should == @recording_url
500
+ end
501
+
502
+ it 'updates its recording duration' do
503
+ @call.recordings.last.duration.should == @recording_duration
504
+ end
505
+ end
506
+
507
+ context 'when not given a recording url and duration' do
508
+ before do
509
+ @call = create :call
510
+
511
+ @recordings_count = @call.recordings.count
512
+ @call.record!({})
513
+ @call.reload
514
+ end
515
+
516
+ it 'does not create a recording' do
517
+ @call.recordings.count.should == @recordings_count
518
+ end
519
+
520
+ end
521
+ end
522
+
523
+ describe '#redirect_to_dial' do
524
+ before do
525
+ @call = create :call
526
+ provider = double 'provider'
527
+ provider
528
+ .should_receive(:redirect_to_dial)
529
+ .with(@call.id, @call.sid)
530
+ Telephony
531
+ .stub(:provider)
532
+ .and_return(provider)
533
+ end
534
+
535
+ it 'redirects the call to dial' do
536
+ @call.redirect_to_dial
537
+ end
538
+ end
539
+
540
+ describe '#redirect_to_conference' do
541
+ before do
542
+ @call = create :call
543
+ provider = double 'provider'
544
+ provider
545
+ .should_receive(:redirect_to_conference)
546
+ .with(@call.id, @call.sid)
547
+ Telephony
548
+ .stub(:provider)
549
+ .and_return(provider)
550
+ end
551
+
552
+ it 'redirects the call to a conference' do
553
+ @call.redirect_to_conference
554
+ end
555
+ end
556
+
557
+ describe '#redirect_to_hold' do
558
+ before do
559
+ @call = create :call
560
+ provider = double 'provider'
561
+ provider
562
+ .should_receive(:redirect_to_hold)
563
+ .with(@call.id, @call.sid)
564
+ Telephony
565
+ .stub(:provider)
566
+ .and_return(provider)
567
+ end
568
+
569
+ it 'redirects the call to a hold' do
570
+ @call.redirect_to_hold
571
+ end
572
+ end
573
+
574
+ describe '#agent?' do
575
+ context 'given a call for a CSR' do
576
+ let(:agent) {create :agent}
577
+ before do
578
+ @call = create :call, agent: agent
579
+ end
580
+
581
+ it 'returns true' do
582
+ @call.should be_an_agent
583
+ end
584
+ end
585
+
586
+ context 'given a call not for a CSR' do
587
+ before do
588
+ @call = create :call, agent: nil
589
+ end
590
+
591
+ it 'returns false' do
592
+ @call.should_not be_an_agent
593
+ end
594
+ end
595
+ end
596
+ end
597
+ end