ruby-trello 0.2.1 → 0.3.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.
- data/README.md +6 -1
- data/lib/trello.rb +23 -3
- data/lib/trello/action.rb +1 -0
- data/lib/trello/authorization.rb +77 -0
- data/lib/trello/basic_data.rb +1 -2
- data/lib/trello/board.rb +33 -16
- data/lib/trello/card.rb +24 -3
- data/lib/trello/checklist.rb +1 -0
- data/lib/trello/client.rb +33 -48
- data/lib/trello/item.rb +1 -0
- data/lib/trello/item_state.rb +1 -0
- data/lib/trello/list.rb +19 -0
- data/lib/trello/member.rb +1 -0
- data/lib/trello/net.rb +35 -0
- data/lib/trello/notification.rb +1 -0
- data/lib/trello/organization.rb +1 -0
- data/lib/trello/string.rb +1 -1
- data/spec/action_spec.rb +39 -10
- data/spec/basic_auth_policy_spec.rb +56 -0
- data/spec/board_spec.rb +156 -13
- data/spec/card_spec.rb +58 -23
- data/spec/client_spec.rb +123 -22
- data/spec/integration/how_to_authorize_spec.rb +53 -0
- data/spec/integration/how_to_use_boards_spec.rb +48 -0
- data/spec/integration/integration_test.rb +40 -0
- data/spec/list_spec.rb +15 -9
- data/spec/member_spec.rb +14 -11
- data/spec/oauth_policy_spec.rb +83 -0
- data/spec/spec_helper.rb +27 -11
- data/spec/string_spec.rb +50 -0
- metadata +23 -9
data/lib/trello/member.rb
CHANGED
data/lib/trello/net.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module Trello
|
2
|
+
Request = Struct.new "Request", :verb, :uri, :headers, :body
|
3
|
+
Response = Struct.new "Response", :code, :headers, :body
|
4
|
+
|
5
|
+
class TInternet
|
6
|
+
class << self
|
7
|
+
def execute(request)
|
8
|
+
try_execute request
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def try_execute(request)
|
14
|
+
begin
|
15
|
+
result = execute_core request
|
16
|
+
Response.new(200, {}, result)
|
17
|
+
rescue Exception => e
|
18
|
+
Response.new(e.http_code, {}, e.http_body)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def execute_core(request)
|
23
|
+
require "rest_client"
|
24
|
+
|
25
|
+
RestClient::Request.execute(
|
26
|
+
:method => request.verb,
|
27
|
+
:url => request.uri.to_s,
|
28
|
+
:headers => request.headers,
|
29
|
+
:payload => request.body,
|
30
|
+
:timeout => 10
|
31
|
+
)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/trello/notification.rb
CHANGED
data/lib/trello/organization.rb
CHANGED
data/lib/trello/string.rb
CHANGED
data/spec/action_spec.rb
CHANGED
@@ -4,17 +4,11 @@ module Trello
|
|
4
4
|
describe Action do
|
5
5
|
include Helpers
|
6
6
|
|
7
|
-
before(:all) do
|
8
|
-
Client.public_key = 'dummy'
|
9
|
-
Client.secret = 'dummy'
|
10
|
-
end
|
11
|
-
|
12
7
|
before(:each) do
|
13
|
-
|
14
|
-
|
15
|
-
to_return(:status => 200, :headers => {}, :body => JSON.generate(actions_details.first))
|
8
|
+
Client.stub(:get).with("/actions/4ee2482134a81a757a08af47").
|
9
|
+
and_return JSON.generate(actions_details.first)
|
16
10
|
|
17
|
-
@action = Action.find('
|
11
|
+
@action = Action.find('4ee2482134a81a757a08af47')
|
18
12
|
end
|
19
13
|
|
20
14
|
context "fields" do
|
@@ -34,5 +28,40 @@ module Trello
|
|
34
28
|
@action.data.should == @detail['data']
|
35
29
|
end
|
36
30
|
end
|
31
|
+
|
32
|
+
context "boards" do
|
33
|
+
it "has a board" do
|
34
|
+
Client.stub(:get).with("/actions/4ee2482134a81a757a08af47/board").
|
35
|
+
and_return JSON.generate(boards_details.first)
|
36
|
+
|
37
|
+
@action.board.should_not be_nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "card" do
|
42
|
+
it "has a card" do
|
43
|
+
Client.stub(:get).with("/actions/4ee2482134a81a757a08af47/card").
|
44
|
+
and_return JSON.generate(cards_details.first)
|
45
|
+
|
46
|
+
@action.card.should_not be_nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context "list" do
|
51
|
+
it "has a list of lists" do
|
52
|
+
Client.stub(:get).with("/actions/4ee2482134a81a757a08af47/list").
|
53
|
+
and_return JSON.generate(lists_details.first)
|
54
|
+
|
55
|
+
@action.list.should_not be_nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "member creator" do
|
60
|
+
it "knows its member creator" do
|
61
|
+
Client.stub(:get).with("/members/abcdef123456789123456789").and_return user_payload
|
62
|
+
|
63
|
+
@action.member_creator.should_not be_nil
|
64
|
+
end
|
65
|
+
end
|
37
66
|
end
|
38
|
-
end
|
67
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
include Trello::Authorization
|
4
|
+
|
5
|
+
describe BasicAuthPolicy do
|
6
|
+
before do
|
7
|
+
BasicAuthPolicy.developer_public_key = "xxx"
|
8
|
+
BasicAuthPolicy.member_token = "xxx"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "adds key and token query parameters" do
|
12
|
+
BasicAuthPolicy.developer_public_key = "xxx_developer_public_key_xxx"
|
13
|
+
BasicAuthPolicy.member_token = "xxx_member_token_xxx"
|
14
|
+
|
15
|
+
uri = Addressable::URI.parse("https://xxx/")
|
16
|
+
|
17
|
+
request = Request.new :get, uri
|
18
|
+
|
19
|
+
authorized_request = BasicAuthPolicy.authorize request
|
20
|
+
|
21
|
+
the_query_parameters = Addressable::URI.parse(authorized_request.uri).query_values
|
22
|
+
|
23
|
+
the_query_parameters["key"].should === "xxx_developer_public_key_xxx"
|
24
|
+
the_query_parameters["token"].should === "xxx_member_token_xxx"
|
25
|
+
end
|
26
|
+
|
27
|
+
it "preserves other query parameters" do
|
28
|
+
uri = Addressable::URI.parse("https://xxx/?name=Phil")
|
29
|
+
|
30
|
+
request = Request.new :get, uri, {:example_header => "example_value"}
|
31
|
+
|
32
|
+
authorized_request = BasicAuthPolicy.authorize request
|
33
|
+
|
34
|
+
the_query_parameters = Addressable::URI.parse(authorized_request.uri).query_values
|
35
|
+
|
36
|
+
the_query_parameters["name"].should == "Phil"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "preserves headers" do
|
40
|
+
uri = Addressable::URI.parse("https://xxx/")
|
41
|
+
|
42
|
+
request = Request.new :get, uri, {:example_header => "example_value"}
|
43
|
+
|
44
|
+
authorized_request = BasicAuthPolicy.authorize request
|
45
|
+
|
46
|
+
authorized_request.headers.should === request.headers
|
47
|
+
end
|
48
|
+
|
49
|
+
it "returns nil body if one is supplied" do
|
50
|
+
uri = Addressable::URI.parse("https://xxx/")
|
51
|
+
request = Request.new :get, uri, {}, "any body"
|
52
|
+
BasicAuthPolicy.authorize(request).body.should be_nil
|
53
|
+
end
|
54
|
+
|
55
|
+
it "does what when a query parameter already exists called key or token?"
|
56
|
+
end
|
data/spec/board_spec.rb
CHANGED
@@ -4,15 +4,9 @@ module Trello
|
|
4
4
|
describe Board do
|
5
5
|
include Helpers
|
6
6
|
|
7
|
-
before(:all) do
|
8
|
-
Client.public_key = 'dummy'
|
9
|
-
Client.secret = 'dummy'
|
10
|
-
end
|
11
|
-
|
12
7
|
before(:each) do
|
13
|
-
|
14
|
-
|
15
|
-
to_return(:status => 200, :headers => {}, :body => JSON.generate(boards_details.first))
|
8
|
+
Client.stub(:get).with("/boards/abcdef123456789123456789").
|
9
|
+
and_return JSON.generate(boards_details.first)
|
16
10
|
|
17
11
|
@board = Board.find('abcdef123456789123456789')
|
18
12
|
end
|
@@ -31,7 +25,7 @@ module Trello
|
|
31
25
|
end
|
32
26
|
|
33
27
|
it "knows if it is closed or open" do
|
34
|
-
@board.closed
|
28
|
+
@board.closed?.should_not be_nil
|
35
29
|
end
|
36
30
|
|
37
31
|
it "gets its url" do
|
@@ -39,14 +33,163 @@ module Trello
|
|
39
33
|
end
|
40
34
|
end
|
41
35
|
|
36
|
+
context "actions" do
|
37
|
+
it "has a list of actions" do
|
38
|
+
Client.stub(:get).with("/boards/abcdef123456789123456789/actions").
|
39
|
+
and_return actions_payload
|
40
|
+
|
41
|
+
@board.actions.count.should be > 0
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
42
45
|
context "cards" do
|
43
46
|
it "gets its list of cards" do
|
44
|
-
|
45
|
-
|
46
|
-
to_return(:status => 200, :headers => {}, :body => cards_payload)
|
47
|
+
Client.stub(:get).with("/boards/abcdef123456789123456789/cards").
|
48
|
+
and_return cards_payload
|
47
49
|
|
48
50
|
@board.cards.count.should be > 0
|
49
51
|
end
|
50
52
|
end
|
53
|
+
|
54
|
+
context "lists" do
|
55
|
+
it "has a list of lists" do
|
56
|
+
Client.stub(:get).with("/boards/abcdef123456789123456789/lists", hash_including(:filter => :open)).
|
57
|
+
and_return lists_payload
|
58
|
+
|
59
|
+
@board.lists.count.should be > 0
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "members" do
|
64
|
+
it "has a list of members" do
|
65
|
+
Client.stub(:get).with("/boards/abcdef123456789123456789/members", hash_including(:filter => :all)).
|
66
|
+
and_return JSON.generate([user_details])
|
67
|
+
|
68
|
+
@board.members.count.should be > 0
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "organization" do
|
73
|
+
it "belongs to an organization" do
|
74
|
+
Client.stub(:get).with("/organizations/abcdef123456789123456789").
|
75
|
+
and_return JSON.generate(orgs_details.first)
|
76
|
+
|
77
|
+
@board.organization.should_not be_nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it "is not closed" do
|
82
|
+
@board.closed?.should_not be_true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "#update_fields" do
|
87
|
+
it "does not set any fields when the fields argument is empty" do
|
88
|
+
expected = {
|
89
|
+
'id' => "id",
|
90
|
+
'name' => "name",
|
91
|
+
'desc' => "desc",
|
92
|
+
'closed' => false,
|
93
|
+
'url' => "url",
|
94
|
+
'idOrganization' => "org_id"
|
95
|
+
}
|
96
|
+
|
97
|
+
board = Board.new(expected)
|
98
|
+
|
99
|
+
board.update_fields({})
|
100
|
+
|
101
|
+
expected.each_pair do |key, value|
|
102
|
+
if board.respond_to?(key)
|
103
|
+
board.send(key).should == value
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
board.description.should == expected['desc']
|
108
|
+
board.organization_id.should == expected['idOrganization']
|
109
|
+
end
|
110
|
+
|
111
|
+
it "sets any attributes supplied in the fields argument"
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "#save!" do
|
115
|
+
include Helpers
|
116
|
+
|
117
|
+
let(:any_board_json) do
|
118
|
+
JSON.generate(boards_details.first)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "cannot currently save a new instance" do
|
122
|
+
Client.should_not_receive :put
|
123
|
+
|
124
|
+
the_new_board = Board.new
|
125
|
+
lambda{the_new_board.save!}.should raise_error "Cannot save new instance."
|
126
|
+
end
|
127
|
+
|
128
|
+
it "puts all fields except id" do
|
129
|
+
expected_fields = %w{name description closed url organisation_id}.map{|s| s.to_sym}
|
130
|
+
|
131
|
+
Client.should_receive(:put) do |anything, body|
|
132
|
+
body.keys.should =~ expected_fields
|
133
|
+
any_board_json
|
134
|
+
end
|
135
|
+
|
136
|
+
the_new_board = Board.new 'id' => "xxx"
|
137
|
+
the_new_board.save!
|
138
|
+
end
|
139
|
+
|
140
|
+
it "mutates the current instance" do
|
141
|
+
Client.stub(:put).and_return any_board_json
|
142
|
+
|
143
|
+
board = Board.new 'id' => "xxx"
|
144
|
+
|
145
|
+
the_result_of_save = board.save!
|
146
|
+
|
147
|
+
the_result_of_save.should equal board
|
148
|
+
end
|
149
|
+
|
150
|
+
it "uses the correct resource" do
|
151
|
+
expected_resource_id = "xxx_board_id_xxx"
|
152
|
+
|
153
|
+
Client.should_receive(:put) do |path, anything|
|
154
|
+
path.should =~ /#{expected_resource_id}\/$/
|
155
|
+
any_board_json
|
156
|
+
end
|
157
|
+
|
158
|
+
the_new_board = Board.new 'id' => expected_resource_id
|
159
|
+
the_new_board.save!
|
160
|
+
end
|
161
|
+
|
162
|
+
it "saves OR updates depending on whether or not it has an id set"
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "Repository" do
|
166
|
+
include Helpers
|
167
|
+
|
168
|
+
let(:any_board_json) do
|
169
|
+
JSON.generate(boards_details.first)
|
170
|
+
end
|
171
|
+
|
172
|
+
it "creates a new board with whatever attributes are supplied " do
|
173
|
+
expected_attributes = { :name => "Any new board name", :description => "Any new board desription" }
|
174
|
+
|
175
|
+
Client.should_receive(:post).with(anything, expected_attributes).and_return any_board_json
|
176
|
+
|
177
|
+
Board.create expected_attributes
|
178
|
+
end
|
179
|
+
|
180
|
+
it "posts to the boards collection" do
|
181
|
+
Client.should_receive(:post).with("/boards/", anything).and_return any_board_json
|
182
|
+
|
183
|
+
Board.create :xxx => ""
|
184
|
+
end
|
185
|
+
|
186
|
+
it "returns a board" do
|
187
|
+
Client.stub(:post).with("/boards/", anything).and_return any_board_json
|
188
|
+
|
189
|
+
the_new_board = Board.create :xxx => ""
|
190
|
+
the_new_board.should be_a Board
|
191
|
+
end
|
192
|
+
|
193
|
+
it "at least name is required"
|
51
194
|
end
|
52
|
-
end
|
195
|
+
end
|
data/spec/card_spec.rb
CHANGED
@@ -4,15 +4,9 @@ module Trello
|
|
4
4
|
describe Card do
|
5
5
|
include Helpers
|
6
6
|
|
7
|
-
before(:all) do
|
8
|
-
Client.public_key = 'dummy'
|
9
|
-
Client.secret = 'dummy'
|
10
|
-
end
|
11
|
-
|
12
7
|
before(:each) do
|
13
|
-
|
14
|
-
|
15
|
-
to_return(:status => 200, :headers => {}, :body => JSON.generate(cards_details.first))
|
8
|
+
Client.stub(:get).with("/cards/abcdef123456789123456789").
|
9
|
+
and_return JSON.generate(cards_details.first)
|
16
10
|
|
17
11
|
@card = Card.find('abcdef123456789123456789')
|
18
12
|
end
|
@@ -33,14 +27,31 @@ module Trello
|
|
33
27
|
card.should_not be_valid
|
34
28
|
end
|
35
29
|
|
36
|
-
it 'creates a new record and saves it on Trello' do
|
30
|
+
it 'creates a new record and saves it on Trello', :refactor => true do
|
37
31
|
payload = {
|
38
32
|
:name => 'Test Card',
|
39
33
|
:desc => '',
|
40
34
|
}
|
41
|
-
|
42
|
-
|
43
|
-
|
35
|
+
|
36
|
+
result = JSON.generate(cards_details.first.merge(payload.merge(:idList => lists_details.first['id'])))
|
37
|
+
|
38
|
+
expected_payload = {:name => "Test Card", :desc => nil, :idList => "abcdef123456789123456789"}
|
39
|
+
|
40
|
+
Client.should_receive(:post).with("/cards", expected_payload).and_return result
|
41
|
+
|
42
|
+
card = Card.create(cards_details.first.merge(payload.merge(:list_id => lists_details.first['id'])))
|
43
|
+
|
44
|
+
card.class.should be Card
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "updating" do
|
49
|
+
it "updating name does a put on the correct resource with the correct value" do
|
50
|
+
expected_new_name = "xxx"
|
51
|
+
expected_resource = "/card/#{@card.id}/name"
|
52
|
+
|
53
|
+
Client.should_receive(:put).once.with expected_resource, :value => expected_new_name
|
54
|
+
@card.name = expected_new_name
|
44
55
|
end
|
45
56
|
end
|
46
57
|
|
@@ -66,28 +77,52 @@ module Trello
|
|
66
77
|
end
|
67
78
|
end
|
68
79
|
|
80
|
+
context "actions" do
|
81
|
+
it "has a list of actions" do
|
82
|
+
Client.stub(:get).with("/cards/abcdef123456789123456789/actions").and_return actions_payload
|
83
|
+
@card.actions.count.should be > 0
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
69
87
|
context "boards" do
|
70
88
|
it "has a board" do
|
71
|
-
|
72
|
-
with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
|
73
|
-
to_return(:status => 200, :headers => {}, :body => JSON.generate(boards_details.first))
|
74
|
-
|
89
|
+
Client.stub(:get).with("/boards/abcdef123456789123456789").and_return JSON.generate(boards_details.first)
|
75
90
|
@card.board.should_not be_nil
|
76
91
|
end
|
77
92
|
end
|
78
93
|
|
94
|
+
context "checklists" do
|
95
|
+
it "has a list of checklists" do
|
96
|
+
Client.stub(:get).with("/cards/abcdef123456789123456789/checklists", { :filter => :all }).and_return checklists_payload
|
97
|
+
@card.checklists.count.should be > 0
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "list" do
|
102
|
+
it 'has a list' do
|
103
|
+
Client.stub(:get).with("/lists/abcdef123456789123456789").and_return JSON.generate(lists_details.first)
|
104
|
+
@card.list.should_not be_nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
79
108
|
context "members" do
|
80
109
|
it "has a list of members" do
|
81
|
-
|
82
|
-
|
83
|
-
to_return(:status => 200, :headers => {}, :body => JSON.generate(boards_details.first))
|
84
|
-
stub_request(:get, "https://api.trello.com/1/members/abcdef123456789123456789?").
|
85
|
-
with(:headers => {'Accept'=>'*/*', 'Authorization'=>/.*/, 'User-Agent' => /.*/}).
|
86
|
-
to_return(:status => 200, :headers => {}, :body => user_payload)
|
110
|
+
Client.stub(:get).with("/boards/abcdef123456789123456789").and_return JSON.generate(boards_details.first)
|
111
|
+
Client.stub(:get).with("/members/abcdef123456789123456789").and_return user_payload
|
87
112
|
|
88
113
|
@card.board.should_not be_nil
|
89
114
|
@card.members.should_not be_nil
|
90
115
|
end
|
91
116
|
end
|
117
|
+
|
118
|
+
context "comments" do
|
119
|
+
it "posts a comment" do
|
120
|
+
Client.should_receive(:post).
|
121
|
+
with("/cards/abcdef123456789123456789/actions/comments", { :text => 'testing' }).
|
122
|
+
and_return JSON.generate(boards_details.first)
|
123
|
+
|
124
|
+
@card.add_comment "testing"
|
125
|
+
end
|
126
|
+
end
|
92
127
|
end
|
93
|
-
end
|
128
|
+
end
|