fortnox-api 0.9.2 → 1.0.0.rc2

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 (344) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +120 -95
  3. data/{LICENSE.txt → LICENSE.md} +0 -0
  4. data/README.md +245 -248
  5. data/bin/fortnox-setup +211 -0
  6. data/bin/fortnox-update-env +38 -0
  7. data/fortnox.gemspec +29 -0
  8. data/lib/fortnox/auth/thread_local.rb +28 -0
  9. data/lib/fortnox/collection.rb +23 -0
  10. data/lib/fortnox/mappers/country_code.rb +34 -0
  11. data/lib/fortnox/mappers/date.rb +21 -0
  12. data/lib/fortnox/mappers/document_row.rb +12 -0
  13. data/lib/fortnox/mappers/edi_information.rb +15 -0
  14. data/lib/fortnox/mappers/email_information.rb +11 -0
  15. data/lib/fortnox/mappers/invoice_row.rb +14 -0
  16. data/lib/fortnox/mappers/label_references.rb +24 -0
  17. data/lib/fortnox/mappers/order_row.rb +9 -0
  18. data/lib/fortnox/mappers/struct.rb +71 -0
  19. data/lib/fortnox/mappers/struct_array.rb +31 -0
  20. data/lib/fortnox/resource.rb +131 -0
  21. data/lib/fortnox/resources/article.rb +160 -0
  22. data/lib/fortnox/resources/customer.rb +209 -0
  23. data/lib/fortnox/resources/document.rb +202 -0
  24. data/lib/fortnox/resources/invoice.rb +92 -0
  25. data/lib/fortnox/resources/label.rb +15 -0
  26. data/lib/fortnox/resources/order.rb +38 -0
  27. data/lib/fortnox/resources/project.rb +41 -0
  28. data/lib/fortnox/resources/terms_of_payment.rb +23 -0
  29. data/lib/fortnox/resources/unit.rb +26 -0
  30. data/lib/fortnox/struct.rb +24 -0
  31. data/lib/fortnox/structs/default_delivery_types.rb +16 -0
  32. data/lib/fortnox/structs/default_templates.rb +19 -0
  33. data/lib/fortnox/structs/document_row.rb +62 -0
  34. data/lib/fortnox/structs/edi_information.rb +25 -0
  35. data/lib/fortnox/structs/email_information.rb +22 -0
  36. data/lib/fortnox/structs/invoice_row.rb +13 -0
  37. data/lib/fortnox/structs/order_row.rb +10 -0
  38. data/lib/fortnox/types.rb +129 -0
  39. data/lib/fortnox/{api/version.rb → version.rb} +1 -3
  40. data/lib/fortnox.rb +111 -0
  41. metadata +55 -580
  42. data/.codeclimate.yml +0 -20
  43. data/.env.template +0 -7
  44. data/.env.test +0 -11
  45. data/.gitignore +0 -20
  46. data/.rspec +0 -2
  47. data/.rubocop.yml +0 -41
  48. data/.tool-versions +0 -1
  49. data/.travis.yml +0 -32
  50. data/CLAUDE.md +0 -79
  51. data/CONTRIBUTE.md +0 -38
  52. data/DEVELOPER_README.md +0 -69
  53. data/Gemfile +0 -6
  54. data/Guardfile +0 -16
  55. data/Rakefile +0 -140
  56. data/bin/console +0 -22
  57. data/bin/fortnox +0 -285
  58. data/bin/get_tokens +0 -79
  59. data/bin/renew_tokens +0 -28
  60. data/docs/gotchas.md +0 -146
  61. data/fortnox-api.gemspec +0 -50
  62. data/lib/fortnox/api/mappers/article.rb +0 -23
  63. data/lib/fortnox/api/mappers/base/canonical_name_sym.rb +0 -21
  64. data/lib/fortnox/api/mappers/base/from_json.rb +0 -91
  65. data/lib/fortnox/api/mappers/base/to_json.rb +0 -66
  66. data/lib/fortnox/api/mappers/base.rb +0 -30
  67. data/lib/fortnox/api/mappers/customer.rb +0 -27
  68. data/lib/fortnox/api/mappers/default_delivery_types.rb +0 -15
  69. data/lib/fortnox/api/mappers/default_templates.rb +0 -16
  70. data/lib/fortnox/api/mappers/edi_information.rb +0 -23
  71. data/lib/fortnox/api/mappers/email_information.rb +0 -19
  72. data/lib/fortnox/api/mappers/invoice.rb +0 -29
  73. data/lib/fortnox/api/mappers/invoice_row.rb +0 -25
  74. data/lib/fortnox/api/mappers/order.rb +0 -26
  75. data/lib/fortnox/api/mappers/order_row.rb +0 -23
  76. data/lib/fortnox/api/mappers/project.rb +0 -17
  77. data/lib/fortnox/api/mappers/terms_of_payment.rb +0 -17
  78. data/lib/fortnox/api/mappers/unit.rb +0 -17
  79. data/lib/fortnox/api/mappers/value/array.rb +0 -18
  80. data/lib/fortnox/api/mappers/value/country_string.rb +0 -24
  81. data/lib/fortnox/api/mappers/value/date.rb +0 -11
  82. data/lib/fortnox/api/mappers/value/hash.rb +0 -16
  83. data/lib/fortnox/api/mappers/value/identity.rb +0 -18
  84. data/lib/fortnox/api/mappers.rb +0 -21
  85. data/lib/fortnox/api/models/article.rb +0 -134
  86. data/lib/fortnox/api/models/base.rb +0 -128
  87. data/lib/fortnox/api/models/customer.rb +0 -210
  88. data/lib/fortnox/api/models/document.rb +0 -189
  89. data/lib/fortnox/api/models/invoice.rb +0 -87
  90. data/lib/fortnox/api/models/label.rb +0 -19
  91. data/lib/fortnox/api/models/order.rb +0 -27
  92. data/lib/fortnox/api/models/project.rb +0 -42
  93. data/lib/fortnox/api/models/terms_of_payment.rb +0 -28
  94. data/lib/fortnox/api/models/unit.rb +0 -24
  95. data/lib/fortnox/api/models.rb +0 -9
  96. data/lib/fortnox/api/repositories/article.rb +0 -17
  97. data/lib/fortnox/api/repositories/authentication.rb +0 -61
  98. data/lib/fortnox/api/repositories/base/loaders.rb +0 -64
  99. data/lib/fortnox/api/repositories/base/savers.rb +0 -57
  100. data/lib/fortnox/api/repositories/base.rb +0 -93
  101. data/lib/fortnox/api/repositories/customer.rb +0 -17
  102. data/lib/fortnox/api/repositories/invoice.rb +0 -17
  103. data/lib/fortnox/api/repositories/order.rb +0 -17
  104. data/lib/fortnox/api/repositories/project.rb +0 -17
  105. data/lib/fortnox/api/repositories/terms_of_payment.rb +0 -17
  106. data/lib/fortnox/api/repositories/unit.rb +0 -17
  107. data/lib/fortnox/api/repositories.rb +0 -10
  108. data/lib/fortnox/api/request_handling.rb +0 -46
  109. data/lib/fortnox/api/types/default_delivery_types.rb +0 -20
  110. data/lib/fortnox/api/types/default_templates.rb +0 -23
  111. data/lib/fortnox/api/types/defaulted.rb +0 -11
  112. data/lib/fortnox/api/types/document_row.rb +0 -64
  113. data/lib/fortnox/api/types/edi_information.rb +0 -29
  114. data/lib/fortnox/api/types/email_information.rb +0 -26
  115. data/lib/fortnox/api/types/enums.rb +0 -116
  116. data/lib/fortnox/api/types/invoice_row.rb +0 -19
  117. data/lib/fortnox/api/types/model.rb +0 -37
  118. data/lib/fortnox/api/types/nullable.rb +0 -25
  119. data/lib/fortnox/api/types/order_row.rb +0 -16
  120. data/lib/fortnox/api/types/required.rb +0 -13
  121. data/lib/fortnox/api/types/shim/country_string.rb +0 -10
  122. data/lib/fortnox/api/types/sized.rb +0 -33
  123. data/lib/fortnox/api/types.rb +0 -144
  124. data/lib/fortnox/api.rb +0 -62
  125. data/spec/fortnox/api/mappers/article_spec.rb +0 -17
  126. data/spec/fortnox/api/mappers/base/canonical_name_sym_spec.rb +0 -36
  127. data/spec/fortnox/api/mappers/base/from_json_spec.rb +0 -70
  128. data/spec/fortnox/api/mappers/base/to_json_spec.rb +0 -68
  129. data/spec/fortnox/api/mappers/base_spec.rb +0 -154
  130. data/spec/fortnox/api/mappers/contexts/json_conversion.rb +0 -62
  131. data/spec/fortnox/api/mappers/customer_spec.rb +0 -27
  132. data/spec/fortnox/api/mappers/default_delivery_types_spec.rb +0 -14
  133. data/spec/fortnox/api/mappers/edi_information_spec.rb +0 -23
  134. data/spec/fortnox/api/mappers/email_information_spec.rb +0 -19
  135. data/spec/fortnox/api/mappers/examples/mapper.rb +0 -34
  136. data/spec/fortnox/api/mappers/invoice_row_spec.rb +0 -24
  137. data/spec/fortnox/api/mappers/invoice_spec.rb +0 -27
  138. data/spec/fortnox/api/mappers/order_row_spec.rb +0 -21
  139. data/spec/fortnox/api/mappers/order_spec.rb +0 -23
  140. data/spec/fortnox/api/mappers/project_spec.rb +0 -12
  141. data/spec/fortnox/api/mappers/terms_of_payment_spec.rb +0 -16
  142. data/spec/fortnox/api/mappers/unit_spec.rb +0 -56
  143. data/spec/fortnox/api/models/article_spec.rb +0 -9
  144. data/spec/fortnox/api/models/base_spec.rb +0 -117
  145. data/spec/fortnox/api/models/customer_spec.rb +0 -9
  146. data/spec/fortnox/api/models/examples/document_base.rb +0 -15
  147. data/spec/fortnox/api/models/examples/model.rb +0 -22
  148. data/spec/fortnox/api/models/invoice_spec.rb +0 -11
  149. data/spec/fortnox/api/models/order_spec.rb +0 -12
  150. data/spec/fortnox/api/models/project_spec.rb +0 -9
  151. data/spec/fortnox/api/models/terms_of_payment_spec.rb +0 -9
  152. data/spec/fortnox/api/models/unit_spec.rb +0 -33
  153. data/spec/fortnox/api/repositories/article_spec.rb +0 -80
  154. data/spec/fortnox/api/repositories/authentication_spec.rb +0 -103
  155. data/spec/fortnox/api/repositories/base_spec.rb +0 -168
  156. data/spec/fortnox/api/repositories/customer_spec.rb +0 -119
  157. data/spec/fortnox/api/repositories/examples/all.rb +0 -17
  158. data/spec/fortnox/api/repositories/examples/find.rb +0 -84
  159. data/spec/fortnox/api/repositories/examples/only.rb +0 -34
  160. data/spec/fortnox/api/repositories/examples/save.rb +0 -76
  161. data/spec/fortnox/api/repositories/examples/save_with_nested_model.rb +0 -28
  162. data/spec/fortnox/api/repositories/examples/save_with_specially_named_attribute.rb +0 -26
  163. data/spec/fortnox/api/repositories/examples/search.rb +0 -39
  164. data/spec/fortnox/api/repositories/invoice_spec.rb +0 -297
  165. data/spec/fortnox/api/repositories/order_spec.rb +0 -53
  166. data/spec/fortnox/api/repositories/project_spec.rb +0 -36
  167. data/spec/fortnox/api/repositories/terms_of_payment_spec.rb +0 -34
  168. data/spec/fortnox/api/repositories/unit_spec.rb +0 -39
  169. data/spec/fortnox/api/types/account_number_spec.rb +0 -35
  170. data/spec/fortnox/api/types/country_code_spec.rb +0 -42
  171. data/spec/fortnox/api/types/country_spec.rb +0 -67
  172. data/spec/fortnox/api/types/default_delivery_types_spec.rb +0 -12
  173. data/spec/fortnox/api/types/edi_information_spec.rb +0 -15
  174. data/spec/fortnox/api/types/email_information_spec.rb +0 -15
  175. data/spec/fortnox/api/types/email_spec.rb +0 -56
  176. data/spec/fortnox/api/types/enums_spec.rb +0 -17
  177. data/spec/fortnox/api/types/examples/document_row.rb +0 -25
  178. data/spec/fortnox/api/types/examples/enum.rb +0 -55
  179. data/spec/fortnox/api/types/examples/types.rb +0 -11
  180. data/spec/fortnox/api/types/housework_types_spec.rb +0 -149
  181. data/spec/fortnox/api/types/invoice_row_spec.rb +0 -11
  182. data/spec/fortnox/api/types/model_spec.rb +0 -69
  183. data/spec/fortnox/api/types/nullable_spec.rb +0 -79
  184. data/spec/fortnox/api/types/order_row_spec.rb +0 -15
  185. data/spec/fortnox/api/types/required_spec.rb +0 -36
  186. data/spec/fortnox/api/types/sales_account_spec.rb +0 -57
  187. data/spec/fortnox/api/types/sized_spec.rb +0 -76
  188. data/spec/fortnox/api_spec.rb +0 -66
  189. data/spec/spec_helper.rb +0 -35
  190. data/spec/support/helpers/configuration_helper.rb +0 -39
  191. data/spec/support/helpers/repository_helper.rb +0 -10
  192. data/spec/support/helpers.rb +0 -3
  193. data/spec/support/matchers/type/attribute_matcher.rb +0 -40
  194. data/spec/support/matchers/type/enum_matcher.rb +0 -23
  195. data/spec/support/matchers/type/have_account_number_matcher.rb +0 -23
  196. data/spec/support/matchers/type/have_currency_matcher.rb +0 -9
  197. data/spec/support/matchers/type/have_customer_type_matcher.rb +0 -15
  198. data/spec/support/matchers/type/have_default_delivery_type_matcher.rb +0 -9
  199. data/spec/support/matchers/type/have_discount_type_matcher.rb +0 -9
  200. data/spec/support/matchers/type/have_email_matcher.rb +0 -24
  201. data/spec/support/matchers/type/have_housework_type_matcher.rb +0 -9
  202. data/spec/support/matchers/type/have_nullable_date_matcher.rb +0 -60
  203. data/spec/support/matchers/type/have_nullable_matcher.rb +0 -54
  204. data/spec/support/matchers/type/have_nullable_string_matcher.rb +0 -47
  205. data/spec/support/matchers/type/have_sized_float_matcher.rb +0 -10
  206. data/spec/support/matchers/type/have_sized_integer_matcher.rb +0 -10
  207. data/spec/support/matchers/type/have_sized_string_matcher.rb +0 -36
  208. data/spec/support/matchers/type/have_vat_type_matcher.rb +0 -9
  209. data/spec/support/matchers/type/numeric_matcher.rb +0 -52
  210. data/spec/support/matchers/type/require_attribute_matcher.rb +0 -68
  211. data/spec/support/matchers/type/type_matcher.rb +0 -40
  212. data/spec/support/matchers/type.rb +0 -19
  213. data/spec/support/matchers.rb +0 -3
  214. data/spec/support/vcr_setup.rb +0 -25
  215. data/spec/vcr_cassettes/articles/all.yml +0 -67
  216. data/spec/vcr_cassettes/articles/find_by_hash_failure.yml +0 -62
  217. data/spec/vcr_cassettes/articles/find_failure.yml +0 -62
  218. data/spec/vcr_cassettes/articles/find_id_1.yml +0 -63
  219. data/spec/vcr_cassettes/articles/find_new.yml +0 -63
  220. data/spec/vcr_cassettes/articles/limits/quantity_in_stock_min_value.yml +0 -63
  221. data/spec/vcr_cassettes/articles/limits/quantity_in_stock_rounding_positive_value.yml +0 -63
  222. data/spec/vcr_cassettes/articles/multi_param_find_by_hash.yml +0 -62
  223. data/spec/vcr_cassettes/articles/save_new.yml +0 -63
  224. data/spec/vcr_cassettes/articles/save_old.yml +0 -63
  225. data/spec/vcr_cassettes/articles/save_with_specially_named_attribute.yml +0 -63
  226. data/spec/vcr_cassettes/articles/search_by_name.yml +0 -65
  227. data/spec/vcr_cassettes/articles/search_miss.yml +0 -62
  228. data/spec/vcr_cassettes/articles/search_with_special_char.yml +0 -62
  229. data/spec/vcr_cassettes/articles/single_param_find_by_hash.yml +0 -62
  230. data/spec/vcr_cassettes/authentication/expired_token.yml +0 -54
  231. data/spec/vcr_cassettes/authentication/invalid_authorization.yml +0 -57
  232. data/spec/vcr_cassettes/authentication/invalid_refresh_token.yml +0 -58
  233. data/spec/vcr_cassettes/authentication/valid_request.yml +0 -63
  234. data/spec/vcr_cassettes/customers/all.yml +0 -69
  235. data/spec/vcr_cassettes/customers/find_by_hash_failure.yml +0 -62
  236. data/spec/vcr_cassettes/customers/find_failure.yml +0 -62
  237. data/spec/vcr_cassettes/customers/find_id_1.yml +0 -64
  238. data/spec/vcr_cassettes/customers/find_new.yml +0 -63
  239. data/spec/vcr_cassettes/customers/find_with_sales_account.yml +0 -63
  240. data/spec/vcr_cassettes/customers/multi_param_find_by_hash.yml +0 -63
  241. data/spec/vcr_cassettes/customers/save_new.yml +0 -63
  242. data/spec/vcr_cassettes/customers/save_new_with_country_code_SE.yml +0 -64
  243. data/spec/vcr_cassettes/customers/save_new_with_idn_email.yml +0 -67
  244. data/spec/vcr_cassettes/customers/save_new_with_sales_account.yml +0 -63
  245. data/spec/vcr_cassettes/customers/save_old.yml +0 -63
  246. data/spec/vcr_cassettes/customers/save_with_specially_named_attribute.yml +0 -63
  247. data/spec/vcr_cassettes/customers/search_by_name.yml +0 -64
  248. data/spec/vcr_cassettes/customers/search_miss.yml +0 -62
  249. data/spec/vcr_cassettes/customers/search_with_special_char.yml +0 -62
  250. data/spec/vcr_cassettes/customers/single_param_find_by_hash.yml +0 -64
  251. data/spec/vcr_cassettes/invoices/all.yml +0 -96
  252. data/spec/vcr_cassettes/invoices/filter_hit.yml +0 -64
  253. data/spec/vcr_cassettes/invoices/filter_invalid.yml +0 -60
  254. data/spec/vcr_cassettes/invoices/find_by_hash_failure.yml +0 -62
  255. data/spec/vcr_cassettes/invoices/find_failure.yml +0 -62
  256. data/spec/vcr_cassettes/invoices/find_id_1.yml +0 -65
  257. data/spec/vcr_cassettes/invoices/find_new.yml +0 -65
  258. data/spec/vcr_cassettes/invoices/multi_param_find_by_hash.yml +0 -63
  259. data/spec/vcr_cassettes/invoices/row_delivered_quantity_decimals.yml +0 -65
  260. data/spec/vcr_cassettes/invoices/row_delivered_quantity_decimals_round_up.yml +0 -65
  261. data/spec/vcr_cassettes/invoices/row_description_limit.yml +0 -65
  262. data/spec/vcr_cassettes/invoices/row_price_limit.yml +0 -65
  263. data/spec/vcr_cassettes/invoices/row_price_limit_round_up.yml +0 -65
  264. data/spec/vcr_cassettes/invoices/save_new.yml +0 -65
  265. data/spec/vcr_cassettes/invoices/save_new_with_comments.yml +0 -65
  266. data/spec/vcr_cassettes/invoices/save_new_with_country.yml +0 -65
  267. data/spec/vcr_cassettes/invoices/save_new_with_country_GB.yml +0 -66
  268. data/spec/vcr_cassettes/invoices/save_new_with_country_Norge.yml +0 -65
  269. data/spec/vcr_cassettes/invoices/save_new_with_country_Norway.yml +0 -65
  270. data/spec/vcr_cassettes/invoices/save_new_with_country_Sverige.yml +0 -65
  271. data/spec/vcr_cassettes/invoices/save_new_with_country_VA.yml +0 -66
  272. data/spec/vcr_cassettes/invoices/save_new_with_country_VI.yml +0 -66
  273. data/spec/vcr_cassettes/invoices/save_new_with_country_empty_string.yml +0 -65
  274. data/spec/vcr_cassettes/invoices/save_new_with_country_nil.yml +0 -65
  275. data/spec/vcr_cassettes/invoices/save_new_with_unsaved_parent.yml +0 -65
  276. data/spec/vcr_cassettes/invoices/save_old.yml +0 -65
  277. data/spec/vcr_cassettes/invoices/save_old_with_empty_comments.yml +0 -65
  278. data/spec/vcr_cassettes/invoices/save_old_with_empty_country.yml +0 -65
  279. data/spec/vcr_cassettes/invoices/save_old_with_nil_comments.yml +0 -65
  280. data/spec/vcr_cassettes/invoices/save_old_with_nil_country.yml +0 -65
  281. data/spec/vcr_cassettes/invoices/save_with_nested_model.yml +0 -65
  282. data/spec/vcr_cassettes/invoices/save_with_specially_named_attribute.yml +0 -65
  283. data/spec/vcr_cassettes/invoices/search_by_name.yml +0 -63
  284. data/spec/vcr_cassettes/invoices/search_miss.yml +0 -62
  285. data/spec/vcr_cassettes/invoices/search_with_special_char.yml +0 -62
  286. data/spec/vcr_cassettes/invoices/single_param_find_by_hash.yml +0 -64
  287. data/spec/vcr_cassettes/orders/all.yml +0 -69
  288. data/spec/vcr_cassettes/orders/filter_hit.yml +0 -64
  289. data/spec/vcr_cassettes/orders/filter_invalid.yml +0 -60
  290. data/spec/vcr_cassettes/orders/find_by_hash_failure.yml +0 -62
  291. data/spec/vcr_cassettes/orders/find_failure.yml +0 -62
  292. data/spec/vcr_cassettes/orders/find_id_1.yml +0 -67
  293. data/spec/vcr_cassettes/orders/find_new.yml +0 -65
  294. data/spec/vcr_cassettes/orders/housework_invalid_tax_reduction_type.yml +0 -61
  295. data/spec/vcr_cassettes/orders/housework_othercoses_invalid.yml +0 -61
  296. data/spec/vcr_cassettes/orders/housework_type_babysitting.yml +0 -65
  297. data/spec/vcr_cassettes/orders/housework_type_cleaning.yml +0 -65
  298. data/spec/vcr_cassettes/orders/housework_type_construction.yml +0 -65
  299. data/spec/vcr_cassettes/orders/housework_type_cooking.yml +0 -61
  300. data/spec/vcr_cassettes/orders/housework_type_electricity.yml +0 -65
  301. data/spec/vcr_cassettes/orders/housework_type_gardening.yml +0 -65
  302. data/spec/vcr_cassettes/orders/housework_type_glassmetalwork.yml +0 -65
  303. data/spec/vcr_cassettes/orders/housework_type_grounddrainagework.yml +0 -65
  304. data/spec/vcr_cassettes/orders/housework_type_hvac.yml +0 -65
  305. data/spec/vcr_cassettes/orders/housework_type_itservices.yml +0 -65
  306. data/spec/vcr_cassettes/orders/housework_type_majorappliancerepair.yml +0 -65
  307. data/spec/vcr_cassettes/orders/housework_type_masonry.yml +0 -65
  308. data/spec/vcr_cassettes/orders/housework_type_movingservices.yml +0 -65
  309. data/spec/vcr_cassettes/orders/housework_type_othercare.yml +0 -65
  310. data/spec/vcr_cassettes/orders/housework_type_othercosts.yml +0 -65
  311. data/spec/vcr_cassettes/orders/housework_type_paintingwallpapering.yml +0 -65
  312. data/spec/vcr_cassettes/orders/housework_type_snowplowing.yml +0 -65
  313. data/spec/vcr_cassettes/orders/housework_type_textileclothing.yml +0 -65
  314. data/spec/vcr_cassettes/orders/housework_type_tutoring.yml +0 -61
  315. data/spec/vcr_cassettes/orders/multi_param_find_by_hash.yml +0 -63
  316. data/spec/vcr_cassettes/orders/save_new.yml +0 -65
  317. data/spec/vcr_cassettes/orders/save_old.yml +0 -65
  318. data/spec/vcr_cassettes/orders/save_with_nested_model.yml +0 -65
  319. data/spec/vcr_cassettes/orders/search_by_name.yml +0 -63
  320. data/spec/vcr_cassettes/orders/search_miss.yml +0 -62
  321. data/spec/vcr_cassettes/orders/search_with_special_char.yml +0 -62
  322. data/spec/vcr_cassettes/orders/single_param_find_by_hash.yml +0 -64
  323. data/spec/vcr_cassettes/projects/all.yml +0 -64
  324. data/spec/vcr_cassettes/projects/find_by_hash_failure.yml +0 -62
  325. data/spec/vcr_cassettes/projects/find_failure.yml +0 -62
  326. data/spec/vcr_cassettes/projects/find_id_1.yml +0 -63
  327. data/spec/vcr_cassettes/projects/find_new.yml +0 -63
  328. data/spec/vcr_cassettes/projects/multi_param_find_by_hash.yml +0 -64
  329. data/spec/vcr_cassettes/projects/save_new.yml +0 -63
  330. data/spec/vcr_cassettes/projects/save_old.yml +0 -63
  331. data/spec/vcr_cassettes/projects/single_param_find_by_hash.yml +0 -63
  332. data/spec/vcr_cassettes/termsofpayments/all.yml +0 -68
  333. data/spec/vcr_cassettes/termsofpayments/find_failure.yml +0 -62
  334. data/spec/vcr_cassettes/termsofpayments/find_id_1.yml +0 -62
  335. data/spec/vcr_cassettes/termsofpayments/find_new.yml +0 -63
  336. data/spec/vcr_cassettes/termsofpayments/save_new.yml +0 -63
  337. data/spec/vcr_cassettes/termsofpayments/save_old.yml +0 -63
  338. data/spec/vcr_cassettes/units/all.yml +0 -64
  339. data/spec/vcr_cassettes/units/find_failure.yml +0 -62
  340. data/spec/vcr_cassettes/units/find_id_1.yml +0 -63
  341. data/spec/vcr_cassettes/units/find_new.yml +0 -63
  342. data/spec/vcr_cassettes/units/save_new.yml +0 -63
  343. data/spec/vcr_cassettes/units/save_old.yml +0 -63
  344. data/spec/vcr_cassettes/units/save_with_specially_named_attribute.yml +0 -63
@@ -1,168 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'fortnox/api'
5
- require 'jwt'
6
- require 'dry/container/stub'
7
-
8
- describe Fortnox::API::Repository::Base, integration: true do
9
- include Helpers::Configuration
10
-
11
- before do
12
- stub_const('TestModel', Class.new)
13
- stub_const('TestRepository', Class.new(described_class))
14
- stub_const('TestRepository::MODEL', TestModel)
15
-
16
- Fortnox::API::Registry.enable_stubs!
17
-
18
- add_to_registry(:testmodel, TestModel)
19
- end
20
-
21
- let(:repository) { TestRepository.new }
22
-
23
- describe '#initialize' do
24
- context 'without providing an access token' do
25
- before { Fortnox::API.access_token = nil }
26
-
27
- it 'raises an error' do
28
- expect { TestRepository.new }.to raise_error(Fortnox::API::MissingAccessToken)
29
- end
30
- end
31
-
32
- context 'with expired access token' do
33
- before { Fortnox::API.access_token = ENV.fetch('EXPIRED_ACCESS_TOKEN') }
34
-
35
- it 'raises an error' do
36
- expect do
37
- VCR.use_cassette('authentication/expired_token') { repository.get('/customers', body: '') }
38
- end.to raise_error(Fortnox::API::RemoteServerError, /Unauthorized request(.)*"message":"unauthorized"/)
39
- end
40
- end
41
- end
42
-
43
- context 'when making a request including the proper headers' do
44
- subject { repository.get('/test', body: '') }
45
-
46
- before do
47
- set_api_test_configuration
48
-
49
- stub_request(
50
- :get,
51
- 'https://api.fortnox.se/3/test'
52
- ).to_return(
53
- status: 200
54
- )
55
- end
56
-
57
- it { is_expected.to be_nil }
58
- end
59
-
60
- context 'when receiving an error from remote server' do
61
- before do
62
- set_api_test_configuration
63
-
64
- stub_request(
65
- :post,
66
- 'https://api.fortnox.se/3/test'
67
- ).to_return(
68
- status: 500,
69
- body: {
70
- 'ErrorInformation' => {
71
- 'error' => 1,
72
- 'message' => 'some-error-message'
73
- }
74
- }.to_json,
75
- headers: { 'Content-Type' => 'application/json' }
76
- )
77
- end
78
-
79
- it 'raises an error' do
80
- expect do
81
- repository.post('/test', body: '')
82
- end.to raise_error(Fortnox::API::RemoteServerError, /some-error-message/)
83
- end
84
-
85
- context 'with debugging enabled' do
86
- before { Fortnox::API.config.debugging = true }
87
- after { Fortnox::API.config.debugging = false }
88
-
89
- it do
90
- expect do
91
- repository.post('/test', body: '')
92
- end.to raise_error(/<HTTParty::Request:0x/)
93
- end
94
- end
95
- end
96
-
97
- context 'when receiving HTML from remote server' do
98
- before do
99
- set_api_test_configuration
100
-
101
- stub_request(
102
- :get,
103
- 'https://api.fortnox.se/3nonsense'
104
- ).to_return(
105
- status: 404,
106
- body: "<html>\r\n" \
107
- "<head><title>404 Not Found</title></head>\r\n" \
108
- "<body>\r\n<center><h1>404 Not Found</h1></center>\r\n" \
109
- "<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n",
110
- headers: { 'Content-Type' => 'text/html' }
111
- )
112
- end
113
-
114
- it 'raises an error' do
115
- expect do
116
- repository.get('nonsense')
117
- end.to raise_error(Fortnox::API::RemoteServerError,
118
- %r{Fortnox API's response has content type "text/html"})
119
- end
120
- end
121
-
122
- describe 'update existing' do
123
- context 'with no change' do
124
- before do
125
- set_api_test_configuration
126
-
127
- stub_const(
128
- 'Product',
129
- Class.new(Fortnox::API::Model::Base) do
130
- attribute :name, 'strict.string'
131
- attribute :description, 'string' # nullable
132
- end
133
- )
134
- stub_const('Product::STUB', { name: '' }.freeze)
135
- stub_const('Product::UNIQUE_ID', :name)
136
-
137
- stub_const('ProductMapper', Class.new(Fortnox::API::Mapper::Base))
138
- stub_const('ProductMapper::JSON_ENTITY_WRAPPER', 'Product')
139
- stub_const('ProductMapper::JSON_COLLECTION_WRAPPER', 'Products')
140
- stub_const('ProductMapper::KEY_MAP', {})
141
-
142
- stub_const('TestRepository::MODEL', Product)
143
- stub_const('TestRepository::MAPPER', ProductMapper)
144
- stub_const('TestRepository::URI', '/test/')
145
-
146
- Fortnox::API::Registry.enable_stubs!
147
- add_to_registry(:product, ProductMapper)
148
-
149
- stub_request(
150
- :post,
151
- 'https://api.fortnox.se/3/test/'
152
- ).to_return(
153
- status: 200,
154
- body: '{"Product" : {"Name": "test", "Desription": null}}',
155
- headers: { 'Content-Type' => 'application/json' }
156
- ).times(1) # Only stub the first save request
157
- end
158
-
159
- let(:updated_entity) do
160
- repository.save(Product.new(name: 'test')).update({ description: nil })
161
- end
162
-
163
- it 'does not call Fortnox' do
164
- expect { repository.save(updated_entity) }.not_to raise_error
165
- end
166
- end
167
- end
168
- end
@@ -1,119 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'fortnox/api'
5
- require 'fortnox/api/mappers'
6
- require 'fortnox/api/repositories/customer'
7
- require 'fortnox/api/repositories/examples/all'
8
- require 'fortnox/api/repositories/examples/find'
9
- require 'fortnox/api/repositories/examples/save'
10
- require 'fortnox/api/repositories/examples/save_with_specially_named_attribute'
11
- require 'fortnox/api/repositories/examples/search'
12
-
13
- describe Fortnox::API::Repository::Customer, integration: true, order: :defined do
14
- include Helpers::Configuration
15
- include Helpers::Repositories
16
-
17
- subject(:repository) { described_class.new }
18
-
19
- before { set_api_test_configuration }
20
-
21
- include_examples '.save', :name
22
-
23
- include_examples '.save with specially named attribute',
24
- { name: 'Test customer' },
25
- :email_invoice_cc,
26
- 'test@example.com'
27
-
28
- # VCR: It is not yet possible to delete Customers. Therefore, expected nr of
29
- # Customers when running .all will continue to increase
30
- # (until 100, which is max by default).
31
- include_examples '.all', 7
32
-
33
- # VCR: Searched Customers needs to be created manually
34
- include_examples '.find', '1' do
35
- let(:find_by_hash_failure) { { city: 'Not Found' } }
36
- let(:single_param_find_by_hash) { { find_hash: { city: 'New York' }, matches: 2 } }
37
-
38
- let(:multi_param_find_by_hash) do
39
- { find_hash: { city: 'New York', zipcode: '10001' }, matches: 1 }
40
- end
41
- end
42
-
43
- # NOTE: When recording new VCR casettes, expected matches must be increased
44
- include_examples '.search', :name, 'Test', 2
45
-
46
- describe 'country reference' do
47
- describe 'with valid country code \'SE\'' do
48
- subject(:customer) do
49
- VCR.use_cassette("#{vcr_dir}/save_new_with_country_code_SE") do
50
- repository.save(
51
- described_class::MODEL.new(
52
- name: 'Customer with Swedish country code',
53
- country_code: 'SE'
54
- )
55
- )
56
- end
57
- end
58
-
59
- describe 'country code' do
60
- subject { customer.country_code }
61
-
62
- it { is_expected.to eq('SE') }
63
- end
64
-
65
- describe 'country' do
66
- subject { customer.country }
67
-
68
- it { is_expected.to eq('Sverige') }
69
- end
70
- end
71
- end
72
-
73
- describe 'sales account' do
74
- # VCR: The Sales Account needs to be created manually in Fortnox
75
- context 'when saving a Customer with a Sales Account set' do
76
- let(:customer) do
77
- VCR.use_cassette("#{vcr_dir}/save_new_with_sales_account") do
78
- repository.save(
79
- described_class::MODEL.new(
80
- name: 'Customer with Sales Account',
81
- sales_account: '3001'
82
- )
83
- )
84
- end
85
- end
86
-
87
- context 'when fetching that Customer' do
88
- subject { fetched_customer.sales_account }
89
-
90
- let(:fetched_customer) do
91
- VCR.use_cassette("#{vcr_dir}/find_with_sales_account") do
92
- repository.find(customer.customer_number)
93
- end
94
- end
95
-
96
- it { is_expected.to eq('3001') }
97
- end
98
- end
99
- end
100
-
101
- describe 'internationalized domain name email' do
102
- context 'when saving a Customer with an IDN email address' do
103
- subject(:customer) do
104
- VCR.use_cassette("#{vcr_dir}/save_new_with_idn_email") do
105
- repository.save(
106
- described_class::MODEL.new(
107
- name: 'Customer with IDN email',
108
- email: 'user@teståäö.se'
109
- )
110
- )
111
- end
112
- end
113
-
114
- it 'saves the email' do
115
- expect(customer.email).to eq('user@teståäö.se')
116
- end
117
- end
118
- end
119
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.shared_examples_for '.all' do |count|
4
- describe '.all' do
5
- let(:response) do
6
- VCR.use_cassette("#{vcr_dir}/all") { subject.all }
7
- end
8
-
9
- specify 'returns correct number of records' do
10
- expect(response.size).to be count
11
- end
12
-
13
- specify 'returns correct class' do
14
- expect(response.first.class).to be described_class::MODEL
15
- end
16
- end
17
- end
@@ -1,84 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- shared_examples_for '.find' do |searched_entity_id, find_by_hash: true|
4
- describe '.find by id' do
5
- let(:returned_object) do
6
- VCR.use_cassette("#{vcr_dir}/find_id_1") { repository.find(searched_entity_id) }
7
- end
8
-
9
- context 'when found' do
10
- describe 'returned object' do
11
- subject { returned_object }
12
-
13
- it { is_expected.to be_saved }
14
- it { is_expected.not_to be_new }
15
- end
16
-
17
- describe 'class' do
18
- subject { returned_object.class }
19
-
20
- it { is_expected.to be described_class::MODEL }
21
- end
22
-
23
- describe 'unique id' do
24
- subject { returned_object.unique_id }
25
-
26
- it { is_expected.to eq searched_entity_id }
27
- end
28
- end
29
-
30
- context 'when not found' do
31
- let(:find_with_non_existing_id) do
32
- VCR.use_cassette("#{vcr_dir}/find_failure") { repository.find('123456789') }
33
- end
34
-
35
- specify do
36
- expect { find_with_non_existing_id }.to raise_error(Fortnox::API::RemoteServerError, /Kan inte hitta /)
37
- end
38
- end
39
- end
40
-
41
- if find_by_hash
42
- describe '.find by hash' do
43
- context 'when found' do
44
- let(:returned_array) do
45
- VCR.use_cassette("#{vcr_dir}/#{cassette}") { repository.find(find_hash) }
46
- end
47
-
48
- context 'with single parameter' do
49
- let(:cassette) { 'single_param_find_by_hash' }
50
- let(:find_hash) { single_param_find_by_hash[:find_hash] }
51
-
52
- describe 'returned array size' do
53
- subject { returned_array.size }
54
-
55
- it { is_expected.to eq single_param_find_by_hash[:matches] }
56
- end
57
- end
58
-
59
- context 'with multiple parameters' do
60
- let(:cassette) { 'multi_param_find_by_hash' }
61
- let(:find_hash) { multi_param_find_by_hash[:find_hash] }
62
-
63
- describe 'returned array size' do
64
- subject { returned_array.size }
65
-
66
- it { is_expected.to eq multi_param_find_by_hash[:matches] }
67
- end
68
- end
69
- end
70
-
71
- context 'when not found' do
72
- subject { find_failure }
73
-
74
- let(:find_failure) do
75
- VCR.use_cassette("#{vcr_dir}/find_by_hash_failure") do
76
- repository.find(find_by_hash_failure)
77
- end
78
- end
79
-
80
- it { is_expected.to eq [] }
81
- end
82
- end
83
- end
84
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- shared_examples_for '.only' do |matching_filter, expected_matches, missing_filter: nil|
4
- describe '.only' do
5
- shared_examples '.only response' do |vcr_cassette, expected_entries|
6
- subject { VCR.use_cassette("#{vcr_dir}/#{vcr_cassette}") { repository.only(filter) } }
7
-
8
- it { is_expected.to be_instance_of(Array) }
9
- it { is_expected.to have(expected_entries).entries }
10
- end
11
-
12
- unless missing_filter.nil?
13
- context 'with no matches' do
14
- include_examples '.only response', 'filter_miss', 0 do
15
- let(:filter) { missing_filter }
16
- end
17
- end
18
- end
19
-
20
- context 'with matches' do
21
- include_examples '.only response', 'filter_hit', expected_matches do
22
- let(:filter) { matching_filter }
23
- end
24
- end
25
-
26
- context 'with invalid filter' do
27
- let(:only_with_invalid_filter) do
28
- VCR.use_cassette("#{vcr_dir}/filter_invalid") { repository.only('doesntexist') }
29
- end
30
-
31
- specify { expect { only_with_invalid_filter }.to raise_error(Fortnox::API::RemoteServerError, /ogiltigt filter/) }
32
- end
33
- end
34
- end
@@ -1,76 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #######################################
4
- # SPEC IS DEPENDENT ON DEFINED ORDER!
5
- #######################################
6
- #
7
- # Assumes that attribute is a string attribute without restrictions.
8
- shared_examples_for '.save' do |attribute, additional_attrs: {}|
9
- describe '.save' do
10
- let(:new_hash) { additional_attrs.merge(attribute => 'A value') }
11
- let(:save_new) do
12
- VCR.use_cassette("#{vcr_dir}/save_new") do
13
- repository.save(described_class::MODEL.new(new_hash))
14
- end
15
- end
16
-
17
- shared_examples_for 'save' do
18
- specify "includes correct #{attribute.inspect}" do
19
- saved_entity = send_request
20
- expect(saved_entity.send(attribute)).to eql(value)
21
- end
22
- end
23
-
24
- describe 'new' do
25
- context 'when not saved' do
26
- include_examples 'save' do
27
- let(:model) { described_class::MODEL.new(new_hash) }
28
- let(:send_request) { save_new }
29
- let(:value) { 'A value' }
30
- end
31
- end
32
-
33
- context "saved #{described_class::MODEL}" do
34
- let(:hash) { { unsaved: false }.merge(new_hash) }
35
- let(:model) { described_class::MODEL.new(hash) }
36
-
37
- specify { expect(repository.save(model)).to be(true) }
38
- end
39
- end
40
-
41
- describe 'old (update existing)' do
42
- let(:find_new_cassette) { "#{vcr_dir}/find_new" }
43
-
44
- include_examples 'save' do
45
- let(:value) { "Updated #{attribute}" }
46
-
47
- let(:model) do
48
- existing_model = VCR.use_cassette(find_new_cassette) do
49
- repository.find(save_new.unique_id)
50
- end
51
-
52
- updated_model = existing_model.update(attribute => value)
53
-
54
- if updated_model.saved?
55
- raise(
56
- "We are trying to update the :#{attribute} attribute with " \
57
- "#{value} on an existing record, but that record " \
58
- 'loaded from Fortnox ' \
59
- "already has this attribute set to that value:\n" \
60
- "#{existing_model.inspect}\nHave a look at the VCR cassette " \
61
- "\"#{find_new_cassette}\" which should load the record with the " \
62
- "attribute :#{attribute} set to something else than " \
63
- 'the value we want to set. ' \
64
- )
65
- end
66
-
67
- updated_model
68
- end
69
-
70
- let(:send_request) do
71
- VCR.use_cassette("#{vcr_dir}/save_old") { repository.save(model) }
72
- end
73
- end
74
- end
75
- end
76
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # TODO: This will not work until we solve issue #62.
4
- # Until then, these tests are pending.
5
- shared_examples_for '.save with nested model' do |required_hash, nested_model_key, nested_model_hash, nested_entity|
6
- describe '.save with nested model' do
7
- let(:repository) { described_class.new }
8
- let(:new_hash) do
9
- required_hash.merge(nested_model_key => nested_entity)
10
- end
11
- let(:response) do
12
- VCR.use_cassette("#{vcr_dir}/save_with_nested_model") do
13
- model = described_class::MODEL.new(new_hash)
14
- repository.save(model)
15
- end
16
- end
17
-
18
- describe 'returned entity\'s nested model' do
19
- subject(:returned_nested_model) { response.send(nested_model_key).first }
20
-
21
- it 'has the wanted attributes' do
22
- nested_model_hash.each do |attribute, value|
23
- expect(returned_nested_model.send(attribute)).to eq(value)
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Test saving model with attributes that has specially names that needs to be mapped.
4
- #
5
- # NOTE: VCR cassette must be discarded when repositories are updated to reflect
6
- # the changes!
7
- shared_examples_for '.save with specially named attribute' do |required_hash, attribute, value|
8
- describe '.save' do
9
- context 'with specially named attribute' do
10
- let(:new_model) { described_class::MODEL.new(required_hash.merge(attribute => value)) }
11
- let(:save_model) do
12
- VCR.use_cassette("#{vcr_dir}/save_with_specially_named_attribute") do
13
- repository.save(new_model)
14
- end
15
- end
16
-
17
- it { expect { save_model }.not_to raise_error }
18
-
19
- describe 'response' do
20
- subject { save_model.send(attribute) }
21
-
22
- it { is_expected.to eq(value) }
23
- end
24
- end
25
- end
26
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- shared_examples_for '.search' do |attribute_hash_key_name, value, matches|
4
- describe '.search' do
5
- describe 'search' do
6
- context 'with no matches' do
7
- subject do
8
- VCR.use_cassette("#{vcr_dir}/search_miss") do
9
- repository.search(attribute_hash_key_name => 'nothing')
10
- end
11
- end
12
-
13
- it { is_expected.to be_instance_of(Array) }
14
- it { is_expected.to have(0).entries }
15
- end
16
-
17
- context "with #{matches} match(es)" do
18
- subject do
19
- VCR.use_cassette("#{vcr_dir}/search_by_name") do
20
- repository.search(attribute_hash_key_name => value)
21
- end
22
- end
23
-
24
- it { is_expected.to be_instance_of(Array) }
25
- it { is_expected.to have(matches).entries }
26
- end
27
-
28
- context 'with special characters' do
29
- let(:search_with_special_char) do
30
- VCR.use_cassette("#{vcr_dir}/search_with_special_char") do
31
- repository.search(attribute_hash_key_name => 'special char å')
32
- end
33
- end
34
-
35
- specify { expect { search_with_special_char }.not_to raise_error }
36
- end
37
- end
38
- end
39
- end