laziness 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +22 -17
- data/README.md +14 -0
- data/lib/laziness/api/base.rb +8 -0
- data/lib/laziness/api/channels.rb +9 -3
- data/lib/laziness/api/conversations.rb +19 -11
- data/lib/laziness/api/groups.rb +9 -3
- data/lib/laziness/api/im.rb +6 -3
- data/lib/laziness/api/users.rb +6 -3
- data/lib/laziness/base.rb +8 -2
- data/lib/laziness/cursor.rb +60 -0
- data/lib/laziness/errors.rb +19 -0
- data/lib/laziness/pager.rb +32 -0
- data/lib/laziness/version.rb +1 -1
- data/lib/laziness.rb +2 -0
- data/spec/laziness/api/conversations_spec.rb +14 -0
- data/spec/laziness/base_spec.rb +20 -0
- data/spec/laziness/cursor_spec.rb +129 -0
- data/spec/laziness/errors_spec.rb +13 -0
- data/spec/laziness/message_spec.rb +8 -4
- data/spec/laziness/pager_spec.rb +60 -0
- data/spec/support/fixtures/conversations_list.json +4 -1
- data/spec/support/slack_stub_factory.rb +11 -2
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a76e439503c65d13c7c8ab8f00bdc5ee3d22dc06d60acf0ae8fe959808e63133
|
4
|
+
data.tar.gz: e6297370c3f3f22f01b468844d4ae79a3cd20e691c27d95e7471cc645133c66a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de5a77da3465d2a5a6ce098539c6802d515e6a57c1d88aafde8345f42448c747f0512bd6ead50c101a7ddbf90bc85bca5e65049059cfeb6e0989485eb60ecae1
|
7
|
+
data.tar.gz: 6f1b839c1a7d8235376564141a5323b050606870bd6907fa6909d57bbb77f1a1e4037c7937dcd798038296746ca458c22bd84d9509d37d2f84164a05a9f89be3
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
laziness (0.2.
|
4
|
+
laziness (0.2.5)
|
5
5
|
eventmachine
|
6
6
|
faye-websocket (>= 0.8.0)
|
7
7
|
hashie
|
@@ -10,14 +10,16 @@ PATH
|
|
10
10
|
GEM
|
11
11
|
remote: https://rubygems.org/
|
12
12
|
specs:
|
13
|
-
addressable (2.
|
14
|
-
|
13
|
+
addressable (2.6.0)
|
14
|
+
public_suffix (>= 2.0.2, < 4.0)
|
15
|
+
crack (0.4.3)
|
15
16
|
safe_yaml (~> 1.0.0)
|
16
|
-
diff-lcs (1.
|
17
|
+
diff-lcs (1.3)
|
17
18
|
eventmachine (1.2.7)
|
18
19
|
faye-websocket (0.10.7)
|
19
20
|
eventmachine (>= 0.12.0)
|
20
21
|
websocket-driver (>= 0.5.1)
|
22
|
+
hashdiff (0.3.8)
|
21
23
|
hashie (3.6.0)
|
22
24
|
httparty (0.16.4)
|
23
25
|
mime-types (~> 3.0)
|
@@ -26,23 +28,26 @@ GEM
|
|
26
28
|
mime-types-data (~> 3.2015)
|
27
29
|
mime-types-data (3.2018.0812)
|
28
30
|
multi_xml (0.6.0)
|
31
|
+
public_suffix (3.0.3)
|
29
32
|
rake (10.3.2)
|
30
|
-
rspec (3.
|
31
|
-
rspec-core (~> 3.
|
32
|
-
rspec-expectations (~> 3.
|
33
|
-
rspec-mocks (~> 3.
|
34
|
-
rspec-core (3.
|
35
|
-
rspec-support (~> 3.
|
36
|
-
rspec-expectations (3.
|
33
|
+
rspec (3.8.0)
|
34
|
+
rspec-core (~> 3.8.0)
|
35
|
+
rspec-expectations (~> 3.8.0)
|
36
|
+
rspec-mocks (~> 3.8.0)
|
37
|
+
rspec-core (3.8.0)
|
38
|
+
rspec-support (~> 3.8.0)
|
39
|
+
rspec-expectations (3.8.2)
|
37
40
|
diff-lcs (>= 1.2.0, < 2.0)
|
38
|
-
rspec-support (~> 3.
|
39
|
-
rspec-mocks (3.
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
rspec-support (~> 3.8.0)
|
42
|
+
rspec-mocks (3.8.0)
|
43
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
44
|
+
rspec-support (~> 3.8.0)
|
45
|
+
rspec-support (3.8.0)
|
46
|
+
safe_yaml (1.0.5)
|
47
|
+
webmock (3.5.1)
|
44
48
|
addressable (>= 2.3.6)
|
45
49
|
crack (>= 0.3.2)
|
50
|
+
hashdiff
|
46
51
|
websocket-driver (0.7.0)
|
47
52
|
websocket-extensions (>= 0.1.0)
|
48
53
|
websocket-extensions (0.1.3)
|
data/README.md
CHANGED
@@ -178,6 +178,20 @@ client.users.find(user_id) # get info about a specific user
|
|
178
178
|
client.users.set_active # sets the current user (defined by the access_token) as active
|
179
179
|
```
|
180
180
|
|
181
|
+
### Pagination
|
182
|
+
|
183
|
+
In order to support paging, you can provide a `page` parameter to all methods that support paging. If the `page` parameter exists, the method will map until all conversations are retrieved.
|
184
|
+
|
185
|
+
```
|
186
|
+
conversations = client.conversations.all(page: { limit: 10, sleep_interval: 2, max_retries: 20 })
|
187
|
+
```
|
188
|
+
|
189
|
+
If you want to limit the number of page retrievals, you can set the `page` parameter to the number of retrievals to retrieve. For example, if you just want to retrieve one page worth of 1000 results, you can do the following:
|
190
|
+
|
191
|
+
```
|
192
|
+
conversations = client.conversations.all(page: { limit: 1000 })
|
193
|
+
```
|
194
|
+
|
181
195
|
## REAL TIME API USAGE
|
182
196
|
|
183
197
|
The [Slack Real Time Messaging API](https://api.slack.com/rtm) is made up of Websocket events that allow you to communicate with Slack as a bot (or yourself) with an access token.
|
data/lib/laziness/api/base.rb
CHANGED
@@ -18,6 +18,12 @@ module Slack
|
|
18
18
|
nil
|
19
19
|
end
|
20
20
|
|
21
|
+
def with_paging(page)
|
22
|
+
Cursor.new(page).paginate do |pager|
|
23
|
+
yield(pager)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
21
27
|
def request(method, path, arguments={})
|
22
28
|
full_path = "#{base_path}#{path}"
|
23
29
|
full_path = "#{full_path}?token=#{access_token}" unless access_token.nil?
|
@@ -45,6 +51,8 @@ module Slack
|
|
45
51
|
klass = "#{parsed['error'].gsub(/(^|_)(.)/) { $2.upcase }}Error"
|
46
52
|
if Slack.const_defined? klass
|
47
53
|
raise Slack.const_get(klass)
|
54
|
+
elsif response.code == 429
|
55
|
+
raise Slack::TooManyRequestsError.new(response)
|
48
56
|
else
|
49
57
|
raise Slack::APIError.new parsed['error']
|
50
58
|
end
|
@@ -1,9 +1,15 @@
|
|
1
1
|
module Slack
|
2
2
|
module API
|
3
3
|
class Channels < Base
|
4
|
-
def all(exclude_archived=false)
|
5
|
-
|
6
|
-
|
4
|
+
def all(exclude_archived=false, page: nil)
|
5
|
+
responses = with_paging(page) do |pager|
|
6
|
+
request :get,
|
7
|
+
'channels.list',
|
8
|
+
exclude_archived: exclude_archived ? 1 : 0,
|
9
|
+
**pager.to_h
|
10
|
+
end
|
11
|
+
|
12
|
+
Slack::Channel.parse_all responses, 'channels'
|
7
13
|
end
|
8
14
|
|
9
15
|
def archive(id)
|
@@ -1,13 +1,16 @@
|
|
1
1
|
module Slack
|
2
2
|
module API
|
3
3
|
class Conversations < Base
|
4
|
-
def all(exclude_archived=false, types='public_channel')
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
def all(exclude_archived=false, types='public_channel', page: nil)
|
5
|
+
responses = with_paging(page) do |pager|
|
6
|
+
request :get,
|
7
|
+
'conversations.list',
|
8
|
+
exclude_archived: exclude_archived ? 1 : 0,
|
9
|
+
types: types,
|
10
|
+
**pager.to_h
|
11
|
+
end
|
9
12
|
|
10
|
-
Slack::Conversation.
|
13
|
+
Slack::Conversation.parse_all responses, 'channels'
|
11
14
|
end
|
12
15
|
|
13
16
|
def archive(id)
|
@@ -58,12 +61,17 @@ module Slack
|
|
58
61
|
with_nil_response { request :post, 'conversations.leave', channel: id }
|
59
62
|
end
|
60
63
|
|
61
|
-
def members(id)
|
62
|
-
|
63
|
-
|
64
|
-
|
64
|
+
def members(id, page: nil)
|
65
|
+
responses = with_paging(page) do |pager|
|
66
|
+
request :get,
|
67
|
+
'conversations.members',
|
68
|
+
channel: id,
|
69
|
+
**pager.to_h
|
70
|
+
end
|
65
71
|
|
66
|
-
|
72
|
+
responses.map do |response|
|
73
|
+
JSON.parse(response.body)["members"]
|
74
|
+
end.flatten
|
67
75
|
end
|
68
76
|
|
69
77
|
def open(users=[], id=nil, return_im: false)
|
data/lib/laziness/api/groups.rb
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
module Slack
|
2
2
|
module API
|
3
3
|
class Groups < Base
|
4
|
-
def all(exclude_archived=false)
|
5
|
-
|
6
|
-
|
4
|
+
def all(exclude_archived=false, page: nil)
|
5
|
+
responses = with_paging(page) do |pager|
|
6
|
+
request :get,
|
7
|
+
'groups.list',
|
8
|
+
exclude_archived: exclude_archived ? 1 : 0,
|
9
|
+
**pager.to_h
|
10
|
+
end
|
11
|
+
|
12
|
+
Slack::Group.parse_all responses, 'groups'
|
7
13
|
end
|
8
14
|
|
9
15
|
def archive(id)
|
data/lib/laziness/api/im.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
module Slack
|
2
2
|
module API
|
3
3
|
class IM < Base
|
4
|
-
def all
|
5
|
-
|
6
|
-
|
4
|
+
def all(page: nil)
|
5
|
+
responses = with_paging(page) do |pager|
|
6
|
+
request :get, 'im.list', **pager.to_h
|
7
|
+
end
|
8
|
+
|
9
|
+
Slack::Channel.parse_all responses, 'ims'
|
7
10
|
end
|
8
11
|
|
9
12
|
def close(channel)
|
data/lib/laziness/api/users.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
module Slack
|
2
2
|
module API
|
3
3
|
class Users < Base
|
4
|
-
def all
|
5
|
-
|
6
|
-
|
4
|
+
def all(page: nil)
|
5
|
+
responses = with_paging(page) do |pager|
|
6
|
+
request :get, 'users.list', **pager.to_h
|
7
|
+
end
|
8
|
+
|
9
|
+
Slack::User.parse_all responses, 'members'
|
7
10
|
end
|
8
11
|
|
9
12
|
def find(id)
|
data/lib/laziness/base.rb
CHANGED
@@ -3,8 +3,8 @@ require 'hashie'
|
|
3
3
|
module Slack
|
4
4
|
class Base < Hashie::Mash
|
5
5
|
class << self
|
6
|
-
def parse(
|
7
|
-
parsed = JSON.parse(
|
6
|
+
def parse(response, key=nil)
|
7
|
+
parsed = JSON.parse(response.body)
|
8
8
|
parsed = parsed[key] if key && parsed[key]
|
9
9
|
if parsed.is_a? Array
|
10
10
|
models = []
|
@@ -14,6 +14,12 @@ module Slack
|
|
14
14
|
new parsed
|
15
15
|
end
|
16
16
|
end
|
17
|
+
|
18
|
+
def parse_all(responses, key=nil)
|
19
|
+
responses.map do |response|
|
20
|
+
parse(response, key)
|
21
|
+
end.flatten
|
22
|
+
end
|
17
23
|
end
|
18
24
|
end
|
19
25
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Slack
|
2
|
+
class Cursor
|
3
|
+
attr_reader :page
|
4
|
+
|
5
|
+
def initialize(page)
|
6
|
+
@page = page
|
7
|
+
@max_retries = (page && page[:max_retries]) || 0
|
8
|
+
@sleep_interval = (page && page[:sleep_interval])
|
9
|
+
end
|
10
|
+
|
11
|
+
def paginate(&blk)
|
12
|
+
responses = []
|
13
|
+
|
14
|
+
if block_given?
|
15
|
+
pager = Pager.new(page)
|
16
|
+
retries = 0
|
17
|
+
|
18
|
+
loop do
|
19
|
+
begin
|
20
|
+
response = blk.call(pager)
|
21
|
+
rescue Slack::TooManyRequestsError => e
|
22
|
+
raise e if retries >= max_retries
|
23
|
+
|
24
|
+
retries += 1
|
25
|
+
|
26
|
+
sleep(e.retry_after_in_seconds)
|
27
|
+
next
|
28
|
+
end
|
29
|
+
|
30
|
+
responses << response
|
31
|
+
|
32
|
+
break unless has_cursor?(response)
|
33
|
+
|
34
|
+
retries = 0
|
35
|
+
|
36
|
+
pager = pager.next(next_cursor(response))
|
37
|
+
|
38
|
+
sleep(sleep_interval) if sleep_interval
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
responses
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
attr_reader :max_retries, :sleep_interval
|
48
|
+
|
49
|
+
def next_cursor(response)
|
50
|
+
response["response_metadata"]["next_cursor"] unless !has_cursor?(response)
|
51
|
+
end
|
52
|
+
|
53
|
+
def has_cursor?(response)
|
54
|
+
response.respond_to?(:[]) &&
|
55
|
+
!response["response_metadata"].nil? &&
|
56
|
+
!response["response_metadata"]["next_cursor"].nil? &&
|
57
|
+
!response["response_metadata"]["next_cursor"].empty?
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/laziness/errors.rb
CHANGED
@@ -94,4 +94,23 @@ module Slack
|
|
94
94
|
super "You cannot archive the last channel for a restricted account."
|
95
95
|
end
|
96
96
|
end
|
97
|
+
|
98
|
+
class TooManyRequestsError < APIError
|
99
|
+
def initialize(response)
|
100
|
+
@response = response
|
101
|
+
end
|
102
|
+
|
103
|
+
def message
|
104
|
+
"Retry after #{retry_after_in_seconds} seconds"
|
105
|
+
end
|
106
|
+
|
107
|
+
def retry_after_in_seconds
|
108
|
+
retry_after = response.headers["retry-after"]
|
109
|
+
(retry_after || 0).to_i
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
attr_reader :response
|
115
|
+
end
|
97
116
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "ostruct"
|
2
|
+
|
3
|
+
module Slack
|
4
|
+
class Pager
|
5
|
+
attr_reader :cursor, :limit, :page
|
6
|
+
|
7
|
+
def initialize(page)
|
8
|
+
@page = page.dup
|
9
|
+
@limit = @page[:limit] unless empty?
|
10
|
+
end
|
11
|
+
|
12
|
+
def empty?
|
13
|
+
page.nil? || page.empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_h
|
17
|
+
{ cursor: cursor, limit: limit }
|
18
|
+
end
|
19
|
+
|
20
|
+
def next(cursor)
|
21
|
+
self.class.new(page).tap do |pager|
|
22
|
+
pager.cursor = cursor
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def cursor=(cursor)
|
29
|
+
@cursor = cursor
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/laziness/version.rb
CHANGED
data/lib/laziness.rb
CHANGED
@@ -6,11 +6,13 @@ require 'laziness/channel'
|
|
6
6
|
require 'laziness/chat'
|
7
7
|
require 'laziness/client'
|
8
8
|
require 'laziness/conversation'
|
9
|
+
require 'laziness/cursor'
|
9
10
|
require 'laziness/errors'
|
10
11
|
require 'laziness/group'
|
11
12
|
require 'laziness/message'
|
12
13
|
require 'laziness/oauth'
|
13
14
|
require 'laziness/observer'
|
15
|
+
require 'laziness/pager'
|
14
16
|
require 'laziness/real_time_client'
|
15
17
|
require 'laziness/registry'
|
16
18
|
require 'laziness/session'
|
@@ -13,6 +13,20 @@ describe Slack::API::Conversations do
|
|
13
13
|
expect(conversations.length).to eq 1
|
14
14
|
expect(conversations[0].id).to eq "C02BLAH"
|
15
15
|
end
|
16
|
+
|
17
|
+
context 'with paging' do
|
18
|
+
it 'pages through until there are no more pages left' do
|
19
|
+
stub_slack_request :get,
|
20
|
+
"conversations.list?token=#{access_token}&exclude_archived=0&"\
|
21
|
+
"limit=1000&"\
|
22
|
+
"types=public_channel",
|
23
|
+
"conversations_list.json"
|
24
|
+
|
25
|
+
conversations = subject.all(page: { limit: 1000 })
|
26
|
+
expect(conversations.length).to eq 1
|
27
|
+
expect(conversations[0].id).to eq "C02BLAH"
|
28
|
+
end
|
29
|
+
end
|
16
30
|
end
|
17
31
|
|
18
32
|
describe '.archive' do
|
@@ -0,0 +1,20 @@
|
|
1
|
+
describe Slack::Base do
|
2
|
+
describe "#parse_all" do
|
3
|
+
let(:responses) do
|
4
|
+
[
|
5
|
+
double(:response,
|
6
|
+
body: '{ "ok": true, "messages": [{ "id": "1234", "type": "blah" }] }'),
|
7
|
+
double(:response,
|
8
|
+
body: '{ "ok": true, "messages": [{ "id": "4567", "type": "bleh" }] }')
|
9
|
+
]
|
10
|
+
end
|
11
|
+
|
12
|
+
it "parses all of the messages in an array" do
|
13
|
+
result = described_class.parse_all responses, 'messages'
|
14
|
+
|
15
|
+
expect(result.count).to eq 2
|
16
|
+
expect(result.first.id).to eq "1234"
|
17
|
+
expect(result.last.id).to eq "4567"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
describe Slack::Cursor do
|
2
|
+
describe '#initialize' do
|
3
|
+
let(:page) { { limit: 10 } }
|
4
|
+
|
5
|
+
it 'initializes with page attributes' do
|
6
|
+
expect(described_class.new(page).page).to eq page
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#paginate' do
|
11
|
+
let(:first_response) do
|
12
|
+
{
|
13
|
+
"ok" => true,
|
14
|
+
"channels" => [{
|
15
|
+
"id" => "C01"
|
16
|
+
}],
|
17
|
+
"response_metadata" => {
|
18
|
+
"next_cursor" => "onto-second-request"
|
19
|
+
}
|
20
|
+
}
|
21
|
+
end
|
22
|
+
let(:last_response) do
|
23
|
+
{
|
24
|
+
"ok" => true,
|
25
|
+
"channels" => [{
|
26
|
+
"id" => "C03"
|
27
|
+
}],
|
28
|
+
"response_metadata" => {
|
29
|
+
"next_cursor" => ""
|
30
|
+
}
|
31
|
+
}
|
32
|
+
end
|
33
|
+
let(:page) { { limit: 10 } }
|
34
|
+
let(:second_response) do
|
35
|
+
{
|
36
|
+
"ok" => true,
|
37
|
+
"channels" => [{
|
38
|
+
"id" => "C02"
|
39
|
+
}],
|
40
|
+
"response_metadata" => {
|
41
|
+
"next_cursor" => "onto-last-request"
|
42
|
+
}
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
subject { described_class.new(page) }
|
47
|
+
|
48
|
+
it 'does not require a block' do
|
49
|
+
expect { subject.paginate }.to_not raise_error
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'yields a pager' do
|
53
|
+
expect { |b| subject.paginate(&b) }.to yield_with_args(Slack::Pager)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'returns the results of each yield' do
|
57
|
+
expected = [first_response, second_response, last_response]
|
58
|
+
index = 0
|
59
|
+
responses = subject.paginate do |pager|
|
60
|
+
response = expected[index]
|
61
|
+
index += 1
|
62
|
+
response
|
63
|
+
end
|
64
|
+
|
65
|
+
expect(responses).to eq(expected)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'updates the cursor on the pager' do
|
69
|
+
expect_any_instance_of(Slack::Pager).to \
|
70
|
+
receive(:next).with("onto-last-request").and_call_original
|
71
|
+
|
72
|
+
responses = [second_response, last_response]
|
73
|
+
subject.paginate do |pager|
|
74
|
+
responses.shift
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'with a too many requests error' do
|
79
|
+
let(:page) { { limit: 10, max_retries: 2 } }
|
80
|
+
let(:response) { OpenStruct.new(headers: { 'retry-after' => '0' }) }
|
81
|
+
|
82
|
+
it 'tries again when there is a max retries setting' do
|
83
|
+
number_of_tries = 0
|
84
|
+
|
85
|
+
expect {
|
86
|
+
subject.paginate do |pager|
|
87
|
+
number_of_tries += 1
|
88
|
+
raise Slack::TooManyRequestsError, response
|
89
|
+
end
|
90
|
+
}.to raise_error(Slack::TooManyRequestsError)
|
91
|
+
|
92
|
+
expect(number_of_tries).to eq 3
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'without a max retries' do
|
96
|
+
it 'bubbles up the error' do
|
97
|
+
expect do
|
98
|
+
subject.paginate do |pager|
|
99
|
+
raise Slack::TooManyRequestsError, response
|
100
|
+
end
|
101
|
+
end.to raise_error Slack::TooManyRequestsError
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'with a sleep interval' do
|
107
|
+
let(:page) { { limit: 10, sleep_interval: 2 } }
|
108
|
+
|
109
|
+
it 'sleeps in between requests' do
|
110
|
+
expect(subject).to receive(:sleep).with(2)
|
111
|
+
|
112
|
+
responses = [second_response, last_response]
|
113
|
+
subject.paginate do |pager|
|
114
|
+
responses.shift
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'with a nil page' do
|
120
|
+
subject { described_class.new(nil) }
|
121
|
+
|
122
|
+
it 'yields with an empty pager' do
|
123
|
+
subject.paginate do |pager|
|
124
|
+
expect(pager).to be_empty
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -154,6 +154,19 @@ describe 'API errors' do
|
|
154
154
|
expect { subject.channels.all }.to raise_error Slack::NoChannelError
|
155
155
|
end
|
156
156
|
|
157
|
+
it 'raises a too many requests error if the status is 429' do
|
158
|
+
response = {
|
159
|
+
ok: false,
|
160
|
+
error: "ratelimited"
|
161
|
+
}
|
162
|
+
stub_request(:get, "https://slack.com/api/users.list?token=#{access_token}").
|
163
|
+
to_return(status: 429,
|
164
|
+
body: response.to_json,
|
165
|
+
headers: { "Retry-After" => "30" })
|
166
|
+
expect { subject.users.all }.to \
|
167
|
+
raise_error Slack::TooManyRequestsError, "Retry after 30 seconds"
|
168
|
+
end
|
169
|
+
|
157
170
|
it 'raises an http error if the error is not known' do
|
158
171
|
response = {
|
159
172
|
ok: false,
|
@@ -1,7 +1,8 @@
|
|
1
1
|
describe Slack::Message do
|
2
2
|
describe "#parse" do
|
3
3
|
it "initializes a new message with a JSON string" do
|
4
|
-
message =
|
4
|
+
message = described_class.parse '{ "id": "1234", "type": "blah" }'
|
5
|
+
|
5
6
|
expect(message).to be_a Slack::Message
|
6
7
|
expect(message.id).to eq "1234"
|
7
8
|
expect(message.type).to eq :blah
|
@@ -10,15 +11,18 @@ describe Slack::Message do
|
|
10
11
|
|
11
12
|
describe "#generate" do
|
12
13
|
it "generates a new message with a random id and type" do
|
13
|
-
message =
|
14
|
+
message = described_class.generate text: "This is a test"
|
15
|
+
|
14
16
|
expect(message.id).to_not be_empty
|
15
17
|
expect(message.type).to eq :message
|
16
18
|
expect(message.text).to eq "This is a test"
|
17
19
|
end
|
18
20
|
|
19
21
|
it "can have an id specified" do
|
20
|
-
expect(
|
21
|
-
|
22
|
+
expect(described_class).to_not receive(:generate_id)
|
23
|
+
|
24
|
+
message = described_class.generate id: 12345
|
25
|
+
|
22
26
|
expect(message.id).to eq 12345
|
23
27
|
end
|
24
28
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
describe Slack::Pager do
|
2
|
+
describe "#initialize" do
|
3
|
+
let(:page) { { limit: 20 } }
|
4
|
+
|
5
|
+
it "initializes with a page" do
|
6
|
+
expect(described_class.new(page).page).to eq page
|
7
|
+
end
|
8
|
+
|
9
|
+
it "saves the limit" do
|
10
|
+
expect(described_class.new(page).limit).to eq 20
|
11
|
+
end
|
12
|
+
|
13
|
+
it "initializes a nil cursor" do
|
14
|
+
expect(described_class.new(page).cursor).to be_nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#empty?" do
|
19
|
+
context "with a non-empty page" do
|
20
|
+
it "is not empty" do
|
21
|
+
expect(described_class.new({ limit: 200 })).to_not be_empty
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with an empty page" do
|
26
|
+
it "is empty" do
|
27
|
+
expect(described_class.new({})).to be_empty
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "with a nil page" do
|
32
|
+
it "is empty" do
|
33
|
+
expect(described_class.new(nil)).to be_empty
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#to_h" do
|
39
|
+
subject { described_class.new({ limit: 200 }) }
|
40
|
+
|
41
|
+
it "returns a hash with the limit and the cursor" do
|
42
|
+
expect(subject.to_h).to eq({ limit: 200, cursor: nil })
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#next" do
|
47
|
+
subject { described_class.new({ limit: 200 }) }
|
48
|
+
|
49
|
+
it "returns a new instance of the pager" do
|
50
|
+
pager = subject.next("next")
|
51
|
+
|
52
|
+
expect(pager).to be_instance_of(described_class)
|
53
|
+
expect(pager).to_not equal subject
|
54
|
+
end
|
55
|
+
|
56
|
+
it "sets the cursor" do
|
57
|
+
expect(subject.next("next").cursor).to eq "next"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -1,7 +1,16 @@
|
|
1
1
|
module SlackStubFactory
|
2
|
-
def stub_slack_request(method, path,
|
2
|
+
def stub_slack_request(method, path, fixtures)
|
3
|
+
fixtures = [fixtures].flatten
|
4
|
+
|
3
5
|
full_path = "https://slack.com/api/#{path}"
|
4
|
-
|
6
|
+
|
7
|
+
stub = stub_request(method, full_path)
|
8
|
+
begin
|
9
|
+
fixture = fixtures.shift
|
10
|
+
stub.to_return(status: 200, body: slack_json_fixture(fixture))
|
11
|
+
end while !fixtures.empty?
|
12
|
+
|
13
|
+
stub
|
5
14
|
end
|
6
15
|
|
7
16
|
def slack_json_fixture(fixture)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: laziness
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jamie Wright
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eventmachine
|
@@ -100,11 +100,13 @@ files:
|
|
100
100
|
- lib/laziness/chat.rb
|
101
101
|
- lib/laziness/client.rb
|
102
102
|
- lib/laziness/conversation.rb
|
103
|
+
- lib/laziness/cursor.rb
|
103
104
|
- lib/laziness/errors.rb
|
104
105
|
- lib/laziness/group.rb
|
105
106
|
- lib/laziness/message.rb
|
106
107
|
- lib/laziness/oauth.rb
|
107
108
|
- lib/laziness/observer.rb
|
109
|
+
- lib/laziness/pager.rb
|
108
110
|
- lib/laziness/real_time_client.rb
|
109
111
|
- lib/laziness/registry.rb
|
110
112
|
- lib/laziness/session.rb
|
@@ -119,10 +121,13 @@ files:
|
|
119
121
|
- spec/laziness/api/oauth_spec.rb
|
120
122
|
- spec/laziness/api/rtm_spec.rb
|
121
123
|
- spec/laziness/api/users_spec.rb
|
124
|
+
- spec/laziness/base_spec.rb
|
122
125
|
- spec/laziness/client_spec.rb
|
126
|
+
- spec/laziness/cursor_spec.rb
|
123
127
|
- spec/laziness/errors_spec.rb
|
124
128
|
- spec/laziness/message_spec.rb
|
125
129
|
- spec/laziness/observer_spec.rb
|
130
|
+
- spec/laziness/pager_spec.rb
|
126
131
|
- spec/laziness/real_time_client_spec.rb
|
127
132
|
- spec/laziness/registry_spec.rb
|
128
133
|
- spec/spec_helper.rb
|
@@ -181,10 +186,13 @@ test_files:
|
|
181
186
|
- spec/laziness/api/oauth_spec.rb
|
182
187
|
- spec/laziness/api/rtm_spec.rb
|
183
188
|
- spec/laziness/api/users_spec.rb
|
189
|
+
- spec/laziness/base_spec.rb
|
184
190
|
- spec/laziness/client_spec.rb
|
191
|
+
- spec/laziness/cursor_spec.rb
|
185
192
|
- spec/laziness/errors_spec.rb
|
186
193
|
- spec/laziness/message_spec.rb
|
187
194
|
- spec/laziness/observer_spec.rb
|
195
|
+
- spec/laziness/pager_spec.rb
|
188
196
|
- spec/laziness/real_time_client_spec.rb
|
189
197
|
- spec/laziness/registry_spec.rb
|
190
198
|
- spec/spec_helper.rb
|