grape-slack-bot 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,479 @@
1
+ require 'spec_helper'
2
+
3
+ describe SlackBot::ApiClient do
4
+ subject(:client) { described_class.new(authorization_token: authorization_token) }
5
+ let(:authorization_token) { "test_authorization_token" }
6
+
7
+ it "does not raise errors" do
8
+ expect { client }.not_to raise_error
9
+ end
10
+
11
+ context "when the authorization token is not set" do
12
+ let(:authorization_token) { nil }
13
+ it "raises an error" do
14
+ expect { client }.to raise_error("Slack bot API token is not set")
15
+ end
16
+ end
17
+
18
+ describe "#users_info" do
19
+ before do
20
+ stub_request(:post, "https://slack.com/api/users.info").to_return(response)
21
+ end
22
+ subject(:users_info) { client.users_info(user_id: user_id) }
23
+ let(:user_id) { "U0R7JM" }
24
+ let(:response) {
25
+ {
26
+ status: 200,
27
+ body: {
28
+ "ok" => true,
29
+ "user" => {
30
+ "id" => "W012A3CDE",
31
+ "team_id" => "T012AB3C4",
32
+ "name" => "spengler",
33
+ "deleted" => false,
34
+ "color" => "9f69e7",
35
+ "real_name" => "Egon Spengler",
36
+ "tz" => "America/Los_Angeles",
37
+ "tz_label" => "Pacific Daylight Time",
38
+ "tz_offset" => -25200,
39
+ "profile" => {
40
+ "avatar_hash" => "ge3b51ca72de",
41
+ "status_text" => "Print is dead",
42
+ "status_emoji" => ":books:",
43
+ "real_name" => "Egon Spengler",
44
+ "display_name" => "spengler",
45
+ "real_name_normalized" => "Egon Spengler",
46
+ "display_name_normalized" => "spengler",
47
+ "email" => "spengler@ghostbusters.example.com",
48
+ "image_original" => "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
49
+ "image_24" => "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
50
+ "image_32" => "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
51
+ "image_48" => "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
52
+ "image_72" => "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
53
+ "image_192" => "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
54
+ "image_512" => "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
55
+ "team" => "T012AB3C4"
56
+ },
57
+ "is_admin" => true,
58
+ "is_owner" => false,
59
+ "is_primary_owner" => false,
60
+ "is_restricted" => false,
61
+ "is_ultra_restricted" => false,
62
+ "is_bot" => false,
63
+ "updated" => 1502138686,
64
+ "is_app_user" => false,
65
+ "has_2fa" => false
66
+ }
67
+ }.to_json
68
+ }
69
+ }
70
+ it "sends authorization token" do
71
+ expect(users_info.response.env.request_headers["Authorization"]).to eq("Bearer #{authorization_token}")
72
+ end
73
+ it "returns a successful response" do
74
+ expect(users_info.ok?).to eq(true)
75
+ end
76
+ context "when the response is not successful" do
77
+ let(:response) {
78
+ {
79
+ status: 200,
80
+ body: {
81
+ "ok" => false,
82
+ "error" => "user_not_found"
83
+ }.to_json
84
+ }
85
+ }
86
+ it "returns an unsuccessful response" do
87
+ expect(users_info.ok?).to eq(false)
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "#views_open" do
93
+ before do
94
+ stub_request(:post, "https://slack.com/api/views.open").to_return(response)
95
+ end
96
+ subject(:views_open) {
97
+ client.views_open(
98
+ trigger_id: "trigger_id",
99
+ view: {
100
+ "type" => "modal",
101
+ "title" => {
102
+ "type" => "plain_text",
103
+ "text" => "Quite a plain modal"
104
+ },
105
+ "submit" => {
106
+ "type" => "plain_text",
107
+ "text" => "Create"
108
+ },
109
+ "blocks" => [
110
+ {
111
+ "type" => "input",
112
+ "block_id" => "a_block_id",
113
+ "label" => [
114
+ "type" => "plain_text",
115
+ "text" => "A simple label",
116
+ "emoji" => true
117
+ ],
118
+ "optional" => false,
119
+ "element" => {
120
+ "type" => "plain_text_input",
121
+ "action_id" => "an_action_id"
122
+ }
123
+ }
124
+ ],
125
+ }
126
+ )
127
+ }
128
+ let(:response) {
129
+ {
130
+ status: 200,
131
+ body: {
132
+ "ok" => true,
133
+ "view" => {
134
+ "id" => "VMHU10V25",
135
+ "team_id" => "T8N4K1JN",
136
+ "type" => "modal",
137
+ "title" => {
138
+ "type" => "plain_text",
139
+ "text" => "Quite a plain modal"
140
+ },
141
+ "submit" => {
142
+ "type" => "plain_text",
143
+ "text" => "Create"
144
+ },
145
+ "blocks" => [
146
+ {
147
+ "type" => "input",
148
+ "block_id" => "a_block_id",
149
+ "label" => {
150
+ "type" => "plain_text",
151
+ "text" => "A simple label",
152
+ "emoji" => true
153
+ },
154
+ "optional" => false,
155
+ "element" => {
156
+ "type" => "plain_text_input",
157
+ "action_id" => "an_action_id"
158
+ }
159
+ }
160
+ ],
161
+ "private_metadata" => "Shh it is a secret",
162
+ "callback_id" => "identify_your_modals",
163
+ "external_id" => "",
164
+ "state" => {
165
+ "values" => {}
166
+ },
167
+ "hash" => "156772938.1827394",
168
+ "clear_on_close" => false,
169
+ "notify_on_close" => false,
170
+ "root_view_id" => "VMHU10V25",
171
+ "app_id" => "AA4928AQ",
172
+ "bot_id" => "BA13894H"
173
+ }
174
+ }.to_json
175
+ }
176
+ }
177
+ it "returns a successful response" do
178
+ expect(views_open.ok?).to eq(true)
179
+ end
180
+
181
+ context "when the response is unsuccessful" do
182
+ let(:response) {
183
+ {
184
+ status: 200,
185
+ body: {
186
+ "ok" => false,
187
+ "error" => "invalid_arguments",
188
+ "response_metadata" => {
189
+ "messages" => [
190
+ "invalid `trigger_id`"
191
+ ]
192
+ }
193
+ }.to_json
194
+ }
195
+ }
196
+ it "returns an unsuccessful response" do
197
+ expect(views_open.ok?).to eq(false)
198
+ end
199
+ end
200
+ end
201
+
202
+ describe "#views_update" do
203
+ before do
204
+ stub_request(:post, "https://slack.com/api/views.update").to_return(response)
205
+ end
206
+ subject(:views_update) {
207
+ client.views_update(
208
+ view_id: "VMHU10V25",
209
+ view: {
210
+ "type" => "modal",
211
+ "title" => {
212
+ "type" => "plain_text",
213
+ "text" => "Quite a plain modal"
214
+ },
215
+ "submit" => {
216
+ "type" => "plain_text",
217
+ "text" => "Create"
218
+ },
219
+ "blocks" => [
220
+ {
221
+ "type" => "input",
222
+ "block_id" => "a_block_id",
223
+ "label" => [
224
+ "type" => "plain_text",
225
+ "text" => "A simple label",
226
+ "emoji" => true
227
+ ],
228
+ "optional" => false,
229
+ "element" => {
230
+ "type" => "plain_text_input",
231
+ "action_id" => "an_action_id"
232
+ }
233
+ }
234
+ ],
235
+ }
236
+ )
237
+ }
238
+ let(:response) {
239
+ {
240
+ status: 200,
241
+ body: {
242
+ "ok" => true,
243
+ "view" => {
244
+ "id" => "VMHU10V25",
245
+ "team_id" => "T8N4K1JN",
246
+ "type" => "modal",
247
+ "title" => {
248
+ "type" => "plain_text",
249
+ "text" => "Quite a plain modal"
250
+ },
251
+ "submit" => {
252
+ "type" => "plain_text",
253
+ "text" => "Create"
254
+ },
255
+ "blocks" => [
256
+ {
257
+ "type" => "input",
258
+ "block_id" => "a_block_id",
259
+ "label" => {
260
+ "type" => "plain_text",
261
+ "text" => "A simple label",
262
+ "emoji" => true
263
+ },
264
+ "optional" => false,
265
+ "element" => {
266
+ "type" => "plain_text_input",
267
+ "action_id" => "an_action_id"
268
+ }
269
+ }
270
+ ],
271
+ "private_metadata" => "Shh it is a secret",
272
+ "callback_id" => "identify_your_modals",
273
+ "external_id" => "",
274
+ "state" => {
275
+ "values" => {}
276
+ },
277
+ "hash" => "156772938.1827394",
278
+ "clear_on_close" => false,
279
+ "notify_on_close" => false,
280
+ "root_view_id" => "VMHU10V25",
281
+ "app_id" => "AA4928AQ",
282
+ "bot_id" => "BA13894H"
283
+ }
284
+ }.to_json
285
+ }
286
+ }
287
+ it "returns a successful response" do
288
+ expect(views_update.ok?).to eq(true)
289
+ end
290
+ context "when the response is unsuccessful" do
291
+ let(:response) {
292
+ {
293
+ status: 200,
294
+ body: {
295
+ "ok" => false,
296
+ "error" => "invalid_arguments",
297
+ "response_metadata" => {
298
+ "messages" => [
299
+ "invalid `trigger_id`"
300
+ ]
301
+ }
302
+ }.to_json
303
+ }
304
+ }
305
+ it "returns an unsuccessful response" do
306
+ expect(views_update.ok?).to eq(false)
307
+ end
308
+ end
309
+ end
310
+
311
+ describe "#chat_post_message" do
312
+ before do
313
+ stub_request(:post, "https://slack.com/api/chat.postMessage").to_return(response)
314
+ end
315
+ subject(:chat_post_message) {
316
+ client.chat_post_message(
317
+ channel: "C1234567890",
318
+ text: "Hello world",
319
+ blocks: [
320
+ {
321
+ "type" => "section",
322
+ "text" => {
323
+ "type" => "mrkdwn",
324
+ "text" => "Hello world"
325
+ }
326
+ }
327
+ ]
328
+ )
329
+ }
330
+ let(:response) {
331
+ {
332
+ status: 200,
333
+ body: {
334
+ "ok" => true,
335
+ "channel" => "C1234567890",
336
+ "ts" => "1503435956.000247",
337
+ "message" => {
338
+ "text" => "Hello world",
339
+ "username" => "ecto1",
340
+ "bot_id" => "B19LU7CSY",
341
+ "attachments" => [
342
+ {
343
+ "text" => "This is an attachment",
344
+ "id" => 1,
345
+ "fallback" => "This is an attachment's fallback"
346
+ }
347
+ ],
348
+ "type" => "message",
349
+ "subtype" => "bot_message",
350
+ "ts" => "1503435956.000247"
351
+ }
352
+ }.to_json
353
+ }
354
+ }
355
+ it "returns a successful response" do
356
+ expect(chat_post_message.ok?).to eq(true)
357
+ end
358
+ context "when the response is unsuccessful" do
359
+ let(:response) {
360
+ {
361
+ status: 200,
362
+ body: {
363
+ "ok" => false,
364
+ "error" => "too_many_attachments"
365
+ }.to_json
366
+ }
367
+ }
368
+ it "returns an unsuccessful response" do
369
+ expect(chat_post_message.ok?).to eq(false)
370
+ end
371
+ end
372
+ end
373
+
374
+ describe "#chat_update" do
375
+ before do
376
+ stub_request(:post, "https://slack.com/api/chat.update").to_return(response)
377
+ end
378
+ subject(:chat_update) {
379
+ client.chat_update(
380
+ channel: "C1234567890",
381
+ ts: "1503435956.000247",
382
+ text: "Hello world",
383
+ blocks: [
384
+ {
385
+ "type" => "section",
386
+ "text" => {
387
+ "type" => "mrkdwn",
388
+ "text" => "Hello world"
389
+ }
390
+ }
391
+ ]
392
+ )
393
+ }
394
+ let(:response) {
395
+ {
396
+ status: 200,
397
+ body: {
398
+ "ok" => true,
399
+ "channel" => "C1234567890",
400
+ "ts" => "1503435956.000247",
401
+ "message" => {
402
+ "text" => "Hello world",
403
+ "username" => "ecto1",
404
+ "bot_id" => "B19LU7CSY",
405
+ "attachments" => [
406
+ {
407
+ "text" => "This is an attachment",
408
+ "id" => 1,
409
+ "fallback" => "This is an attachment's fallback"
410
+ }
411
+ ],
412
+ "type" => "message",
413
+ "subtype" => "bot_message",
414
+ "ts" => "1503435956.000247"
415
+ }
416
+ }.to_json
417
+ }
418
+ }
419
+ it "returns a successful response" do
420
+ expect(chat_update.ok?).to eq(true)
421
+ end
422
+ context "when the response is unsuccessful" do
423
+ let(:response) {
424
+ {
425
+ status: 200,
426
+ body: {
427
+ "ok" => false,
428
+ "error" => "too_many_attachments"
429
+ }.to_json
430
+ }
431
+ }
432
+ it "returns an unsuccessful response" do
433
+ expect(chat_update.ok?).to eq(false)
434
+ end
435
+ end
436
+ end
437
+
438
+ describe "#views_publish" do
439
+ before do
440
+ stub_request(:post, "https://slack.com/api/views.publish").to_return(response)
441
+ end
442
+ subject(:views_publish) {
443
+ client.views_publish(
444
+ user_id: "U0R7JM",
445
+ view: {
446
+ "type" => "home",
447
+ "blocks" => [
448
+ {
449
+ "type" => "section",
450
+ "text" => {
451
+ "type" => "mrkdwn",
452
+ "text" => "Welcome to your _App's Home_* :tada:"
453
+ }
454
+ },
455
+ {
456
+ "type" => "divider"
457
+ },
458
+ {
459
+ "type" => "section",
460
+ "text" => {
461
+ "type" => "mrkdwn",
462
+ "text" => "This is a section block with a button."
463
+ },
464
+ "accessory" => {
465
+ "type" => "button",
466
+ "text" => {
467
+ "type" => "plain_text",
468
+ "text" => "Click Me"
469
+ },
470
+ "action_id" => "button_click"
471
+ }
472
+ }
473
+ ]
474
+ }
475
+ )
476
+ }
477
+ # TODO: Add a test for the response
478
+ end
479
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe SlackBot::Args do
4
+ let(:args) { SlackBot::Args.new }
5
+ let(:raw_args) { "foo=bar&baz=qux" }
6
+
7
+ describe "#raw_args=" do
8
+ it "parses raw args" do
9
+ args.raw_args = raw_args
10
+ expect(args.args).to eq({ "foo" => "bar", "baz" => "qux" }.with_indifferent_access)
11
+ end
12
+ end
13
+
14
+ describe "#to_s" do
15
+ it "builds args" do
16
+ args.raw_args = raw_args
17
+ expect(args.to_s).to eq(raw_args)
18
+ end
19
+ end
20
+
21
+ describe "#merge" do
22
+ it "merges args" do
23
+ args.raw_args = raw_args
24
+ expect(args.merge(foo: "baz").args).to eq({ "foo" => "baz", "baz" => "qux" }.with_indifferent_access)
25
+ end
26
+ end
27
+
28
+ describe "#except" do
29
+ it "removes args" do
30
+ args.raw_args = raw_args
31
+ expect(args.except(:foo).args).to eq({ "baz" => "qux" }.with_indifferent_access)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,104 @@
1
+ require 'spec_helper'
2
+
3
+ describe SlackBot::Callback do
4
+ subject(:callback) {
5
+ described_class.new(
6
+ class_name: "Test",
7
+ method_name: "test",
8
+ user: user,
9
+ channel_id: "test_channel_id",
10
+ extra: { test: "test" },
11
+ config: config
12
+ )
13
+ }
14
+
15
+ let(:config) {
16
+ instance_double(
17
+ SlackBot::Config,
18
+ callback_storage_instance: callback_storage_instance,
19
+ callback_user_finder_method: callback_user_finder_method
20
+ )
21
+ }
22
+ let(:callback_storage_instance) { instance_double(SlackBot::CallbackStorage) }
23
+ let(:callback_user_finder_method) { ->(user_id) { user } }
24
+
25
+ let(:user) { double(:user, id: 1) }
26
+
27
+ let(:callback_id) { "test_callback_id" }
28
+
29
+ describe ".find" do
30
+ subject(:find) { described_class.find(callback_id, config: config) }
31
+
32
+ before do
33
+ allow(callback_storage_instance).to receive(:read).with("slack-bot-callback:test_callback_id").and_return(data)
34
+ end
35
+
36
+ context "when callback is found" do
37
+ let(:data) { { class_name: "Test", method_name: "test", user_id: 1, channel_id: "test_channel_id", extra: { test: "test" } } }
38
+
39
+ it "returns callback" do
40
+ expect(find).to be_a(described_class)
41
+ expect(find.id).to eq(callback_id)
42
+ expect(find.class_name).to eq("Test")
43
+ expect(find.user).to eq(user)
44
+ expect(find.user_id).to eq(1)
45
+ expect(find.channel_id).to eq("test_channel_id")
46
+ expect(find.method_name).to eq("test")
47
+ expect(find.extra).to eq({ test: "test" })
48
+ end
49
+ end
50
+ end
51
+
52
+ describe ".create" do
53
+ subject(:create) { described_class.create(class_name: "Test", method_name: "test", user: user, channel_id: "test_channel_id", config: config) }
54
+
55
+ before do
56
+ allow_any_instance_of(described_class).to receive(:generate_id).and_return("test_callback_id")
57
+ allow(callback_storage_instance).to receive(:write).with("slack-bot-callback:test_callback_id", {
58
+ args: "",
59
+ class_name: "Test",
60
+ method_name: "test",
61
+ user_id: 1,
62
+ channel_id: "test_channel_id",
63
+ extra: nil
64
+ }, expires_in: 1.hour)
65
+ end
66
+
67
+ let(:data) { { class_name: "Test", method_name: "test", user_id: 1, channel_id: "test_channel_id", extra: nil } }
68
+
69
+ it "returns callback" do
70
+ expect(create).to be_a(described_class)
71
+ expect(create.id).to eq("test_callback_id")
72
+ expect(create.class_name).to eq("Test")
73
+ expect(create.user).to eq(user)
74
+ expect(create.user_id).to eq(1)
75
+ expect(create.channel_id).to eq("test_channel_id")
76
+ expect(create.method_name).to eq("test")
77
+ expect(create.extra).to eq(nil)
78
+ end
79
+ end
80
+
81
+ describe "#reload" do
82
+
83
+ end
84
+
85
+ describe "#save" do
86
+
87
+ end
88
+
89
+ describe "#update" do
90
+
91
+ end
92
+
93
+ describe "#destroy" do
94
+
95
+ end
96
+
97
+ describe "#user" do
98
+
99
+ end
100
+
101
+ describe "#handler_class" do
102
+
103
+ end
104
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe SlackBot::Command do
4
+
5
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe SlackBot::Config do
4
+ subject(:config) { described_class.new }
5
+
6
+ describe ".configure" do
7
+
8
+ end
9
+
10
+ describe ".current_instance" do
11
+
12
+ end
13
+
14
+ describe "#callback_storage" do
15
+
16
+ end
17
+
18
+ describe "#callback_user_finder" do
19
+
20
+ end
21
+
22
+ describe "#event" do
23
+
24
+ end
25
+
26
+ describe "#slash_command_endpoint" do
27
+
28
+ end
29
+
30
+ describe "#menu_options" do
31
+
32
+ end
33
+
34
+ describe "#handler_class" do
35
+
36
+ end
37
+
38
+ describe "#find_event_handler" do
39
+
40
+ end
41
+
42
+ describe "#find_slash_command_config" do
43
+
44
+ end
45
+
46
+ describe "#find_menu_options" do
47
+
48
+ end
49
+
50
+ describe "#find_handler_class" do
51
+
52
+ end
53
+
54
+ describe "#find_command_config" do
55
+
56
+ end
57
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe SlackBot::Event do
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe SlackBot::GrapeExtension do
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe SlackBot::Interaction do
4
+
5
+ end