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
@@ -101,4 +101,4 @@ http_interactions:
101
101
  Explorer","icons":{"image_36":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2016-01-21\/19073538231_edf8d896148b6bfef790_36.png","image_48":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2016-01-21\/19073538231_edf8d896148b6bfef790_48.png","image_72":"https:\/\/s3-us-west-2.amazonaws.com\/slack-files2\/avatars\/2016-01-21\/19073538231_edf8d896148b6bfef790_72.png"}}],"url":"wss:\/\/ms173.slack-msgs.com\/websocket\/lqcUiAvrKTP-uuid="}'
102
102
  http_version:
103
103
  recorded_at: Sun, 31 Jan 2016 22:42:57 GMT
104
- recorded_with: VCR 3.0.0
104
+ recorded_with: VCR 3.0.3
@@ -0,0 +1,76 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://slack.com/api/views.open
6
+ body:
7
+ encoding: UTF-8
8
+ string: token=token&trigger_id=trigger_id&view=%7B%7D
9
+ headers:
10
+ Accept:
11
+ - application/json; charset=utf-8
12
+ User-Agent:
13
+ - Slack Ruby Client/0.14.6
14
+ Content-Type:
15
+ - application/x-www-form-urlencoded
16
+ Accept-Encoding:
17
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ Content-Type:
24
+ - application/json; charset=utf-8
25
+ Content-Length:
26
+ - '154'
27
+ Connection:
28
+ - keep-alive
29
+ Date:
30
+ - Wed, 19 Feb 2020 17:52:59 GMT
31
+ Server:
32
+ - Apache
33
+ X-Content-Type-Options:
34
+ - nosniff
35
+ Expires:
36
+ - Mon, 26 Jul 1997 05:00:00 GMT
37
+ Cache-Control:
38
+ - private, no-cache, no-store, must-revalidate
39
+ X-Xss-Protection:
40
+ - '0'
41
+ Vary:
42
+ - Accept-Encoding
43
+ Pragma:
44
+ - no-cache
45
+ Access-Control-Allow-Headers:
46
+ - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid,
47
+ x-b3-sampled, x-b3-flags
48
+ Strict-Transport-Security:
49
+ - max-age=31536000; includeSubDomains; preload
50
+ Referrer-Policy:
51
+ - no-referrer
52
+ X-Slack-Backend:
53
+ - h
54
+ Access-Control-Expose-Headers:
55
+ - x-slack-req-id, retry-after
56
+ Access-Control-Allow-Origin:
57
+ - "*"
58
+ X-Via:
59
+ - haproxy-www-ixj4
60
+ X-Cache:
61
+ - Miss from cloudfront
62
+ Via:
63
+ - 1.1 b6cc1359c0cd55a8339441d8abb6a450.cloudfront.net (CloudFront)
64
+ X-Amz-Cf-Pop:
65
+ - JFK51-C1
66
+ X-Amz-Cf-Id:
67
+ - fWF96IvY1omctxPC6XwjvZ2TIfpmVLlsT35MsfAWqK7zDChMCpE_oQ==
68
+ body:
69
+ encoding: ASCII-8BIT
70
+ string: '{"ok":false,"error":"invalid_arguments","response_metadata":{"messages":["[ERROR]
71
+ missing required field: title [json-pointer:\/view]","[ERROR] missing required
72
+ field: blocks [json-pointer:\/view]","[ERROR] missing required field: type
73
+ [json-pointer:\/view]"]}}'
74
+ http_version: null
75
+ recorded_at: Wed, 19 Feb 2020 17:52:59 GMT
76
+ recorded_with: VCR 5.1.0
@@ -1,17 +1,22 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
- RSpec.describe 'integration test', skip: (!ENV['SLACK_API_TOKEN'] || !ENV['CONCURRENCY']) && 'missing SLACK_API_TOKEN and/or CONCURRENCY' do
4
+ RSpec.describe 'integration test', skip: ( # rubocop:disable RSpec/DescribeClass
5
+ (!ENV['SLACK_API_TOKEN'] || !ENV['CONCURRENCY']) && 'missing SLACK_API_TOKEN and/or CONCURRENCY'
6
+ ) do
4
7
  around do |ex|
5
8
  WebMock.allow_net_connect!
6
9
  VCR.turned_off { ex.run }
7
10
  WebMock.disable_net_connect!
8
11
  end
9
12
 
13
+ let(:client) { Slack::RealTime::Client.new(token: ENV['SLACK_API_TOKEN']) }
10
14
  let(:logger) do
11
15
  logger = Logger.new(STDOUT)
12
- logger.level = Logger::DEBUG
16
+ logger.level = Logger::INFO
13
17
  logger
14
18
  end
19
+ let!(:queue) { @queue = QueueWithTimeout.new }
15
20
 
16
21
  before do
17
22
  Thread.abort_on_exception = true
@@ -19,77 +24,69 @@ RSpec.describe 'integration test', skip: (!ENV['SLACK_API_TOKEN'] || !ENV['CONCU
19
24
  Slack.configure do |slack|
20
25
  slack.logger = logger
21
26
  end
22
- end
23
-
24
- after do
25
- Slack.config.reset
26
- end
27
27
 
28
- let(:queue) { QueueWithTimeout.new }
29
-
30
- let(:client) { Slack::RealTime::Client.new(token: ENV['SLACK_API_TOKEN']) }
31
-
32
- let(:connection) do
33
- # starts the client and pushes an item on a queue when connected
34
- client.start_async do |driver|
35
- driver.on :open do |data|
36
- logger.debug "connection.on :open, data=#{data}"
37
- queue.push nil
38
- end
28
+ client.on :hello do
29
+ logger.info(
30
+ "Successfully connected, welcome '#{client.self.name}' to " \
31
+ "the '#{client.team.name}' team at https://#{client.team.domain}.slack.com."
32
+ )
39
33
  end
40
- end
41
34
 
42
- before do
43
- client.on :hello do
44
- logger.info "Successfully connected, welcome '#{client.self.name}' to the '#{client.team.name}' team at https://#{client.team.domain}.slack.com."
35
+ client.on :message do |event|
36
+ logger.info " #{event.class}"
45
37
  end
46
38
 
47
39
  client.on :close do
40
+ logger.info 'Disconnecting ...'
48
41
  # pushes another item to the queue when disconnected
49
- queue.push nil
42
+ queue.push :closed
50
43
  end
51
44
  end
52
45
 
46
+ after do
47
+ Slack.config.reset
48
+ wait_for_server # wait for :closed to be pushed on queue
49
+ @server.join if @server.is_a?(::Thread)
50
+ end
51
+
53
52
  def start_server
54
- dt = rand(5) + 1
53
+ dt = rand(10..20)
55
54
  logger.debug "#start_server, waiting #{dt} second(s)"
56
55
  sleep dt # prevent Slack 429 rate limit errors
57
- # start server and wait for on :open
58
- c = connection
59
- logger.debug "connection is #{c}"
60
- queue.pop_with_timeout(5)
56
+ # starts the client and pushes an item on a queue when connected
57
+ @server = client.start_async do |driver|
58
+ driver.on :open do |data|
59
+ logger.debug "connection.on :open, data=#{data}"
60
+ queue.push :opened
61
+ end
62
+
63
+ driver.on :hello do |data|
64
+ logger.debug "connection.on :hello, data=#{data}"
65
+ end
66
+ end
67
+ logger.debug "started #{@server}"
68
+ expect(queue.pop_with_timeout(5)).to eq :opened
61
69
  end
62
70
 
63
71
  def wait_for_server
72
+ return unless @queue
73
+
64
74
  logger.debug '#wait_for_server'
65
75
  queue.pop_with_timeout(5)
66
76
  logger.debug '#wait_for_server, joined'
67
- end
68
-
69
- def stop_server
70
- logger.debug '#stop_server'
71
- client.stop!
72
- logger.debug '#stop_server, stopped'
73
- end
74
-
75
- after do
76
- wait_for_server
77
+ @queue = nil
77
78
  end
78
79
 
79
80
  context 'client connected' do
80
- before do
81
- start_server
82
- end
83
-
84
- let(:channel) { "@#{client.self.name}" }
81
+ let(:channel) { "@#{client.self.id}" }
82
+ let(:message) { SecureRandom.hex }
85
83
 
86
84
  it 'responds to message' do
87
- message = SecureRandom.hex
88
-
89
85
  client.on :message do |data|
90
86
  logger.debug data
91
87
  # concurrent execution of tests causes messages to arrive in any order
92
88
  next unless data.text == message
89
+
93
90
  expect(data.text).to eq message
94
91
  expect(data.subtype).to eq 'bot_message'
95
92
  logger.debug 'client.stop!'
@@ -97,13 +94,19 @@ RSpec.describe 'integration test', skip: (!ENV['SLACK_API_TOKEN'] || !ENV['CONCU
97
94
  client.stop!
98
95
  end
99
96
 
97
+ start_server
98
+
100
99
  logger.debug "chat_postMessage, channel=#{channel}, message=#{message}"
101
100
  client.web_client.chat_postMessage channel: channel, text: message
102
101
  end
103
102
 
104
103
  it 'sends message' do
105
- client.message(channel: channel, text: 'Hello world!')
106
- client.stop!
104
+ client.on :hello do
105
+ expect(client.message(channel: channel, text: message)).to be true
106
+ client.stop!
107
+ end
108
+
109
+ start_server
107
110
  end
108
111
  end
109
112
 
@@ -117,6 +120,72 @@ RSpec.describe 'integration test', skip: (!ENV['SLACK_API_TOKEN'] || !ENV['CONCU
117
120
  start_server
118
121
  end
119
122
 
123
+ context 'with websocket_ping set' do
124
+ before do
125
+ client.websocket_ping = 5
126
+ end
127
+
128
+ it 'sends pings' do
129
+ @reply_to = nil
130
+ client.on :pong do |data|
131
+ @reply_to = data.reply_to
132
+ queue.push :pong
133
+ client.stop!
134
+ end
135
+
136
+ start_server
137
+
138
+ queue.pop_with_timeout(10)
139
+ expect(@reply_to).to eq 1
140
+ end
141
+
142
+ it 'rebuilds the websocket connection when dropped' do
143
+ @reply_to = nil
144
+ client.on :pong do |data|
145
+ logger.info data
146
+ @reply_to = data.reply_to
147
+ if @reply_to == 1
148
+ client.instance_variable_get(:@socket).close
149
+ queue.push :close
150
+ else
151
+ expect(@reply_to).to eq 2
152
+ queue.push :pong
153
+ client.stop!
154
+ end
155
+ end
156
+
157
+ start_server
158
+
159
+ 4.times do |i|
160
+ queue.pop_with_timeout(10)
161
+ client.logger.info "Pop #{i}"
162
+ end
163
+ end
164
+ end
165
+
166
+ context 'with websocket_ping not set' do
167
+ before do
168
+ client.websocket_ping = 0
169
+ end
170
+
171
+ it 'does not send pings' do
172
+ @reply_to = nil
173
+
174
+ client.on :pong do |data|
175
+ @reply_to = data.reply_to
176
+ end
177
+
178
+ client.on :hello do
179
+ client.stop!
180
+ end
181
+
182
+ start_server
183
+ wait_for_server
184
+
185
+ expect(@reply_to).to be nil
186
+ end
187
+ end
188
+
120
189
  it 'gets close, followed by closed' do
121
190
  client.on :hello do
122
191
  expect(client.started?).to be true
@@ -125,7 +194,6 @@ RSpec.describe 'integration test', skip: (!ENV['SLACK_API_TOKEN'] || !ENV['CONCU
125
194
 
126
195
  client.on :close do |data|
127
196
  logger.debug "client.on :close, data=#{data}"
128
- expect(client.started?).to be true
129
197
  @close_called = true
130
198
  end
131
199
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  describe Slack::Config do
@@ -7,6 +8,7 @@ describe Slack::Config do
7
8
  config.token = 'a token'
8
9
  end
9
10
  end
11
+
10
12
  it 'sets token' do
11
13
  expect(Slack.config.token).to eq 'a token'
12
14
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe Slack::Events::Config do
5
+ before do
6
+ ENV['SLACK_SIGNING_SECRET'] = 'secret'
7
+ described_class.reset
8
+ end
9
+
10
+ after do
11
+ ENV.delete 'SLACK_SIGNING_SECRET'
12
+ end
13
+
14
+ it 'defaults signing secret to ENV[SLACK_SIGNING_SECRET]' do
15
+ expect(Slack::Events.config.signing_secret).to eq 'secret'
16
+ end
17
+ it 'defaults signature expiration to 5 minutes' do
18
+ expect(Slack::Events.config.signature_expires_in).to eq 5 * 60
19
+ end
20
+ context 'configured' do
21
+ before do
22
+ Slack::Events.configure do |config|
23
+ config.signing_secret = 'custom'
24
+ config.signature_expires_in = 45
25
+ end
26
+ end
27
+
28
+ it 'uses the configured values' do
29
+ expect(Slack::Events.config.signing_secret).to eq 'custom'
30
+ expect(Slack::Events.config.signature_expires_in).to eq 45
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,183 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe Slack::Events::Request do
5
+ subject(:request) do
6
+ described_class.new(http_request)
7
+ end
8
+
9
+ before do
10
+ Slack::Events.configure do |config|
11
+ config.signing_secret = signing_secret
12
+ config.signature_expires_in = 30
13
+ end
14
+ end
15
+
16
+ let(:signing_secret) { 'ade6ca762ade4db0e7d31484cd616b9c' }
17
+ let(:signature) { 'v0=91177eea054d65de0fc0f9b4ec57714307bc0ce2c5f3bf0d28b1b720c8f92ba2' }
18
+ let(:timestamp) { '1547933148' }
19
+ let(:body) do
20
+ '{"token":"X34FAqCu8tmGEkEEpoDncnja","challenge":' \
21
+ '"P7sFXA4o3HV2hTx4zb4zcQ9yrvuQs8pDh6EacOxmMRj0tJaXfQFF","type":"url_verification"}'
22
+ end
23
+ let(:http_request) do
24
+ double(
25
+ headers: {
26
+ 'X-Slack-Request-Timestamp' => timestamp,
27
+ 'X-Slack-Signature' => signature
28
+ },
29
+ body: StringIO.new(body)
30
+ )
31
+ end
32
+
33
+ after do
34
+ Slack::Events.config.reset
35
+ end
36
+
37
+ it 'reads http request' do
38
+ expect(request.signature).to eq signature
39
+ expect(request.body).to eq body
40
+ expect(request.timestamp).to eq timestamp
41
+ expect(request.version).to eq 'v0'
42
+ end
43
+
44
+ it 'rewinds the request body after reading it' do
45
+ expect(request.body).to eq body
46
+ expect(http_request.body.read).to eq body
47
+ end
48
+
49
+ context 'time' do
50
+ after do
51
+ Timecop.return
52
+ end
53
+
54
+ context 'with an invalid signature' do
55
+ let(:signature) { 'v0=invalid' }
56
+
57
+ before do
58
+ Timecop.freeze(Time.at(timestamp.to_i))
59
+ end
60
+
61
+ it 'is invalid but not expired' do
62
+ expect(request).not_to be_valid
63
+ expect(request).not_to be_expired
64
+ end
65
+ end
66
+
67
+ context 'with an invalid body' do
68
+ let(:body) { 'invalid' }
69
+
70
+ before do
71
+ Timecop.freeze(Time.at(timestamp.to_i))
72
+ end
73
+
74
+ it 'is invalid but not expired' do
75
+ expect(request).not_to be_valid
76
+ expect(request).not_to be_expired
77
+ end
78
+ end
79
+
80
+ context 'with an invalid signing secret' do
81
+ before do
82
+ Slack::Events.configure do |config|
83
+ config.signing_secret = 'invalid'
84
+ end
85
+ Timecop.freeze(Time.at(timestamp.to_i))
86
+ end
87
+
88
+ it 'is invalid but not expired' do
89
+ expect(request).not_to be_valid
90
+ expect(request).not_to be_expired
91
+ end
92
+ end
93
+
94
+ context 'within time window' do
95
+ before do
96
+ Timecop.freeze(Time.at(timestamp.to_i) + Slack::Events.config.signature_expires_in - 1)
97
+ end
98
+
99
+ it 'is valid' do
100
+ expect(request).to be_valid
101
+ expect(request).not_to be_expired
102
+ end
103
+ it 'does not raise an error and returns true' do
104
+ expect(request.verify!).to be true
105
+ end
106
+ end
107
+
108
+ context 'after time window' do
109
+ before do
110
+ Timecop.freeze(Time.at(timestamp.to_i) + Slack::Events.config.signature_expires_in + 1)
111
+ end
112
+
113
+ it 'is valid but expired' do
114
+ expect(request).to be_valid
115
+ expect(request).to be_expired
116
+ end
117
+ it 'raises an error on verify!' do
118
+ expect { request.verify! }.to raise_error Slack::Events::Request::TimestampExpired
119
+ end
120
+ end
121
+
122
+ context 'before time but within window' do
123
+ before do
124
+ Timecop.freeze(Time.at(timestamp.to_i) - Slack::Events.config.signature_expires_in + 1)
125
+ end
126
+
127
+ it 'is valid and not expired' do
128
+ expect(request).to be_valid
129
+ expect(request).not_to be_expired
130
+ end
131
+ it 'does not raise an error on verify!' do
132
+ expect(request.verify!).to be true
133
+ end
134
+ end
135
+
136
+ context 'before time window' do
137
+ before do
138
+ Timecop.freeze(Time.at(timestamp.to_i) - Slack::Events.config.signature_expires_in - 1)
139
+ end
140
+
141
+ it 'is valid but expired' do
142
+ expect(request).to be_valid
143
+ expect(request).to be_expired
144
+ end
145
+ it 'raises an error on verify!' do
146
+ expect { request.verify! }.to raise_error Slack::Events::Request::TimestampExpired
147
+ end
148
+ end
149
+ end
150
+
151
+ context 'without global config' do
152
+ before do
153
+ Slack::Events.config.reset
154
+ end
155
+
156
+ context 'without a signing secret parameter' do
157
+ subject(:request) do
158
+ described_class.new(http_request)
159
+ end
160
+
161
+ it 'raises MissingSigningSecret' do
162
+ expect { request.valid? }.to raise_error Slack::Events::Request::MissingSigningSecret
163
+ end
164
+ end
165
+
166
+ context 'with a signing secret parameter' do
167
+ subject(:request) do
168
+ described_class.new(http_request,
169
+ signing_secret: signing_secret,
170
+ signature_expires_in: 30)
171
+ end
172
+
173
+ before do
174
+ Timecop.freeze(Time.at(timestamp.to_i))
175
+ end
176
+
177
+ it 'is valid and not expired' do
178
+ expect(request).to be_valid
179
+ expect(request).not_to be_expired
180
+ end
181
+ end
182
+ end
183
+ end