ruby-trello-czuger 2.0.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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +182 -0
  3. data/lib/trello.rb +163 -0
  4. data/lib/trello/action.rb +68 -0
  5. data/lib/trello/association.rb +14 -0
  6. data/lib/trello/association_proxy.rb +42 -0
  7. data/lib/trello/attachment.rb +40 -0
  8. data/lib/trello/authorization.rb +187 -0
  9. data/lib/trello/basic_data.rb +132 -0
  10. data/lib/trello/board.rb +211 -0
  11. data/lib/trello/card.rb +467 -0
  12. data/lib/trello/checklist.rb +143 -0
  13. data/lib/trello/client.rb +120 -0
  14. data/lib/trello/comment.rb +62 -0
  15. data/lib/trello/configuration.rb +68 -0
  16. data/lib/trello/core_ext/array.rb +6 -0
  17. data/lib/trello/core_ext/hash.rb +6 -0
  18. data/lib/trello/core_ext/string.rb +6 -0
  19. data/lib/trello/cover_image.rb +8 -0
  20. data/lib/trello/has_actions.rb +9 -0
  21. data/lib/trello/item.rb +37 -0
  22. data/lib/trello/item_state.rb +30 -0
  23. data/lib/trello/json_utils.rb +64 -0
  24. data/lib/trello/label.rb +108 -0
  25. data/lib/trello/label_name.rb +31 -0
  26. data/lib/trello/list.rb +114 -0
  27. data/lib/trello/member.rb +112 -0
  28. data/lib/trello/multi_association.rb +12 -0
  29. data/lib/trello/net.rb +39 -0
  30. data/lib/trello/notification.rb +61 -0
  31. data/lib/trello/organization.rb +68 -0
  32. data/lib/trello/plugin_datum.rb +34 -0
  33. data/lib/trello/token.rb +37 -0
  34. data/lib/trello/webhook.rb +103 -0
  35. data/spec/action_spec.rb +149 -0
  36. data/spec/array_spec.rb +13 -0
  37. data/spec/association_spec.rb +26 -0
  38. data/spec/basic_auth_policy_spec.rb +51 -0
  39. data/spec/board_spec.rb +442 -0
  40. data/spec/card_spec.rb +822 -0
  41. data/spec/checklist_spec.rb +296 -0
  42. data/spec/client_spec.rb +257 -0
  43. data/spec/configuration_spec.rb +95 -0
  44. data/spec/hash_spec.rb +15 -0
  45. data/spec/integration/how_to_authorize_spec.rb +53 -0
  46. data/spec/integration/how_to_use_boards_spec.rb +48 -0
  47. data/spec/integration/integration_test.rb +40 -0
  48. data/spec/item_spec.rb +75 -0
  49. data/spec/json_utils_spec.rb +73 -0
  50. data/spec/label_spec.rb +205 -0
  51. data/spec/list_spec.rb +253 -0
  52. data/spec/member_spec.rb +159 -0
  53. data/spec/notification_spec.rb +143 -0
  54. data/spec/oauth_policy_spec.rb +160 -0
  55. data/spec/organization_spec.rb +71 -0
  56. data/spec/spec_helper.rb +435 -0
  57. data/spec/string_spec.rb +55 -0
  58. data/spec/token_spec.rb +89 -0
  59. data/spec/trello_spec.rb +134 -0
  60. data/spec/webhook_spec.rb +130 -0
  61. metadata +200 -0
@@ -0,0 +1,12 @@
1
+ module Trello
2
+ class MultiAssociation < Association
3
+ extend Forwardable
4
+
5
+ def_delegator :target, :count
6
+
7
+ def initialize(owner, target = [])
8
+ super
9
+ @proxy = AssociationProxy.new(self)
10
+ end
11
+ end
12
+ end
data/lib/trello/net.rb ADDED
@@ -0,0 +1,39 @@
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
+ require "rest_client"
8
+
9
+ def execute(request)
10
+ try_execute request
11
+ end
12
+
13
+ private
14
+
15
+ def try_execute(request)
16
+ begin
17
+ if request
18
+ result = execute_core request
19
+ Response.new(200, {}, result)
20
+ end
21
+ rescue RestClient::Exception => e
22
+ raise if !e.respond_to?(:http_code) || e.http_code.nil?
23
+ Response.new(e.http_code, {}, e.http_body)
24
+ end
25
+ end
26
+
27
+ def execute_core(request)
28
+ RestClient.proxy = ENV['HTTP_PROXY'] if ENV['HTTP_PROXY']
29
+ RestClient::Request.execute(
30
+ method: request.verb,
31
+ url: request.uri.to_s,
32
+ headers: request.headers,
33
+ payload: request.body,
34
+ timeout: 10
35
+ )
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,61 @@
1
+ module Trello
2
+
3
+ # @!attribute [r] id
4
+ # @return [String]
5
+ # @!attribute [rw] unread
6
+ # @return [Boolean]
7
+ # @!attribute [r] type
8
+ # @return [Object]
9
+ # @!attribute [r] date
10
+ # @return [Datetime]
11
+ # @!attribute [rw] data
12
+ # @return [Object]
13
+ # @!attribute [r] member_creator_id,
14
+ # @return [String]
15
+ class Notification < BasicData
16
+ register_attributes :id, :unread, :type, :date, :data, :member_creator_id,
17
+ read_only: [ :id, :unread, :type, :date, :member_creator_id ]
18
+ validates_presence_of :id, :type, :date, :member_creator_id
19
+
20
+ class << self
21
+ # Locate a notification by its id
22
+ def find(id, params = {})
23
+ client.find(:notification, id, params)
24
+ end
25
+ end
26
+
27
+ def update_fields(fields)
28
+ attributes[:id] = fields['id'] || attributes[:id]
29
+ attributes[:unread] = fields['unread'] if fields.has_key?('unread')
30
+ attributes[:type] = fields['type'] || attributes[:type]
31
+ attributes[:date] = fields['date'] || attributes[:date]
32
+ attributes[:data] = fields['data'] || attributes[:data]
33
+ attributes[:member_creator_id] = fields['idMemberCreator'] || attributes[:member_creator_id]
34
+ self
35
+ end
36
+
37
+ alias :unread? :unread
38
+
39
+ one :member_creator, path: :members, via: Member, using: :member_creator_id
40
+
41
+ def board
42
+ Board.from_response client.get("/notifications/#{id}/board")
43
+ end
44
+
45
+ def list
46
+ List.from_response client.get("/notifications/#{id}/list")
47
+ end
48
+
49
+ def card
50
+ Card.from_response client.get("/notifications/#{id}/card")
51
+ end
52
+
53
+ def member
54
+ Member.from_response client.get("/notifications/#{id}/member")
55
+ end
56
+
57
+ def organization
58
+ Organization.from_response client.get("/notifications/#{id}/organization")
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,68 @@
1
+ module Trello
2
+ # Organizations are useful for linking members together.
3
+ #
4
+ # @!attribute [r] id
5
+ # @return [String]
6
+ # @!attribute [r] name
7
+ # @return [String]
8
+ # @!attribute [r] display_name
9
+ # @return [String]
10
+ # @!attribute [r] description
11
+ # @return [String]
12
+ # @!attribute [r] url
13
+ # @return [String]
14
+ class Organization < BasicData
15
+ register_attributes :id, :name, :display_name, :description, :url, :invited,
16
+ :website, :logo_hash, :billable_member_count, :active_billable_member_count,
17
+ :memberships,
18
+ readonly: [ :id, :name, :display_name, :description, :url, :invited,
19
+ :website, :logo_hash, :billable_member_count, :active_billable_member_count,
20
+ :memberships ]
21
+ validates_presence_of :id, :name
22
+
23
+ include HasActions
24
+
25
+ class << self
26
+ # Find an organization by its id.
27
+ def find(id, params = {})
28
+ client.find(:organization, id, params)
29
+ end
30
+ end
31
+
32
+ # Update the fields of an organization.
33
+ #
34
+ # Supply a hash of string keyed data retrieved from the Trello API representing
35
+ # an Organization.
36
+ def update_fields(fields)
37
+ attributes[:id] = fields['id'] || attributes[:id]
38
+ attributes[:name] = fields['name'] || attributes[:name]
39
+ attributes[:display_name] = fields['displayName'] || attributes[:display_name]
40
+ attributes[:description] = fields['desc'] || attributes[:description]
41
+ attributes[:url] = fields['url'] || attributes[:url]
42
+ attributes[:invited] = fields['invited'] if fields.has_key?('invited')
43
+ attributes[:website] = fields['website'] || attributes[:website]
44
+ attributes[:logo_hash] = fields['logoHash'] || attributes[:logo_hash]
45
+ attributes[:billable_member_count] = fields['billableMemberCount'] || attributes[:billable_member_count]
46
+ attributes[:active_billable_member_count] = fields['activeBillableMemberCount'] || attributes[:active_billable_member_count]
47
+ attributes[:memberships] = fields['memberships'] || attributes[:memberships]
48
+ self
49
+ end
50
+
51
+ # Returns a list of boards under this organization.
52
+ def boards
53
+ boards = Board.from_response client.get("/organizations/#{id}/boards/all")
54
+ MultiAssociation.new(self, boards).proxy
55
+ end
56
+
57
+ # Returns an array of members associated with the organization.
58
+ def members(params = {})
59
+ members = Member.from_response client.get("/organizations/#{id}/members/all", params)
60
+ MultiAssociation.new(self, members).proxy
61
+ end
62
+
63
+ # :nodoc:
64
+ def request_prefix
65
+ "/organizations/#{id}"
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,34 @@
1
+ module Trello
2
+ # A file or url that is linked to a Trello card
3
+ #
4
+ # @!attribute id
5
+ # @return [String]
6
+ # @!attribute idPlugin
7
+ # @return [String]
8
+ # @!attribute scope
9
+ # @return [String]
10
+ # @!attribute idModel
11
+ # @return [String]
12
+ # @!attribute value
13
+ # @return [String]
14
+ # @!attribute access
15
+ # @return [String]
16
+ class PluginDatum < BasicData
17
+ # Update the fields of a plugin.
18
+ register_attributes :id, :idPlugin, :scope, :idModel, :value, :access
19
+
20
+
21
+ # Supply a hash of stringkeyed data retrieved from the Trello API representing
22
+ # an attachment.
23
+ def update_fields(fields)
24
+ attributes[:id] = fields['id'] || attributes[:id]
25
+ attributes[:idPlugin] = fields['idPlugin'] || attributes[:idPlugin]
26
+ attributes[:scope] = fields['scope'] || attributes[:scope]
27
+ attributes[:value] = JSON.parse(fields['value']).presence if fields.has_key?('value')
28
+ attributes[:idModel] = fields['idModel'] || attributes[:idModel]
29
+ attributes[:access] = fields['access'] || attributes[:access]
30
+ self
31
+ end
32
+ end
33
+
34
+ end
@@ -0,0 +1,37 @@
1
+ module Trello
2
+
3
+ # @!attribute [r] id
4
+ # @return [String]
5
+ # @!attribute [r] member_id
6
+ # @return [String]
7
+ # @!attribute [r] created_at
8
+ # @return [Datetime]
9
+ # @!attribute [r] permissions
10
+ # @return [Object]
11
+ # @!attribute [r] webhooks
12
+ # @return [Object]
13
+ class Token < BasicData
14
+ register_attributes :id, :member_id, :created_at, :permissions, :webhooks,
15
+ readonly: [ :id, :member_id, :created_at, :permissions, :webhooks ]
16
+
17
+ class << self
18
+ # Finds a token
19
+ def find(token, params = {webhooks: true})
20
+ client.find(:token, token, params)
21
+ end
22
+ end
23
+
24
+ # :nodoc:
25
+ def update_fields(fields)
26
+ attributes[:id] = fields['id'] || attributes[:id]
27
+ attributes[:member_id] = fields['idMember'] || attributes[:member_id]
28
+ attributes[:created_at] = Time.iso8601(fields['dateCreated']) rescue nil if fields.has_key?('dateCreated')
29
+ attributes[:permissions] = fields['permissions'] || attributes[:permissions]
30
+ attributes[:permissions] ||= {}
31
+ attributes[:webhooks] = fields['webhooks'] || attributes[:webhooks]
32
+ end
33
+
34
+ # Returns a reference to the user who authorized the token.
35
+ one :member, path: :members, using: :member_id
36
+ end
37
+ end
@@ -0,0 +1,103 @@
1
+ module Trello
2
+ # A webhook is a URL called each time a specified model is updated
3
+ #
4
+ # @!attribute [r] id
5
+ # @return [String]
6
+ # @!attribute [r] description
7
+ # @return [String]
8
+ # @!attribute [r] id_model
9
+ # @return [String] A 24-character hex string
10
+ # @!attribute [r] callback_url
11
+ # @return [String]
12
+ # @!attribute [r] active
13
+ # @return [Boolean]
14
+ class Webhook < BasicData
15
+ register_attributes :id, :description, :id_model, :callback_url, :active,
16
+ readonly: [ :id ]
17
+ validates_presence_of :id, :id_model, :callback_url
18
+ validates_length_of :description, in: 1..16384
19
+
20
+ class << self
21
+ # Find a specific webhook by its ID.
22
+ #
23
+ # @raise [Trello::Error] if a Webhook with the given ID can't be found.
24
+ # @return [Trello::Webhook] the Webhook with the given ID.
25
+ def find(id, params = {})
26
+ client.find(:webhook, id, params)
27
+ end
28
+
29
+ # Create a new webhook and save it to Trello.
30
+ #
31
+ # @param [Hash] options
32
+ #
33
+ # @option options [String] :description (optional) A string with a length from 0 to 16384
34
+ # @option options [String] :callback_url (required) A valid URL that is
35
+ # reachable with a HEAD request
36
+ # @option options [String] :id_model (required) id of the model that should be hooked
37
+ #
38
+ # @raise [Trello::Error] if the Webhook could not be created.
39
+ #
40
+ # @return [Trello::Webhook]
41
+ def create(options)
42
+ client.create(:webhook,
43
+ 'description' => options[:description],
44
+ 'idModel' => options[:id_model],
45
+ 'callbackURL' => options[:callback_url])
46
+ end
47
+ end
48
+
49
+ # @return [Trello::Webhook] self
50
+ def update_fields(fields)
51
+ attributes[:id] = fields['id'] || attributes[:id]
52
+ attributes[:description] = fields['description'] || fields[:description] || attributes[:description]
53
+ attributes[:id_model] = fields['idModel'] || fields[:id_model] || attributes[:id_model]
54
+ attributes[:callback_url] = fields['callbackURL'] || fields[:callback_url] || attributes[:callback_url]
55
+ attributes[:active] = fields['active'] if fields.has_key?('active')
56
+ self
57
+ end
58
+
59
+ # Save the webhook.
60
+ #
61
+ # @raise [Trello::Error] if the Webhook could not be saved.
62
+ #
63
+ # @return [String] the JSON representation of the saved webhook.
64
+ def save
65
+ # If we have an id, just update our fields.
66
+ return update! if id
67
+
68
+ from_response client.post("/webhooks", {
69
+ description: description,
70
+ idModel: id_model,
71
+ callbackURL: callback_url
72
+ })
73
+ end
74
+
75
+ # Update the webhook.
76
+ #
77
+ # @raise [Trello::Error] if the Webhook could not be saved.
78
+ #
79
+ # @return [String] the JSON representation of the updated webhook.
80
+ def update!
81
+ client.put("/webhooks/#{id}", {
82
+ description: description,
83
+ idModel: id_model,
84
+ callbackURL: callback_url,
85
+ active: active
86
+ })
87
+ end
88
+
89
+ # Delete this webhook
90
+ #
91
+ # @return [String] the JSON response from the Trello API
92
+ def delete
93
+ client.delete("/webhooks/#{id}")
94
+ end
95
+
96
+ # Check if the webhook is activated
97
+ #
98
+ # @return [Boolean]
99
+ def activated?
100
+ active
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,149 @@
1
+ require 'spec_helper'
2
+
3
+ module Trello
4
+ describe Action do
5
+ include Helpers
6
+
7
+ let(:client) { Client.new }
8
+ let(:action) { client.find(:action, '4ee2482134a81a757a08af47') }
9
+
10
+ before do
11
+ allow(client)
12
+ .to receive(:get)
13
+ .with('/actions/4ee2482134a81a757a08af47', {})
14
+ .and_return JSON.generate(actions_details.first)
15
+ end
16
+
17
+ context 'finding' do
18
+ let(:client) { Trello.client }
19
+
20
+ it 'delegates to Trello.client#find' do
21
+ expect(client)
22
+ .to receive(:find)
23
+ .with(:action, '4ee2482134a81a757a08af47', {})
24
+
25
+ Action.find('4ee2482134a81a757a08af47')
26
+ end
27
+
28
+ it do
29
+ expect(Action.find('4ee2482134a81a757a08af47')).to eq(action)
30
+ end
31
+ end
32
+
33
+ context 'search' do
34
+ let(:client) { Trello.client }
35
+ let(:payload) { JSON.generate({ "cards" => cards_details }) }
36
+
37
+ it "searches and get back a card object" do
38
+ expect(client)
39
+ .to receive(:get)
40
+ .with("/search/", { query: "something"})
41
+ .and_return payload
42
+
43
+ expect(Action.search("something"))
44
+ .to eq({ "cards" => cards_details.jsoned_into(Card) })
45
+ end
46
+ end
47
+
48
+ context 'fields' do
49
+ let(:detail) { actions_details.first }
50
+
51
+ it 'gets its id' do
52
+ expect(action.id).to eq detail['id']
53
+ end
54
+
55
+ it 'gets its type' do
56
+ expect(action.type).to eq detail['type']
57
+ end
58
+
59
+ it 'has the same data' do
60
+ expect(action.data).to eq detail['data']
61
+ end
62
+
63
+ it 'gets the date' do
64
+ expect(action.date.utc.iso8601).to eq detail['date']
65
+ end
66
+ end
67
+
68
+ context 'boards' do
69
+ let(:payload) { JSON.generate(boards_details.first) }
70
+
71
+ before do
72
+ allow(client)
73
+ .to receive(:get)
74
+ .with('/actions/4ee2482134a81a757a08af47/board')
75
+ .and_return payload
76
+ end
77
+
78
+ it 'has a board' do
79
+ expect(action.board).to_not be_nil
80
+ end
81
+ end
82
+
83
+
84
+ context 'card' do
85
+ let(:payload) { JSON.generate(cards_details.first) }
86
+
87
+ before do
88
+ allow(client)
89
+ .to receive(:get)
90
+ .with('/actions/4ee2482134a81a757a08af47/card')
91
+ .and_return payload
92
+ end
93
+
94
+ it 'has a card' do
95
+ expect(action.card).to_not be_nil
96
+ end
97
+ end
98
+
99
+ context 'list' do
100
+ let(:payload) { JSON.generate(lists_details.first) }
101
+
102
+ before do
103
+ allow(client)
104
+ .to receive(:get)
105
+ .with('/actions/4ee2482134a81a757a08af47/list')
106
+ .and_return payload
107
+ end
108
+
109
+ it 'has a list of lists' do
110
+ expect(action.list).to_not be_nil
111
+ end
112
+ end
113
+
114
+ context 'member creator' do
115
+
116
+ before do
117
+ allow(client)
118
+ .to receive(:get)
119
+ .with('/members/abcdef123456789123456789', {})
120
+ .and_return user_payload
121
+ end
122
+
123
+ it 'knows its member creator' do
124
+ expect(action.member_creator).to_not be_nil
125
+ end
126
+ end
127
+
128
+ describe "#update_fields" do
129
+ it "does not set any fields when the fields argument is empty" do
130
+ expected = {
131
+ 'id' => 'id',
132
+ 'type' => 'type',
133
+ 'data' => 'data',
134
+ 'idMemberCreator' => 'member_creator_id',
135
+ 'member' => 'member_participant'
136
+ }
137
+
138
+ action = Action.new(expected)
139
+ action.client = client
140
+
141
+ action.update_fields({})
142
+
143
+ expected.each do |key, value|
144
+ expect(action.send(value)).to eq expected[key]
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end