ruby-trello 2.2.0 → 2.3.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 (113) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +49 -10
  3. data/lib/trello.rb +47 -35
  4. data/lib/trello/action.rb +4 -2
  5. data/lib/trello/association_builder/has_many.rb +17 -0
  6. data/lib/trello/association_builder/has_one.rb +16 -0
  7. data/lib/trello/association_fetcher/has_many.rb +26 -0
  8. data/lib/trello/association_fetcher/has_many/fetch.rb +47 -0
  9. data/lib/trello/association_fetcher/has_many/params.rb +56 -0
  10. data/lib/trello/association_fetcher/has_one.rb +25 -0
  11. data/lib/trello/association_fetcher/has_one/fetch.rb +49 -0
  12. data/lib/trello/association_fetcher/has_one/params.rb +36 -0
  13. data/lib/trello/association_infer_tool.rb +13 -0
  14. data/lib/trello/association_proxy.rb +1 -1
  15. data/lib/trello/basic_data.rb +7 -48
  16. data/lib/trello/board.rb +1 -1
  17. data/lib/trello/card.rb +88 -36
  18. data/lib/trello/custom_field.rb +26 -9
  19. data/lib/trello/custom_field_item.rb +32 -12
  20. data/lib/trello/label.rb +24 -7
  21. data/lib/trello/member.rb +1 -1
  22. data/lib/trello/register_attributes.rb +54 -0
  23. data/spec/action_spec.rb +1 -1
  24. data/spec/card_spec.rb +98 -22
  25. data/spec/cassettes/can_add_a_file_from_url_on_a_card.yml +189 -0
  26. data/spec/cassettes/can_add_a_file_on_a_card.yml +200 -0
  27. data/spec/cassettes/can_add_a_member_to_a_card.yml +190 -0
  28. data/spec/cassettes/can_add_label_on_a_card.yml +281 -0
  29. data/spec/cassettes/can_close_bong_a_card.yml +189 -0
  30. data/spec/cassettes/can_get_actions.yml +196 -0
  31. data/spec/cassettes/can_get_attachments.yml +187 -0
  32. data/spec/cassettes/can_get_comments.yml +193 -0
  33. data/spec/cassettes/can_move_a_card_to_another_board_with_specific_list.yml +373 -0
  34. data/spec/cassettes/can_move_a_card_to_another_board_without_specific_list.yml +281 -0
  35. data/spec/cassettes/can_move_a_card_to_another_list.yml +281 -0
  36. data/spec/cassettes/can_remove_a_member_from_a_card.yml +185 -0
  37. data/spec/cassettes/can_remove_an_attachment_on_a_card.yml +277 -0
  38. data/spec/cassettes/can_remove_an_upvote_on_a_card.yml +465 -0
  39. data/spec/cassettes/can_remove_label_on_a_card.yml +279 -0
  40. data/spec/cassettes/can_success_add_comment_to_a_card.yml +196 -0
  41. data/spec/cassettes/can_success_copy_checklist_to_a_card.yml +281 -0
  42. data/spec/cassettes/can_success_copy_checklist_to_a_card_without_name_pos.yml +281 -0
  43. data/spec/cassettes/can_success_create_a_card.yml +99 -0
  44. data/spec/cassettes/can_success_create_new_checklist_to_a_card.yml +189 -0
  45. data/spec/cassettes/can_success_delete_card.yml +185 -0
  46. data/spec/cassettes/can_success_upate_a_card.yml +189 -0
  47. data/spec/cassettes/can_success_update_bong_a_card.yml +191 -0
  48. data/spec/cassettes/can_upvote_on_a_card.yml +469 -0
  49. data/spec/cassettes/card_find_with_id_and_get_all_fields.yml +95 -0
  50. data/spec/cassettes/card_find_with_id_and_get_specific_fields.yml +96 -0
  51. data/spec/cassettes/custom_field_item_save_1.yml +97 -0
  52. data/spec/cassettes/custom_field_item_save_2.yml +281 -0
  53. data/spec/cassettes/get_board_of_card.yml +187 -0
  54. data/spec/cassettes/get_check_item_states_of_card.yml +188 -0
  55. data/spec/cassettes/get_checklists_of_card.yml +187 -0
  56. data/spec/cassettes/get_cover_image_of_card.yml +187 -0
  57. data/spec/cassettes/get_custom_field_items_of_card.yml +187 -0
  58. data/spec/cassettes/get_list_of_card.yml +188 -0
  59. data/spec/cassettes/get_lists.yml +187 -0
  60. data/spec/cassettes/get_members_of_card.yml +189 -0
  61. data/spec/cassettes/get_plugin_data_of_card.yml +187 -0
  62. data/spec/cassettes/get_voters_of_card.yml +188 -0
  63. data/spec/cassettes/remove_upvote_on_a_card_when_have_not_voted.yml +366 -0
  64. data/spec/cassettes/revote_on_a_card.yml +464 -0
  65. data/spec/custom_field_item_spec.rb +74 -0
  66. data/spec/custom_field_spec.rb +76 -0
  67. data/spec/integration/basic_data/many_spec.rb +123 -0
  68. data/spec/integration/basic_data/one_spec.rb +84 -0
  69. data/spec/integration/basic_data/register_attributes_spec.rb +75 -0
  70. data/spec/integration/board_lists_spec.rb +21 -0
  71. data/spec/integration/card/add_and_remove_attachment_spec.rb +45 -0
  72. data/spec/integration/card/add_and_remove_label_spec.rb +35 -0
  73. data/spec/integration/card/add_checklist_spec.rb +32 -0
  74. data/spec/integration/card/add_comment_spec.rb +19 -0
  75. data/spec/integration/card/add_memeber_spec.rb +19 -0
  76. data/spec/integration/card/associations/actions_spec.rb +17 -0
  77. data/spec/integration/card/associations/attachments_spec.rb +18 -0
  78. data/spec/integration/card/associations/board_spec.rb +17 -0
  79. data/spec/integration/card/associations/check_item_states_spec.rb +17 -0
  80. data/spec/integration/card/associations/checklists_spec.rb +18 -0
  81. data/spec/integration/card/associations/comments_spec.rb +19 -0
  82. data/spec/integration/card/associations/cover_image_spec.rb +18 -0
  83. data/spec/integration/card/associations/custom_field_items_spec.rb +18 -0
  84. data/spec/integration/card/associations/list_spec.rb +16 -0
  85. data/spec/integration/card/associations/members_spec.rb +18 -0
  86. data/spec/integration/card/associations/plugin_data_spec.rb +18 -0
  87. data/spec/integration/card/associations/voters_spec.rb +17 -0
  88. data/spec/integration/card/close!_spec.rb +16 -0
  89. data/spec/integration/card/create_new_check_list_spec.rb +19 -0
  90. data/spec/integration/card/create_spec.rb +50 -0
  91. data/spec/integration/card/delete_spec.rb +16 -0
  92. data/spec/integration/card/find_spec.rb +67 -0
  93. data/spec/integration/card/move_to_board_spec.rb +36 -0
  94. data/spec/integration/card/move_to_list_spec.rb +20 -0
  95. data/spec/integration/card/remove_member_spec.rb +19 -0
  96. data/spec/integration/card/save_spec.rb +61 -0
  97. data/spec/integration/card/update!_spec.rb +53 -0
  98. data/spec/integration/card/vote_spec.rb +50 -0
  99. data/spec/integration/custom_field_item_spec.rb +47 -0
  100. data/spec/label_spec.rb +79 -0
  101. data/spec/spec_helper.rb +48 -23
  102. data/spec/unit/trello/association_builder/has_many_spec.rb +36 -0
  103. data/spec/unit/trello/association_builder/has_one_spec.rb +36 -0
  104. data/spec/unit/trello/association_fetcher/has_many/fetch_spec.rb +38 -0
  105. data/spec/unit/trello/association_fetcher/has_many/params_spec.rb +107 -0
  106. data/spec/unit/trello/association_fetcher/has_many_spec.rb +50 -0
  107. data/spec/unit/trello/association_fetcher/has_one/fetch_spec.rb +51 -0
  108. data/spec/unit/trello/association_fetcher/has_one/params_spec.rb +81 -0
  109. data/spec/unit/trello/association_fetcher/has_one_spec.rb +49 -0
  110. data/spec/unit/trello/association_infer_tool_spec.rb +41 -0
  111. data/spec/unit/trello/basic_data_spec.rb +54 -0
  112. data/spec/unit/trello/card_spec.rb +103 -0
  113. metadata +185 -6
@@ -114,5 +114,79 @@ module Trello
114
114
  expect(text_item.card).to be_a Card
115
115
  end
116
116
  end
117
+
118
+ describe '#update_fields' do
119
+
120
+ context 'when the fields argument is empty' do
121
+ let(:fields) { {} }
122
+
123
+ it 'custom field item does not set any fields' do
124
+ text_item.update_fields(fields)
125
+
126
+ expect(text_item.id).to eq text_field_details['id']
127
+ expect(text_item.option_id).to eq text_field_details['idValue']
128
+ expect(text_item.model_id).to eq text_field_details['idModel']
129
+ expect(text_item.custom_field_id).to eq text_field_details['idCustomField']
130
+ expect(text_item.model_type).to eq text_field_details['modelType']
131
+ expect(text_item.value).to eq text_field_details['value']
132
+ end
133
+ end
134
+
135
+ context 'when the fields argument has at least one field' do
136
+
137
+ context 'and the field does changed' do
138
+ let(:fields) { { value: { number: '42' } } }
139
+
140
+ it 'custom field item does set the changed fields' do
141
+ text_item.update_fields(fields)
142
+
143
+ expect(text_item.value).to eq( { number: '42' } )
144
+ end
145
+
146
+ it 'card has been mark as changed' do
147
+ text_item.update_fields(fields)
148
+
149
+ expect(text_item.changed?).to be_truthy
150
+ end
151
+ end
152
+
153
+ context "and the field doesn't changed" do
154
+ let(:fields) { { value: text_field_details['value'] } }
155
+
156
+ it "custom field item attributes doesn't changed" do
157
+ text_item.update_fields(fields)
158
+
159
+ expect(text_item.value).to eq(text_field_details['value'])
160
+ end
161
+
162
+ it "custom field item hasn't been mark as changed", pending: true do
163
+ text_item.update_fields(fields)
164
+
165
+ expect(text_item.changed?).to be_falsy
166
+ end
167
+ end
168
+
169
+ context "and the field isn't a correct attributes of the card" do
170
+ let(:fields) { { abc: 'abc' } }
171
+
172
+ it "custom field item attributes doesn't changed" do
173
+ text_item.update_fields(fields)
174
+
175
+ expect(text_item.id).to eq text_field_details['id']
176
+ expect(text_item.option_id).to eq text_field_details['idValue']
177
+ expect(text_item.model_id).to eq text_field_details['idModel']
178
+ expect(text_item.custom_field_id).to eq text_field_details['idCustomField']
179
+ expect(text_item.model_type).to eq text_field_details['modelType']
180
+ expect(text_item.value).to eq text_field_details['value']
181
+ end
182
+
183
+ it "custom field item hasn't been mark as changed" do
184
+ text_item.update_fields(fields)
185
+
186
+ expect(text_item.changed?).to be_falsy
187
+ end
188
+ end
189
+ end
190
+ end
117
191
  end
118
192
  end
@@ -181,5 +181,81 @@ module Trello
181
181
  custom_field.delete
182
182
  end
183
183
  end
184
+
185
+ describe '#update_fields' do
186
+ let(:custom_field_detail) { custom_fields_details.first }
187
+ let(:custom_field) { CustomField.new(custom_field_detail) }
188
+
189
+ context 'when the fields argument is empty' do
190
+ let(:fields) { {} }
191
+
192
+ it 'custom field does not set any fields' do
193
+ custom_field.update_fields(fields)
194
+
195
+ expect(custom_field.id).to eq custom_field_detail['id']
196
+ expect(custom_field.model_id).to eq custom_field_detail['idModel']
197
+ expect(custom_field.model_type).to eq custom_field_detail['modelType']
198
+ expect(custom_field.name).to eq custom_field_detail['name']
199
+ expect(custom_field.pos).to eq custom_field_detail['pos']
200
+ expect(custom_field.type).to eq custom_field_detail['type']
201
+ end
202
+ end
203
+
204
+ context 'when the fields argument has at least one field' do
205
+ context 'and the field does changed' do
206
+ let(:fields) { { name: 'Awesome Name' } }
207
+
208
+ it 'custom field does set the changed fields' do
209
+ custom_field.update_fields(fields)
210
+
211
+ expect(custom_field.name).to eq('Awesome Name')
212
+ end
213
+
214
+ it 'custom field has been mark as changed' do
215
+ custom_field.update_fields(fields)
216
+
217
+ expect(custom_field.changed?).to be_truthy
218
+ end
219
+ end
220
+
221
+ context "and the field doesn't changed" do
222
+ let(:fields) { { name: custom_field_detail['name'] } }
223
+
224
+ it "custom field attributes doesn't changed" do
225
+ custom_field.update_fields(fields)
226
+
227
+ expect(custom_field.name).to eq(custom_field_detail['name'])
228
+ end
229
+
230
+ it "custom field hasn't been mark as changed", pending: true do
231
+ custom_field.update_fields(fields)
232
+
233
+ expect(custom_field.changed?).to be_falsy
234
+ end
235
+ end
236
+
237
+ context "and the field isn't a correct attributes of the card" do
238
+ let(:fields) { { abc: 'abc' } }
239
+
240
+ it "custom field attributes doesn't changed" do
241
+ custom_field.update_fields(fields)
242
+
243
+ expect(custom_field.id).to eq custom_field_detail['id']
244
+ expect(custom_field.model_id).to eq custom_field_detail['idModel']
245
+ expect(custom_field.model_type).to eq custom_field_detail['modelType']
246
+ expect(custom_field.name).to eq custom_field_detail['name']
247
+ expect(custom_field.pos).to eq custom_field_detail['pos']
248
+ expect(custom_field.type).to eq custom_field_detail['type']
249
+ end
250
+
251
+ it "custom field hasn't been mark as changed" do
252
+ custom_field.update_fields(fields)
253
+
254
+ expect(custom_field.changed?).to be_falsy
255
+ end
256
+ end
257
+ end
258
+ end
259
+
184
260
  end
185
261
  end
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+
3
+ module Trello
4
+ describe BasicData do
5
+ describe '.many' do
6
+ let(:client_double) { double('client') }
7
+ let(:cards) { double('cards') }
8
+
9
+ around do |example|
10
+ class FakeCard < BasicData
11
+ end
12
+ class FakeBoard < BasicData
13
+ def update_fields(fields)
14
+ attributes[:id] = fields[:id]
15
+ end
16
+ end
17
+
18
+ example.run
19
+
20
+ Trello.send(:remove_const, 'FakeBoard')
21
+ Trello.send(:remove_const, 'FakeCard')
22
+ end
23
+
24
+ def mock_client_and_association(klass:, resource:, id:, path:, params:)
25
+ resources = double('resources')
26
+ allow(FakeBoard).to receive(:client).and_return(client_double)
27
+ allow_any_instance_of(FakeBoard).to receive(:client).and_return(client_double)
28
+ allow(client_double).to receive(:find_many).with(klass, "/#{resource}/#{id}/#{path}", params).and_return(resources)
29
+ allow(MultiAssociation).to receive(:new).with(FakeBoard, resources).and_return(double('association', proxy: cards))
30
+ end
31
+
32
+ context 'when only pass in the name' do
33
+ before do
34
+ FakeBoard.class_eval { many :fake_cards }
35
+
36
+ mock_client_and_association(
37
+ klass: Trello::FakeCard,
38
+ resource: 'fakeboards',
39
+ id: 1,
40
+ path: 'fake_cards',
41
+ params: {}
42
+ )
43
+ end
44
+
45
+ it 'can get cards from client' do
46
+ expect(FakeBoard.new(id: 1).fake_cards).to eq(cards)
47
+ end
48
+ end
49
+
50
+ context 'when pass in name with in:' do
51
+ before do
52
+ FakeBoard.class_eval { many :fake_cards, in: 'boards' }
53
+
54
+ mock_client_and_association(
55
+ klass: Trello::FakeCard,
56
+ resource: 'boards',
57
+ id: 1,
58
+ path: 'fake_cards',
59
+ params: {}
60
+ )
61
+ end
62
+
63
+ it 'can get cards from client' do
64
+ expect(FakeBoard.new(id: 1).fake_cards).to eq(cards)
65
+ end
66
+ end
67
+
68
+ context 'when pass in name with via:' do
69
+ before do
70
+ FakeBoard.class_eval { many :fake_cards, via: Card }
71
+
72
+ mock_client_and_association(
73
+ klass: Trello::Card,
74
+ resource: 'fakeboards',
75
+ id: 1,
76
+ path: 'fake_cards',
77
+ params: {}
78
+ )
79
+ end
80
+
81
+ it 'can get cards from client' do
82
+ expect(FakeBoard.new(id: 1).fake_cards).to eq(cards)
83
+ end
84
+ end
85
+
86
+ context 'when pass in name with path:' do
87
+ before do
88
+ FakeBoard.class_eval { many :fake_cards, path: 'test' }
89
+
90
+ mock_client_and_association(
91
+ klass: Trello::FakeCard,
92
+ resource: 'fakeboards',
93
+ id: 1,
94
+ path: 'test',
95
+ params: {}
96
+ )
97
+ end
98
+
99
+ it 'can get cards from client' do
100
+ expect(FakeBoard.new(id: 1).fake_cards).to eq(cards)
101
+ end
102
+ end
103
+
104
+ context 'when pass in name with other params' do
105
+ before do
106
+ FakeBoard.class_eval { many :fake_cards, test: 'test' }
107
+
108
+ mock_client_and_association(
109
+ klass: Trello::FakeCard,
110
+ resource: 'fakeboards',
111
+ id: 1,
112
+ path: 'fake_cards',
113
+ params: {test: 'test'}
114
+ )
115
+ end
116
+
117
+ it 'can get cards from client' do
118
+ expect(FakeBoard.new(id: 1).fake_cards).to eq(cards)
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Trello::BasicData.one' do
4
+
5
+ let(:client_double) { double('client') }
6
+ let(:organization) { double('organization') }
7
+
8
+ around do |example|
9
+ module Trello
10
+ class FakeOrganization < BasicData
11
+ end
12
+ class FakeBoard < BasicData
13
+ def update_fields(fields)
14
+ attributes[:id] = fields[:id]
15
+ end
16
+ end
17
+ end
18
+
19
+ example.run
20
+
21
+ Trello.send(:remove_const, 'FakeBoard')
22
+ Trello.send(:remove_const, 'FakeOrganization')
23
+ end
24
+
25
+ def mock_client_and_association(klass: Trello::FakeOrganization, id: 1, path: nil, id_field: :id)
26
+ association_restful_name = path
27
+ allow(Trello::FakeBoard).to receive(:client).and_return(client_double)
28
+ allow_any_instance_of(Trello::FakeBoard).to receive(:client).and_return(client_double)
29
+ allow_any_instance_of(Trello::FakeBoard).to receive(id_field).and_return(id)
30
+ if association_restful_name
31
+ allow(client_double).to receive(:find).with(association_restful_name, id).and_return(organization)
32
+ else
33
+ allow(klass).to receive(:find).with(id).and_return(organization)
34
+ end
35
+ end
36
+
37
+ context 'when only pass in the name' do
38
+ before do
39
+ Trello::FakeBoard.class_eval { one :fake_organization }
40
+
41
+ mock_client_and_association
42
+ end
43
+
44
+ it 'can get the association from client' do
45
+ expect(Trello::FakeBoard.new(id: 1).fake_organization).to eq(organization)
46
+ end
47
+ end
48
+
49
+ context 'when pass in name with path' do
50
+ before do
51
+ Trello::FakeBoard.class_eval { one :fake_organization, path: 'organizations' }
52
+
53
+ mock_client_and_association(path: 'organizations')
54
+ end
55
+
56
+ it 'can get the association from client' do
57
+ expect(Trello::FakeBoard.new(id: 1).fake_organization).to eq(organization)
58
+ end
59
+ end
60
+
61
+ context 'when pass in name with via' do
62
+ before do
63
+ Trello::FakeBoard.class_eval { one :fake_organization, via: Trello::FakeOrganization }
64
+
65
+ mock_client_and_association
66
+ end
67
+
68
+ it 'can get the association from client' do
69
+ expect(Trello::FakeBoard.new(id: 1).fake_organization).to eq(organization)
70
+ end
71
+ end
72
+
73
+ context 'when pass in name with using' do
74
+ before do
75
+ Trello::FakeBoard.class_eval { one :fake_organization, using: :test_id }
76
+
77
+ mock_client_and_association(id_field: :test_id)
78
+ end
79
+
80
+ it 'can get the association from client' do
81
+ expect(Trello::FakeBoard.new(id: 1).fake_organization).to eq(organization)
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Trello::BasicData.register_attributes' do
4
+
5
+ around do |example|
6
+ module Trello
7
+ class FakeBoard < BasicData
8
+ end
9
+ end
10
+
11
+ example.run
12
+
13
+ Trello.send(:remove_const, 'FakeBoard')
14
+ end
15
+
16
+ context 'when register attributes are all writable' do
17
+ before do
18
+ Trello::FakeBoard.class_eval do
19
+ register_attributes :id, :name, :description
20
+
21
+ def initialize(fields={})
22
+ attributes[:id] = fields[:id]
23
+ attributes[:name] = fields[:name]
24
+ attributes[:description] = fields[:description]
25
+ end
26
+ end
27
+ end
28
+
29
+ it 'create getter method for all attributes' do
30
+ expect(Trello::FakeBoard.new).to respond_to(:id, :name, :description)
31
+ end
32
+
33
+ it 'create setting method for all attributes' do
34
+ expect(Trello::FakeBoard.new).to respond_to(:id=, :name=, :description=)
35
+ end
36
+
37
+ it 'any attributes changes will caused the record being marked as changed' do
38
+ fake_board = Trello::FakeBoard.new(id: 1, name: 'test')
39
+ expect(fake_board.changed?).to eq(false)
40
+ fake_board.name = 'TEST'
41
+ expect(fake_board.changed?).to eq(true)
42
+ end
43
+ end
44
+
45
+ context 'when register attributes are partial read-only' do
46
+ before do
47
+ Trello::FakeBoard.class_eval do
48
+ register_attributes :id, :name, :description, readonly: [:id]
49
+
50
+ def initialize(fields={})
51
+ attributes[:id] = fields[:id]
52
+ attributes[:name] = fields[:name]
53
+ attributes[:description] = fields[:description]
54
+ end
55
+ end
56
+ end
57
+
58
+ it 'create getter method for all attributes' do
59
+ expect(Trello::FakeBoard.new).to respond_to(:id, :name, :description)
60
+ end
61
+
62
+ it 'create setting method for all writable attributes' do
63
+ expect(Trello::FakeBoard.new).to respond_to(:name=, :description=)
64
+ expect(Trello::FakeBoard.new).not_to respond_to(:id=)
65
+ end
66
+
67
+ it 'any writable attributes changes will caused the record being marked as changed' do
68
+ fake_board = Trello::FakeBoard.new(id: 1, name: 'test')
69
+ expect(fake_board.changed?).to eq(false)
70
+ fake_board.name = 'TEST'
71
+ expect(fake_board.changed?).to eq(true)
72
+ end
73
+ end
74
+
75
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Board - Lists API' do
4
+
5
+ before do
6
+ Trello.configure do |config|
7
+ config.developer_public_key = ENV['TRELLO_DEVELOPER_PUBLIC_KEY'] || 'developerpublickey'
8
+ config.member_token = ENV['TRELLO_MEMBER_TOKEN'] || 'membertoken'
9
+ end
10
+ end
11
+
12
+ it 'AssociationProxy#to_a, #to_ary' do
13
+ VCR.use_cassette('get_lists') do
14
+ board = Trello::Board.find('5e679be40c407034b479459c')
15
+ lists = board.lists
16
+ expect(lists.to_a).to be_a(Array)
17
+ expect(lists.to_ary).to be_a(Array)
18
+ end
19
+ end
20
+
21
+ end