slack-ruby-client 0.7.9 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. checksums.yaml +5 -5
  2. data/.github/FUNDING.yml +1 -0
  3. data/.gitignore +2 -0
  4. data/.rubocop.yml +32 -1
  5. data/.rubocop_todo.yml +98 -49
  6. data/.travis.yml +10 -14
  7. data/CHANGELOG.md +172 -24
  8. data/CONTRIBUTING.md +17 -6
  9. data/Dangerfile +2 -0
  10. data/Gemfile +10 -4
  11. data/LICENSE.md +1 -1
  12. data/README.md +276 -54
  13. data/RELEASING.md +19 -11
  14. data/Rakefile +2 -1
  15. data/UPGRADING.md +84 -2
  16. data/bin/commands.rb +43 -1
  17. data/bin/commands/admin_analytics.rb +15 -0
  18. data/bin/commands/admin_apps.rb +40 -0
  19. data/bin/commands/admin_apps_approved.rb +17 -0
  20. data/bin/commands/admin_apps_requests.rb +16 -0
  21. data/bin/commands/admin_apps_restricted.rb +17 -0
  22. data/bin/commands/admin_barriers.rb +47 -0
  23. data/bin/commands/admin_conversations.rb +169 -0
  24. data/bin/commands/admin_conversations_ekm.rb +17 -0
  25. data/bin/commands/admin_conversations_restrictAccess.rb +37 -0
  26. data/bin/commands/admin_conversations_whitelist.rb +37 -0
  27. data/bin/commands/admin_emoji.rb +54 -0
  28. data/bin/commands/admin_inviteRequests.rb +36 -0
  29. data/bin/commands/admin_inviteRequests_approved.rb +16 -0
  30. data/bin/commands/admin_inviteRequests_denied.rb +16 -0
  31. data/bin/commands/admin_teams.rb +27 -0
  32. data/bin/commands/admin_teams_admins.rb +16 -0
  33. data/bin/commands/admin_teams_owners.rb +16 -0
  34. data/bin/commands/admin_teams_settings.rb +64 -0
  35. data/bin/commands/admin_usergroups.rb +48 -0
  36. data/bin/commands/admin_users.rb +97 -0
  37. data/bin/commands/admin_users_session.rb +38 -0
  38. data/bin/commands/api.rb +3 -3
  39. data/bin/commands/apps.rb +15 -0
  40. data/bin/commands/apps_connections.rb +13 -0
  41. data/bin/commands/apps_event_authorizations.rb +16 -0
  42. data/bin/commands/apps_permissions.rb +23 -0
  43. data/bin/commands/apps_permissions_resources.rb +15 -0
  44. data/bin/commands/apps_permissions_scopes.rb +13 -0
  45. data/bin/commands/apps_permissions_users.rb +26 -0
  46. data/bin/commands/auth.rb +5 -4
  47. data/bin/commands/auth_teams.rb +16 -0
  48. data/bin/commands/bots.rb +4 -2
  49. data/bin/commands/calls.rb +52 -0
  50. data/bin/commands/calls_participants.rb +25 -0
  51. data/bin/commands/channels.rb +64 -43
  52. data/bin/commands/chat.rb +114 -24
  53. data/bin/commands/chat_scheduledMessages.rb +19 -0
  54. data/bin/commands/conversations.rb +196 -0
  55. data/bin/commands/dialog.rb +15 -0
  56. data/bin/commands/dnd.rb +9 -8
  57. data/bin/commands/emoji.rb +3 -2
  58. data/bin/commands/files.rb +45 -30
  59. data/bin/commands/files_comments.rb +3 -24
  60. data/bin/commands/files_remote.rb +78 -0
  61. data/bin/commands/groups.rb +53 -53
  62. data/bin/commands/im.rb +17 -13
  63. data/bin/commands/migration.rb +16 -0
  64. data/bin/commands/mpim.rb +16 -13
  65. data/bin/commands/oauth.rb +17 -2
  66. data/bin/commands/oauth_v2.rb +17 -0
  67. data/bin/commands/pins.rb +7 -10
  68. data/bin/commands/reactions.rb +17 -15
  69. data/bin/commands/reminders.rb +11 -10
  70. data/bin/commands/rtm.rb +19 -4
  71. data/bin/commands/search.rb +15 -11
  72. data/bin/commands/stars.rb +11 -8
  73. data/bin/commands/team.rb +15 -10
  74. data/bin/commands/team_profile.rb +3 -2
  75. data/bin/commands/usergroups.rb +22 -16
  76. data/bin/commands/usergroups_users.rb +7 -4
  77. data/bin/commands/users.rb +65 -37
  78. data/bin/commands/users_admin.rb +29 -0
  79. data/bin/commands/users_prefs.rb +13 -0
  80. data/bin/commands/users_profile.rb +8 -7
  81. data/bin/commands/views.rb +48 -0
  82. data/bin/commands/workflows.rb +38 -0
  83. data/bin/slack +3 -4
  84. data/examples/hi_real_time_and_web/Gemfile +1 -0
  85. data/examples/hi_real_time_and_web/hi.rb +8 -4
  86. data/examples/{hi_real_time_async_eventmachine → hi_real_time_async_async}/Gemfile +2 -1
  87. data/examples/{hi_real_time_async_celluloid → hi_real_time_async_async}/Procfile +0 -0
  88. data/examples/{hi_real_time_async_celluloid → hi_real_time_async_async}/hi.rb +13 -8
  89. data/examples/hi_web/Gemfile +1 -0
  90. data/examples/hi_web/hi.rb +2 -1
  91. data/examples/new_ticket/Gemfile +1 -0
  92. data/examples/new_ticket/new_ticket.rb +2 -1
  93. data/lib/slack-ruby-client.rb +40 -26
  94. data/lib/slack.rb +1 -0
  95. data/lib/slack/config.rb +1 -0
  96. data/lib/slack/events/config.rb +32 -0
  97. data/lib/slack/events/request.rb +70 -0
  98. data/lib/slack/logger.rb +6 -5
  99. data/lib/slack/messages/formatting.rb +4 -4
  100. data/lib/slack/messages/message.rb +2 -6
  101. data/lib/slack/real_time/api/message.rb +3 -1
  102. data/lib/slack/real_time/api/message_id.rb +1 -0
  103. data/lib/slack/real_time/api/ping.rb +5 -2
  104. data/lib/slack/real_time/api/templates/event_handler.erb +1 -1
  105. data/lib/slack/real_time/api/typing.rb +3 -1
  106. data/lib/slack/real_time/client.rb +113 -32
  107. data/lib/slack/real_time/concurrency.rb +2 -2
  108. data/lib/slack/real_time/concurrency/async.rb +140 -0
  109. data/lib/slack/real_time/config.rb +20 -12
  110. data/lib/slack/real_time/models.rb +8 -7
  111. data/lib/slack/real_time/models/base.rb +2 -6
  112. data/lib/slack/real_time/models/bot.rb +1 -0
  113. data/lib/slack/real_time/models/channel.rb +1 -0
  114. data/lib/slack/real_time/models/group.rb +1 -0
  115. data/lib/slack/real_time/models/im.rb +1 -0
  116. data/lib/slack/real_time/models/team.rb +1 -0
  117. data/lib/slack/real_time/models/user.rb +1 -0
  118. data/lib/slack/real_time/socket.rb +46 -17
  119. data/lib/slack/real_time/stores.rb +4 -3
  120. data/lib/slack/real_time/stores/base.rb +5 -3
  121. data/lib/slack/real_time/stores/starter.rb +113 -72
  122. data/lib/slack/real_time/stores/store.rb +131 -88
  123. data/lib/slack/version.rb +2 -1
  124. data/lib/slack/web/api/endpoints.rb +110 -26
  125. data/lib/slack/web/api/endpoints/admin_analytics.rb +26 -0
  126. data/lib/slack/web/api/endpoints/admin_apps.rb +62 -0
  127. data/lib/slack/web/api/endpoints/admin_apps_approved.rb +35 -0
  128. data/lib/slack/web/api/endpoints/admin_apps_requests.rb +33 -0
  129. data/lib/slack/web/api/endpoints/admin_apps_restricted.rb +35 -0
  130. data/lib/slack/web/api/endpoints/admin_barriers.rb +82 -0
  131. data/lib/slack/web/api/endpoints/admin_conversations.rb +260 -0
  132. data/lib/slack/web/api/endpoints/admin_conversations_ekm.rb +35 -0
  133. data/lib/slack/web/api/endpoints/admin_conversations_restrictAccess.rb +61 -0
  134. data/lib/slack/web/api/endpoints/admin_conversations_whitelist.rb +64 -0
  135. data/lib/slack/web/api/endpoints/admin_emoji.rb +88 -0
  136. data/lib/slack/web/api/endpoints/admin_inviteRequests.rb +61 -0
  137. data/lib/slack/web/api/endpoints/admin_inviteRequests_approved.rb +33 -0
  138. data/lib/slack/web/api/endpoints/admin_inviteRequests_denied.rb +33 -0
  139. data/lib/slack/web/api/endpoints/admin_teams.rb +50 -0
  140. data/lib/slack/web/api/endpoints/admin_teams_admins.rb +34 -0
  141. data/lib/slack/web/api/endpoints/admin_teams_owners.rb +34 -0
  142. data/lib/slack/web/api/endpoints/admin_teams_settings.rb +99 -0
  143. data/lib/slack/web/api/endpoints/admin_usergroups.rb +77 -0
  144. data/lib/slack/web/api/endpoints/admin_users.rb +161 -0
  145. data/lib/slack/web/api/endpoints/admin_users_session.rb +66 -0
  146. data/lib/slack/web/api/endpoints/api.rb +3 -4
  147. data/lib/slack/web/api/endpoints/apps.rb +27 -0
  148. data/lib/slack/web/api/endpoints/apps_connections.rb +21 -0
  149. data/lib/slack/web/api/endpoints/apps_event_authorizations.rb +34 -0
  150. data/lib/slack/web/api/endpoints/apps_permissions.rb +36 -0
  151. data/lib/slack/web/api/endpoints/apps_permissions_resources.rb +31 -0
  152. data/lib/slack/web/api/endpoints/apps_permissions_scopes.rb +21 -0
  153. data/lib/slack/web/api/endpoints/apps_permissions_users.rb +50 -0
  154. data/lib/slack/web/api/endpoints/auth.rb +5 -4
  155. data/lib/slack/web/api/endpoints/auth_teams.rb +33 -0
  156. data/lib/slack/web/api/endpoints/bots.rb +5 -2
  157. data/lib/slack/web/api/endpoints/calls.rb +83 -0
  158. data/lib/slack/web/api/endpoints/calls_participants.rb +42 -0
  159. data/lib/slack/web/api/endpoints/channels.rb +105 -49
  160. data/lib/slack/web/api/endpoints/chat.rb +221 -40
  161. data/lib/slack/web/api/endpoints/chat_scheduledMessages.rb +40 -0
  162. data/lib/slack/web/api/endpoints/conversations.rb +332 -0
  163. data/lib/slack/web/api/endpoints/dialog.rb +33 -0
  164. data/lib/slack/web/api/endpoints/dnd.rb +11 -9
  165. data/lib/slack/web/api/endpoints/emoji.rb +3 -2
  166. data/lib/slack/web/api/endpoints/files.rb +75 -38
  167. data/lib/slack/web/api/endpoints/files_comments.rb +3 -38
  168. data/lib/slack/web/api/endpoints/files_remote.rb +127 -0
  169. data/lib/slack/web/api/endpoints/groups.rb +76 -53
  170. data/lib/slack/web/api/endpoints/im.rb +38 -21
  171. data/lib/slack/web/api/endpoints/migration.rb +28 -0
  172. data/lib/slack/web/api/endpoints/mpim.rb +37 -22
  173. data/lib/slack/web/api/endpoints/oauth.rb +25 -4
  174. data/lib/slack/web/api/endpoints/oauth_v2.rb +30 -0
  175. data/lib/slack/web/api/endpoints/pins.rb +10 -19
  176. data/lib/slack/web/api/endpoints/presence.rb +1 -1
  177. data/lib/slack/web/api/endpoints/reactions.rb +37 -28
  178. data/lib/slack/web/api/endpoints/reminders.rb +11 -10
  179. data/lib/slack/web/api/endpoints/rtm.rb +28 -7
  180. data/lib/slack/web/api/endpoints/search.rb +21 -14
  181. data/lib/slack/web/api/endpoints/stars.rb +24 -15
  182. data/lib/slack/web/api/endpoints/team.rb +21 -13
  183. data/lib/slack/web/api/endpoints/team_profile.rb +3 -2
  184. data/lib/slack/web/api/endpoints/usergroups.rb +33 -22
  185. data/lib/slack/web/api/endpoints/usergroups_users.rb +9 -4
  186. data/lib/slack/web/api/endpoints/users.rb +78 -29
  187. data/lib/slack/web/api/endpoints/users_admin.rb +49 -0
  188. data/lib/slack/web/api/endpoints/users_prefs.rb +21 -0
  189. data/lib/slack/web/api/endpoints/users_profile.rb +11 -10
  190. data/lib/slack/web/api/endpoints/views.rb +97 -0
  191. data/lib/slack/web/api/endpoints/workflows.rb +61 -0
  192. data/lib/slack/web/api/error.rb +2 -8
  193. data/lib/slack/web/api/errors.rb +850 -0
  194. data/lib/slack/web/api/errors/internal_error.rb +14 -0
  195. data/lib/slack/web/api/errors/slack_error.rb +29 -0
  196. data/lib/slack/web/api/errors/too_many_requests_error.rb +24 -0
  197. data/lib/slack/web/api/mixins.rb +6 -4
  198. data/lib/slack/web/api/mixins/channels.id.rb +6 -7
  199. data/lib/slack/web/api/mixins/conversations.id.rb +25 -0
  200. data/lib/slack/web/api/mixins/groups.id.rb +6 -7
  201. data/lib/slack/web/api/mixins/ids.id.rb +24 -0
  202. data/lib/slack/web/api/mixins/users.id.rb +6 -7
  203. data/lib/slack/web/api/mixins/users.search.rb +39 -36
  204. data/lib/slack/web/api/patches/chat.1.patch +72 -0
  205. data/lib/slack/web/api/patches/dialog.1.open-json-support.patch +17 -0
  206. data/lib/slack/web/api/patches/views.1.view-json.patch +40 -0
  207. data/lib/slack/web/api/patches/views.1.views-published.patch +16 -0
  208. data/lib/slack/web/api/templates/command.erb +5 -3
  209. data/lib/slack/web/api/templates/commands.erb +2 -1
  210. data/lib/slack/web/api/templates/endpoints.erb +5 -3
  211. data/lib/slack/web/api/templates/errors.erb +20 -0
  212. data/lib/slack/web/api/templates/method.erb +26 -4
  213. data/lib/slack/web/api/templates/method_spec.erb +3 -2
  214. data/lib/slack/web/client.rb +2 -1
  215. data/lib/slack/web/config.rb +21 -10
  216. data/lib/slack/web/faraday/connection.rb +25 -16
  217. data/lib/slack/web/faraday/request.rb +2 -0
  218. data/lib/slack/web/faraday/response/raise_error.rb +23 -1
  219. data/lib/slack/web/faraday/response/wrap_error.rb +18 -0
  220. data/lib/slack/web/pagination/cursor.rb +52 -0
  221. data/lib/slack_ruby_client.rb +1 -0
  222. data/lib/tasks/git.rake +2 -1
  223. data/lib/tasks/real_time.rake +16 -6
  224. data/lib/tasks/update.rake +1 -0
  225. data/lib/tasks/web.rake +38 -10
  226. data/screenshots/create-app.png +0 -0
  227. data/slack-ruby-client.gemspec +9 -6
  228. data/spec/fixtures/slack/web/429_error.yml +2 -0
  229. data/spec/fixtures/slack/web/503_error.yml +14 -0
  230. data/spec/fixtures/slack/web/channels_info.yml +108 -15
  231. data/spec/fixtures/slack/web/conversations_setTopic.yml +69 -0
  232. data/spec/fixtures/slack/web/conversations_setTopic_one_page.yml +142 -0
  233. data/spec/fixtures/slack/web/conversations_setTopic_paginated.yml +208 -0
  234. data/spec/fixtures/slack/web/paginated_users_list.yml +181 -0
  235. data/spec/fixtures/slack/web/rtm_connect.yml +70 -0
  236. data/spec/fixtures/slack/web/rtm_start.yml +1 -1
  237. data/spec/fixtures/slack/web/views_open_error.yml +76 -0
  238. data/spec/integration/integration_spec.rb +116 -48
  239. data/spec/slack/config_spec.rb +2 -0
  240. data/spec/slack/events/config_spec.rb +33 -0
  241. data/spec/slack/events/request_spec.rb +183 -0
  242. data/spec/slack/messages/formatting_spec.rb +25 -14
  243. data/spec/slack/real_time/api/message_spec.rb +6 -1
  244. data/spec/slack/real_time/api/ping_spec.rb +2 -0
  245. data/spec/slack/real_time/api/typing_spec.rb +5 -1
  246. data/spec/slack/real_time/client_spec.rb +462 -134
  247. data/spec/slack/real_time/concurrency/it_behaves_like_a_realtime_socket.rb +3 -1
  248. data/spec/slack/real_time/event_handlers/bot_spec.rb +6 -3
  249. data/spec/slack/real_time/event_handlers/channel_spec.rb +9 -6
  250. data/spec/slack/real_time/event_handlers/event_handlers_spec.rb +3 -2
  251. data/spec/slack/real_time/event_handlers/group_spec.rb +5 -4
  252. data/spec/slack/real_time/event_handlers/im_spec.rb +4 -3
  253. data/spec/slack/real_time/event_handlers/team_spec.rb +8 -4
  254. data/spec/slack/real_time/event_handlers/user_spec.rb +5 -2
  255. data/spec/slack/real_time/rtm_connect_spec.rb +14 -0
  256. data/spec/slack/real_time/rtm_start_spec.rb +1 -0
  257. data/spec/slack/real_time/store_spec.rb +2 -1
  258. data/spec/slack/slack_spec.rb +39 -7
  259. data/spec/slack/version_spec.rb +2 -1
  260. data/spec/slack/web/api/endpoints/admin_analytics_spec.rb +13 -0
  261. data/spec/slack/web/api/endpoints/admin_apps_approved_spec.rb +8 -0
  262. data/spec/slack/web/api/endpoints/admin_apps_requests_spec.rb +8 -0
  263. data/spec/slack/web/api/endpoints/admin_apps_restricted_spec.rb +8 -0
  264. data/spec/slack/web/api/endpoints/admin_apps_spec.rb +13 -0
  265. data/spec/slack/web/api/endpoints/admin_barriers_spec.rb +38 -0
  266. data/spec/slack/web/api/endpoints/admin_conversations_ekm_spec.rb +8 -0
  267. data/spec/slack/web/api/endpoints/admin_conversations_restrictAccess_spec.rb +32 -0
  268. data/spec/slack/web/api/endpoints/admin_conversations_spec.rb +98 -0
  269. data/spec/slack/web/api/endpoints/admin_conversations_whitelist_spec.rb +32 -0
  270. data/spec/slack/web/api/endpoints/admin_emoji_spec.rb +37 -0
  271. data/spec/slack/web/api/endpoints/admin_inviteRequests_approved_spec.rb +8 -0
  272. data/spec/slack/web/api/endpoints/admin_inviteRequests_denied_spec.rb +8 -0
  273. data/spec/slack/web/api/endpoints/admin_inviteRequests_spec.rb +18 -0
  274. data/spec/slack/web/api/endpoints/admin_teams_admins_spec.rb +13 -0
  275. data/spec/slack/web/api/endpoints/admin_teams_owners_spec.rb +13 -0
  276. data/spec/slack/web/api/endpoints/admin_teams_settings_spec.rb +53 -0
  277. data/spec/slack/web/api/endpoints/admin_teams_spec.rb +16 -0
  278. data/spec/slack/web/api/endpoints/admin_usergroups_spec.rb +37 -0
  279. data/spec/slack/web/api/endpoints/admin_users_session_spec.rb +21 -0
  280. data/spec/slack/web/api/endpoints/admin_users_spec.rb +67 -0
  281. data/spec/slack/web/api/endpoints/api_spec.rb +1 -0
  282. data/spec/slack/web/api/endpoints/apps_connections_spec.rb +8 -0
  283. data/spec/slack/web/api/endpoints/apps_event_authorizations_spec.rb +13 -0
  284. data/spec/slack/web/api/endpoints/apps_permissions_resources_spec.rb +8 -0
  285. data/spec/slack/web/api/endpoints/apps_permissions_scopes_spec.rb +8 -0
  286. data/spec/slack/web/api/endpoints/apps_permissions_spec.rb +16 -0
  287. data/spec/slack/web/api/endpoints/apps_permissions_users_spec.rb +19 -0
  288. data/spec/slack/web/api/endpoints/apps_spec.rb +16 -0
  289. data/spec/slack/web/api/endpoints/auth_teams_spec.rb +8 -0
  290. data/spec/slack/web/api/endpoints/bots_spec.rb +1 -0
  291. data/spec/slack/web/api/endpoints/calls_participants_spec.rb +24 -0
  292. data/spec/slack/web/api/endpoints/calls_spec.rb +31 -0
  293. data/spec/slack/web/api/endpoints/chat_scheduledMessages_spec.rb +8 -0
  294. data/spec/slack/web/api/endpoints/conversations_spec.rb +109 -0
  295. data/spec/slack/web/api/endpoints/custom_specs/auth_spec.rb +13 -4
  296. data/spec/slack/web/api/endpoints/custom_specs/channels_spec.rb +5 -3
  297. data/spec/slack/web/api/endpoints/custom_specs/chat_spec.rb +140 -24
  298. data/spec/slack/web/api/endpoints/custom_specs/dialog_spec.rb +36 -0
  299. data/spec/slack/web/api/endpoints/custom_specs/groups_spec.rb +2 -0
  300. data/spec/slack/web/api/endpoints/custom_specs/users_spec.rb +21 -6
  301. data/spec/slack/web/api/endpoints/custom_specs/views_spec.rb +95 -0
  302. data/spec/slack/web/api/endpoints/dnd_spec.rb +6 -0
  303. data/spec/slack/web/api/endpoints/emoji_spec.rb +1 -0
  304. data/spec/slack/web/api/endpoints/files_comments_spec.rb +3 -21
  305. data/spec/slack/web/api/endpoints/files_remote_spec.rb +24 -0
  306. data/spec/slack/web/api/endpoints/files_spec.rb +17 -5
  307. data/spec/slack/web/api/endpoints/im_spec.rb +5 -4
  308. data/spec/slack/web/api/endpoints/migration_spec.rb +13 -0
  309. data/spec/slack/web/api/endpoints/mpim_spec.rb +5 -4
  310. data/spec/slack/web/api/endpoints/oauth_spec.rb +5 -4
  311. data/spec/slack/web/api/endpoints/oauth_v2_spec.rb +13 -0
  312. data/spec/slack/web/api/endpoints/pins_spec.rb +1 -0
  313. data/spec/slack/web/api/endpoints/reactions_spec.rb +8 -1
  314. data/spec/slack/web/api/endpoints/reminders_spec.rb +3 -2
  315. data/spec/slack/web/api/endpoints/rtm_spec.rb +1 -0
  316. data/spec/slack/web/api/endpoints/search_spec.rb +1 -0
  317. data/spec/slack/web/api/endpoints/stars_spec.rb +1 -0
  318. data/spec/slack/web/api/endpoints/team_profile_spec.rb +1 -0
  319. data/spec/slack/web/api/endpoints/team_spec.rb +1 -0
  320. data/spec/slack/web/api/endpoints/usergroups_spec.rb +1 -0
  321. data/spec/slack/web/api/endpoints/usergroups_users_spec.rb +3 -2
  322. data/spec/slack/web/api/endpoints/users_admin_spec.rb +18 -0
  323. data/spec/slack/web/api/endpoints/users_prefs_spec.rb +8 -0
  324. data/spec/slack/web/api/endpoints/users_profile_spec.rb +1 -0
  325. data/spec/slack/web/api/endpoints/views_spec.rb +29 -0
  326. data/spec/slack/web/api/endpoints/workflows_spec.rb +26 -0
  327. data/spec/slack/web/api/error_spec.rb +5 -3
  328. data/spec/slack/web/api/errors/slack_error_spec.rb +38 -0
  329. data/spec/slack/web/api/mixins/channels_spec.rb +24 -12
  330. data/spec/slack/web/api/mixins/conversations_list_spec.rb +21 -0
  331. data/spec/slack/web/api/mixins/conversations_spec.rb +43 -0
  332. data/spec/slack/web/api/mixins/groups_spec.rb +24 -12
  333. data/spec/slack/web/api/mixins/users_spec.rb +30 -17
  334. data/spec/slack/web/api/pagination/cursor_spec.rb +100 -0
  335. data/spec/slack/web/client_spec.rb +215 -14
  336. data/spec/slack/web/faraday/response/raise_error_spec.rb +85 -0
  337. data/spec/spec_helper.rb +8 -1
  338. data/spec/support/queue_with_timeout.rb +6 -5
  339. data/spec/support/real_time/concurrency/mock.rb +2 -2
  340. data/spec/support/real_time/connected_client.rb +13 -2
  341. data/spec/support/real_time/event.rb +1 -0
  342. data/spec/support/token.rb +1 -0
  343. data/spec/support/vcr.rb +6 -1
  344. metadata +280 -55
  345. data/examples/hi_real_time/Gemfile +0 -5
  346. data/examples/hi_real_time/hi.gif +0 -0
  347. data/examples/hi_real_time/hi.rb +0 -37
  348. data/examples/hi_real_time_async_celluloid/Gemfile +0 -6
  349. data/examples/hi_real_time_async_eventmachine/Procfile +0 -2
  350. data/examples/hi_real_time_async_eventmachine/hi.rb +0 -36
  351. data/lib/slack/real_time/concurrency/celluloid.rb +0 -113
  352. data/lib/slack/real_time/concurrency/eventmachine.rb +0 -60
  353. data/lib/slack/web/api/patches/chat.1.text-attachments-required.patch +0 -13
  354. data/lib/slack/web/api/patches/chat.2.attachments-json.patch +0 -17
  355. data/lib/slack/web/api/patches/chat.3.update-attachments-support.patch +0 -20
  356. data/screenshots/register-bot.png +0 -0
  357. data/spec/slack/real_time/concurrency/celluloid_spec.rb +0 -31
  358. data/spec/slack/real_time/concurrency/eventmachine_spec.rb +0 -47
@@ -1,43 +1,54 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
  require 'spec_helper'
3
3
 
4
4
  describe Slack::Messages::Formatting do
5
- subject do
6
- Slack::Messages::Formatting
5
+ subject(:formatting) do
6
+ described_class
7
7
  end
8
+
8
9
  context '#unescape' do
9
10
  it 'plain text' do
10
- expect(subject.unescape('plain text')).to eq 'plain text'
11
+ expect(formatting.unescape('plain text')).to eq 'plain text'
11
12
  end
12
13
  it 'decodes an HTML-encoded message' do
13
- expect(subject.unescape('Hello &amp; &lt;world&gt;')).to eq 'Hello & <world>'
14
+ expect(formatting.unescape('Hello &amp; &lt;world&gt;')).to eq 'Hello & <world>'
14
15
  end
15
16
  it 'unescapes a user reference' do
16
- expect(subject.unescape('Hey <@U024BE7LH|bob>, did you see my file?')).to eq 'Hey @bob, did you see my file?'
17
+ expect(formatting.unescape('Hey <@U024BE7LH|bob>, did you see my file?')).to(
18
+ eq('Hey @bob, did you see my file?')
19
+ )
17
20
  end
18
21
  it 'unescapes a user reference without a name' do
19
- expect(subject.unescape('<@U02BEFY4U> ^^^')).to eq '@U02BEFY4U ^^^'
22
+ expect(formatting.unescape('<@U02BEFY4U> ^^^')).to eq '@U02BEFY4U ^^^'
20
23
  end
21
24
  it 'unescapes a URL without text' do
22
- expect(subject.unescape('This message contains a URL <http://foo.com/>')).to eq 'This message contains a URL http://foo.com/'
25
+ expect(formatting.unescape('This message contains a URL <http://foo.com/>')).to(
26
+ eq('This message contains a URL http://foo.com/')
27
+ )
23
28
  end
24
29
  it 'unescapes a URL with text' do
25
- expect(subject.unescape('So does this one: <http://www.foo.com|www.foo.com>')).to eq 'So does this one: www.foo.com'
30
+ expect(formatting.unescape('So does this one: <http://www.foo.com|www.foo.com>')).to(
31
+ eq('So does this one: www.foo.com')
32
+ )
26
33
  end
27
34
  it 'removes mailto' do
28
- expect(subject.unescape('<mailto:bob@example.com|Bob>')).to eq 'Bob'
35
+ expect(formatting.unescape('<mailto:bob@example.com|Bob>')).to eq 'Bob'
29
36
  end
30
37
  it 'unlinkifies references' do
31
- expect(subject.unescape('Hello <@U123|bob>, say hi to <!everyone> in <#C1234|general>')).to eq 'Hello @bob, say hi to @everyone in #general'
38
+ expect(
39
+ formatting.unescape('Hello <@U123|bob>, say hi to <!everyone> in <#C1234|general>')
40
+ ).to(
41
+ eq('Hello @bob, say hi to @everyone in #general')
42
+ )
32
43
  end
33
44
  it 'can handle a lone &gt;' do
34
- expect(subject.unescape('Hello <@U123|bob> &gt; file.txt')).to eq 'Hello @bob > file.txt'
45
+ expect(formatting.unescape('Hello <@U123|bob> &gt; file.txt')).to eq 'Hello @bob > file.txt'
35
46
  end
36
47
  it 'unescapes a double smart quote' do
37
- expect(subject.unescape('“hello”')).to eq '"hello"'
48
+ expect(formatting.unescape('“hello”')).to eq '"hello"'
38
49
  end
39
50
  it 'unescapes a single smart quote' do
40
- expect(subject.unescape('‘hello’')).to eq "'hello'"
51
+ expect(formatting.unescape('‘hello’')).to eq "'hello'"
41
52
  end
42
53
  end
43
54
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  RSpec.describe Slack::RealTime::Client, vcr: { cassette_name: 'web/rtm_start' } do
@@ -7,8 +8,12 @@ RSpec.describe Slack::RealTime::Client, vcr: { cassette_name: 'web/rtm_start' }
7
8
  before do
8
9
  allow(client).to receive(:next_id).and_return(42)
9
10
  end
11
+
10
12
  it 'sends message' do
11
- expect(socket).to receive(:send_data).with({ type: 'message', id: 42, text: 'hello world', channel: 'channel' }.to_json)
13
+ expect(socket).to(
14
+ receive(:send_data)
15
+ .with({ type: 'message', id: 42, text: 'hello world', channel: 'channel' }.to_json)
16
+ )
12
17
  client.message(text: 'hello world', channel: 'channel')
13
18
  end
14
19
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  RSpec.describe Slack::RealTime::Client, vcr: { cassette_name: 'web/rtm_start' } do
@@ -7,6 +8,7 @@ RSpec.describe Slack::RealTime::Client, vcr: { cassette_name: 'web/rtm_start' }
7
8
  before do
8
9
  allow(client).to receive(:next_id).and_return(42)
9
10
  end
11
+
10
12
  it 'sends message' do
11
13
  expect(socket).to receive(:send_data).with({ type: 'ping', id: 42 }.to_json)
12
14
  client.ping
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  RSpec.describe Slack::RealTime::Client, vcr: { cassette_name: 'web/rtm_start' } do
@@ -7,8 +8,11 @@ RSpec.describe Slack::RealTime::Client, vcr: { cassette_name: 'web/rtm_start' }
7
8
  before do
8
9
  allow(client).to receive(:next_id).and_return(42)
9
10
  end
11
+
10
12
  it 'sends a typing indicator' do
11
- expect(socket).to receive(:send_data).with({ type: 'typing', id: 42, channel: 'channel' }.to_json)
13
+ expect(socket).to(
14
+ receive(:send_data).with({ type: 'typing', id: 42, channel: 'channel' }.to_json)
15
+ )
12
16
  client.typing(channel: 'channel')
13
17
  end
14
18
  end
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
- RSpec.describe Slack::RealTime::Client, vcr: { cassette_name: 'web/rtm_start' } do
4
+ RSpec.describe Slack::RealTime::Client do
4
5
  let(:ws) { double(Slack::RealTime::Concurrency::Mock::WebSocket, on: true) }
5
- let(:url) { 'wss://ms173.slack-msgs.com/websocket/lqcUiAvrKTP-uuid=' }
6
+
6
7
  before do
7
8
  @token = ENV.delete('SLACK_API_TOKEN')
8
9
  Slack::Config.reset
@@ -11,214 +12,461 @@ RSpec.describe Slack::RealTime::Client, vcr: { cassette_name: 'web/rtm_start' }
11
12
  config.concurrency = Slack::RealTime::Concurrency::Mock
12
13
  end
13
14
  end
15
+
14
16
  after do
15
17
  ENV['SLACK_API_TOKEN'] = @token if @token
16
18
  end
19
+
17
20
  context 'token' do
18
21
  before do
19
22
  Slack.configure do |config|
20
23
  config.token = 'global default'
21
24
  end
22
25
  end
26
+
23
27
  it 'defaults token to global default' do
24
- client = Slack::RealTime::Client.new
28
+ client = described_class.new
25
29
  expect(client.token).to eq 'global default'
26
30
  expect(client.web_client.token).to eq 'global default'
27
31
  end
28
32
  context 'with real time config' do
29
33
  before do
30
- Slack::RealTime::Client.configure do |config|
34
+ described_class.configure do |config|
31
35
  config.token = 'custom real time token'
32
36
  end
33
37
  end
38
+
34
39
  it 'overrides token to real time config' do
35
- client = Slack::RealTime::Client.new
40
+ client = described_class.new
36
41
  expect(client.token).to eq 'custom real time token'
37
42
  expect(client.web_client.token).to eq 'custom real time token'
38
43
  end
39
44
  it 'overrides token to specific token' do
40
- client = Slack::RealTime::Client.new(token: 'local token')
45
+ client = described_class.new(token: 'local token')
41
46
  expect(client.token).to eq 'local token'
42
47
  expect(client.web_client.token).to eq 'local token'
43
48
  end
44
49
  end
45
50
  end
46
- context 'client' do
47
- context 'started' do
48
- let(:client) { Slack::RealTime::Client.new(store_class: Slack::RealTime::Stores::Store) }
49
- describe '#start!' do
50
- let(:socket) { double(Slack::RealTime::Socket, connected?: true) }
51
- before do
52
- allow(Slack::RealTime::Socket).to receive(:new).with(url, ping: 30, logger: Slack::Logger.default).and_return(socket)
53
- allow(socket).to receive(:connect!)
54
- allow(socket).to receive(:start_sync)
55
- client.start!
51
+
52
+ context 'websocket_ping_timer' do
53
+ context 'with defaults' do
54
+ let(:client) { described_class.new }
55
+
56
+ it 'defaults to websocket_ping / 2' do
57
+ expect(client.websocket_ping_timer).to eq 15
58
+ end
59
+ end
60
+
61
+ context 'with websocket_ping value changed' do
62
+ let(:client) { described_class.new(websocket_ping: 22) }
63
+
64
+ it 'defaults to websocket_ping / 2' do
65
+ expect(client.websocket_ping_timer).to eq 11
66
+ end
67
+ end
68
+ end
69
+
70
+ context 'client with a full store',
71
+ vcr: { cassette_name: 'web/rtm_start', allow_playback_repeats: true } do
72
+ let(:client) { described_class.new(store_class: Slack::RealTime::Stores::Store) }
73
+ let(:url) { 'wss://ms173.slack-msgs.com/websocket/lqcUiAvrKTP-uuid=' }
74
+
75
+ describe '#start!' do
76
+ let(:socket) { double(Slack::RealTime::Socket, connected?: true) }
77
+
78
+ before do
79
+ allow(Slack::RealTime::Socket).to(
80
+ receive(:new).with(url, ping: 30, logger: Slack::Logger.default).and_return(socket)
81
+ )
82
+ allow(socket).to receive(:connect!)
83
+ allow(socket).to receive(:start_sync)
84
+ client.start!
85
+ end
86
+
87
+ describe 'properties provided upon connection' do
88
+ it 'sets url' do
89
+ expect(client.url).to eq url
56
90
  end
57
- context 'properties provided upon connection' do
58
- it 'sets url' do
59
- expect(client.url).to eq url
60
- end
61
- it 'sets team' do
62
- expect(client.team.domain).to eq 'dblockdotorg'
63
- end
64
- it 'sets teams' do
65
- expect(client.teams.count).to eq 1
66
- expect(client.teams.values.first).to eq client.team
67
- end
68
- it 'sets self' do
69
- expect(client.self.id).to eq 'U07518DTL'
70
- end
71
- it 'sets users' do
72
- expect(client.users.count).to eq 18
73
- expect(client.users.values.first['id']).to eq 'U07518DTL'
74
- end
75
- it 'sets channels' do
76
- expect(client.channels.count).to eq 37
77
- expect(client.channels.values.first['name']).to eq 'a1'
78
- end
79
- it 'sets ims' do
80
- expect(client.ims.count).to eq 2
81
- expect(client.ims.values.first['user']).to eq 'USLACKBOT'
82
- end
83
- it 'sets bots' do
84
- expect(client.bots.count).to eq 16
85
- expect(client.bots.values.first['name']).to eq 'bot'
86
- end
87
- it 'sets groups' do
88
- expect(client.groups.count).to eq 1
89
- end
91
+ it 'sets team' do
92
+ expect(client.team.domain).to eq 'dblockdotorg'
93
+ end
94
+ it 'sets teams' do
95
+ expect(client.teams.count).to eq 1
96
+ expect(client.teams.values.first).to eq client.team
97
+ end
98
+ it 'sets self' do
99
+ expect(client.self.id).to eq 'U07518DTL'
100
+ end
101
+ it 'sets users' do
102
+ expect(client.users.count).to eq 18
103
+ expect(client.users.values.first['id']).to eq 'U07518DTL'
104
+ end
105
+ it 'sets channels' do
106
+ expect(client.channels.count).to eq 37
107
+ expect(client.channels.values.first['name']).to eq 'a1'
90
108
  end
91
- it 'uses web client to fetch url' do
92
- expect(client.web_client).to be_a Slack::Web::Client
109
+ it 'sets ims' do
110
+ expect(client.ims.count).to eq 2
111
+ expect(client.ims.values.first['user']).to eq 'USLACKBOT'
93
112
  end
94
- it 'remembers socket' do
95
- expect(client.instance_variable_get('@socket')).to eq socket
113
+ it 'sets bots' do
114
+ expect(client.bots.count).to eq 16
115
+ expect(client.bots.values.first['name']).to eq 'bot'
96
116
  end
117
+ it 'sets groups' do
118
+ expect(client.groups.count).to eq 1
119
+ end
120
+ it 'includes team name in to_s' do
121
+ expect(client.to_s).to eq(
122
+ "id=#{client.team.id}, name=#{client.team.name}, domain=#{client.team.domain}"
123
+ )
124
+ end
125
+ end
126
+
127
+ it 'uses web client to fetch url' do
128
+ expect(client.web_client).to be_a Slack::Web::Client
129
+ end
130
+ it 'remembers socket' do
131
+ expect(client.instance_variable_get('@socket')).to eq socket
132
+ end
133
+ it 'cannot be invoked twice' do
134
+ expect do
135
+ client.start!
136
+ end.to raise_error Slack::RealTime::Client::ClientAlreadyStartedError
137
+ end
138
+ describe '#stop!' do
139
+ before do
140
+ allow(socket).to receive(:disconnect!)
141
+ client.stop!
142
+ end
143
+
97
144
  it 'cannot be invoked twice' do
145
+ client.instance_variable_set('@socket', nil) # caused by a :close callback
98
146
  expect do
99
- client.start!
100
- end.to raise_error Slack::RealTime::Client::ClientAlreadyStartedError
101
- end
102
- describe '#stop!' do
103
- before do
104
- expect(socket).to receive(:disconnect!)
105
147
  client.stop!
106
- end
107
- it 'cannot be invoked twice' do
108
- client.instance_variable_set('@socket', nil) # caused by a :close callback
109
- expect do
110
- client.stop!
111
- end.to raise_error Slack::RealTime::Client::ClientNotStartedError
112
- end
148
+ end.to raise_error Slack::RealTime::Client::ClientNotStartedError
113
149
  end
114
- describe '#next_id' do
115
- it 'increments' do
116
- previous_id = client.send(:next_id)
117
- expect(client.send(:next_id)).to eq previous_id + 1
118
- end
150
+ end
151
+
152
+ describe '#next_id' do
153
+ it 'increments' do
154
+ previous_id = client.send(:next_id)
155
+ expect(client.send(:next_id)).to eq previous_id + 1
156
+ end
157
+ end
158
+
159
+ context 'subclassed' do
160
+ it 'runs event handlers' do
161
+ event = Slack::RealTime::Event.new(
162
+ 'type' => 'team_rename',
163
+ 'name' => 'New Team Name Inc.'
164
+ )
165
+ client.send(:dispatch, event)
166
+ expect(client.store.team.name).to eq 'New Team Name Inc.'
119
167
  end
120
- context 'store_class: nil' do
121
- let(:client) { Slack::RealTime::Client.new(store_class: nil) }
122
- it 'sets store to nil' do
123
- expect(client.store).to be nil
168
+ end
169
+
170
+ describe '#run_handlers' do
171
+ describe 'empty events' do
172
+ before do
173
+ @e = client.store.class.events
174
+ client.store.class.events = nil
124
175
  end
125
- it "doesn't handle events" do
126
- event = Slack::RealTime::Event.new(
127
- 'type' => 'team_rename',
128
- 'name' => 'New Team Name Inc.'
129
- )
130
- expect(client).to_not receive(:run_handlers)
131
- client.send(:dispatch, event)
176
+
177
+ after do
178
+ client.store.class.events = @e
132
179
  end
133
- it 'self' do
134
- expect(client.self).to be nil
180
+
181
+ it 'returns false when event is nil' do
182
+ expect(client.send(:run_handlers, 'example', {})).to be nil
135
183
  end
136
- it 'team' do
137
- expect(client.team).to be nil
184
+ end
185
+ end
186
+ end
187
+
188
+ describe '#start_async' do
189
+ let(:socket) { double(Slack::RealTime::Socket, connected?: true) }
190
+
191
+ before do
192
+ allow(Slack::RealTime::Socket).to(
193
+ receive(:new).with(url, ping: 30, logger: Slack::Logger.default).and_return(socket)
194
+ )
195
+ allow(socket).to receive(:connect!)
196
+ allow(socket).to receive(:start_async)
197
+ client.start_async
198
+ end
199
+
200
+ describe '#run_ping!' do
201
+ it 'sends ping messages when the websocket connection is idle' do
202
+ allow(socket).to receive(:time_since_last_message).and_return(30)
203
+ expect(socket).to receive(:send_data).with('{"type":"ping","id":1}')
204
+ client.run_ping!
205
+ end
206
+ it 'reconnects the websocket if it has been idle for too long' do
207
+ allow(socket).to receive(:time_since_last_message).and_return(75)
208
+ allow(socket).to receive(:connected?).and_return(true)
209
+ expect(socket).to receive(:close)
210
+ expect(socket).to receive(:restart_async)
211
+ client.run_ping!
212
+ end
213
+ [
214
+ EOFError,
215
+ Errno::ECONNRESET,
216
+ Errno::EPIPE,
217
+ Faraday::ClientError,
218
+ Slack::Web::Api::Errors::SlackError
219
+ ].each do |err|
220
+ context "raising #{err}" do
221
+ it 'does not terminate the ping worker' do
222
+ allow(socket).to receive(:time_since_last_message) { raise err }
223
+ expect(socket).not_to receive(:send_data)
224
+ client.run_ping!
225
+ end
138
226
  end
139
227
  end
140
- context 'subclassed' do
141
- let(:client) { Class.new(Slack::RealTime::Client).new(store_class: Slack::RealTime::Stores::Store) }
142
- it 'runs event handlers' do
143
- event = Slack::RealTime::Event.new(
144
- 'type' => 'team_rename',
145
- 'name' => 'New Team Name Inc.'
146
- )
147
- client.send(:dispatch, event)
148
- expect(client.store.team.name).to eq 'New Team Name Inc.'
228
+ context 'raising Slack::Web::Api::Errors::SlackError' do
229
+ %w[invalid_auth account_inactive].each do |code|
230
+ context code do
231
+ it 'does not terminate the ping worker' do
232
+ allow(socket).to receive(:time_since_last_message) {
233
+ raise Slack::Web::Api::Errors::SlackError, code
234
+ }
235
+ expect(socket).not_to receive(:send_data)
236
+ expect do
237
+ client.run_ping!
238
+ end.to raise_error Slack::Web::Api::Errors::SlackError, code
239
+ end
240
+ end
149
241
  end
150
242
  end
151
243
  end
152
244
  end
153
- context 'with defaults' do
154
- let(:client) { Slack::RealTime::Client.new }
155
- describe '#initialize' do
156
- it 'sets ping' do
157
- expect(client.websocket_ping).to eq 30
245
+
246
+ describe 'to_s' do
247
+ it 'defaults to class instance' do
248
+ expect(client.to_s).to match(/^#<Slack::RealTime::Client:0x\h+>$/)
249
+ end
250
+ end
251
+ end
252
+
253
+ context 'client with starter store', vcr: { cassette_name: 'web/rtm_connect' } do
254
+ let(:client) { described_class.new(store_class: Slack::RealTime::Stores::Starter) }
255
+ let(:url) { 'wss://mpmulti-w5tz.slack-msgs.com/websocket/uid' }
256
+
257
+ describe '#start!' do
258
+ let(:socket) { double(Slack::RealTime::Socket, connected?: true) }
259
+
260
+ before do
261
+ allow(Slack::RealTime::Socket).to(
262
+ receive(:new).with(url, ping: 30, logger: Slack::Logger.default).and_return(socket)
263
+ )
264
+ allow(socket).to receive(:connect!)
265
+ allow(socket).to receive(:start_sync)
266
+ client.start!
267
+ end
268
+
269
+ describe 'properties provided upon connection' do
270
+ it 'sets url' do
271
+ expect(client.url).to eq url
158
272
  end
159
- it "doesn't set proxy" do
160
- expect(client.websocket_proxy).to be nil
273
+ it 'sets team' do
274
+ expect(client.team.domain).to eq 'dblockdotorg'
161
275
  end
162
- it 'defaults logger' do
163
- expect(client.send(:logger)).to be_a ::Logger
276
+ it 'sets self' do
277
+ expect(client.self.id).to eq 'U07518DTL'
164
278
  end
165
- it 'sets default store_class' do
166
- expect(client.send(:store_class)).to eq Slack::RealTime::Store
279
+ it 'no users' do
280
+ expect(client.users).to be_nil
167
281
  end
168
- (Slack::RealTime::Config::ATTRIBUTES - [:logger, :store_class]).each do |key|
169
- it "sets #{key}" do
170
- expect(client.send(key)).to eq Slack::RealTime::Config.send(key)
171
- end
282
+ it 'no teams' do
283
+ expect(client.teams).to be_nil
284
+ end
285
+ it 'no channels' do
286
+ expect(client.channels).to be_nil
287
+ end
288
+ it 'no ims' do
289
+ expect(client.ims).to be_nil
172
290
  end
291
+ it 'no bots' do
292
+ expect(client.bots).to be_nil
293
+ end
294
+ it 'no groups' do
295
+ expect(client.groups).to be_nil
296
+ end
297
+ it 'includes team name in to_s' do
298
+ expect(client.to_s).to eq(
299
+ "id=#{client.team.id}, name=#{client.team.name}, domain=#{client.team.domain}"
300
+ )
301
+ end
302
+ end
303
+
304
+ it 'uses web client to fetch url' do
305
+ expect(client.web_client).to be_a Slack::Web::Client
306
+ end
307
+ it 'remembers socket' do
308
+ expect(client.instance_variable_get('@socket')).to eq socket
309
+ end
310
+ it 'cannot be invoked twice' do
311
+ expect do
312
+ client.start!
313
+ end.to raise_error Slack::RealTime::Client::ClientAlreadyStartedError
314
+ end
315
+ describe '#stop!' do
316
+ before do
317
+ allow(socket).to receive(:disconnect!)
318
+ client.stop!
319
+ end
320
+
321
+ it 'cannot be invoked twice' do
322
+ client.instance_variable_set('@socket', nil) # caused by a :close callback
323
+ expect do
324
+ client.stop!
325
+ end.to raise_error Slack::RealTime::Client::ClientNotStartedError
326
+ end
327
+ end
328
+
329
+ describe '#next_id' do
330
+ it 'increments' do
331
+ previous_id = client.send(:next_id)
332
+ expect(client.send(:next_id)).to eq previous_id + 1
333
+ end
334
+ end
335
+ end
336
+ end
337
+
338
+ context 'client with nil store', vcr: { cassette_name: 'web/rtm_connect' } do
339
+ let(:client) { described_class.new(store_class: nil) }
340
+ let(:url) { 'wss://mpmulti-w5tz.slack-msgs.com/websocket/uid' }
341
+
342
+ it 'sets store to nil' do
343
+ expect(client.store).to be nil
344
+ end
345
+ it "doesn't handle events" do
346
+ event = Slack::RealTime::Event.new(
347
+ 'type' => 'team_rename',
348
+ 'name' => 'New Team Name Inc.'
349
+ )
350
+ expect(client).not_to receive(:run_handlers)
351
+ client.send(:dispatch, event)
352
+ end
353
+ it 'self' do
354
+ expect(client.self).to be nil
355
+ end
356
+ it 'team' do
357
+ expect(client.team).to be nil
358
+ end
359
+ describe 'to_s' do
360
+ it 'defaults to class instance' do
361
+ expect(client.to_s).to match(/^#<Slack::RealTime::Client:0x\h+>$/)
362
+ end
363
+ end
364
+ end
365
+
366
+ context 'client with defaults' do
367
+ let(:client) { described_class.new }
368
+
369
+ describe '#initialize' do
370
+ it 'sets ping' do
371
+ expect(client.websocket_ping).to eq 30
372
+ end
373
+ it "doesn't set proxy" do
374
+ expect(client.websocket_proxy).to be nil
375
+ end
376
+ it 'defaults logger' do
377
+ expect(client.send(:logger)).to be_a ::Logger
378
+ end
379
+ it 'sets default store_class' do
380
+ expect(client.send(:store_class)).to eq Slack::RealTime::Store
381
+ end
382
+ (Slack::RealTime::Config::ATTRIBUTES - %i[logger store_class]).each do |key|
383
+ it "sets #{key}" do
384
+ expect(client.send(key)).to eq Slack::RealTime::Config.send(key)
385
+ end
386
+ end
387
+ end
388
+
389
+ describe '#run_ping?' do
390
+ it 'returns true when websocket_ping is greater than 0' do
391
+ client.websocket_ping = 30
392
+ expect(client.run_ping?).to be true
393
+ end
394
+ it 'returns false when websocket_ping is less than 1' do
395
+ client.websocket_ping = 0
396
+ expect(client.run_ping?).to be false
397
+ client.websocket_ping = nil
398
+ expect(client.run_ping?).to be false
173
399
  end
174
400
  end
175
401
  end
402
+
176
403
  context 'with custom settings' do
177
404
  describe '#initialize' do
178
405
  Slack::RealTime::Config::ATTRIBUTES.each do |key|
179
- context key do
180
- let(:client) { Slack::RealTime::Client.new(key => 'custom') }
406
+ context key.to_s do
407
+ let(:client) { described_class.new(key => 'custom') }
408
+
181
409
  it "sets #{key}" do
182
- expect(client.send(key)).to_not eq Slack::RealTime::Config.send(key)
410
+ expect(client.send(key)).not_to eq Slack::RealTime::Config.send(key)
183
411
  expect(client.send(key)).to eq 'custom'
184
412
  end
185
413
  end
186
414
  end
187
415
  end
416
+
417
+ describe 'logger accessor' do
418
+ let(:client) { described_class.new }
419
+
420
+ it 'exposes public logger' do
421
+ expect(client.logger).to be_a(::Logger)
422
+ end
423
+ it 'exposes public logger=' do
424
+ expect { client.logger = nil }.not_to raise_error(NoMethodError)
425
+ end
426
+ end
188
427
  end
428
+
189
429
  context 'global config' do
190
430
  after do
191
- Slack::RealTime::Client.config.reset
431
+ described_class.config.reset
192
432
  end
193
- let(:client) { Slack::RealTime::Client.new }
433
+
434
+ let(:url) { 'wss://ms173.slack-msgs.com/websocket/lqcUiAvrKTP-uuid=' }
435
+ let(:client) { described_class.new }
436
+
194
437
  context 'ping' do
195
438
  before do
196
- Slack::RealTime::Client.configure do |config|
439
+ described_class.configure do |config|
197
440
  config.websocket_ping = 15
198
441
  end
199
442
  end
443
+
200
444
  describe '#initialize' do
201
445
  it 'sets ping' do
202
446
  expect(client.websocket_ping).to eq 15
203
447
  end
204
- it 'creates a connection with custom ping' do
205
- expect(Slack::RealTime::Concurrency::Mock::WebSocket).to receive(:new).with(url, nil, ping: 15).and_return(ws)
448
+ it 'creates a connection with custom ping', vcr: { cassette_name: 'web/rtm_start' } do
449
+ expect(Slack::RealTime::Concurrency::Mock::WebSocket).to(
450
+ receive(:new).with(url, nil, ping: 15).and_return(ws)
451
+ )
206
452
  client.start!
207
453
  end
208
454
  it 'sets start_options' do
209
- expect(client.start_options).to eq({})
455
+ expect(client.start_options).to eq(request: { timeout: 180 })
210
456
  end
211
457
  end
212
458
  end
459
+
213
460
  context 'proxy' do
214
461
  before do
215
- Slack::RealTime::Client.configure do |config|
462
+ described_class.configure do |config|
216
463
  config.websocket_proxy = {
217
464
  origin: 'http://username:password@proxy.example.com',
218
465
  headers: { 'User-Agent' => 'ruby' }
219
466
  }
220
467
  end
221
468
  end
469
+
222
470
  describe '#initialize' do
223
471
  it 'sets proxy' do
224
472
  expect(client.websocket_proxy).to eq(
@@ -226,7 +474,7 @@ RSpec.describe Slack::RealTime::Client, vcr: { cassette_name: 'web/rtm_start' }
226
474
  headers: { 'User-Agent' => 'ruby' }
227
475
  )
228
476
  end
229
- it 'creates a connection with custom proxy' do
477
+ it 'creates a connection with custom proxy', vcr: { cassette_name: 'web/rtm_start' } do
230
478
  expect(Slack::RealTime::Concurrency::Mock::WebSocket).to receive(:new).with(
231
479
  url,
232
480
  nil,
@@ -234,59 +482,139 @@ RSpec.describe Slack::RealTime::Client, vcr: { cassette_name: 'web/rtm_start' }
234
482
  proxy: {
235
483
  origin: 'http://username:password@proxy.example.com',
236
484
  headers: { 'User-Agent' => 'ruby' }
237
- }).and_return(ws)
485
+ }
486
+ ).and_return(ws)
238
487
  client.start!
239
488
  end
240
489
  end
241
490
  end
491
+
242
492
  context 'start_options' do
243
493
  before do
244
- Slack::RealTime::Client.configure do |config|
494
+ described_class.configure do |config|
245
495
  config.start_options = { simple_latest: true }
246
496
  end
247
497
  end
498
+
248
499
  describe '#initialize' do
249
500
  it 'sets start_options' do
250
501
  expect(client.start_options).to eq(simple_latest: true)
251
502
  end
252
503
  context 'start!' do
253
504
  let(:socket) { double(Slack::RealTime::Socket, connected?: true) }
505
+
254
506
  before do
255
507
  allow(Slack::RealTime::Socket).to receive(:new).and_return(socket)
256
508
  allow(socket).to receive(:connect!)
257
509
  allow(socket).to receive(:start_sync)
258
510
  end
259
- it 'calls rtm_start with start options' do
260
- expect(client.web_client).to receive(:rtm_start).with(simple_latest: true).and_call_original
511
+
512
+ it 'calls rtm_start with start options', vcr: { cassette_name: 'web/rtm_start' } do
513
+ expect(client.web_client).to(
514
+ receive(:rtm_start).with(simple_latest: true).and_call_original
515
+ )
261
516
  client.start!
262
517
  end
263
518
  end
264
519
  end
265
520
  end
521
+
266
522
  context 'store_class' do
267
- before do
268
- Slack::RealTime::Client.configure do |config|
269
- config.store_class = Slack::RealTime::Stores::Starter
523
+ context 'starter' do
524
+ before do
525
+ described_class.configure do |config|
526
+ config.store_class = Slack::RealTime::Stores::Starter
527
+ end
528
+ end
529
+
530
+ describe '#initialize' do
531
+ it 'can be overriden explicitly' do
532
+ client = described_class.new(store_class: Slack::RealTime::Store)
533
+ expect(client.send(:store_class)).to eq Slack::RealTime::Store
534
+ end
535
+ it 'sets store_class' do
536
+ expect(client.send(:store_class)).to eq(Slack::RealTime::Stores::Starter)
537
+ end
538
+ context 'start!' do
539
+ let(:socket) { double(Slack::RealTime::Socket, connected?: true) }
540
+
541
+ before do
542
+ allow(Slack::RealTime::Socket).to receive(:new).and_return(socket)
543
+ allow(socket).to receive(:connect!)
544
+ allow(socket).to receive(:start_sync)
545
+ end
546
+
547
+ it 'instantiates the correct store class', vcr: { cassette_name: 'web/rtm_connect' } do
548
+ client.start!
549
+ expect(client.store).to be_a Slack::RealTime::Stores::Starter
550
+ end
551
+ end
552
+ end
553
+ end
554
+
555
+ context 'store' do
556
+ before do
557
+ described_class.configure do |config|
558
+ config.store_class = Slack::RealTime::Stores::Store
559
+ end
560
+ end
561
+
562
+ describe '#initialize' do
563
+ context 'start!' do
564
+ let(:socket) { double(Slack::RealTime::Socket, connected?: true) }
565
+
566
+ before do
567
+ allow(Slack::RealTime::Socket).to receive(:new).and_return(socket)
568
+ allow(socket).to receive(:connect!)
569
+ allow(socket).to receive(:start_sync)
570
+ end
571
+
572
+ it 'calls rtm_start and not rtm_connect', vcr: { cassette_name: 'web/rtm_start' } do
573
+ expect(client.web_client).to receive(:rtm_start).and_call_original
574
+ client.start!
575
+ end
576
+ end
270
577
  end
271
578
  end
579
+ end
580
+
581
+ context 'start_method' do
272
582
  describe '#initialize' do
273
583
  it 'can be overriden explicitly' do
274
- client = Slack::RealTime::Client.new(store_class: Slack::RealTime::Store)
275
- expect(client.send(:store_class)).to eq Slack::RealTime::Store
584
+ client = described_class.new(start_method: :overriden)
585
+ expect(client.send(:start_method)).to eq :overriden
276
586
  end
277
- it 'sets store_class' do
278
- expect(client.send(:store_class)).to eq(Slack::RealTime::Stores::Starter)
587
+ context 'with start_method' do
588
+ before do
589
+ described_class.configure do |config|
590
+ config.start_method = :overriden
591
+ end
592
+ end
593
+
594
+ it 'sets start_method' do
595
+ expect(client.send(:start_method)).to eq :overriden
596
+ end
597
+ it 'calls the overriden method' do
598
+ expect(client.web_client).to receive(:overriden).and_raise('overriden')
599
+ expect do
600
+ client.start!
601
+ end.to raise_error RuntimeError, 'overriden'
602
+ end
279
603
  end
604
+
280
605
  context 'start!' do
281
606
  let(:socket) { double(Slack::RealTime::Socket, connected?: true) }
607
+
282
608
  before do
283
609
  allow(Slack::RealTime::Socket).to receive(:new).and_return(socket)
284
610
  allow(socket).to receive(:connect!)
285
611
  allow(socket).to receive(:start_sync)
286
612
  end
287
- it 'instantiates the correct store class' do
613
+
614
+ it 'defaults to :rtm_start when using full store',
615
+ vcr: { cassette_name: 'web/rtm_start' } do
616
+ expect(client.web_client).to receive(:rtm_start).and_call_original
288
617
  client.start!
289
- expect(client.store).to be_a Slack::RealTime::Stores::Starter
290
618
  end
291
619
  end
292
620
  end