fortnox-api 0.6.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (165) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +5 -1
  3. data/.travis.yml +20 -22
  4. data/CHANGELOG.md +48 -0
  5. data/README.md +14 -19
  6. data/Rakefile +5 -0
  7. data/fortnox-api.gemspec +10 -10
  8. data/lib/fortnox/api/mappers.rb +5 -38
  9. data/lib/fortnox/api/mappers/base.rb +2 -24
  10. data/lib/fortnox/api/mappers/base/canonical_name_sym.rb +21 -0
  11. data/lib/fortnox/api/mappers/base/from_json.rb +6 -1
  12. data/lib/fortnox/api/mappers/value/array.rb +18 -0
  13. data/lib/fortnox/api/mappers/value/country_string.rb +24 -0
  14. data/lib/fortnox/api/mappers/value/date.rb +11 -0
  15. data/lib/fortnox/api/mappers/value/hash.rb +16 -0
  16. data/lib/fortnox/api/mappers/value/identity.rb +18 -0
  17. data/lib/fortnox/api/models/document.rb +6 -3
  18. data/lib/fortnox/api/models/invoice.rb +1 -1
  19. data/lib/fortnox/api/models/order.rb +1 -1
  20. data/lib/fortnox/api/repositories/base.rb +9 -11
  21. data/lib/fortnox/api/request_handling.rb +0 -1
  22. data/lib/fortnox/api/types.rb +40 -3
  23. data/lib/fortnox/api/types/enums.rb +36 -31
  24. data/lib/fortnox/api/types/shim/country_string.rb +10 -0
  25. data/lib/fortnox/api/version.rb +1 -1
  26. data/spec/fortnox/api/circular_queue_spec.rb +52 -0
  27. data/spec/fortnox/api/mappers/base/canonical_name_sym_spec.rb +34 -0
  28. data/spec/fortnox/api/mappers/base_spec.rb +33 -43
  29. data/spec/fortnox/api/mappers/contexts/json_conversion.rb +1 -1
  30. data/spec/fortnox/api/repositories/article_spec.rb +4 -2
  31. data/spec/fortnox/api/repositories/base_spec.rb +28 -8
  32. data/spec/fortnox/api/repositories/customer_spec.rb +29 -1
  33. data/spec/fortnox/api/repositories/invoice_spec.rb +147 -3
  34. data/spec/fortnox/api/repositories/order_spec.rb +2 -2
  35. data/spec/fortnox/api/repositories/project_spec.rb +1 -1
  36. data/spec/fortnox/api/repositories/terms_of_payment_spec.rb +4 -2
  37. data/spec/fortnox/api/repositories/unit_spec.rb +6 -3
  38. data/spec/fortnox/api/types/account_number_spec.rb +19 -15
  39. data/spec/fortnox/api/types/country_code_spec.rb +42 -0
  40. data/spec/fortnox/api/types/country_spec.rb +67 -0
  41. data/spec/fortnox/api/types/email_spec.rb +8 -7
  42. data/spec/fortnox/api/types/enums_spec.rb +1 -1
  43. data/spec/fortnox/api/types/examples/document_row.rb +1 -1
  44. data/spec/fortnox/api/types/housework_types_spec.rb +151 -34
  45. data/spec/fortnox/api_spec.rb +3 -1
  46. data/spec/vcr_cassettes/articles/all.yml +40 -10
  47. data/spec/vcr_cassettes/articles/find_by_hash_failure.yml +21 -8
  48. data/spec/vcr_cassettes/articles/find_failure.yml +21 -8
  49. data/spec/vcr_cassettes/articles/find_id_1.yml +22 -9
  50. data/spec/vcr_cassettes/articles/find_new.yml +24 -11
  51. data/spec/vcr_cassettes/articles/multi_param_find_by_hash.yml +21 -8
  52. data/spec/vcr_cassettes/articles/save_new.yml +22 -8
  53. data/spec/vcr_cassettes/articles/save_old.yml +24 -11
  54. data/spec/vcr_cassettes/articles/save_with_specially_named_attribute.yml +22 -8
  55. data/spec/vcr_cassettes/articles/search_by_name.yml +21 -8
  56. data/spec/vcr_cassettes/articles/search_miss.yml +21 -8
  57. data/spec/vcr_cassettes/articles/search_with_special_char.yml +21 -8
  58. data/spec/vcr_cassettes/articles/single_param_find_by_hash.yml +33 -10
  59. data/spec/vcr_cassettes/customers/all.yml +26 -13
  60. data/spec/vcr_cassettes/customers/find_by_hash_failure.yml +21 -8
  61. data/spec/vcr_cassettes/customers/find_failure.yml +21 -8
  62. data/spec/vcr_cassettes/customers/find_id_1.yml +22 -9
  63. data/spec/vcr_cassettes/customers/find_new.yml +24 -11
  64. data/spec/vcr_cassettes/customers/multi_param_find_by_hash.yml +21 -8
  65. data/spec/vcr_cassettes/customers/save_new.yml +21 -7
  66. data/spec/vcr_cassettes/customers/save_new_with_country_code_SE.yml +60 -0
  67. data/spec/vcr_cassettes/customers/save_old.yml +23 -10
  68. data/spec/vcr_cassettes/customers/save_with_specially_named_attribute.yml +21 -7
  69. data/spec/vcr_cassettes/customers/search_by_name.yml +32 -10
  70. data/spec/vcr_cassettes/customers/search_miss.yml +21 -8
  71. data/spec/vcr_cassettes/customers/search_with_special_char.yml +21 -8
  72. data/spec/vcr_cassettes/customers/single_param_find_by_hash.yml +22 -9
  73. data/spec/vcr_cassettes/invoices/all.yml +118 -67
  74. data/spec/vcr_cassettes/invoices/filter_hit.yml +26 -10
  75. data/spec/vcr_cassettes/invoices/filter_invalid.yml +20 -6
  76. data/spec/vcr_cassettes/invoices/find_by_hash_failure.yml +21 -8
  77. data/spec/vcr_cassettes/invoices/find_failure.yml +21 -8
  78. data/spec/vcr_cassettes/invoices/find_id_1.yml +23 -10
  79. data/spec/vcr_cassettes/invoices/find_new.yml +26 -14
  80. data/spec/vcr_cassettes/invoices/multi_param_find_by_hash.yml +23 -10
  81. data/spec/vcr_cassettes/invoices/save_new.yml +23 -10
  82. data/spec/vcr_cassettes/invoices/save_new_with_comments.yml +61 -0
  83. data/spec/vcr_cassettes/invoices/save_new_with_country.yml +60 -0
  84. data/spec/vcr_cassettes/invoices/save_new_with_country_GB.yml +61 -0
  85. data/spec/vcr_cassettes/invoices/save_new_with_country_KR.yml +61 -0
  86. data/spec/vcr_cassettes/invoices/save_new_with_country_Norge.yml +60 -0
  87. data/spec/vcr_cassettes/invoices/save_new_with_country_Norway.yml +60 -0
  88. data/spec/vcr_cassettes/invoices/save_new_with_country_Sverige.yml +60 -0
  89. data/spec/vcr_cassettes/invoices/save_new_with_country_VA.yml +61 -0
  90. data/spec/vcr_cassettes/invoices/save_new_with_country_VI.yml +61 -0
  91. data/spec/vcr_cassettes/invoices/save_new_with_country_empty_string.yml +60 -0
  92. data/spec/vcr_cassettes/invoices/save_new_with_country_nil.yml +60 -0
  93. data/spec/vcr_cassettes/invoices/save_old.yml +25 -13
  94. data/spec/vcr_cassettes/invoices/save_old_with_empty_comments.yml +61 -0
  95. data/spec/vcr_cassettes/invoices/save_old_with_empty_country.yml +60 -0
  96. data/spec/vcr_cassettes/invoices/save_old_with_nil_comments.yml +61 -0
  97. data/spec/vcr_cassettes/invoices/save_old_with_nil_country.yml +60 -0
  98. data/spec/vcr_cassettes/invoices/save_with_nested_model.yml +23 -10
  99. data/spec/vcr_cassettes/invoices/save_with_specially_named_attribute.yml +23 -10
  100. data/spec/vcr_cassettes/invoices/search_by_name.yml +28 -11
  101. data/spec/vcr_cassettes/invoices/search_miss.yml +21 -8
  102. data/spec/vcr_cassettes/invoices/search_with_special_char.yml +21 -8
  103. data/spec/vcr_cassettes/invoices/single_param_find_by_hash.yml +24 -11
  104. data/spec/vcr_cassettes/orders/all.yml +120 -107
  105. data/spec/vcr_cassettes/orders/filter_hit.yml +28 -12
  106. data/spec/vcr_cassettes/orders/filter_invalid.yml +20 -6
  107. data/spec/vcr_cassettes/orders/find_by_hash_failure.yml +21 -8
  108. data/spec/vcr_cassettes/orders/find_failure.yml +21 -8
  109. data/spec/vcr_cassettes/orders/find_id_1.yml +23 -10
  110. data/spec/vcr_cassettes/orders/find_new.yml +26 -14
  111. data/spec/vcr_cassettes/orders/housework_invalid_tax_reduction_type.yml +57 -0
  112. data/spec/vcr_cassettes/orders/housework_othercoses_invalid.yml +57 -0
  113. data/spec/vcr_cassettes/orders/housework_type_babysitting.yml +24 -10
  114. data/spec/vcr_cassettes/orders/housework_type_cleaning.yml +24 -10
  115. data/spec/vcr_cassettes/orders/housework_type_construction.yml +24 -10
  116. data/spec/vcr_cassettes/orders/housework_type_cooking.yml +21 -7
  117. data/spec/vcr_cassettes/orders/housework_type_electricity.yml +24 -10
  118. data/spec/vcr_cassettes/orders/housework_type_gardening.yml +24 -10
  119. data/spec/vcr_cassettes/orders/housework_type_glassmetalwork.yml +24 -10
  120. data/spec/vcr_cassettes/orders/housework_type_grounddrainagework.yml +24 -10
  121. data/spec/vcr_cassettes/orders/housework_type_hvac.yml +24 -10
  122. data/spec/vcr_cassettes/orders/housework_type_itservices.yml +60 -0
  123. data/spec/vcr_cassettes/orders/housework_type_majorappliancerepair.yml +60 -0
  124. data/spec/vcr_cassettes/orders/housework_type_masonry.yml +24 -10
  125. data/spec/vcr_cassettes/orders/housework_type_movingservices.yml +60 -0
  126. data/spec/vcr_cassettes/orders/housework_type_othercare.yml +24 -10
  127. data/spec/vcr_cassettes/orders/housework_type_othercosts.yml +24 -10
  128. data/spec/vcr_cassettes/orders/housework_type_paintingwallpapering.yml +24 -10
  129. data/spec/vcr_cassettes/orders/housework_type_snowplowing.yml +24 -10
  130. data/spec/vcr_cassettes/orders/housework_type_textileclothing.yml +24 -10
  131. data/spec/vcr_cassettes/orders/housework_type_tutoring.yml +21 -7
  132. data/spec/vcr_cassettes/orders/housework_without_tax_reduction_type.yml +57 -0
  133. data/spec/vcr_cassettes/orders/multi_param_find_by_hash.yml +22 -9
  134. data/spec/vcr_cassettes/orders/save_new.yml +23 -10
  135. data/spec/vcr_cassettes/orders/save_old.yml +25 -13
  136. data/spec/vcr_cassettes/orders/save_with_nested_model.yml +23 -10
  137. data/spec/vcr_cassettes/orders/search_by_name.yml +25 -11
  138. data/spec/vcr_cassettes/orders/search_miss.yml +21 -8
  139. data/spec/vcr_cassettes/orders/search_with_special_char.yml +21 -8
  140. data/spec/vcr_cassettes/orders/single_param_find_by_hash.yml +23 -10
  141. data/spec/vcr_cassettes/projects/all.yml +41 -16
  142. data/spec/vcr_cassettes/projects/find_by_hash_failure.yml +21 -8
  143. data/spec/vcr_cassettes/projects/find_failure.yml +21 -8
  144. data/spec/vcr_cassettes/projects/find_id_1.yml +21 -8
  145. data/spec/vcr_cassettes/projects/find_new.yml +24 -11
  146. data/spec/vcr_cassettes/projects/multi_param_find_by_hash.yml +23 -10
  147. data/spec/vcr_cassettes/projects/save_new.yml +22 -8
  148. data/spec/vcr_cassettes/projects/save_old.yml +24 -11
  149. data/spec/vcr_cassettes/projects/single_param_find_by_hash.yml +22 -9
  150. data/spec/vcr_cassettes/termsofpayments/all.yml +31 -14
  151. data/spec/vcr_cassettes/termsofpayments/find_failure.yml +21 -8
  152. data/spec/vcr_cassettes/termsofpayments/find_id_1.yml +22 -9
  153. data/spec/vcr_cassettes/termsofpayments/find_new.yml +23 -10
  154. data/spec/vcr_cassettes/termsofpayments/save_new.yml +22 -8
  155. data/spec/vcr_cassettes/termsofpayments/save_old.yml +23 -10
  156. data/spec/vcr_cassettes/units/all.yml +31 -12
  157. data/spec/vcr_cassettes/units/find_failure.yml +21 -8
  158. data/spec/vcr_cassettes/units/find_id_1.yml +21 -8
  159. data/spec/vcr_cassettes/units/find_new.yml +23 -12
  160. data/spec/vcr_cassettes/units/save_new.yml +22 -10
  161. data/spec/vcr_cassettes/units/save_old.yml +23 -12
  162. data/spec/vcr_cassettes/units/save_with_specially_named_attribute.yml +22 -10
  163. data/temp.txt +1 -0
  164. metadata +99 -21
  165. data/spec/support/matchers/type/have_country_code_matcher.rb +0 -15
@@ -40,7 +40,7 @@ shared_context 'with JSON conversion' do
40
40
  attribute :url, 'strict.string'
41
41
  attribute :name, 'strict.string'
42
42
  attribute :vat, 'strict.float'
43
- attribute :categories, Dry::Types['coercible.array'].member(Test::Category)
43
+ attribute :categories, Dry::Types['coercible.array'].of(Test::Category)
44
44
  attribute :designer, Test::ProductDesigner
45
45
  end
46
46
  end
@@ -26,11 +26,13 @@ describe Fortnox::API::Repository::Article, order: :defined, integration: true d
26
26
  :ean,
27
27
  '5901234123457'
28
28
 
29
- include_examples '.all', 12
29
+ # When recording new VCR cassettes, expected matches must be increased
30
+ include_examples '.all', 29
30
31
 
32
+ # When recording new VCR cassettes, expected matches must be increased
31
33
  include_examples '.find', '1' do
32
34
  let(:find_by_hash_failure) { { description: 'Not Found' } }
33
- let(:single_param_find_by_hash) { { find_hash: { articlenumber: 1 }, matches: 3 } }
35
+ let(:single_param_find_by_hash) { { find_hash: { articlenumber: 1 }, matches: 13 } }
34
36
 
35
37
  let(:multi_param_find_by_hash) do
36
38
  { find_hash: { articlenumber: 1, description: 'Cykelpump' }, matches: 1 }
@@ -6,18 +6,25 @@ require 'fortnox/api'
6
6
  describe Fortnox::API::Repository::Base do
7
7
  using_test_class do
8
8
  module Model
9
- class Test
9
+ class RepositoryBaseTest
10
10
  end
11
11
  end
12
12
  module Repository
13
13
  class Test < Fortnox::API::Repository::Base
14
- MODEL = Model::Test
14
+ MODEL = Model::RepositoryBaseTest
15
15
  end
16
16
  end
17
+ end
18
+
19
+ before do
20
+ Fortnox::API::Registry.register(:repositorybasetest, Model::RepositoryBaseTest)
21
+ end
17
22
 
18
- require 'dry/container/stub'
19
- Fortnox::API::Registry.enable_stubs!
20
- Fortnox::API::Registry.stub(:test, Model::Test)
23
+ after do
24
+ # HACK: Currently, there is no way to remove keys from the Dry::Container#register.
25
+ # We could move the register call to a before(:all) hook, but that registered key
26
+ # would then leak into other tests. Instead, we can simply delete it with this little hack :)
27
+ Fortnox::API::Registry._container.delete('repositorybasetest')
21
28
  end
22
29
 
23
30
  let(:access_token) { '3f08d038-f380-4893-94a0-a08f6e60e67a' }
@@ -36,7 +43,7 @@ describe Fortnox::API::Repository::Base do
36
43
 
37
44
  describe 'creation' do
38
45
  shared_examples_for 'missing configuration' do
39
- subject { -> { repository } }
46
+ subject { -> { Repository::Test.new(token_store: :store1).get('nonsense') } }
40
47
 
41
48
  let(:error) { Fortnox::API::MissingConfiguration }
42
49
 
@@ -45,14 +52,27 @@ describe Fortnox::API::Repository::Base do
45
52
 
46
53
  context 'without base url' do
47
54
  include_examples 'missing configuration' do
48
- before { Fortnox::API.configure { |conf| conf.base_url = nil } }
55
+ before do
56
+ Fortnox::API.configure do |config|
57
+ config.base_url = nil
58
+ config.client_secret = client_secret
59
+ config.access_tokens = { store1: access_token }
60
+ end
61
+ end
62
+
49
63
  let(:message) { 'have to provide a base url' }
50
64
  end
51
65
  end
52
66
 
53
67
  context 'without client secret' do
54
68
  include_examples 'missing configuration' do
55
- before { Fortnox::API.configure { |conf| conf.client_secret = nil } }
69
+ before do
70
+ Fortnox::API.configure do |config|
71
+ config.client_secret = nil
72
+ config.access_tokens = { store1: access_token }
73
+ end
74
+ end
75
+
56
76
  let(:message) { 'have to provide your client secret' }
57
77
  end
58
78
  end
@@ -38,5 +38,33 @@ describe Fortnox::API::Repository::Customer, order: :defined, integration: true
38
38
  end
39
39
  end
40
40
 
41
- include_examples '.search', :name, 'Test', 23
41
+ # When recording new VCR casettes, expected matches must be increased
42
+ include_examples '.search', :name, 'Test', 31
43
+
44
+ describe 'country reference' do
45
+ describe 'with valid country code \'SE\'' do
46
+ subject(:customer) do
47
+ VCR.use_cassette("#{vcr_dir}/save_new_with_country_code_SE") do
48
+ repository.save(
49
+ described_class::MODEL.new(
50
+ name: 'Customer with Swedish country code',
51
+ country_code: 'SE'
52
+ )
53
+ )
54
+ end
55
+ end
56
+
57
+ describe 'country code' do
58
+ subject { customer.country_code }
59
+
60
+ it { is_expected.to eq('SE') }
61
+ end
62
+
63
+ describe 'country' do
64
+ subject { customer.country }
65
+
66
+ it { is_expected.to eq('Sverige') }
67
+ end
68
+ end
69
+ end
42
70
  end
@@ -37,7 +37,7 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
37
37
 
38
38
  # It is not possible to delete Invoces. Therefore, expected nr of Orders
39
39
  # when running .all will continue to increase (until 100, which is max by default).
40
- include_examples '.all', 60
40
+ include_examples '.all', 100
41
41
 
42
42
  include_examples '.find', 1 do
43
43
  let(:find_by_hash_failure) { { yourreference: 'Not found' } }
@@ -51,7 +51,151 @@ describe Fortnox::API::Repository::Invoice, order: :defined, integration: true d
51
51
  end
52
52
  end
53
53
 
54
- include_examples '.search', :customername, 'Test', 3
54
+ include_examples '.search', :customername, 'Test', 7
55
55
 
56
- include_examples '.only', :fullypaid, 1
56
+ include_examples '.only', :fullypaid, 4
57
+
58
+ describe 'country attribute' do
59
+ def new_invoice(country:)
60
+ described_class::MODEL.new(customer_number: 1, country: country)
61
+ end
62
+
63
+ context 'with valid country' do
64
+ def save_invoice(country:, vcr_cassette: country)
65
+ VCR.use_cassette("#{vcr_dir}/save_new_with_country_#{vcr_cassette}") do
66
+ repository.save(new_invoice(country: country))
67
+ end
68
+ end
69
+
70
+ it 'accepts English country names' do
71
+ expect(save_invoice(country: 'Norway').country).to eq('NO')
72
+ end
73
+
74
+ it 'translates Swedish country names to English' do
75
+ expect(save_invoice(country: 'Norge').country).to eq('NO')
76
+ end
77
+
78
+ it 'skips nil values' do
79
+ expect(save_invoice(country: nil, vcr_cassette: 'nil').country).to eq('')
80
+ end
81
+
82
+ it 'skips empty string values' do
83
+ expect(save_invoice(country: '', vcr_cassette: 'empty_string').country).to eq('')
84
+ end
85
+
86
+ describe 'GB' do
87
+ subject { save_invoice(country: 'GB').country }
88
+
89
+ it { is_expected.to eq('GB') }
90
+ end
91
+
92
+ describe 'KR' do
93
+ subject { save_invoice(country: 'KR').country }
94
+
95
+ it { is_expected.to eq('KR') }
96
+ end
97
+
98
+ describe 'VA' do
99
+ subject { save_invoice(country: 'VA').country }
100
+
101
+ it { is_expected.to eq('VA') }
102
+ end
103
+
104
+ describe 'VI' do
105
+ subject { save_invoice(country: 'VI').country }
106
+
107
+ it { is_expected.to eq('VI') }
108
+ end
109
+
110
+ describe 'special cases Sverige' do
111
+ subject { save_invoice(country: 'Sverige').country }
112
+
113
+ it { is_expected.to eq('SE') }
114
+ end
115
+ end
116
+ end
117
+
118
+ describe 'resetting values in Fortnox' do
119
+ context 'with String values' do
120
+ def new_invoice(comments:)
121
+ described_class::MODEL.new(customer_number: 1, comments: comments)
122
+ end
123
+
124
+ let(:persisted_invoice) do
125
+ VCR.use_cassette("#{vcr_dir}/save_new_with_comments") do
126
+ repository.save(new_invoice(comments: 'A comment to be reset'))
127
+ end
128
+ end
129
+
130
+ before { persisted_invoice }
131
+
132
+ context 'when setting value to nil' do
133
+ subject { updated_persisted_invoice.comments }
134
+
135
+ let(:updated_persisted_invoice) do
136
+ VCR.use_cassette("#{vcr_dir}/save_old_with_nil_comments") do
137
+ repository.save(persisted_invoice.update(comments: nil))
138
+ end
139
+ end
140
+
141
+ pending { is_expected.to eq(nil) }
142
+ end
143
+
144
+ context 'when setting value to empty string' do
145
+ subject { updated_persisted_invoice.comments }
146
+
147
+ let(:updated_persisted_invoice) do
148
+ VCR.use_cassette("#{vcr_dir}/save_old_with_empty_comments") do
149
+ repository.save(persisted_invoice.update(comments: ''))
150
+ end
151
+ end
152
+
153
+ it 'does not reset the value' do
154
+ is_expected.to eq('A comment to be reset')
155
+ end
156
+ end
157
+ end
158
+
159
+ context 'with other values' do
160
+ def new_invoice(country:)
161
+ described_class::MODEL.new(customer_number: 1, country: country)
162
+ end
163
+
164
+ let(:persisted_invoice) do
165
+ VCR.use_cassette("#{vcr_dir}/save_new_with_country") do
166
+ repository.save(new_invoice(country: 'Sverige'))
167
+ end
168
+ end
169
+
170
+ before { persisted_invoice }
171
+
172
+ context 'when setting value to nil' do
173
+ subject { updated_persisted_invoice.country }
174
+
175
+ let(:updated_persisted_invoice) do
176
+ # TODO: This VCR cassette needs to be re-recorded again
177
+ # when the we fix #172.
178
+ VCR.use_cassette("#{vcr_dir}/save_old_with_nil_country") do
179
+ repository.save(persisted_invoice.update(country: nil))
180
+ end
181
+ end
182
+
183
+ pending { is_expected.to eq(nil) }
184
+ end
185
+
186
+ context 'when setting value to empty string' do
187
+ subject { updated_persisted_invoice.country }
188
+
189
+ let(:updated_persisted_invoice) do
190
+ VCR.use_cassette("#{vcr_dir}/save_old_with_empty_country") do
191
+ repository.save(persisted_invoice.update(country: ''))
192
+ end
193
+ end
194
+
195
+ it 'does not reset the country' do
196
+ is_expected.to eq('SE')
197
+ end
198
+ end
199
+ end
200
+ end
57
201
  end
@@ -45,7 +45,7 @@ describe Fortnox::API::Repository::Order, order: :defined, integration: true do
45
45
  end
46
46
  end
47
47
 
48
- include_examples '.search', :customername, 'A customer', 2
48
+ include_examples '.search', :customername, 'A customer', 3
49
49
 
50
- include_examples '.only', :cancelled, 3
50
+ include_examples '.only', :cancelled, 6
51
51
  end
@@ -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', 8
25
+ include_examples '.all', 33
26
26
 
27
27
  include_examples '.find', '1' do
28
28
  let(:find_by_hash_failure) { { offset: 10_000 } }
@@ -17,11 +17,13 @@ describe Fortnox::API::Repository::TermsOfPayment, order: :defined, integration:
17
17
 
18
18
  before { set_api_test_configuration }
19
19
 
20
- required_hash = { code: '15DAYS' }
20
+ # When recording new VCR cassettes, code must be changed to a new unique one
21
+ required_hash = { code: '19DAYS' }
21
22
 
22
23
  include_examples '.save', :description, additional_attrs: required_hash
23
24
 
24
- include_examples '.all', 9
25
+ # When recording new VCR cassettes, expected matches needs to be increased
26
+ include_examples '.all', 13
25
27
 
26
28
  include_examples '.find', '15DAYS', find_by_hash: false do
27
29
  let(:find_by_hash_failure) { { code: '15days' } }
@@ -16,16 +16,19 @@ describe Fortnox::API::Repository::Unit, order: :defined, integration: true do
16
16
 
17
17
  subject(:repository) { described_class.new }
18
18
 
19
+ # When recording new VCR cassettes, code needs to be changed to a unique value
19
20
  include_examples '.save',
20
21
  :description,
21
- additional_attrs: { code: 'blarg' }
22
+ additional_attrs: { code: 'blarg5' }
22
23
 
24
+ # When recording new VCR cassettes, code needs to be changed to a unique value
23
25
  include_examples '.save with specially named attribute',
24
26
  { description: 'Happy clouds' },
25
27
  :code,
26
- 'woooh'
28
+ 'woooh5'
27
29
 
28
- include_examples '.all', 6
30
+ # When recording new VCR cassettes, expected number must be updated
31
+ include_examples '.all', 14
29
32
 
30
33
  include_examples '.find', 'blarg', find_by_hash: false do
31
34
  let(:find_by_hash_failure) { { code: 'notfound' } }
@@ -7,25 +7,29 @@ require 'fortnox/api/types/examples/types'
7
7
  describe Fortnox::API::Types do
8
8
  let(:klass) { Fortnox::API::Types::AccountNumber }
9
9
 
10
- context 'when AccountNumber created with nil' do
11
- subject { klass[nil] }
10
+ describe 'AccountNumber' do
11
+ context 'when created with nil' do
12
+ subject { klass[nil] }
12
13
 
13
- it { is_expected.to be_nil }
14
- end
14
+ it { is_expected.to be_nil }
15
+ end
15
16
 
16
- context 'when AccountNumber created with empty string' do
17
- include_examples 'raises ConstraintError', ''
18
- end
17
+ context 'when created with empty string' do
18
+ subject { klass[''] }
19
19
 
20
- context 'when AccountNumber created with valid number' do
21
- include_examples 'equals input', 1234
22
- end
20
+ it { is_expected.to be_nil }
21
+ end
23
22
 
24
- context 'when AccountNumber created with a too large number' do
25
- include_examples 'raises ConstraintError', 10_000
26
- end
23
+ context 'when created with valid number' do
24
+ include_examples 'equals input', 1234
25
+ end
26
+
27
+ context 'when created with a too large number' do
28
+ include_examples 'raises ConstraintError', 10_000
29
+ end
27
30
 
28
- context 'when AccountNumber created with a negative number' do
29
- include_examples 'raises ConstraintError', -1
31
+ context 'when created with a negative number' do
32
+ include_examples 'raises ConstraintError', -1
33
+ end
30
34
  end
31
35
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'fortnox/api/types'
5
+
6
+ describe Fortnox::API::Types::CountryCode do
7
+ context 'with nil' do
8
+ subject { described_class[nil] }
9
+
10
+ it { is_expected.to be_nil }
11
+ end
12
+
13
+ context 'with empty string' do
14
+ subject { described_class[''] }
15
+
16
+ it { is_expected.to eq('') }
17
+ end
18
+
19
+ context 'with valid input' do
20
+ it 'accepts country codes' do
21
+ expect(described_class['NO']).to eq 'NO'
22
+ end
23
+ end
24
+
25
+ context 'with invalid input' do
26
+ describe 'valid country name' do
27
+ it do
28
+ expect do
29
+ described_class['Norway']
30
+ end.to raise_error(Dry::Types::ConstraintError)
31
+ end
32
+ end
33
+
34
+ describe 'invalid country code' do
35
+ it do
36
+ expect do
37
+ described_class['XX']
38
+ end.to raise_error(Dry::Types::ConstraintError)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'fortnox/api/types'
5
+
6
+ describe Fortnox::API::Types::Country do
7
+ context 'with nil' do
8
+ subject { described_class[nil] }
9
+
10
+ it { is_expected.to be_nil }
11
+ end
12
+
13
+ context 'with empty string' do
14
+ subject { described_class[''] }
15
+
16
+ it { is_expected.to eq('') }
17
+ end
18
+
19
+ context 'with valid input' do
20
+ it 'accepts country codes' do
21
+ expect(described_class['NO']).to eq 'NO'
22
+ end
23
+
24
+ it 'translates English country names to country code' do
25
+ expect(described_class['Norway']).to eq 'NO'
26
+ end
27
+
28
+ it 'translates Swedish country names to country code' do
29
+ expect(described_class['Norge']).to eq 'NO'
30
+ end
31
+
32
+ describe 'special cases' do
33
+ valid_sweden_inputs = [
34
+ 'SE', 'se', 'Sweden', 'sweden', 'Sverige', 'sverige',
35
+ :SE, :se, :Sweden, :sweden, :Sverige, :sverige
36
+ ].freeze
37
+
38
+ valid_sweden_inputs.each do |sweden_input|
39
+ it "converts \"#{sweden_input}\" to \"SE\"" do
40
+ expect(described_class[sweden_input]).to eq 'SE'
41
+ end
42
+ end
43
+
44
+ it 'accepts country code for El Salvador' do
45
+ expect(described_class['SV']).to eq 'SV'
46
+ end
47
+
48
+ it 'translated Switzerland to ' do
49
+ expect(described_class['Switzerland']).to eq 'CH'
50
+ end
51
+ end
52
+ end
53
+
54
+ context 'with invalid input' do
55
+ invalid_inputs = [
56
+ 'SEA', 'S', 'nonsense', :s
57
+ ].freeze
58
+
59
+ invalid_inputs.each do |invalid_input|
60
+ it "#{invalid_input} raises Dry::Types::ConstraintError" do
61
+ expect do
62
+ described_class[invalid_input]
63
+ end.to raise_error(Dry::Types::ConstraintError)
64
+ end
65
+ end
66
+ end
67
+ end