fortnox-api 0.8.2 → 0.9.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 (205) hide show
  1. checksums.yaml +4 -4
  2. data/.env.template +7 -0
  3. data/.env.test +11 -3
  4. data/.gitignore +7 -1
  5. data/.rubocop.yml +17 -1
  6. data/.travis.yml +10 -9
  7. data/CHANGELOG.md +22 -8
  8. data/CONTRIBUTE.md +21 -9
  9. data/DEVELOPER_README.md +72 -0
  10. data/Guardfile +13 -4
  11. data/README.md +226 -64
  12. data/Rakefile +128 -0
  13. data/bin/get_tokens +79 -0
  14. data/bin/renew_tokens +28 -0
  15. data/fortnox-api.gemspec +10 -9
  16. data/lib/fortnox/api/mappers/base/from_json.rb +4 -3
  17. data/lib/fortnox/api/mappers/base/to_json.rb +2 -3
  18. data/lib/fortnox/api/models/base.rb +12 -10
  19. data/lib/fortnox/api/models/customer.rb +55 -55
  20. data/lib/fortnox/api/models/label.rb +2 -2
  21. data/lib/fortnox/api/repositories/authentication.rb +61 -0
  22. data/lib/fortnox/api/repositories/base/savers.rb +3 -1
  23. data/lib/fortnox/api/repositories/base.rb +21 -35
  24. data/lib/fortnox/api/repositories.rb +1 -0
  25. data/lib/fortnox/api/request_handling.rb +30 -18
  26. data/lib/fortnox/api/types/document_row.rb +3 -3
  27. data/lib/fortnox/api/types/enums.rb +27 -11
  28. data/lib/fortnox/api/types/model.rb +1 -4
  29. data/lib/fortnox/api/types/sized.rb +2 -2
  30. data/lib/fortnox/api/types.rb +14 -1
  31. data/lib/fortnox/api/version.rb +1 -1
  32. data/lib/fortnox/api.rb +12 -32
  33. data/spec/fortnox/api/mappers/base/canonical_name_sym_spec.rb +4 -4
  34. data/spec/fortnox/api/mappers/base/from_json_spec.rb +10 -12
  35. data/spec/fortnox/api/mappers/base/to_json_spec.rb +48 -57
  36. data/spec/fortnox/api/mappers/base_spec.rb +4 -7
  37. data/spec/fortnox/api/mappers/contexts/json_conversion.rb +38 -33
  38. data/spec/fortnox/api/mappers/unit_spec.rb +3 -4
  39. data/spec/fortnox/api/models/base_spec.rb +27 -16
  40. data/spec/fortnox/api/models/unit_spec.rb +5 -3
  41. data/spec/fortnox/api/repositories/article_spec.rb +14 -9
  42. data/spec/fortnox/api/repositories/authentication_spec.rb +103 -0
  43. data/spec/fortnox/api/repositories/base_spec.rb +106 -319
  44. data/spec/fortnox/api/repositories/customer_spec.rb +37 -7
  45. data/spec/fortnox/api/repositories/examples/all.rb +0 -1
  46. data/spec/fortnox/api/repositories/examples/find.rb +5 -8
  47. data/spec/fortnox/api/repositories/examples/only.rb +4 -13
  48. data/spec/fortnox/api/repositories/examples/save.rb +32 -18
  49. data/spec/fortnox/api/repositories/examples/save_with_nested_model.rb +0 -5
  50. data/spec/fortnox/api/repositories/examples/save_with_specially_named_attribute.rb +1 -4
  51. data/spec/fortnox/api/repositories/examples/search.rb +4 -7
  52. data/spec/fortnox/api/repositories/invoice_spec.rb +64 -15
  53. data/spec/fortnox/api/repositories/order_spec.rb +11 -9
  54. data/spec/fortnox/api/repositories/project_spec.rb +7 -6
  55. data/spec/fortnox/api/repositories/terms_of_payment_spec.rb +9 -7
  56. data/spec/fortnox/api/repositories/unit_spec.rb +13 -11
  57. data/spec/fortnox/api/types/country_spec.rb +1 -1
  58. data/spec/fortnox/api/types/email_spec.rb +2 -2
  59. data/spec/fortnox/api/types/examples/document_row.rb +3 -3
  60. data/spec/fortnox/api/types/examples/enum.rb +4 -4
  61. data/spec/fortnox/api/types/examples/types.rb +1 -3
  62. data/spec/fortnox/api/types/housework_types_spec.rb +54 -61
  63. data/spec/fortnox/api/types/model_spec.rb +3 -27
  64. data/spec/fortnox/api/types/order_row_spec.rb +2 -2
  65. data/spec/fortnox/api/types/required_spec.rb +6 -11
  66. data/spec/fortnox/api/types/sales_account_spec.rb +57 -0
  67. data/spec/fortnox/api_spec.rb +19 -124
  68. data/spec/spec_helper.rb +0 -14
  69. data/spec/support/helpers/configuration_helper.rb +30 -3
  70. data/spec/support/helpers.rb +1 -1
  71. data/spec/support/matchers/type/attribute_matcher.rb +2 -2
  72. data/spec/support/matchers/type/have_nullable_date_matcher.rb +6 -4
  73. data/spec/support/matchers/type/have_nullable_matcher.rb +1 -1
  74. data/spec/support/matchers/type/have_nullable_string_matcher.rb +5 -5
  75. data/spec/support/matchers/type/require_attribute_matcher.rb +5 -5
  76. data/spec/support/matchers/type/type_matcher.rb +1 -1
  77. data/spec/support/vcr_setup.rb +16 -0
  78. data/spec/vcr_cassettes/articles/all.yml +16 -43
  79. data/spec/vcr_cassettes/articles/find_by_hash_failure.yml +10 -12
  80. data/spec/vcr_cassettes/articles/find_failure.yml +10 -12
  81. data/spec/vcr_cassettes/articles/find_id_1.yml +13 -14
  82. data/spec/vcr_cassettes/articles/find_new.yml +14 -16
  83. data/spec/vcr_cassettes/articles/multi_param_find_by_hash.yml +13 -15
  84. data/spec/vcr_cassettes/articles/save_new.yml +13 -15
  85. data/spec/vcr_cassettes/articles/save_old.yml +14 -16
  86. data/spec/vcr_cassettes/articles/save_with_specially_named_attribute.yml +13 -15
  87. data/spec/vcr_cassettes/articles/search_by_name.yml +16 -15
  88. data/spec/vcr_cassettes/articles/search_miss.yml +10 -12
  89. data/spec/vcr_cassettes/articles/search_with_special_char.yml +10 -12
  90. data/spec/vcr_cassettes/articles/single_param_find_by_hash.yml +13 -27
  91. data/spec/vcr_cassettes/authentication/expired_token.yml +54 -0
  92. data/spec/vcr_cassettes/authentication/invalid_authorization.yml +57 -0
  93. data/spec/vcr_cassettes/authentication/invalid_refresh_token.yml +58 -0
  94. data/spec/vcr_cassettes/authentication/valid_request.yml +63 -0
  95. data/spec/vcr_cassettes/customers/all.yml +20 -127
  96. data/spec/vcr_cassettes/customers/find_by_hash_failure.yml +10 -12
  97. data/spec/vcr_cassettes/customers/find_failure.yml +10 -12
  98. data/spec/vcr_cassettes/customers/find_id_1.yml +14 -15
  99. data/spec/vcr_cassettes/customers/find_new.yml +13 -15
  100. data/spec/vcr_cassettes/customers/find_with_sales_account.yml +63 -0
  101. data/spec/vcr_cassettes/customers/multi_param_find_by_hash.yml +13 -15
  102. data/spec/vcr_cassettes/customers/save_new.yml +12 -14
  103. data/spec/vcr_cassettes/customers/save_new_with_country_code_SE.yml +12 -14
  104. data/spec/vcr_cassettes/customers/save_new_with_sales_account.yml +63 -0
  105. data/spec/vcr_cassettes/customers/save_old.yml +13 -15
  106. data/spec/vcr_cassettes/customers/save_with_specially_named_attribute.yml +12 -14
  107. data/spec/vcr_cassettes/customers/search_by_name.yml +13 -45
  108. data/spec/vcr_cassettes/customers/search_miss.yml +10 -12
  109. data/spec/vcr_cassettes/customers/search_with_special_char.yml +10 -12
  110. data/spec/vcr_cassettes/customers/single_param_find_by_hash.yml +14 -16
  111. data/spec/vcr_cassettes/invoices/all.yml +47 -112
  112. data/spec/vcr_cassettes/invoices/filter_hit.yml +14 -18
  113. data/spec/vcr_cassettes/invoices/filter_invalid.yml +10 -12
  114. data/spec/vcr_cassettes/invoices/find_by_hash_failure.yml +10 -12
  115. data/spec/vcr_cassettes/invoices/find_failure.yml +10 -12
  116. data/spec/vcr_cassettes/invoices/find_id_1.yml +15 -16
  117. data/spec/vcr_cassettes/invoices/find_new.yml +16 -18
  118. data/spec/vcr_cassettes/invoices/multi_param_find_by_hash.yml +13 -15
  119. data/spec/vcr_cassettes/invoices/row_description_limit.yml +65 -0
  120. data/spec/vcr_cassettes/invoices/save_new.yml +14 -16
  121. data/spec/vcr_cassettes/invoices/save_new_with_comments.yml +14 -16
  122. data/spec/vcr_cassettes/invoices/save_new_with_country.yml +14 -15
  123. data/spec/vcr_cassettes/invoices/save_new_with_country_GB.yml +15 -16
  124. data/spec/vcr_cassettes/invoices/save_new_with_country_Norge.yml +14 -15
  125. data/spec/vcr_cassettes/invoices/save_new_with_country_Norway.yml +14 -15
  126. data/spec/vcr_cassettes/invoices/save_new_with_country_Sverige.yml +14 -15
  127. data/spec/vcr_cassettes/invoices/save_new_with_country_VA.yml +15 -16
  128. data/spec/vcr_cassettes/invoices/save_new_with_country_VI.yml +15 -16
  129. data/spec/vcr_cassettes/invoices/save_new_with_country_empty_string.yml +14 -15
  130. data/spec/vcr_cassettes/invoices/save_new_with_country_nil.yml +14 -15
  131. data/spec/vcr_cassettes/invoices/save_new_with_unsaved_parent.yml +65 -0
  132. data/spec/vcr_cassettes/invoices/save_old.yml +16 -18
  133. data/spec/vcr_cassettes/invoices/save_old_with_empty_comments.yml +16 -18
  134. data/spec/vcr_cassettes/invoices/save_old_with_empty_country.yml +16 -17
  135. data/spec/vcr_cassettes/invoices/save_old_with_nil_comments.yml +16 -18
  136. data/spec/vcr_cassettes/invoices/save_old_with_nil_country.yml +16 -17
  137. data/spec/vcr_cassettes/invoices/save_with_nested_model.yml +15 -16
  138. data/spec/vcr_cassettes/invoices/save_with_specially_named_attribute.yml +14 -15
  139. data/spec/vcr_cassettes/invoices/search_by_name.yml +13 -21
  140. data/spec/vcr_cassettes/invoices/search_miss.yml +10 -12
  141. data/spec/vcr_cassettes/invoices/search_with_special_char.yml +10 -12
  142. data/spec/vcr_cassettes/invoices/single_param_find_by_hash.yml +14 -16
  143. data/spec/vcr_cassettes/orders/all.yml +19 -113
  144. data/spec/vcr_cassettes/orders/filter_hit.yml +14 -20
  145. data/spec/vcr_cassettes/orders/filter_invalid.yml +10 -12
  146. data/spec/vcr_cassettes/orders/find_by_hash_failure.yml +10 -12
  147. data/spec/vcr_cassettes/orders/find_failure.yml +10 -12
  148. data/spec/vcr_cassettes/orders/find_id_1.yml +17 -17
  149. data/spec/vcr_cassettes/orders/find_new.yml +16 -18
  150. data/spec/vcr_cassettes/orders/housework_invalid_tax_reduction_type.yml +11 -13
  151. data/spec/vcr_cassettes/orders/housework_othercoses_invalid.yml +11 -13
  152. data/spec/vcr_cassettes/orders/housework_type_babysitting.yml +15 -16
  153. data/spec/vcr_cassettes/orders/housework_type_cleaning.yml +15 -16
  154. data/spec/vcr_cassettes/orders/housework_type_construction.yml +15 -16
  155. data/spec/vcr_cassettes/orders/housework_type_cooking.yml +11 -13
  156. data/spec/vcr_cassettes/orders/housework_type_electricity.yml +15 -16
  157. data/spec/vcr_cassettes/orders/housework_type_gardening.yml +15 -16
  158. data/spec/vcr_cassettes/orders/housework_type_glassmetalwork.yml +15 -16
  159. data/spec/vcr_cassettes/orders/housework_type_grounddrainagework.yml +15 -16
  160. data/spec/vcr_cassettes/orders/housework_type_hvac.yml +15 -16
  161. data/spec/vcr_cassettes/orders/housework_type_itservices.yml +15 -16
  162. data/spec/vcr_cassettes/orders/housework_type_majorappliancerepair.yml +15 -16
  163. data/spec/vcr_cassettes/orders/housework_type_masonry.yml +15 -16
  164. data/spec/vcr_cassettes/orders/housework_type_movingservices.yml +15 -16
  165. data/spec/vcr_cassettes/orders/housework_type_othercare.yml +15 -16
  166. data/spec/vcr_cassettes/orders/housework_type_othercosts.yml +15 -16
  167. data/spec/vcr_cassettes/orders/housework_type_paintingwallpapering.yml +15 -16
  168. data/spec/vcr_cassettes/orders/housework_type_snowplowing.yml +15 -16
  169. data/spec/vcr_cassettes/orders/housework_type_textileclothing.yml +15 -16
  170. data/spec/vcr_cassettes/orders/housework_type_tutoring.yml +11 -13
  171. data/spec/vcr_cassettes/orders/multi_param_find_by_hash.yml +13 -15
  172. data/spec/vcr_cassettes/orders/save_new.yml +16 -18
  173. data/spec/vcr_cassettes/orders/save_old.yml +16 -18
  174. data/spec/vcr_cassettes/orders/save_with_nested_model.yml +15 -16
  175. data/spec/vcr_cassettes/orders/search_by_name.yml +13 -17
  176. data/spec/vcr_cassettes/orders/search_miss.yml +10 -12
  177. data/spec/vcr_cassettes/orders/search_with_special_char.yml +10 -12
  178. data/spec/vcr_cassettes/orders/single_param_find_by_hash.yml +14 -16
  179. data/spec/vcr_cassettes/projects/all.yml +14 -37
  180. data/spec/vcr_cassettes/projects/find_by_hash_failure.yml +10 -12
  181. data/spec/vcr_cassettes/projects/find_failure.yml +10 -12
  182. data/spec/vcr_cassettes/projects/find_id_1.yml +13 -15
  183. data/spec/vcr_cassettes/projects/find_new.yml +14 -16
  184. data/spec/vcr_cassettes/projects/multi_param_find_by_hash.yml +15 -16
  185. data/spec/vcr_cassettes/projects/save_new.yml +13 -15
  186. data/spec/vcr_cassettes/projects/save_old.yml +14 -16
  187. data/spec/vcr_cassettes/projects/single_param_find_by_hash.yml +12 -14
  188. data/spec/vcr_cassettes/termsofpayments/all.yml +16 -23
  189. data/spec/vcr_cassettes/termsofpayments/find_failure.yml +10 -12
  190. data/spec/vcr_cassettes/termsofpayments/find_id_1.yml +13 -16
  191. data/spec/vcr_cassettes/termsofpayments/find_new.yml +12 -14
  192. data/spec/vcr_cassettes/termsofpayments/save_new.yml +12 -14
  193. data/spec/vcr_cassettes/termsofpayments/save_old.yml +12 -14
  194. data/spec/vcr_cassettes/units/all.yml +13 -24
  195. data/spec/vcr_cassettes/units/find_failure.yml +10 -12
  196. data/spec/vcr_cassettes/units/find_id_1.yml +13 -15
  197. data/spec/vcr_cassettes/units/find_new.yml +12 -14
  198. data/spec/vcr_cassettes/units/save_new.yml +12 -14
  199. data/spec/vcr_cassettes/units/save_old.yml +12 -14
  200. data/spec/vcr_cassettes/units/save_with_specially_named_attribute.yml +12 -14
  201. metadata +39 -230
  202. data/lib/fortnox/api/circular_queue.rb +0 -39
  203. data/spec/fortnox/api/circular_queue_spec.rb +0 -52
  204. data/spec/support/helpers/when_performing_helper.rb +0 -7
  205. data/temp.txt +0 -1
@@ -7,21 +7,14 @@
7
7
  # Assumes that attribute is a string attribute without restrictions.
8
8
  shared_examples_for '.save' do |attribute, additional_attrs: {}|
9
9
  describe '.save' do
10
- let(:new_hash) { additional_attrs.merge(attribute => value) }
11
- let(:new_model) { described_class::MODEL.new(new_hash) }
12
- let(:save_new) { VCR.use_cassette("#{vcr_dir}/save_new") { repository.save(new_model) } }
13
- let(:entity_wrapper) { repository.mapper.class::JSON_ENTITY_WRAPPER }
14
- let(:value) { 'A value' }
15
-
16
- shared_examples_for 'save' do
17
- before do
18
- if model.saved?
19
- message = 'Test trying to save model, but already marked as saved!'
20
- message << " Model: #{model.inspect}"
21
- raise(message)
22
- end
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))
23
14
  end
15
+ end
24
16
 
17
+ shared_examples_for 'save' do
25
18
  specify "includes correct #{attribute.inspect}" do
26
19
  saved_entity = send_request
27
20
  expect(saved_entity.send(attribute)).to eql(value)
@@ -31,8 +24,9 @@ shared_examples_for '.save' do |attribute, additional_attrs: {}|
31
24
  describe 'new' do
32
25
  context 'when not saved' do
33
26
  include_examples 'save' do
34
- let(:model) { new_model }
27
+ let(:model) { described_class::MODEL.new(new_hash) }
35
28
  let(:send_request) { save_new }
29
+ let(:value) { 'A value' }
36
30
  end
37
31
  end
38
32
 
@@ -45,13 +39,34 @@ shared_examples_for '.save' do |attribute, additional_attrs: {}|
45
39
  end
46
40
 
47
41
  describe 'old (update existing)' do
42
+ let(:find_new_cassette) { "#{vcr_dir}/find_new" }
43
+
48
44
  include_examples 'save' do
49
45
  let(:value) { "Updated #{attribute}" }
46
+
50
47
  let(:model) do
51
- new_id = save_new.unique_id
52
- new_record = VCR.use_cassette("#{vcr_dir}/find_new") { repository.find(new_id) }
53
- new_record.update(attribute => value)
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
54
68
  end
69
+
55
70
  let(:send_request) do
56
71
  VCR.use_cassette("#{vcr_dir}/save_old") { repository.save(model) }
57
72
  end
@@ -59,4 +74,3 @@ shared_examples_for '.save' do |attribute, additional_attrs: {}|
59
74
  end
60
75
  end
61
76
  end
62
- # rubocop:enable RSpec/DescribeClass
@@ -15,10 +15,6 @@ shared_examples_for '.save with nested model' do |required_hash, nested_model_ke
15
15
  end
16
16
  end
17
17
 
18
- it 'does not raise any errors' do
19
- expect { response }.not_to raise_error
20
- end
21
-
22
18
  describe 'returned entity\'s nested model' do
23
19
  subject(:returned_nested_model) { response.send(nested_model_key).first }
24
20
 
@@ -30,4 +26,3 @@ shared_examples_for '.save with nested model' do |required_hash, nested_model_ke
30
26
  end
31
27
  end
32
28
  end
33
- # rubocop:enable RSpec/DescribeClass
@@ -7,8 +7,6 @@
7
7
  shared_examples_for '.save with specially named attribute' do |required_hash, attribute, value|
8
8
  describe '.save' do
9
9
  context 'with specially named attribute' do
10
- subject { -> { save_model } }
11
-
12
10
  let(:new_model) { described_class::MODEL.new(required_hash.merge(attribute => value)) }
13
11
  let(:save_model) do
14
12
  VCR.use_cassette("#{vcr_dir}/save_with_specially_named_attribute") do
@@ -16,7 +14,7 @@ shared_examples_for '.save with specially named attribute' do |required_hash, at
16
14
  end
17
15
  end
18
16
 
19
- it { is_expected.not_to raise_error }
17
+ it { expect { save_model }.not_to raise_error }
20
18
 
21
19
  describe 'response' do
22
20
  subject { save_model.send(attribute) }
@@ -26,4 +24,3 @@ shared_examples_for '.save with specially named attribute' do |required_hash, at
26
24
  end
27
25
  end
28
26
  end
29
- # rubocop:enable RSpec/DescribeClass
@@ -26,17 +26,14 @@ shared_examples_for '.search' do |attribute_hash_key_name, value, matches|
26
26
  end
27
27
 
28
28
  context 'with special characters' do
29
- subject do
30
- when_performing do
31
- VCR.use_cassette("#{vcr_dir}/search_with_special_char") do
32
- repository.search(attribute_hash_key_name => 'special char å')
33
- end
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 å')
34
32
  end
35
33
  end
36
34
 
37
- it { is_expected.not_to raise_error }
35
+ specify { expect { search_with_special_char }.not_to raise_error }
38
36
  end
39
37
  end
40
38
  end
41
39
  end
42
- # rubocop:enable RSpec/DescribeClass
@@ -12,18 +12,36 @@ require 'fortnox/api/repositories/examples/save_with_nested_model'
12
12
  require 'fortnox/api/repositories/examples/save_with_specially_named_attribute'
13
13
  require 'fortnox/api/repositories/examples/only'
14
14
 
15
- describe Fortnox::API::Repository::Invoice, order: :defined, integration: true do
15
+ describe Fortnox::API::Repository::Invoice, integration: true, order: :defined do
16
16
  include Helpers::Configuration
17
-
18
- before { set_api_test_configuration }
17
+ include Helpers::Repositories
19
18
 
20
19
  subject(:repository) { described_class.new }
21
20
 
21
+ before { set_api_test_configuration }
22
+
22
23
  required_hash = { customer_number: '1' }
23
24
 
24
25
  include_examples '.save', :comments, additional_attrs: required_hash
25
26
 
26
- nested_model_hash = { price: 10, article_number: '0000' }
27
+ describe '#save' do
28
+ context 'with unsaved parent' do
29
+ subject(:saved_child) do
30
+ parent_invoice = Fortnox::API::Model::Invoice.new(customer_number: '1')
31
+ child_invoice = parent_invoice.update(due_date: '2023-01-01')
32
+
33
+ VCR.use_cassette("#{vcr_dir}/save_new_with_unsaved_parent") do
34
+ described_class.new.save(child_invoice)
35
+ end
36
+ end
37
+
38
+ it 'sets attribute from parent when saved' do
39
+ expect(saved_child.customer_number).to eq '1'
40
+ end
41
+ end
42
+ end
43
+
44
+ nested_model_hash = { price: 10, article_number: '101' }
27
45
  include_examples '.save with nested model',
28
46
  required_hash,
29
47
  :invoice_rows,
@@ -37,8 +55,9 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
37
55
 
38
56
  # It is not possible to delete Invoces. Therefore, expected nr of Orders
39
57
  # when running .all will continue to increase (until 100, which is max by default).
40
- include_examples '.all', 100
58
+ include_examples '.all', 34
41
59
 
60
+ # VCR: Models needs to be created manually in Fortnox
42
61
  include_examples '.find', 1 do
43
62
  let(:find_by_hash_failure) { { yourreference: 'Not found' } }
44
63
 
@@ -51,9 +70,10 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
51
70
  end
52
71
  end
53
72
 
54
- include_examples '.search', :customername, 'Test', 7
73
+ include_examples '.search', :customername, 'Test', 1
55
74
 
56
- include_examples '.only', :fullypaid, 4
75
+ # VCR: Need to be set manually in Fortnox
76
+ include_examples '.only', :fullypaid, 2
57
77
 
58
78
  describe 'country attribute' do
59
79
  def new_invoice(country:)
@@ -124,7 +144,7 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
124
144
  before { persisted_invoice }
125
145
 
126
146
  context 'when setting value to nil' do
127
- subject { updated_persisted_invoice.comments }
147
+ subject(:comments) { updated_persisted_invoice.comments }
128
148
 
129
149
  let(:updated_persisted_invoice) do
130
150
  VCR.use_cassette("#{vcr_dir}/save_old_with_nil_comments") do
@@ -132,11 +152,14 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
132
152
  end
133
153
  end
134
154
 
135
- pending { is_expected.to eq(nil) }
155
+ it do
156
+ pending "test to rerecord VCR cassette, maybe it's working now"
157
+ expect(comments).to be_nil
158
+ end
136
159
  end
137
160
 
138
161
  context 'when setting value to empty string' do
139
- subject { updated_persisted_invoice.comments }
162
+ subject(:comments) { updated_persisted_invoice.comments }
140
163
 
141
164
  let(:updated_persisted_invoice) do
142
165
  VCR.use_cassette("#{vcr_dir}/save_old_with_empty_comments") do
@@ -145,7 +168,7 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
145
168
  end
146
169
 
147
170
  it 'does not reset the value' do
148
- is_expected.to eq('A comment to be reset')
171
+ expect(comments).to eq('A comment to be reset')
149
172
  end
150
173
  end
151
174
  end
@@ -164,7 +187,7 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
164
187
  before { persisted_invoice }
165
188
 
166
189
  context 'when setting value to nil' do
167
- subject { updated_persisted_invoice.country }
190
+ subject(:country) { updated_persisted_invoice.country }
168
191
 
169
192
  let(:updated_persisted_invoice) do
170
193
  # TODO: This VCR cassette needs to be re-recorded again
@@ -174,11 +197,14 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
174
197
  end
175
198
  end
176
199
 
177
- pending { is_expected.to eq(nil) }
200
+ it 'is nil' do
201
+ pending 'see comment above'
202
+ expect(country).to be_nil
203
+ end
178
204
  end
179
205
 
180
206
  context 'when setting value to empty string' do
181
- subject { updated_persisted_invoice.country }
207
+ subject(:country) { updated_persisted_invoice.country }
182
208
 
183
209
  let(:updated_persisted_invoice) do
184
210
  VCR.use_cassette("#{vcr_dir}/save_old_with_empty_country") do
@@ -187,9 +213,32 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
187
213
  end
188
214
 
189
215
  it 'does not reset the country' do
190
- is_expected.to eq('SE')
216
+ expect(country).to eq('SE')
191
217
  end
192
218
  end
193
219
  end
194
220
  end
221
+
222
+ describe 'limits for invoice_row' do
223
+ describe 'description' do
224
+ let(:model) do
225
+ described_class::MODEL.new(
226
+ customer_number: '1',
227
+ invoice_rows: [
228
+ {
229
+ article_number: '101',
230
+ description: 'a' * 255
231
+ }
232
+ ]
233
+ )
234
+ end
235
+ let(:saving_with_max_row_description) do
236
+ VCR.use_cassette("#{vcr_dir}/row_description_limit") { repository.save(model) }
237
+ end
238
+
239
+ it 'allows 255 characters' do
240
+ expect { saving_with_max_row_description }.not_to raise_error
241
+ end
242
+ end
243
+ end
195
244
  end
@@ -11,28 +11,29 @@ require 'fortnox/api/repositories/examples/save'
11
11
  require 'fortnox/api/repositories/examples/save_with_nested_model'
12
12
  require 'fortnox/api/repositories/examples/search'
13
13
 
14
- describe Fortnox::API::Repository::Order, order: :defined, integration: true do
14
+ describe Fortnox::API::Repository::Order, integration: true, order: :defined do
15
15
  include Helpers::Configuration
16
-
17
- before { set_api_test_configuration }
16
+ include Helpers::Repositories
18
17
 
19
18
  subject(:repository) { described_class.new }
20
19
 
20
+ before { set_api_test_configuration }
21
+
21
22
  required_hash = { customer_number: '1' }
22
23
 
23
24
  include_examples '.save', :comments, additional_attrs: required_hash
24
25
 
25
- nested_model_hash = { price: 10, article_number: '0000', ordered_quantity: 1 }
26
+ nested_model_hash = { price: -9_999_999_999, article_number: '101', ordered_quantity: 1 }
26
27
  include_examples '.save with nested model',
27
28
  required_hash,
28
29
  :order_rows,
29
30
  nested_model_hash,
30
31
  [Fortnox::API::Types::OrderRow.new(nested_model_hash)]
31
32
 
32
- # It is not possible to delete Orders. Therefore, expected nr of Orders
33
- # when running .all will continue to increase (until 100, which is max by default).
34
- include_examples '.all', 100
33
+ # VCR: Update expected result
34
+ include_examples '.all', 7
35
35
 
36
+ # VCR: Searched Orders needs to be created manually in Fortnox
36
37
  include_examples '.find', 1 do
37
38
  let(:find_by_hash_failure) { { ourreference: 'Not found' } }
38
39
 
@@ -45,7 +46,8 @@ describe Fortnox::API::Repository::Order, order: :defined, integration: true do
45
46
  end
46
47
  end
47
48
 
48
- include_examples '.search', :customername, 'A customer', 3
49
+ # VCR: Searched Order needs to be created manually
50
+ include_examples '.search', :customername, 'A customer', 1
49
51
 
50
- include_examples '.only', :cancelled, 6
52
+ include_examples '.only', :cancelled, 2
51
53
  end
@@ -8,28 +8,29 @@ require 'fortnox/api/repositories/examples/all'
8
8
  require 'fortnox/api/repositories/examples/find'
9
9
  require 'fortnox/api/repositories/examples/save'
10
10
 
11
- describe Fortnox::API::Repository::Project, order: :defined, integration: true do
11
+ describe Fortnox::API::Repository::Project, integration: true, order: :defined do
12
12
  include Helpers::Configuration
13
-
14
- before { set_api_test_configuration }
13
+ include Helpers::Repositories
15
14
 
16
15
  subject(:repository) { described_class.new }
17
16
 
17
+ before { set_api_test_configuration }
18
+
18
19
  include_examples '.save',
19
20
  :comments,
20
21
  additional_attrs: { description: 'Some important project' }
21
22
 
22
- # It is not yet possible to delete Projects. Therefore, expected nr of
23
+ # VCR: It is not yet possible to delete Projects. Therefore, expected nr of
23
24
  # Projects when running .all will continue to increase
24
25
  # (until 100, which is max by default).
25
- include_examples '.all', 37
26
+ include_examples '.all', 2
26
27
 
27
28
  include_examples '.find', '1' do
28
29
  let(:find_by_hash_failure) { { offset: 10_000 } }
29
30
  let(:single_param_find_by_hash) { { find_hash: { limit: 1 }, matches: 1 } }
30
31
 
31
32
  let(:multi_param_find_by_hash) do
32
- { find_hash: { limit: 2, offset: 2 }, matches: 2 }
33
+ { find_hash: { limit: 2, offset: 0 }, matches: 2 }
33
34
  end
34
35
  end
35
36
  end
@@ -10,23 +10,25 @@ require 'fortnox/api/repositories/examples/save'
10
10
  require 'fortnox/api/repositories/examples/save_with_specially_named_attribute'
11
11
  require 'fortnox/api/repositories/examples/search'
12
12
 
13
- describe Fortnox::API::Repository::TermsOfPayment, order: :defined, integration: true do
13
+ describe Fortnox::API::Repository::TermsOfPayment, integration: true, order: :defined do
14
14
  include Helpers::Configuration
15
+ include Helpers::Repositories
15
16
 
16
17
  subject(:repository) { described_class.new }
17
18
 
18
19
  before { set_api_test_configuration }
19
20
 
20
- # When recording new VCR cassettes, code must be changed to a new unique one
21
- required_hash = { code: '20DAYS' }
21
+ # VCR: code must be changed to a new unique one
22
+ required_hash = { code: '21DAYS' }
22
23
 
23
24
  include_examples '.save', :description, additional_attrs: required_hash
24
25
 
25
- # When recording new VCR cassettes, expected matches needs to be increased
26
- include_examples '.all', 14
26
+ # VCR: expected matches needs to be increased
27
+ include_examples '.all', 10
27
28
 
28
- include_examples '.find', '15DAYS', find_by_hash: false do
29
- let(:find_by_hash_failure) { { code: '15days' } }
29
+ # VCR: The terms of payment searched here needs to be created manually in Fortnox
30
+ include_examples '.find', '19DAYS', find_by_hash: false do
31
+ let(:find_by_hash_failure) { { code: '19days' } }
30
32
  let(:single_param_find_by_hash) { { find_hash: { code: '30days' }, matches: 1 } }
31
33
  end
32
34
  end
@@ -9,29 +9,31 @@ require 'fortnox/api/repositories/examples/find'
9
9
  require 'fortnox/api/repositories/examples/save'
10
10
  require 'fortnox/api/repositories/examples/save_with_specially_named_attribute'
11
11
 
12
- describe Fortnox::API::Repository::Unit, order: :defined, integration: true do
12
+ describe Fortnox::API::Repository::Unit, integration: true, order: :defined do
13
13
  include Helpers::Configuration
14
-
15
- before { set_api_test_configuration }
14
+ include Helpers::Repositories
16
15
 
17
16
  subject(:repository) { described_class.new }
18
17
 
19
- # When recording new VCR cassettes, code needs to be changed to a unique value
18
+ before { set_api_test_configuration }
19
+
20
+ # VCR: code needs to be changed to a unique value
20
21
  include_examples '.save',
21
22
  :description,
22
- additional_attrs: { code: 'blarg7' }
23
+ additional_attrs: { code: 'blarg9' }
23
24
 
24
- # When recording new VCR cassettes, code needs to be changed to a unique value
25
+ # VCR: code needs to be changed to a unique value
25
26
  include_examples '.save with specially named attribute',
26
27
  { description: 'Happy clouds' },
27
28
  :code,
28
- 'woooh6'
29
+ 'woooh7'
29
30
 
30
- # When recording new VCR cassettes, expected number must be updated
31
- include_examples '.all', 16
31
+ # VCR: expected number must be updated
32
+ include_examples '.all', 7
32
33
 
33
- include_examples '.find', 'blarg', find_by_hash: false do
34
+ # VCR: code must be updated
35
+ include_examples '.find', 'blarg7', find_by_hash: false do
34
36
  let(:find_by_hash_failure) { { code: 'notfound' } }
35
- let(:single_param_find_by_hash) { { find_hash: { code: 'blarg' }, matches: 1 } }
37
+ let(:single_param_find_by_hash) { { find_hash: { code: 'blarg7' }, matches: 1 } }
36
38
  end
37
39
  end
@@ -45,7 +45,7 @@ describe Fortnox::API::Types::Country do
45
45
  expect(described_class['SV']).to eq 'SV'
46
46
  end
47
47
 
48
- it 'translated Switzerland to ' do
48
+ it 'translated Switzerland to' do
49
49
  expect(described_class['Switzerland']).to eq 'CH'
50
50
  end
51
51
  end
@@ -36,8 +36,8 @@ describe Fortnox::API::Types::Email do
36
36
  end
37
37
 
38
38
  context 'when created with more than 1024 characters' do
39
- legal_characters = 'abcdefghijklmnopqrstuvwxyz0123456789.-_+'.split('')
40
- too_long_email = (legal_characters * 35).shuffle.join + '@example.com'
39
+ legal_characters = 'abcdefghijklmnopqrstuvwxyz0123456789.-_+'.chars
40
+ too_long_email = "#{(legal_characters * 35).shuffle.join}@example.com"
41
41
  include_examples 'raises ConstraintError', too_long_email
42
42
  end
43
43
  end
@@ -4,7 +4,7 @@ shared_examples_for 'DocumentRow' do |valid_hash|
4
4
  it { is_expected.to have_account_number(:account_number, valid_hash) }
5
5
 
6
6
  it { is_expected.to have_sized_string(:article_number, 50, valid_hash) }
7
- it { is_expected.to have_sized_string(:description, 50, valid_hash) }
7
+ it { is_expected.to have_sized_string(:description, 255, valid_hash) }
8
8
 
9
9
  it { is_expected.to have_discount_type(:discount_type, valid_hash) }
10
10
 
@@ -12,10 +12,10 @@ shared_examples_for 'DocumentRow' do |valid_hash|
12
12
 
13
13
  it { is_expected.to have_housework_type(:housework_type, valid_hash) }
14
14
 
15
- it { is_expected.to have_sized_float(:price, 0.0, 99_999_999_999.9, valid_hash) }
15
+ it { is_expected.to have_sized_float(:price, -9_999_999_999, 99_999_999_999.9, valid_hash) }
16
16
 
17
17
  it do # rubocop:disable RSpec/ExampleLength
18
- is_expected.to have_sized_float(
18
+ expect(subject).to have_sized_float(
19
19
  :delivered_quantity,
20
20
  -9_999_999_999_999.9,
21
21
  9_999_999_999_999.9,
@@ -36,14 +36,14 @@ shared_examples_for 'enum' do |name, values, auto_crop: false|
36
36
  end
37
37
 
38
38
  context 'with a string that starts like a random member from the enum' do
39
- let(:input) { enum_value.downcase + 'more string' }
39
+ let(:input) { "#{enum_value.downcase}more string" }
40
40
 
41
41
  if auto_crop
42
42
  it { is_expected.to eq enum_value }
43
43
  else
44
- subject { -> { klass[input] } }
45
-
46
- it { is_expected.to raise_error(Dry::Types::ConstraintError) }
44
+ it do
45
+ expect { klass[input] }.to raise_error(Dry::Types::ConstraintError)
46
+ end
47
47
  end
48
48
  end
49
49
  end
@@ -7,7 +7,5 @@ shared_examples_for 'equals input' do |input|
7
7
  end
8
8
 
9
9
  shared_examples_for 'raises ConstraintError' do |input|
10
- subject { -> { klass[input] } }
11
-
12
- it { is_expected.to raise_error(Dry::Types::ConstraintError) }
10
+ specify { expect { klass[input] }.to raise_error(Dry::Types::ConstraintError) }
13
11
  end