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,104 @@
1
+ require 'spec_helper'
2
+
3
+ describe Telephony do
4
+ describe '.whitelisted?' do
5
+ context 'when using a whitelist' do
6
+ before do
7
+ @old_whitelist = Telephony.whitelist
8
+ @whitelisted_number = '1234567890'
9
+ Telephony.whitelist = [@whitelisted_number]
10
+ end
11
+
12
+ after do
13
+ Telephony.whitelist = @old_whitelist
14
+ end
15
+
16
+ context 'and given a whitelisted number' do
17
+ before do
18
+ @whitelisted = Telephony.whitelisted? @whitelisted_number
19
+ end
20
+
21
+ it 'returns true' do
22
+ @whitelisted.should be_true
23
+ end
24
+ end
25
+
26
+ context 'and given a whitelisted number in a custom format' do
27
+ before do
28
+ formatted_whitelisted_number = '(123) 456-7890'
29
+ Telephony.whitelist = [formatted_whitelisted_number.gsub(/\D/, '')]
30
+ @whitelisted = Telephony.whitelisted? formatted_whitelisted_number
31
+ end
32
+
33
+ it 'returns true' do
34
+ @whitelisted.should be_true
35
+ end
36
+ end
37
+
38
+ context 'and given a whitelisted number with a leading country code' do
39
+ before do
40
+ @whitelisted = Telephony.whitelisted? "+1#{@whitelisted_number}"
41
+ end
42
+
43
+ it 'returns true' do
44
+ @whitelisted.should be_true
45
+ end
46
+ end
47
+
48
+ context 'and given a non-whitelisted number' do
49
+ before do
50
+ @whitelisted = Telephony.whitelisted? '1'
51
+ end
52
+
53
+ it 'returns false' do
54
+ @whitelisted.should be_false
55
+ end
56
+ end
57
+
58
+ context 'that contains formatted numbers' do
59
+ before do
60
+ @formatted_number = '(123) 456-7890'
61
+ Telephony.whitelist = [@formatted_number]
62
+ end
63
+
64
+ context 'and given an unformatted whitelisted number' do
65
+ before do
66
+ @whitelisted = Telephony.whitelisted? @formatted_number.gsub(/\D/, '')
67
+ end
68
+
69
+ it 'returns true' do
70
+ @whitelisted.should be_true
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ context 'when not using a whitelist' do
77
+ before do
78
+ @old_whitelist = Telephony.whitelist
79
+ Telephony.whitelist = nil
80
+
81
+ @whitelisted = Telephony.whitelisted? '1234567890'
82
+ end
83
+
84
+ after do
85
+ Telephony.whitelist = @old_whitelist
86
+ end
87
+
88
+ it 'returns true' do
89
+ @whitelisted.should be_true
90
+ end
91
+ end
92
+ end
93
+
94
+ describe '.americanize' do
95
+ it 'unformats a formatted number' do
96
+ Telephony.americanize('(123) 456-7890').should == '1234567890'
97
+ end
98
+
99
+ it 'does nothing to an unformatted number' do
100
+ Telephony.americanize('1234567890').should == '1234567890'
101
+ end
102
+ end
103
+ end
104
+
@@ -0,0 +1,479 @@
1
+ require 'spec_helper'
2
+
3
+ module Telephony
4
+ describe Agent do
5
+ before { VCR.insert_cassette "Pusher channel as JSON", match_requests_on: [:path] }
6
+ after { VCR.eject_cassette }
7
+
8
+ describe "#valid?" do
9
+ it "requires a csr id" do
10
+ agent = Agent.create csr_id: nil
11
+ agent.should_not be_valid
12
+ end
13
+
14
+ it "requires a valid phone_type" do
15
+ agent = build :agent, phone_type: 'invalid'
16
+ agent.should_not be_valid
17
+ agent.should have(1).error_on(:phone_type)
18
+ end
19
+
20
+ it "requires a sip number if agent uses sip" do
21
+ agent = build :agent, phone_type: 'sip', sip_number: nil
22
+ agent.should_not be_valid
23
+ agent.should have(1).error_on(:sip_number)
24
+ end
25
+
26
+ it "requires a phone number if agent uses phone" do
27
+ agent = build :agent, phone_type: 'phone', phone_number: nil
28
+ agent.should_not be_valid
29
+ agent.should have(1).error_on(:phone_number)
30
+ end
31
+ end
32
+
33
+ describe '.new' do
34
+ it 'defaults its status to "offline"' do
35
+ agent = create :agent
36
+ agent.status.should == 'offline'
37
+ end
38
+
39
+ it 'defaults its phone_type to "phone"' do
40
+ agent = build :agent
41
+ agent.phone_type.should == Agent::PhoneType::PHONE
42
+ end
43
+ end
44
+
45
+ describe ".sort_by_status" do
46
+ it "orders by agents by status" do
47
+ agent1 = create :available_agent
48
+ agent2 = create :offline_agent
49
+ agent3 = create :not_available_agent
50
+ agent4 = create :on_a_call_agent
51
+ agents = Agent.sort_by_status [agent1, agent2, agent3, agent4]
52
+
53
+ agents.map(&:id).should == [agent1.id, agent4.id, agent3.id, agent2.id]
54
+ end
55
+ end
56
+
57
+ describe ".all_transferable_for_csr_id" do
58
+ context "given transferable agents" do
59
+ before do
60
+ @agent = create :agent,
61
+ csr_id: 123,
62
+ transferable_agents: [11, 12]
63
+ end
64
+
65
+ it "returns transferable agents sorted by status" do
66
+ agent1 = create :available_agent, csr_id: 12
67
+ agent2 = create :offline_agent, csr_id: 11
68
+ create :not_available_agent, csr_id: 13
69
+ create :on_a_call_agent, csr_id: 14
70
+ agents = Agent.all_transferable_for_csr_id 123
71
+
72
+ agents.map(&:id).should == [agent1.id, agent2.id]
73
+ end
74
+ end
75
+
76
+ context "given no transferable agents" do
77
+ before do
78
+ @agent = create :agent,
79
+ csr_id: 123,
80
+ transferable_agents: []
81
+ end
82
+
83
+ it "returns all agents sorted by status" do
84
+ agent1 = create :available_agent, csr_id: 12
85
+ agent2 = create :offline_agent, csr_id: 11
86
+ agent3 = create :not_available_agent, csr_id: 13
87
+ agent4 = create :on_a_call_agent, csr_id: 14
88
+ agents = Agent.all_transferable_for_csr_id 123
89
+
90
+ agents.map(&:id).should == [agent1.id, agent4.id, agent3.id, agent2.id, @agent.id]
91
+ end
92
+ end
93
+
94
+ context "given no valid csr id" do
95
+ before do
96
+ @agent = create :agent,
97
+ csr_id: 123,
98
+ transferable_agents: []
99
+ end
100
+
101
+ it "returns all agents sorted by status" do
102
+ agent1 = create :available_agent, csr_id: 12
103
+ agent2 = create :offline_agent, csr_id: 11
104
+ agent3 = create :not_available_agent, csr_id: 13
105
+ agent4 = create :on_a_call_agent, csr_id: 14
106
+ agents = Agent.all_transferable_for_csr_id ''
107
+
108
+ agents.map(&:id).should == [agent1.id, agent4.id, agent3.id, agent2.id, @agent.id]
109
+ end
110
+ end
111
+ end
112
+
113
+ describe '.update_or_create_by_widget_data' do
114
+ context "given an existing agent" do
115
+ before do
116
+ @existing_agent = create :on_a_call_agent, name: nil, phone_ext: nil
117
+ end
118
+
119
+ it 'finds the agent' do
120
+ data = { csr_id: @existing_agent.csr_id }
121
+ agent = Agent.update_or_create_by_widget_data data
122
+
123
+ agent.should == @existing_agent
124
+ end
125
+
126
+ it "updates agent's attributes" do
127
+ data = {
128
+ csr_id: @existing_agent.csr_id,
129
+ csr_type: "A",
130
+ csr_generate_caller_id: "true",
131
+ csr_name: "csr_name",
132
+ csr_phone_number: "555-555-1234",
133
+ csr_phone_ext: "csr_phone_ext",
134
+ csr_sip_number: "432",
135
+ csr_call_center_name: "other_location",
136
+ csr_phone_type: Agent::PhoneType::SIP,
137
+ csr_transferable_agents: [1, 2].to_json
138
+ }
139
+ Agent.update_or_create_by_widget_data data
140
+ @existing_agent.reload
141
+
142
+ @existing_agent.csr_type.should == "A"
143
+ @existing_agent.generate_caller_id.should be_true
144
+ @existing_agent.name.should == "csr_name"
145
+ @existing_agent.phone_number.should == "555-555-1234"
146
+ @existing_agent.phone_ext.should == "csr_phone_ext"
147
+ @existing_agent.sip_number.should == "432"
148
+ @existing_agent.call_center_name.should == "other_location"
149
+ @existing_agent.phone_type.should == Agent::PhoneType::SIP
150
+ @existing_agent.transferable_agents.should == [1, 2]
151
+ end
152
+ end
153
+
154
+ context "given a new agent" do
155
+ it 'creates the agent' do
156
+ data = {
157
+ csr_id: 123,
158
+ csr_type: "A",
159
+ csr_name: 'csr_name',
160
+ csr_phone_number: "555-555-1234",
161
+ csr_phone_ext: 'csr_phone_ext'
162
+ }
163
+ agent = Agent.update_or_create_by_widget_data data
164
+
165
+ agent.csr_id.should == 123
166
+ agent.csr_type.should == "A"
167
+ agent.name.should == 'csr_name'
168
+ agent.phone_ext.should == 'csr_phone_ext'
169
+ agent.phone_number.should == '555-555-1234'
170
+ end
171
+ end
172
+ end
173
+
174
+ describe '#transferrable?' do
175
+ context 'given an available agent' do
176
+ before do
177
+ @agent = create :available_agent
178
+ end
179
+
180
+ it 'returns true' do
181
+ @agent.should be_transferrable
182
+ end
183
+ end
184
+
185
+ context 'given an unavailable agent' do
186
+ before do
187
+ @agent = create :not_available_agent
188
+ end
189
+
190
+ it 'returns true' do
191
+ @agent.should_not be_transferrable
192
+ end
193
+ end
194
+ end
195
+
196
+ describe '#process_presence_event' do
197
+ context "given a member_added event" do
198
+ before do
199
+ @agent = create type_of_agent
200
+ @timestamp = 1234
201
+ @agent.process_presence_event 'member_added', @timestamp
202
+ end
203
+
204
+ context "when the agent is offline" do
205
+ let(:type_of_agent) { :offline_agent }
206
+
207
+ it "updates the agent's status to be available" do
208
+ @agent.reload.should be_available
209
+ end
210
+ end
211
+
212
+ context "when the agent is on_a_call" do
213
+ let(:type_of_agent) { :on_a_call_agent }
214
+
215
+ it "doesn't update the status" do
216
+ @agent.reload.should be_on_a_call
217
+ end
218
+ end
219
+
220
+ context "whatever the agent's status is" do
221
+ let(:type_of_agent) { :on_a_call_agent }
222
+
223
+ it "unconditionally updates the timestamp" do
224
+ @agent.reload.timestamp_of_last_presence_event.should == @timestamp
225
+ end
226
+ end
227
+ end
228
+
229
+ context "given a member_removed event" do
230
+ let(:job) { mock(Telephony::Jobs::AgentOffline)}
231
+ let(:timestamp) { 1234 }
232
+
233
+ before do
234
+ @agent = create :available_agent
235
+ end
236
+
237
+ context "delayed job is defined" do
238
+ before do
239
+ Telephony::DELAYED_JOB.should_receive(:enqueue)
240
+ Telephony::Jobs::AgentOffline.stub(:new)
241
+ .with(@agent.id, timestamp).and_return { job }
242
+ end
243
+
244
+ it "defer the handling of an offline webhook" do
245
+ @agent.process_presence_event "member_removed", timestamp
246
+ end
247
+ end
248
+
249
+ context "delayed job is not defined" do
250
+ before do
251
+ Telephony::Jobs::AgentOffline.stub(:new)
252
+ .with(@agent.id, timestamp).and_return(job)
253
+ end
254
+
255
+ it "calls the job update_status directly" do
256
+ job.should_receive(:update_status)
257
+ @agent.process_presence_event "member_removed", timestamp
258
+ end
259
+ end
260
+ end
261
+ end
262
+
263
+ describe '#terminate_active_call' do
264
+ subject { Agent.new.terminate_active_call }
265
+
266
+ context "given an agent that's on a call" do
267
+ let(:active_call) { double terminate!: :terminated }
268
+ before { Agent.any_instance.should_receive(:active_call)
269
+ .twice
270
+ .and_return active_call }
271
+ it { should == :terminated }
272
+ end
273
+
274
+ context "given an agent that's not on a call" do
275
+ let(:active_call) { nil }
276
+ before { Agent.any_instance.should_receive(:active_call) }
277
+ it { should == nil }
278
+ end
279
+
280
+ end
281
+
282
+ describe '#verify_status!' do
283
+ context "given an agent that's on a call" do
284
+ before do
285
+ @agent = create :on_a_call_agent
286
+ end
287
+
288
+ context 'and the call has ended locally' do
289
+ before do
290
+ create :terminated_call,
291
+ agent: @agent
292
+
293
+ @agent.verify_status!
294
+ end
295
+
296
+ it 'sets itself to not available' do
297
+ @agent.reload
298
+ @agent.should be_not_available
299
+ end
300
+ end
301
+
302
+ context 'and the call has ended remotely but not locally' do
303
+ before do
304
+ @call = create :in_progress_call,
305
+ agent: @agent,
306
+ created_at: call_created_at
307
+
308
+ provider = double 'provider'
309
+ provider
310
+ .stub(:call_ended?)
311
+ .with(@call.sid)
312
+ .and_return(true)
313
+
314
+ Telephony
315
+ .stub(:provider)
316
+ .and_return(provider)
317
+
318
+ @agent.verify_status!
319
+ end
320
+
321
+ context 'and the call is over 5 minutes old' do
322
+ let(:call_created_at) { 6.minutes.ago }
323
+
324
+ it 'terminates the call' do
325
+ @call.reload
326
+ @call.should be_terminated
327
+ end
328
+ end
329
+
330
+ context 'and the call is less than 5 minutes old' do
331
+ let(:call_created_at) { 4.minutes.ago }
332
+
333
+ it 'does not the call' do
334
+ @call.reload
335
+ @call.should_not be_terminated
336
+ end
337
+ end
338
+ end
339
+
340
+ context 'and the call has not ended remotely' do
341
+ before do
342
+ provider = double 'provider'
343
+ provider
344
+ .stub(:call_ended?)
345
+ .and_return(false)
346
+
347
+ Telephony
348
+ .stub(:provider)
349
+ .and_return(provider)
350
+
351
+ @call = create :in_progress_call,
352
+ agent: @agent
353
+
354
+ @agent.verify_status!
355
+ end
356
+
357
+ it 'does not try to terminate the call' do
358
+ @call.reload
359
+ @call.should_not be_terminated
360
+ end
361
+ end
362
+ end
363
+
364
+ context "given an agent that's not on a call" do
365
+ before do
366
+ provider = double 'provider'
367
+ provider.should_not_receive(:call_ended?)
368
+
369
+ Telephony
370
+ .stub(:provider)
371
+ .and_return(provider)
372
+
373
+ @agent = create :offline_agent
374
+ end
375
+
376
+ it 'does not try to verify a call status' do
377
+ @agent.verify_status!
378
+ end
379
+ end
380
+ end
381
+ end
382
+
383
+ describe "#timestamp_of_last_presence_event" do
384
+ it "defaults to zero" do
385
+ agent = create :agent
386
+ agent.timestamp_of_last_presence_event.should == 0
387
+ end
388
+
389
+ it "can store big integer" do
390
+ agent = create :agent, :timestamp_of_last_presence_event => 9223372036854775807
391
+ agent.reload
392
+ agent.timestamp_of_last_presence_event.should == 9223372036854775807
393
+ end
394
+ end
395
+
396
+ describe '#publish_status_change' do
397
+ before do
398
+ @agent = create :available_agent
399
+ end
400
+
401
+ it 'asks the event publisher to publish its new status' do
402
+ Timecop.freeze do
403
+ PusherEventPublisher
404
+ .should_receive(:publish)
405
+ .with(channel: "csrs-#{@agent.csr_id}",
406
+ name: 'statusChange',
407
+ data: {
408
+ status: @agent.status,
409
+ timestamp: Integer(Time.now.to_f * 1000)
410
+ })
411
+
412
+ @agent.publish_status_change
413
+ end
414
+ end
415
+ end
416
+
417
+ describe "#number" do
418
+ before do
419
+ @agent = build :agent,
420
+ sip_number: '123',
421
+ call_center_name: 'other_location',
422
+ phone_number: '3213214321'
423
+ end
424
+ subject { @agent.number @with_protocol }
425
+
426
+ context "when phone_type is 'sip'" do
427
+ before { @agent.phone_type = Agent::PhoneType::SIP }
428
+
429
+ context "by default" do
430
+ it { should == "123@192.168.1.2" }
431
+ end
432
+
433
+ context "called with true" do
434
+ before { @with_protocol = true }
435
+ it { should == "sip:123@192.168.1.2" }
436
+ end
437
+ end
438
+
439
+ context "when phone_type is 'twilio_client'" do
440
+ before { @agent.phone_type = Agent::PhoneType::TWILIO_CLIENT }
441
+
442
+ context "by default" do
443
+ it { should == "agent#{@agent.csr_id}" }
444
+ end
445
+
446
+ context "called with true" do
447
+ before { @with_protocol = true }
448
+ it { should == "client:agent#{@agent.csr_id}"}
449
+ end
450
+ end
451
+
452
+ context "when phone_type is 'phone'" do
453
+ before { @agent.phone_type = Agent::PhoneType::PHONE }
454
+ it { should == @agent.phone_number }
455
+ end
456
+ end
457
+
458
+ describe "#uses_phone_type?" do
459
+ Agent::PhoneType::ALL.each do |type|
460
+ it "defines question mark method for #{type} phone type" do
461
+ agent = build :agent, phone_type: type
462
+ agent.should(send "be_uses_#{type}".to_sym)
463
+ end
464
+ end
465
+ end
466
+
467
+ describe "#encode_with" do
468
+ context "when serializing into a string with limited length" do
469
+ it "overrides ActiveRecord::Base#encode_with with selected attributes" do
470
+ agent = create :agent
471
+
472
+ deserialized_agent = YAML.load agent.to_yaml
473
+ deserialized_agent.attributes.keys.should == %w(id csr_id)
474
+ deserialized_agent.id.should == agent.id
475
+ deserialized_agent.csr_id.should == agent.csr_id
476
+ end
477
+ end
478
+ end
479
+ end