ruby-trello 1.3.0 → 1.4.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.
- checksums.yaml +4 -4
- data/README.md +14 -13
- data/lib/trello.rb +55 -1
- data/lib/trello/action.rb +6 -5
- data/lib/trello/attachment.rb +7 -6
- data/lib/trello/basic_data.rb +4 -5
- data/lib/trello/board.rb +15 -9
- data/lib/trello/card.rb +15 -14
- data/lib/trello/checklist.rb +12 -8
- data/lib/trello/core_ext/array.rb +3 -2
- data/lib/trello/core_ext/hash.rb +3 -3
- data/lib/trello/core_ext/string.rb +3 -28
- data/lib/trello/has_actions.rb +1 -1
- data/lib/trello/json_utils.rb +64 -0
- data/lib/trello/label.rb +5 -3
- data/lib/trello/list.rb +2 -2
- data/lib/trello/member.rb +2 -2
- data/lib/trello/notification.rb +5 -5
- data/lib/trello/organization.rb +6 -3
- data/lib/trello/webhook.rb +2 -2
- data/spec/board_spec.rb +17 -3
- data/spec/card_spec.rb +11 -6
- data/spec/checklist_spec.rb +7 -4
- data/spec/integration/how_to_use_boards_spec.rb +1 -1
- data/spec/json_utils_spec.rb +73 -0
- data/spec/spec_helper.rb +16 -7
- data/spec/string_spec.rb +2 -0
- data/spec/trello_spec.rb +48 -0
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15e12149591973e1e515f0b8c510dc3718bddd7a
|
4
|
+
data.tar.gz: 7702c5ee26e57d7684581a4ccf465d3a99df3214
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e689031f702357536e227cfe2d806af95f9222ce61baecc1548654d0d5255f25384f5d0adedc0205fceb164fc88e1c397bb00c7420ef02b28ac5ff521c401642
|
7
|
+
data.tar.gz: 58a9f2cf4a51385de17a23e60ba9b168c514e52d98b28eb0e8eb282e260f501ccba622c9639866420ac60c5bfcf5117a1f4659ba859ba7c03146e2b84044ca91
|
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# Ruby Trello API
|
2
2
|
|
3
|
-
[](http://waffle.io/jeremytregunna/ruby-trello)
|
3
|
+
[](http://waffle.io/jeremytregunna/ruby-trello)
|
4
4
|
[](http://travis-ci.org/jeremytregunna/ruby-trello) [](https://gemnasium.com/jeremytregunna/ruby-trello.png)
|
5
|
+
[](https://codeclimate.com/github/jeremytregunna/ruby-trello)
|
5
6
|
|
6
7
|
This library implements the [Trello](http://www.trello.com/) [API](http://trello.com/api).
|
7
8
|
|
@@ -19,23 +20,23 @@ Seriously, [check it out](http://www.trello.com/).
|
|
19
20
|
Full Disclosure: This library is mostly complete, if you do find anything missing or not functioning as you expect it
|
20
21
|
to, please [let us know](https://trello.com/card/spot-a-bug-report-it/4f092b2ee23cb6fe6d1aaabd/17).
|
21
22
|
|
22
|
-
|
23
|
-
illustrate that future versions may include ruby 1.9.3+ specific features.
|
23
|
+
Supports Ruby 2.0 or newer. Version 1.3.0 is the last version that supports Ruby that is older than 1.9.3.
|
24
24
|
|
25
25
|
## Configuration
|
26
26
|
|
27
27
|
####Basic authorization:
|
28
28
|
|
29
|
-
1. Get your API
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
29
|
+
1. Get your API public key from Trello via the irb console:
|
30
|
+
|
31
|
+
```
|
32
|
+
$ gem install ruby-trello
|
33
|
+
$ irb -rubygems
|
34
|
+
irb> require 'trello'
|
35
|
+
irb> Trello.open_public_key_url # copy your public key
|
36
|
+
irb> Trello.open_authorization_url key: 'yourpublickey' # copy your member token
|
37
|
+
```
|
38
|
+
|
39
|
+
2. You can now use the public key and member token in your app code:
|
39
40
|
|
40
41
|
```ruby
|
41
42
|
require 'trello'
|
data/lib/trello.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
|
2
1
|
require 'oauth'
|
3
2
|
require 'json'
|
4
3
|
require 'logger'
|
5
4
|
require 'active_model'
|
5
|
+
require 'addressable/uri'
|
6
6
|
|
7
7
|
# Ruby wrapper around the Trello[http://trello.com] API
|
8
8
|
#
|
@@ -62,6 +62,7 @@ module Trello
|
|
62
62
|
autoload :TInternet, 'trello/net'
|
63
63
|
autoload :Token, 'trello/token'
|
64
64
|
autoload :Webhook, 'trello/webhook'
|
65
|
+
autoload :JsonUtils, 'trello/json_utils'
|
65
66
|
|
66
67
|
module Authorization
|
67
68
|
autoload :AuthPolicy, 'trello/authorization'
|
@@ -104,4 +105,57 @@ module Trello
|
|
104
105
|
|
105
106
|
def self.auth_policy; client.auth_policy; end
|
106
107
|
def self.configuration; client.configuration; end
|
108
|
+
|
109
|
+
# Url to Trello API public key page
|
110
|
+
def self.public_key_url
|
111
|
+
'https://trello.com/app-key'
|
112
|
+
end
|
113
|
+
|
114
|
+
# Url to token for making authorized requests to the Trello API
|
115
|
+
#
|
116
|
+
# @param [String, #read] contents the contents to reverse
|
117
|
+
# @param options [Hash] Repository information to update
|
118
|
+
# @option options [String] :name Name of the application
|
119
|
+
# @option options [String] :key Application key
|
120
|
+
# @option options [String] :response_type 'token'
|
121
|
+
# @option options [String] :callback_method 'postMessage' or 'fragment'
|
122
|
+
# @option options [String] :return_url URL the token should be returned to
|
123
|
+
# @option options [String] :scope Comma-separated list of one or more of 'read', 'write', 'account'
|
124
|
+
# @option options [String] :expiration '1hour', '1day', '30days', 'never'
|
125
|
+
# @see https://developers.trello.com/authorize
|
126
|
+
def self.authorize_url(options = {})
|
127
|
+
params = options.dup
|
128
|
+
params[:key] ||= configuration.developer_public_key or
|
129
|
+
raise ArgumentError, 'Please configure your Trello public key'
|
130
|
+
params[:name] ||= 'Ruby Trello'
|
131
|
+
params[:scope] = 'read,write,account'
|
132
|
+
params[:expiration] ||= 'never'
|
133
|
+
params[:response_type] ||= 'token'
|
134
|
+
uri = Addressable::URI.parse 'https://trello.com/1/authorize'
|
135
|
+
uri.query_values = params
|
136
|
+
uri
|
137
|
+
end
|
138
|
+
|
139
|
+
# Visit the Trello API public key page
|
140
|
+
#
|
141
|
+
# @see https://trello.com/app-key
|
142
|
+
def self.open_public_key_url
|
143
|
+
open_url public_key_url
|
144
|
+
end
|
145
|
+
|
146
|
+
# Visit the Trello authorized token page
|
147
|
+
#
|
148
|
+
# @see https://developers.trello.com/authorize
|
149
|
+
def self.open_authorization_url(options = {})
|
150
|
+
open_url authorize_url(options)
|
151
|
+
end
|
152
|
+
|
153
|
+
# @private
|
154
|
+
def self.open_url(url)
|
155
|
+
require 'launchy'
|
156
|
+
Launchy.open(url.to_s)
|
157
|
+
rescue LoadError
|
158
|
+
warn 'Please install the launchy gem to open the url automatically.'
|
159
|
+
url
|
160
|
+
end
|
107
161
|
end
|
data/lib/trello/action.rb
CHANGED
@@ -26,8 +26,9 @@ module Trello
|
|
26
26
|
|
27
27
|
def search(query, opts={})
|
28
28
|
response = client.get("/search/", { query: query }.merge(opts))
|
29
|
-
|
30
|
-
|
29
|
+
parse_json(response).except("options").each_with_object({}) do |(key, data), result|
|
30
|
+
klass = "Trello::#{key.singularize.capitalize}".constantize
|
31
|
+
result[key] = klass.from_json(data)
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
@@ -48,17 +49,17 @@ module Trello
|
|
48
49
|
|
49
50
|
# Returns the board this action occurred on.
|
50
51
|
def board
|
51
|
-
client.get("/actions/#{id}/board")
|
52
|
+
Board.from_response client.get("/actions/#{id}/board")
|
52
53
|
end
|
53
54
|
|
54
55
|
# Returns the card the action occurred on.
|
55
56
|
def card
|
56
|
-
client.get("/actions/#{id}/card")
|
57
|
+
Card.from_response client.get("/actions/#{id}/card")
|
57
58
|
end
|
58
59
|
|
59
60
|
# Returns the list the action occurred on.
|
60
61
|
def list
|
61
|
-
client.get("/actions/#{id}/list")
|
62
|
+
List.from_response client.get("/actions/#{id}/list")
|
62
63
|
end
|
63
64
|
|
64
65
|
# Returns the member who created the action.
|
data/lib/trello/attachment.rb
CHANGED
@@ -16,20 +16,21 @@ module Trello
|
|
16
16
|
# @!attribute mime_type
|
17
17
|
# @return [String]
|
18
18
|
class Attachment < BasicData
|
19
|
-
register_attributes :name, :id, :url, :bytes, :member_id, :date, :is_upload, :mime_type
|
19
|
+
register_attributes :name, :id, :url, :bytes, :member_id, :date, :is_upload, :mime_type, :previews
|
20
20
|
# Update the fields of an attachment.
|
21
21
|
#
|
22
22
|
# Supply a hash of stringkeyed data retrieved from the Trello API representing
|
23
23
|
# an attachment.
|
24
24
|
def update_fields(fields)
|
25
|
-
attributes[:name]
|
26
|
-
attributes[:id]
|
27
|
-
attributes[:url]
|
28
|
-
attributes[:bytes]
|
25
|
+
attributes[:name] = fields['name']
|
26
|
+
attributes[:id] = fields['id']
|
27
|
+
attributes[:url] = fields['url']
|
28
|
+
attributes[:bytes] = fields['bytes'].to_i
|
29
29
|
attributes[:member_id] = fields['idMember']
|
30
|
-
attributes[:date]
|
30
|
+
attributes[:date] = Time.parse(fields['date'])
|
31
31
|
attributes[:is_upload] = fields['isUpload']
|
32
32
|
attributes[:mime_type] = fields['mimeType']
|
33
|
+
attributes[:previews] = fields['previews']
|
33
34
|
self
|
34
35
|
end
|
35
36
|
end
|
data/lib/trello/basic_data.rb
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'trello/core_ext/array'
|
2
|
-
require 'trello/core_ext/hash'
|
3
|
-
require 'trello/core_ext/string'
|
4
1
|
require 'active_support/inflector'
|
5
2
|
|
6
3
|
module Trello
|
@@ -9,6 +6,8 @@ module Trello
|
|
9
6
|
include ActiveModel::Dirty
|
10
7
|
include ActiveModel::Serializers::JSON
|
11
8
|
|
9
|
+
include Trello::JsonUtils
|
10
|
+
|
12
11
|
class << self
|
13
12
|
def path_name
|
14
13
|
name.split("::").last.underscore
|
@@ -29,13 +28,13 @@ module Trello
|
|
29
28
|
end
|
30
29
|
|
31
30
|
def parse(response)
|
32
|
-
response
|
31
|
+
from_response(response).tap do |basic_data|
|
33
32
|
yield basic_data if block_given?
|
34
33
|
end
|
35
34
|
end
|
36
35
|
|
37
36
|
def parse_many(response)
|
38
|
-
response
|
37
|
+
from_response(response).map do |data|
|
39
38
|
data.tap do |d|
|
40
39
|
yield d if block_given?
|
41
40
|
end
|
data/lib/trello/board.rb
CHANGED
@@ -17,8 +17,8 @@ module Trello
|
|
17
17
|
# @!attribute [r] prefs
|
18
18
|
# @return [Hash] A 24-character hex string
|
19
19
|
class Board < BasicData
|
20
|
-
register_attributes :id, :name, :description, :closed, :starred, :url, :organization_id, :prefs,
|
21
|
-
readonly: [ :id, :url ]
|
20
|
+
register_attributes :id, :name, :description, :closed, :starred, :url, :organization_id, :prefs, :last_activity_date,
|
21
|
+
readonly: [ :id, :url, :last_activity_date ]
|
22
22
|
validates_presence_of :id, :name
|
23
23
|
validates_length_of :name, in: 1..16384
|
24
24
|
validates_length_of :description, maximum: 16384
|
@@ -53,7 +53,7 @@ module Trello
|
|
53
53
|
|
54
54
|
# @return [Array<Trello::Board>] all boards for the current user
|
55
55
|
def all
|
56
|
-
client.get("/members/#{Member.find(:me).username}/boards")
|
56
|
+
from_response client.get("/members/#{Member.find(:me).username}/boards")
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
@@ -65,7 +65,7 @@ module Trello
|
|
65
65
|
fields.merge!(idOrganization: organization_id) if organization_id
|
66
66
|
fields.merge!(flat_prefs)
|
67
67
|
|
68
|
-
client.post("/boards", fields)
|
68
|
+
from_response(client.post("/boards", fields))
|
69
69
|
end
|
70
70
|
|
71
71
|
def update!
|
@@ -83,7 +83,7 @@ module Trello
|
|
83
83
|
}
|
84
84
|
fields.merge!(flat_prefs)
|
85
85
|
|
86
|
-
client.put("/boards/#{self.id}/", fields)
|
86
|
+
from_response client.put("/boards/#{self.id}/", fields)
|
87
87
|
end
|
88
88
|
|
89
89
|
def update_fields(fields)
|
@@ -95,6 +95,7 @@ module Trello
|
|
95
95
|
attributes[:url] = fields['url'] if fields['url']
|
96
96
|
attributes[:organization_id] = fields['idOrganization'] if fields['idOrganization']
|
97
97
|
attributes[:prefs] = fields['prefs'] || {}
|
98
|
+
attributes[:last_activity_date] = Time.iso8601(fields['dateLastActivity']) rescue nil
|
98
99
|
self
|
99
100
|
end
|
100
101
|
|
@@ -107,7 +108,7 @@ module Trello
|
|
107
108
|
def starred?
|
108
109
|
attributes[:starred]
|
109
110
|
end
|
110
|
-
|
111
|
+
|
111
112
|
# @return [Boolean]
|
112
113
|
def has_lists?
|
113
114
|
lists.size > 0
|
@@ -116,7 +117,7 @@ module Trello
|
|
116
117
|
# Find a card on this Board with the given ID.
|
117
118
|
# @return [Trello::Card]
|
118
119
|
def find_card(card_id)
|
119
|
-
client.get("/boards/#{self.id}/cards/#{card_id}")
|
120
|
+
Card.from_response client.get("/boards/#{self.id}/cards/#{card_id}")
|
120
121
|
end
|
121
122
|
|
122
123
|
# Add a member to this Board.
|
@@ -154,10 +155,15 @@ module Trello
|
|
154
155
|
# Returns a reference to the organization this board belongs to.
|
155
156
|
one :organization, path: :organizations, using: :organization_id
|
156
157
|
|
157
|
-
|
158
|
+
def labels(params={})
|
159
|
+
# Set the limit to as high as possible given there is no pagination in this API.
|
160
|
+
params[:limit] = 1000 unless params[:limit]
|
161
|
+
labels = Label.from_response client.get("/boards/#{id}/labels", params)
|
162
|
+
MultiAssociation.new(self, labels).proxy
|
163
|
+
end
|
158
164
|
|
159
165
|
def label_names
|
160
|
-
label_names = client.get("/boards/#{id}/labelnames")
|
166
|
+
label_names = LabelName.from_response client.get("/boards/#{id}/labelnames")
|
161
167
|
MultiAssociation.new(self, label_names).proxy
|
162
168
|
end
|
163
169
|
|
data/lib/trello/card.rb
CHANGED
@@ -78,7 +78,8 @@ module Trello
|
|
78
78
|
|
79
79
|
# Create a new card and save it on Trello.
|
80
80
|
#
|
81
|
-
# @param [Hash] options
|
81
|
+
# @param [Hash] options
|
82
|
+
# @option options [String] :name The name of the new card.
|
82
83
|
# @option options [String] :list_id ID of the list that the card should
|
83
84
|
# be added to.
|
84
85
|
# @option options [String] :desc A string with a
|
@@ -157,6 +158,7 @@ module Trello
|
|
157
158
|
attributes[:cover_image_id] = fields[SYMBOL_TO_STRING[:cover_image_id]]
|
158
159
|
attributes[:badges] = fields[SYMBOL_TO_STRING[:badges]]
|
159
160
|
attributes[:card_members] = fields[SYMBOL_TO_STRING[:card_members]]
|
161
|
+
|
160
162
|
self
|
161
163
|
end
|
162
164
|
|
@@ -173,12 +175,12 @@ module Trello
|
|
173
175
|
many :checklists, filter: :all
|
174
176
|
|
175
177
|
def check_item_states
|
176
|
-
states = client.get("/cards/#{self.id}/checkItemStates")
|
178
|
+
states = CheckItemState.from_response client.get("/cards/#{self.id}/checkItemStates")
|
177
179
|
MultiAssociation.new(self, states).proxy
|
178
180
|
end
|
179
181
|
|
180
182
|
many :labels
|
181
|
-
|
183
|
+
|
182
184
|
# Returns a reference to the list this card is currently in.
|
183
185
|
one :list, path: :lists, using: :list_id
|
184
186
|
|
@@ -187,7 +189,7 @@ module Trello
|
|
187
189
|
# @return [Array<Trello::Member>]
|
188
190
|
def members
|
189
191
|
members = member_ids.map do |member_id|
|
190
|
-
client.get("/members/#{member_id}")
|
192
|
+
Member.from_response client.get("/members/#{member_id}")
|
191
193
|
end
|
192
194
|
MultiAssociation.new(self, members).proxy
|
193
195
|
end
|
@@ -202,7 +204,7 @@ module Trello
|
|
202
204
|
# If we have an id, just update our fields.
|
203
205
|
return update! if id
|
204
206
|
|
205
|
-
client.post("/cards", {
|
207
|
+
from_response client.post("/cards", {
|
206
208
|
name: name,
|
207
209
|
desc: desc,
|
208
210
|
idList: list_id,
|
@@ -210,7 +212,7 @@ module Trello
|
|
210
212
|
labels: card_labels,
|
211
213
|
pos: pos,
|
212
214
|
due: due
|
213
|
-
})
|
215
|
+
})
|
214
216
|
end
|
215
217
|
|
216
218
|
# Update an existing record.
|
@@ -232,7 +234,6 @@ module Trello
|
|
232
234
|
client.put("/cards/#{id}", payload)
|
233
235
|
end
|
234
236
|
|
235
|
-
|
236
237
|
# Delete this card
|
237
238
|
#
|
238
239
|
# @return [String] the JSON response from the Trello API
|
@@ -315,7 +316,7 @@ module Trello
|
|
315
316
|
def remove_member(member)
|
316
317
|
client.delete("/cards/#{id}/members/#{member.id}")
|
317
318
|
end
|
318
|
-
|
319
|
+
|
319
320
|
# Add a label
|
320
321
|
def add_label(label)
|
321
322
|
unless label.valid?
|
@@ -327,11 +328,11 @@ module Trello
|
|
327
328
|
|
328
329
|
# Remove a label
|
329
330
|
def remove_label(label)
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
331
|
+
unless label.valid?
|
332
|
+
errors.add(:label, "is not valid.")
|
333
|
+
return Trello.logger.warn "Label is not valid." unless label.valid?
|
334
|
+
end
|
335
|
+
client.delete("/cards/#{id}/idLabels/#{label.id}")
|
335
336
|
end
|
336
337
|
|
337
338
|
# Add an attachment to this card
|
@@ -351,7 +352,7 @@ module Trello
|
|
351
352
|
|
352
353
|
# Retrieve a list of attachments
|
353
354
|
def attachments
|
354
|
-
attachments = client.get("/cards/#{id}/attachments")
|
355
|
+
attachments = Attachment.from_response client.get("/cards/#{id}/attachments")
|
355
356
|
MultiAssociation.new(self, attachments).proxy
|
356
357
|
end
|
357
358
|
|
data/lib/trello/checklist.rb
CHANGED
@@ -22,8 +22,8 @@ module Trello
|
|
22
22
|
# @!attribute [r] member_ids
|
23
23
|
# @return [Array<String>] An array of 24-character hex strings
|
24
24
|
class Checklist < BasicData
|
25
|
-
register_attributes :id, :name, :description, :closed, :position, :url, :check_items, :board_id, :list_id, :member_ids,
|
26
|
-
readonly: [:id, :description, :closed, :url, :check_items, :board_id, :list_id, :member_ids]
|
25
|
+
register_attributes :id, :name, :description, :closed, :position, :url, :check_items, :board_id, :list_id, :card_id, :member_ids,
|
26
|
+
readonly: [:id, :description, :closed, :url, :check_items, :board_id, :list_id, :card_id, :member_ids]
|
27
27
|
validates_presence_of :id, :board_id, :list_id
|
28
28
|
validates_length_of :name, in: 1..16384
|
29
29
|
|
@@ -36,7 +36,7 @@ module Trello
|
|
36
36
|
def create(options)
|
37
37
|
client.create(:checklist,
|
38
38
|
'name' => options[:name],
|
39
|
-
'
|
39
|
+
'idCard' => options[:card_id])
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -53,6 +53,7 @@ module Trello
|
|
53
53
|
attributes[:check_items] = fields['checkItems']
|
54
54
|
attributes[:position] = fields['pos']
|
55
55
|
attributes[:board_id] = fields['idBoard']
|
56
|
+
attributes[:card_id] = fields['idCard']
|
56
57
|
attributes[:list_id] = fields['idList']
|
57
58
|
attributes[:member_ids] = fields['idMembers']
|
58
59
|
self
|
@@ -67,14 +68,14 @@ module Trello
|
|
67
68
|
def save
|
68
69
|
return update! if id
|
69
70
|
|
70
|
-
client.post("/checklists", {
|
71
|
-
|
72
|
-
|
73
|
-
})
|
71
|
+
from_response(client.post("/checklists", {
|
72
|
+
name: name,
|
73
|
+
idCard: card_id
|
74
|
+
}))
|
74
75
|
end
|
75
76
|
|
76
77
|
def update!
|
77
|
-
client.put("/checklists/#{id}", {name: name, pos: position})
|
78
|
+
from_response(client.put("/checklists/#{id}", {name: name, pos: position}))
|
78
79
|
end
|
79
80
|
|
80
81
|
# Return a list of items on the checklist.
|
@@ -87,6 +88,9 @@ module Trello
|
|
87
88
|
# Return a reference to the board the checklist is on.
|
88
89
|
one :board, path: :checklists, using: :board_id
|
89
90
|
|
91
|
+
# Return a reference to the card the checklist is on.
|
92
|
+
one :card, path: :checklists, using: :card_id
|
93
|
+
|
90
94
|
# Return a reference to the list the checklist is on.
|
91
95
|
one :list, path: :lists, using: :list_id
|
92
96
|
|
data/lib/trello/core_ext/hash.rb
CHANGED
@@ -1,31 +1,6 @@
|
|
1
|
+
warn "Use of trello/core_ext/string is deprecated. Use Trello::JsonUtils instead"
|
1
2
|
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
3
|
def json_into(obj, encoding = 'UTF-8')
|
19
|
-
|
20
|
-
data.jsoned_into(obj)
|
21
|
-
rescue JSON::ParserError => json_error
|
22
|
-
if json_error.message =~ /model not found/
|
23
|
-
Trello.logger.error "Could not find that record."
|
24
|
-
raise Trello::Error, "Request could not be found."
|
25
|
-
elsif json_error.message =~ /A JSON text must at least contain two octets/
|
26
|
-
else
|
27
|
-
Trello.logger.error "Unknown error."
|
28
|
-
raise
|
29
|
-
end
|
4
|
+
obj.from_response(self, encoding)
|
30
5
|
end
|
31
|
-
end
|
6
|
+
end
|
data/lib/trello/has_actions.rb
CHANGED
@@ -2,7 +2,7 @@ module Trello
|
|
2
2
|
module HasActions
|
3
3
|
# Returns a list of the actions associated with this object.
|
4
4
|
def actions(options = {})
|
5
|
-
actions = client.get("#{request_prefix}/actions", { filter: :all }.merge(options))
|
5
|
+
actions = Action.from_response client.get("#{request_prefix}/actions", { filter: :all }.merge(options))
|
6
6
|
MultiAssociation.new(self, actions).proxy
|
7
7
|
end
|
8
8
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Trello
|
2
|
+
module JsonUtils
|
3
|
+
def self.included(base)
|
4
|
+
base.send :include, InstanceMethods
|
5
|
+
base.send :extend, ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module InstanceMethods
|
9
|
+
def from_response(*args)
|
10
|
+
update_fields parse_json(*args)
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse_json(*args)
|
14
|
+
self.class.parse_json(*args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
# Public - Decodes some JSON text in the receiver, and marshals it into a class specified
|
20
|
+
# in _obj_.
|
21
|
+
#
|
22
|
+
# For instance:
|
23
|
+
#
|
24
|
+
# class Stuff
|
25
|
+
# attr_reader :a, :b
|
26
|
+
# def initialize(values)
|
27
|
+
# @a = values['a']
|
28
|
+
# @b = values['b']
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
# thing = Stuff.from_response '{"a":42,"b":"foo"}'
|
32
|
+
# thing.a == 42
|
33
|
+
# thing.b == "foo"
|
34
|
+
#
|
35
|
+
def from_response(data, encoding = 'UTF-8')
|
36
|
+
from_json(parse_json(data, encoding))
|
37
|
+
end
|
38
|
+
|
39
|
+
def from_json(json)
|
40
|
+
case json
|
41
|
+
when Array
|
42
|
+
json.map { |element| from_json(element) }
|
43
|
+
when Hash
|
44
|
+
self.new(json)
|
45
|
+
else
|
46
|
+
json
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse_json(string, encoding = 'UTF-8')
|
51
|
+
JSON.parse(string.force_encoding(encoding))
|
52
|
+
rescue JSON::ParserError => json_error
|
53
|
+
if json_error.message =~ /model not found/
|
54
|
+
Trello.logger.error "Could not find that record."
|
55
|
+
raise Trello::Error, "Request could not be found."
|
56
|
+
elsif json_error.message =~ /A JSON text must at least contain two octets/
|
57
|
+
else
|
58
|
+
Trello.logger.error "Unknown error."
|
59
|
+
raise
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/trello/label.rb
CHANGED
@@ -21,6 +21,8 @@ module Trello
|
|
21
21
|
}
|
22
22
|
|
23
23
|
class << self
|
24
|
+
VALID_LABEL_COLOURS = %w{green yellow orange red purple blue sky lime pink black} << ''
|
25
|
+
|
24
26
|
# Find a specific card by its id.
|
25
27
|
def find(id, params = {})
|
26
28
|
client.find(:label, id, params)
|
@@ -37,7 +39,7 @@ module Trello
|
|
37
39
|
|
38
40
|
# Label colours
|
39
41
|
def label_colours
|
40
|
-
|
42
|
+
VALID_LABEL_COLOURS
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
@@ -78,11 +80,11 @@ module Trello
|
|
78
80
|
# If we have an id, just update our fields.
|
79
81
|
return update! if id
|
80
82
|
|
81
|
-
client.post("/labels", {
|
83
|
+
from_response client.post("/labels", {
|
82
84
|
name: name,
|
83
85
|
color: color,
|
84
86
|
idBoard: board_id,
|
85
|
-
})
|
87
|
+
})
|
86
88
|
end
|
87
89
|
|
88
90
|
# Update an existing record.
|
data/lib/trello/list.rb
CHANGED
@@ -51,12 +51,12 @@ module Trello
|
|
51
51
|
def save
|
52
52
|
return update! if id
|
53
53
|
|
54
|
-
client.post("/lists", {
|
54
|
+
from_response client.post("/lists", {
|
55
55
|
name: name,
|
56
56
|
closed: closed || false,
|
57
57
|
idBoard: board_id,
|
58
58
|
pos: pos
|
59
|
-
})
|
59
|
+
})
|
60
60
|
end
|
61
61
|
|
62
62
|
def update!
|
data/lib/trello/member.rb
CHANGED
data/lib/trello/notification.rb
CHANGED
@@ -39,23 +39,23 @@ module Trello
|
|
39
39
|
one :member_creator, path: :members, via: Member, using: :member_creator_id
|
40
40
|
|
41
41
|
def board
|
42
|
-
client.get("/notifications/#{id}/board")
|
42
|
+
Board.from_response client.get("/notifications/#{id}/board")
|
43
43
|
end
|
44
44
|
|
45
45
|
def list
|
46
|
-
client.get("/notifications/#{id}/list")
|
46
|
+
List.from_response client.get("/notifications/#{id}/list")
|
47
47
|
end
|
48
48
|
|
49
49
|
def card
|
50
|
-
client.get("/notifications/#{id}/card")
|
50
|
+
Card.from_response client.get("/notifications/#{id}/card")
|
51
51
|
end
|
52
52
|
|
53
53
|
def member
|
54
|
-
client.get("/notifications/#{id}/member")
|
54
|
+
Member.from_response client.get("/notifications/#{id}/member")
|
55
55
|
end
|
56
56
|
|
57
57
|
def organization
|
58
|
-
client.get("/notifications/#{id}/organization")
|
58
|
+
Organization.from_response client.get("/notifications/#{id}/organization")
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
data/lib/trello/organization.rb
CHANGED
@@ -14,8 +14,10 @@ module Trello
|
|
14
14
|
class Organization < BasicData
|
15
15
|
register_attributes :id, :name, :display_name, :description, :url, :invited,
|
16
16
|
:website, :logo_hash, :billable_member_count, :active_billable_member_count,
|
17
|
+
:memberships,
|
17
18
|
readonly: [ :id, :name, :display_name, :description, :url, :invited,
|
18
|
-
:website, :logo_hash, :billable_member_count, :active_billable_member_count
|
19
|
+
:website, :logo_hash, :billable_member_count, :active_billable_member_count,
|
20
|
+
:memberships ]
|
19
21
|
validates_presence_of :id, :name
|
20
22
|
|
21
23
|
include HasActions
|
@@ -42,18 +44,19 @@ module Trello
|
|
42
44
|
attributes[:logo_hash] = fields['logoHash']
|
43
45
|
attributes[:billable_member_count] = fields['billableMemberCount']
|
44
46
|
attributes[:active_billable_member_count] = fields['activeBillableMemberCount']
|
47
|
+
attributes[:memberships] = fields['memberships']
|
45
48
|
self
|
46
49
|
end
|
47
50
|
|
48
51
|
# Returns a list of boards under this organization.
|
49
52
|
def boards
|
50
|
-
boards = client.get("/organizations/#{id}/boards/all")
|
53
|
+
boards = Board.from_response client.get("/organizations/#{id}/boards/all")
|
51
54
|
MultiAssociation.new(self, boards).proxy
|
52
55
|
end
|
53
56
|
|
54
57
|
# Returns an array of members associated with the organization.
|
55
58
|
def members(params = {})
|
56
|
-
members = client.get("/organizations/#{id}/members/all", params)
|
59
|
+
members = Member.from_response client.get("/organizations/#{id}/members/all", params)
|
57
60
|
MultiAssociation.new(self, members).proxy
|
58
61
|
end
|
59
62
|
|
data/lib/trello/webhook.rb
CHANGED
@@ -65,11 +65,11 @@ module Trello
|
|
65
65
|
# If we have an id, just update our fields.
|
66
66
|
return update! if id
|
67
67
|
|
68
|
-
client.post("/webhooks", {
|
68
|
+
from_response client.post("/webhooks", {
|
69
69
|
description: description,
|
70
70
|
idModel: id_model,
|
71
71
|
callbackURL: callback_url
|
72
|
-
})
|
72
|
+
})
|
73
73
|
end
|
74
74
|
|
75
75
|
# Update the webhook.
|
data/spec/board_spec.rb
CHANGED
@@ -74,6 +74,14 @@ module Trello
|
|
74
74
|
it "gets its url" do
|
75
75
|
expect(board.url).to_not be_nil
|
76
76
|
end
|
77
|
+
|
78
|
+
it "gets its last_activity_date" do
|
79
|
+
expect(board.last_activity_date).to_not be_nil
|
80
|
+
end
|
81
|
+
|
82
|
+
it "gets a Time object for last_activity_date" do
|
83
|
+
expect(board.last_activity_date).to be_a(Time)
|
84
|
+
end
|
77
85
|
end
|
78
86
|
|
79
87
|
context "actions" do
|
@@ -116,11 +124,11 @@ module Trello
|
|
116
124
|
end
|
117
125
|
|
118
126
|
it "gets the specific labels for the board" do
|
119
|
-
client.
|
127
|
+
allow(client).to receive(:get).with("/boards/abcdef123456789123456789/labels", {:limit => 1000}).
|
120
128
|
and_return label_payload
|
121
129
|
labels = board.labels
|
122
|
-
labels.count.should eq(4)
|
123
130
|
|
131
|
+
expect(labels.count).to eq(4)
|
124
132
|
expect(labels[2].color).to eq('red')
|
125
133
|
expect(labels[2].id).to eq('abcdef123456789123456789')
|
126
134
|
expect(labels[2].board_id).to eq('abcdef123456789123456789')
|
@@ -132,6 +140,12 @@ module Trello
|
|
132
140
|
expect(labels[3].name).to eq('on hold')
|
133
141
|
expect(labels[3].uses).to eq(6)
|
134
142
|
end
|
143
|
+
|
144
|
+
it "passes the label limit" do
|
145
|
+
allow(client).to receive(:get).with("/boards/abcdef123456789123456789/labels", {:limit => 50}).
|
146
|
+
and_return label_payload
|
147
|
+
labels = board.labels(:limit => 50)
|
148
|
+
end
|
135
149
|
end
|
136
150
|
|
137
151
|
context "find_card" do
|
@@ -278,7 +292,7 @@ module Trello
|
|
278
292
|
expect(client).to_not receive(:put)
|
279
293
|
expect {
|
280
294
|
Board.new.save
|
281
|
-
}.to raise_error
|
295
|
+
}.to raise_error(Trello::ConfigurationError)
|
282
296
|
end
|
283
297
|
|
284
298
|
it "puts all fields except id" do
|
data/spec/card_spec.rb
CHANGED
@@ -99,7 +99,7 @@ module Trello
|
|
99
99
|
desc: expected_new_desc,
|
100
100
|
}
|
101
101
|
|
102
|
-
client.
|
102
|
+
expect(client).to receive(:put).once.with("/cards/abcdef123456789123456789", payload)
|
103
103
|
|
104
104
|
card.desc = expected_new_desc
|
105
105
|
card.save
|
@@ -367,7 +367,8 @@ module Trello
|
|
367
367
|
.and_return "not important"
|
368
368
|
end
|
369
369
|
it "can retrieve labels" do
|
370
|
-
client.
|
370
|
+
allow(client).to receive(:get).
|
371
|
+
with("/cards/abcdef123456789123456789/labels", {}).
|
371
372
|
and_return label_payload
|
372
373
|
labels = card.labels
|
373
374
|
expect(labels.size).to eq(4)
|
@@ -384,19 +385,19 @@ module Trello
|
|
384
385
|
end
|
385
386
|
|
386
387
|
it "can remove a label" do
|
387
|
-
client.
|
388
|
+
expect(client).to receive(:delete).once.with("/cards/abcdef123456789123456789/idLabels/abcdef123456789123456789")
|
388
389
|
label = Label.new(label_details.first)
|
389
390
|
card.remove_label(label)
|
390
391
|
end
|
391
392
|
|
392
393
|
it "can add a label" do
|
393
|
-
client.
|
394
|
+
expect(client).to receive(:post).once.with("/cards/abcdef123456789123456789/idLabels", {:value => "abcdef123456789123456789"})
|
394
395
|
label = Label.new(label_details.first)
|
395
396
|
card.add_label label
|
396
397
|
end
|
397
398
|
|
398
399
|
it "throws an error when trying to add a invalid label" do
|
399
|
-
client.
|
400
|
+
allow(client).to receive(:post).with("/cards/abcdef123456789123456789/idLabels", { value: 'abcdef123456789123456789' }).
|
400
401
|
and_return "not important"
|
401
402
|
label = Label.new(label_details.first)
|
402
403
|
label.name = nil
|
@@ -405,7 +406,7 @@ module Trello
|
|
405
406
|
end
|
406
407
|
|
407
408
|
it "throws an error when trying to remove a invalid label" do
|
408
|
-
client.
|
409
|
+
allow(client).to receive(:delete).with("/cards/abcdef123456789123456789/idLabels/abcdef123456789123456789").
|
409
410
|
and_return "not important"
|
410
411
|
label = Label.new(label_details.first)
|
411
412
|
label.name = nil
|
@@ -455,6 +456,10 @@ module Trello
|
|
455
456
|
expect(first_attachment.date).to eq Time.parse(attachments_details[0]["date"])
|
456
457
|
expect(first_attachment.is_upload).to eq attachments_details[0]["isUpload"]
|
457
458
|
expect(first_attachment.mime_type).to eq attachments_details[0]["mimeType"]
|
459
|
+
expect(first_attachment.previews).to eq attachments_details[0]["previews"]
|
460
|
+
|
461
|
+
second_attachment = card.attachments[1]
|
462
|
+
expect(second_attachment.previews).to eq nil
|
458
463
|
end
|
459
464
|
|
460
465
|
it "can remove an attachment" do
|
data/spec/checklist_spec.rb
CHANGED
@@ -37,18 +37,21 @@ module Trello
|
|
37
37
|
payload = {
|
38
38
|
name: 'Test Checklist',
|
39
39
|
desc: '',
|
40
|
+
card_id: cards_details.first['id']
|
40
41
|
}
|
41
42
|
|
42
|
-
|
43
|
+
attributes = checklists_details.first.merge(payload).except("idBoard")
|
44
|
+
result = JSON.generate(attributes)
|
45
|
+
|
43
46
|
|
44
|
-
expected_payload = {name: "Test Checklist",
|
47
|
+
expected_payload = {name: "Test Checklist", idCard: cards_details.first['id']}
|
45
48
|
|
46
49
|
expect(client)
|
47
50
|
.to receive(:post)
|
48
51
|
.with("/checklists", expected_payload)
|
49
52
|
.and_return result
|
50
53
|
|
51
|
-
checklist = Checklist.create(
|
54
|
+
checklist = Checklist.create(attributes)
|
52
55
|
|
53
56
|
expect(checklist).to be_a Checklist
|
54
57
|
end
|
@@ -166,7 +169,7 @@ module Trello
|
|
166
169
|
|
167
170
|
context "making a copy" do
|
168
171
|
let(:client) { Trello.client }
|
169
|
-
let(:copy_options) { { :name => checklist.name, :
|
172
|
+
let(:copy_options) { { :name => checklist.name, :idCard => checklist.card_id } }
|
170
173
|
let(:copied_checklist) { checklist.copy }
|
171
174
|
|
172
175
|
before(:each) do
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Trello
|
4
|
+
RSpec.describe JsonUtils do
|
5
|
+
include Helpers
|
6
|
+
|
7
|
+
describe ".from_json" do
|
8
|
+
describe "Trello::Card" do
|
9
|
+
it "should convert an array of parsed json into cards" do
|
10
|
+
cards = Trello::Card.from_json(cards_details)
|
11
|
+
|
12
|
+
expect(cards.size).to eq(cards_details.size)
|
13
|
+
|
14
|
+
card = cards.first
|
15
|
+
expect(card).to be_a(Trello::Card)
|
16
|
+
expect(card.name).to eq(cards_details.first['name'])
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should convert a single parsed json into card" do
|
20
|
+
card_details = cards_details.first
|
21
|
+
card = Trello::Card.from_json(card_details)
|
22
|
+
|
23
|
+
expect(card).to be_a(Trello::Card)
|
24
|
+
expect(card.name).to eq(cards_details.first['name'])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe ".from_response" do
|
30
|
+
def example_class
|
31
|
+
@example_class ||= Class.new do
|
32
|
+
include Trello::JsonUtils
|
33
|
+
|
34
|
+
attr_accessor :name, :description
|
35
|
+
|
36
|
+
def initialize(options = {})
|
37
|
+
@name = options['name']
|
38
|
+
@description = options['description']
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'converts json into an instance of a class' do
|
44
|
+
expect(example_class.from_response('{}')).to be_a example_class
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'supplies the parsed json to the class ctor as a hash' do
|
48
|
+
json_text = '{"name" : "Jazz Kang", "description": "Plonker"}'
|
49
|
+
|
50
|
+
result = example_class.from_response json_text
|
51
|
+
expect(result.name).to eq("Jazz Kang")
|
52
|
+
expect(result.description).to eq("Plonker")
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'can also handle arrays of instances of a class' do
|
56
|
+
json_text = <<-JSON
|
57
|
+
[
|
58
|
+
{"name" : "Jazz Kang", "description": "Plonker"},
|
59
|
+
{"name" : "Phil Murphy", "description": "Shoreditch hipster"}
|
60
|
+
]
|
61
|
+
JSON
|
62
|
+
|
63
|
+
result = example_class.from_response json_text
|
64
|
+
|
65
|
+
expect(result).to be_an Array
|
66
|
+
expect(result.size).to eq 2
|
67
|
+
result.each do |parsed|
|
68
|
+
expect(parsed).to be_a example_class
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -35,6 +35,13 @@ RSpec.configure do |rspec|
|
|
35
35
|
rspec.before :each do
|
36
36
|
Trello.reset!
|
37
37
|
end
|
38
|
+
|
39
|
+
rspec.around(:each, :silence_warnings) do |example|
|
40
|
+
verbose = $VERBOSE
|
41
|
+
$VERBOSE = nil
|
42
|
+
example.run
|
43
|
+
$VERBOSE = verbose
|
44
|
+
end
|
38
45
|
end
|
39
46
|
|
40
47
|
module Helpers
|
@@ -57,13 +64,14 @@ module Helpers
|
|
57
64
|
|
58
65
|
def boards_details
|
59
66
|
[{
|
60
|
-
'id'
|
61
|
-
'name'
|
62
|
-
'desc'
|
63
|
-
'closed'
|
64
|
-
'starred'
|
65
|
-
'idOrganization'
|
66
|
-
'url'
|
67
|
+
'id' => 'abcdef123456789123456789',
|
68
|
+
'name' => 'Test',
|
69
|
+
'desc' => 'This is a test board',
|
70
|
+
'closed' => false,
|
71
|
+
'starred' => false,
|
72
|
+
'idOrganization' => 'abcdef123456789123456789',
|
73
|
+
'url' => 'https://trello.com/board/test/abcdef123456789123456789',
|
74
|
+
'dateLastActivity' => '2012-12-08T18:40:24.314Z'
|
67
75
|
}]
|
68
76
|
end
|
69
77
|
|
@@ -155,6 +163,7 @@ module Helpers
|
|
155
163
|
'idMember' => 'abcdef123456789123456781',
|
156
164
|
'isUpload' => false,
|
157
165
|
'date' => '2013-02-28T17:12:28.497Z',
|
166
|
+
'previews' => 'previews'
|
158
167
|
},
|
159
168
|
{
|
160
169
|
'id' => 'abcdef123456789123456781',
|
data/spec/string_spec.rb
CHANGED
data/spec/trello_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'launchy'
|
2
3
|
|
3
4
|
include Trello
|
4
5
|
include Trello::Authorization
|
@@ -75,6 +76,53 @@ describe Trello do
|
|
75
76
|
it { expect(Trello.auth_policy).to be_a(AuthPolicy) }
|
76
77
|
it { expect { Trello.client.get(:member) }.to raise_error(Trello::ConfigurationError) }
|
77
78
|
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'client authorization helpers' do
|
82
|
+
before do
|
83
|
+
allow(Launchy).to receive(:open)
|
84
|
+
end
|
85
|
+
|
86
|
+
it { expect(Trello.public_key_url).to eq('https://trello.com/app-key') }
|
87
|
+
it { expect(Trello.authorize_url(key: 'foo')).to match(%r{^https://trello.com/1/authorize}) }
|
88
|
+
|
89
|
+
describe '.open_public_key_url' do
|
90
|
+
it 'launches app key endpoint' do
|
91
|
+
expect(Launchy).to receive(:open).with('https://trello.com/app-key')
|
78
92
|
|
93
|
+
Trello.open_public_key_url
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'rescues LoadError', :silence_warnings do
|
97
|
+
allow(Launchy).to receive(:open).and_raise(LoadError)
|
98
|
+
|
99
|
+
expect { Trello.open_public_key_url }.to_not raise_error(LoadError)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '.open_authorization_url' do
|
104
|
+
it 'launches authorize endpoint with configured public key' do
|
105
|
+
app_key = 'abcd1234'
|
106
|
+
allow(Trello.configuration).to receive(:developer_public_key).and_return(app_key)
|
107
|
+
authorize_url = "https://trello.com/1/authorize?expiration=never&key=#{app_key}&name=Ruby%20Trello&response_type=token&scope=read%2Cwrite%2Caccount"
|
108
|
+
expect(Launchy).to receive(:open).with(authorize_url)
|
109
|
+
|
110
|
+
Trello.open_authorization_url
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'launches authorize endpoint with given public key' do
|
114
|
+
app_key = 'wxyz6789'
|
115
|
+
authorize_url = "https://trello.com/1/authorize?expiration=never&key=#{app_key}&name=Ruby%20Trello&response_type=token&scope=read%2Cwrite%2Caccount"
|
116
|
+
expect(Launchy).to receive(:open).with(authorize_url)
|
117
|
+
|
118
|
+
Trello.open_authorization_url(key: 'wxyz6789')
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'raises an error if key not configured' do
|
122
|
+
expect(Launchy).to_not receive(:open)
|
123
|
+
|
124
|
+
expect { Trello.open_authorization_url }.to raise_error(ArgumentError)
|
125
|
+
end
|
126
|
+
end
|
79
127
|
end
|
80
128
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-trello
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Tregunna
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -105,6 +105,7 @@ files:
|
|
105
105
|
- lib/trello/has_actions.rb
|
106
106
|
- lib/trello/item.rb
|
107
107
|
- lib/trello/item_state.rb
|
108
|
+
- lib/trello/json_utils.rb
|
108
109
|
- lib/trello/label.rb
|
109
110
|
- lib/trello/label_name.rb
|
110
111
|
- lib/trello/list.rb
|
@@ -131,6 +132,7 @@ files:
|
|
131
132
|
- spec/integration/how_to_use_boards_spec.rb
|
132
133
|
- spec/integration/integration_test.rb
|
133
134
|
- spec/item_spec.rb
|
135
|
+
- spec/json_utils_spec.rb
|
134
136
|
- spec/label_spec.rb
|
135
137
|
- spec/list_spec.rb
|
136
138
|
- spec/member_spec.rb
|
@@ -155,12 +157,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
155
157
|
requirements:
|
156
158
|
- - '>='
|
157
159
|
- !ruby/object:Gem::Version
|
158
|
-
version:
|
160
|
+
version: 2.0.0
|
159
161
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
162
|
requirements:
|
161
163
|
- - '>='
|
162
164
|
- !ruby/object:Gem::Version
|
163
|
-
version:
|
165
|
+
version: '0'
|
164
166
|
requirements: []
|
165
167
|
rubyforge_project: ruby-trello
|
166
168
|
rubygems_version: 2.0.14
|
@@ -182,6 +184,7 @@ test_files:
|
|
182
184
|
- spec/integration/how_to_use_boards_spec.rb
|
183
185
|
- spec/integration/integration_test.rb
|
184
186
|
- spec/item_spec.rb
|
187
|
+
- spec/json_utils_spec.rb
|
185
188
|
- spec/label_spec.rb
|
186
189
|
- spec/list_spec.rb
|
187
190
|
- spec/member_spec.rb
|