ruby-trello 2.3.1 → 3.2.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 (240) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +49 -23
  3. data/lib/trello/action.rb +27 -21
  4. data/lib/trello/attachment.rb +40 -27
  5. data/lib/trello/basic_data.rb +104 -9
  6. data/lib/trello/board.rb +88 -102
  7. data/lib/trello/card.rb +34 -235
  8. data/lib/trello/checklist.rb +17 -71
  9. data/lib/trello/client.rb +1 -1
  10. data/lib/trello/comment.rb +39 -26
  11. data/lib/trello/configuration.rb +8 -0
  12. data/lib/trello/cover_image.rb +20 -0
  13. data/lib/trello/custom_field.rb +31 -84
  14. data/lib/trello/custom_field_item.rb +36 -58
  15. data/lib/trello/custom_field_option.rb +40 -13
  16. data/lib/trello/item.rb +27 -16
  17. data/lib/trello/item_state.rb +7 -15
  18. data/lib/trello/json_utils.rb +11 -5
  19. data/lib/trello/label.rb +14 -101
  20. data/lib/trello/label_name.rb +22 -25
  21. data/lib/trello/list.rb +31 -44
  22. data/lib/trello/member.rb +77 -32
  23. data/lib/trello/net/faraday.rb +46 -0
  24. data/lib/trello/net/rest_client.rb +41 -0
  25. data/lib/trello/net.rb +1 -28
  26. data/lib/trello/notification.rb +27 -20
  27. data/lib/trello/organization.rb +53 -25
  28. data/lib/trello/plugin_datum.rb +11 -16
  29. data/lib/trello/schema/attribute/base.rb +79 -0
  30. data/lib/trello/schema/attribute/board_pref.rb +45 -0
  31. data/lib/trello/schema/attribute/custom_field_display.rb +45 -0
  32. data/lib/trello/schema/attribute/default.rb +45 -0
  33. data/lib/trello/schema/attribute_builder.rb +42 -0
  34. data/lib/trello/schema/attribute_registration.rb +47 -0
  35. data/lib/trello/schema/serializer/default.rb +17 -0
  36. data/lib/trello/schema/serializer/labels.rb +23 -0
  37. data/lib/trello/schema/serializer/time.rb +25 -0
  38. data/lib/trello/schema/serializer/webhooks.rb +25 -0
  39. data/lib/trello/schema.rb +31 -0
  40. data/lib/trello/token.rb +15 -12
  41. data/lib/trello/webhook.rb +18 -71
  42. data/lib/trello.rb +62 -7
  43. data/spec/action_spec.rb +1 -2
  44. data/spec/board_spec.rb +43 -103
  45. data/spec/card_spec.rb +51 -50
  46. data/spec/cassettes/action_find_with_id_and_get_all_fields.yml +104 -0
  47. data/spec/cassettes/board_find_with_id_and_get_all_fields.yml +96 -0
  48. data/spec/cassettes/board_find_with_id_and_get_specific_fields.yml +96 -0
  49. data/spec/cassettes/can_add_a_member_to_a_board.yml +191 -0
  50. data/spec/cassettes/can_arvhice_all_cards_of_list.yml +397 -0
  51. data/spec/cassettes/can_get_actions_of_board.yml +188 -0
  52. data/spec/cassettes/can_get_actions_of_list.yml +202 -0
  53. data/spec/cassettes/can_get_actions_of_members.yml +199 -0
  54. data/spec/cassettes/can_get_actions_of_organization.yml +201 -0
  55. data/spec/cassettes/can_get_boards_of_custom_field.yml +198 -0
  56. data/spec/cassettes/can_get_boards_of_label.yml +197 -0
  57. data/spec/cassettes/can_get_boards_of_organization.yml +207 -0
  58. data/spec/cassettes/can_get_cards_of_board.yml +193 -0
  59. data/spec/cassettes/can_get_cards_of_list.yml +201 -0
  60. data/spec/cassettes/can_get_cards_of_member.yml +204 -0
  61. data/spec/cassettes/can_get_checklists_of_board.yml +187 -0
  62. data/spec/cassettes/can_get_comments_board.yml +109 -0
  63. data/spec/cassettes/can_get_comments_card.yml +111 -0
  64. data/spec/cassettes/can_get_comments_list.yml +109 -0
  65. data/spec/cassettes/can_get_custom_field_options_of_custom_field.yml +197 -0
  66. data/spec/cassettes/can_get_custom_fields_of_board.yml +187 -0
  67. data/spec/cassettes/can_get_label_names_of_board.yml +187 -0
  68. data/spec/cassettes/can_get_labels_of_board.yml +187 -0
  69. data/spec/cassettes/can_get_lists_of_board.yml +187 -0
  70. data/spec/cassettes/can_get_members_of_board.yml +188 -0
  71. data/spec/cassettes/can_get_members_of_organization.yml +200 -0
  72. data/spec/cassettes/can_get_notifications_of_member.yml +199 -0
  73. data/spec/cassettes/can_get_organization_of_board.yml +189 -0
  74. data/spec/cassettes/can_get_organizations_of_member.yml +203 -0
  75. data/spec/cassettes/can_get_plugin_data_of_board.yml +187 -0
  76. data/spec/cassettes/can_move_all_cards_to_another_list.yml +886 -0
  77. data/spec/cassettes/can_success_create_a_board.yml +98 -0
  78. data/spec/cassettes/can_success_create_a_board_with_full_parameters.yml +97 -0
  79. data/spec/cassettes/can_success_create_a_board_without_clone_from_other.yml +98 -0
  80. data/spec/cassettes/can_success_create_a_card_when_due_is_datetime.yml +98 -0
  81. data/spec/cassettes/can_success_create_a_card_when_due_is_time.yml +98 -0
  82. data/spec/cassettes/can_success_create_a_checklist.yml +102 -0
  83. data/spec/cassettes/can_success_create_a_custom_field.yml +102 -0
  84. data/spec/cassettes/can_success_create_a_custom_field_option.yml +102 -0
  85. data/spec/cassettes/can_success_create_a_label.yml +102 -0
  86. data/spec/cassettes/can_success_create_a_list.yml +102 -0
  87. data/spec/cassettes/can_success_create_a_list_with_full_parameters.yml +102 -0
  88. data/spec/cassettes/can_success_create_a_organization.yml +104 -0
  89. data/spec/cassettes/can_success_create_a_webhook.yml +102 -0
  90. data/spec/cassettes/can_success_delete_a_custom_field_option.yml +389 -0
  91. data/spec/cassettes/can_success_delete_checklist.yml +284 -0
  92. data/spec/cassettes/can_success_get_card_of_board_by_card_id.yml +188 -0
  93. data/spec/cassettes/can_success_remove_member_from_board.yml +186 -0
  94. data/spec/cassettes/can_success_return_all_boards_of_current_user.yml +195 -0
  95. data/spec/cassettes/can_success_upate_a_board.yml +191 -0
  96. data/spec/cassettes/can_success_upate_a_list.yml +296 -0
  97. data/spec/cassettes/can_success_update_bong_a_board.yml +39 -39
  98. data/spec/cassettes/can_success_update_bong_a_board_with_specific_fields.yml +284 -0
  99. data/spec/cassettes/can_success_update_bong_a_checklist_with_specific_fields.yml +296 -0
  100. data/spec/cassettes/can_success_update_bong_a_custom_field.yml +200 -0
  101. data/spec/cassettes/can_success_update_bong_a_label.yml +200 -0
  102. data/spec/cassettes/can_success_update_bong_a_list.yml +199 -0
  103. data/spec/cassettes/can_success_update_bong_a_list_with_specific_fields.yml +296 -0
  104. data/spec/cassettes/can_success_update_bong_a_organization.yml +203 -0
  105. data/spec/cassettes/can_success_update_bong_a_webhook.yml +296 -0
  106. data/spec/cassettes/checklist_can_add_an_item.yml +296 -0
  107. data/spec/cassettes/checklist_can_update_the_item_state.yml +296 -0
  108. data/spec/cassettes/checklist_find_with_id_and_get_all_fields.yml +100 -0
  109. data/spec/cassettes/comment_delete.yml +331 -0
  110. data/spec/cassettes/comment_find_with_id.yml +116 -0
  111. data/spec/cassettes/custom_field_find_with_id_and_get_all_fields.yml +100 -0
  112. data/spec/cassettes/custom_field_find_with_id_and_get_specific_fields.yml +100 -0
  113. data/spec/cassettes/custom_field_item_save_1.yml +1 -1
  114. data/spec/cassettes/custom_field_item_save_2.yml +1 -1
  115. data/spec/cassettes/custom_field_option_find_with_id.yml +100 -0
  116. data/spec/cassettes/get_board_of_list.yml +197 -0
  117. data/spec/cassettes/get_boards_of_member.yml +207 -0
  118. data/spec/cassettes/label_delete.yml +285 -0
  119. data/spec/cassettes/label_find_with_id.yml +100 -0
  120. data/spec/cassettes/list_find_with_id_and_get_all_fields.yml +100 -0
  121. data/spec/cassettes/list_find_with_id_and_get_specific_fields.yml +100 -0
  122. data/spec/cassettes/member_find_with_id_and_get_all_fields.yml +101 -0
  123. data/spec/cassettes/member_find_with_id_and_get_specific_fields.yml +100 -0
  124. data/spec/cassettes/notification_find_with_id.yml +103 -0
  125. data/spec/cassettes/organization_find_with_id_and_get_all_fields.yml +102 -0
  126. data/spec/cassettes/organization_find_with_id_and_get_specific_fields.yml +100 -0
  127. data/spec/cassettes/token_find_with_token_string.yml +100 -0
  128. data/spec/cassettes/webhook_delete.yml +286 -0
  129. data/spec/cassettes/webhook_find_with_id.yml +100 -0
  130. data/spec/checklist_spec.rb +27 -43
  131. data/spec/client_spec.rb +57 -3
  132. data/spec/configuration_spec.rb +13 -0
  133. data/spec/custom_field_item_spec.rb +2 -2
  134. data/spec/custom_field_option_spec.rb +2 -2
  135. data/spec/custom_field_spec.rb +25 -13
  136. data/spec/integration/action/find_spec.rb +23 -0
  137. data/spec/integration/basic_data/many_spec.rb +4 -0
  138. data/spec/integration/basic_data/schema_spec.rb +156 -0
  139. data/spec/integration/board/add_member_spec.rb +20 -0
  140. data/spec/integration/board/all_spec.rb +20 -0
  141. data/spec/integration/board/associations/actions_spec.rb +18 -0
  142. data/spec/integration/board/associations/cards_spec.rb +18 -0
  143. data/spec/integration/board/associations/checklists_spec.rb +18 -0
  144. data/spec/integration/board/associations/custom_fields_spec.rb +18 -0
  145. data/spec/integration/board/associations/label_names_spec.rb +17 -0
  146. data/spec/integration/board/associations/labels_spec.rb +18 -0
  147. data/spec/integration/board/associations/lists_spec.rb +18 -0
  148. data/spec/integration/board/associations/members_spec.rb +18 -0
  149. data/spec/integration/board/associations/organization_spec.rb +19 -0
  150. data/spec/integration/board/associations/plugin_data_spec.rb +18 -0
  151. data/spec/integration/board/create_spec.rb +95 -0
  152. data/spec/integration/board/find_card_spec.rb +18 -0
  153. data/spec/integration/board/find_spec.rb +42 -0
  154. data/spec/integration/board/remove_member_spec.rb +21 -0
  155. data/spec/integration/board/save_spec.rb +37 -0
  156. data/spec/integration/board/update!_spec.rb +33 -2
  157. data/spec/integration/card/associations/plugin_data_spec.rb +1 -1
  158. data/spec/integration/card/create_spec.rb +36 -2
  159. data/spec/integration/card/delete_spec.rb +2 -2
  160. data/spec/integration/card/find_spec.rb +1 -1
  161. data/spec/integration/card/save_spec.rb +2 -2
  162. data/spec/integration/checklist/add_item_spec.rb +20 -0
  163. data/spec/integration/checklist/create_spec.rb +23 -0
  164. data/spec/integration/checklist/delete_spec.rb +17 -0
  165. data/spec/integration/checklist/find_spec.rb +22 -0
  166. data/spec/integration/checklist/update!_spec.rb +21 -0
  167. data/spec/integration/checklist/update_item_state_spec.rb +20 -0
  168. data/spec/integration/comment/association/board_spec.rb +17 -0
  169. data/spec/integration/comment/association/card_spec.rb +17 -0
  170. data/spec/integration/comment/association/list_spec.rb +17 -0
  171. data/spec/integration/comment/delete_spec.rb +20 -0
  172. data/spec/integration/comment/find_spec.rb +17 -0
  173. data/spec/integration/custom_field/association/board_spec.rb +18 -0
  174. data/spec/integration/custom_field/association/custom_field_options_spec.rb +18 -0
  175. data/spec/integration/custom_field/create_spec.rb +29 -0
  176. data/spec/integration/custom_field/find_spec.rb +41 -0
  177. data/spec/integration/custom_field/update!_spec.rb +25 -0
  178. data/spec/integration/custom_field_option/create_spec.rb +23 -0
  179. data/spec/integration/custom_field_option/delete_spec.rb +19 -0
  180. data/spec/integration/custom_field_option/find_spec.rb +21 -0
  181. data/spec/integration/integration_test.rb +3 -3
  182. data/spec/integration/label/association/board_spec.rb +18 -0
  183. data/spec/integration/label/create_spec.rb +23 -0
  184. data/spec/integration/label/delete_spec.rb +21 -0
  185. data/spec/integration/label/find_spec.rb +20 -0
  186. data/spec/integration/label/update!_spec.rb +25 -0
  187. data/spec/integration/list/archive_all_cards_spec.rb +20 -0
  188. data/spec/integration/list/associations/actions_spec.rb +18 -0
  189. data/spec/integration/list/associations/board_spec.rb +18 -0
  190. data/spec/integration/list/associations/cards_spec.rb +18 -0
  191. data/spec/integration/list/create_spec.rb +44 -0
  192. data/spec/integration/list/find_spec.rb +37 -0
  193. data/spec/integration/list/move_all_cards_spec.rb +31 -0
  194. data/spec/integration/list/save_spec.rb +40 -0
  195. data/spec/integration/list/update!_spec.rb +43 -0
  196. data/spec/integration/member/associations/actions_spec.rb +17 -0
  197. data/spec/integration/member/associations/boards_spec.rb +18 -0
  198. data/spec/integration/member/associations/cards_spec.rb +18 -0
  199. data/spec/integration/member/associations/notifications_spec.rb +18 -0
  200. data/spec/integration/member/associations/organizations_spec.rb +18 -0
  201. data/spec/integration/member/find_spec.rb +39 -0
  202. data/spec/integration/member/update!_spec.rb +18 -0
  203. data/spec/integration/notification/find_spec.rb +27 -0
  204. data/spec/integration/organization/associations/actions_spec.rb +18 -0
  205. data/spec/integration/organization/associations/boards_spec.rb +18 -0
  206. data/spec/integration/organization/associations/members_spec.rb +18 -0
  207. data/spec/integration/organization/create_spec.rb +23 -0
  208. data/spec/integration/organization/find_spec.rb +37 -0
  209. data/spec/integration/organization/update!_spec.rb +28 -0
  210. data/spec/integration/token/find_spec.rb +24 -0
  211. data/spec/integration/webhook/create_spec.rb +27 -0
  212. data/spec/integration/webhook/delete_spec.rb +21 -0
  213. data/spec/integration/webhook/find_spec.rb +22 -0
  214. data/spec/integration/webhook/update!_spec.rb +24 -0
  215. data/spec/item_spec.rb +2 -2
  216. data/spec/label_spec.rb +31 -33
  217. data/spec/list_spec.rb +32 -14
  218. data/spec/notification_spec.rb +3 -3
  219. data/spec/organization_spec.rb +6 -5
  220. data/spec/spec_helper.rb +31 -14
  221. data/spec/token_spec.rb +10 -11
  222. data/spec/unit/trello/basic_data_spec.rb +67 -8
  223. data/spec/unit/trello/board/new_spec.rb +370 -0
  224. data/spec/unit/trello/board/save_spec.rb +49 -0
  225. data/spec/unit/trello/board/update_fields_spec.rb +129 -0
  226. data/spec/unit/trello/board/update_spec.rb +197 -0
  227. data/spec/unit/trello/member/new_spec.rb +62 -0
  228. data/spec/unit/trello/member/update_fields_spec.rb +80 -0
  229. data/spec/unit/trello/schema/attribute/base_spec.rb +349 -0
  230. data/spec/unit/trello/schema/attribute/board_pref_spec.rb +208 -0
  231. data/spec/unit/trello/schema/attribute/default_spec.rb +236 -0
  232. data/spec/unit/trello/schema/attribute_builder_spec.rb +55 -0
  233. data/spec/unit/trello/schema/attribute_registration_spec.rb +59 -0
  234. data/spec/unit/trello/schema/serializer/default_spec.rb +19 -0
  235. data/spec/unit/trello/schema/serializer/time_spec.rb +39 -0
  236. data/spec/unit/trello/schema_spec.rb +25 -0
  237. data/spec/webhook_spec.rb +23 -7
  238. metadata +444 -102
  239. data/lib/trello/register_attributes.rb +0 -54
  240. data/spec/integration/basic_data/register_attributes_spec.rb +0 -75
@@ -0,0 +1,45 @@
1
+ module Trello
2
+ class Schema
3
+ module Attribute
4
+ class CustomFieldDisplay < Base
5
+
6
+ def build_attributes(params, attributes)
7
+ attrs = attributes.with_indifferent_access
8
+ params = params.with_indifferent_access
9
+
10
+ value = if params.key?(:display)
11
+ params[:display][remote_key]
12
+ else
13
+ params[name]
14
+ end
15
+
16
+ attrs[name] = serializer.deserialize(value, default)
17
+ attrs
18
+ end
19
+
20
+ def build_payload_for_create(attributes, payload)
21
+ payload ||= {}
22
+ return payload unless for_action?(:create)
23
+ return payload unless attributes.key?(name)
24
+
25
+ value = attributes[name]
26
+ return payload if value.nil?
27
+
28
+ payload["display_#{remote_key}"] = serializer.serialize(value)
29
+ payload
30
+ end
31
+
32
+ def build_payload_for_update(attributes, payload)
33
+ payload ||= {}
34
+ return payload unless for_action?(:update)
35
+ return payload unless attributes.key?(name)
36
+
37
+ value = attributes[name]
38
+ payload["display/#{remote_key}"] = serializer.serialize(value)
39
+ payload
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ module Trello
2
+ class Schema
3
+ module Attribute
4
+ class Default < Base
5
+
6
+ def build_attributes(params, attributes)
7
+ attrs = attributes.with_indifferent_access
8
+ params = params.with_indifferent_access
9
+
10
+ value = if params.key?(remote_key)
11
+ params[remote_key]
12
+ else
13
+ params[name]
14
+ end
15
+
16
+ attrs[name] = serializer.deserialize(value, default)
17
+ attrs
18
+ end
19
+
20
+ def build_payload_for_create(attributes, payload)
21
+ payload ||= {}
22
+ return payload unless for_action?(:create)
23
+ return payload unless attributes.key?(name)
24
+
25
+ value = attributes[name]
26
+ return payload if value.nil?
27
+
28
+ payload[remote_key] = serializer.serialize(value)
29
+ payload
30
+ end
31
+
32
+ def build_payload_for_update(attributes, payload)
33
+ payload ||= {}
34
+ return payload unless for_action?(:update)
35
+ return payload unless attributes.key?(name)
36
+
37
+ value = attributes[name]
38
+ payload[remote_key] = serializer.serialize(value)
39
+ payload
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,42 @@
1
+ module Trello
2
+ class Schema
3
+ class AttributeBuilder
4
+ class << self
5
+ def build(name, options = {})
6
+ new(name, options).build
7
+ end
8
+ end
9
+
10
+ attr_reader :name, :options
11
+
12
+ def initialize(name, options)
13
+ @name = name
14
+ @options = options
15
+ end
16
+
17
+ def build
18
+ attribute_class.new(
19
+ name: name,
20
+ options: options,
21
+ serializer: serializer
22
+ )
23
+ end
24
+
25
+ private
26
+
27
+ def attribute_class
28
+ class_name = options.delete(:class_name)
29
+ return Schema::Attribute::Default unless class_name
30
+
31
+ "Trello::Schema::Attribute::#{class_name}".constantize
32
+ end
33
+
34
+ def serializer
35
+ serializer_class_name = options.delete(:serializer)
36
+ return Schema::Serializer::Default unless serializer_class_name
37
+
38
+ "Trello::Schema::Serializer::#{serializer_class_name}".constantize
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,47 @@
1
+ module Trello
2
+ class Schema
3
+ class AttributeRegistration
4
+ class << self
5
+ def register(klass, attribute)
6
+ new(klass, attribute).register
7
+ end
8
+ end
9
+
10
+ attr_reader :klass, :attribute
11
+
12
+ def initialize(klass, attribute)
13
+ @klass = klass
14
+ @attribute = attribute
15
+ end
16
+
17
+ def register
18
+ define_getter
19
+ define_setter
20
+ end
21
+
22
+ private
23
+
24
+ def define_getter
25
+ attribute_name = attribute.name
26
+
27
+ klass.class_eval do
28
+ define_method(attribute_name) { @__attributes[attribute_name] }
29
+ end
30
+ end
31
+
32
+ def define_setter
33
+ return if attribute.readonly?
34
+
35
+ attribute_name = attribute.name
36
+
37
+ klass.class_eval do
38
+ define_method("#{attribute_name}=") do |value|
39
+ send("#{attribute_name}_will_change!") if value != @__attributes[attribute_name]
40
+ @__attributes[attribute_name] = value
41
+ end
42
+ end
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,17 @@
1
+ module Trello
2
+ class Schema
3
+ module Serializer
4
+ class Default
5
+ class << self
6
+ def serialize(value)
7
+ value
8
+ end
9
+
10
+ def deserialize(value, default)
11
+ value == nil ? default : value
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ module Trello
2
+ class Schema
3
+ module Serializer
4
+ class Labels
5
+ class << self
6
+ def serialize(labels)
7
+ labels.map(&:id)
8
+ end
9
+
10
+ def deserialize(labels, default)
11
+ return default unless labels
12
+
13
+ labels.map do |label|
14
+ next label if label.is_a?(Trello::Label)
15
+
16
+ Trello::Label.new(label)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ module Trello
2
+ class Schema
3
+ module Serializer
4
+ class Time
5
+ class << self
6
+ def serialize(time)
7
+ return nil unless time.respond_to?(:iso8601)
8
+
9
+ time.strftime('%FT%T.%LZ')
10
+ end
11
+
12
+ def deserialize(time, default)
13
+ if time.is_a?(String)
14
+ ::Time.iso8601(time) rescue default
15
+ elsif time.respond_to?(:to_time)
16
+ time.to_time
17
+ else
18
+ default
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ module Trello
2
+ class Schema
3
+ module Serializer
4
+ class Webhooks
5
+ class << self
6
+ def serialize(webhooks)
7
+ webhooks ||= []
8
+
9
+ webhooks.map(&:id)
10
+ end
11
+
12
+ def deserialize(webhooks, default)
13
+ return default unless webhooks
14
+
15
+ webhooks.map do |webhook|
16
+ next webhook if webhook.is_a?(Trello::Webhook)
17
+
18
+ Trello::Webhook.new(webhook)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,31 @@
1
+ module Trello
2
+ class Schema
3
+ module Attribute
4
+ autoload :Base, 'trello/schema/attribute/base'
5
+ autoload :Default, 'trello/schema/attribute/default'
6
+ autoload :BoardPref, 'trello/schema/attribute/board_pref'
7
+ autoload :CustomFieldDisplay, 'trello/schema/attribute/custom_field_display'
8
+ end
9
+
10
+ module Serializer
11
+ autoload :Default, 'trello/schema/serializer/default'
12
+ autoload :Time, 'trello/schema/serializer/time'
13
+ autoload :Labels, 'trello/schema/serializer/labels'
14
+ autoload :Webhooks, 'trello/schema/serializer/webhooks'
15
+ end
16
+
17
+ autoload :AttributeBuilder, 'trello/schema/attribute_builder'
18
+ autoload :AttributeRegistration, 'trello/schema/attribute_registration'
19
+
20
+ attr_reader :attrs
21
+
22
+ def initialize
23
+ @attrs = ActiveSupport::HashWithIndifferentAccess.new
24
+ end
25
+
26
+ def attribute(name, options={})
27
+ @attrs[name] = AttributeBuilder.build(name, options)
28
+ self
29
+ end
30
+ end
31
+ end
data/lib/trello/token.rb CHANGED
@@ -2,17 +2,30 @@ module Trello
2
2
 
3
3
  # @!attribute [r] id
4
4
  # @return [String]
5
+ # @!attribute [r] identifier
6
+ # @return [String]
5
7
  # @!attribute [r] member_id
6
8
  # @return [String]
7
9
  # @!attribute [r] created_at
8
10
  # @return [Datetime]
11
+ # @!attribute [r] expires_at
12
+ # @return [Datetime]
9
13
  # @!attribute [r] permissions
10
14
  # @return [Object]
11
15
  # @!attribute [r] webhooks
12
16
  # @return [Object]
13
17
  class Token < BasicData
14
- register_attributes :id, :member_id, :created_at, :permissions, :webhooks,
15
- readonly: [ :id, :member_id, :created_at, :permissions, :webhooks ]
18
+
19
+ schema do
20
+ # Readonly
21
+ attribute :id, readonly: true, primary_key: true
22
+ attribute :identifier, readonly: true
23
+ attribute :member_id, readonly: true, remote_key: 'idMember'
24
+ attribute :created_at, readonly: true, remote_key: 'dateCreated', serializer: 'Time'
25
+ attribute :expires_at, readonly: true, remote_key: 'dateExpires', serializer: 'Time'
26
+ attribute :permissions, readonly: true
27
+ attribute :webhooks, readonly: true, default: [], serializer: 'Webhooks'
28
+ end
16
29
 
17
30
  class << self
18
31
  # Finds a token
@@ -21,16 +34,6 @@ module Trello
21
34
  end
22
35
  end
23
36
 
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
37
  # Returns a reference to the user who authorized the token.
35
38
  one :member, path: :members, using: :member_id
36
39
  end
@@ -5,86 +5,33 @@ module Trello
5
5
  # @return [String]
6
6
  # @!attribute [r] description
7
7
  # @return [String]
8
- # @!attribute [r] id_model
8
+ # @!attribute [r] model_id
9
9
  # @return [String] A 24-character hex string
10
10
  # @!attribute [r] callback_url
11
11
  # @return [String]
12
12
  # @!attribute [r] active
13
13
  # @return [Boolean]
14
+ # @!attribute [r] consecutive_failures
15
+ # @return [Integer]
16
+ # @!attribute [r] first_consecutive_fail_date
17
+ # @return [Datetime]
14
18
  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
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
20
+ schema do
21
+ # Readonly
22
+ attribute :id, readonly: true, primary_key: true
23
+ attribute :consecutive_failures, readonly: true, remote_key: 'consecutiveFailures'
24
+ attribute :first_consecutive_fail_date, readonly: true, remote_key: 'firstConsecutiveFailDate', serializer: 'Time'
25
+
26
+ # Writable
27
+ attribute :description
28
+ attribute :model_id, remote_key: 'idModel'
29
+ attribute :callback_url, remote_key: 'callbackURL'
30
+ attribute :active
57
31
  end
58
32
 
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
33
+ validates_presence_of :id, :model_id, :callback_url
34
+ validates_length_of :description, in: 1..16384
88
35
 
89
36
  # Delete this webhook
90
37
  #
data/lib/trello.rb CHANGED
@@ -1,12 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'oauth'
2
4
  require 'json'
3
5
  require 'logger'
4
6
  require 'active_model'
5
7
  require 'addressable/uri'
8
+ require 'active_support/core_ext/hash/indifferent_access'
6
9
 
7
- # Ruby wrapper around the Trello[http://trello.com] API
10
+ # Ruby wrapper around the [Trello] API
8
11
  #
9
- # First, set up your key information. You can get this information by {clicking here}[https://trello.com/1/appKey/generate].
12
+ # First, set up your key information. You can get this information by [clicking here][trello-app-key].
10
13
  #
11
14
  # You can get the key by going to this url in your browser:
12
15
  # https://trello.com/1/authorize?key=TRELLO_CONSUMER_KEY_FROM_ABOVE&name=MyApp&response_type=token&scope=read,write,account&expiration=never
@@ -35,7 +38,11 @@ require 'addressable/uri'
35
38
  #
36
39
  # And so much more. Consult the rest of the documentation for more information.
37
40
  #
38
- # Feel free to {peruse and participate in our Trello board}[https://trello.com/board/ruby-trello/4f092b2ee23cb6fe6d1aaabd]. It's completely open to the public.
41
+ # Feel free to [peruse and participate in our Trello board][ruby-trello-board]. It's completely open to the public.
42
+ #
43
+ # [trello]: http://trello.com
44
+ # [trello-app-key]: https://trello.com/app-key
45
+ # [ruby-trello-board]: https://trello.com/board/ruby-trello/4f092b2ee23cb6fe6d1aaabd
39
46
  module Trello
40
47
  autoload :Error, 'trello/error'
41
48
  autoload :Action, 'trello/action'
@@ -65,12 +72,21 @@ module Trello
65
72
  autoload :Organization, 'trello/organization'
66
73
  autoload :PluginDatum, 'trello/plugin_datum'
67
74
  autoload :Request, 'trello/net'
75
+ autoload :Response, 'trello/net'
68
76
  autoload :TInternet, 'trello/net'
69
77
  autoload :Token, 'trello/token'
70
78
  autoload :Webhook, 'trello/webhook'
71
79
  autoload :JsonUtils, 'trello/json_utils'
72
80
  autoload :AssociationInferTool, 'trello/association_infer_tool'
73
- autoload :RegisterAttributes, 'trello/register_attributes'
81
+ autoload :Schema, 'trello/schema'
82
+
83
+ module TFaraday
84
+ autoload :TInternet, 'trello/net/faraday'
85
+ end
86
+
87
+ module TRestClient
88
+ autoload :TInternet, 'trello/net/rest_client'
89
+ end
74
90
 
75
91
  module Authorization
76
92
  autoload :AuthPolicy, 'trello/authorization'
@@ -80,12 +96,12 @@ module Trello
80
96
 
81
97
  module AssociationFetcher
82
98
  autoload :HasMany, 'trello/association_fetcher/has_many'
83
- autoload :HasOne, 'trello/association_fetcher/has_one'
99
+ autoload :HasOne, 'trello/association_fetcher/has_one'
84
100
  end
85
101
 
86
102
  module AssociationBuilder
87
103
  autoload :HasMany, 'trello/association_builder/has_many'
88
- autoload :HasOne, 'trello/association_builder/has_one'
104
+ autoload :HasOne, 'trello/association_builder/has_one'
89
105
  end
90
106
 
91
107
  # Version of the Trello API that we use by default.
@@ -105,6 +121,45 @@ module Trello
105
121
  @logger = logger
106
122
  end
107
123
 
124
+ # The order in which we will try the http clients
125
+ HTTP_CLIENT_PRIORITY = %w(rest-client faraday)
126
+ HTTP_CLIENTS = {
127
+ 'faraday' => Trello::TFaraday::TInternet,
128
+ 'rest-client' => Trello::TRestClient::TInternet
129
+ }
130
+
131
+ def self.http_client
132
+ @http_client ||= begin
133
+ # No client has been set explicitly. Try to load each supported client.
134
+ # The first one that loads successfully will be used.
135
+ client = HTTP_CLIENT_PRIORITY.each do |key|
136
+ begin
137
+ require key
138
+ break HTTP_CLIENTS[key]
139
+ rescue LoadError
140
+ next
141
+ end
142
+ end
143
+
144
+ raise ConfigurationError, 'Trello requires either rest-client or faraday installed' unless client
145
+
146
+ client
147
+ end
148
+ end
149
+
150
+ def self.http_client=(http_client)
151
+ if HTTP_CLIENTS.include?(http_client)
152
+ begin
153
+ require http_client
154
+ @http_client = HTTP_CLIENTS[http_client]
155
+ rescue LoadError
156
+ raise ConfigurationError, "Trello tried to use #{http_client}, but that gem is not installed"
157
+ end
158
+ else
159
+ raise ArgumentError, "Unsupported HTTP client: #{http_client}"
160
+ end
161
+ end
162
+
108
163
  def self.client
109
164
  @client ||= Client.new
110
165
  end
@@ -116,6 +171,7 @@ module Trello
116
171
 
117
172
  def self.reset!
118
173
  @client = nil
174
+ @http_client = nil
119
175
  end
120
176
 
121
177
  def self.auth_policy; client.auth_policy; end
@@ -128,7 +184,6 @@ module Trello
128
184
 
129
185
  # Url to token for making authorized requests to the Trello API
130
186
  #
131
- # @param [String, #read] contents the contents to reverse
132
187
  # @param options [Hash] Repository information to update
133
188
  # @option options [String] :name Name of the application
134
189
  # @option options [String] :key Application key
data/spec/action_spec.rb CHANGED
@@ -131,8 +131,7 @@ module Trello
131
131
  'id' => 'id',
132
132
  'type' => 'type',
133
133
  'data' => 'data',
134
- 'idMemberCreator' => 'member_creator_id',
135
- 'member' => 'member_participant'
134
+ 'idMemberCreator' => 'creator_id'
136
135
  }
137
136
 
138
137
  action = Action.new(expected)