ruby-trello 0.4.4.3 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +81 -8
- data/lib/trello.rb +25 -9
- data/lib/trello/action.rb +5 -5
- data/lib/trello/association_proxy.rb +3 -3
- data/lib/trello/authorization.rb +105 -49
- data/lib/trello/basic_data.rb +48 -4
- data/lib/trello/board.rb +10 -9
- data/lib/trello/card.rb +38 -35
- data/lib/trello/checklist.rb +10 -8
- data/lib/trello/client.rb +98 -29
- data/lib/trello/configuration.rb +68 -0
- data/lib/trello/has_actions.rb +1 -1
- data/lib/trello/list.rb +9 -7
- data/lib/trello/member.rb +3 -3
- data/lib/trello/multi_association.rb +4 -2
- data/lib/trello/notification.rb +8 -8
- data/lib/trello/organization.rb +3 -3
- data/lib/trello/token.rb +4 -4
- data/spec/action_spec.rb +30 -18
- data/spec/basic_auth_policy_spec.rb +1 -0
- data/spec/board_spec.rb +141 -120
- data/spec/card_spec.rb +104 -82
- data/spec/checklist_spec.rb +35 -6
- data/spec/client_spec.rb +56 -19
- data/spec/configuration_spec.rb +114 -0
- data/spec/integration/how_to_authorize_spec.rb +1 -1
- data/spec/list_spec.rb +74 -20
- data/spec/member_spec.rb +37 -23
- data/spec/notification_spec.rb +28 -24
- data/spec/oauth_policy_spec.rb +55 -9
- data/spec/organization_spec.rb +18 -7
- data/spec/spec_helper.rb +5 -0
- data/spec/token_spec.rb +25 -8
- data/spec/trello_spec.rb +73 -0
- metadata +10 -6
@@ -0,0 +1,114 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Trello::Configuration do
|
4
|
+
let(:configuration) { Trello::Configuration.new }
|
5
|
+
|
6
|
+
it "has a consumer_key attribute" do
|
7
|
+
configuration.consumer_key = 'consumer_key'
|
8
|
+
configuration.consumer_key.should eq('consumer_key')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "has a consumer_secret attribute" do
|
12
|
+
configuration.consumer_secret = 'consumer_secret'
|
13
|
+
configuration.consumer_secret.should eq('consumer_secret')
|
14
|
+
end
|
15
|
+
|
16
|
+
it "has a oauth_token attribute" do
|
17
|
+
configuration.oauth_token = 'oauth_token'
|
18
|
+
configuration.oauth_token.should eq('oauth_token')
|
19
|
+
end
|
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')
|
34
|
+
end
|
35
|
+
|
36
|
+
it "has a callback (for oauth)" do
|
37
|
+
callback = lambda { 'foobar' }
|
38
|
+
configuration.callback = callback
|
39
|
+
configuration.callback.call.should eq('foobar')
|
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")
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "initialize" do
|
48
|
+
it "sets key attributes provided as a hash" do
|
49
|
+
configuration = Trello::Configuration.new(
|
50
|
+
:consumer_key => 'consumer_key',
|
51
|
+
:consumer_secret => 'consumer_secret',
|
52
|
+
:oauth_token => 'oauth_token',
|
53
|
+
:oauth_token_secret => 'oauth_token_secret'
|
54
|
+
)
|
55
|
+
configuration.consumer_key.should eq('consumer_key')
|
56
|
+
configuration.consumer_secret.should eq('consumer_secret')
|
57
|
+
configuration.oauth_token.should eq('oauth_token')
|
58
|
+
configuration.oauth_token_secret.should eq('oauth_token_secret')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#credentials" do
|
63
|
+
let(:configuration) { Trello::Configuration.new(attributes) }
|
64
|
+
|
65
|
+
it "returns an empty if no attributes specified" do
|
66
|
+
Trello::Configuration.new({}).credentials.should eq({})
|
67
|
+
end
|
68
|
+
|
69
|
+
it "returns an empty if attributes incomplete" do
|
70
|
+
Trello::Configuration.new(:consumer_key => 'consumer_key').credentials.should eq({})
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'returns a hash of oauth attributes' do
|
74
|
+
configuration = Trello::Configuration.new(
|
75
|
+
:consumer_key => 'consumer_key',
|
76
|
+
:consumer_secret => 'consumer_secret',
|
77
|
+
:oauth_token => 'oauth_token',
|
78
|
+
:oauth_token_secret => 'oauth_token_secret'
|
79
|
+
)
|
80
|
+
configuration.credentials.should eq(
|
81
|
+
:consumer_key => 'consumer_key',
|
82
|
+
:consumer_secret => 'consumer_secret',
|
83
|
+
:oauth_token => 'oauth_token',
|
84
|
+
:oauth_token_secret => 'oauth_token_secret'
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'includes callback and return url if given' do
|
89
|
+
configuration = Trello::Configuration.new(
|
90
|
+
:consumer_key => 'consumer_key',
|
91
|
+
:consumer_secret => 'consumer_secret',
|
92
|
+
:return_url => 'http://example.com',
|
93
|
+
:callback => 'callback'
|
94
|
+
)
|
95
|
+
configuration.credentials.should eq(
|
96
|
+
:consumer_key => 'consumer_key',
|
97
|
+
:consumer_secret => 'consumer_secret',
|
98
|
+
:return_url => 'http://example.com',
|
99
|
+
:callback => 'callback'
|
100
|
+
)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "returns a hash of basic auth policy attributes" do
|
104
|
+
configuration = Trello::Configuration.new(
|
105
|
+
:developer_public_key => 'developer_public_key',
|
106
|
+
:member_token => 'member_token'
|
107
|
+
)
|
108
|
+
configuration.credentials.should eq(
|
109
|
+
:developer_public_key => 'developer_public_key',
|
110
|
+
:member_token => 'member_token'
|
111
|
+
)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -45,7 +45,7 @@ describe "OAuth", :broken => true do
|
|
45
45
|
it "[!] actually does not enforce signature at all, only the keys are required" do
|
46
46
|
OAuthPolicy.consumer_credential = OAuthCredential.new @developer_public_key, nil
|
47
47
|
OAuthPolicy.token = OAuthCredential.new @access_token_key, nil
|
48
|
-
|
48
|
+
|
49
49
|
pending "I would expect this to fail because I have signed with nil secrets" do
|
50
50
|
lambda{Client.get("/boards/#{@welcome_board}/")}.should raise_error
|
51
51
|
end
|
data/spec/list_spec.rb
CHANGED
@@ -4,11 +4,61 @@ module Trello
|
|
4
4
|
describe List do
|
5
5
|
include Helpers
|
6
6
|
|
7
|
+
let(:list) { client.find(:list, "abcdef123456789123456789") }
|
8
|
+
let(:client) { Client.new }
|
9
|
+
|
7
10
|
before(:each) do
|
8
|
-
|
9
|
-
|
11
|
+
client.stub(:get).with("/lists/abcdef123456789123456789").and_return JSON.generate(lists_details.first)
|
12
|
+
client.stub(:get).with("/boards/abcdef123456789123456789").and_return JSON.generate(boards_details.first)
|
13
|
+
end
|
10
14
|
|
11
|
-
|
15
|
+
context "finding" do
|
16
|
+
let(:client) { Trello.client }
|
17
|
+
|
18
|
+
it "delegates to client#find" do
|
19
|
+
client.should_receive(:find).with(:list, 'abcdef123456789123456789')
|
20
|
+
List.find('abcdef123456789123456789')
|
21
|
+
end
|
22
|
+
|
23
|
+
it "is equivalent to client#find" do
|
24
|
+
List.find('abcdef123456789123456789').should eq(list)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "creating" do
|
29
|
+
let(:client) { Trello.client }
|
30
|
+
|
31
|
+
it "creates a new record" do
|
32
|
+
list = List.new(lists_details.first)
|
33
|
+
list.should be_valid
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'must not be valid if not given a name' do
|
37
|
+
list = List.new(lists_details.first.except('name'))
|
38
|
+
list.should_not be_valid
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'must not be valid if not given a list id' do
|
42
|
+
list = List.new(lists_details.first.except('id'))
|
43
|
+
list.should_not be_valid
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'creates a new record and saves it on Trello', :refactor => true do
|
47
|
+
payload = {
|
48
|
+
:name => 'Test List',
|
49
|
+
:board_id => 'abcdef123456789123456789'
|
50
|
+
}
|
51
|
+
|
52
|
+
result = JSON.generate(payload)
|
53
|
+
|
54
|
+
expected_payload = {:name => "Test List", :closed => false, :idBoard => "abcdef123456789123456789"}
|
55
|
+
|
56
|
+
client.should_receive(:post).with("/lists", expected_payload).and_return result
|
57
|
+
|
58
|
+
list = List.create(payload)
|
59
|
+
|
60
|
+
list.class.should be List
|
61
|
+
end
|
12
62
|
end
|
13
63
|
|
14
64
|
context "updating" do
|
@@ -20,65 +70,69 @@ module Trello
|
|
20
70
|
:closed => false
|
21
71
|
}
|
22
72
|
|
23
|
-
|
24
|
-
|
25
|
-
|
73
|
+
client.should_receive(:put).once.with("/lists/abcdef123456789123456789", payload)
|
74
|
+
list.name = expected_new_name
|
75
|
+
list.save
|
26
76
|
end
|
27
77
|
end
|
28
78
|
|
29
79
|
context "fields" do
|
30
80
|
it "gets its id" do
|
31
|
-
|
81
|
+
list.id.should == lists_details.first['id']
|
32
82
|
end
|
33
83
|
|
34
84
|
it "gets its name" do
|
35
|
-
|
85
|
+
list.name.should == lists_details.first['name']
|
36
86
|
end
|
37
87
|
|
38
88
|
it "knows if it is open or closed" do
|
39
|
-
|
89
|
+
list.closed.should == lists_details.first['closed']
|
40
90
|
end
|
41
91
|
|
42
92
|
it "has a board" do
|
43
|
-
|
93
|
+
list.board.should == Board.new(boards_details.first)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "gets its position" do
|
97
|
+
list.pos.should == lists_details.first['pos']
|
44
98
|
end
|
45
99
|
end
|
46
100
|
|
47
101
|
context "actions" do
|
48
102
|
it "has a list of actions" do
|
49
|
-
|
50
|
-
|
103
|
+
client.stub(:get).with("/lists/abcdef123456789123456789/actions", { :filter => :all }).and_return actions_payload
|
104
|
+
list.actions.count.should be > 0
|
51
105
|
end
|
52
106
|
end
|
53
107
|
|
54
108
|
context "cards" do
|
55
109
|
it "has a list of cards" do
|
56
|
-
|
57
|
-
|
110
|
+
client.stub(:get).with("/lists/abcdef123456789123456789/cards", { :filter => :open }).and_return cards_payload
|
111
|
+
list.cards.count.should be > 0
|
58
112
|
end
|
59
113
|
end
|
60
114
|
|
61
115
|
describe "#closed?" do
|
62
116
|
it "returns the closed attribute" do
|
63
|
-
|
117
|
+
list.closed?.should_not be_true
|
64
118
|
end
|
65
119
|
end
|
66
120
|
|
67
121
|
describe "#close" do
|
68
122
|
it "updates the close attribute to true" do
|
69
|
-
|
70
|
-
|
123
|
+
list.close
|
124
|
+
list.closed.should be_true
|
71
125
|
end
|
72
126
|
end
|
73
127
|
|
74
128
|
describe "#close!" do
|
75
129
|
it "updates the close attribute to true and saves the list" do
|
76
|
-
|
77
|
-
:name =>
|
130
|
+
client.should_receive(:put).once.with("/lists/abcdef123456789123456789", {
|
131
|
+
:name => list.name,
|
78
132
|
:closed => true
|
79
133
|
})
|
80
134
|
|
81
|
-
|
135
|
+
list.close!
|
82
136
|
end
|
83
137
|
end
|
84
138
|
end
|
data/spec/member_spec.rb
CHANGED
@@ -6,86 +6,100 @@ module Trello
|
|
6
6
|
describe Member do
|
7
7
|
include Helpers
|
8
8
|
|
9
|
+
let(:member) { client.find(:member, 'abcdef123456789012345678') }
|
10
|
+
let(:client) { Client.new }
|
11
|
+
|
9
12
|
before(:each) do
|
10
|
-
|
13
|
+
client.stub(:get).with("/members/abcdef123456789012345678").and_return user_payload
|
14
|
+
end
|
15
|
+
|
16
|
+
context "finding" do
|
17
|
+
let(:client) { Trello.client }
|
11
18
|
|
12
|
-
|
19
|
+
it "delegates to Trello.client#find" do
|
20
|
+
client.should_receive(:find).with(:member, 'abcdef123456789012345678')
|
21
|
+
Member.find('abcdef123456789012345678')
|
22
|
+
end
|
23
|
+
|
24
|
+
it "is equivalent to client#find" do
|
25
|
+
Member.find('abcdef123456789012345678').should eq(member)
|
26
|
+
end
|
13
27
|
end
|
14
28
|
|
15
29
|
context "actions" do
|
16
30
|
it "retrieves a list of actions", :refactor => true do
|
17
|
-
|
18
|
-
|
31
|
+
client.stub(:get).with("/members/abcdef123456789012345678/actions", { :filter => :all }).and_return actions_payload
|
32
|
+
member.actions.count.should be > 0
|
19
33
|
end
|
20
34
|
end
|
21
35
|
|
22
36
|
context "boards" do
|
23
37
|
it "has a list of boards" do
|
24
|
-
|
25
|
-
boards =
|
38
|
+
client.stub(:get).with("/members/abcdef123456789012345678/boards", { :filter => :all }).and_return boards_payload
|
39
|
+
boards = member.boards
|
26
40
|
boards.count.should be > 0
|
27
41
|
end
|
28
42
|
end
|
29
43
|
|
30
44
|
context "cards" do
|
31
45
|
it "has a list of cards" do
|
32
|
-
|
33
|
-
cards =
|
46
|
+
client.stub(:get).with("/members/abcdef123456789012345678/cards", { :filter => :open }).and_return cards_payload
|
47
|
+
cards = member.cards
|
34
48
|
cards.count.should be > 0
|
35
49
|
end
|
36
50
|
end
|
37
51
|
|
38
52
|
context "organizations" do
|
39
53
|
it "has a list of organizations" do
|
40
|
-
|
41
|
-
orgs =
|
54
|
+
client.stub(:get).with("/members/abcdef123456789012345678/organizations", { :filter => :all }).and_return orgs_payload
|
55
|
+
orgs = member.organizations
|
42
56
|
orgs.count.should be > 0
|
43
57
|
end
|
44
58
|
end
|
45
59
|
|
46
60
|
context "notifications" do
|
47
61
|
it "has a list of notifications" do
|
48
|
-
|
49
|
-
|
62
|
+
client.stub(:get).with("/members/abcdef123456789012345678/notifications", {}).and_return "[" << notification_payload << "]"
|
63
|
+
member.notifications.count.should be 1
|
50
64
|
end
|
51
65
|
end
|
52
66
|
|
53
67
|
context "personal" do
|
54
68
|
it "gets the members bio" do
|
55
|
-
|
69
|
+
member.bio.should == user_details['bio']
|
56
70
|
end
|
57
71
|
|
58
72
|
it "gets the full name" do
|
59
|
-
|
73
|
+
member.full_name.should == user_details['fullName']
|
60
74
|
end
|
61
75
|
|
62
76
|
it "gets the avatar id" do
|
63
|
-
|
77
|
+
member.avatar_id.should == user_details['avatarHash']
|
64
78
|
end
|
65
79
|
|
66
80
|
it "returns a valid url for the avatar" do
|
67
|
-
|
68
|
-
|
81
|
+
member.avatar_url(:size => :large).should == "https://trello-avatars.s3.amazonaws.com/abcdef1234567890abcdef1234567890/170.png"
|
82
|
+
member.avatar_url(:size => :small).should == "https://trello-avatars.s3.amazonaws.com/abcdef1234567890abcdef1234567890/30.png"
|
69
83
|
end
|
70
84
|
|
71
85
|
it "gets the url" do
|
72
|
-
|
86
|
+
member.url.should == user_details['url']
|
73
87
|
end
|
74
88
|
|
75
89
|
it "gets the username" do
|
76
|
-
|
90
|
+
member.username.should == user_details['username']
|
77
91
|
end
|
78
92
|
end
|
79
93
|
|
80
94
|
context "modification" do
|
81
95
|
it "lets us know a field has changed without committing it" do
|
82
|
-
|
83
|
-
|
84
|
-
|
96
|
+
member.changed?.should be_false
|
97
|
+
member.bio = "New and amazing"
|
98
|
+
member.changed?.should be_true
|
85
99
|
end
|
86
100
|
|
87
101
|
it "doesn't understand the #id= method" do
|
88
|
-
lambda {
|
102
|
+
lambda { member.id = "42" }.should raise_error NoMethodError
|
89
103
|
end
|
90
104
|
end
|
91
105
|
end
|
data/spec/notification_spec.rb
CHANGED
@@ -4,80 +4,84 @@ module Trello
|
|
4
4
|
describe Notification do
|
5
5
|
include Helpers
|
6
6
|
|
7
|
+
let(:notification) { member.notifications.first }
|
8
|
+
let(:member) { client.find(:member, "abcdef123456789012345678") }
|
9
|
+
let(:client) { Client.new }
|
10
|
+
|
7
11
|
before(:each) do
|
8
|
-
|
9
|
-
|
10
|
-
Client.stub(:get).with("/members/abcdef123456789012345678/notifications", {}).and_return "[" << notification_payload << "]"
|
11
|
-
@notification = member.notifications.first
|
12
|
+
client.stub(:get).with("/members/abcdef123456789012345678").and_return user_payload
|
13
|
+
client.stub(:get).with("/members/abcdef123456789012345678/notifications", {}).and_return "[" << notification_payload << "]"
|
12
14
|
end
|
13
15
|
|
14
16
|
context "finding" do
|
17
|
+
let(:client) { Trello.client }
|
18
|
+
|
15
19
|
it "can find a specific notification" do
|
16
|
-
|
17
|
-
Notification.find(notification_details['id']).should ==
|
20
|
+
client.stub(:get).with("/notifications/#{notification_details['id']}").and_return notification_payload
|
21
|
+
Notification.find(notification_details['id']).should == notification
|
18
22
|
end
|
19
23
|
end
|
20
24
|
|
21
25
|
context "boards" do
|
22
26
|
it "can retrieve the board" do
|
23
|
-
|
24
|
-
|
27
|
+
client.stub(:get).with("/notifications/#{notification_details['id']}/board").and_return JSON.generate(boards_details.first)
|
28
|
+
notification.board.id.should == boards_details.first['id']
|
25
29
|
end
|
26
30
|
end
|
27
31
|
|
28
32
|
context "lists" do
|
29
33
|
it "can retrieve the list" do
|
30
|
-
|
31
|
-
|
34
|
+
client.stub(:get).with("/notifications/#{notification_details['id']}/list").and_return JSON.generate(lists_details.first)
|
35
|
+
notification.list.id.should == lists_details.first['id']
|
32
36
|
end
|
33
37
|
end
|
34
38
|
|
35
39
|
context "cards" do
|
36
40
|
it "can retrieve the card" do
|
37
|
-
|
38
|
-
|
41
|
+
client.stub(:get).with("/notifications/#{notification_details['id']}/card").and_return JSON.generate(cards_details.first)
|
42
|
+
notification.card.id.should == cards_details.first['id']
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
42
46
|
context "members" do
|
43
47
|
it "can retrieve the member" do
|
44
|
-
|
45
|
-
|
48
|
+
client.stub(:get).with("/notifications/#{notification_details['id']}/member").and_return user_payload
|
49
|
+
notification.member.id.should == user_details['id']
|
46
50
|
end
|
47
51
|
|
48
52
|
it "can retrieve the member creator" do
|
49
|
-
|
50
|
-
|
53
|
+
client.stub(:get).with("/members/#{user_details['id']}").and_return user_payload
|
54
|
+
notification.member_creator.id.should == user_details['id']
|
51
55
|
end
|
52
56
|
end
|
53
57
|
|
54
58
|
context "organization" do
|
55
59
|
it "can retrieve the organization" do
|
56
|
-
|
57
|
-
|
60
|
+
client.stub(:get).with("/notifications/#{notification_details['id']}/organization").and_return JSON.generate(orgs_details.first)
|
61
|
+
notification.organization.id.should == orgs_details.first['id']
|
58
62
|
end
|
59
63
|
end
|
60
64
|
|
61
65
|
context "local" do
|
62
66
|
it "gets the read status" do
|
63
|
-
|
67
|
+
notification.unread?.should == notification_details['unread']
|
64
68
|
end
|
65
69
|
|
66
70
|
it "gets the type" do
|
67
|
-
|
71
|
+
notification.type.should == notification_details['type']
|
68
72
|
end
|
69
73
|
|
70
74
|
it "gets the date" do
|
71
|
-
|
75
|
+
notification.date.should == notification_details['date']
|
72
76
|
end
|
73
77
|
|
74
78
|
it "gets the data" do
|
75
|
-
|
79
|
+
notification.data.should == notification_details['data']
|
76
80
|
end
|
77
81
|
|
78
82
|
it "gets the member creator id" do
|
79
|
-
|
83
|
+
notification.member_creator_id.should == notification_details['idMemberCreator']
|
80
84
|
end
|
81
85
|
end
|
82
86
|
end
|
83
|
-
end
|
87
|
+
end
|