ruby-trello 2.0.1 → 2.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77b35b3b765d1056e69ec92a4d403439849c66edfdb01747d590d79026b7ac67
4
- data.tar.gz: 35173e15c5deb8a4c8404831c2cb524e3b8283cc60ac69d0d9519b9b9b22d66c
3
+ metadata.gz: 2971d7fb189328ae318b068c480ccb94824c8c85dbefed703a1837d839790144
4
+ data.tar.gz: ffdf9a6dac2e3adc9d69306d70c7a8b784cd1809e0ebab2a3bb4dd394d25a732
5
5
  SHA512:
6
- metadata.gz: 155bdc62579174c62bf3ade75dd2921cdfb29aa5ced74176d90ea62a94fa279f0e164a54cd0970392296fa04dec7d53a293d45bb188f9eeac3f662d23109f309
7
- data.tar.gz: d4e75692b37cd6d1befa4d14dff5bce2acdca231a90287e898af1cadcaec4d5f006e8fb6ed05aeeb6982ab741a1f93e003bda3b8f3aa1eb9974fcdff9a6fd920
6
+ metadata.gz: 4c7b7da985552a94069f359ea7e80200305e60ae1642f50541d28a412e8fe83b9dd8ca77594556435b0b7aac827eecf83d6ee5b8da378cbdfac635a42146694e
7
+ data.tar.gz: 230297498d5a1847802cc5a1a0a273222e75b2204554f2caed1b41549bf2942cedda5633156f414d108c384dfaaac8fa865d8520a7f16545105c6ee9adcc8aa9
data/lib/trello.rb CHANGED
@@ -50,6 +50,9 @@ module Trello
50
50
  autoload :Checklist, 'trello/checklist'
51
51
  autoload :Client, 'trello/client'
52
52
  autoload :Configuration, 'trello/configuration'
53
+ autoload :CustomField, 'trello/custom_field'
54
+ autoload :CustomFieldItem, 'trello/custom_field_item'
55
+ autoload :CustomFieldOption, 'trello/custom_field_option'
53
56
  autoload :HasActions, 'trello/has_actions'
54
57
  autoload :Item, 'trello/item'
55
58
  autoload :CheckItemState, 'trello/item_state'
@@ -122,7 +122,15 @@ module Trello
122
122
 
123
123
  # Two objects are equal if their _id_ methods are equal.
124
124
  def ==(other)
125
- id == other.id
125
+ self.class == other.class && id == other.id
126
+ end
127
+
128
+ # Alias hash equality to equality
129
+ alias eql? ==
130
+
131
+ # Delegate hash key computation to class and id pair
132
+ def hash
133
+ [self.class, id].hash
126
134
  end
127
135
 
128
136
  def client
data/lib/trello/board.rb CHANGED
@@ -167,6 +167,9 @@ module Trello
167
167
  # Returns a list of plugins associated with the board
168
168
  many :plugin_data, path: "pluginData"
169
169
 
170
+ # Returns custom fields activated on this board
171
+ many :custom_fields, path: "customFields"
172
+
170
173
  def labels(params = {})
171
174
  # Set the limit to as high as possible given there is no pagination in this API.
172
175
  params[:limit] = 1000 unless params[:limit]
data/lib/trello/card.rb CHANGED
@@ -210,6 +210,9 @@ module Trello
210
210
  # Returns a list of plugins associated with the card
211
211
  many :plugin_data, path: "pluginData"
212
212
 
213
+ # List of custom field values on the card, only the ones that have been set
214
+ many :custom_field_items, path: 'customFieldItems'
215
+
213
216
  def check_item_states
214
217
  states = CheckItemState.from_response client.get("/cards/#{self.id}/checkItemStates")
215
218
  MultiAssociation.new(self, states).proxy
@@ -0,0 +1,113 @@
1
+ module Trello
2
+ # A Custom Field can be activated on a board. Values are stored at the card level.
3
+ #
4
+ # @!attribute id
5
+ # @return [String]
6
+ # @!attribute model_id
7
+ # @return [String]
8
+ # @!attribute model_type
9
+ # @return [String]
10
+ # @!attribute field_group
11
+ # @return [String]
12
+ # @!attribute name
13
+ # @return [String]
14
+ # @!attribute pos
15
+ # @return [Float]
16
+ # @!attribute type
17
+ # @return [String]
18
+ # @!attribute options
19
+ # @return [Array<Hash>]
20
+ class CustomField < BasicData
21
+ register_attributes :id, :model_id, :model_type, :field_group, :name, :pos, :type
22
+ validates_presence_of :id, :model_id, :model_type, :name, :type, :pos
23
+
24
+ SYMBOL_TO_STRING = {
25
+ id: 'id',
26
+ name: 'name',
27
+ model_id: 'idModel',
28
+ model_type: 'modelType',
29
+ field_group: 'fieldGroup',
30
+ type: 'type',
31
+ pos: 'pos'
32
+ }
33
+
34
+ class << self
35
+ # Find a custom field by its id.
36
+ def find(id, params = {})
37
+ client.find('customFields', id, params)
38
+ end
39
+
40
+ # Create a new custom field and save it on Trello.
41
+ def create(options)
42
+ client.create('customFields',
43
+ 'name' => options[:name],
44
+ 'idModel' => options[:model_id],
45
+ 'modelType' => options[:model_type],
46
+ 'fieldGroup' => options[:field_group],
47
+ 'type' => options[:type],
48
+ 'pos' => options[:pos]
49
+ )
50
+ end
51
+ end
52
+
53
+ # References Board where this custom field is located
54
+ # Currently, model_type will always be "board" at the customFields endpoint
55
+ one :board, path: :boards, using: :model_id
56
+
57
+ # If type == 'list'
58
+ many :custom_field_options, path: 'options'
59
+
60
+ def update_fields(fields)
61
+ attributes[:id] = fields[SYMBOL_TO_STRING[:id]] || fields[:id] || attributes[:id]
62
+ attributes[:name] = fields[SYMBOL_TO_STRING[:name]] || fields[:name] || attributes[:name]
63
+ attributes[:model_id] = fields[SYMBOL_TO_STRING[:model_id]] || fields[:model_id] || attributes[:model_id]
64
+ attributes[:model_type] = fields[SYMBOL_TO_STRING[:model_type]] || fields[:model_type] || attributes[:model_type]
65
+ attributes[:field_group] = fields[SYMBOL_TO_STRING[:field_group]] || fields[:field_group] || attributes[:field_group]
66
+ attributes[:type] = fields[SYMBOL_TO_STRING[:type]] || fields[:type] || attributes[:type]
67
+ attributes[:pos] = fields[SYMBOL_TO_STRING[:pos]] || fields[:pos] || attributes[:pos]
68
+ self
69
+ end
70
+
71
+ # Saves a record.
72
+ def save
73
+ # If we have an id, just update our fields.
74
+ return update! if id
75
+
76
+ from_response client.post("/customFields", {
77
+ name: name,
78
+ idModel: model_id,
79
+ modelType: model_type,
80
+ type: type,
81
+ pos: pos,
82
+ fieldGroup: field_group
83
+ })
84
+ end
85
+
86
+ # Update an existing custom field.
87
+ def update!
88
+ @previously_changed = changes
89
+ # extract only new values to build payload
90
+ payload = Hash[changes.map { |key, values| [SYMBOL_TO_STRING[key.to_sym].to_sym, values[1]] }]
91
+ @changed_attributes.clear
92
+
93
+ client.put("/customFields/#{id}", payload)
94
+ end
95
+
96
+ # Delete this custom field
97
+ # Also deletes all associated values across all cards
98
+ def delete
99
+ client.delete("/customFields/#{id}")
100
+ end
101
+
102
+ # If type == 'list', create a new option and add to this Custom Field
103
+ def create_new_option(value)
104
+ payload = { value: value }
105
+ client.post("/customFields/#{id}/options", payload)
106
+ end
107
+
108
+ # Will also clear it from individual cards that have this option selected
109
+ def delete_option(option_id)
110
+ client.delete("/customFields/#{id}/options/#{option_id}")
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,77 @@
1
+ module Trello
2
+ # A custom field item contains the value for a custom field on a particular card.
3
+ #
4
+ class CustomFieldItem < BasicData
5
+ register_attributes :id, :model_id, :model_type, :custom_field_id, :value, :option_id,
6
+ readonly: [ :id, :custom_field_id, :model_id, :model_type, :option_id ]
7
+ validates_presence_of :id, :model_id, :custom_field_id
8
+
9
+ # References the card with this custom field value
10
+ one :card, path: :cards, using: :model_id
11
+
12
+ # References the parent custom field that this item is an instance of
13
+ one :custom_field, path: 'customFields', using: :custom_field_id
14
+
15
+ # Update the fields of a custom field item.
16
+ #
17
+ # Supply a hash of string keyed data retrieved from the Trello API representing
18
+ # an item state.
19
+ def update_fields(fields)
20
+ attributes[:id] = fields['id'] || fields[:id] || attributes[:id]
21
+ attributes[:model_id] = fields['idModel'] || fields[:model_id] || attributes[:model_id]
22
+ attributes[:custom_field_id] = fields['idCustomField'] || fields[:custom_field_id] || attributes[:custom_field_id]
23
+ attributes[:model_type] = fields['modelType'] || fields[:model_type] || attributes[:model_type]
24
+ # Dropdown custom field items do not have a value, they have an ID that maps to
25
+ # a different endpoint to get the value
26
+ attributes[:option_id] = fields['idValue'] if fields.has_key?('idValue')
27
+ # value format: { "text": "hello world" }
28
+ attributes[:value] = fields['value'] if fields.has_key?('value')
29
+ self
30
+ end
31
+
32
+ def update!
33
+ @previously_changed = changes
34
+ # extract only new values to build payload
35
+ payload = Hash[changes.map { |key, values| [key.to_sym, values[1]] }]
36
+ @changed_attributes.clear
37
+
38
+ client.put("/card/#{model_id}/customField/#{custom_field_id}/item", payload)
39
+ end
40
+
41
+ # Saves a record.
42
+ #
43
+ # @raise [Trello::Error] if the card could not be saved
44
+ #
45
+ # @return [String] The JSON representation of the saved custom field item returned by
46
+ # the Trello API.
47
+ def save
48
+ # If we have an id, just update our fields.
49
+ return update! if id
50
+
51
+ from_response client.post("/card/#{model_id}/customField/#{custom_field_id}/item", {
52
+ value: value
53
+ })
54
+ end
55
+
56
+ # You can't "delete" a custom field item, you can only clear the value
57
+ def remove
58
+ params = { value: {} }
59
+ client.put("/card/#{model_id}/customField/#{custom_field_id}/item", params)
60
+ end
61
+
62
+ # Type is saved at the CustomField level
63
+ # Can equally be derived from :value, with a little parsing work: {"number": 42}
64
+ def type
65
+ custom_field.type
66
+ end
67
+
68
+ # Need to make another call to get the actual value if the custom field type == 'list'
69
+ def option_value
70
+ if option_id
71
+ option_endpoint = "/customFields/#{custom_field_id}/options/#{option_id}"
72
+ option = CustomFieldOption.from_response client.get(option_endpoint)
73
+ option.value
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,22 @@
1
+ module Trello
2
+ # A custom field option contains the individual items in a custom field dropdown menu.
3
+ #
4
+ class CustomFieldOption < BasicData
5
+ register_attributes :id, :value, :pos, :color,
6
+ readonly: [:id]
7
+ validates_presence_of :id, :value
8
+
9
+ # Update the fields of a custom field option.
10
+ #
11
+ # Supply a hash of string keyed data retrieved from the Trello API representing
12
+ # an item state.
13
+ def update_fields(fields)
14
+ attributes[:id] = fields['_id'] || fields[:id] || attributes[:id]
15
+ attributes[:color] = fields['color'] || fields[:color] || attributes[:color]
16
+ attributes[:pos] = fields['pos'] || fields[:pos] || attributes[:pos]
17
+ # value format: { "text": "hello world" }
18
+ attributes[:value] = fields['value'] || fields[:value] || attributes[:value]
19
+ self
20
+ end
21
+ end
22
+ end
data/lib/trello/label.rb CHANGED
@@ -9,7 +9,7 @@ module Trello
9
9
  class Label < BasicData
10
10
  register_attributes :id, :name, :board_id, :uses,
11
11
  readonly: [ :id, :uses, :board_id ]
12
- validates_presence_of :id, :uses, :board_id, :name
12
+ validates_presence_of :id, :board_id, :name
13
13
  validates_length_of :name, in: 1..16384
14
14
 
15
15
  SYMBOL_TO_STRING = {
@@ -23,7 +23,7 @@ module Trello
23
23
  class << self
24
24
  VALID_LABEL_COLOURS = %w{green yellow orange red purple blue sky lime pink black} << ''
25
25
 
26
- # Find a specific card by its id.
26
+ # Find a specific label by its id.
27
27
  def find(id, params = {})
28
28
  client.find(:label, id, params)
29
29
  end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+
3
+ module Trello
4
+ describe BasicData do
5
+ describe "equality" do
6
+ specify "two objects of the same type are equal if their id values are equal" do
7
+ data_object = Card.new('id' => 'abc123')
8
+ other_data_object = Card.new('id' => 'abc123')
9
+
10
+ expect(data_object).to eq(other_data_object)
11
+ end
12
+
13
+ specify "two object of the samy type are not equal if their id values are different" do
14
+ data_object = Card.new('id' => 'abc123')
15
+ other_data_object = Card.new('id' => 'def456')
16
+
17
+ expect(data_object).not_to eq(other_data_object)
18
+ end
19
+
20
+ specify "two object of different types are not equal even if their id values are equal" do
21
+ card = Card.new('id' => 'abc123')
22
+ list = List.new('id' => 'abc123')
23
+
24
+ expect(card.id).to eq(list.id)
25
+ expect(card).to_not eq(list)
26
+ end
27
+ end
28
+
29
+ describe "hash equality" do
30
+ specify "two objects of the same type point to the same hash key" do
31
+ data_object = Card.new('id' => 'abc123')
32
+ other_data_object = Card.new('id' => 'abc123')
33
+
34
+ hash = {data_object => 'one'}
35
+
36
+ expect(hash[other_data_object]).to eq('one')
37
+ end
38
+
39
+ specify "two object of the same type with different ids do not point to the same hash key" do
40
+ data_object = Card.new('id' => 'abc123')
41
+ other_data_object = Card.new('id' => 'def456')
42
+
43
+ hash = {data_object => 'one'}
44
+
45
+ expect(hash[other_data_object]).to be_nil
46
+ end
47
+
48
+ specify "two object of different types with same ids do not point to the same hash key" do
49
+ card = Card.new('id' => 'abc123')
50
+ list = List.new('id' => 'abc123')
51
+
52
+ hash = {card => 'one'}
53
+
54
+ expect(hash[list]).to be_nil
55
+ end
56
+ end
57
+ end
58
+ end
data/spec/board_spec.rb CHANGED
@@ -251,6 +251,19 @@ module Trello
251
251
  end
252
252
  end
253
253
 
254
+ context "custom fields" do
255
+ before do
256
+ allow(client)
257
+ .to receive(:get)
258
+ .with("/boards/abcdef123456789123456789/customFields", {})
259
+ .and_return JSON.generate([custom_fields_details.first])
260
+ end
261
+
262
+ it "has custom fields" do
263
+ expect(board.custom_fields.count).to be > 0
264
+ end
265
+ end
266
+
254
267
  it "is not closed" do
255
268
  expect(board).not_to be_closed
256
269
  end
data/spec/card_spec.rb CHANGED
@@ -257,7 +257,6 @@ module Trello
257
257
  expect(card.pos).to_not be_nil
258
258
  end
259
259
 
260
-
261
260
  it 'gets its creation time' do
262
261
  expect(card.created_at).to be_kind_of Time
263
262
  end
@@ -338,6 +337,41 @@ module Trello
338
337
  end
339
338
  end
340
339
 
340
+ context "custom field items" do
341
+ before do
342
+ allow(client)
343
+ .to receive(:get)
344
+ .with("/cards/abcdef123456789123456789/customFieldItems", {})
345
+ .and_return JSON.generate([custom_field_item_details])
346
+ end
347
+
348
+ it "has a list of custom field items" do
349
+ expect(card.custom_field_items.count).to be > 0
350
+ end
351
+
352
+ it "clears the custom field value on a card" do
353
+ params = { value: {} }
354
+
355
+ expect(client)
356
+ .to receive(:put)
357
+ .with("/card/abcdef123456789123456789/customField/abcdef123456789123456789/item", params)
358
+
359
+ card.custom_field_items.last.remove
360
+ end
361
+
362
+ it "updates a custom field value" do
363
+ payload = { value: { text: 'Test Text' } }
364
+
365
+ expect(client)
366
+ .to receive(:put)
367
+ .with("/card/abcdef123456789123456789/customField/abcdef123456789123456789/item", payload)
368
+
369
+ text_custom_field = card.custom_field_items.last
370
+ text_custom_field.value = { text: 'Test Text' }
371
+ text_custom_field.save
372
+ end
373
+ end
374
+
341
375
  context "list" do
342
376
  before do
343
377
  allow(client)
@@ -345,6 +379,7 @@ module Trello
345
379
  .with("/lists/abcdef123456789123456789", {})
346
380
  .and_return JSON.generate(lists_details.first)
347
381
  end
382
+
348
383
  it 'has a list' do
349
384
  expect(card.list).to_not be_nil
350
385
  end
@@ -556,7 +591,6 @@ module Trello
556
591
  end
557
592
  end
558
593
 
559
-
560
594
  context "comments" do
561
595
  it "posts a comment" do
562
596
  expect(client)
@@ -0,0 +1,118 @@
1
+ require 'spec_helper'
2
+
3
+ module Trello
4
+ describe CustomFieldItem do
5
+ include Helpers
6
+
7
+ let(:text_field_details) {
8
+ {
9
+ 'id' => 'abcdefgh12345678',
10
+ 'value' => {"text" => "Low Priority"},
11
+ 'idValue' => nil,
12
+ 'idModel' => 'abc123',
13
+ 'idCustomField' => 'abcd1234',
14
+ 'modelType' => 'card'
15
+ }
16
+ }
17
+
18
+ let(:list_item_details) {
19
+ {
20
+ 'id' => 'abcdefgh12345678',
21
+ 'value' => nil,
22
+ 'idValue' => 'abcde12345',
23
+ 'idModel' => 'abc123',
24
+ 'idCustomField' => 'abcd1234',
25
+ 'modelType' => 'card'
26
+ }
27
+ }
28
+
29
+ let(:client) { Client.new }
30
+ let(:text_item) { CustomFieldItem.new(text_field_details) }
31
+ let(:list_item) { CustomFieldItem.new(list_item_details) }
32
+
33
+ it 'validates presence of id, model ID and custom field ID' do
34
+ invalid_item = CustomFieldItem.new
35
+
36
+ expect(invalid_item).to be_invalid
37
+ expect(invalid_item.errors).to include(:id)
38
+ expect(invalid_item.errors).to include(:model_id)
39
+ expect(invalid_item.errors).to include(:custom_field_id)
40
+ end
41
+
42
+ describe 'retrieve item fields' do
43
+ it 'gets its id' do
44
+ expect(text_item.id).to eq text_field_details['id']
45
+ end
46
+
47
+ it 'gets its value' do
48
+ expect(text_item.value).to eq text_field_details['value']
49
+ end
50
+
51
+ it 'gets its model type' do
52
+ expect(text_item.model_type).to eq text_field_details['modelType']
53
+ end
54
+
55
+ it 'gets its model ID' do
56
+ expect(text_item.model_id).to eq text_field_details['idModel']
57
+ end
58
+
59
+ it 'gets its custom field ID' do
60
+ expect(text_item.custom_field_id).to eq text_field_details['idCustomField']
61
+ end
62
+
63
+ it 'has a value ID for list option' do
64
+ expect(list_item.option_id).to eq list_item_details['idValue']
65
+ end
66
+ end
67
+
68
+ describe 'list option' do
69
+ let(:client) { Trello.client }
70
+
71
+ before do
72
+ allow(client)
73
+ .to receive(:get)
74
+ .with("/customFields/#{list_item.custom_field_id}/options/#{list_item.option_id}")
75
+ .and_return JSON.generate(custom_field_option_details)
76
+ end
77
+
78
+ it 'gets the value' do
79
+ expect(list_item.option_value).to_not be_nil
80
+ end
81
+ end
82
+
83
+ describe 'custom field' do
84
+ let(:client) { Trello.client }
85
+
86
+ before do
87
+ allow(client)
88
+ .to receive(:get)
89
+ .with("/customFields/abcd1234", {})
90
+ .and_return JSON.generate(custom_fields_details.first)
91
+ end
92
+
93
+ it 'has a custom field' do
94
+ expect(text_item.custom_field).to be_a CustomField
95
+ expect(text_item.custom_field.name).to eq('Priority')
96
+ end
97
+
98
+ it 'returns the custom field type' do
99
+ expect(text_item.type).to eq 'checkbox'
100
+ end
101
+ end
102
+
103
+ describe 'card' do
104
+ let(:client) { Trello.client }
105
+
106
+ before do
107
+ allow(client)
108
+ .to receive(:get)
109
+ .with("/cards/abc123", {})
110
+ .and_return JSON.generate(cards_details.first)
111
+ end
112
+
113
+ it 'has a card' do
114
+ expect(text_item.card).to be_a Card
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,49 @@
1
+ require 'spec_helper'
2
+
3
+ module Trello
4
+ describe CustomFieldOption do
5
+ include Helpers
6
+
7
+ let(:option) { CustomFieldOption.new(custom_field_option_details) }
8
+
9
+ it 'validates presence of value and id' do
10
+ invalid_option = CustomFieldOption.new
11
+
12
+ expect(invalid_option).to be_invalid
13
+ expect(invalid_option.errors).to include(:value)
14
+ expect(invalid_option.errors).to include(:id)
15
+ end
16
+
17
+ describe 'retrieve option fields' do
18
+ it 'gets its id' do
19
+ expect(option.id).to eq custom_field_option_details['_id']
20
+ end
21
+
22
+ it 'gets its color' do
23
+ expect(option.color).to eq custom_field_option_details['color']
24
+ end
25
+
26
+ it 'knows its value' do
27
+ expect(option.value).to eq custom_field_option_details['value']
28
+ end
29
+
30
+ it 'gets its pos' do
31
+ expect(option.pos).to eq custom_field_option_details['pos']
32
+ end
33
+ end
34
+
35
+ describe 'update fields' do
36
+ it 'allows fields to be updated' do
37
+ updated = {
38
+ color: "purple",
39
+ value: { "text" => "Medium Priority" }
40
+ }
41
+
42
+ option.update_fields(updated)
43
+
44
+ expect(option.color).to eq "purple"
45
+ expect(option.value).to eq({"text" => "Medium Priority"})
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,185 @@
1
+ require 'spec_helper'
2
+
3
+ module Trello
4
+ describe CustomField do
5
+ include Helpers
6
+
7
+ let(:custom_field) { client.find('customFields', 'abcdef123456789123456789') }
8
+ let(:client) { Client.new }
9
+
10
+ before do
11
+ allow(client)
12
+ .to receive(:get)
13
+ .with('/customFields/abcdef123456789123456789', {})
14
+ .and_return custom_fields_payload
15
+ end
16
+
17
+ context 'creating' do
18
+ let(:client) { Trello.client }
19
+
20
+ it 'creates a new CustomField record' do
21
+ custom_fields_details.each do |details|
22
+ custom_field = CustomField.new(details)
23
+ expect(custom_field).to be_valid
24
+ end
25
+ end
26
+
27
+ it 'properly initializes all fields from response-like formatted hash' do
28
+ custom_field_details = custom_fields_details.first
29
+ custom_field = CustomField.new(custom_field_details)
30
+ expect(custom_field.id).to eq(custom_field_details['id'])
31
+ expect(custom_field.name).to eq(custom_field_details['name'])
32
+ expect(custom_field.type).to eq(custom_field_details['type'])
33
+ expect(custom_field.pos).to eq(custom_field_details['pos'])
34
+ expect(custom_field.model_id).to eq(custom_field_details['idModel'])
35
+ expect(custom_field.model_type).to eq(custom_field_details['modelType'])
36
+ end
37
+
38
+ it 'properly initializes all fields from options-like formatted hash' do
39
+ custom_field_details = custom_fields_details[1]
40
+ custom_field = CustomField.new(custom_field_details)
41
+ expect(custom_field.id).to eq(custom_field_details[:id])
42
+ expect(custom_field.name).to eq(custom_field_details[:name])
43
+ expect(custom_field.type).to eq(custom_field_details[:type])
44
+ expect(custom_field.pos).to eq(custom_field_details[:pos])
45
+ expect(custom_field.model_id).to eq(custom_field_details[:model_id])
46
+ expect(custom_field.model_type).to eq(custom_field_details[:model_type])
47
+ end
48
+
49
+ it 'validates presence of id, name, model id, model type, type, and position' do
50
+ custom_field = CustomField.new
51
+ expect(custom_field).to_not be_valid
52
+ expect(custom_field.errors.count).to eq(6)
53
+ expect(custom_field.errors).to include(:name)
54
+ expect(custom_field.errors).to include(:id)
55
+ expect(custom_field.errors).to include(:model_id)
56
+ expect(custom_field.errors).to include(:model_type)
57
+ expect(custom_field.errors).to include(:pos)
58
+ expect(custom_field.errors).to include(:type)
59
+ end
60
+
61
+ it 'creates a new record and saves it on Trello', refactor: true do
62
+ test_payload = {
63
+ name: 'Test Custom Field'
64
+ }
65
+
66
+ result = JSON.generate(custom_fields_details.first.merge(test_payload))
67
+ expected_payload = {name: 'Test Custom Field', type: 'checkbox', idModel: 'abc123',
68
+ modelType: 'board', pos: 123, fieldGroup: nil}
69
+
70
+ expect(client)
71
+ .to receive(:post)
72
+ .with('/customFields', expected_payload)
73
+ .and_return result
74
+
75
+ custom_field = CustomField.create(custom_fields_details[1].merge(test_payload))
76
+ expect(custom_field).to be_a CustomField
77
+ end
78
+ end
79
+
80
+ context 'finding' do
81
+ let(:client) { Trello.client }
82
+
83
+ before do
84
+ allow(client)
85
+ .to receive(:find)
86
+ end
87
+
88
+ it 'delegates to Trello.client#find' do
89
+ expect(client)
90
+ .to receive(:find)
91
+ .with('customFields', 'abcdef123456789123456789', {})
92
+
93
+ CustomField.find('abcdef123456789123456789')
94
+ end
95
+
96
+ it 'is equivalent to client#find' do
97
+ expect(CustomField.find('abcdef123456789123456789')).to eq(custom_field)
98
+ end
99
+ end
100
+
101
+ context 'updating' do
102
+ it 'correctly updates custom field name' do
103
+ expected_new_name = 'Test Name'
104
+
105
+ payload = { name: expected_new_name }
106
+
107
+ expect(client)
108
+ .to receive(:put).once
109
+ .with('/customFields/abcdef123456789123456789', payload)
110
+
111
+ custom_field.name = expected_new_name
112
+ custom_field.save
113
+ end
114
+ end
115
+
116
+ context 'fields' do
117
+ it 'gets its id' do
118
+ expect(custom_field.id).to_not be_nil
119
+ end
120
+
121
+ it 'gets its name' do
122
+ expect(custom_field.name).to_not be_nil
123
+ end
124
+
125
+ it 'gets the model id' do
126
+ expect(custom_field.model_id).to_not be_nil
127
+ end
128
+
129
+ it 'gets the model type' do
130
+ expect(custom_field.model_type).to_not be_nil
131
+ end
132
+
133
+ it 'gets its type' do
134
+ expect(custom_field.type).to_not be_nil
135
+ end
136
+
137
+ it 'gets its position' do
138
+ expect(custom_field.pos).to_not be_nil
139
+ end
140
+ end
141
+
142
+ context 'boards' do
143
+ before do
144
+ allow(client)
145
+ .to receive(:get)
146
+ .with('/boards/abc123', {})
147
+ .and_return JSON.generate(boards_details.first)
148
+ end
149
+
150
+ it 'has a board' do
151
+ expect(custom_field.board).to_not be_nil
152
+ end
153
+ end
154
+
155
+ context 'options' do
156
+ it 'creates a new option' do
157
+ payload = { :value => { "text" => "High Priority" } }
158
+
159
+ expect(client)
160
+ .to receive(:post)
161
+ .with('/customFields/abcdef123456789123456789/options', payload)
162
+
163
+ custom_field.create_new_option({"text" => "High Priority"})
164
+ end
165
+
166
+ it 'deletes option' do
167
+ expect(client)
168
+ .to receive(:delete)
169
+ .with('/customFields/abcdef123456789123456789/options/abc123')
170
+
171
+ custom_field.delete_option('abc123')
172
+ end
173
+ end
174
+
175
+ context 'deleting' do
176
+ it 'deletes the custom field' do
177
+ expect(client)
178
+ .to receive(:delete)
179
+ .with("/customFields/#{custom_field.id}")
180
+
181
+ custom_field.delete
182
+ end
183
+ end
184
+ end
185
+ end
data/spec/spec_helper.rb CHANGED
@@ -425,6 +425,54 @@ module Helpers
425
425
  JSON.generate(label_name_details)
426
426
  end
427
427
 
428
+ def custom_fields_details
429
+ [
430
+ {
431
+ 'id' => 'abcdef123456789123456789',
432
+ 'name' => 'Priority',
433
+ 'idModel' => 'abc123',
434
+ 'type' => 'checkbox',
435
+ 'pos' => 123,
436
+ 'modelType' => 'board'
437
+ },
438
+ {
439
+ id: 'abcdef123456789123456789',
440
+ name: 'Priority',
441
+ model_id: 'abc123',
442
+ type: 'checkbox',
443
+ pos: 123,
444
+ model_type: 'board'
445
+ }
446
+ ]
447
+ end
448
+
449
+ def custom_fields_payload
450
+ JSON.generate(custom_fields_details.first)
451
+ end
452
+
453
+ def custom_field_option_details
454
+ {
455
+ '_id' => 'abcdefgh12345678',
456
+ 'value' => {'text' => 'Low Priority'},
457
+ 'color' => 'green',
458
+ 'pos' => 1
459
+ }
460
+ end
461
+
462
+ def custom_field_item_details
463
+ {
464
+ 'id' => 'abcdefg1234567',
465
+ 'value' => { 'text' => 'hello world' },
466
+ 'idModel' => 'abcdef123456789123456789',
467
+ 'idCustomField' => 'abcdef123456789123456789',
468
+ 'modelType' => 'card'
469
+ }
470
+ end
471
+
472
+ def custom_field_items_payload
473
+ JSON.generate(custom_field_item_details)
474
+ end
475
+
428
476
  def webhooks_payload
429
477
  JSON.generate(webhooks_details)
430
478
  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: 2.0.1
4
+ version: 2.1.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: 2018-02-04 00:00:00.000000000 Z
11
+ date: 2018-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -105,6 +105,9 @@ files:
105
105
  - lib/trello/core_ext/hash.rb
106
106
  - lib/trello/core_ext/string.rb
107
107
  - lib/trello/cover_image.rb
108
+ - lib/trello/custom_field.rb
109
+ - lib/trello/custom_field_item.rb
110
+ - lib/trello/custom_field_option.rb
108
111
  - lib/trello/error.rb
109
112
  - lib/trello/has_actions.rb
110
113
  - lib/trello/item.rb
@@ -125,11 +128,15 @@ files:
125
128
  - spec/array_spec.rb
126
129
  - spec/association_spec.rb
127
130
  - spec/basic_auth_policy_spec.rb
131
+ - spec/basic_data_spec.rb
128
132
  - spec/board_spec.rb
129
133
  - spec/card_spec.rb
130
134
  - spec/checklist_spec.rb
131
135
  - spec/client_spec.rb
132
136
  - spec/configuration_spec.rb
137
+ - spec/custom_field_item_spec.rb
138
+ - spec/custom_field_option_spec.rb
139
+ - spec/custom_field_spec.rb
133
140
  - spec/hash_spec.rb
134
141
  - spec/integration/how_to_authorize_spec.rb
135
142
  - spec/integration/how_to_use_boards_spec.rb
@@ -168,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
175
  version: '0'
169
176
  requirements: []
170
177
  rubyforge_project: ruby-trello
171
- rubygems_version: 2.7.3
178
+ rubygems_version: 2.7.7
172
179
  signing_key:
173
180
  specification_version: 4
174
181
  summary: A wrapper around the trello.com API.
@@ -179,11 +186,13 @@ test_files:
179
186
  - spec/integration/how_to_use_boards_spec.rb
180
187
  - spec/integration/how_to_authorize_spec.rb
181
188
  - spec/integration/integration_test.rb
189
+ - spec/custom_field_spec.rb
182
190
  - spec/card_spec.rb
183
191
  - spec/hash_spec.rb
184
192
  - spec/trello_spec.rb
185
193
  - spec/board_spec.rb
186
194
  - spec/member_spec.rb
195
+ - spec/custom_field_option_spec.rb
187
196
  - spec/oauth_policy_spec.rb
188
197
  - spec/configuration_spec.rb
189
198
  - spec/json_utils_spec.rb
@@ -191,10 +200,12 @@ test_files:
191
200
  - spec/list_spec.rb
192
201
  - spec/webhook_spec.rb
193
202
  - spec/organization_spec.rb
203
+ - spec/custom_field_item_spec.rb
194
204
  - spec/basic_auth_policy_spec.rb
195
205
  - spec/token_spec.rb
196
206
  - spec/string_spec.rb
197
207
  - spec/action_spec.rb
208
+ - spec/basic_data_spec.rb
198
209
  - spec/array_spec.rb
199
210
  - spec/client_spec.rb
200
211
  - spec/item_spec.rb