slack-ruby-client 0.13.1 → 2.0.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 (402) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/.github/workflows/integration_test.yml +26 -0
  4. data/.github/workflows/lint.yml +14 -0
  5. data/.github/workflows/pr_lint.yml +21 -0
  6. data/.github/workflows/test.yml +36 -0
  7. data/.gitignore +5 -3
  8. data/.rubocop.yml +34 -5
  9. data/.rubocop_todo.yml +180 -46
  10. data/.ruby-version +1 -0
  11. data/CHANGELOG.md +119 -2
  12. data/CONTRIBUTING.md +23 -11
  13. data/Dangerfile +2 -0
  14. data/Gemfile +22 -5
  15. data/Gemfile.danger +6 -0
  16. data/LICENSE.md +1 -1
  17. data/README.md +236 -101
  18. data/RELEASING.md +2 -2
  19. data/Rakefile +2 -1
  20. data/UPGRADING.md +100 -2
  21. data/bin/commands/admin_analytics.rb +16 -0
  22. data/bin/commands/admin_apps.rb +51 -0
  23. data/bin/commands/admin_apps_approved.rb +17 -0
  24. data/bin/commands/admin_apps_requests.rb +28 -0
  25. data/bin/commands/admin_apps_restricted.rb +17 -0
  26. data/bin/commands/admin_audit_anomaly_allow.rb +23 -0
  27. data/bin/commands/admin_auth_policy.rb +39 -0
  28. data/bin/commands/admin_barriers.rb +47 -0
  29. data/bin/commands/admin_conversations.rb +171 -0
  30. data/bin/commands/admin_conversations_ekm.rb +17 -0
  31. data/bin/commands/admin_conversations_restrictAccess.rb +37 -0
  32. data/bin/commands/admin_emoji.rb +54 -0
  33. data/bin/commands/admin_inviteRequests.rb +36 -0
  34. data/bin/commands/admin_inviteRequests_approved.rb +16 -0
  35. data/bin/commands/admin_inviteRequests_denied.rb +16 -0
  36. data/bin/commands/admin_teams.rb +27 -0
  37. data/bin/commands/admin_teams_admins.rb +16 -0
  38. data/bin/commands/admin_teams_owners.rb +16 -0
  39. data/bin/commands/admin_teams_settings.rb +64 -0
  40. data/bin/commands/admin_usergroups.rb +48 -0
  41. data/bin/commands/admin_users.rb +98 -0
  42. data/bin/commands/admin_users_session.rb +78 -0
  43. data/bin/commands/admin_users_unsupportedVersions.rb +15 -0
  44. data/bin/commands/api.rb +1 -1
  45. data/bin/commands/apps.rb +15 -0
  46. data/bin/commands/apps_connections.rb +13 -0
  47. data/bin/commands/apps_event_authorizations.rb +16 -0
  48. data/bin/commands/apps_manifest.rb +52 -0
  49. data/bin/commands/auth.rb +1 -0
  50. data/bin/commands/auth_teams.rb +16 -0
  51. data/bin/commands/bookmarks.rb +53 -0
  52. data/bin/commands/bots.rb +2 -0
  53. data/bin/commands/calls.rb +52 -0
  54. data/bin/commands/calls_participants.rb +25 -0
  55. data/bin/commands/chat.rb +61 -14
  56. data/bin/commands/chat_scheduledMessages.rb +19 -0
  57. data/bin/commands/conversations.rb +82 -10
  58. data/bin/commands/dialog.rb +1 -0
  59. data/bin/commands/dnd.rb +6 -3
  60. data/bin/commands/emoji.rb +1 -0
  61. data/bin/commands/files.rb +34 -18
  62. data/bin/commands/files_comments.rb +1 -21
  63. data/bin/commands/files_remote.rb +78 -0
  64. data/bin/commands/migration.rb +2 -0
  65. data/bin/commands/oauth.rb +2 -14
  66. data/bin/commands/oauth_v2.rb +29 -0
  67. data/bin/commands/openid_connect.rb +27 -0
  68. data/bin/commands/pins.rb +3 -6
  69. data/bin/commands/reactions.rb +3 -3
  70. data/bin/commands/reminders.rb +7 -0
  71. data/bin/commands/rtm.rb +1 -15
  72. data/bin/commands/search.rb +6 -1
  73. data/bin/commands/stars.rb +8 -6
  74. data/bin/commands/team.rb +6 -0
  75. data/bin/commands/team_billing.rb +13 -0
  76. data/bin/commands/team_preferences.rb +13 -0
  77. data/bin/commands/team_profile.rb +1 -0
  78. data/bin/commands/tooling_tokens.rb +14 -0
  79. data/bin/commands/usergroups.rb +7 -1
  80. data/bin/commands/usergroups_users.rb +3 -0
  81. data/bin/commands/users.rb +6 -4
  82. data/bin/commands/users_admin.rb +1 -0
  83. data/bin/commands/users_prefs.rb +1 -0
  84. data/bin/commands/users_profile.rb +6 -5
  85. data/bin/commands/views.rb +50 -0
  86. data/bin/commands/workflows.rb +38 -0
  87. data/bin/commands.rb +41 -8
  88. data/bin/slack +3 -4
  89. data/examples/hi_real_time_and_web/Gemfile +1 -0
  90. data/examples/hi_real_time_and_web/hi.rb +7 -3
  91. data/examples/hi_real_time_async_async/Gemfile +1 -0
  92. data/examples/hi_real_time_async_async/hi.rb +6 -2
  93. data/examples/hi_web/Gemfile +1 -0
  94. data/examples/hi_web/hi.rb +1 -0
  95. data/examples/new_ticket/Gemfile +1 -0
  96. data/examples/new_ticket/new_ticket.rb +1 -0
  97. data/lib/slack/config.rb +2 -2
  98. data/lib/slack/events/config.rb +32 -0
  99. data/lib/slack/events/request.rb +72 -0
  100. data/lib/slack/logger.rb +6 -5
  101. data/lib/slack/messages/formatting.rb +1 -0
  102. data/lib/slack/messages/message.rb +1 -4
  103. data/lib/slack/real_time/api/message.rb +6 -3
  104. data/lib/slack/real_time/api/message_id.rb +1 -0
  105. data/lib/slack/real_time/api/ping.rb +5 -2
  106. data/lib/slack/real_time/api/templates/event_handler.erb +5 -1
  107. data/lib/slack/real_time/api/typing.rb +5 -2
  108. data/lib/slack/real_time/client.rb +105 -54
  109. data/lib/slack/real_time/concurrency/async.rb +77 -6
  110. data/lib/slack/real_time/concurrency.rb +1 -2
  111. data/lib/slack/real_time/config.rb +9 -13
  112. data/lib/slack/real_time/models/base.rb +1 -4
  113. data/lib/slack/real_time/models/bot.rb +1 -0
  114. data/lib/slack/real_time/models/channel.rb +5 -0
  115. data/lib/slack/real_time/models/im.rb +1 -0
  116. data/lib/slack/real_time/models/{group.rb → mpim.rb} +2 -1
  117. data/lib/slack/real_time/models/team.rb +1 -0
  118. data/lib/slack/real_time/models/user.rb +1 -0
  119. data/lib/slack/real_time/models.rb +3 -1
  120. data/lib/slack/real_time/socket.rb +45 -17
  121. data/lib/slack/real_time/stores/base.rb +28 -14
  122. data/lib/slack/real_time/stores/starter.rb +325 -297
  123. data/lib/slack/real_time/stores/store.rb +271 -196
  124. data/lib/slack/real_time/stores.rb +2 -7
  125. data/lib/slack/version.rb +2 -1
  126. data/lib/slack/web/api/endpoints/admin_analytics.rb +28 -0
  127. data/lib/slack/web/api/endpoints/admin_apps.rb +78 -0
  128. data/lib/slack/web/api/endpoints/admin_apps_approved.rb +35 -0
  129. data/lib/slack/web/api/endpoints/admin_apps_requests.rb +51 -0
  130. data/lib/slack/web/api/endpoints/admin_apps_restricted.rb +35 -0
  131. data/lib/slack/web/api/endpoints/admin_audit_anomaly_allow.rb +34 -0
  132. data/lib/slack/web/api/endpoints/admin_auth_policy.rb +72 -0
  133. data/lib/slack/web/api/endpoints/admin_barriers.rb +82 -0
  134. data/lib/slack/web/api/endpoints/admin_conversations.rb +264 -0
  135. data/lib/slack/web/api/endpoints/admin_conversations_ekm.rb +35 -0
  136. data/lib/slack/web/api/endpoints/admin_conversations_restrictAccess.rb +61 -0
  137. data/lib/slack/web/api/endpoints/admin_emoji.rb +88 -0
  138. data/lib/slack/web/api/endpoints/admin_inviteRequests.rb +61 -0
  139. data/lib/slack/web/api/endpoints/admin_inviteRequests_approved.rb +33 -0
  140. data/lib/slack/web/api/endpoints/admin_inviteRequests_denied.rb +33 -0
  141. data/lib/slack/web/api/endpoints/admin_teams.rb +50 -0
  142. data/lib/slack/web/api/endpoints/admin_teams_admins.rb +34 -0
  143. data/lib/slack/web/api/endpoints/admin_teams_owners.rb +34 -0
  144. data/lib/slack/web/api/endpoints/admin_teams_settings.rb +99 -0
  145. data/lib/slack/web/api/endpoints/admin_usergroups.rb +77 -0
  146. data/lib/slack/web/api/endpoints/admin_users.rb +163 -0
  147. data/lib/slack/web/api/endpoints/admin_users_session.rb +122 -0
  148. data/lib/slack/web/api/endpoints/admin_users_unsupportedVersions.rb +25 -0
  149. data/lib/slack/web/api/endpoints/api.rb +2 -3
  150. data/lib/slack/web/api/endpoints/apps.rb +27 -0
  151. data/lib/slack/web/api/endpoints/apps_connections.rb +21 -0
  152. data/lib/slack/web/api/endpoints/apps_event_authorizations.rb +34 -0
  153. data/lib/slack/web/api/endpoints/apps_manifest.rb +77 -0
  154. data/lib/slack/web/api/endpoints/auth.rb +2 -1
  155. data/lib/slack/web/api/endpoints/auth_teams.rb +33 -0
  156. data/lib/slack/web/api/endpoints/bookmarks.rb +88 -0
  157. data/lib/slack/web/api/endpoints/bots.rb +4 -1
  158. data/lib/slack/web/api/endpoints/calls.rb +83 -0
  159. data/lib/slack/web/api/endpoints/calls_participants.rb +42 -0
  160. data/lib/slack/web/api/endpoints/chat.rb +168 -65
  161. data/lib/slack/web/api/endpoints/chat_scheduledMessages.rb +40 -0
  162. data/lib/slack/web/api/endpoints/conversations.rb +182 -67
  163. data/lib/slack/web/api/endpoints/dialog.rb +5 -4
  164. data/lib/slack/web/api/endpoints/dnd.rb +9 -4
  165. data/lib/slack/web/api/endpoints/emoji.rb +1 -0
  166. data/lib/slack/web/api/endpoints/files.rb +69 -37
  167. data/lib/slack/web/api/endpoints/files_comments.rb +4 -36
  168. data/lib/slack/web/api/endpoints/files_remote.rb +127 -0
  169. data/lib/slack/web/api/endpoints/migration.rb +6 -3
  170. data/lib/slack/web/api/endpoints/oauth.rb +7 -31
  171. data/lib/slack/web/api/endpoints/oauth_v2.rb +48 -0
  172. data/lib/slack/web/api/endpoints/openid_connect.rb +42 -0
  173. data/lib/slack/web/api/endpoints/pins.rb +11 -18
  174. data/lib/slack/web/api/endpoints/reactions.rb +22 -21
  175. data/lib/slack/web/api/endpoints/reminders.rb +23 -10
  176. data/lib/slack/web/api/endpoints/rtm.rb +3 -25
  177. data/lib/slack/web/api/endpoints/search.rb +31 -16
  178. data/lib/slack/web/api/endpoints/stars.rb +14 -11
  179. data/lib/slack/web/api/endpoints/team.rb +15 -4
  180. data/lib/slack/web/api/endpoints/team_billing.rb +21 -0
  181. data/lib/slack/web/api/endpoints/team_preferences.rb +21 -0
  182. data/lib/slack/web/api/endpoints/team_profile.rb +2 -1
  183. data/lib/slack/web/api/endpoints/tooling_tokens.rb +24 -0
  184. data/lib/slack/web/api/endpoints/usergroups.rb +31 -20
  185. data/lib/slack/web/api/endpoints/usergroups_users.rb +13 -8
  186. data/lib/slack/web/api/endpoints/users.rb +24 -23
  187. data/lib/slack/web/api/endpoints/users_admin.rb +3 -2
  188. data/lib/slack/web/api/endpoints/users_prefs.rb +1 -0
  189. data/lib/slack/web/api/endpoints/users_profile.rb +8 -7
  190. data/lib/slack/web/api/endpoints/views.rb +102 -0
  191. data/lib/slack/web/api/endpoints/workflows.rb +61 -0
  192. data/lib/slack/web/api/endpoints.rb +82 -18
  193. data/lib/slack/web/api/error.rb +1 -0
  194. data/lib/slack/web/api/errors/server_error.rb +37 -0
  195. data/lib/slack/web/api/errors/slack_error.rb +14 -1
  196. data/lib/slack/web/api/errors/too_many_requests_error.rb +2 -4
  197. data/lib/slack/web/api/errors.rb +1116 -0
  198. data/lib/slack/web/api/mixins/{channels.id.rb → conversations.id.rb} +5 -6
  199. data/lib/slack/web/api/mixins/ids.id.rb +3 -2
  200. data/lib/slack/web/api/mixins/users.id.rb +3 -4
  201. data/lib/slack/web/api/mixins/users.search.rb +3 -1
  202. data/lib/slack/web/api/mixins.rb +2 -2
  203. data/lib/slack/web/api/patches/chat.attachments-blocks.patch +69 -0
  204. data/lib/slack/web/api/patches/{dialog.1.open-json-support.patch → dialog.encoded-json.patch} +4 -4
  205. data/lib/slack/web/api/patches/views.view-json.patch +55 -0
  206. data/lib/slack/web/api/templates/command.erb +1 -0
  207. data/lib/slack/web/api/templates/commands.erb +1 -0
  208. data/lib/slack/web/api/templates/endpoints.erb +2 -2
  209. data/lib/slack/web/api/templates/errors.erb +20 -0
  210. data/lib/slack/web/api/templates/method.erb +6 -2
  211. data/lib/slack/web/api/templates/method_spec.erb +2 -1
  212. data/lib/slack/web/client.rb +2 -1
  213. data/lib/slack/web/config.rb +5 -2
  214. data/lib/slack/web/faraday/connection.rb +24 -20
  215. data/lib/slack/web/faraday/request.rb +5 -1
  216. data/lib/slack/web/faraday/response/raise_error.rb +14 -7
  217. data/lib/slack/web/faraday/response/wrap_error.rb +24 -0
  218. data/lib/slack/web/pagination/cursor.rb +7 -7
  219. data/lib/slack-ruby-client.rb +12 -5
  220. data/lib/slack.rb +1 -0
  221. data/lib/slack_ruby_client.rb +1 -0
  222. data/lib/tasks/git.rake +1 -0
  223. data/lib/tasks/real_time.rake +51 -21
  224. data/lib/tasks/update.rake +1 -0
  225. data/lib/tasks/web.rake +48 -12
  226. data/screenshots/create-app.png +0 -0
  227. data/slack-ruby-client.gemspec +7 -12
  228. data/spec/fixtures/slack/web/429_error.yml +50 -54
  229. data/spec/fixtures/slack/web/auth_test_error.yml +51 -18
  230. data/spec/fixtures/slack/web/auth_test_success.yml +50 -26
  231. data/spec/fixtures/slack/web/conversations_info.yml +167 -0
  232. data/spec/fixtures/slack/web/conversations_setTopic.yml +84 -0
  233. data/spec/fixtures/slack/web/conversations_setTopic_one_page.yml +172 -0
  234. data/spec/fixtures/slack/web/conversations_setTopic_paginated.yml +253 -0
  235. data/spec/fixtures/slack/web/paginated_users_list.yml +501 -69
  236. data/spec/fixtures/slack/web/rtm_connect.yml +347 -26
  237. data/spec/fixtures/slack/web/users_info.yml +153 -69
  238. data/spec/fixtures/slack/web/users_list.yml +102 -41
  239. data/spec/fixtures/slack/web/views_open_error.yml +83 -0
  240. data/spec/integration/integration_spec.rb +115 -47
  241. data/spec/slack/config_spec.rb +2 -0
  242. data/spec/slack/events/config_spec.rb +35 -0
  243. data/spec/slack/events/request_spec.rb +188 -0
  244. data/spec/slack/messages/formatting_spec.rb +35 -13
  245. data/spec/slack/real_time/api/message_spec.rb +7 -2
  246. data/spec/slack/real_time/api/ping_spec.rb +3 -1
  247. data/spec/slack/real_time/api/typing_spec.rb +6 -2
  248. data/spec/slack/real_time/client_spec.rb +300 -142
  249. data/spec/slack/real_time/concurrency/it_behaves_like_a_realtime_socket.rb +2 -0
  250. data/spec/slack/real_time/concurrency/with_concurrency_spec.rb +10 -0
  251. data/spec/slack/real_time/concurrency/without_concurrency_spec.rb +10 -0
  252. data/spec/slack/real_time/event_handlers/bot_spec.rb +20 -17
  253. data/spec/slack/real_time/event_handlers/event_handlers_spec.rb +3 -2
  254. data/spec/slack/real_time/event_handlers/im_spec.rb +31 -27
  255. data/spec/slack/real_time/event_handlers/{group_spec.rb → private_channel_spec.rb} +36 -27
  256. data/spec/slack/real_time/event_handlers/{channel_spec.rb → public_channel_spec.rb} +31 -24
  257. data/spec/slack/real_time/event_handlers/team_spec.rb +8 -7
  258. data/spec/slack/real_time/event_handlers/user_spec.rb +7 -5
  259. data/spec/slack/real_time/rtm_connect_spec.rb +2 -1
  260. data/spec/slack/real_time/stores/store_spec.rb +50 -0
  261. data/spec/slack/slack_spec.rb +41 -6
  262. data/spec/slack/version_spec.rb +2 -1
  263. data/spec/slack/web/api/endpoints/admin_analytics_spec.rb +13 -0
  264. data/spec/slack/web/api/endpoints/admin_apps_approved_spec.rb +8 -0
  265. data/spec/slack/web/api/endpoints/admin_apps_requests_spec.rb +13 -0
  266. data/spec/slack/web/api/endpoints/admin_apps_restricted_spec.rb +8 -0
  267. data/spec/slack/web/api/endpoints/admin_apps_spec.rb +18 -0
  268. data/spec/slack/web/api/endpoints/admin_audit_anomaly_allow_spec.rb +8 -0
  269. data/spec/slack/web/api/endpoints/admin_auth_policy_spec.rb +35 -0
  270. data/spec/slack/web/api/endpoints/admin_barriers_spec.rb +38 -0
  271. data/spec/slack/web/api/endpoints/admin_conversations_ekm_spec.rb +8 -0
  272. data/spec/slack/web/api/endpoints/admin_conversations_restrictAccess_spec.rb +32 -0
  273. data/spec/slack/web/api/endpoints/admin_conversations_spec.rb +98 -0
  274. data/spec/slack/web/api/endpoints/admin_emoji_spec.rb +37 -0
  275. data/spec/slack/web/api/endpoints/admin_inviteRequests_approved_spec.rb +8 -0
  276. data/spec/slack/web/api/endpoints/admin_inviteRequests_denied_spec.rb +8 -0
  277. data/spec/slack/web/api/endpoints/admin_inviteRequests_spec.rb +18 -0
  278. data/spec/slack/web/api/endpoints/admin_teams_admins_spec.rb +13 -0
  279. data/spec/slack/web/api/endpoints/admin_teams_owners_spec.rb +13 -0
  280. data/spec/slack/web/api/endpoints/admin_teams_settings_spec.rb +53 -0
  281. data/spec/slack/web/api/endpoints/admin_teams_spec.rb +16 -0
  282. data/spec/slack/web/api/endpoints/admin_usergroups_spec.rb +37 -0
  283. data/spec/slack/web/api/endpoints/admin_users_session_spec.rb +41 -0
  284. data/spec/slack/web/api/endpoints/admin_users_spec.rb +67 -0
  285. data/spec/slack/web/api/endpoints/admin_users_unsupportedVersions_spec.rb +8 -0
  286. data/spec/slack/web/api/endpoints/api_spec.rb +1 -0
  287. data/spec/slack/web/api/endpoints/apps_connections_spec.rb +8 -0
  288. data/spec/slack/web/api/endpoints/apps_event_authorizations_spec.rb +13 -0
  289. data/spec/slack/web/api/endpoints/apps_manifest_spec.rb +36 -0
  290. data/spec/slack/web/api/endpoints/apps_spec.rb +16 -0
  291. data/spec/slack/web/api/endpoints/{apps_permissions_resources_spec.rb → auth_teams_spec.rb} +2 -1
  292. data/spec/slack/web/api/endpoints/bookmarks_spec.rb +40 -0
  293. data/spec/slack/web/api/endpoints/bots_spec.rb +1 -0
  294. data/spec/slack/web/api/endpoints/calls_participants_spec.rb +24 -0
  295. data/spec/slack/web/api/endpoints/calls_spec.rb +31 -0
  296. data/spec/slack/web/api/endpoints/chat_scheduledMessages_spec.rb +8 -0
  297. data/spec/slack/web/api/endpoints/custom_specs/auth_spec.rb +9 -7
  298. data/spec/slack/web/api/endpoints/custom_specs/chat_spec.rb +144 -40
  299. data/spec/slack/web/api/endpoints/custom_specs/conversations_spec.rb +13 -0
  300. data/spec/slack/web/api/endpoints/custom_specs/dialog_spec.rb +18 -6
  301. data/spec/slack/web/api/endpoints/custom_specs/users_spec.rb +8 -3
  302. data/spec/slack/web/api/endpoints/custom_specs/views_spec.rb +112 -0
  303. data/spec/slack/web/api/endpoints/dnd_spec.rb +4 -3
  304. data/spec/slack/web/api/endpoints/emoji_spec.rb +1 -0
  305. data/spec/slack/web/api/endpoints/files_comments_spec.rb +3 -21
  306. data/spec/slack/web/api/endpoints/files_remote_spec.rb +24 -0
  307. data/spec/slack/web/api/endpoints/files_spec.rb +18 -4
  308. data/spec/slack/web/api/endpoints/migration_spec.rb +1 -0
  309. data/spec/slack/web/api/endpoints/oauth_spec.rb +1 -22
  310. data/spec/slack/web/api/endpoints/oauth_v2_spec.rb +16 -0
  311. data/spec/slack/web/api/endpoints/openid_connect_spec.rb +8 -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/{apps_permissions_scopes_spec.rb → team_billing_spec.rb} +2 -1
  319. data/spec/slack/web/api/endpoints/team_preferences_spec.rb +8 -0
  320. data/spec/slack/web/api/endpoints/team_profile_spec.rb +1 -0
  321. data/spec/slack/web/api/endpoints/team_spec.rb +1 -0
  322. data/spec/slack/web/api/endpoints/tooling_tokens_spec.rb +13 -0
  323. data/spec/slack/web/api/endpoints/usergroups_spec.rb +1 -0
  324. data/spec/slack/web/api/endpoints/usergroups_users_spec.rb +3 -2
  325. data/spec/slack/web/api/endpoints/users_admin_spec.rb +1 -0
  326. data/spec/slack/web/api/endpoints/users_prefs_spec.rb +1 -0
  327. data/spec/slack/web/api/endpoints/users_profile_spec.rb +1 -0
  328. data/spec/slack/web/api/endpoints/workflows_spec.rb +26 -0
  329. data/spec/slack/web/api/error_spec.rb +7 -7
  330. data/spec/slack/web/api/errors/slack_error_spec.rb +26 -7
  331. data/spec/slack/web/api/mixins/conversations_list_spec.rb +21 -0
  332. data/spec/slack/web/api/mixins/conversations_spec.rb +45 -0
  333. data/spec/slack/web/api/mixins/users_spec.rb +19 -8
  334. data/spec/slack/web/api/pagination/cursor_spec.rb +47 -15
  335. data/spec/slack/web/client_spec.rb +199 -22
  336. data/spec/slack/web/faraday/request_spec.rb +80 -0
  337. data/spec/slack/web/faraday/response/raise_error_spec.rb +48 -12
  338. data/spec/spec_helper.rb +9 -2
  339. data/spec/support/queue_with_timeout.rb +5 -4
  340. data/spec/support/real_time/concurrency/mock.rb +1 -0
  341. data/spec/support/real_time/connected_client.rb +6 -6
  342. data/spec/support/real_time/event.rb +1 -0
  343. data/spec/support/real_time/loaded_client.rb +120 -0
  344. data/spec/support/token.rb +1 -0
  345. data/spec/support/vcr.rb +37 -1
  346. metadata +174 -262
  347. data/.travis.yml +0 -32
  348. data/bin/commands/apps_permissions.rb +0 -22
  349. data/bin/commands/apps_permissions_resources.rb +0 -14
  350. data/bin/commands/apps_permissions_scopes.rb +0 -12
  351. data/bin/commands/apps_permissions_users.rb +0 -25
  352. data/bin/commands/channels.rb +0 -175
  353. data/bin/commands/groups.rb +0 -174
  354. data/bin/commands/im.rb +0 -67
  355. data/bin/commands/mpim.rb +0 -65
  356. data/examples/hi_real_time/Gemfile +0 -5
  357. data/examples/hi_real_time/hi.gif +0 -0
  358. data/examples/hi_real_time/hi.rb +0 -37
  359. data/examples/hi_real_time_async_celluloid/Gemfile +0 -6
  360. data/examples/hi_real_time_async_celluloid/Procfile +0 -2
  361. data/examples/hi_real_time_async_celluloid/hi.rb +0 -35
  362. data/examples/hi_real_time_async_eventmachine/Gemfile +0 -6
  363. data/examples/hi_real_time_async_eventmachine/Procfile +0 -2
  364. data/examples/hi_real_time_async_eventmachine/hi.rb +0 -35
  365. data/lib/slack/real_time/concurrency/celluloid.rb +0 -118
  366. data/lib/slack/real_time/concurrency/eventmachine.rb +0 -66
  367. data/lib/slack/web/api/endpoints/apps_permissions.rb +0 -35
  368. data/lib/slack/web/api/endpoints/apps_permissions_resources.rb +0 -30
  369. data/lib/slack/web/api/endpoints/apps_permissions_scopes.rb +0 -20
  370. data/lib/slack/web/api/endpoints/apps_permissions_users.rb +0 -49
  371. data/lib/slack/web/api/endpoints/channels.rb +0 -266
  372. data/lib/slack/web/api/endpoints/groups.rb +0 -265
  373. data/lib/slack/web/api/endpoints/im.rb +0 -113
  374. data/lib/slack/web/api/endpoints/mpim.rb +0 -108
  375. data/lib/slack/web/api/endpoints/presence.rb +0 -23
  376. data/lib/slack/web/api/mixins/channels.id.json +0 -20
  377. data/lib/slack/web/api/mixins/groups.id.json +0 -20
  378. data/lib/slack/web/api/mixins/groups.id.rb +0 -26
  379. data/lib/slack/web/api/patches/chat.1.text-attachments-required.patch +0 -13
  380. data/lib/slack/web/api/patches/chat.2.attachments-json.patch +0 -17
  381. data/lib/slack/web/api/patches/chat.3.update-attachments-support.patch +0 -21
  382. data/lib/slack/web/api/patches/chat.4.postEphemeral-attachments-support.patch +0 -17
  383. data/lib/slack/web/api/patches/chat.5.postEphemeral-text-or-attachments.patch +0 -13
  384. data/screenshots/register-bot.png +0 -0
  385. data/spec/fixtures/slack/web/503_error.yml +0 -14
  386. data/spec/fixtures/slack/web/channels_info.yml +0 -46
  387. data/spec/fixtures/slack/web/groups_info.yml +0 -43
  388. data/spec/fixtures/slack/web/rtm_start.yml +0 -104
  389. data/spec/slack/real_time/concurrency/celluloid_spec.rb +0 -106
  390. data/spec/slack/real_time/concurrency/eventmachine_spec.rb +0 -47
  391. data/spec/slack/real_time/rtm_start_spec.rb +0 -13
  392. data/spec/slack/real_time/store_spec.rb +0 -11
  393. data/spec/slack/web/api/endpoints/apps_permissions_spec.rb +0 -15
  394. data/spec/slack/web/api/endpoints/apps_permissions_users_spec.rb +0 -18
  395. data/spec/slack/web/api/endpoints/conversations_spec.rb +0 -100
  396. data/spec/slack/web/api/endpoints/custom_specs/channels_spec.rb +0 -11
  397. data/spec/slack/web/api/endpoints/custom_specs/groups_spec.rb +0 -11
  398. data/spec/slack/web/api/endpoints/im_spec.rb +0 -38
  399. data/spec/slack/web/api/endpoints/mpim_spec.rb +0 -38
  400. data/spec/slack/web/api/errors/service_unavailable_spec.rb +0 -14
  401. data/spec/slack/web/api/mixins/channels_spec.rb +0 -33
  402. data/spec/slack/web/api/mixins/groups_spec.rb +0 -33
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe Slack::Web::Api::Mixins::Conversations do
5
+ subject(:conversations) do
6
+ klass.new
7
+ end
8
+
9
+ let(:klass) do
10
+ Class.new do
11
+ include Slack::Web::Api::Mixins::Conversations
12
+ end
13
+ end
14
+
15
+ before do
16
+ allow(conversations).to receive(:conversations_list).and_yield(
17
+ Slack::Messages::Message.new(
18
+ 'channels' => [{
19
+ 'id' => 'CDEADBEEF',
20
+ 'name' => 'general'
21
+ }]
22
+ )
23
+ )
24
+ end
25
+
26
+ describe '#conversations_id' do
27
+ it 'leaves channels specified by ID alone' do
28
+ expect(conversations.conversations_id(channel: 'C123456')).to(
29
+ eq('ok' => true, 'channel' => { 'id' => 'C123456' })
30
+ )
31
+ end
32
+
33
+ it 'translates a channel that starts with a #' do
34
+ expect(conversations.conversations_id(channel: '#general')).to(
35
+ eq('ok' => true, 'channel' => { 'id' => 'CDEADBEEF' })
36
+ )
37
+ end
38
+
39
+ it 'fails with an exception' do
40
+ expect { conversations.conversations_id(channel: '#invalid') }.to(
41
+ raise_error(Slack::Web::Api::Errors::SlackError, 'channel_not_found')
42
+ )
43
+ end
44
+ end
45
+ end
@@ -1,16 +1,19 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  RSpec.describe Slack::Web::Api::Mixins::Users do
5
+ subject(:users) do
6
+ klass.new
7
+ end
8
+
4
9
  let(:klass) do
5
10
  Class.new do
6
11
  include Slack::Web::Api::Mixins::Users
7
12
  end
8
13
  end
9
- subject do
10
- klass.new
11
- end
14
+
12
15
  before do
13
- allow(subject).to receive(:users_list).and_return(
16
+ allow(users).to receive(:users_list).and_yield(
14
17
  Slack::Messages::Message.new(
15
18
  'members' => [{
16
19
  'id' => 'UDEADBEEF',
@@ -20,21 +23,29 @@ RSpec.describe Slack::Web::Api::Mixins::Users do
20
23
  )
21
24
  )
22
25
  end
26
+
23
27
  context '#users_id' do
24
28
  it 'leaves users specified by ID alone' do
25
- expect(subject.users_id(user: 'U123456')).to eq('ok' => true, 'user' => { 'id' => 'U123456' })
29
+ expect(users.users_id(user: 'U123456')).to eq('ok' => true, 'user' => { 'id' => 'U123456' })
26
30
  end
31
+
27
32
  it 'translates a user that starts with a #' do
28
- expect(subject.users_id(user: '@aws')).to eq('ok' => true, 'user' => { 'id' => 'UDEADBEEF' })
33
+ expect(users.users_id(user: '@aws')).to eq('ok' => true, 'user' => { 'id' => 'UDEADBEEF' })
29
34
  end
35
+
30
36
  it 'fails with an exception' do
31
- expect { subject.users_id(user: '@foo') }.to raise_error Slack::Web::Api::Errors::SlackError, 'user_not_found'
37
+ expect { users.users_id(user: '@foo') }.to(
38
+ raise_error(Slack::Web::Api::Errors::SlackError, 'user_not_found')
39
+ )
32
40
  end
33
41
  end
42
+
34
43
  if defined?(Picky)
35
44
  context '#users_search' do
36
45
  it 'finds a user' do
37
- expect(subject.users_search(user: 'aws')).to eq('ok' => true, 'members' => [{ 'id' => 'UDEADBEEF', 'name' => 'aws', 'profile' => {} }])
46
+ expect(users.users_search(user: 'aws')).to(
47
+ eq('ok' => true, 'members' => [{ 'id' => 'UDEADBEEF', 'name' => 'aws', 'profile' => {} }])
48
+ )
38
49
  end
39
50
  end
40
51
  end
@@ -1,21 +1,29 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  RSpec.describe Slack::Web::Api::Pagination::Cursor do
4
5
  let(:client) { Slack::Web::Client.new }
6
+
5
7
  context 'default cursor' do
6
- let(:cursor) { Slack::Web::Api::Pagination::Cursor.new(client, 'users_list', {}) }
8
+ let(:cursor) { described_class.new(client, 'users_list', {}) }
9
+
7
10
  it 'provides a default limit' do
8
- expect(client).to receive(:users_list).with(limit: 100, cursor: nil)
11
+ expect(client).to receive(:users_list).with({ limit: 100, cursor: nil })
9
12
  cursor.first
10
13
  end
14
+
11
15
  it 'handles blank response metadata' do
12
16
  expect(client).to receive(:users_list).once.and_return(Slack::Messages::Message.new)
13
17
  cursor.to_a
14
18
  end
19
+
15
20
  it 'handles nil response metadata' do
16
- expect(client).to receive(:users_list).once.and_return(Slack::Messages::Message.new(response_metadata: nil))
21
+ expect(client).to(
22
+ receive(:users_list).once.and_return(Slack::Messages::Message.new(response_metadata: nil))
23
+ )
17
24
  cursor.to_a
18
25
  end
26
+
19
27
  it 'paginates with a cursor inside response metadata' do
20
28
  expect(client).to receive(:users_list).twice.and_return(
21
29
  Slack::Messages::Message.new(response_metadata: { next_cursor: 'next' }),
@@ -24,39 +32,63 @@ RSpec.describe Slack::Web::Api::Pagination::Cursor do
24
32
  expect(cursor).not_to receive(:sleep)
25
33
  cursor.to_a
26
34
  end
35
+
27
36
  context 'with rate limiting' do
28
- let(:error) { Slack::Web::Api::Errors::TooManyRequestsError.new(nil) }
37
+ let(:error) { Slack::Web::Api::Errors::TooManyRequestsError.new(OpenStruct.new(headers: { 'retry-after' => 9 })) }
38
+
29
39
  context 'with default max retries' do
30
40
  it 'sleeps after a TooManyRequestsError' do
31
- expect(client).to receive(:users_list).with(limit: 100, cursor: nil).ordered.and_return(Slack::Messages::Message.new(response_metadata: { next_cursor: 'next' }))
32
- expect(client).to receive(:users_list).with(limit: 100, cursor: 'next').ordered.and_raise(error)
33
- expect(error).to receive(:retry_after).once.ordered.and_return(9)
41
+ expect(client).to(
42
+ receive(:users_list)
43
+ .with({ limit: 100, cursor: nil })
44
+ .ordered
45
+ .and_return(Slack::Messages::Message.new(response_metadata: { next_cursor: 'next' }))
46
+ )
47
+ expect(client).to(
48
+ receive(:users_list).with({ limit: 100, cursor: 'next' }).ordered.and_raise(error)
49
+ )
34
50
  expect(cursor).to receive(:sleep).once.ordered.with(9)
35
- expect(client).to receive(:users_list).with(limit: 100, cursor: 'next').ordered.and_return(Slack::Messages::Message.new)
51
+ expect(client).to(
52
+ receive(:users_list)
53
+ .with({ limit: 100, cursor: 'next' })
54
+ .ordered
55
+ .and_return(Slack::Messages::Message.new)
56
+ )
36
57
  cursor.to_a
37
58
  end
38
59
  end
60
+
39
61
  context 'with a custom max_retries' do
40
- let(:cursor) { Slack::Web::Api::Pagination::Cursor.new(client, 'users_list', max_retries: 4) }
62
+ let(:cursor) { described_class.new(client, 'users_list', max_retries: 4) }
63
+
41
64
  it 'raises the error after hitting the max retries' do
42
- expect(client).to receive(:users_list).with(limit: 100, cursor: nil).and_return(Slack::Messages::Message.new(response_metadata: { next_cursor: 'next' }))
43
- expect(client).to receive(:users_list).with(limit: 100, cursor: 'next').exactly(5).times.and_raise(error)
44
- expect(error).to receive(:retry_after).exactly(4).times.and_return(9)
65
+ expect(client).to(
66
+ receive(:users_list)
67
+ .with({ limit: 100, cursor: nil })
68
+ .and_return(Slack::Messages::Message.new(response_metadata: { next_cursor: 'next' }))
69
+ )
70
+ expect(client).to(
71
+ receive(:users_list).with({ limit: 100, cursor: 'next' }).exactly(5).times.and_raise(error)
72
+ )
45
73
  expect(cursor).to receive(:sleep).exactly(4).times.with(9)
46
74
  expect { cursor.to_a }.to raise_error(error)
47
75
  end
48
76
  end
49
77
  end
50
78
  end
79
+
51
80
  context 'with a custom limit' do
52
- let(:cursor) { Slack::Web::Api::Pagination::Cursor.new(client, 'users_list', limit: 42) }
81
+ let(:cursor) { described_class.new(client, 'users_list', limit: 42) }
82
+
53
83
  it 'overrides default limit' do
54
- expect(client).to receive(:users_list).with(limit: 42, cursor: nil)
84
+ expect(client).to receive(:users_list).with({ limit: 42, cursor: nil })
55
85
  cursor.first
56
86
  end
57
87
  end
88
+
58
89
  context 'with a custom sleep_interval' do
59
- let(:cursor) { Slack::Web::Api::Pagination::Cursor.new(client, 'users_list', sleep_interval: 3) }
90
+ let(:cursor) { described_class.new(client, 'users_list', sleep_interval: 3) }
91
+
60
92
  it 'sleeps between requests' do
61
93
  expect(client).to receive(:users_list).exactly(3).times.and_return(
62
94
  Slack::Messages::Message.new(response_metadata: { next_cursor: 'next_a' }),
@@ -1,16 +1,21 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
3
+ require 'faraday/typhoeus'
2
4
 
3
5
  RSpec.describe Slack::Web::Client do
4
6
  before do
5
7
  Slack::Config.reset
6
8
  end
9
+
7
10
  context 'with defaults' do
8
- let(:client) { Slack::Web::Client.new }
11
+ let(:client) { described_class.new }
12
+
9
13
  describe '#initialize' do
10
14
  it 'sets user-agent' do
11
15
  expect(client.user_agent).to eq Slack::Web::Config.user_agent
12
16
  expect(client.user_agent).to include Slack::VERSION
13
17
  end
18
+
14
19
  (Slack::Web::Config::ATTRIBUTES - [:logger]).each do |key|
15
20
  it "sets #{key}" do
16
21
  expect(client.send(key)).to eq Slack::Web::Config.send(key)
@@ -18,34 +23,41 @@ RSpec.describe Slack::Web::Client do
18
23
  end
19
24
  end
20
25
  end
26
+
21
27
  context 'with custom settings' do
22
28
  describe '#initialize' do
23
29
  Slack::Web::Config::ATTRIBUTES.each do |key|
24
- context key do
25
- let(:client) { Slack::Web::Client.new(key => 'custom') }
30
+ context key.to_s do
31
+ let(:client) { described_class.new(key => 'custom') }
32
+
26
33
  it "sets #{key}" do
27
- expect(client.send(key)).to_not eq Slack::Web::Config.send(key)
34
+ expect(client.send(key)).not_to eq Slack::Web::Config.send(key)
28
35
  expect(client.send(key)).to eq 'custom'
29
36
  end
30
37
  end
31
38
  end
32
39
  end
33
40
  end
41
+
34
42
  context 'global config' do
35
43
  after do
36
- Slack::Web::Client.config.reset
44
+ described_class.config.reset
37
45
  end
38
- let(:client) { Slack::Web::Client.new }
46
+
47
+ let(:client) { described_class.new }
48
+
39
49
  context 'user-agent' do
40
50
  before do
41
- Slack::Web::Client.configure do |config|
51
+ described_class.configure do |config|
42
52
  config.user_agent = 'custom/user-agent'
43
53
  end
44
54
  end
55
+
45
56
  describe '#initialize' do
46
57
  it 'sets user-agent' do
47
58
  expect(client.user_agent).to eq 'custom/user-agent'
48
59
  end
60
+
49
61
  it 'creates a connection with the custom user-agent' do
50
62
  expect(client.send(:connection).headers).to eq(
51
63
  'Accept' => 'application/json; charset=utf-8',
@@ -54,59 +66,70 @@ RSpec.describe Slack::Web::Client do
54
66
  end
55
67
  end
56
68
  end
69
+
57
70
  context 'token' do
58
71
  before do
59
72
  Slack.configure do |config|
60
73
  config.token = 'global default'
61
74
  end
62
75
  end
76
+
63
77
  it 'defaults token to global default' do
64
- client = Slack::Web::Client.new
78
+ client = described_class.new
65
79
  expect(client.token).to eq 'global default'
66
80
  end
81
+
67
82
  context 'with web config' do
68
83
  before do
69
- Slack::Web::Client.configure do |config|
84
+ described_class.configure do |config|
70
85
  config.token = 'custom web token'
71
86
  end
72
87
  end
88
+
73
89
  it 'overrides token to web config' do
74
- client = Slack::Web::Client.new
90
+ client = described_class.new
75
91
  expect(client.token).to eq 'custom web token'
76
92
  end
93
+
77
94
  it 'overrides token to specific token' do
78
- client = Slack::Web::Client.new(token: 'local token')
95
+ client = described_class.new(token: 'local token')
79
96
  expect(client.token).to eq 'local token'
80
97
  end
81
98
  end
82
99
  end
100
+
83
101
  context 'proxy' do
84
102
  before do
85
- Slack::Web::Client.configure do |config|
103
+ described_class.configure do |config|
86
104
  config.proxy = 'http://localhost:8080'
87
105
  end
88
106
  end
107
+
89
108
  describe '#initialize' do
90
109
  it 'sets proxy' do
91
110
  expect(client.proxy).to eq 'http://localhost:8080'
92
111
  end
112
+
93
113
  it 'creates a connection with the proxy' do
94
114
  expect(client.send(:connection).proxy.uri.to_s).to eq 'http://localhost:8080'
95
115
  end
96
116
  end
97
117
  end
118
+
98
119
  context 'SSL options' do
99
120
  before do
100
- Slack::Web::Client.configure do |config|
121
+ described_class.configure do |config|
101
122
  config.ca_path = '/ca_path'
102
123
  config.ca_file = '/ca_file'
103
124
  end
104
125
  end
126
+
105
127
  describe '#initialize' do
106
128
  it 'sets ca_path and ca_file' do
107
129
  expect(client.ca_path).to eq '/ca_path'
108
130
  expect(client.ca_file).to eq '/ca_file'
109
131
  end
132
+
110
133
  it 'creates a connection with ssl options' do
111
134
  ssl = client.send(:connection).ssl
112
135
  expect(ssl.ca_path).to eq '/ca_path'
@@ -114,34 +137,87 @@ RSpec.describe Slack::Web::Client do
114
137
  end
115
138
  end
116
139
  end
140
+
117
141
  context 'logger option' do
118
142
  let(:logger) { Logger.new(STDOUT) }
143
+
119
144
  before do
120
- Slack::Web::Client.configure do |config|
145
+ described_class.configure do |config|
121
146
  config.logger = logger
122
147
  end
123
148
  end
149
+
124
150
  describe '#initialize' do
125
151
  it 'sets logger' do
126
152
  expect(client.logger).to eq logger
127
153
  end
154
+
128
155
  it 'creates a connection with a logger' do
129
156
  expect(client.send(:connection).builder.handlers).to include ::Faraday::Response::Logger
130
157
  end
131
158
  end
132
159
  end
160
+
161
+ context 'adapter option' do
162
+ let(:adapter) { Faraday.default_adapter }
163
+ let(:adapter_class) { Faraday::Adapter::NetHttp }
164
+
165
+ around do |ex|
166
+ previous_adapter = Faraday.default_adapter
167
+ # ensure default adapter is set for this spec
168
+ Faraday.default_adapter = :net_http
169
+ ex.run
170
+ Faraday.default_adapter = previous_adapter
171
+ end
172
+
173
+ context 'default adapter' do
174
+ describe '#initialize' do
175
+ it 'sets adapter' do
176
+ expect(client.adapter).to eq adapter
177
+ end
178
+
179
+ it 'creates a connection with an adapter' do
180
+ expect(client.send(:connection).adapter).to eq adapter_class
181
+ end
182
+ end
183
+ end
184
+
185
+ context 'non default adapter' do
186
+ let(:adapter) { :typhoeus }
187
+ let(:adapter_class) { Faraday::Adapter::Typhoeus }
188
+
189
+ before do
190
+ described_class.configure do |config|
191
+ config.adapter = adapter
192
+ end
193
+ end
194
+
195
+ describe '#initialize' do
196
+ it 'sets adapter' do
197
+ expect(client.adapter).to eq adapter
198
+ end
199
+
200
+ it 'creates a connection with an adapter' do
201
+ expect(client.send(:connection).adapter).to eq adapter_class
202
+ end
203
+ end
204
+ end
205
+ end
206
+
133
207
  context 'timeout options' do
134
208
  before do
135
- Slack::Web::Client.configure do |config|
209
+ described_class.configure do |config|
136
210
  config.timeout = 10
137
211
  config.open_timeout = 15
138
212
  end
139
213
  end
214
+
140
215
  describe '#initialize' do
141
216
  it 'sets timeout and open_timeout' do
142
217
  expect(client.timeout).to eq 10
143
218
  expect(client.open_timeout).to eq 15
144
219
  end
220
+
145
221
  it 'creates a connection with timeout options' do
146
222
  conn = client.send(:connection)
147
223
  expect(conn.options.timeout).to eq 10
@@ -149,34 +225,135 @@ RSpec.describe Slack::Web::Client do
149
225
  end
150
226
  end
151
227
  end
228
+
152
229
  context 'per-request options' do
153
- it 'applies timeout', vcr: { cassette_name: 'web/rtm_start', allow_playback_repeats: true } do
230
+ it 'applies timeout', vcr: { cassette_name: 'web/rtm_connect', allow_playback_repeats: true } do
154
231
  # reuse the same connection for the test, otherwise it creates a new one every time
155
232
  conn = client.send(:connection)
156
233
  expect(client).to receive(:connection).and_return(conn)
157
234
 
158
- # get the yielded request to reuse in the next call to rtm_start so that we can examine request.options later
235
+ # get the yielded request to reuse in the next call to
236
+ # rtm.connect so that we can examine request.options later
159
237
  request = nil
160
238
  response = conn.post do |r|
161
- r.path = 'rtm.start'
162
- r.body = { token: 'token' }
239
+ r.path = 'rtm.connect'
240
+ r.headers = {
241
+ 'Accept' => ['application/json; charset=utf-8'],
242
+ 'Authorization' => ['Bearer <SLACK_API_TOKEN>']
243
+ }
163
244
  request = r
164
245
  end
165
246
 
166
247
  expect(conn).to receive(:post).and_yield(request).and_return(response)
167
248
 
168
- client.rtm_start(request: { timeout: 3 })
249
+ client.rtm_connect(request: { timeout: 3 })
169
250
 
170
251
  expect(request.options.timeout).to eq 3
171
252
  end
172
253
  end
254
+
173
255
  context 'calling undocumented methods' do
174
- let(:client) { Slack::Web::Client.new }
256
+ let(:client) { described_class.new }
257
+
175
258
  it 'produces a warning' do
176
- expect(client.logger).to receive(:warn).with('The users.admin.setInactive method is undocumented.')
259
+ expect(client.logger).to(
260
+ receive(:warn).with('The users.admin.setInactive method is undocumented.')
261
+ )
177
262
  expect(client).to receive(:post)
178
263
  client.users_admin_setInactive(user: 'U092BDCLV')
179
264
  end
180
265
  end
266
+
267
+ context 'persistent capability' do
268
+ describe '#initialize' do
269
+ it 'caches the Faraday connection to allow persistent adapters' do
270
+ first = client.send(:connection)
271
+ second = client.send(:connection)
272
+
273
+ expect(first).to equal second
274
+ end
275
+ end
276
+ end
277
+
278
+ context 'server failures' do
279
+ subject(:request) { client.api_test }
280
+
281
+ let(:stub_slack_request) { stub_request(:post, 'https://slack.com/api/api.test') }
282
+ let(:exception) do
283
+ request
284
+ rescue Slack::Web::Api::Errors::ServerError => e
285
+ return e
286
+ end
287
+
288
+ context 'parsing error' do
289
+ context 'when the response is not JSON' do
290
+ before do
291
+ stub_slack_request.to_return(body: '<html></html>', headers: { 'Content-Type' => 'text/html' })
292
+ end
293
+
294
+ it 'raises ParsingError' do
295
+ expect { request }.to raise_error(Slack::Web::Api::Errors::ParsingError).with_message('parsing_error')
296
+ expect(exception.response.body).to eq('<html></html>')
297
+ expect(exception.cause).to be_a(Faraday::ParsingError)
298
+ expect(exception.cause.cause).to be_a(JSON::ParserError)
299
+ end
300
+ end
301
+
302
+ context 'when the response is malformed JSON' do
303
+ before { stub_slack_request.to_return(body: '{') }
304
+
305
+ it 'raises ParsingError' do
306
+ expect { request }.to raise_error(Slack::Web::Api::Errors::ParsingError).with_message('parsing_error')
307
+ expect(exception.response.body).to eq('{')
308
+ expect(exception.cause).to be_a(Faraday::ParsingError)
309
+ expect(exception.cause.cause).to be_a(JSON::ParserError)
310
+ end
311
+ end
312
+ end
313
+
314
+ context 'timeout' do
315
+ context 'open timeout' do
316
+ before { stub_slack_request.to_timeout }
317
+
318
+ it 'raises TimoutError' do
319
+ expect { request }.to raise_error(Slack::Web::Api::Errors::TimeoutError).with_message('timeout_error')
320
+ expect(exception.cause).to be_a(Faraday::ConnectionFailed)
321
+ expect(exception.cause.cause).to be_a(Net::OpenTimeout)
322
+ end
323
+ end
324
+
325
+ context 'read timeout' do
326
+ before { stub_slack_request.to_raise(Net::ReadTimeout) }
327
+
328
+ it 'raises TimeoutError' do
329
+ expect { request }.to raise_error(Slack::Web::Api::Errors::TimeoutError).with_message('timeout_error')
330
+ expect(exception.cause).to be_a(Faraday::TimeoutError)
331
+ expect(exception.cause.cause).to be_a(Net::ReadTimeout)
332
+ end
333
+ end
334
+ end
335
+
336
+ context '5xx response' do
337
+ context 'with a JSON body' do
338
+ before { stub_slack_request.to_return(status: 500, body: '{}') }
339
+
340
+ it 'raises UnavailableError' do
341
+ expect { request }.to raise_error(Slack::Web::Api::Errors::UnavailableError).with_message('unavailable_error')
342
+ expect(exception.response.status).to eq(500)
343
+ end
344
+ end
345
+
346
+ context 'with a HTML response' do
347
+ before do
348
+ stub_slack_request.to_return(status: 500, body: '<html></html>', headers: { 'Content-Type' => 'text/html' })
349
+ end
350
+
351
+ it 'raises UnavailableError' do
352
+ expect { request }.to raise_error(Slack::Web::Api::Errors::UnavailableError).with_message('unavailable_error')
353
+ expect(exception.response.status).to eq(500)
354
+ end
355
+ end
356
+ end
357
+ end
181
358
  end
182
359
  end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ class DummyClient
5
+ include Slack::Web::Faraday::Connection
6
+ include Slack::Web::Faraday::Request
7
+
8
+ attr_reader :token
9
+
10
+ def initialize(token)
11
+ @token = token
12
+ end
13
+ end
14
+
15
+ RSpec.describe Slack::Web::Faraday::Request do
16
+ let(:token) { 'by-the-power-of-grayskull' }
17
+ let(:client) { DummyClient.new(token) }
18
+
19
+ before do
20
+ Slack::Config.reset
21
+ end
22
+
23
+ context 'authorization' do
24
+ let(:path) { '/any-path' }
25
+ let(:options) { {} }
26
+ let(:connection) { instance_double('Faraday::Connection') }
27
+ let(:request) { instance_double('Faraday::Request') }
28
+ let(:headers) { instance_double('Faraday::Utils::Headers') }
29
+ let(:response) { instance_double('Faraday::Response', body: '') }
30
+
31
+ before do
32
+ allow(client).to receive(:connection).and_return(connection)
33
+ allow(request).to receive(:url).with(path, options)
34
+ allow(request).to receive(:path=).with(path)
35
+ allow(request).to receive(:headers).and_return(headers)
36
+ allow(connection).to receive(:send)
37
+ .with(method).and_yield(request).and_return(response)
38
+ end
39
+
40
+ describe '#get' do
41
+ let(:method) { :get }
42
+
43
+ it 'sets authorization header' do
44
+ expect(headers).to receive(:[]=)
45
+ .with('Authorization', "Bearer #{token}")
46
+ client.send(method, path, options)
47
+ end
48
+ end
49
+
50
+ describe '#post' do
51
+ let(:method) { :post }
52
+
53
+ it 'sets authorization header' do
54
+ expect(headers).to receive(:[]=)
55
+ .with('Authorization', "Bearer #{token}")
56
+ client.send(method, path, options)
57
+ end
58
+ end
59
+
60
+ describe '#put' do
61
+ let(:method) { :put }
62
+
63
+ it 'sets authorization header' do
64
+ expect(headers).to receive(:[]=)
65
+ .with('Authorization', "Bearer #{token}")
66
+ client.send(method, path, options)
67
+ end
68
+ end
69
+
70
+ describe '#delete' do
71
+ let(:method) { :delete }
72
+
73
+ it 'sets authorization header' do
74
+ expect(headers).to receive(:[]=)
75
+ .with('Authorization', "Bearer #{token}")
76
+ client.send(method, path, options)
77
+ end
78
+ end
79
+ end
80
+ end