ruby-trello 2.2.0 → 3.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.
Files changed (314) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +63 -10
  3. data/lib/trello/action.rb +31 -23
  4. data/lib/trello/association_builder/has_many.rb +17 -0
  5. data/lib/trello/association_builder/has_one.rb +16 -0
  6. data/lib/trello/association_fetcher/has_many/fetch.rb +47 -0
  7. data/lib/trello/association_fetcher/has_many/params.rb +56 -0
  8. data/lib/trello/association_fetcher/has_many.rb +26 -0
  9. data/lib/trello/association_fetcher/has_one/fetch.rb +49 -0
  10. data/lib/trello/association_fetcher/has_one/params.rb +36 -0
  11. data/lib/trello/association_fetcher/has_one.rb +25 -0
  12. data/lib/trello/association_infer_tool.rb +13 -0
  13. data/lib/trello/association_proxy.rb +1 -1
  14. data/lib/trello/attachment.rb +40 -27
  15. data/lib/trello/basic_data.rb +103 -49
  16. data/lib/trello/board.rb +88 -102
  17. data/lib/trello/card.rb +49 -198
  18. data/lib/trello/checklist.rb +17 -71
  19. data/lib/trello/comment.rb +39 -26
  20. data/lib/trello/cover_image.rb +20 -0
  21. data/lib/trello/custom_field.rb +31 -67
  22. data/lib/trello/custom_field_item.rb +37 -39
  23. data/lib/trello/custom_field_option.rb +40 -13
  24. data/lib/trello/item.rb +27 -16
  25. data/lib/trello/item_state.rb +7 -15
  26. data/lib/trello/json_utils.rb +1 -1
  27. data/lib/trello/label.rb +15 -85
  28. data/lib/trello/label_name.rb +22 -25
  29. data/lib/trello/list.rb +31 -44
  30. data/lib/trello/member.rb +77 -32
  31. data/lib/trello/notification.rb +27 -20
  32. data/lib/trello/organization.rb +53 -25
  33. data/lib/trello/plugin_datum.rb +11 -16
  34. data/lib/trello/schema/attribute/base.rb +79 -0
  35. data/lib/trello/schema/attribute/board_pref.rb +45 -0
  36. data/lib/trello/schema/attribute/custom_field_display.rb +45 -0
  37. data/lib/trello/schema/attribute/default.rb +45 -0
  38. data/lib/trello/schema/attribute_builder.rb +42 -0
  39. data/lib/trello/schema/attribute_registration.rb +47 -0
  40. data/lib/trello/schema/serializer/default.rb +17 -0
  41. data/lib/trello/schema/serializer/labels.rb +23 -0
  42. data/lib/trello/schema/serializer/time.rb +25 -0
  43. data/lib/trello/schema/serializer/webhooks.rb +25 -0
  44. data/lib/trello/schema.rb +31 -0
  45. data/lib/trello/token.rb +15 -12
  46. data/lib/trello/webhook.rb +18 -71
  47. data/lib/trello.rb +57 -39
  48. data/spec/action_spec.rb +2 -3
  49. data/spec/board_spec.rb +43 -103
  50. data/spec/card_spec.rb +143 -66
  51. data/spec/cassettes/action_find_with_id_and_get_all_fields.yml +104 -0
  52. data/spec/cassettes/board_find_with_id_and_get_all_fields.yml +96 -0
  53. data/spec/cassettes/board_find_with_id_and_get_specific_fields.yml +96 -0
  54. data/spec/cassettes/can_add_a_file_from_url_on_a_card.yml +189 -0
  55. data/spec/cassettes/can_add_a_file_on_a_card.yml +200 -0
  56. data/spec/cassettes/can_add_a_member_to_a_board.yml +191 -0
  57. data/spec/cassettes/can_add_a_member_to_a_card.yml +190 -0
  58. data/spec/cassettes/can_add_label_on_a_card.yml +281 -0
  59. data/spec/cassettes/can_arvhice_all_cards_of_list.yml +397 -0
  60. data/spec/cassettes/can_close_bong_a_card.yml +189 -0
  61. data/spec/cassettes/can_get_actions.yml +196 -0
  62. data/spec/cassettes/can_get_actions_of_board.yml +188 -0
  63. data/spec/cassettes/can_get_actions_of_list.yml +202 -0
  64. data/spec/cassettes/can_get_actions_of_members.yml +199 -0
  65. data/spec/cassettes/can_get_actions_of_organization.yml +201 -0
  66. data/spec/cassettes/can_get_attachments.yml +187 -0
  67. data/spec/cassettes/can_get_boards_of_custom_field.yml +198 -0
  68. data/spec/cassettes/can_get_boards_of_label.yml +197 -0
  69. data/spec/cassettes/can_get_boards_of_organization.yml +207 -0
  70. data/spec/cassettes/can_get_cards_of_board.yml +193 -0
  71. data/spec/cassettes/can_get_cards_of_list.yml +201 -0
  72. data/spec/cassettes/can_get_cards_of_member.yml +204 -0
  73. data/spec/cassettes/can_get_checklists_of_board.yml +187 -0
  74. data/spec/cassettes/can_get_comments.yml +193 -0
  75. data/spec/cassettes/can_get_comments_board.yml +109 -0
  76. data/spec/cassettes/can_get_comments_card.yml +111 -0
  77. data/spec/cassettes/can_get_comments_list.yml +109 -0
  78. data/spec/cassettes/can_get_custom_field_options_of_custom_field.yml +197 -0
  79. data/spec/cassettes/can_get_custom_fields_of_board.yml +187 -0
  80. data/spec/cassettes/can_get_label_names_of_board.yml +187 -0
  81. data/spec/cassettes/can_get_labels_of_board.yml +187 -0
  82. data/spec/cassettes/can_get_lists_of_board.yml +187 -0
  83. data/spec/cassettes/can_get_members_of_board.yml +188 -0
  84. data/spec/cassettes/can_get_members_of_organization.yml +200 -0
  85. data/spec/cassettes/can_get_notifications_of_member.yml +199 -0
  86. data/spec/cassettes/can_get_organization_of_board.yml +189 -0
  87. data/spec/cassettes/can_get_organizations_of_member.yml +203 -0
  88. data/spec/cassettes/can_get_plugin_data_of_board.yml +187 -0
  89. data/spec/cassettes/can_move_a_card_to_another_board_with_specific_list.yml +373 -0
  90. data/spec/cassettes/can_move_a_card_to_another_board_without_specific_list.yml +281 -0
  91. data/spec/cassettes/can_move_a_card_to_another_list.yml +281 -0
  92. data/spec/cassettes/can_move_all_cards_to_another_list.yml +886 -0
  93. data/spec/cassettes/can_remove_a_member_from_a_card.yml +185 -0
  94. data/spec/cassettes/can_remove_an_attachment_on_a_card.yml +277 -0
  95. data/spec/cassettes/can_remove_an_upvote_on_a_card.yml +465 -0
  96. data/spec/cassettes/can_remove_label_on_a_card.yml +279 -0
  97. data/spec/cassettes/can_success_add_comment_to_a_card.yml +196 -0
  98. data/spec/cassettes/can_success_copy_checklist_to_a_card.yml +281 -0
  99. data/spec/cassettes/can_success_copy_checklist_to_a_card_without_name_pos.yml +281 -0
  100. data/spec/cassettes/can_success_create_a_board.yml +98 -0
  101. data/spec/cassettes/can_success_create_a_board_with_full_parameters.yml +97 -0
  102. data/spec/cassettes/can_success_create_a_board_without_clone_from_other.yml +98 -0
  103. data/spec/cassettes/can_success_create_a_card.yml +99 -0
  104. data/spec/cassettes/can_success_create_a_card_when_due_is_datetime.yml +98 -0
  105. data/spec/cassettes/can_success_create_a_card_when_due_is_time.yml +98 -0
  106. data/spec/cassettes/can_success_create_a_checklist.yml +102 -0
  107. data/spec/cassettes/can_success_create_a_custom_field.yml +102 -0
  108. data/spec/cassettes/can_success_create_a_custom_field_option.yml +102 -0
  109. data/spec/cassettes/can_success_create_a_label.yml +102 -0
  110. data/spec/cassettes/can_success_create_a_list.yml +102 -0
  111. data/spec/cassettes/can_success_create_a_list_with_full_parameters.yml +102 -0
  112. data/spec/cassettes/can_success_create_a_organization.yml +104 -0
  113. data/spec/cassettes/can_success_create_a_webhook.yml +102 -0
  114. data/spec/cassettes/can_success_create_new_checklist_to_a_card.yml +189 -0
  115. data/spec/cassettes/can_success_delete_a_custom_field_option.yml +389 -0
  116. data/spec/cassettes/can_success_delete_card.yml +185 -0
  117. data/spec/cassettes/can_success_delete_checklist.yml +284 -0
  118. data/spec/cassettes/can_success_get_card_of_board_by_card_id.yml +188 -0
  119. data/spec/cassettes/can_success_remove_member_from_board.yml +186 -0
  120. data/spec/cassettes/can_success_return_all_boards_of_current_user.yml +195 -0
  121. data/spec/cassettes/can_success_upate_a_board.yml +191 -0
  122. data/spec/cassettes/can_success_upate_a_card.yml +189 -0
  123. data/spec/cassettes/can_success_upate_a_list.yml +296 -0
  124. data/spec/cassettes/can_success_update_bong_a_board.yml +283 -0
  125. data/spec/cassettes/can_success_update_bong_a_board_with_specific_fields.yml +284 -0
  126. data/spec/cassettes/can_success_update_bong_a_card.yml +191 -0
  127. data/spec/cassettes/can_success_update_bong_a_checklist_with_specific_fields.yml +296 -0
  128. data/spec/cassettes/can_success_update_bong_a_custom_field.yml +200 -0
  129. data/spec/cassettes/can_success_update_bong_a_label.yml +200 -0
  130. data/spec/cassettes/can_success_update_bong_a_list.yml +199 -0
  131. data/spec/cassettes/can_success_update_bong_a_list_with_specific_fields.yml +296 -0
  132. data/spec/cassettes/can_success_update_bong_a_organization.yml +203 -0
  133. data/spec/cassettes/can_success_update_bong_a_webhook.yml +296 -0
  134. data/spec/cassettes/can_upvote_on_a_card.yml +469 -0
  135. data/spec/cassettes/card_find_with_id_and_get_all_fields.yml +95 -0
  136. data/spec/cassettes/card_find_with_id_and_get_specific_fields.yml +96 -0
  137. data/spec/cassettes/checklist_can_add_an_item.yml +296 -0
  138. data/spec/cassettes/checklist_can_update_the_item_state.yml +296 -0
  139. data/spec/cassettes/checklist_find_with_id_and_get_all_fields.yml +100 -0
  140. data/spec/cassettes/comment_delete.yml +331 -0
  141. data/spec/cassettes/comment_find_with_id.yml +116 -0
  142. data/spec/cassettes/custom_field_find_with_id_and_get_all_fields.yml +100 -0
  143. data/spec/cassettes/custom_field_find_with_id_and_get_specific_fields.yml +100 -0
  144. data/spec/cassettes/custom_field_item_save_1.yml +97 -0
  145. data/spec/cassettes/custom_field_item_save_2.yml +281 -0
  146. data/spec/cassettes/custom_field_option_find_with_id.yml +100 -0
  147. data/spec/cassettes/get_board_of_card.yml +187 -0
  148. data/spec/cassettes/get_board_of_list.yml +197 -0
  149. data/spec/cassettes/get_boards_of_member.yml +207 -0
  150. data/spec/cassettes/get_check_item_states_of_card.yml +188 -0
  151. data/spec/cassettes/get_checklists_of_card.yml +187 -0
  152. data/spec/cassettes/get_cover_image_of_card.yml +187 -0
  153. data/spec/cassettes/get_custom_field_items_of_card.yml +187 -0
  154. data/spec/cassettes/get_list_of_card.yml +188 -0
  155. data/spec/cassettes/get_lists.yml +187 -0
  156. data/spec/cassettes/get_members_of_card.yml +189 -0
  157. data/spec/cassettes/get_plugin_data_of_card.yml +187 -0
  158. data/spec/cassettes/get_voters_of_card.yml +188 -0
  159. data/spec/cassettes/label_delete.yml +285 -0
  160. data/spec/cassettes/label_find_with_id.yml +100 -0
  161. data/spec/cassettes/list_find_with_id_and_get_all_fields.yml +100 -0
  162. data/spec/cassettes/list_find_with_id_and_get_specific_fields.yml +100 -0
  163. data/spec/cassettes/member_find_with_id_and_get_all_fields.yml +101 -0
  164. data/spec/cassettes/member_find_with_id_and_get_specific_fields.yml +100 -0
  165. data/spec/cassettes/notification_find_with_id.yml +103 -0
  166. data/spec/cassettes/organization_find_with_id_and_get_all_fields.yml +102 -0
  167. data/spec/cassettes/organization_find_with_id_and_get_specific_fields.yml +100 -0
  168. data/spec/cassettes/remove_upvote_on_a_card_when_have_not_voted.yml +366 -0
  169. data/spec/cassettes/revote_on_a_card.yml +464 -0
  170. data/spec/cassettes/token_find_with_token_string.yml +100 -0
  171. data/spec/cassettes/webhook_delete.yml +286 -0
  172. data/spec/cassettes/webhook_find_with_id.yml +100 -0
  173. data/spec/checklist_spec.rb +27 -43
  174. data/spec/custom_field_item_spec.rb +74 -0
  175. data/spec/custom_field_option_spec.rb +2 -2
  176. data/spec/custom_field_spec.rb +98 -10
  177. data/spec/integration/action/find_spec.rb +23 -0
  178. data/spec/integration/basic_data/many_spec.rb +127 -0
  179. data/spec/integration/basic_data/one_spec.rb +84 -0
  180. data/spec/integration/basic_data/schema_spec.rb +156 -0
  181. data/spec/integration/board/add_member_spec.rb +21 -0
  182. data/spec/integration/board/all_spec.rb +20 -0
  183. data/spec/integration/board/associations/actions_spec.rb +18 -0
  184. data/spec/integration/board/associations/cards_spec.rb +18 -0
  185. data/spec/integration/board/associations/checklists_spec.rb +18 -0
  186. data/spec/integration/board/associations/custom_fields_spec.rb +18 -0
  187. data/spec/integration/board/associations/label_names_spec.rb +17 -0
  188. data/spec/integration/board/associations/labels_spec.rb +18 -0
  189. data/spec/integration/board/associations/lists_spec.rb +18 -0
  190. data/spec/integration/board/associations/members_spec.rb +18 -0
  191. data/spec/integration/board/associations/organization_spec.rb +19 -0
  192. data/spec/integration/board/associations/plugin_data_spec.rb +18 -0
  193. data/spec/integration/board/create_spec.rb +95 -0
  194. data/spec/integration/board/find_card_spec.rb +18 -0
  195. data/spec/integration/board/find_spec.rb +42 -0
  196. data/spec/integration/board/remove_member_spec.rb +21 -0
  197. data/spec/integration/board/save_spec.rb +37 -0
  198. data/spec/integration/board/update!_spec.rb +62 -0
  199. data/spec/integration/board_lists_spec.rb +21 -0
  200. data/spec/integration/card/add_and_remove_attachment_spec.rb +45 -0
  201. data/spec/integration/card/add_and_remove_label_spec.rb +35 -0
  202. data/spec/integration/card/add_checklist_spec.rb +32 -0
  203. data/spec/integration/card/add_comment_spec.rb +19 -0
  204. data/spec/integration/card/add_memeber_spec.rb +19 -0
  205. data/spec/integration/card/associations/actions_spec.rb +17 -0
  206. data/spec/integration/card/associations/attachments_spec.rb +18 -0
  207. data/spec/integration/card/associations/board_spec.rb +17 -0
  208. data/spec/integration/card/associations/check_item_states_spec.rb +17 -0
  209. data/spec/integration/card/associations/checklists_spec.rb +18 -0
  210. data/spec/integration/card/associations/comments_spec.rb +19 -0
  211. data/spec/integration/card/associations/cover_image_spec.rb +18 -0
  212. data/spec/integration/card/associations/custom_field_items_spec.rb +18 -0
  213. data/spec/integration/card/associations/list_spec.rb +16 -0
  214. data/spec/integration/card/associations/members_spec.rb +18 -0
  215. data/spec/integration/card/associations/plugin_data_spec.rb +18 -0
  216. data/spec/integration/card/associations/voters_spec.rb +17 -0
  217. data/spec/integration/card/close!_spec.rb +16 -0
  218. data/spec/integration/card/create_new_check_list_spec.rb +19 -0
  219. data/spec/integration/card/create_spec.rb +84 -0
  220. data/spec/integration/card/delete_spec.rb +16 -0
  221. data/spec/integration/card/find_spec.rb +67 -0
  222. data/spec/integration/card/move_to_board_spec.rb +36 -0
  223. data/spec/integration/card/move_to_list_spec.rb +20 -0
  224. data/spec/integration/card/remove_member_spec.rb +19 -0
  225. data/spec/integration/card/save_spec.rb +61 -0
  226. data/spec/integration/card/update!_spec.rb +53 -0
  227. data/spec/integration/card/vote_spec.rb +50 -0
  228. data/spec/integration/checklist/add_item_spec.rb +20 -0
  229. data/spec/integration/checklist/create_spec.rb +23 -0
  230. data/spec/integration/checklist/delete_spec.rb +17 -0
  231. data/spec/integration/checklist/find_spec.rb +22 -0
  232. data/spec/integration/checklist/update!_spec.rb +21 -0
  233. data/spec/integration/checklist/update_item_state_spec.rb +20 -0
  234. data/spec/integration/comment/association/board_spec.rb +17 -0
  235. data/spec/integration/comment/association/card_spec.rb +17 -0
  236. data/spec/integration/comment/association/list_spec.rb +17 -0
  237. data/spec/integration/comment/delete_spec.rb +20 -0
  238. data/spec/integration/comment/find_spec.rb +17 -0
  239. data/spec/integration/custom_field/association/board_spec.rb +18 -0
  240. data/spec/integration/custom_field/association/custom_field_options_spec.rb +18 -0
  241. data/spec/integration/custom_field/create_spec.rb +29 -0
  242. data/spec/integration/custom_field/find_spec.rb +41 -0
  243. data/spec/integration/custom_field/update!_spec.rb +25 -0
  244. data/spec/integration/custom_field_item_spec.rb +47 -0
  245. data/spec/integration/custom_field_option/create_spec.rb +23 -0
  246. data/spec/integration/custom_field_option/delete_spec.rb +19 -0
  247. data/spec/integration/custom_field_option/find_spec.rb +21 -0
  248. data/spec/integration/label/association/board_spec.rb +18 -0
  249. data/spec/integration/label/create_spec.rb +23 -0
  250. data/spec/integration/label/delete_spec.rb +21 -0
  251. data/spec/integration/label/find_spec.rb +20 -0
  252. data/spec/integration/label/update!_spec.rb +25 -0
  253. data/spec/integration/list/archive_all_cards_spec.rb +20 -0
  254. data/spec/integration/list/associations/actions_spec.rb +18 -0
  255. data/spec/integration/list/associations/board_spec.rb +18 -0
  256. data/spec/integration/list/associations/cards_spec.rb +18 -0
  257. data/spec/integration/list/create_spec.rb +44 -0
  258. data/spec/integration/list/find_spec.rb +37 -0
  259. data/spec/integration/list/move_all_cards_spec.rb +31 -0
  260. data/spec/integration/list/save_spec.rb +40 -0
  261. data/spec/integration/list/update!_spec.rb +43 -0
  262. data/spec/integration/member/associations/actions_spec.rb +17 -0
  263. data/spec/integration/member/associations/boards_spec.rb +18 -0
  264. data/spec/integration/member/associations/cards_spec.rb +18 -0
  265. data/spec/integration/member/associations/notifications_spec.rb +18 -0
  266. data/spec/integration/member/associations/organizations_spec.rb +18 -0
  267. data/spec/integration/member/find_spec.rb +39 -0
  268. data/spec/integration/member/update!_spec.rb +18 -0
  269. data/spec/integration/notification/find_spec.rb +27 -0
  270. data/spec/integration/organization/associations/actions_spec.rb +18 -0
  271. data/spec/integration/organization/associations/boards_spec.rb +18 -0
  272. data/spec/integration/organization/associations/members_spec.rb +18 -0
  273. data/spec/integration/organization/create_spec.rb +23 -0
  274. data/spec/integration/organization/find_spec.rb +37 -0
  275. data/spec/integration/organization/update!_spec.rb +28 -0
  276. data/spec/integration/token/find_spec.rb +24 -0
  277. data/spec/integration/webhook/create_spec.rb +27 -0
  278. data/spec/integration/webhook/delete_spec.rb +21 -0
  279. data/spec/integration/webhook/find_spec.rb +22 -0
  280. data/spec/integration/webhook/update!_spec.rb +24 -0
  281. data/spec/item_spec.rb +2 -2
  282. data/spec/label_spec.rb +105 -28
  283. data/spec/list_spec.rb +32 -14
  284. data/spec/notification_spec.rb +3 -3
  285. data/spec/organization_spec.rb +6 -5
  286. data/spec/spec_helper.rb +70 -37
  287. data/spec/token_spec.rb +10 -11
  288. data/spec/unit/trello/association_builder/has_many_spec.rb +36 -0
  289. data/spec/unit/trello/association_builder/has_one_spec.rb +36 -0
  290. data/spec/unit/trello/association_fetcher/has_many/fetch_spec.rb +38 -0
  291. data/spec/unit/trello/association_fetcher/has_many/params_spec.rb +107 -0
  292. data/spec/unit/trello/association_fetcher/has_many_spec.rb +50 -0
  293. data/spec/unit/trello/association_fetcher/has_one/fetch_spec.rb +51 -0
  294. data/spec/unit/trello/association_fetcher/has_one/params_spec.rb +81 -0
  295. data/spec/unit/trello/association_fetcher/has_one_spec.rb +49 -0
  296. data/spec/unit/trello/association_infer_tool_spec.rb +41 -0
  297. data/spec/unit/trello/basic_data_spec.rb +113 -0
  298. data/spec/unit/trello/board/new_spec.rb +370 -0
  299. data/spec/unit/trello/board/save_spec.rb +49 -0
  300. data/spec/unit/trello/board/update_fields_spec.rb +129 -0
  301. data/spec/unit/trello/board/update_spec.rb +197 -0
  302. data/spec/unit/trello/card_spec.rb +103 -0
  303. data/spec/unit/trello/member/new_spec.rb +62 -0
  304. data/spec/unit/trello/member/update_fields_spec.rb +80 -0
  305. data/spec/unit/trello/schema/attribute/base_spec.rb +349 -0
  306. data/spec/unit/trello/schema/attribute/board_pref_spec.rb +208 -0
  307. data/spec/unit/trello/schema/attribute/default_spec.rb +236 -0
  308. data/spec/unit/trello/schema/attribute_builder_spec.rb +55 -0
  309. data/spec/unit/trello/schema/attribute_registration_spec.rb +59 -0
  310. data/spec/unit/trello/schema/serializer/default_spec.rb +19 -0
  311. data/spec/unit/trello/schema/serializer/time_spec.rb +39 -0
  312. data/spec/unit/trello/schema_spec.rb +25 -0
  313. data/spec/webhook_spec.rb +23 -7
  314. metadata +556 -33
@@ -0,0 +1,236 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Trello::Schema::Attribute::Default' do
4
+
5
+ let(:attribute) { Trello::Schema::Attribute::Default.new(name: name, options: options, serializer: serializer) }
6
+
7
+ describe '#build_attributes' do
8
+ let(:name) { :date_create_utc }
9
+ let(:options) { { remote_key: 'dateCreateUTC' } }
10
+ let(:serializer) { double('serializer') }
11
+ let(:default) { nil }
12
+
13
+ before do
14
+ allow(serializer)
15
+ .to receive(:deserialize)
16
+ .with(raw_value, default)
17
+ .and_return(deserialize_result)
18
+ end
19
+
20
+ let(:build_attributes) { attribute.build_attributes(params, attributes) }
21
+ let(:attributes) { { name: 'John' } }
22
+
23
+ context 'when target key in params is string' do
24
+ let(:raw_value) { '2020-02-20 00:00:00' }
25
+ let(:deserialize_result) { Time.new(2020, 2, 20) }
26
+ let(:params) { { 'date_create_utc' => raw_value } }
27
+
28
+ it 'get and deserialize that value and set to attributes' do
29
+ expect(build_attributes).to match_hash_with_indifferent_access(
30
+ { name: 'John', date_create_utc: Time.new(2020, 2, 20) }
31
+ )
32
+ end
33
+ end
34
+
35
+ context 'when target key in params is symbol' do
36
+ let(:raw_value) { '2020-02-20 00:00:00' }
37
+ let(:deserialize_result) { Time.new(2020, 2, 20) }
38
+ let(:params) { { date_create_utc: raw_value } }
39
+
40
+ it 'get and deserialize that value and set to attributes' do
41
+ expect(build_attributes).to match_hash_with_indifferent_access(
42
+ { name: 'John', date_create_utc: Time.new(2020, 2, 20) }
43
+ )
44
+ end
45
+ end
46
+
47
+ context 'when value under remote_key is nil' do
48
+ let(:raw_value) { nil }
49
+ let(:deserialize_result) { nil }
50
+ let(:params) { { 'dateCreateUTC': raw_value } }
51
+
52
+ it 'get and deserialize that value and set to attributes' do
53
+ expect(build_attributes).to match_hash_with_indifferent_access(
54
+ { name: 'John', date_create_utc: nil }
55
+ )
56
+ end
57
+ end
58
+
59
+ context 'when value under name key is nil' do
60
+ let(:raw_value) { nil }
61
+ let(:deserialize_result) { nil }
62
+ let(:params) { { date_create_utc: raw_value } }
63
+
64
+ it 'get and deserialize that value and set to attributes' do
65
+ expect(build_attributes).to match_hash_with_indifferent_access(
66
+ { name: 'John', date_create_utc: nil }
67
+ )
68
+ end
69
+ end
70
+
71
+ context 'when value under remote_key is false' do
72
+ let(:raw_value) { false }
73
+ let(:deserialize_result) { false }
74
+ let(:params) { { 'dateCreateUTC': raw_value } }
75
+
76
+ it 'get and deserialize that value and set to attributes' do
77
+ expect(build_attributes).to match_hash_with_indifferent_access(
78
+ { name: 'John', date_create_utc: false }
79
+ )
80
+ end
81
+ end
82
+ end
83
+
84
+
85
+ describe '#build_pending_update_attributes' do
86
+ let(:name) { :date_create_utc }
87
+ let(:options) { { remote_key: 'dateCreateUTC' } }
88
+ let(:serializer) { double('serializer') }
89
+ let(:default) { nil }
90
+
91
+ before do
92
+ allow(serializer)
93
+ .to receive(:deserialize)
94
+ .with(raw_value, default)
95
+ .and_return(deserialize_result)
96
+ end
97
+
98
+ let(:build_pending_update_attributes) { attribute.build_pending_update_attributes(params, attributes) }
99
+ let(:attributes) { { name: 'John' } }
100
+
101
+ context 'when remote_key and target key is missing' do
102
+ let(:raw_value) { false }
103
+ let(:deserialize_result) { false }
104
+ let(:params) { {} }
105
+
106
+ it "won't set any value to pending update attributes" do
107
+ expect(build_pending_update_attributes).to match_hash_with_indifferent_access({ name: 'John' })
108
+ end
109
+ end
110
+
111
+ context 'when remote_key exists' do
112
+ let(:raw_value) { false }
113
+ let(:deserialize_result) { false }
114
+ let(:params) { { 'dateCreateUTC': raw_value } }
115
+
116
+ it 'will set the value to pending update attributes' do
117
+ expect(build_pending_update_attributes).to match_hash_with_indifferent_access(
118
+ { name: 'John', date_create_utc: raw_value }
119
+ )
120
+ end
121
+ end
122
+
123
+ context 'when target key exists' do
124
+ let(:raw_value) { false }
125
+ let(:deserialize_result) { false }
126
+ let(:params) { { date_create_utc: raw_value } }
127
+
128
+ it 'will set the value to pending update attributes' do
129
+ expect(build_pending_update_attributes).to match_hash_with_indifferent_access(
130
+ { name: 'John', date_create_utc: raw_value }
131
+ )
132
+ end
133
+ end
134
+ end
135
+
136
+
137
+ describe '#build_payload_for_create' do
138
+ let(:name) { :date_create_utc }
139
+ let(:serializer) { double('serializer') }
140
+ let(:default) { nil }
141
+
142
+ before do
143
+ allow(serializer)
144
+ .to receive(:serialize)
145
+ .with(Time.new(2020, 2, 20))
146
+ .and_return('2020-02-20 00:00:00')
147
+ end
148
+
149
+ let(:build_attributes) { attribute.build_payload_for_create(attributes, payload) }
150
+ let(:payload) { { 'name' => 'John' } }
151
+
152
+
153
+ context 'when attribute is for action create' do
154
+ let(:options) { {} }
155
+
156
+ context 'when attribute value is nil' do
157
+ let(:attributes) { { date_create_utc: nil } }
158
+
159
+ it "won't put it in payload" do
160
+ expect(build_attributes).to eq({ 'name' => 'John' })
161
+ end
162
+ end
163
+
164
+ context 'when attributes does not contain the attribute key' do
165
+ let(:attributes) { {} }
166
+
167
+ it "won't put it in payload" do
168
+ expect(build_attributes).to eq({ 'name' => 'John' })
169
+ end
170
+ end
171
+
172
+ context 'when attribute value is normal' do
173
+ let(:attributes) { { date_create_utc: Time.new(2020, 2, 20) } }
174
+
175
+ it 'get and serialize that value and set to payload with stringify name' do
176
+ expect(build_attributes).to eq({ 'name' => 'John', 'date_create_utc' => '2020-02-20 00:00:00' })
177
+ end
178
+ end
179
+ end
180
+
181
+ context 'when attribute is not for action create' do
182
+ let(:options) { { update_only: true } }
183
+ let(:attributes) { { date_create_utc: Time.new(2020, 2, 20) } }
184
+
185
+ it "won't put it in payload" do
186
+ expect(build_attributes).to eq({ 'name' => 'John' })
187
+ end
188
+ end
189
+ end
190
+
191
+ describe '#build_payload_for_update' do
192
+ let(:name) { :date_create_utc }
193
+ let(:serializer) { double('serializer') }
194
+ let(:default) { nil }
195
+
196
+ before do
197
+ allow(serializer)
198
+ .to receive(:serialize)
199
+ .with(Time.new(2020, 2, 20))
200
+ .and_return('2020-02-20 00:00:00')
201
+ end
202
+
203
+ let(:build_attributes) { attribute.build_payload_for_update(attributes, payload) }
204
+ let(:payload) { { 'name' => 'John' } }
205
+
206
+ context 'when attribute is for action create' do
207
+ let(:options) { {} }
208
+
209
+ context 'when attributes does not contain the attribute key' do
210
+ let(:attributes) { {} }
211
+
212
+ it "won't put it in payload" do
213
+ expect(build_attributes).to eq({ 'name' => 'John' })
214
+ end
215
+ end
216
+
217
+ context 'when attribute value is normal' do
218
+ let(:attributes) { { date_create_utc: Time.new(2020, 2, 20) } }
219
+
220
+ it 'get and serialize that value and set to payload with stringify name' do
221
+ expect(build_attributes).to eq({ 'name' => 'John', 'date_create_utc' => '2020-02-20 00:00:00' })
222
+ end
223
+ end
224
+ end
225
+
226
+ context 'when attribute is not for action create' do
227
+ let(:options) { { create_only: true } }
228
+ let(:attributes) { { date_create_utc: Time.new(2020, 2, 20) } }
229
+
230
+ it "won't put it in payload" do
231
+ expect(build_attributes).to eq({ 'name' => 'John' })
232
+ end
233
+ end
234
+ end
235
+
236
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Trello::Schema::AttributeBuilder do
4
+
5
+ describe '.build' do
6
+ context 'when does not pass class_name and serializer' do
7
+ let(:build_attribute) { Trello::Schema::AttributeBuilder.build(:name, { readonly: true }) }
8
+ let(:attribute) { double('attribute') }
9
+
10
+ it 'use Schema::Attribute::Default to initialize with Schema::Serializer::Default' do
11
+ expect(Schema::Attribute::Default)
12
+ .to receive(:new)
13
+ .with(name: :name, options: { readonly: true }, serializer: Schema::Serializer::Default)
14
+ .and_return(attribute)
15
+
16
+ expect(build_attribute).to eq(attribute)
17
+ end
18
+ end
19
+
20
+ context 'when does pass class_name and serializer' do
21
+ let(:build_attribute) { Trello::Schema::AttributeBuilder.build(:name, { readonly: true, class_name: 'CustomAttribute', serializer: 'CustomSerializer' }) }
22
+ let(:attribute) { double('attribute') }
23
+
24
+ around do |example|
25
+ module Trello
26
+ class Schema
27
+ module Attribute
28
+ class CustomAttribute
29
+ end
30
+ end
31
+ module Serializer
32
+ class CustomSerializer
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ example.run
39
+
40
+ Trello::Schema::Attribute.send(:remove_const, 'CustomAttribute')
41
+ Trello::Schema::Serializer.send(:remove_const, 'CustomSerializer')
42
+ end
43
+
44
+ it 'use passin class to initializer with passin serializer' do
45
+ expect(Schema::Attribute::CustomAttribute)
46
+ .to receive(:new)
47
+ .with(name: :name, options: { readonly: true }, serializer: Schema::Serializer::CustomSerializer)
48
+ .and_return(attribute)
49
+
50
+ expect(build_attribute).to eq(attribute)
51
+ end
52
+ end
53
+ end
54
+
55
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Trello::Schema::AttributeRegistration do
4
+
5
+ around do |example|
6
+ module Trello
7
+ class FakeBoard < BasicData
8
+ def initialize; end
9
+ end
10
+ end
11
+
12
+ example.run
13
+
14
+ Trello.send(:remove_const, 'FakeBoard')
15
+ end
16
+
17
+ let(:attribute) { Trello::Schema::Attribute::Base.new(
18
+ name: name,
19
+ options: options,
20
+ serializer: serializer
21
+ ) }
22
+
23
+ context 'when it is a writable attribute' do
24
+ let(:name) { :name }
25
+ let(:serializer) { double('serializer') }
26
+ let(:options) { nil }
27
+
28
+ it 'create getter method for the attribute' do
29
+ Trello::Schema::AttributeRegistration.register(Trello::FakeBoard, attribute)
30
+
31
+ expect(Trello::FakeBoard.new).to respond_to(:name)
32
+ end
33
+
34
+ it 'create setter method for the attribute' do
35
+ Trello::Schema::AttributeRegistration.register(Trello::FakeBoard, attribute)
36
+
37
+ expect(Trello::FakeBoard.new).to respond_to(:name=)
38
+ end
39
+ end
40
+
41
+ context 'when it is a readonly attribute' do
42
+ let(:name) { :name }
43
+ let(:serializer) { double('serializer') }
44
+ let(:options) { { readonly: true } }
45
+
46
+ it 'create getter method for the attribute' do
47
+ Trello::Schema::AttributeRegistration.register(Trello::FakeBoard, attribute)
48
+
49
+ expect(Trello::FakeBoard.new).to respond_to(:name)
50
+ end
51
+
52
+ it "won't create setter method for the attribute" do
53
+ Trello::Schema::AttributeRegistration.register(Trello::FakeBoard, attribute)
54
+
55
+ expect(Trello::FakeBoard.new).not_to respond_to(:name=)
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Trello::Schema::Serializer::Default' do
4
+
5
+ describe '.serialize' do
6
+ it 'directly return the value' do
7
+ expect(Trello::Schema::Serializer::Default.serialize('John')).to eq('John')
8
+ end
9
+ end
10
+
11
+ describe '.deserialize' do
12
+ it 'directly return the value' do
13
+ expect(Trello::Schema::Serializer::Default.deserialize('John', nil)).to eq('John')
14
+ expect(Trello::Schema::Serializer::Default.deserialize(nil, 'John')).to eq('John')
15
+ expect(Trello::Schema::Serializer::Default.deserialize(false, 'John')).to eq(false)
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Trello::Schema::Serializer::Time' do
4
+
5
+ describe '.serialize' do
6
+ it 'parse the time to string with format like: 2020-01-01T00:00:00.000Z' do
7
+ expect(Trello::Schema::Serializer::Time.serialize(Time.new(2020, 4, 13, 23, 12, 59))).to eq('2020-04-13T23:12:59.000Z')
8
+ end
9
+ end
10
+
11
+ describe '.deserialize' do
12
+ context 'when pass in time string' do
13
+ it 'parset it to a time' do
14
+ expect(Trello::Schema::Serializer::Time.deserialize('2020-04-13T23:12:59.000Z', nil)).to eq(Time.new(2020, 4, 13, 23, 12, 59))
15
+ end
16
+ end
17
+
18
+ context 'when pass in a time' do
19
+ it 'return the time' do
20
+ expect(Trello::Schema::Serializer::Time.deserialize(Time.new(2020, 4, 13, 23, 12, 59), nil)).to eq(Time.new(2020, 4, 13, 23, 12, 59))
21
+ end
22
+ end
23
+
24
+ context 'when pass in a object respond to :to_time. i.e. Date, DateTime ...' do
25
+ it 'convert it to time' do
26
+ expect(Trello::Schema::Serializer::Time.deserialize(Date.new(2020, 4, 13), nil)).to eq(Time.new(2020, 4, 13))
27
+ end
28
+ end
29
+
30
+ context 'when pass in a invalid value' do
31
+ it 'return the default value' do
32
+ expect(Trello::Schema::Serializer::Time.deserialize('abc', nil)).to eq(nil)
33
+ expect(Trello::Schema::Serializer::Time.deserialize('abc', Time.new(2020, 1, 1))).to eq(Time.new(2020, 1, 1))
34
+ expect(Trello::Schema::Serializer::Time.deserialize(nil, Time.new(2020, 1, 1))).to eq(Time.new(2020, 1, 1))
35
+ end
36
+ end
37
+ end
38
+
39
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Trello::Schema do
4
+
5
+ describe '#attribute' do
6
+ let(:schema) { Trello::Schema.new }
7
+
8
+ it 'record attribute to attrs' do
9
+ attribute_1 = double('Trello::Schema::Attribute::Default')
10
+ attribute_2 = double('Trello::Schema::Attribute::Default')
11
+
12
+ expect(Trello::Schema::AttributeBuilder).to receive(:build).with(:id, readonly: true).and_return(attribute_1)
13
+ expect(Trello::Schema::AttributeBuilder).to receive(:build).with(:name, {}).and_return(attribute_2)
14
+
15
+ schema.attribute(:id, readonly: true)
16
+ schema.attribute(:name)
17
+
18
+ expect(schema.attrs).to be_a(Hash)
19
+ expect(schema.attrs.count).to eq(2)
20
+ expect(schema.attrs[:id]).to eq(attribute_1)
21
+ expect(schema.attrs[:name]).to eq(attribute_2)
22
+ end
23
+ end
24
+
25
+ end
data/spec/webhook_spec.rb CHANGED
@@ -20,7 +20,7 @@ module Trello
20
20
  it "delegates to Trello.client#find" do
21
21
  expect(client)
22
22
  .to receive(:find)
23
- .with(:webhook, '1234', {})
23
+ .with('webhook', '1234', {})
24
24
 
25
25
  Webhook.find('1234')
26
26
  end
@@ -43,7 +43,7 @@ module Trello
43
43
  webhook = Webhook.new(webhook_details)
44
44
  expect(webhook.id).to eq webhook_details['id']
45
45
  expect(webhook.description).to eq webhook_details['description']
46
- expect(webhook.id_model).to eq webhook_details['idModel']
46
+ expect(webhook.model_id).to eq webhook_details['idModel']
47
47
  expect(webhook.callback_url).to eq webhook_details['callbackURL']
48
48
  expect(webhook.active).to eq webhook_details['active']
49
49
  end
@@ -52,7 +52,7 @@ module Trello
52
52
  webhook_details = webhooks_details[1]
53
53
  webhook = Webhook.new(webhook_details)
54
54
  expect(webhook.description).to eq webhook_details[:description]
55
- expect(webhook.id_model).to eq webhook_details[:id_model]
55
+ expect(webhook.model_id).to eq webhook_details[:model_id]
56
56
  expect(webhook.callback_url).to eq webhook_details[:callback_url]
57
57
  end
58
58
 
@@ -62,14 +62,21 @@ module Trello
62
62
  webhook = webhooks_details.first
63
63
  result = JSON.generate(webhook)
64
64
 
65
- expected_payload = {description: webhook[:description], idModel: webhook[:idModel], callbackURL: webhook[:callbackURL]}
65
+ expected_payload = {
66
+ 'description' => webhook['description'],
67
+ 'idModel' => webhook['idModel'],
68
+ 'callbackURL' => webhook['callbackURL'],
69
+ 'active' => webhook['active']
70
+ }
66
71
 
67
72
  expect(client)
68
73
  .to receive(:post)
69
74
  .with("/webhooks", expected_payload)
70
75
  .and_return result
71
76
 
72
- webhook = Webhook.create(webhooks_details.first)
77
+ params = webhooks_details.first
78
+ params.delete('id')
79
+ webhook = Webhook.create(params)
73
80
 
74
81
  expect(webhook.class).to be Webhook
75
82
  end
@@ -79,12 +86,21 @@ module Trello
79
86
  it "updating description does a put on the correct resource with the correct value" do
80
87
  expected_new_description = "xxx"
81
88
 
82
- expected_payload = {description: expected_new_description, idModel: webhook.id_model, callbackURL: webhook.callback_url, active: webhook.active}
89
+ expected_payload = { 'description' => expected_new_description}
83
90
 
84
91
  expect(client)
85
92
  .to receive(:put)
86
93
  .once
87
94
  .with("/webhooks/#{webhook.id}", expected_payload)
95
+ .and_return({
96
+ 'id' => webhook.id,
97
+ 'idModel' => webhook.model_id,
98
+ 'description' => 'xxx',
99
+ 'callbackURL' => webhook.callback_url,
100
+ 'active' => webhook.active,
101
+ 'consecutiveFailures' => webhook.consecutive_failures,
102
+ 'firstConsecutiveFailDate' => webhook.first_consecutive_fail_date
103
+ }.to_json)
88
104
 
89
105
  webhook.description = expected_new_description
90
106
  webhook.save
@@ -112,7 +128,7 @@ module Trello
112
128
  expected = {
113
129
  'id' => 'id',
114
130
  'description' => 'description',
115
- 'idModel' => 'id_model',
131
+ 'idModel' => 'model_id',
116
132
  'callbackURL' => 'callback_url',
117
133
  'active' => 'active'
118
134
  }