fortnox-api 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +1 -0
  3. data/.rubocop.yml +1 -1
  4. data/.tool-versions +1 -0
  5. data/.travis.yml +5 -3
  6. data/CHANGELOG.md +37 -3
  7. data/fortnox-api.gemspec +22 -17
  8. data/lib/fortnox/api/mappers/article.rb +1 -1
  9. data/lib/fortnox/api/mappers/base/from_json.rb +1 -1
  10. data/lib/fortnox/api/mappers/base/to_json.rb +2 -2
  11. data/lib/fortnox/api/mappers/base.rb +3 -3
  12. data/lib/fortnox/api/mappers/customer.rb +1 -1
  13. data/lib/fortnox/api/mappers/default_delivery_types.rb +1 -1
  14. data/lib/fortnox/api/mappers/default_templates.rb +1 -1
  15. data/lib/fortnox/api/mappers/edi_information.rb +1 -1
  16. data/lib/fortnox/api/mappers/email_information.rb +1 -1
  17. data/lib/fortnox/api/mappers/invoice.rb +4 -4
  18. data/lib/fortnox/api/mappers/invoice_row.rb +1 -1
  19. data/lib/fortnox/api/mappers/order.rb +4 -4
  20. data/lib/fortnox/api/mappers/order_row.rb +1 -1
  21. data/lib/fortnox/api/mappers/project.rb +1 -1
  22. data/lib/fortnox/api/mappers/terms_of_payment.rb +1 -1
  23. data/lib/fortnox/api/mappers/unit.rb +1 -1
  24. data/lib/fortnox/api/mappers/value/country_string.rb +1 -1
  25. data/lib/fortnox/api/mappers.rb +18 -18
  26. data/lib/fortnox/api/models/article.rb +2 -2
  27. data/lib/fortnox/api/models/base.rb +14 -14
  28. data/lib/fortnox/api/models/customer.rb +2 -2
  29. data/lib/fortnox/api/models/document.rb +2 -2
  30. data/lib/fortnox/api/models/invoice.rb +2 -2
  31. data/lib/fortnox/api/models/label.rb +1 -1
  32. data/lib/fortnox/api/models/order.rb +2 -2
  33. data/lib/fortnox/api/models/project.rb +2 -2
  34. data/lib/fortnox/api/models/terms_of_payment.rb +2 -2
  35. data/lib/fortnox/api/models/unit.rb +2 -2
  36. data/lib/fortnox/api/models.rb +7 -7
  37. data/lib/fortnox/api/repositories/article.rb +3 -3
  38. data/lib/fortnox/api/repositories/base.rb +4 -3
  39. data/lib/fortnox/api/repositories/customer.rb +3 -3
  40. data/lib/fortnox/api/repositories/invoice.rb +3 -3
  41. data/lib/fortnox/api/repositories/order.rb +3 -3
  42. data/lib/fortnox/api/repositories/project.rb +3 -3
  43. data/lib/fortnox/api/repositories/terms_of_payment.rb +3 -3
  44. data/lib/fortnox/api/repositories/unit.rb +3 -3
  45. data/lib/fortnox/api/repositories.rb +7 -7
  46. data/lib/fortnox/api/types/default_delivery_types.rb +0 -2
  47. data/lib/fortnox/api/types/default_templates.rb +0 -2
  48. data/lib/fortnox/api/types/edi_information.rb +0 -2
  49. data/lib/fortnox/api/types/email_information.rb +0 -2
  50. data/lib/fortnox/api/types/invoice_row.rb +1 -1
  51. data/lib/fortnox/api/types/model.rb +4 -6
  52. data/lib/fortnox/api/types/nullable.rb +13 -9
  53. data/lib/fortnox/api/types/order_row.rb +1 -1
  54. data/lib/fortnox/api/types/required.rb +3 -3
  55. data/lib/fortnox/api/types/sized.rb +2 -2
  56. data/lib/fortnox/api/types.rb +17 -22
  57. data/lib/fortnox/api/version.rb +1 -1
  58. data/lib/fortnox/api.rb +18 -16
  59. data/spec/fortnox/api/mappers/base/canonical_name_sym_spec.rb +9 -7
  60. data/spec/fortnox/api/mappers/default_delivery_types_spec.rb +1 -1
  61. data/spec/fortnox/api/mappers/examples/mapper.rb +1 -1
  62. data/spec/fortnox/api/models/base_spec.rb +8 -8
  63. data/spec/fortnox/api/repositories/article_spec.rb +2 -2
  64. data/spec/fortnox/api/repositories/base_spec.rb +4 -12
  65. data/spec/fortnox/api/repositories/customer_spec.rb +1 -1
  66. data/spec/fortnox/api/repositories/invoice_spec.rb +0 -6
  67. data/spec/fortnox/api/repositories/project_spec.rb +1 -1
  68. data/spec/fortnox/api/repositories/terms_of_payment_spec.rb +2 -2
  69. data/spec/fortnox/api/repositories/unit_spec.rb +3 -3
  70. data/spec/fortnox/api/types/housework_types_spec.rb +0 -29
  71. data/spec/fortnox/api/types/model_spec.rb +11 -17
  72. data/spec/fortnox/api/types/nullable_spec.rb +30 -10
  73. data/spec/fortnox/api/types/required_spec.rb +1 -4
  74. data/spec/support/matchers/type/enum_matcher.rb +1 -1
  75. data/spec/support/matchers/type/have_account_number_matcher.rb +1 -1
  76. data/spec/support/matchers/type/have_email_matcher.rb +1 -1
  77. data/spec/support/matchers/type/have_nullable_date_matcher.rb +5 -5
  78. data/spec/support/matchers/type/have_nullable_string_matcher.rb +3 -3
  79. data/spec/vcr_cassettes/articles/all.yml +30 -20
  80. data/spec/vcr_cassettes/articles/find_by_hash_failure.yml +25 -19
  81. data/spec/vcr_cassettes/articles/find_failure.yml +25 -19
  82. data/spec/vcr_cassettes/articles/find_id_1.yml +26 -20
  83. data/spec/vcr_cassettes/articles/find_new.yml +28 -22
  84. data/spec/vcr_cassettes/articles/multi_param_find_by_hash.yml +25 -19
  85. data/spec/vcr_cassettes/articles/save_new.yml +27 -21
  86. data/spec/vcr_cassettes/articles/save_old.yml +28 -22
  87. data/spec/vcr_cassettes/articles/save_with_specially_named_attribute.yml +27 -21
  88. data/spec/vcr_cassettes/articles/search_by_name.yml +25 -19
  89. data/spec/vcr_cassettes/articles/search_miss.yml +25 -19
  90. data/spec/vcr_cassettes/articles/search_with_special_char.yml +25 -19
  91. data/spec/vcr_cassettes/articles/single_param_find_by_hash.yml +28 -21
  92. data/spec/vcr_cassettes/customers/all.yml +26 -20
  93. data/spec/vcr_cassettes/customers/find_by_hash_failure.yml +25 -19
  94. data/spec/vcr_cassettes/customers/find_failure.yml +25 -19
  95. data/spec/vcr_cassettes/customers/find_id_1.yml +25 -19
  96. data/spec/vcr_cassettes/customers/find_new.yml +27 -21
  97. data/spec/vcr_cassettes/customers/multi_param_find_by_hash.yml +25 -19
  98. data/spec/vcr_cassettes/customers/save_new.yml +26 -20
  99. data/spec/vcr_cassettes/customers/save_new_with_country_code_SE.yml +26 -20
  100. data/spec/vcr_cassettes/customers/save_old.yml +27 -21
  101. data/spec/vcr_cassettes/customers/save_with_specially_named_attribute.yml +26 -20
  102. data/spec/vcr_cassettes/customers/search_by_name.yml +28 -20
  103. data/spec/vcr_cassettes/customers/search_miss.yml +25 -19
  104. data/spec/vcr_cassettes/customers/search_with_special_char.yml +25 -19
  105. data/spec/vcr_cassettes/customers/single_param_find_by_hash.yml +25 -19
  106. data/spec/vcr_cassettes/invoices/all.yml +26 -20
  107. data/spec/vcr_cassettes/invoices/filter_hit.yml +25 -19
  108. data/spec/vcr_cassettes/invoices/filter_invalid.yml +25 -19
  109. data/spec/vcr_cassettes/invoices/find_by_hash_failure.yml +25 -19
  110. data/spec/vcr_cassettes/invoices/find_failure.yml +25 -19
  111. data/spec/vcr_cassettes/invoices/find_id_1.yml +26 -20
  112. data/spec/vcr_cassettes/invoices/find_new.yml +30 -24
  113. data/spec/vcr_cassettes/invoices/multi_param_find_by_hash.yml +25 -19
  114. data/spec/vcr_cassettes/invoices/save_new.yml +29 -23
  115. data/spec/vcr_cassettes/invoices/save_new_with_comments.yml +29 -23
  116. data/spec/vcr_cassettes/invoices/save_new_with_country.yml +28 -22
  117. data/spec/vcr_cassettes/invoices/save_new_with_country_GB.yml +29 -23
  118. data/spec/vcr_cassettes/invoices/save_new_with_country_Norge.yml +28 -22
  119. data/spec/vcr_cassettes/invoices/save_new_with_country_Norway.yml +28 -22
  120. data/spec/vcr_cassettes/invoices/save_new_with_country_Sverige.yml +28 -22
  121. data/spec/vcr_cassettes/invoices/save_new_with_country_VA.yml +29 -23
  122. data/spec/vcr_cassettes/invoices/save_new_with_country_VI.yml +29 -23
  123. data/spec/vcr_cassettes/invoices/save_new_with_country_empty_string.yml +28 -22
  124. data/spec/vcr_cassettes/invoices/save_new_with_country_nil.yml +28 -22
  125. data/spec/vcr_cassettes/invoices/save_old.yml +30 -24
  126. data/spec/vcr_cassettes/invoices/save_old_with_empty_comments.yml +30 -24
  127. data/spec/vcr_cassettes/invoices/save_old_with_empty_country.yml +29 -23
  128. data/spec/vcr_cassettes/invoices/save_old_with_nil_comments.yml +30 -24
  129. data/spec/vcr_cassettes/invoices/save_old_with_nil_country.yml +29 -23
  130. data/spec/vcr_cassettes/invoices/save_with_nested_model.yml +28 -22
  131. data/spec/vcr_cassettes/invoices/save_with_specially_named_attribute.yml +28 -22
  132. data/spec/vcr_cassettes/invoices/search_by_name.yml +25 -19
  133. data/spec/vcr_cassettes/invoices/search_miss.yml +25 -19
  134. data/spec/vcr_cassettes/invoices/search_with_special_char.yml +25 -19
  135. data/spec/vcr_cassettes/invoices/single_param_find_by_hash.yml +25 -19
  136. data/spec/vcr_cassettes/orders/all.yml +26 -20
  137. data/spec/vcr_cassettes/orders/filter_hit.yml +25 -19
  138. data/spec/vcr_cassettes/orders/filter_invalid.yml +25 -19
  139. data/spec/vcr_cassettes/orders/find_by_hash_failure.yml +25 -19
  140. data/spec/vcr_cassettes/orders/find_failure.yml +25 -19
  141. data/spec/vcr_cassettes/orders/find_id_1.yml +25 -19
  142. data/spec/vcr_cassettes/orders/find_new.yml +29 -23
  143. data/spec/vcr_cassettes/orders/housework_invalid_tax_reduction_type.yml +25 -19
  144. data/spec/vcr_cassettes/orders/housework_othercoses_invalid.yml +25 -19
  145. data/spec/vcr_cassettes/orders/housework_type_babysitting.yml +28 -22
  146. data/spec/vcr_cassettes/orders/housework_type_cleaning.yml +28 -22
  147. data/spec/vcr_cassettes/orders/housework_type_construction.yml +28 -22
  148. data/spec/vcr_cassettes/orders/housework_type_cooking.yml +25 -19
  149. data/spec/vcr_cassettes/orders/housework_type_electricity.yml +28 -22
  150. data/spec/vcr_cassettes/orders/housework_type_gardening.yml +28 -22
  151. data/spec/vcr_cassettes/orders/housework_type_glassmetalwork.yml +28 -22
  152. data/spec/vcr_cassettes/orders/housework_type_grounddrainagework.yml +28 -22
  153. data/spec/vcr_cassettes/orders/housework_type_hvac.yml +28 -22
  154. data/spec/vcr_cassettes/orders/housework_type_itservices.yml +28 -22
  155. data/spec/vcr_cassettes/orders/housework_type_majorappliancerepair.yml +28 -22
  156. data/spec/vcr_cassettes/orders/housework_type_masonry.yml +28 -22
  157. data/spec/vcr_cassettes/orders/housework_type_movingservices.yml +28 -22
  158. data/spec/vcr_cassettes/orders/housework_type_othercare.yml +28 -22
  159. data/spec/vcr_cassettes/orders/housework_type_othercosts.yml +28 -22
  160. data/spec/vcr_cassettes/orders/housework_type_paintingwallpapering.yml +28 -22
  161. data/spec/vcr_cassettes/orders/housework_type_snowplowing.yml +28 -22
  162. data/spec/vcr_cassettes/orders/housework_type_textileclothing.yml +28 -22
  163. data/spec/vcr_cassettes/orders/housework_type_tutoring.yml +25 -19
  164. data/spec/vcr_cassettes/orders/multi_param_find_by_hash.yml +25 -19
  165. data/spec/vcr_cassettes/orders/save_new.yml +28 -22
  166. data/spec/vcr_cassettes/orders/save_old.yml +29 -23
  167. data/spec/vcr_cassettes/orders/save_with_nested_model.yml +28 -22
  168. data/spec/vcr_cassettes/orders/search_by_name.yml +25 -19
  169. data/spec/vcr_cassettes/orders/search_miss.yml +25 -19
  170. data/spec/vcr_cassettes/orders/search_with_special_char.yml +25 -19
  171. data/spec/vcr_cassettes/orders/single_param_find_by_hash.yml +25 -19
  172. data/spec/vcr_cassettes/projects/all.yml +31 -21
  173. data/spec/vcr_cassettes/projects/find_by_hash_failure.yml +25 -19
  174. data/spec/vcr_cassettes/projects/find_failure.yml +25 -19
  175. data/spec/vcr_cassettes/projects/find_id_1.yml +25 -19
  176. data/spec/vcr_cassettes/projects/find_new.yml +28 -22
  177. data/spec/vcr_cassettes/projects/multi_param_find_by_hash.yml +26 -20
  178. data/spec/vcr_cassettes/projects/save_new.yml +27 -21
  179. data/spec/vcr_cassettes/projects/save_old.yml +28 -22
  180. data/spec/vcr_cassettes/projects/single_param_find_by_hash.yml +26 -20
  181. data/spec/vcr_cassettes/termsofpayments/all.yml +34 -27
  182. data/spec/vcr_cassettes/termsofpayments/find_failure.yml +25 -19
  183. data/spec/vcr_cassettes/termsofpayments/find_id_1.yml +25 -19
  184. data/spec/vcr_cassettes/termsofpayments/find_new.yml +27 -21
  185. data/spec/vcr_cassettes/termsofpayments/save_new.yml +27 -21
  186. data/spec/vcr_cassettes/termsofpayments/save_old.yml +27 -21
  187. data/spec/vcr_cassettes/units/all.yml +36 -28
  188. data/spec/vcr_cassettes/units/find_failure.yml +25 -19
  189. data/spec/vcr_cassettes/units/find_id_1.yml +26 -20
  190. data/spec/vcr_cassettes/units/find_new.yml +27 -21
  191. data/spec/vcr_cassettes/units/save_new.yml +27 -21
  192. data/spec/vcr_cassettes/units/save_old.yml +27 -21
  193. data/spec/vcr_cassettes/units/save_with_specially_named_attribute.yml +27 -21
  194. metadata +107 -47
  195. data/spec/support/helpers/dummy_class_helper.rb +0 -38
  196. data/spec/vcr_cassettes/invoices/save_new_with_country_KR.yml +0 -61
  197. data/spec/vcr_cassettes/orders/housework_without_tax_reduction_type.yml +0 -57
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/repositories/base'
4
- require 'fortnox/api/models/order'
5
- require 'fortnox/api/mappers/order'
3
+ require_relative 'base'
4
+ require_relative '../models/order'
5
+ require_relative '../mappers/order'
6
6
 
7
7
  module Fortnox
8
8
  module API
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/repositories/base'
4
- require 'fortnox/api/models/project'
5
- require 'fortnox/api/mappers/project'
3
+ require_relative 'base'
4
+ require_relative '../models/project'
5
+ require_relative '../mappers/project'
6
6
 
7
7
  module Fortnox
8
8
  module API
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/repositories/base'
4
- require 'fortnox/api/models/terms_of_payment'
5
- require 'fortnox/api/mappers/terms_of_payment'
3
+ require_relative 'base'
4
+ require_relative '../models/terms_of_payment'
5
+ require_relative '../mappers/terms_of_payment'
6
6
 
7
7
  module Fortnox
8
8
  module API
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/repositories/base'
4
- require 'fortnox/api/models/unit'
5
- require 'fortnox/api/mappers/unit'
3
+ require_relative 'base'
4
+ require_relative '../models/unit'
5
+ require_relative '../mappers/unit'
6
6
 
7
7
  module Fortnox
8
8
  module API
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/repositories/article'
4
- require 'fortnox/api/repositories/customer'
5
- require 'fortnox/api/repositories/invoice'
6
- require 'fortnox/api/repositories/order'
7
- require 'fortnox/api/repositories/project'
8
- require 'fortnox/api/repositories/unit'
9
- require 'fortnox/api/repositories/terms_of_payment'
3
+ require_relative 'repositories/article'
4
+ require_relative 'repositories/customer'
5
+ require_relative 'repositories/invoice'
6
+ require_relative 'repositories/order'
7
+ require_relative 'repositories/project'
8
+ require_relative 'repositories/unit'
9
+ require_relative 'repositories/terms_of_payment'
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/types'
4
-
5
3
  module Fortnox
6
4
  module API
7
5
  module Types
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/types'
4
-
5
3
  module Fortnox
6
4
  module API
7
5
  module Types
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/types'
4
-
5
3
  module Fortnox
6
4
  module API
7
5
  module Types
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/types'
4
-
5
3
  module Fortnox
6
4
  module API
7
5
  module Types
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/types/document_row'
3
+ require_relative 'document_row'
4
4
 
5
5
  module Fortnox
6
6
  module API
@@ -4,7 +4,7 @@ module Fortnox
4
4
  module API
5
5
  module Types
6
6
  class Model < Dry::Struct
7
- constructor_type(:schema)
7
+ transform_types(&:omittable)
8
8
 
9
9
  def initialize(input_attributes)
10
10
  if (missing_key = first_missing_required_key(input_attributes))
@@ -15,23 +15,21 @@ module Fortnox
15
15
  super
16
16
  end
17
17
 
18
- def self.is?(*_args) end
19
-
20
18
  private
21
19
 
22
20
  def missing_keys(attributes)
23
21
  non_nil_attributes = attributes.reject { |_, value| value.nil? }
24
22
 
25
23
  attribute_keys = non_nil_attributes.keys
26
- schema_keys = self.class.schema.keys
24
+ schema_keys = self.class.schema.keys.map(&:name)
27
25
 
28
26
  schema_keys - attribute_keys
29
27
  end
30
28
 
31
29
  def first_missing_required_key(attributes)
32
30
  missing_keys(attributes).find do |name|
33
- attribute = self.class.schema[name]
34
- attribute.respond_to?(:options) && attribute.options[:required]
31
+ attribute = self.class.schema.keys.find { |key| key.name == name }
32
+ attribute.type.respond_to?(:options) && attribute.type.options[:required]
35
33
  end
36
34
  end
37
35
  end
@@ -6,15 +6,19 @@ module Fortnox
6
6
  module API
7
7
  module Types
8
8
  module Nullable
9
- String = Types::Strict::String.optional.constructor { |value| value.to_s unless value.nil? }
10
- Float = Types::Strict::Float.optional.constructor { |value| value.to_f unless value.nil? }
11
- Integer = Types::Strict::Int.optional.constructor { |value| value.to_i unless value.nil? }
12
- Boolean = Types::Bool.optional.constructor { |value| THE_TRUTH.fetch(value) { false } }
13
- # TODO: Improve parsing!
14
- # In case date parsing fails, ArgumentError is thrown. Currently, it is rescued in Repository::Loaders.find.
15
- # That method assumes that the exception is due to invalid argument to the find method, which is not the case
16
- # if it is raised from here!
17
- Date = Types::Date.optional.constructor { |value| ::Date.parse(value.to_s) unless value.nil? || value == '' }
9
+ String = Types::Strict::String.optional.constructor { |value| value&.to_s }
10
+ Float = Types::Strict::Float.optional.constructor { |value| value&.to_f }
11
+ Integer = Types::Strict::Integer.optional.constructor { |value| value&.to_i }
12
+ Boolean = Types::Bool.optional.constructor { |value| THE_TRUTH.fetch(value, false) }
13
+ Date = Types::Date.optional.constructor do |value|
14
+ next if value.nil? || value == ''
15
+
16
+ begin
17
+ ::Date.parse(value.to_s)
18
+ rescue ::Date::Error
19
+ raise Fortnox::API::AttributeError, 'invalid date'
20
+ end
21
+ end
18
22
  end
19
23
  end
20
24
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'fortnox/api/types/document_row'
3
+ require_relative 'document_row'
4
4
 
5
5
  module Fortnox
6
6
  module API
@@ -4,9 +4,9 @@ module Fortnox
4
4
  module API
5
5
  module Types
6
6
  module Required
7
- String = Types::Strict::String.constructor { |value| value.to_s unless value.nil? }.is(:required)
8
- Integer = Types::Strict::Int.constructor { |value| value.to_i unless value.nil? }.is(:required)
9
- Float = Types::Strict::Float.constructor { |value| value.to_f unless value.nil? }.is(:required)
7
+ String = Types::Strict::String.constructor { |value| value&.to_s }.is(:required)
8
+ Integer = Types::Strict::Integer.constructor { |value| value&.to_i }.is(:required)
9
+ Float = Types::Strict::Float.constructor { |value| value&.to_f }.is(:required)
10
10
  end
11
11
  end
12
12
  end
@@ -14,8 +14,8 @@ module Fortnox
14
14
 
15
15
  module Integer
16
16
  def self.[](low, high)
17
- Types::Strict::Int.constrained(gteq: low, lteq: high).optional.constructor do |value|
18
- value.to_i unless value.nil?
17
+ Types::Strict::Integer.constrained(gteq: low, lteq: high).optional.constructor do |value|
18
+ value&.to_i
19
19
  end
20
20
  end
21
21
  end
@@ -3,7 +3,7 @@
3
3
  require 'dry-struct'
4
4
  require 'dry-types'
5
5
  require 'countries'
6
- require 'fortnox/api/types/shim/country_string'
6
+ require_relative 'types/shim/country_string'
7
7
 
8
8
  module Dry
9
9
  module Types
@@ -12,11 +12,7 @@ module Dry
12
12
  new_options = option_names.each_with_object({}) do |name, hash|
13
13
  hash[name] = true
14
14
  end
15
- with(new_options)
16
- end
17
-
18
- def is?(option_name)
19
- @options[option_name]
15
+ with(**new_options)
20
16
  end
21
17
  end
22
18
  end
@@ -25,20 +21,19 @@ end
25
21
  module Fortnox
26
22
  module API
27
23
  module Types
28
- include Dry::Types.module
24
+ include Dry.Types(default: :nominal)
29
25
  ISO3166.configure { |config| config.locales = %i[en sv] }
30
26
 
31
27
  THE_TRUTH = { true => true, 'true' => true, false => false, 'false' => false }.freeze
32
28
 
33
- require 'fortnox/api/types/required'
34
- require 'fortnox/api/types/defaulted'
35
- require 'fortnox/api/types/nullable'
36
-
37
- require 'fortnox/api/types/enums'
29
+ require_relative 'types/required'
30
+ require_relative 'types/defaulted'
31
+ require_relative 'types/nullable'
38
32
 
39
- require 'fortnox/api/types/sized'
33
+ require_relative 'types/enums'
34
+ require_relative 'types/sized'
40
35
 
41
- AccountNumber = Strict::Int
36
+ AccountNumber = Strict::Integer
42
37
  .constrained(gteq: 0, lteq: 9999)
43
38
  .optional
44
39
  .constructor do |value|
@@ -60,7 +55,7 @@ module Fortnox
60
55
  next CountryString.new('SE') if value.match?(/^s(e$|we|ve)/i)
61
56
 
62
57
  country = ::ISO3166::Country[value] ||
63
- ::ISO3166::Country.find_country_by_name(value) ||
58
+ ::ISO3166::Country.find_country_by_any_name(value) ||
64
59
  ::ISO3166::Country.find_country_by_translated_names(value)
65
60
 
66
61
  raise Dry::Types::ConstraintError.new('value violates constraints', value) if country.nil?
@@ -124,13 +119,13 @@ module Fortnox
124
119
  .optional
125
120
  .constructor(EnumConstructors.lower_case)
126
121
 
127
- require 'fortnox/api/types/model'
128
- require 'fortnox/api/types/default_delivery_types'
129
- require 'fortnox/api/types/default_templates'
130
- require 'fortnox/api/types/email_information'
131
- require 'fortnox/api/types/edi_information'
132
- require 'fortnox/api/types/invoice_row'
133
- require 'fortnox/api/types/order_row'
122
+ require_relative 'types/model'
123
+ require_relative 'types/default_delivery_types'
124
+ require_relative 'types/default_templates'
125
+ require_relative 'types/email_information'
126
+ require_relative 'types/edi_information'
127
+ require_relative 'types/invoice_row'
128
+ require_relative 'types/order_row'
134
129
  end
135
130
  end
136
131
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Fortnox
4
4
  module API
5
- VERSION = '0.8.0'
5
+ VERSION = '0.8.1'
6
6
  end
7
7
  end
data/lib/fortnox/api.rb CHANGED
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'set'
4
- require 'dry-struct'
5
- require 'fortnox/api/circular_queue'
6
- require 'fortnox/api/version'
4
+ require 'dry-configurable'
5
+ require 'dry-container'
7
6
  require 'logger'
8
7
 
8
+ require_relative 'api/circular_queue'
9
+ require_relative 'api/version'
10
+
9
11
  module Fortnox
10
12
  module API
11
13
  extend Dry::Configurable
@@ -18,29 +20,29 @@ module Fortnox
18
20
  access_tokens: nil,
19
21
  debugging: false,
20
22
  logger: lambda {
21
- logger = Logger.new(STDOUT)
23
+ logger = Logger.new($stdout)
22
24
  logger.level = Logger::WARN
23
25
  return logger
24
26
  }.call
25
27
  }.freeze
26
28
 
27
- setting :base_url, DEFAULT_CONFIGURATION[:base_url]
28
- setting :client_secret, DEFAULT_CONFIGURATION[:client_secret]
29
- setting :token_store, DEFAULT_CONFIGURATION[:token_store]
30
- setting :access_token, DEFAULT_CONFIGURATION[:access_token] do |value|
29
+ setting :base_url, default: DEFAULT_CONFIGURATION[:base_url]
30
+ setting :client_secret, default: DEFAULT_CONFIGURATION[:client_secret]
31
+ setting :token_store, default: DEFAULT_CONFIGURATION[:token_store]
32
+ setting :access_token, default: DEFAULT_CONFIGURATION[:access_token], constructor: (proc do |value|
31
33
  next if value.nil? # nil is a valid unassigned value
32
34
  invalid_access_token_format!(value) unless value.is_a?(String)
33
35
  config.token_store = { default: value }
34
36
  value
35
- end
36
- setting :access_tokens, DEFAULT_CONFIGURATION[:access_tokens] do |value|
37
+ end)
38
+ setting :access_tokens, default: DEFAULT_CONFIGURATION[:access_tokens], constructor: (proc do |value|
37
39
  next if value.nil? # nil is a valid unassigned value
38
40
  invalid_access_tokens_format!(value) unless value.is_a?(Hash) || value.is_a?(Array)
39
41
  config.token_store = value.is_a?(Hash) ? value : { default: value }
40
42
  value
41
- end
42
- setting :debugging, DEFAULT_CONFIGURATION[:debugging], reader: true
43
- setting :logger, DEFAULT_CONFIGURATION[:logger], reader: true
43
+ end)
44
+ setting :debugging, default: DEFAULT_CONFIGURATION[:debugging], reader: true
45
+ setting :logger, default: DEFAULT_CONFIGURATION[:logger], reader: true
44
46
 
45
47
  class Exception < StandardError
46
48
  end
@@ -75,6 +77,6 @@ module Fortnox
75
77
  end
76
78
  end
77
79
 
78
- require 'fortnox/api/models'
79
- require 'fortnox/api/repositories'
80
- require 'fortnox/api/mappers'
80
+ require_relative 'api/models'
81
+ require_relative 'api/repositories'
82
+ require_relative 'api/mappers'
@@ -6,10 +6,12 @@ require 'fortnox/api/mappers/base/canonical_name_sym'
6
6
  describe Fortnox::API::Mapper::CanonicalNameSym do
7
7
  describe '.canonical_name_sym' do
8
8
  context 'with simple class' do
9
- using_test_class do
10
- class TestClass
9
+ before do
10
+ test_class = Class.new do
11
11
  extend Fortnox::API::Mapper::CanonicalNameSym
12
12
  end
13
+
14
+ stub_const('TestClass', test_class)
13
15
  end
14
16
 
15
17
  subject { TestClass.canonical_name_sym }
@@ -18,12 +20,12 @@ describe Fortnox::API::Mapper::CanonicalNameSym do
18
20
  end
19
21
 
20
22
  context 'when class included in module' do
21
- using_test_class do
22
- module Something
23
- class Test
24
- extend Fortnox::API::Mapper::CanonicalNameSym
25
- end
23
+ before do
24
+ test_class = Class.new do
25
+ extend Fortnox::API::Mapper::CanonicalNameSym
26
26
  end
27
+
28
+ stub_const('Something::Test', test_class)
27
29
  end
28
30
 
29
31
  subject { Something::Test.canonical_name_sym }
@@ -8,7 +8,7 @@ require 'fortnox/api/mappers/examples/mapper'
8
8
  describe Fortnox::API::Mapper::DefaultDeliveryTypes do
9
9
  key_map = {}
10
10
 
11
- it_behaves_like 'mapper', key_map do
11
+ it_behaves_like 'mapper', key_map, nil, nil do
12
12
  let(:mapper) { described_class.new }
13
13
  end
14
14
  end
@@ -12,7 +12,7 @@ shared_examples_for 'mapper' do |key_map, json_entity_wrapper = nil, json_collec
12
12
  describe 'key_map' do
13
13
  subject { described_class::KEY_MAP }
14
14
 
15
- it { is_expected.to eq(key_map) }
15
+ it { expect(subject).to eq(key_map) }
16
16
  end
17
17
 
18
18
  unless json_entity_wrapper.nil?
@@ -5,8 +5,8 @@ require 'fortnox/api/models/base'
5
5
  require 'fortnox/api/types'
6
6
 
7
7
  describe Fortnox::API::Model::Base do
8
- using_test_classes do
9
- class Entity < Fortnox::API::Model::Base
8
+ let(:entity_class) do
9
+ Class.new(Fortnox::API::Model::Base) do
10
10
  attribute :private, Fortnox::API::Types::String.is(:read_only)
11
11
  attribute :string, Fortnox::API::Types::Required::String
12
12
  attribute :number, Fortnox::API::Types::Nullable::Integer
@@ -16,15 +16,15 @@ describe Fortnox::API::Model::Base do
16
16
 
17
17
  describe '.new' do
18
18
  context 'with basic attribute' do
19
- subject { Entity.new(string: 'Test') }
19
+ subject { entity_class.new(string: 'Test') }
20
20
 
21
- it { is_expected.to be_a Entity }
21
+ it { is_expected.to be_a entity_class }
22
22
  it { is_expected.to be_new }
23
23
  it { is_expected.not_to be_saved }
24
24
  end
25
25
 
26
26
  context 'without required attribute' do
27
- subject { -> { Entity.new({}) } }
27
+ subject { -> { entity_class.new({}) } }
28
28
 
29
29
  it { is_expected.to raise_error Fortnox::API::Exception }
30
30
  it { is_expected.to raise_error Fortnox::API::MissingAttributeError }
@@ -32,7 +32,7 @@ describe Fortnox::API::Model::Base do
32
32
  end
33
33
 
34
34
  context 'with invalid attribute value' do
35
- subject { -> { Entity.new(string: 'Test', account: 13_337) } }
35
+ subject { -> { entity_class.new(string: 'Test', account: 13_337) } }
36
36
 
37
37
  it { is_expected.to raise_error Fortnox::API::Exception }
38
38
  it { is_expected.to raise_error Fortnox::API::AttributeError }
@@ -41,7 +41,7 @@ describe Fortnox::API::Model::Base do
41
41
  end
42
42
 
43
43
  describe '.update' do
44
- let(:original) { Entity.new(string: 'Test') }
44
+ let(:original) { entity_class.new(string: 'Test') }
45
45
 
46
46
  context 'with new, simple value' do
47
47
  subject { updated_model }
@@ -85,7 +85,7 @@ describe Fortnox::API::Model::Base do
85
85
 
86
86
  context 'when updating' do
87
87
  let(:updated_entity) do
88
- saved_entity = Entity.new(string: 'Saved', new: false, unsaved: false)
88
+ saved_entity = entity_class.new(string: 'Saved', new: false, unsaved: false)
89
89
  saved_entity.update(string: 'Updated')
90
90
  end
91
91
 
@@ -27,12 +27,12 @@ describe Fortnox::API::Repository::Article, order: :defined, integration: true d
27
27
  '5901234123457'
28
28
 
29
29
  # When recording new VCR cassettes, expected matches must be increased
30
- include_examples '.all', 29
30
+ include_examples '.all', 33
31
31
 
32
32
  # When recording new VCR cassettes, expected matches must be increased
33
33
  include_examples '.find', '1' do
34
34
  let(:find_by_hash_failure) { { description: 'Not Found' } }
35
- let(:single_param_find_by_hash) { { find_hash: { articlenumber: 1 }, matches: 13 } }
35
+ let(:single_param_find_by_hash) { { find_hash: { articlenumber: 1 }, matches: 14 } }
36
36
 
37
37
  let(:multi_param_find_by_hash) do
38
38
  { find_hash: { articlenumber: 1, description: 'Cykelpump' }, matches: 1 }
@@ -4,19 +4,11 @@ require 'spec_helper'
4
4
  require 'fortnox/api'
5
5
 
6
6
  describe Fortnox::API::Repository::Base do
7
- using_test_class do
8
- module Model
9
- class RepositoryBaseTest
10
- end
11
- end
12
- module Repository
13
- class Test < Fortnox::API::Repository::Base
14
- MODEL = Model::RepositoryBaseTest
15
- end
16
- end
17
- end
18
-
19
7
  before do
8
+ stub_const('Model::RepositoryBaseTest', Class.new)
9
+ stub_const('Repository::Test', Class.new(described_class))
10
+ stub_const('Repository::Test::MODEL', Model::RepositoryBaseTest)
11
+
20
12
  Fortnox::API::Registry.register(:repositorybasetest, Model::RepositoryBaseTest)
21
13
  end
22
14
 
@@ -39,7 +39,7 @@ describe Fortnox::API::Repository::Customer, order: :defined, integration: true
39
39
  end
40
40
 
41
41
  # When recording new VCR casettes, expected matches must be increased
42
- include_examples '.search', :name, 'Test', 31
42
+ include_examples '.search', :name, 'Test', 33
43
43
 
44
44
  describe 'country reference' do
45
45
  describe 'with valid country code \'SE\'' do
@@ -89,12 +89,6 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
89
89
  it { is_expected.to eq('GB') }
90
90
  end
91
91
 
92
- describe 'KR' do
93
- subject { save_invoice(country: 'KR').country }
94
-
95
- it { is_expected.to eq('KR') }
96
- end
97
-
98
92
  describe 'VA' do
99
93
  subject { save_invoice(country: 'VA').country }
100
94
 
@@ -22,7 +22,7 @@ describe Fortnox::API::Repository::Project, order: :defined, integration: true d
22
22
  # It is not yet possible to delete Projects. Therefore, expected nr of
23
23
  # Projects when running .all will continue to increase
24
24
  # (until 100, which is max by default).
25
- include_examples '.all', 33
25
+ include_examples '.all', 37
26
26
 
27
27
  include_examples '.find', '1' do
28
28
  let(:find_by_hash_failure) { { offset: 10_000 } }
@@ -18,12 +18,12 @@ describe Fortnox::API::Repository::TermsOfPayment, order: :defined, integration:
18
18
  before { set_api_test_configuration }
19
19
 
20
20
  # When recording new VCR cassettes, code must be changed to a new unique one
21
- required_hash = { code: '19DAYS' }
21
+ required_hash = { code: '20DAYS' }
22
22
 
23
23
  include_examples '.save', :description, additional_attrs: required_hash
24
24
 
25
25
  # When recording new VCR cassettes, expected matches needs to be increased
26
- include_examples '.all', 13
26
+ include_examples '.all', 14
27
27
 
28
28
  include_examples '.find', '15DAYS', find_by_hash: false do
29
29
  let(:find_by_hash_failure) { { code: '15days' } }
@@ -19,16 +19,16 @@ describe Fortnox::API::Repository::Unit, order: :defined, integration: true do
19
19
  # When recording new VCR cassettes, code needs to be changed to a unique value
20
20
  include_examples '.save',
21
21
  :description,
22
- additional_attrs: { code: 'blarg5' }
22
+ additional_attrs: { code: 'blarg7' }
23
23
 
24
24
  # When recording new VCR cassettes, code needs to be changed to a unique value
25
25
  include_examples '.save with specially named attribute',
26
26
  { description: 'Happy clouds' },
27
27
  :code,
28
- 'woooh5'
28
+ 'woooh6'
29
29
 
30
30
  # When recording new VCR cassettes, expected number must be updated
31
- include_examples '.all', 14
31
+ include_examples '.all', 16
32
32
 
33
33
  include_examples '.find', 'blarg', find_by_hash: false do
34
34
  let(:find_by_hash_failure) { { code: 'notfound' } }
@@ -93,35 +93,6 @@ describe 'HouseworkTypes', integration: true do
93
93
  it_behaves_like 'housework type', 'COOKING', TYPE_RUT, legacy: true
94
94
  it_behaves_like 'housework type', 'TUTORING', TYPE_RUT, legacy: true
95
95
 
96
- describe 'without tax reduction type' do
97
- subject do
98
- cassette = 'orders/housework_without_tax_reduction_type'
99
- -> { VCR.use_cassette(cassette) { repository.save(document) } }
100
- end
101
-
102
- let(:document) do
103
- Fortnox::API::Model::Order.new(
104
- customer_number: '1',
105
- order_rows: [
106
- Fortnox::API::Types::OrderRow.new(
107
- ordered_quantity: 1,
108
- article_number: '0000',
109
- housework_type: Fortnox::API::Types::HouseworkTypes['CONSTRUCTION'],
110
- housework: true
111
- )
112
- ]
113
- )
114
- end
115
-
116
- let(:error_message) do
117
- 'Dokument utan angiven skattereduktionstyp får inte innehålla artikelrader med husarbetestyp.'
118
- end
119
-
120
- it 'raises an error' do
121
- is_expected.to raise_error(Fortnox::API::RemoteServerError, error_message)
122
- end
123
- end
124
-
125
96
  describe 'with OTHERCOSTS' do
126
97
  subject do
127
98
  cassette = 'orders/housework_othercoses_invalid'