ruby-trello 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -5
- data/lib/trello/board.rb +6 -8
- data/lib/trello/card.rb +14 -28
- data/lib/trello/checklist.rb +14 -0
- data/lib/trello/item.rb +4 -0
- data/lib/trello/label.rb +3 -3
- data/lib/trello/list.rb +13 -3
- data/lib/trello/organization.rb +14 -7
- data/spec/action_spec.rb +67 -31
- data/spec/array_spec.rb +1 -1
- data/spec/association_spec.rb +11 -7
- data/spec/basic_auth_policy_spec.rb +4 -4
- data/spec/board_spec.rb +169 -92
- data/spec/card_spec.rb +232 -119
- data/spec/checklist_spec.rb +109 -16
- data/spec/client_spec.rb +83 -45
- data/spec/configuration_spec.rb +24 -43
- data/spec/hash_spec.rb +5 -1
- data/spec/item_spec.rb +27 -9
- data/spec/label_spec.rb +52 -27
- data/spec/list_spec.rb +86 -29
- data/spec/member_spec.rb +62 -40
- data/spec/notification_spec.rb +57 -22
- data/spec/oauth_policy_spec.rb +45 -24
- data/spec/organization_spec.rb +16 -8
- data/spec/spec_helper.rb +28 -3
- data/spec/string_spec.rb +11 -8
- data/spec/token_spec.rb +31 -11
- data/spec/trello_spec.rb +20 -23
- data/spec/webhook_spec.rb +24 -9
- metadata +4 -6
- data/spec/item_state_spec.rb +0 -0
data/spec/checklist_spec.rb
CHANGED
@@ -7,21 +7,26 @@ module Trello
|
|
7
7
|
let(:checklist) { client.find(:checklist, 'abcdef123456789123456789') }
|
8
8
|
let(:client) { Client.new }
|
9
9
|
|
10
|
-
before
|
11
|
-
client
|
12
|
-
|
10
|
+
before do
|
11
|
+
allow(client)
|
12
|
+
.to receive(:get)
|
13
|
+
.with("/checklists/abcdef123456789123456789", {})
|
14
|
+
.and_return JSON.generate(checklists_details.first)
|
13
15
|
end
|
14
16
|
|
15
17
|
context "finding" do
|
16
18
|
let(:client) { Trello.client }
|
17
19
|
|
18
20
|
it "delegates to Trello.client#find" do
|
19
|
-
client
|
21
|
+
expect(client)
|
22
|
+
.to receive(:find)
|
23
|
+
.with(:checklist, 'abcdef123456789123456789', {})
|
24
|
+
|
20
25
|
Checklist.find('abcdef123456789123456789')
|
21
26
|
end
|
22
27
|
|
23
28
|
it "is equivalent to client#find" do
|
24
|
-
Checklist.find('abcdef123456789123456789').
|
29
|
+
expect(Checklist.find('abcdef123456789123456789')).to eq(checklist)
|
25
30
|
end
|
26
31
|
end
|
27
32
|
|
@@ -38,11 +43,14 @@ module Trello
|
|
38
43
|
|
39
44
|
expected_payload = {name: "Test Checklist", idBoard: "abcdef123456789123456789"}
|
40
45
|
|
41
|
-
client
|
46
|
+
expect(client)
|
47
|
+
.to receive(:post)
|
48
|
+
.with("/checklists", expected_payload)
|
49
|
+
.and_return result
|
42
50
|
|
43
51
|
checklist = Checklist.create(checklists_details.first.merge(payload.merge(board_id: boards_details.first['id'])))
|
44
52
|
|
45
|
-
checklist.
|
53
|
+
expect(checklist).to be_a Checklist
|
46
54
|
end
|
47
55
|
end
|
48
56
|
|
@@ -50,13 +58,19 @@ module Trello
|
|
50
58
|
let(:client) { Trello.client }
|
51
59
|
|
52
60
|
it "deletes a checklist" do
|
53
|
-
client
|
61
|
+
expect(client)
|
62
|
+
.to receive(:delete)
|
63
|
+
.with("/checklists/#{checklist.id}")
|
64
|
+
|
54
65
|
checklist.delete
|
55
66
|
end
|
56
67
|
|
57
68
|
it "deletes a checklist item" do
|
58
69
|
item_id = checklist.check_items.first.last
|
59
|
-
client
|
70
|
+
expect(client)
|
71
|
+
.to receive(:delete)
|
72
|
+
.with("/checklists/#{checklist.id}/checkItems/#{item_id}")
|
73
|
+
|
60
74
|
checklist.delete_checklist_item(item_id)
|
61
75
|
end
|
62
76
|
end
|
@@ -71,7 +85,10 @@ module Trello
|
|
71
85
|
}
|
72
86
|
|
73
87
|
result = JSON.generate(checklists_details.first)
|
74
|
-
client
|
88
|
+
expect(client)
|
89
|
+
.to receive(:put)
|
90
|
+
.once.with(expected_resource, payload)
|
91
|
+
.and_return result
|
75
92
|
|
76
93
|
checklist.name = expected_new_name
|
77
94
|
checklist.save
|
@@ -86,7 +103,11 @@ module Trello
|
|
86
103
|
}
|
87
104
|
|
88
105
|
result = JSON.generate(checklists_details.first)
|
89
|
-
client
|
106
|
+
expect(client)
|
107
|
+
.to receive(:put)
|
108
|
+
.once
|
109
|
+
.with(expected_resource, payload)
|
110
|
+
.and_return result
|
90
111
|
|
91
112
|
checklist.position = expected_new_position
|
92
113
|
checklist.save
|
@@ -107,23 +128,95 @@ module Trello
|
|
107
128
|
pos: expected_pos
|
108
129
|
}
|
109
130
|
result = JSON.generate(result_hash)
|
110
|
-
client
|
131
|
+
expect(client)
|
132
|
+
.to receive(:post)
|
133
|
+
.once
|
134
|
+
.with("/checklists/abcdef123456789123456789/checkItems", payload)
|
135
|
+
.and_return result
|
111
136
|
|
112
137
|
checklist.add_item(expected_item_name, expected_checked, expected_pos)
|
113
138
|
end
|
114
139
|
end
|
115
140
|
|
116
141
|
context "board" do
|
142
|
+
before do
|
143
|
+
allow(client)
|
144
|
+
.to receive(:get)
|
145
|
+
.with("/boards/abcdef123456789123456789")
|
146
|
+
.and_return JSON.generate(boards_details.first)
|
147
|
+
end
|
148
|
+
|
117
149
|
it "has a board" do
|
118
|
-
|
119
|
-
checklist.board.should_not be_nil
|
150
|
+
expect(checklist.board).to_not be_nil
|
120
151
|
end
|
121
152
|
end
|
122
153
|
|
123
154
|
context "list" do
|
155
|
+
before do
|
156
|
+
allow(client)
|
157
|
+
.to receive(:get)
|
158
|
+
.with("/lists/abcdef123456789123456789", {})
|
159
|
+
.and_return JSON.generate(lists_details.first)
|
160
|
+
end
|
161
|
+
|
124
162
|
it 'has a list' do
|
125
|
-
|
126
|
-
|
163
|
+
expect(checklist.list).to_not be_nil
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context "making a copy" do
|
168
|
+
let(:client) { Trello.client }
|
169
|
+
let(:copy_options) { { :name => checklist.name, :idBoard => checklist.board_id } }
|
170
|
+
let(:copied_checklist) { checklist.copy }
|
171
|
+
|
172
|
+
before(:each) do
|
173
|
+
allow(client)
|
174
|
+
.to receive(:post)
|
175
|
+
.with("/checklists", copy_options)
|
176
|
+
.and_return JSON.generate(copied_checklists_details.first)
|
177
|
+
|
178
|
+
allow(checklist)
|
179
|
+
.to receive(:items)
|
180
|
+
.and_return []
|
181
|
+
end
|
182
|
+
|
183
|
+
it "creates a new checklist" do
|
184
|
+
expect(copied_checklist).to be_an_instance_of Checklist
|
185
|
+
end
|
186
|
+
|
187
|
+
it "is not the same Ruby object as the original checklist" do
|
188
|
+
expect(copied_checklist).to_not be checklist
|
189
|
+
end
|
190
|
+
|
191
|
+
it "has the same name as the original checklist" do
|
192
|
+
expect(copied_checklist.name).to eq checklist.name
|
193
|
+
end
|
194
|
+
|
195
|
+
it "has the same board as the original checklist" do
|
196
|
+
expect(copied_checklist.board_id).to eq checklist.board_id
|
197
|
+
end
|
198
|
+
|
199
|
+
it "creates items for the copy based on the original checklist's items" do
|
200
|
+
checklist_copy = Trello::Checklist.new
|
201
|
+
allow(checklist_copy)
|
202
|
+
.to receive(:add_item)
|
203
|
+
|
204
|
+
allow(Trello::Checklist)
|
205
|
+
.to receive(:create)
|
206
|
+
.and_return(checklist_copy)
|
207
|
+
|
208
|
+
incomplete_item = double("incomplete", name: "1", complete?: false)
|
209
|
+
complete_item = double("complete", name: "2", complete?: true)
|
210
|
+
checklist_items = [incomplete_item, complete_item]
|
211
|
+
allow(checklist).to receive(:items).and_return checklist_items
|
212
|
+
|
213
|
+
checklist_items.each do |item|
|
214
|
+
expect(checklist_copy)
|
215
|
+
.to receive(:add_item)
|
216
|
+
.with(item.name, item.complete?)
|
217
|
+
end
|
218
|
+
|
219
|
+
checklist.copy
|
127
220
|
end
|
128
221
|
end
|
129
222
|
end
|
data/spec/client_spec.rb
CHANGED
@@ -13,16 +13,28 @@ describe Client, "and how it handles authorization" do
|
|
13
13
|
let(:auth_policy) { double }
|
14
14
|
|
15
15
|
before do
|
16
|
-
TInternet
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
allow(TInternet)
|
17
|
+
.to receive(:execute)
|
18
|
+
.and_return fake_ok_response
|
19
|
+
|
20
|
+
allow(Authorization::AuthPolicy)
|
21
|
+
.to receive(:new)
|
22
|
+
.and_return(auth_policy)
|
23
|
+
|
24
|
+
allow(auth_policy)
|
25
|
+
.to receive(:authorize) { |request| request }
|
21
26
|
end
|
22
27
|
|
23
28
|
it "authorizes before it queries the internet" do
|
24
|
-
auth_policy
|
25
|
-
|
29
|
+
expect(auth_policy)
|
30
|
+
.to receive(:authorize)
|
31
|
+
.once
|
32
|
+
.ordered
|
33
|
+
|
34
|
+
expect(TInternet)
|
35
|
+
.to receive(:execute)
|
36
|
+
.once
|
37
|
+
.ordered
|
26
38
|
|
27
39
|
client.get "/xxx"
|
28
40
|
end
|
@@ -31,7 +43,10 @@ describe Client, "and how it handles authorization" do
|
|
31
43
|
expected_uri = Addressable::URI.parse("https://api.trello.com/1/xxx?a=1&b=2")
|
32
44
|
expected_request = Request.new :get, expected_uri, {}
|
33
45
|
|
34
|
-
TInternet
|
46
|
+
expect(TInternet)
|
47
|
+
.to receive(:execute)
|
48
|
+
.once
|
49
|
+
.with expected_request
|
35
50
|
|
36
51
|
client.get "/xxx", a: "1", b: "2"
|
37
52
|
end
|
@@ -40,7 +55,10 @@ describe Client, "and how it handles authorization" do
|
|
40
55
|
expected_uri = Addressable::URI.parse("https://api.trello.com/1/xxx?name=Jazz%20Kang")
|
41
56
|
expected_request = Request.new :get, expected_uri, {}
|
42
57
|
|
43
|
-
TInternet
|
58
|
+
expect(TInternet)
|
59
|
+
.to receive(:execute)
|
60
|
+
.once
|
61
|
+
.with expected_request
|
44
62
|
|
45
63
|
client.get "/xxx", name: "Jazz Kang"
|
46
64
|
end
|
@@ -51,31 +69,40 @@ describe Client, "and how it handles authorization" do
|
|
51
69
|
code: 404,
|
52
70
|
body: expected_error_message
|
53
71
|
|
54
|
-
TInternet
|
72
|
+
expect(TInternet)
|
73
|
+
.to receive(:execute)
|
74
|
+
.and_return response_with_non_200_status
|
55
75
|
|
56
|
-
|
76
|
+
expect { client.get "/xxx" }.to raise_error expected_error_message
|
57
77
|
end
|
58
78
|
|
59
79
|
it "uses version 1 of the API" do
|
60
|
-
TInternet
|
61
|
-
|
62
|
-
|
63
|
-
|
80
|
+
expect(TInternet)
|
81
|
+
.to receive(:execute)
|
82
|
+
.once do |request|
|
83
|
+
expect(request.uri.to_s).to match(/1\//)
|
84
|
+
fake_ok_response
|
85
|
+
end
|
64
86
|
|
65
87
|
client.get "/"
|
66
88
|
end
|
67
89
|
|
68
90
|
it "omits the \"?\" when no parameters" do
|
69
|
-
TInternet
|
70
|
-
|
71
|
-
|
72
|
-
|
91
|
+
expect(TInternet)
|
92
|
+
.to receive(:execute)
|
93
|
+
.once do |request|
|
94
|
+
expect(request.uri.to_s).not_to match(/\?$/)
|
95
|
+
fake_ok_response
|
96
|
+
end
|
73
97
|
|
74
98
|
client.get "/xxx"
|
75
99
|
end
|
76
100
|
|
77
101
|
it "supports post" do
|
78
|
-
TInternet
|
102
|
+
expect(TInternet)
|
103
|
+
.to receive(:execute)
|
104
|
+
.once
|
105
|
+
.and_return fake_ok_response
|
79
106
|
|
80
107
|
client.post "/xxx", { phil: "T' north" }
|
81
108
|
end
|
@@ -83,10 +110,12 @@ describe Client, "and how it handles authorization" do
|
|
83
110
|
it "supplies the body for a post" do
|
84
111
|
expected_body = { name: "Phil", nickname: "The Crack Fox" }
|
85
112
|
|
86
|
-
TInternet
|
87
|
-
|
88
|
-
|
89
|
-
|
113
|
+
expect(TInternet)
|
114
|
+
.to receive(:execute)
|
115
|
+
.once do |request|
|
116
|
+
expect(request.body).to eq expected_body
|
117
|
+
fake_ok_response
|
118
|
+
end
|
90
119
|
|
91
120
|
client.post "/xxx", expected_body
|
92
121
|
end
|
@@ -94,16 +123,21 @@ describe Client, "and how it handles authorization" do
|
|
94
123
|
it "supplies the path for a post" do
|
95
124
|
expected_path = "/xxx"
|
96
125
|
|
97
|
-
TInternet
|
98
|
-
|
99
|
-
|
100
|
-
|
126
|
+
expect(TInternet)
|
127
|
+
.to receive(:execute)
|
128
|
+
.once do |request|
|
129
|
+
expect(request.uri.path).to match(/#{expected_path}$/)
|
130
|
+
fake_ok_response
|
131
|
+
end
|
101
132
|
|
102
133
|
client.post "/xxx", {}
|
103
134
|
end
|
104
135
|
|
105
136
|
it "supports put" do
|
106
|
-
TInternet
|
137
|
+
expect(TInternet)
|
138
|
+
.to receive(:execute)
|
139
|
+
.once
|
140
|
+
.and_return fake_ok_response
|
107
141
|
|
108
142
|
client.put "/xxx", { phil: "T' north" }
|
109
143
|
end
|
@@ -111,10 +145,12 @@ describe Client, "and how it handles authorization" do
|
|
111
145
|
it "supplies the body for a put" do
|
112
146
|
expected_body = { name: "Phil", nickname: "The Crack Fox" }
|
113
147
|
|
114
|
-
TInternet
|
115
|
-
|
116
|
-
|
117
|
-
|
148
|
+
expect(TInternet)
|
149
|
+
.to receive(:execute)
|
150
|
+
.once do |request|
|
151
|
+
expect(request.body).to eq expected_body
|
152
|
+
fake_ok_response
|
153
|
+
end
|
118
154
|
|
119
155
|
client.put "/xxx", expected_body
|
120
156
|
end
|
@@ -122,10 +158,12 @@ describe Client, "and how it handles authorization" do
|
|
122
158
|
it "supplies the path for a put" do
|
123
159
|
expected_path = "/xxx"
|
124
160
|
|
125
|
-
TInternet
|
126
|
-
|
127
|
-
|
128
|
-
|
161
|
+
expect(TInternet)
|
162
|
+
.to receive(:execute)
|
163
|
+
.once do |request|
|
164
|
+
expect(request.uri.path).to match(/#{expected_path}$/)
|
165
|
+
fake_ok_response
|
166
|
+
end
|
129
167
|
|
130
168
|
client.put "/xxx", {}
|
131
169
|
end
|
@@ -141,10 +179,10 @@ describe Client, "and how it handles authorization" do
|
|
141
179
|
end
|
142
180
|
|
143
181
|
it "is configurable" do
|
144
|
-
client.consumer_key.
|
145
|
-
client.consumer_secret.
|
146
|
-
client.oauth_token.
|
147
|
-
client.oauth_token_secret.
|
182
|
+
expect(client.consumer_key).to eq('consumer_key')
|
183
|
+
expect(client.consumer_secret).to eq('consumer_secret')
|
184
|
+
expect(client.oauth_token).to eq('oauth_token')
|
185
|
+
expect(client.oauth_token_secret).to eq('oauth_token_secret')
|
148
186
|
end
|
149
187
|
end
|
150
188
|
|
@@ -157,10 +195,10 @@ describe Client, "and how it handles authorization" do
|
|
157
195
|
config.oauth_token_secret = 'oauth_token_secret'
|
158
196
|
end
|
159
197
|
|
160
|
-
client.consumer_key.
|
161
|
-
client.consumer_secret.
|
162
|
-
client.oauth_token.
|
163
|
-
client.oauth_token_secret.
|
198
|
+
expect(client.consumer_key).to eq('consumer_key')
|
199
|
+
expect(client.consumer_secret).to eq('consumer_secret')
|
200
|
+
expect(client.oauth_token).to eq('oauth_token')
|
201
|
+
expect(client.oauth_token_secret).to eq('oauth_token_secret')
|
164
202
|
end
|
165
203
|
end
|
166
204
|
end
|
data/spec/configuration_spec.rb
CHANGED
@@ -3,45 +3,26 @@ require 'spec_helper'
|
|
3
3
|
describe Trello::Configuration do
|
4
4
|
let(:configuration) { Trello::Configuration.new }
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
it 'has a oauth_token_secret attribute' do
|
22
|
-
configuration.oauth_token_secret = 'oauth_token_secret'
|
23
|
-
configuration.oauth_token_secret.should eq('oauth_token_secret')
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'has a developer public key attribute' do
|
27
|
-
configuration.developer_public_key = 'developer_public_key'
|
28
|
-
configuration.developer_public_key.should eq('developer_public_key')
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'has a member token attribute' do
|
32
|
-
configuration.member_token = 'member_token'
|
33
|
-
configuration.member_token.should eq('member_token')
|
6
|
+
[
|
7
|
+
:consumer_key,
|
8
|
+
:consumer_secret,
|
9
|
+
:oauth_token,
|
10
|
+
:oauth_token_secret,
|
11
|
+
:developer_public_key,
|
12
|
+
:member_token,
|
13
|
+
:return_url
|
14
|
+
|
15
|
+
].each do |attribute|
|
16
|
+
it "has a #{attribute} attribute" do
|
17
|
+
configuration.public_send(:"#{attribute}=", attribute)
|
18
|
+
expect(configuration.public_send(attribute)).to eq attribute
|
19
|
+
end
|
34
20
|
end
|
35
21
|
|
36
22
|
it 'has a callback (for oauth)' do
|
37
23
|
callback = -> { 'foobar' }
|
38
24
|
configuration.callback = callback
|
39
|
-
configuration.callback.call.
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'has a return_url' do
|
43
|
-
configuration.return_url = 'http://www.example.com/callback'
|
44
|
-
configuration.return_url.should eq('http://www.example.com/callback')
|
25
|
+
expect(configuration.callback.call).to eq('foobar')
|
45
26
|
end
|
46
27
|
|
47
28
|
describe 'initialize' do
|
@@ -52,10 +33,10 @@ describe Trello::Configuration do
|
|
52
33
|
oauth_token: 'oauth_token',
|
53
34
|
oauth_token_secret: 'oauth_token_secret'
|
54
35
|
)
|
55
|
-
configuration.consumer_key.
|
56
|
-
configuration.consumer_secret.
|
57
|
-
configuration.oauth_token.
|
58
|
-
configuration.oauth_token_secret.
|
36
|
+
expect(configuration.consumer_key).to eq('consumer_key')
|
37
|
+
expect(configuration.consumer_secret).to eq('consumer_secret')
|
38
|
+
expect(configuration.oauth_token).to eq('oauth_token')
|
39
|
+
expect(configuration.oauth_token_secret).to eq('oauth_token_secret')
|
59
40
|
end
|
60
41
|
end
|
61
42
|
|
@@ -63,11 +44,11 @@ describe Trello::Configuration do
|
|
63
44
|
let(:configuration) { Trello::Configuration.new(attributes) }
|
64
45
|
|
65
46
|
it 'returns an empty if no attributes specified' do
|
66
|
-
Trello::Configuration.new({}).credentials.
|
47
|
+
expect(Trello::Configuration.new({}).credentials).to eq({})
|
67
48
|
end
|
68
49
|
|
69
50
|
it 'returns an empty if attributes incomplete' do
|
70
|
-
Trello::Configuration.new(consumer_key: 'consumer_key').credentials.
|
51
|
+
expect(Trello::Configuration.new(consumer_key: 'consumer_key').credentials).to eq({})
|
71
52
|
end
|
72
53
|
|
73
54
|
it 'returns a hash of oauth attributes' do
|
@@ -77,7 +58,7 @@ describe Trello::Configuration do
|
|
77
58
|
oauth_token: 'oauth_token',
|
78
59
|
oauth_token_secret: 'oauth_token_secret'
|
79
60
|
)
|
80
|
-
configuration.credentials.
|
61
|
+
expect(configuration.credentials).to eq(
|
81
62
|
consumer_key: 'consumer_key',
|
82
63
|
consumer_secret: 'consumer_secret',
|
83
64
|
oauth_token: 'oauth_token',
|
@@ -92,7 +73,7 @@ describe Trello::Configuration do
|
|
92
73
|
return_url: 'http://example.com',
|
93
74
|
callback: 'callback'
|
94
75
|
)
|
95
|
-
configuration.credentials.
|
76
|
+
expect(configuration.credentials).to eq(
|
96
77
|
consumer_key: 'consumer_key',
|
97
78
|
consumer_secret: 'consumer_secret',
|
98
79
|
return_url: 'http://example.com',
|
@@ -105,7 +86,7 @@ describe Trello::Configuration do
|
|
105
86
|
developer_public_key: 'developer_public_key',
|
106
87
|
member_token: 'member_token'
|
107
88
|
)
|
108
|
-
configuration.credentials.
|
89
|
+
expect(configuration.credentials).to eq(
|
109
90
|
developer_public_key: 'developer_public_key',
|
110
91
|
member_token: 'member_token'
|
111
92
|
)
|