ruby-trello 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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