ruby-trello-wgibbs 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- 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,49 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
|
3
|
+
module Trello
|
4
|
+
class Client
|
5
|
+
extend Authorization
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def get(path, params = {})
|
9
|
+
uri = Addressable::URI.parse("https://api.trello.com/#{API_VERSION}#{path}")
|
10
|
+
uri.query_values = params unless params.empty?
|
11
|
+
invoke_verb(:get, uri)
|
12
|
+
end
|
13
|
+
|
14
|
+
def post(path, body = {})
|
15
|
+
uri = Addressable::URI.parse("https://api.trello.com/#{API_VERSION}#{path}")
|
16
|
+
invoke_verb(:post, uri, body)
|
17
|
+
end
|
18
|
+
|
19
|
+
def put(path, body = {})
|
20
|
+
uri = Addressable::URI.parse("https://api.trello.com/#{API_VERSION}#{path}")
|
21
|
+
invoke_verb(:put, uri, body)
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete(path)
|
25
|
+
uri = Addressable::URI.parse("https://api.trello.com/#{API_VERSION}#{path}")
|
26
|
+
invoke_verb(:delete, uri)
|
27
|
+
end
|
28
|
+
|
29
|
+
def invoke_verb(name, uri, body = nil)
|
30
|
+
request = Request.new name, uri, {}, body
|
31
|
+
response = TInternet.execute AuthPolicy.authorize(request)
|
32
|
+
|
33
|
+
return '' unless response
|
34
|
+
|
35
|
+
if response.code.to_i == 401 && response.body =~ /expired token/
|
36
|
+
Trello.logger.error("[401 #{name.to_s.upcase} #{uri}]: Your access token has expired.")
|
37
|
+
raise InvalidAccessToken, response.body
|
38
|
+
end
|
39
|
+
|
40
|
+
unless [200, 201].include? response.code
|
41
|
+
Trello.logger.error("[#{response.code} #{name.to_s.upcase} #{uri}]: #{response.body}")
|
42
|
+
raise Error, response.body
|
43
|
+
end
|
44
|
+
|
45
|
+
response.body
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Trello
|
2
|
+
module HasActions
|
3
|
+
# Returns a list of the actions associated with this object.
|
4
|
+
def actions(options = {})
|
5
|
+
actions = Client.get("#{request_prefix}/actions", { :filter => :all }.merge(options)).json_into(Action)
|
6
|
+
MultiAssociation.new(self, actions).proxy
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
data/lib/trello/item.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Trello
|
2
|
+
# An Item is a basic task that can be checked off and marked as completed.
|
3
|
+
class Item < BasicData
|
4
|
+
register_attributes :id, :name, :type, :readonly => [ :id, :name, :type ]
|
5
|
+
validates_presence_of :id, :type
|
6
|
+
|
7
|
+
# Updates the fields of an item.
|
8
|
+
#
|
9
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
10
|
+
# an item.
|
11
|
+
def update_fields(fields)
|
12
|
+
attributes[:id] = fields['id']
|
13
|
+
attributes[:name] = fields['name']
|
14
|
+
attributes[:type] = fields['type']
|
15
|
+
self
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Trello
|
2
|
+
# Represents the state of an item.
|
3
|
+
class ItemState < BasicData
|
4
|
+
register_attributes :id, :state, :item_id, :readonly => [ :id, :state, :item_id ]
|
5
|
+
validates_presence_of :id, :item_id
|
6
|
+
|
7
|
+
# Update the fields of an item state.
|
8
|
+
#
|
9
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
10
|
+
# an item state.
|
11
|
+
def update_fields(fields)
|
12
|
+
attributes[:id] = fields['id']
|
13
|
+
attributes[:state] = fields['state']
|
14
|
+
attributes[:item_id] = fields['idItem']
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
# Return the item this state belongs to.
|
19
|
+
def item
|
20
|
+
Item.find(item_id)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/trello/label.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Trello
|
2
|
+
|
3
|
+
# A colored Label attached to a card
|
4
|
+
class Label < BasicData
|
5
|
+
register_attributes :name, :color
|
6
|
+
|
7
|
+
# Update the fields of a label.
|
8
|
+
#
|
9
|
+
# Supply a hash of stringkeyed data retrieved from the Trello API representing
|
10
|
+
# a label.
|
11
|
+
def update_fields(fields)
|
12
|
+
attributes[:name] = fields['name']
|
13
|
+
attributes[:color] = fields['color']
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/lib/trello/list.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
module Trello
|
2
|
+
# A List is a container which holds cards. Lists are items on a board.
|
3
|
+
class List < BasicData
|
4
|
+
register_attributes :id, :name, :closed, :board_id, :readonly => [ :id, :board_id ]
|
5
|
+
validates_presence_of :id, :name, :board_id
|
6
|
+
validates_length_of :name, :in => 1..16384
|
7
|
+
|
8
|
+
include HasActions
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# Finds a specific list, given an id.
|
12
|
+
def find(id)
|
13
|
+
super(:lists, id)
|
14
|
+
end
|
15
|
+
|
16
|
+
def create(options)
|
17
|
+
new('name' => options[:name],
|
18
|
+
'idBoard' => options[:board_id]).save
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Updates the fields of a list.
|
23
|
+
#
|
24
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
25
|
+
# a List.
|
26
|
+
def update_fields(fields)
|
27
|
+
attributes[:id] = fields['id']
|
28
|
+
attributes[:name] = fields['name']
|
29
|
+
attributes[:closed] = fields['closed']
|
30
|
+
attributes[:board_id] = fields['idBoard']
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def save
|
35
|
+
return update! if id
|
36
|
+
|
37
|
+
Client.post("/lists", {
|
38
|
+
:name => name,
|
39
|
+
:closed => closed || false,
|
40
|
+
:idBoard => board_id
|
41
|
+
}).json_into(self)
|
42
|
+
end
|
43
|
+
|
44
|
+
def update!
|
45
|
+
Client.put("/lists", {
|
46
|
+
:name => name,
|
47
|
+
:closed => closed
|
48
|
+
}).json_into(self)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Check if the list is not active anymore.
|
52
|
+
def closed?
|
53
|
+
closed
|
54
|
+
end
|
55
|
+
|
56
|
+
# Return the board the list is connected to.
|
57
|
+
one :board, :using => :board_id
|
58
|
+
|
59
|
+
# Returns all the cards on this list.
|
60
|
+
#
|
61
|
+
# The options hash may have a filter key which can have its value set as any
|
62
|
+
# of the following values:
|
63
|
+
# :filter => [ :none, :open, :closed, :all ] # default :open
|
64
|
+
many :cards, :filter => :open
|
65
|
+
|
66
|
+
# :nodoc:
|
67
|
+
def request_prefix
|
68
|
+
"/lists/#{id}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module Trello
|
2
|
+
# A Member is a user of the Trello service.
|
3
|
+
class Member < BasicData
|
4
|
+
register_attributes :id, :username, :full_name, :avatar_id, :bio, :url, :readonly => [ :id, :username, :avatar_id, :url ]
|
5
|
+
validates_presence_of :id, :username
|
6
|
+
validates_length_of :full_name, :minimum => 4
|
7
|
+
validates_length_of :bio, :maximum => 16384
|
8
|
+
|
9
|
+
include HasActions
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# Finds a user
|
13
|
+
#
|
14
|
+
# The argument may be specified as either an _id_ or a _username_.
|
15
|
+
def find(id_or_username)
|
16
|
+
super(:members, id_or_username)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Update the fields of a member.
|
21
|
+
#
|
22
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
23
|
+
# an Member.
|
24
|
+
def update_fields(fields)
|
25
|
+
attributes[:id] = fields['id']
|
26
|
+
attributes[:full_name] = fields['fullName']
|
27
|
+
attributes[:username] = fields['username']
|
28
|
+
attributes[:avatar_id] = fields['avatarHash']
|
29
|
+
attributes[:bio] = fields['bio']
|
30
|
+
attributes[:url] = fields['url']
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
# Retrieve a URL to the avatar.
|
35
|
+
#
|
36
|
+
# Valid values for options are:
|
37
|
+
# :large (170x170)
|
38
|
+
# :small (30x30)
|
39
|
+
def avatar_url(options = { :size => :large })
|
40
|
+
size = options[:size] == :small ? 30 : 170
|
41
|
+
"https://trello-avatars.s3.amazonaws.com/#{avatar_id}/#{size}.png"
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns a list of the boards a member is a part of.
|
45
|
+
#
|
46
|
+
# This method, when called, can take a hash table with a filter key containing any
|
47
|
+
# of the following values:
|
48
|
+
# :filter => [ :none, :members, :organization, :public, :open, :closed, :all ] # default: :all
|
49
|
+
# i.e.,
|
50
|
+
# me.boards(:filter => :closed) # retrieves all closed boards
|
51
|
+
many :boards, :filter => :all
|
52
|
+
|
53
|
+
# Returns a list of cards the member is assigned to.
|
54
|
+
#
|
55
|
+
# This method, when called, can take a hash table with a filter key containing any
|
56
|
+
# of the following values:
|
57
|
+
# :filter => [ :none, :open, :closed, :all ] # default :open
|
58
|
+
# i.e.,
|
59
|
+
# me.cards(:filter => :closed) # retrieves all closed cards
|
60
|
+
many :cards, :filter => :open
|
61
|
+
|
62
|
+
# Returns a list of the organizations this member is a part of.
|
63
|
+
#
|
64
|
+
# This method, when called, can take a hash table with a filter key containing any
|
65
|
+
# of the following values:
|
66
|
+
# :filter => [ :none, :members, :public, :all ] # default: all
|
67
|
+
# i.e.,
|
68
|
+
# me.organizations(:filter => :public) # retrieves all public organizations
|
69
|
+
many :organizations, :filter => :all
|
70
|
+
|
71
|
+
# Returns a list of notifications for the user
|
72
|
+
many :notifications
|
73
|
+
|
74
|
+
def save
|
75
|
+
@previously_changed = changes
|
76
|
+
@changed_attributes.clear
|
77
|
+
|
78
|
+
return update! if id
|
79
|
+
end
|
80
|
+
|
81
|
+
def update!
|
82
|
+
Client.put(request_prefix, {
|
83
|
+
:fullName => full_name,
|
84
|
+
:bio => bio
|
85
|
+
}).json_into(self)
|
86
|
+
end
|
87
|
+
|
88
|
+
# :nodoc:
|
89
|
+
def request_prefix
|
90
|
+
"/members/#{id}"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
data/lib/trello/net.rb
ADDED
@@ -0,0 +1,37 @@
|
|
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
|
+
if request
|
16
|
+
result = execute_core request
|
17
|
+
Response.new(200, {}, result)
|
18
|
+
end
|
19
|
+
rescue Exception => e
|
20
|
+
Response.new(e.http_code, {}, e.http_body)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def execute_core(request)
|
25
|
+
require "rest_client"
|
26
|
+
|
27
|
+
RestClient::Request.execute(
|
28
|
+
:method => request.verb,
|
29
|
+
:url => request.uri.to_s,
|
30
|
+
:headers => request.headers,
|
31
|
+
:payload => request.body,
|
32
|
+
:timeout => 10
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Trello
|
2
|
+
class Notification < BasicData
|
3
|
+
register_attributes :id, :unread, :type, :date, :data, :member_creator_id,
|
4
|
+
:read_only => [ :id, :unread, :type, :date, :member_creator_id ]
|
5
|
+
validates_presence_of :id, :type, :date, :member_creator_id
|
6
|
+
|
7
|
+
class << self
|
8
|
+
# Locate a notification by its id
|
9
|
+
def find(id)
|
10
|
+
super(:notifications, id)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def update_fields(fields)
|
15
|
+
attributes[:id] = fields['id']
|
16
|
+
attributes[:unread] = fields['unread']
|
17
|
+
attributes[:type] = fields['type']
|
18
|
+
attributes[:date] = fields['date']
|
19
|
+
attributes[:data] = fields['data']
|
20
|
+
attributes[:member_creator_id] = fields['idMemberCreator']
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
alias :unread? :unread
|
25
|
+
|
26
|
+
one :member_creator, :via => Member, :using => :member_creator_id
|
27
|
+
|
28
|
+
def board
|
29
|
+
Client.get("/notifications/#{id}/board").json_into(Board)
|
30
|
+
end
|
31
|
+
|
32
|
+
def list
|
33
|
+
Client.get("/notifications/#{id}/list").json_into(List)
|
34
|
+
end
|
35
|
+
|
36
|
+
def card
|
37
|
+
Client.get("/notifications/#{id}/card").json_into(Card)
|
38
|
+
end
|
39
|
+
|
40
|
+
def member
|
41
|
+
Client.get("/notifications/#{id}/member").json_into(Member)
|
42
|
+
end
|
43
|
+
|
44
|
+
def organization
|
45
|
+
Client.get("/notifications/#{id}/organization").json_into(Organization)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Trello
|
2
|
+
# Organizations are useful for linking members together.
|
3
|
+
class Organization < BasicData
|
4
|
+
register_attributes :id, :name, :display_name, :description, :url,
|
5
|
+
:readonly => [ :id, :name, :display_name, :description, :url ]
|
6
|
+
validates_presence_of :id, :name
|
7
|
+
|
8
|
+
include HasActions
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# Find an organization by its id.
|
12
|
+
def find(id)
|
13
|
+
super(:organizations, id)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Update the fields of an organization.
|
18
|
+
#
|
19
|
+
# Supply a hash of string keyed data retrieved from the Trello API representing
|
20
|
+
# an Organization.
|
21
|
+
def update_fields(fields)
|
22
|
+
attributes[:id] = fields['id']
|
23
|
+
attributes[:name] = fields['name']
|
24
|
+
attributes[:display_name] = fields['displayName']
|
25
|
+
attributes[:description] = fields['description']
|
26
|
+
attributes[:url] = fields['url']
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns a list of boards under this organization.
|
31
|
+
def boards
|
32
|
+
boards = Client.get("/organizations/#{id}/boards/all").json_into(Board)
|
33
|
+
MultiAssociation.new(self, boards).proxy
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns an array of members associated with the organization.
|
37
|
+
def members
|
38
|
+
members = Client.get("/organizations/#{id}/members/all").json_into(Member)
|
39
|
+
MultiAssociation.new(self, members).proxy
|
40
|
+
end
|
41
|
+
|
42
|
+
# :nodoc:
|
43
|
+
def request_prefix
|
44
|
+
"/organizations/#{id}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class String
|
2
|
+
# Decodes some JSON text in the receiver, and marshals it into a class specified
|
3
|
+
# in _obj_. If _obj_ is not a class, then we marshall the data into that instance
|
4
|
+
# via _update_fields_.
|
5
|
+
#
|
6
|
+
# For instance:
|
7
|
+
#
|
8
|
+
# class Stuff
|
9
|
+
# attr_reader :a, :b
|
10
|
+
# def initialize(values)
|
11
|
+
# @a = values['a']
|
12
|
+
# @b = values['b']
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
# thing = '{"a":42,"b":"foo"}'.json_into(Stuff)
|
16
|
+
# thing.a == 42
|
17
|
+
# thing.b == "foo"
|
18
|
+
def json_into(obj)
|
19
|
+
data = JSON.parse(self)
|
20
|
+
action = obj.kind_of?(Class) ? :new : :update_fields
|
21
|
+
if data.kind_of? Hash
|
22
|
+
obj.send(action, JSON.parse(self))
|
23
|
+
else
|
24
|
+
data.map { |element| obj.send(action, element) }
|
25
|
+
end
|
26
|
+
rescue JSON::ParserError => json_error
|
27
|
+
if json_error.message =~ /model not found/
|
28
|
+
Trello.logger.error "Could not find that record."
|
29
|
+
raise Trello::Error, "Request could not be found."
|
30
|
+
elsif json_error.message =~ /A JSON text must at least contain two octets/
|
31
|
+
else
|
32
|
+
Trello.logger.error "Unknown error."
|
33
|
+
raise
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/trello/token.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
module Trello
|
2
|
+
class Token < BasicData
|
3
|
+
register_attributes :id, :member_id, :created_at, :permissions,
|
4
|
+
:readonly => [ :id, :member_id, :created_at, :permissions ]
|
5
|
+
|
6
|
+
class << self
|
7
|
+
# Finds a token
|
8
|
+
def find(token)
|
9
|
+
super(:tokens, token)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# :nodoc:
|
14
|
+
def update_fields(fields)
|
15
|
+
attributes[:id] = fields['id']
|
16
|
+
attributes[:member_id] = fields['idMember']
|
17
|
+
attributes[:created_at] = Time.iso8601(fields['dateCreated'])
|
18
|
+
attributes[:permissions] = fields['permissions'] || {}
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns a reference to the user who authorized the token.
|
22
|
+
one :member, :using => :member_id
|
23
|
+
end
|
24
|
+
end
|
data/lib/trello.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'oauth'
|
2
|
+
require 'json'
|
3
|
+
require 'logger'
|
4
|
+
require 'active_model'
|
5
|
+
|
6
|
+
# Ruby wrapper around the Trello[http://trello.com] API
|
7
|
+
#
|
8
|
+
# First, set up your key information. You can get this information by {clicking here}[https://trello.com/1/appKey/generate].
|
9
|
+
#
|
10
|
+
# include Trello
|
11
|
+
# include Trello::Authorization
|
12
|
+
#
|
13
|
+
# Trello::Authorization.const_set :AuthPolicy, OAuthPolicy
|
14
|
+
#
|
15
|
+
# OAuthPolicy.consumer_credential = OAuthCredential.new 'PUBLIC_KEY', 'SECRET'
|
16
|
+
#
|
17
|
+
# You can get the key by going to this url in your browser:
|
18
|
+
# https://trello.com/1/connect?key=PUBLIC_KEY_FROM_ABOVE&name=MyApp&response_type=token&scope=read,write,account&expiration=never
|
19
|
+
# Only request the permissions you need; i.e., scope=read if you only need read, or scope=write if you only need write. Comma separate scopes you need.
|
20
|
+
# If you want your token to expire after 30 days, drop the &expiration=never. Then run the following code, where KEY denotes the key returned from the
|
21
|
+
# url above:
|
22
|
+
#
|
23
|
+
# OAuthPolicy.token = OAuthCredential.new 'KEY', nil
|
24
|
+
#
|
25
|
+
# All the calls this library make to Trello require authentication using these keys. Be sure to protect them.
|
26
|
+
#
|
27
|
+
# So lets say you want to get information about the user *bobtester*. We can do something like this:
|
28
|
+
#
|
29
|
+
# bob = Member.find("bobtester")
|
30
|
+
# # Print out his name
|
31
|
+
# puts bob.full_name # "Bob Tester"
|
32
|
+
# # Print his bio
|
33
|
+
# puts bob.bio # A wonderfully delightful test user
|
34
|
+
# # How about a list of his boards?
|
35
|
+
# bob.boards
|
36
|
+
#
|
37
|
+
# And so much more. Consult the rest of the documentation for more information.
|
38
|
+
#
|
39
|
+
# Feel free to {peruse and participate in our Trello board}[https://trello.com/board/ruby-trello/4f092b2ee23cb6fe6d1aaabd]. It's completely open to the public.
|
40
|
+
module Trello
|
41
|
+
autoload :Action, 'trello/action'
|
42
|
+
autoload :Association, 'trello/association'
|
43
|
+
autoload :AssociationProxy, 'trello/association_proxy'
|
44
|
+
autoload :BasicData, 'trello/basic_data'
|
45
|
+
autoload :Board, 'trello/board'
|
46
|
+
autoload :Card, 'trello/card'
|
47
|
+
autoload :Checklist, 'trello/checklist'
|
48
|
+
autoload :Client, 'trello/client'
|
49
|
+
autoload :HasActions, 'trello/has_actions'
|
50
|
+
autoload :Item, 'trello/item'
|
51
|
+
autoload :ItemState, 'trello/item_state'
|
52
|
+
autoload :Label, 'trello/label'
|
53
|
+
autoload :List, 'trello/list'
|
54
|
+
autoload :Member, 'trello/member'
|
55
|
+
autoload :MultiAssociation, 'trello/multi_association'
|
56
|
+
autoload :Notification, 'trello/notification'
|
57
|
+
autoload :Organization, 'trello/organization'
|
58
|
+
autoload :Request, 'trello/net'
|
59
|
+
autoload :TInternet, 'trello/net'
|
60
|
+
autoload :Token, 'trello/token'
|
61
|
+
|
62
|
+
module Authorization
|
63
|
+
autoload :AuthPolicy, 'trello/authorization'
|
64
|
+
autoload :BasicAuthPolicy, 'trello/authorization'
|
65
|
+
autoload :OAuthPolicy, 'trello/authorization'
|
66
|
+
end
|
67
|
+
|
68
|
+
# Version of the Trello API that we use by default.
|
69
|
+
API_VERSION = 1
|
70
|
+
|
71
|
+
# Raise this when we hit a Trello error.
|
72
|
+
class Error < StandardError; end
|
73
|
+
# This specific error is thrown when your access token is invalid. You should get a new one.
|
74
|
+
class InvalidAccessToken < StandardError; end
|
75
|
+
|
76
|
+
def self.logger
|
77
|
+
@logger ||= Logger.new(STDOUT)
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.logger=(logger)
|
81
|
+
@logger = logger
|
82
|
+
end
|
83
|
+
end
|
data/spec/action_spec.rb
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Trello
|
4
|
+
describe Action do
|
5
|
+
include Helpers
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
Client.stub(:get).with("/actions/4ee2482134a81a757a08af47").
|
9
|
+
and_return JSON.generate(actions_details.first)
|
10
|
+
|
11
|
+
@action = Action.find('4ee2482134a81a757a08af47')
|
12
|
+
end
|
13
|
+
|
14
|
+
context "fields" do
|
15
|
+
before(:all) do
|
16
|
+
@detail = actions_details.first
|
17
|
+
end
|
18
|
+
|
19
|
+
it "gets its id" do
|
20
|
+
@action.id.should == @detail['id']
|
21
|
+
end
|
22
|
+
|
23
|
+
it "gets its type" do
|
24
|
+
@action.type.should == @detail['type']
|
25
|
+
end
|
26
|
+
|
27
|
+
it "has the same data" do
|
28
|
+
@action.data.should == @detail['data']
|
29
|
+
end
|
30
|
+
|
31
|
+
it "gets the date" do
|
32
|
+
@action.date.utc.iso8601.should == @detail['date']
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "boards" do
|
37
|
+
it "has a board" do
|
38
|
+
Client.stub(:get).with("/actions/4ee2482134a81a757a08af47/board").
|
39
|
+
and_return JSON.generate(boards_details.first)
|
40
|
+
|
41
|
+
@action.board.should_not be_nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "card" do
|
46
|
+
it "has a card" do
|
47
|
+
Client.stub(:get).with("/actions/4ee2482134a81a757a08af47/card").
|
48
|
+
and_return JSON.generate(cards_details.first)
|
49
|
+
|
50
|
+
@action.card.should_not be_nil
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "list" do
|
55
|
+
it "has a list of lists" do
|
56
|
+
Client.stub(:get).with("/actions/4ee2482134a81a757a08af47/list").
|
57
|
+
and_return JSON.generate(lists_details.first)
|
58
|
+
|
59
|
+
@action.list.should_not be_nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "member creator" do
|
64
|
+
it "knows its member creator" do
|
65
|
+
Client.stub(:get).with("/members/abcdef123456789123456789").and_return user_payload
|
66
|
+
|
67
|
+
@action.member_creator.should_not be_nil
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|