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,132 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Dialing a whitelisted number' do
4
+ before do
5
+ @to = '8881234567'
6
+ @conversation = create :initiating_one_step_transferring_conversation
7
+ @call = @conversation.initiating_call
8
+ @child_call = @conversation.not_initiated_call
9
+
10
+ @existing_whitelist = Telephony.whitelist
11
+ Telephony.whitelist = [@to]
12
+ end
13
+
14
+ after do
15
+ Telephony.whitelist = @existing_whitelist
16
+ end
17
+
18
+ context 'when one-step transferring to an available agent' do
19
+ context "with a phone number" do
20
+ before do
21
+ agent = create :available_agent, phone_number: @to
22
+ @child_call.update_attributes agent: agent, number: @to
23
+
24
+ post "/zestphone/providers/twilio/calls/#{@call.id}/dial"
25
+ end
26
+
27
+ it 'returns TwiML for dialing to a specific number' do
28
+ xml = Nokogiri::XML response.body
29
+ dial = xml.at('/Response/Dial')
30
+ dial.attributes['method'].value.should == 'POST'
31
+ dial.attributes['action'].value.should == "/zestphone/providers/twilio/calls/#{@call.id}/child_detached"
32
+ dial.attributes['record'].value.should == 'true'
33
+ dial.attributes['timeout'].value.should == '15'
34
+ number = dial.at('Number')
35
+ number.attributes['url'].value.should == "/zestphone/providers/twilio/calls/#{@child_call.id}/child_answered"
36
+ number.text.should == @to
37
+ end
38
+ end
39
+
40
+ context "with a twilio client" do
41
+ before do
42
+ @agent = create :available_agent,
43
+ phone_type: Telephony::Agent::PhoneType::TWILIO_CLIENT
44
+ @child_call.update_attributes agent: @agent
45
+
46
+ post "/zestphone/providers/twilio/calls/#{@call.id}/dial"
47
+ end
48
+
49
+ it "returns TwiML for dialing to the agent's twilio client" do
50
+ xml = Nokogiri::XML response.body
51
+ dial = xml.at('/Response/Dial')
52
+ dial.attributes['method'].value.should == 'POST'
53
+ dial.attributes['action'].value.should == "/zestphone/providers/twilio/calls/#{@call.id}/child_detached"
54
+ dial.attributes['record'].value.should == 'true'
55
+ dial.attributes['timeout'].value.should == '15'
56
+ client = dial.at('Client')
57
+ client.attributes['url'].value.should == "/zestphone/providers/twilio/calls/#{@child_call.id}/child_answered"
58
+ client.text.should == "agent#{@agent.csr_id}"
59
+ end
60
+ end
61
+
62
+ context "with a sip" do
63
+ before do
64
+ @agent = create :available_agent,
65
+ phone_type: Telephony::Agent::PhoneType::SIP,
66
+ sip_number: 200,
67
+ call_center_name: 'other_location'
68
+ @child_call.update_attributes agent: @agent
69
+
70
+ post "/zestphone/providers/twilio/calls/#{@call.id}/dial"
71
+ end
72
+
73
+ it "returns TwiML for dialing to the agent's sip number" do
74
+ xml = Nokogiri::XML response.body
75
+ dial = xml.at('/Response/Dial')
76
+ dial.attributes['method'].value.should == 'POST'
77
+ dial.attributes['action'].value.should == "/zestphone/providers/twilio/calls/#{@call.id}/child_detached"
78
+ dial.attributes['record'].value.should == 'true'
79
+ dial.attributes['timeout'].value.should == '15'
80
+ client = dial.at('Sip')
81
+ client.attributes['url'].value.should == "/zestphone/providers/twilio/calls/#{@child_call.id}/child_answered"
82
+ client.text.should == "200@192.168.1.2"
83
+ end
84
+ end
85
+ end
86
+
87
+ context 'when leaving a voicemail for an unavailable agent' do
88
+ before do
89
+ @conversation.leave_voicemail!
90
+ @agent = create :not_available_agent, phone_number: @to
91
+ @child_call.update_attributes agent: @agent, number: @to
92
+
93
+ post "/zestphone/providers/twilio/calls/#{@call.id}/dial"
94
+ end
95
+
96
+ it 'returns TwiML for leaving a voicemail' do
97
+ xml = Nokogiri::XML response.body
98
+ say = xml.at '/Response/Say'
99
+ say.text.should =~ /at extension #{@agent.phone_ext}/i
100
+ say.text.should =~ /record your message/i
101
+ record = xml.at '/Response/Record'
102
+ record.attributes['action'].value.should == "/zestphone/providers/twilio/calls/#{@call.id}/voicemail?csr_id=#{@agent.csr_id}"
103
+ end
104
+ end
105
+ end
106
+
107
+ describe 'Dialing a non-whitelisted number' do
108
+ context "one step transferring to an agent" do
109
+ before do
110
+ @to = '8881234567'
111
+ @conversation = create :initiating_one_step_transferring_conversation
112
+ @call = @conversation.initiating_call
113
+ @child_call = @conversation.not_initiated_call
114
+ available_agent = create :available_agent, phone_number: @to
115
+ @child_call.update_attributes agent: available_agent
116
+ @existing_whitelist = Telephony.whitelist
117
+ Telephony.whitelist = []
118
+
119
+ post "/zestphone/providers/twilio/calls/#{@call.id}/dial"
120
+ end
121
+
122
+ after do
123
+ Telephony.whitelist = @existing_whitelist
124
+ end
125
+
126
+ it 'dials the number since we trust our agents' do
127
+ xml = Nokogiri::XML response.body
128
+ number = xml.at('/Response/Dial/Number')
129
+ number.text.should == @to
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'When the callee does not answer' do
4
+ before do
5
+ agent = create :agent
6
+ @call = create :connecting_call, agent: agent
7
+
8
+ post "/zestphone/providers/twilio/calls/#{@call.id}/done",
9
+ { CallStatus: 'no-answer'}
10
+ end
11
+
12
+ it 'sets the call as terminated' do
13
+ @call.reload
14
+ @call.should be_terminated
15
+ end
16
+ end
17
+
18
+ describe 'When the call ends' do
19
+ before do
20
+ agent = create :agent
21
+ @call = create :call, agent: agent
22
+ @recording_url = 'recording_url'
23
+ @recording_duration = 0
24
+
25
+ post "/zestphone/providers/twilio/calls/#{@call.id}/done",
26
+ { CallStatus: 'completed',
27
+ RecordingUrl: @recording_url,
28
+ RecordingDuration: @recording_duration }
29
+
30
+ @call.reload
31
+ end
32
+
33
+ it 'saves the recording of the call' do
34
+ @call.recordings.last.url.should == @recording_url
35
+ @call.recordings.last.duration.should == @recording_duration
36
+ end
37
+
38
+ it 'terminates the call' do
39
+ @call.should be_terminated
40
+ end
41
+
42
+ it 'returns TwiML saying the caller on the other end has hung up' do
43
+ xml = Nokogiri::XML response.body
44
+ say = xml.at('/Response/Say')
45
+ say.text.should =~ /the caller on the other line has hung up/i
46
+ end
47
+ end
48
+
49
+ describe 'When the call has already not been answered' do
50
+ before do
51
+ agent = create :agent
52
+ @call = create :terminated_call, agent: agent
53
+ @recording_url = 'recording_url'
54
+ @recording_duration = 0
55
+ @call.should_not_receive(:no_answer!)
56
+
57
+ post "/zestphone/providers/twilio/calls/#{@call.id}/done",
58
+ { CallStatus: 'no-answer',
59
+ RecordingUrl: @recording_url,
60
+ RecordingDuration: @recording_duration }
61
+
62
+ @call.reload
63
+ end
64
+
65
+ it 'saves the recording of the call' do
66
+ @call.recordings.last.url.should == @recording_url
67
+ @call.recordings.last.duration.should == @recording_duration
68
+ end
69
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Joining a conference' do
4
+
5
+ context "given an 'in_progress' conversation" do
6
+ before do
7
+ @conversation = create :in_progress_conversation_with_calls
8
+ @call = @conversation.active_agent_leg
9
+ @original_conversation_state = @call.conversation.state
10
+
11
+ post "/zestphone/providers/twilio/calls/#{@call.id}/join_conference"
12
+
13
+ @call.reload
14
+ end
15
+
16
+ it "updates the call's state to 'in_conference'" do
17
+ @call.should be_in_conference
18
+ end
19
+
20
+ it 'returns TwiML for joining a conference' do
21
+ @call.should join_conference
22
+ end
23
+
24
+ it 'does not change the conversation state' do
25
+ @call.conversation.state.should == @original_conversation_state
26
+ end
27
+ end
28
+
29
+ context "given an 'initiating_resume' conversation" do
30
+ before do
31
+ @conversation = create :initiating_resume_conversation
32
+ create :active_agent_leg, :state => 'in_conference', :conversation => @conversation
33
+ call = create :call, :state => 'in_progress_hold', :conversation => @conversation
34
+
35
+ post "/zestphone/providers/twilio/calls/#{call.id}/join_conference"
36
+ end
37
+
38
+ it "triggers 'complete_resume' event on the conversation" do
39
+ @conversation.reload.should be_in_progress
40
+ end
41
+ end
42
+
43
+ context "given an 'initiating_hold' conversation" do
44
+ before do
45
+ @conversation = create :initiating_hold_conversation
46
+ agent_call = create :active_agent_leg, :state => 'in_progress', :conversation => @conversation
47
+ create :call, :state => 'in_progress_hold', :conversation => @conversation
48
+
49
+ post "/zestphone/providers/twilio/calls/#{agent_call.id}/join_conference"
50
+ end
51
+
52
+ it "triggers 'complete_hold' event on the conversation" do
53
+ @conversation.reload.should be_in_progress_hold
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'When the caller hangs up' do
4
+ before do
5
+ @call = create :call
6
+
7
+ post "/zestphone/providers/twilio/calls/#{@call.id}/leave_queue",
8
+ { QueueResult: "hangup" }
9
+ end
10
+
11
+ it 'sets the call as terminated' do
12
+ @call.reload
13
+ @call.should be_terminated
14
+ end
15
+ end
16
+
17
+ describe 'When Twilio fails to enqueue the caller call' do
18
+ before do
19
+ @call = create :call
20
+ Rails.logger.should_receive(:error)
21
+
22
+ post "/zestphone/providers/twilio/calls/#{@call.id}/leave_queue",
23
+ { QueueResult: "error" }
24
+ end
25
+
26
+ it 'sets the call as terminated and logs the error' do
27
+ @call.reload
28
+ @call.should be_terminated
29
+ end
30
+ end
31
+
32
+ describe 'When the caller is taken from the queue' do
33
+ before do
34
+ @call = create :call
35
+
36
+ post "/zestphone/providers/twilio/calls/#{@call.id}/leave_queue",
37
+ { QueueResult: "redirected" }
38
+ end
39
+
40
+ it 'does not change the call state' do
41
+ @call.should be_not_initiated
42
+ end
43
+ end
44
+
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Answering a call' do
4
+ before do
5
+ @existing_whitelist = Telephony.whitelist
6
+ phone_number = '562-555-5555'
7
+ Telephony.whitelist = [phone_number]
8
+
9
+ agent = create :agent
10
+ @call = create :connecting_call, agent: agent
11
+ @participant = create :call,
12
+ number: phone_number,
13
+ conversation: @call.conversation
14
+
15
+ post "/zestphone/providers/twilio/calls/#{@call.id}/connect"
16
+ end
17
+
18
+ after do
19
+ Telephony.whitelist = @existing_whitelist
20
+ end
21
+
22
+ it "updates the conversation's customer's state to 'connecting'" do
23
+ @participant.reload
24
+ @participant.state.should == 'connecting'
25
+ end
26
+
27
+ it 'returns TwiML for calling the callee' do
28
+ xml = Nokogiri::XML response.body
29
+ dial = xml.at('/Response/Dial')
30
+ dial.attributes['action'].value.should == "/zestphone/providers/twilio/calls/#{@call.id}/child_detached"
31
+ dial.attributes['record'].value.should == 'true'
32
+ number = dial.at('Number')
33
+ number.attributes['url'].value.should == "/zestphone/providers/twilio/calls/#{@participant.id}/child_answered"
34
+ number.text.should == @participant.number
35
+ end
36
+ end
37
+
38
+ describe 'Answering a call to a non-whitelisted number' do
39
+ before do
40
+ @existing_whitelist = Telephony.whitelist
41
+ Telephony.whitelist = []
42
+ agent = create :agent
43
+ @call = create :connecting_call, agent: agent
44
+ create :participant,
45
+ conversation: @call.conversation
46
+
47
+ post "/zestphone/providers/twilio/calls/#{@call.id}/connect"
48
+ end
49
+
50
+ after do
51
+ Telephony.whitelist = @existing_whitelist
52
+ end
53
+
54
+ it 'returns TwiML that includes a message about the callee not being whitelisted' do
55
+ xml = Nokogiri::XML response.body
56
+ say = xml.at('/Response/Say')
57
+ say.text.should =~ /The number you are trying to call is not whitelisted/i
58
+ end
59
+ end
@@ -0,0 +1,124 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Connecting a dequeued call' do
4
+ context 'given a non-whitelisted phone number' do
5
+ before do
6
+ Telephony::Call.any_instance.stub(:whitelisted_number?).and_return false
7
+ call = create :call
8
+ agent = create :agent
9
+ create :connecting_agent_leg, conversation: call.conversation, agent: agent
10
+
11
+ post "/zestphone/providers/twilio/inbound_calls/connect?csr_id=#{agent.csr_id}",
12
+ CallSid: call.sid
13
+ end
14
+
15
+ it 'returns TwiML saying the number is not whitelisted' do
16
+ xml = Nokogiri::XML response.body
17
+ say = xml.at '/Response/Say'
18
+ say.text.should =~ /the number you are trying to call is not whitelisted/i
19
+ end
20
+ end
21
+
22
+ context 'given a whitelisted phone number' do
23
+ before do
24
+ Telephony.stub(:whitelisted?).and_return true
25
+ @conversation = create :conversation
26
+ customer_leg = create :call, conversation: @conversation
27
+ @agent = create :agent, phone_number: '222-333-4444'
28
+ create :connecting_agent_leg, conversation: @conversation, agent: @agent
29
+
30
+ post "/zestphone/providers/twilio/inbound_calls/connect?csr_id=#{@agent.csr_id}",
31
+ CallSid: customer_leg.sid
32
+ end
33
+
34
+ it 'creates an agent leg for the conversation' do
35
+ @conversation.reload
36
+ @conversation.should have(2).calls
37
+ agent_leg = @conversation.calls.last
38
+ agent_leg.agent.should == @agent
39
+ end
40
+
41
+ it 'connects the agent leg' do
42
+ @conversation.reload
43
+ agent_leg = @conversation.calls.last
44
+ agent_leg.should be_connecting
45
+ end
46
+
47
+ it 'returns TwiML for dialing the phone number' do
48
+ @conversation.reload
49
+ customer = @conversation.customer
50
+ agent_leg = @conversation.active_agent_leg
51
+
52
+ xml = Nokogiri::XML response.body
53
+
54
+ dial = xml.at '/Response/Dial'
55
+ dial.attributes['record'].value.should == "true"
56
+ dial.attributes['action'].value.should == "/zestphone/providers/twilio/calls/#{customer.id}/child_detached"
57
+
58
+ number = dial.at 'Number'
59
+ number.text.should == @agent.phone_number
60
+ number.attributes['url'].value.should == "/zestphone/providers/twilio/calls/#{agent_leg.id}/child_answered"
61
+ end
62
+ end
63
+
64
+ context 'given a twilio client number' do
65
+ before do
66
+ @conversation = create :conversation, caller_id: 'caller_id'
67
+ customer_leg = create :call, conversation: @conversation
68
+ @agent = create :agent, phone_type: Telephony::Agent::PhoneType::TWILIO_CLIENT
69
+ create :connecting_agent_leg, conversation: @conversation, agent: @agent
70
+
71
+ post "/zestphone/providers/twilio/inbound_calls/connect?csr_id=#{@agent.csr_id}",
72
+ CallSid: customer_leg.sid
73
+ end
74
+
75
+ it "returns TwiML for dialing the agent's twilio client" do
76
+ @conversation.reload
77
+ customer = @conversation.customer
78
+ agent_leg = @conversation.active_agent_leg
79
+
80
+ xml = Nokogiri::XML response.body
81
+
82
+ dial = xml.at '/Response/Dial'
83
+ dial.attributes['record'].value.should == "true"
84
+ dial.attributes['callerId'].value.should == "caller_id"
85
+ dial.attributes['action'].value.should == "/zestphone/providers/twilio/calls/#{customer.id}/child_detached"
86
+
87
+ client = dial.at 'Client'
88
+ client.text.should == "agent#{@agent.csr_id}"
89
+ client.attributes['url'].value.should == "/zestphone/providers/twilio/calls/#{agent_leg.id}/child_answered"
90
+ end
91
+ end
92
+
93
+ context 'given a sip number' do
94
+ before do
95
+ @conversation = create :conversation, caller_id: 'caller_id'
96
+ customer_leg = create :call, conversation: @conversation
97
+ @agent = create :agent,
98
+ phone_type: Telephony::Agent::PhoneType::SIP,
99
+ sip_number: '200',
100
+ call_center_name: 'other_location'
101
+ create :connecting_agent_leg, conversation: @conversation, agent: @agent
102
+
103
+ post "/zestphone/providers/twilio/inbound_calls/connect?csr_id=#{@agent.csr_id}",
104
+ CallSid: customer_leg.sid
105
+ end
106
+
107
+ it "returns TwiML for dialing the agent's sip address" do
108
+ @conversation.reload
109
+ customer = @conversation.customer
110
+ agent_leg = @conversation.active_agent_leg
111
+
112
+ xml = Nokogiri::XML response.body
113
+
114
+ dial = xml.at '/Response/Dial'
115
+ dial.attributes['record'].value.should == "true"
116
+ dial.attributes['callerId'].value.should == "caller_id"
117
+ dial.attributes['action'].value.should == "/zestphone/providers/twilio/calls/#{customer.id}/child_detached"
118
+
119
+ client = dial.at 'Sip'
120
+ client.text.should == "200@192.168.1.2"
121
+ client.attributes['url'].value.should == "/zestphone/providers/twilio/calls/#{agent_leg.id}/child_answered"
122
+ end
123
+ end
124
+ end