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.
- checksums.yaml +5 -5
- data/.rubocop.yml +5 -1
- data/.travis.yml +20 -22
- data/CHANGELOG.md +48 -0
- data/README.md +14 -19
- data/Rakefile +5 -0
- data/fortnox-api.gemspec +10 -10
- data/lib/fortnox/api/mappers.rb +5 -38
- data/lib/fortnox/api/mappers/base.rb +2 -24
- data/lib/fortnox/api/mappers/base/canonical_name_sym.rb +21 -0
- data/lib/fortnox/api/mappers/base/from_json.rb +6 -1
- data/lib/fortnox/api/mappers/value/array.rb +18 -0
- data/lib/fortnox/api/mappers/value/country_string.rb +24 -0
- data/lib/fortnox/api/mappers/value/date.rb +11 -0
- data/lib/fortnox/api/mappers/value/hash.rb +16 -0
- data/lib/fortnox/api/mappers/value/identity.rb +18 -0
- data/lib/fortnox/api/models/document.rb +6 -3
- data/lib/fortnox/api/models/invoice.rb +1 -1
- data/lib/fortnox/api/models/order.rb +1 -1
- data/lib/fortnox/api/repositories/base.rb +9 -11
- data/lib/fortnox/api/request_handling.rb +0 -1
- data/lib/fortnox/api/types.rb +40 -3
- data/lib/fortnox/api/types/enums.rb +36 -31
- data/lib/fortnox/api/types/shim/country_string.rb +10 -0
- data/lib/fortnox/api/version.rb +1 -1
- data/spec/fortnox/api/circular_queue_spec.rb +52 -0
- data/spec/fortnox/api/mappers/base/canonical_name_sym_spec.rb +34 -0
- data/spec/fortnox/api/mappers/base_spec.rb +33 -43
- data/spec/fortnox/api/mappers/contexts/json_conversion.rb +1 -1
- data/spec/fortnox/api/repositories/article_spec.rb +4 -2
- data/spec/fortnox/api/repositories/base_spec.rb +28 -8
- data/spec/fortnox/api/repositories/customer_spec.rb +29 -1
- data/spec/fortnox/api/repositories/invoice_spec.rb +147 -3
- data/spec/fortnox/api/repositories/order_spec.rb +2 -2
- data/spec/fortnox/api/repositories/project_spec.rb +1 -1
- data/spec/fortnox/api/repositories/terms_of_payment_spec.rb +4 -2
- data/spec/fortnox/api/repositories/unit_spec.rb +6 -3
- data/spec/fortnox/api/types/account_number_spec.rb +19 -15
- data/spec/fortnox/api/types/country_code_spec.rb +42 -0
- data/spec/fortnox/api/types/country_spec.rb +67 -0
- data/spec/fortnox/api/types/email_spec.rb +8 -7
- data/spec/fortnox/api/types/enums_spec.rb +1 -1
- data/spec/fortnox/api/types/examples/document_row.rb +1 -1
- data/spec/fortnox/api/types/housework_types_spec.rb +151 -34
- data/spec/fortnox/api_spec.rb +3 -1
- data/spec/vcr_cassettes/articles/all.yml +40 -10
- data/spec/vcr_cassettes/articles/find_by_hash_failure.yml +21 -8
- data/spec/vcr_cassettes/articles/find_failure.yml +21 -8
- data/spec/vcr_cassettes/articles/find_id_1.yml +22 -9
- data/spec/vcr_cassettes/articles/find_new.yml +24 -11
- data/spec/vcr_cassettes/articles/multi_param_find_by_hash.yml +21 -8
- data/spec/vcr_cassettes/articles/save_new.yml +22 -8
- data/spec/vcr_cassettes/articles/save_old.yml +24 -11
- data/spec/vcr_cassettes/articles/save_with_specially_named_attribute.yml +22 -8
- data/spec/vcr_cassettes/articles/search_by_name.yml +21 -8
- data/spec/vcr_cassettes/articles/search_miss.yml +21 -8
- data/spec/vcr_cassettes/articles/search_with_special_char.yml +21 -8
- data/spec/vcr_cassettes/articles/single_param_find_by_hash.yml +33 -10
- data/spec/vcr_cassettes/customers/all.yml +26 -13
- data/spec/vcr_cassettes/customers/find_by_hash_failure.yml +21 -8
- data/spec/vcr_cassettes/customers/find_failure.yml +21 -8
- data/spec/vcr_cassettes/customers/find_id_1.yml +22 -9
- data/spec/vcr_cassettes/customers/find_new.yml +24 -11
- data/spec/vcr_cassettes/customers/multi_param_find_by_hash.yml +21 -8
- data/spec/vcr_cassettes/customers/save_new.yml +21 -7
- data/spec/vcr_cassettes/customers/save_new_with_country_code_SE.yml +60 -0
- data/spec/vcr_cassettes/customers/save_old.yml +23 -10
- data/spec/vcr_cassettes/customers/save_with_specially_named_attribute.yml +21 -7
- data/spec/vcr_cassettes/customers/search_by_name.yml +32 -10
- data/spec/vcr_cassettes/customers/search_miss.yml +21 -8
- data/spec/vcr_cassettes/customers/search_with_special_char.yml +21 -8
- data/spec/vcr_cassettes/customers/single_param_find_by_hash.yml +22 -9
- data/spec/vcr_cassettes/invoices/all.yml +118 -67
- data/spec/vcr_cassettes/invoices/filter_hit.yml +26 -10
- data/spec/vcr_cassettes/invoices/filter_invalid.yml +20 -6
- data/spec/vcr_cassettes/invoices/find_by_hash_failure.yml +21 -8
- data/spec/vcr_cassettes/invoices/find_failure.yml +21 -8
- data/spec/vcr_cassettes/invoices/find_id_1.yml +23 -10
- data/spec/vcr_cassettes/invoices/find_new.yml +26 -14
- data/spec/vcr_cassettes/invoices/multi_param_find_by_hash.yml +23 -10
- data/spec/vcr_cassettes/invoices/save_new.yml +23 -10
- data/spec/vcr_cassettes/invoices/save_new_with_comments.yml +61 -0
- data/spec/vcr_cassettes/invoices/save_new_with_country.yml +60 -0
- data/spec/vcr_cassettes/invoices/save_new_with_country_GB.yml +61 -0
- data/spec/vcr_cassettes/invoices/save_new_with_country_KR.yml +61 -0
- data/spec/vcr_cassettes/invoices/save_new_with_country_Norge.yml +60 -0
- data/spec/vcr_cassettes/invoices/save_new_with_country_Norway.yml +60 -0
- data/spec/vcr_cassettes/invoices/save_new_with_country_Sverige.yml +60 -0
- data/spec/vcr_cassettes/invoices/save_new_with_country_VA.yml +61 -0
- data/spec/vcr_cassettes/invoices/save_new_with_country_VI.yml +61 -0
- data/spec/vcr_cassettes/invoices/save_new_with_country_empty_string.yml +60 -0
- data/spec/vcr_cassettes/invoices/save_new_with_country_nil.yml +60 -0
- data/spec/vcr_cassettes/invoices/save_old.yml +25 -13
- data/spec/vcr_cassettes/invoices/save_old_with_empty_comments.yml +61 -0
- data/spec/vcr_cassettes/invoices/save_old_with_empty_country.yml +60 -0
- data/spec/vcr_cassettes/invoices/save_old_with_nil_comments.yml +61 -0
- data/spec/vcr_cassettes/invoices/save_old_with_nil_country.yml +60 -0
- data/spec/vcr_cassettes/invoices/save_with_nested_model.yml +23 -10
- data/spec/vcr_cassettes/invoices/save_with_specially_named_attribute.yml +23 -10
- data/spec/vcr_cassettes/invoices/search_by_name.yml +28 -11
- data/spec/vcr_cassettes/invoices/search_miss.yml +21 -8
- data/spec/vcr_cassettes/invoices/search_with_special_char.yml +21 -8
- data/spec/vcr_cassettes/invoices/single_param_find_by_hash.yml +24 -11
- data/spec/vcr_cassettes/orders/all.yml +120 -107
- data/spec/vcr_cassettes/orders/filter_hit.yml +28 -12
- data/spec/vcr_cassettes/orders/filter_invalid.yml +20 -6
- data/spec/vcr_cassettes/orders/find_by_hash_failure.yml +21 -8
- data/spec/vcr_cassettes/orders/find_failure.yml +21 -8
- data/spec/vcr_cassettes/orders/find_id_1.yml +23 -10
- data/spec/vcr_cassettes/orders/find_new.yml +26 -14
- data/spec/vcr_cassettes/orders/housework_invalid_tax_reduction_type.yml +57 -0
- data/spec/vcr_cassettes/orders/housework_othercoses_invalid.yml +57 -0
- data/spec/vcr_cassettes/orders/housework_type_babysitting.yml +24 -10
- data/spec/vcr_cassettes/orders/housework_type_cleaning.yml +24 -10
- data/spec/vcr_cassettes/orders/housework_type_construction.yml +24 -10
- data/spec/vcr_cassettes/orders/housework_type_cooking.yml +21 -7
- data/spec/vcr_cassettes/orders/housework_type_electricity.yml +24 -10
- data/spec/vcr_cassettes/orders/housework_type_gardening.yml +24 -10
- data/spec/vcr_cassettes/orders/housework_type_glassmetalwork.yml +24 -10
- data/spec/vcr_cassettes/orders/housework_type_grounddrainagework.yml +24 -10
- data/spec/vcr_cassettes/orders/housework_type_hvac.yml +24 -10
- data/spec/vcr_cassettes/orders/housework_type_itservices.yml +60 -0
- data/spec/vcr_cassettes/orders/housework_type_majorappliancerepair.yml +60 -0
- data/spec/vcr_cassettes/orders/housework_type_masonry.yml +24 -10
- data/spec/vcr_cassettes/orders/housework_type_movingservices.yml +60 -0
- data/spec/vcr_cassettes/orders/housework_type_othercare.yml +24 -10
- data/spec/vcr_cassettes/orders/housework_type_othercosts.yml +24 -10
- data/spec/vcr_cassettes/orders/housework_type_paintingwallpapering.yml +24 -10
- data/spec/vcr_cassettes/orders/housework_type_snowplowing.yml +24 -10
- data/spec/vcr_cassettes/orders/housework_type_textileclothing.yml +24 -10
- data/spec/vcr_cassettes/orders/housework_type_tutoring.yml +21 -7
- data/spec/vcr_cassettes/orders/housework_without_tax_reduction_type.yml +57 -0
- data/spec/vcr_cassettes/orders/multi_param_find_by_hash.yml +22 -9
- data/spec/vcr_cassettes/orders/save_new.yml +23 -10
- data/spec/vcr_cassettes/orders/save_old.yml +25 -13
- data/spec/vcr_cassettes/orders/save_with_nested_model.yml +23 -10
- data/spec/vcr_cassettes/orders/search_by_name.yml +25 -11
- data/spec/vcr_cassettes/orders/search_miss.yml +21 -8
- data/spec/vcr_cassettes/orders/search_with_special_char.yml +21 -8
- data/spec/vcr_cassettes/orders/single_param_find_by_hash.yml +23 -10
- data/spec/vcr_cassettes/projects/all.yml +41 -16
- data/spec/vcr_cassettes/projects/find_by_hash_failure.yml +21 -8
- data/spec/vcr_cassettes/projects/find_failure.yml +21 -8
- data/spec/vcr_cassettes/projects/find_id_1.yml +21 -8
- data/spec/vcr_cassettes/projects/find_new.yml +24 -11
- data/spec/vcr_cassettes/projects/multi_param_find_by_hash.yml +23 -10
- data/spec/vcr_cassettes/projects/save_new.yml +22 -8
- data/spec/vcr_cassettes/projects/save_old.yml +24 -11
- data/spec/vcr_cassettes/projects/single_param_find_by_hash.yml +22 -9
- data/spec/vcr_cassettes/termsofpayments/all.yml +31 -14
- data/spec/vcr_cassettes/termsofpayments/find_failure.yml +21 -8
- data/spec/vcr_cassettes/termsofpayments/find_id_1.yml +22 -9
- data/spec/vcr_cassettes/termsofpayments/find_new.yml +23 -10
- data/spec/vcr_cassettes/termsofpayments/save_new.yml +22 -8
- data/spec/vcr_cassettes/termsofpayments/save_old.yml +23 -10
- data/spec/vcr_cassettes/units/all.yml +31 -12
- data/spec/vcr_cassettes/units/find_failure.yml +21 -8
- data/spec/vcr_cassettes/units/find_id_1.yml +21 -8
- data/spec/vcr_cassettes/units/find_new.yml +23 -12
- data/spec/vcr_cassettes/units/save_new.yml +22 -10
- data/spec/vcr_cassettes/units/save_old.yml +23 -12
- data/spec/vcr_cassettes/units/save_with_specially_named_attribute.yml +22 -10
- data/temp.txt +1 -0
- metadata +99 -21
- 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'].
|
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
|
-
|
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:
|
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
|
9
|
+
class RepositoryBaseTest
|
10
10
|
end
|
11
11
|
end
|
12
12
|
module Repository
|
13
13
|
class Test < Fortnox::API::Repository::Base
|
14
|
-
MODEL = Model::
|
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
|
-
|
19
|
-
|
20
|
-
|
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 { -> {
|
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
|
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
|
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
|
-
|
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',
|
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',
|
54
|
+
include_examples '.search', :customername, 'Test', 7
|
55
55
|
|
56
|
-
include_examples '.only', :fullypaid,
|
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',
|
48
|
+
include_examples '.search', :customername, 'A customer', 3
|
49
49
|
|
50
|
-
include_examples '.only', :cancelled,
|
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',
|
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
|
-
|
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
|
-
|
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: '
|
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
|
-
'
|
28
|
+
'woooh5'
|
27
29
|
|
28
|
-
|
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
|
-
|
11
|
-
|
10
|
+
describe 'AccountNumber' do
|
11
|
+
context 'when created with nil' do
|
12
|
+
subject { klass[nil] }
|
12
13
|
|
13
|
-
|
14
|
-
|
14
|
+
it { is_expected.to be_nil }
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
end
|
17
|
+
context 'when created with empty string' do
|
18
|
+
subject { klass[''] }
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
end
|
20
|
+
it { is_expected.to be_nil }
|
21
|
+
end
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
29
|
-
|
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
|