ruby-trello-wgibbs 0.4.3
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 +37 -0
- data/lib/trello/action.rb +46 -0
- data/lib/trello/association.rb +11 -0
- data/lib/trello/association_proxy.rb +42 -0
- data/lib/trello/authorization.rb +114 -0
- data/lib/trello/basic_data.rb +84 -0
- data/lib/trello/board.rb +95 -0
- data/lib/trello/card.rb +162 -0
- data/lib/trello/checklist.rb +82 -0
- data/lib/trello/client.rb +49 -0
- data/lib/trello/has_actions.rb +9 -0
- data/lib/trello/item.rb +18 -0
- data/lib/trello/item_state.rb +23 -0
- data/lib/trello/label.rb +19 -0
- data/lib/trello/list.rb +71 -0
- data/lib/trello/member.rb +93 -0
- data/lib/trello/multi_association.rb +10 -0
- data/lib/trello/net.rb +37 -0
- data/lib/trello/notification.rb +48 -0
- data/lib/trello/organization.rb +47 -0
- data/lib/trello/string.rb +36 -0
- data/lib/trello/token.rb +24 -0
- data/lib/trello.rb +83 -0
- data/spec/action_spec.rb +71 -0
- data/spec/basic_auth_policy_spec.rb +56 -0
- data/spec/board_spec.rb +196 -0
- data/spec/card_spec.rb +213 -0
- data/spec/checklist_spec.rb +50 -0
- data/spec/client_spec.rb +131 -0
- 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/item_spec.rb +27 -0
- data/spec/item_state_spec.rb +0 -0
- data/spec/list_spec.rb +50 -0
- data/spec/member_spec.rb +92 -0
- data/spec/notification_spec.rb +83 -0
- data/spec/oauth_policy_spec.rb +93 -0
- data/spec/organization_spec.rb +26 -0
- data/spec/spec_helper.rb +244 -0
- data/spec/string_spec.rb +50 -0
- data/spec/token_spec.rb +33 -0
- metadata +220 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'integration/integration_test'
|
3
|
+
|
4
|
+
describe "how to use boards", :broken => true do
|
5
|
+
include IntegrationTest
|
6
|
+
|
7
|
+
context "given a valid access token" do
|
8
|
+
before :all do
|
9
|
+
OAuthPolicy.consumer_credential = OAuthCredential.new @developer_public_key, @developer_secret
|
10
|
+
OAuthPolicy.token = OAuthCredential.new @access_token_key, @access_token_secret
|
11
|
+
Container.set Trello::Authorization, "AuthPolicy", OAuthPolicy
|
12
|
+
end
|
13
|
+
|
14
|
+
after do
|
15
|
+
if @new_board and false == @new_board.closed?
|
16
|
+
@new_board.update_fields 'closed' => true
|
17
|
+
@new_board.save
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "can add a board" do
|
22
|
+
@new_board = Board.create(:name => "An example")
|
23
|
+
@new_board.should_not be_nil
|
24
|
+
@new_board.id.should_not be_nil
|
25
|
+
@new_board.name.should == "An example"
|
26
|
+
@new_board.should_not be_closed
|
27
|
+
end
|
28
|
+
|
29
|
+
it "can read the welcome board" do
|
30
|
+
welcome_board = Board.find @welcome_board
|
31
|
+
welcome_board.name.should === "Welcome Board"
|
32
|
+
welcome_board.id.should === @welcome_board
|
33
|
+
end
|
34
|
+
|
35
|
+
it "can close a board" do
|
36
|
+
@new_board = Board.create(:name => "[#{Time.now}, CLOSED] An example")
|
37
|
+
|
38
|
+
@new_board.update_fields 'closed' => true
|
39
|
+
@new_board.save
|
40
|
+
|
41
|
+
Board.find(@new_board.id).should be_closed
|
42
|
+
end
|
43
|
+
|
44
|
+
it "can list all boards" do
|
45
|
+
Client.get("/members/me/boards/").json_into(Board).should be_an Array
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module IntegrationTest
|
2
|
+
include Trello
|
3
|
+
include Trello::Authorization
|
4
|
+
|
5
|
+
class Container
|
6
|
+
class << self
|
7
|
+
def set(parent, name, value)
|
8
|
+
parent.send :remove_const, name
|
9
|
+
parent.const_set name, value
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.included(klass)
|
15
|
+
klass.class_eval do
|
16
|
+
before :all do
|
17
|
+
# Getting developer/member key
|
18
|
+
# 1. https://trello.com/1/appKey/generate
|
19
|
+
# 2. https://trello.com/1/connect?key=<public_key_here>&name=RubyTrelloIntegrationTests&response_type=token
|
20
|
+
# See: https://trello.com/board/trello-public-api/4ed7e27fe6abb2517a21383d
|
21
|
+
|
22
|
+
@developer_public_key = ENV["DEVELOPER_PUBLIC_KEY"]
|
23
|
+
@developer_secret = ENV["DEVELOPER_SECRET"]
|
24
|
+
@member_token = ENV["MEMBER_TOKEN"]
|
25
|
+
@welcome_board = ENV["WELCOME_BOARD"]
|
26
|
+
@access_token_key = ENV["ACCESS_TOKEN_KEY"]
|
27
|
+
@access_token_secret = ENV["ACCESS_TOKEN_SECRET"]
|
28
|
+
|
29
|
+
WebMock.disable!
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
protected
|
35
|
+
|
36
|
+
def get(uri)
|
37
|
+
require "rest_client"
|
38
|
+
RestClient.get uri.to_s
|
39
|
+
end
|
40
|
+
end
|
data/spec/item_spec.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Trello
|
4
|
+
describe Item do
|
5
|
+
before(:all) do
|
6
|
+
@detail = {
|
7
|
+
'id' => "abcdef123456789123456789",
|
8
|
+
'name' => "test item",
|
9
|
+
'type' => "check"
|
10
|
+
}
|
11
|
+
|
12
|
+
@item = Item.new(@detail)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "gets its id" do
|
16
|
+
@item.id.should == @detail['id']
|
17
|
+
end
|
18
|
+
|
19
|
+
it "gets its name" do
|
20
|
+
@item.name.should == @detail['name']
|
21
|
+
end
|
22
|
+
|
23
|
+
it "knows its type" do
|
24
|
+
@item.type.should == @detail['type']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
File without changes
|
data/spec/list_spec.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Trello
|
4
|
+
describe List do
|
5
|
+
include Helpers
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
Client.stub(:get).with("/lists/abcdef123456789123456789").and_return JSON.generate(lists_details.first)
|
9
|
+
Client.stub(:get).with("/boards/abcdef123456789123456789").and_return JSON.generate(boards_details.first)
|
10
|
+
|
11
|
+
@list = List.find("abcdef123456789123456789")
|
12
|
+
end
|
13
|
+
|
14
|
+
context "fields" do
|
15
|
+
it "gets its id" do
|
16
|
+
@list.id.should == lists_details.first['id']
|
17
|
+
end
|
18
|
+
|
19
|
+
it "gets its name" do
|
20
|
+
@list.name.should == lists_details.first['name']
|
21
|
+
end
|
22
|
+
|
23
|
+
it "knows if it is open or closed" do
|
24
|
+
@list.closed.should == lists_details.first['closed']
|
25
|
+
end
|
26
|
+
|
27
|
+
it "has a board" do
|
28
|
+
@list.board.should == Board.new(boards_details.first)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "actions" do
|
33
|
+
it "has a list of actions" do
|
34
|
+
Client.stub(:get).with("/lists/abcdef123456789123456789/actions", { :filter => :all }).and_return actions_payload
|
35
|
+
@list.actions.count.should be > 0
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "cards" do
|
40
|
+
it "has a list of cards" do
|
41
|
+
Client.stub(:get).with("/lists/abcdef123456789123456789/cards", { :filter => :open }).and_return cards_payload
|
42
|
+
@list.cards.count.should be > 0
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "is not closed" do
|
47
|
+
@list.closed?.should_not be_true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/spec/member_spec.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# Specs covering the members namespace in the Trello API
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
module Trello
|
6
|
+
describe Member do
|
7
|
+
include Helpers
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
Client.stub(:get).with("/members/abcdef123456789012345678").and_return user_payload
|
11
|
+
|
12
|
+
@member = Member.find('abcdef123456789012345678')
|
13
|
+
end
|
14
|
+
|
15
|
+
context "actions" do
|
16
|
+
it "retrieves a list of actions", :refactor => true do
|
17
|
+
Client.stub(:get).with("/members/abcdef123456789012345678/actions", { :filter => :all }).and_return actions_payload
|
18
|
+
@member.actions.count.should be > 0
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "boards" do
|
23
|
+
it "has a list of boards" do
|
24
|
+
Client.stub(:get).with("/members/abcdef123456789012345678/boards", { :filter => :all }).and_return boards_payload
|
25
|
+
boards = @member.boards
|
26
|
+
boards.count.should be > 0
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "cards" do
|
31
|
+
it "has a list of cards" do
|
32
|
+
Client.stub(:get).with("/members/abcdef123456789012345678/cards", { :filter => :open }).and_return cards_payload
|
33
|
+
cards = @member.cards
|
34
|
+
cards.count.should be > 0
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "organizations" do
|
39
|
+
it "has a list of organizations" do
|
40
|
+
Client.stub(:get).with("/members/abcdef123456789012345678/organizations", { :filter => :all }).and_return orgs_payload
|
41
|
+
orgs = @member.organizations
|
42
|
+
orgs.count.should be > 0
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "notifications" do
|
47
|
+
it "has a list of notifications" do
|
48
|
+
Client.stub(:get).with("/members/abcdef123456789012345678/notifications", {}).and_return "[" << notification_payload << "]"
|
49
|
+
@member.notifications.count.should be 1
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "personal" do
|
54
|
+
it "gets the members bio" do
|
55
|
+
@member.bio.should == user_details['bio']
|
56
|
+
end
|
57
|
+
|
58
|
+
it "gets the full name" do
|
59
|
+
@member.full_name.should == user_details['fullName']
|
60
|
+
end
|
61
|
+
|
62
|
+
it "gets the avatar id" do
|
63
|
+
@member.avatar_id.should == user_details['avatarHash']
|
64
|
+
end
|
65
|
+
|
66
|
+
it "returns a valid url for the avatar" do
|
67
|
+
@member.avatar_url(:size => :large).should == "https://trello-avatars.s3.amazonaws.com/abcdef1234567890abcdef1234567890/170.png"
|
68
|
+
@member.avatar_url(:size => :small).should == "https://trello-avatars.s3.amazonaws.com/abcdef1234567890abcdef1234567890/30.png"
|
69
|
+
end
|
70
|
+
|
71
|
+
it "gets the url" do
|
72
|
+
@member.url.should == user_details['url']
|
73
|
+
end
|
74
|
+
|
75
|
+
it "gets the username" do
|
76
|
+
@member.username.should == user_details['username']
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "modification" do
|
81
|
+
it "lets us know a field has changed without committing it" do
|
82
|
+
@member.changed?.should be_false
|
83
|
+
@member.bio = "New and amazing"
|
84
|
+
@member.changed?.should be_true
|
85
|
+
end
|
86
|
+
|
87
|
+
it "doesn't understand the #id= method" do
|
88
|
+
lambda { @member.id = "42" }.should raise_error NoMethodError
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Trello
|
4
|
+
describe Notification do
|
5
|
+
include Helpers
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
Client.stub(:get).with("/members/abcdef123456789012345678").and_return user_payload
|
9
|
+
member = Member.find("abcdef123456789012345678")
|
10
|
+
Client.stub(:get).with("/members/abcdef123456789012345678/notifications", {}).and_return "[" << notification_payload << "]"
|
11
|
+
@notification = member.notifications.first
|
12
|
+
end
|
13
|
+
|
14
|
+
context "finding" do
|
15
|
+
it "can find a specific notification" do
|
16
|
+
Client.stub(:get).with("/notifications/#{notification_details['id']}").and_return notification_payload
|
17
|
+
Notification.find(notification_details['id']).should == @notification
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "boards" do
|
22
|
+
it "can retrieve the board" do
|
23
|
+
Client.stub(:get).with("/notifications/#{notification_details['id']}/board").and_return JSON.generate(boards_details.first)
|
24
|
+
@notification.board.id.should == boards_details.first['id']
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "lists" do
|
29
|
+
it "can retrieve the list" do
|
30
|
+
Client.stub(:get).with("/notifications/#{notification_details['id']}/list").and_return JSON.generate(lists_details.first)
|
31
|
+
@notification.list.id.should == lists_details.first['id']
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "cards" do
|
36
|
+
it "can retrieve the card" do
|
37
|
+
Client.stub(:get).with("/notifications/#{notification_details['id']}/card").and_return JSON.generate(cards_details.first)
|
38
|
+
@notification.card.id.should == cards_details.first['id']
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "members" do
|
43
|
+
it "can retrieve the member" do
|
44
|
+
Client.stub(:get).with("/notifications/#{notification_details['id']}/member").and_return user_payload
|
45
|
+
@notification.member.id.should == user_details['id']
|
46
|
+
end
|
47
|
+
|
48
|
+
it "can retrieve the member creator" do
|
49
|
+
Client.stub(:get).with("/members/#{user_details['id']}").and_return user_payload
|
50
|
+
@notification.member_creator.id.should == user_details['id']
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "organization" do
|
55
|
+
it "can retrieve the organization" do
|
56
|
+
Client.stub(:get).with("/notifications/#{notification_details['id']}/organization").and_return JSON.generate(orgs_details.first)
|
57
|
+
@notification.organization.id.should == orgs_details.first['id']
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "local" do
|
62
|
+
it "gets the read status" do
|
63
|
+
@notification.unread?.should == notification_details['unread']
|
64
|
+
end
|
65
|
+
|
66
|
+
it "gets the type" do
|
67
|
+
@notification.type.should == notification_details['type']
|
68
|
+
end
|
69
|
+
|
70
|
+
it "gets the date" do
|
71
|
+
@notification.date.should == notification_details['date']
|
72
|
+
end
|
73
|
+
|
74
|
+
it "gets the data" do
|
75
|
+
@notification.data.should == notification_details['data']
|
76
|
+
end
|
77
|
+
|
78
|
+
it "gets the member creator id" do
|
79
|
+
@notification.member_creator_id.should == notification_details['idMemberCreator']
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
include Trello::Authorization
|
4
|
+
include Trello
|
5
|
+
|
6
|
+
describe OAuthPolicy do
|
7
|
+
before do
|
8
|
+
OAuthPolicy.consumer_credential = OAuthCredential.new "xxx", "xxx"
|
9
|
+
OAuthPolicy.token = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
context "2-legged" do
|
13
|
+
it "adds an authorization header" do
|
14
|
+
uri = Addressable::URI.parse("https://xxx/")
|
15
|
+
|
16
|
+
request = Request.new :get, uri
|
17
|
+
|
18
|
+
OAuthPolicy.token = OAuthCredential.new "token", nil
|
19
|
+
|
20
|
+
authorized_request = OAuthPolicy.authorize request
|
21
|
+
|
22
|
+
authorized_request.headers.keys.should include "Authorization"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "preserves query parameters" do
|
26
|
+
uri = Addressable::URI.parse("https://xxx/?name=Riccardo")
|
27
|
+
request = Request.new :get, uri
|
28
|
+
|
29
|
+
Clock.stub(:timestamp).and_return "1327048592"
|
30
|
+
Nonce.stub(:next).and_return "b94ff2bf7f0a5e87a326064ae1dbb18f"
|
31
|
+
OAuthPolicy.consumer_credential = OAuthCredential.new "consumer_key", "consumer_secret"
|
32
|
+
OAuthPolicy.token = OAuthCredential.new "token", nil
|
33
|
+
|
34
|
+
authorized_request = OAuthPolicy.authorize request
|
35
|
+
|
36
|
+
the_query_parameters = Addressable::URI.parse(authorized_request.uri).query_values
|
37
|
+
the_query_parameters.should == {"name" => "Riccardo"}
|
38
|
+
end
|
39
|
+
|
40
|
+
it "adds the correct signature as part of authorization header" do
|
41
|
+
Clock.stub(:timestamp).and_return "1327048592"
|
42
|
+
Nonce.stub(:next).and_return "b94ff2bf7f0a5e87a326064ae1dbb18f"
|
43
|
+
|
44
|
+
OAuthPolicy.consumer_credential = OAuthCredential.new "consumer_key", "consumer_secret"
|
45
|
+
OAuthPolicy.token = OAuthCredential.new "token", nil
|
46
|
+
|
47
|
+
request = Request.new :get, Addressable::URI.parse("http://xxx/")
|
48
|
+
|
49
|
+
authorized_request = OAuthPolicy.authorize request
|
50
|
+
|
51
|
+
authorized_request.headers["Authorization"].should =~ /oauth_signature="kLcSxrCTd4ATHcLmTp8q%2Foa%2BFMA%3D"/
|
52
|
+
end
|
53
|
+
|
54
|
+
it "adds correct signature for uri with parameters" do
|
55
|
+
Clock.stub(:timestamp).and_return "1327351010"
|
56
|
+
Nonce.stub(:next).and_return "f5474aaf44ca84df0b09870044f91c69"
|
57
|
+
|
58
|
+
OAuthPolicy.consumer_credential = OAuthCredential.new "consumer_key", "consumer_secret"
|
59
|
+
OAuthPolicy.token = OAuthCredential.new "token", nil
|
60
|
+
|
61
|
+
request = Request.new :get, Addressable::URI.parse("http://xxx/?a=b")
|
62
|
+
|
63
|
+
authorized_request = OAuthPolicy.authorize request
|
64
|
+
|
65
|
+
authorized_request.headers["Authorization"].should =~ /oauth_signature="xm%2FJ1swxxPb6mnuR1Q1ucJMdGRk%3D"/
|
66
|
+
end
|
67
|
+
|
68
|
+
it "fails if consumer_credential is unset" do
|
69
|
+
OAuthPolicy.consumer_credential = nil
|
70
|
+
|
71
|
+
request = Request.new :get, Addressable::URI.parse("http://xxx/")
|
72
|
+
|
73
|
+
lambda{OAuthPolicy.authorize request}.should raise_error "The consumer_credential has not been supplied."
|
74
|
+
end
|
75
|
+
|
76
|
+
it "can sign with token" do
|
77
|
+
Clock.stub(:timestamp).and_return "1327360530"
|
78
|
+
Nonce.stub(:next).and_return "4f610cb28e7aa8711558de5234af1f0e"
|
79
|
+
|
80
|
+
OAuthPolicy.consumer_credential = OAuthCredential.new "consumer_key", "consumer_secret"
|
81
|
+
OAuthPolicy.token = OAuthCredential.new "token_key", "token_secret"
|
82
|
+
|
83
|
+
request = Request.new :get, Addressable::URI.parse("http://xxx/")
|
84
|
+
|
85
|
+
authorized_request = OAuthPolicy.authorize request
|
86
|
+
|
87
|
+
authorized_request.headers["Authorization"].should =~ /oauth_signature="3JeZSzsLCYnGNdVALZMgbzQKN44%3D"/
|
88
|
+
end
|
89
|
+
|
90
|
+
it "adds correct signature for https uri"
|
91
|
+
it "adds correct signature for verbs other than get"
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
module Trello
|
5
|
+
describe Organization do
|
6
|
+
include Helpers
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
Client.stub(:get).with("/organizations/4ee7e59ae582acdec8000291").
|
10
|
+
and_return organization_payload
|
11
|
+
|
12
|
+
@organization = Organization.find('4ee7e59ae582acdec8000291')
|
13
|
+
end
|
14
|
+
|
15
|
+
context "actions" do
|
16
|
+
it "retrieves actions" do
|
17
|
+
Client.stub(:get).with("/organizations/4ee7e59ae582acdec8000291/actions", { :filter => :all }).and_return actions_payload
|
18
|
+
@organization.actions.count.should be > 0
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|