fortnox-api 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +3 -2
- data/.env.test +3 -0
- data/.rubocop.yml +32 -23
- data/.travis.yml +3 -2
- data/Guardfile +2 -2
- data/LICENSE.txt +165 -22
- data/README.md +56 -37
- data/fortnox-api.gemspec +9 -6
- data/lib/fortnox/api.rb +18 -2
- data/lib/fortnox/api/base.rb +5 -3
- data/lib/fortnox/api/environment_validation.rb +51 -6
- data/lib/fortnox/api/mappers.rb +49 -0
- data/lib/fortnox/api/mappers/base.rb +47 -0
- data/lib/fortnox/api/mappers/base/from_json.rb +78 -0
- data/lib/fortnox/api/mappers/base/to_json.rb +65 -0
- data/lib/fortnox/api/mappers/customer.rb +27 -0
- data/lib/fortnox/api/mappers/default_delivery_types.rb +13 -0
- data/lib/fortnox/api/mappers/default_templates.rb +15 -0
- data/lib/fortnox/api/mappers/edi_information.rb +22 -0
- data/lib/fortnox/api/mappers/email_information.rb +18 -0
- data/lib/fortnox/api/mappers/invoice.rb +27 -0
- data/lib/fortnox/api/mappers/invoice_row.rb +20 -0
- data/lib/fortnox/api/mappers/order.rb +23 -0
- data/lib/fortnox/api/mappers/order_row.rb +16 -0
- data/lib/fortnox/api/models.rb +2 -0
- data/lib/fortnox/api/models/base.rb +56 -13
- data/lib/fortnox/api/models/customer.rb +112 -101
- data/lib/fortnox/api/models/document_base.rb +189 -0
- data/lib/fortnox/api/models/invoice.rb +29 -195
- data/lib/fortnox/api/models/label.rb +17 -0
- data/lib/fortnox/api/models/order.rb +27 -0
- data/lib/fortnox/api/repositories.rb +2 -0
- data/lib/fortnox/api/repositories/base.rb +4 -5
- data/lib/fortnox/api/repositories/base/loaders.rb +22 -14
- data/lib/fortnox/api/repositories/base/savers.rb +30 -16
- data/lib/fortnox/api/repositories/customer.rb +3 -25
- data/lib/fortnox/api/repositories/invoice.rb +3 -22
- data/lib/fortnox/api/repositories/order.rb +16 -0
- data/lib/fortnox/api/request_handling.rb +3 -3
- data/lib/fortnox/api/types.rb +44 -0
- data/lib/fortnox/api/types/default_delivery_types.rb +20 -0
- data/lib/fortnox/api/types/default_templates.rb +23 -0
- data/lib/fortnox/api/types/defaulted.rb +11 -0
- data/lib/fortnox/api/types/document_row.rb +65 -0
- data/lib/fortnox/api/types/edi_information.rb +29 -0
- data/lib/fortnox/api/types/email_information.rb +26 -0
- data/lib/fortnox/api/types/enums.rb +75 -0
- data/lib/fortnox/api/types/invoice_row.rb +19 -0
- data/lib/fortnox/api/types/model.rb +40 -0
- data/lib/fortnox/api/types/nullable.rb +21 -0
- data/lib/fortnox/api/types/order_row.rb +16 -0
- data/lib/fortnox/api/types/required.rb +13 -0
- data/lib/fortnox/api/types/sized.rb +25 -0
- data/lib/fortnox/api/version.rb +1 -1
- data/spec/fortnox/api/base_spec.rb +85 -14
- data/spec/fortnox/api/mappers/base/from_json_spec.rb +70 -0
- data/spec/fortnox/api/mappers/base/to_json_spec.rb +76 -0
- data/spec/fortnox/api/mappers/base_spec.rb +156 -0
- data/spec/fortnox/api/mappers/contexts/json_conversion.rb +56 -0
- data/spec/fortnox/api/mappers/customer_spec.rb +25 -0
- data/spec/fortnox/api/mappers/default_delivery_types_spec.rb +12 -0
- data/spec/fortnox/api/mappers/edi_information_spec.rb +21 -0
- data/spec/fortnox/api/mappers/email_information_spec.rb +17 -0
- data/spec/fortnox/api/mappers/examples/mapper.rb +26 -0
- data/spec/fortnox/api/mappers/invoice_row_spec.rb +19 -0
- data/spec/fortnox/api/mappers/invoice_spec.rb +24 -0
- data/spec/fortnox/api/mappers/order_row_spec.rb +14 -0
- data/spec/fortnox/api/mappers/order_spec.rb +20 -0
- data/spec/fortnox/api/models/base_spec.rb +44 -22
- data/spec/fortnox/api/models/customer_spec.rb +9 -0
- data/spec/fortnox/api/models/examples/document_base.rb +13 -0
- data/spec/fortnox/api/models/examples/model.rb +13 -0
- data/spec/fortnox/api/models/invoice_spec.rb +7 -31
- data/spec/fortnox/api/models/order_spec.rb +13 -0
- data/spec/fortnox/api/repositories/customer_spec.rb +20 -76
- data/spec/fortnox/api/repositories/examples/all.rb +17 -0
- data/spec/fortnox/api/repositories/examples/find.rb +25 -0
- data/spec/fortnox/api/repositories/examples/only.rb +42 -0
- data/spec/fortnox/api/repositories/examples/save.rb +69 -0
- data/spec/fortnox/api/repositories/examples/save_with_nested_model.rb +32 -0
- data/spec/fortnox/api/repositories/examples/save_with_specially_named_attribute.rb +27 -0
- data/spec/fortnox/api/repositories/examples/search.rb +31 -0
- data/spec/fortnox/api/repositories/invoice_spec.rb +36 -5
- data/spec/fortnox/api/repositories/order_spec.rb +35 -0
- data/spec/fortnox/api/types/account_number_spec.rb +28 -0
- data/spec/fortnox/api/types/default_delivery_types_spec.rb +10 -0
- data/spec/fortnox/api/types/edi_information_spec.rb +13 -0
- data/spec/fortnox/api/types/email_information_spec.rb +13 -0
- data/spec/fortnox/api/types/email_spec.rb +29 -0
- data/spec/fortnox/api/types/enums_spec.rb +13 -0
- data/spec/fortnox/api/types/examples/document_row.rb +15 -0
- data/spec/fortnox/api/types/examples/enum.rb +48 -0
- data/spec/fortnox/api/types/examples/types.rb +9 -0
- data/spec/fortnox/api/types/house_work_types_spec.rb +60 -0
- data/spec/fortnox/api/types/invoice_row_spec.rb +9 -0
- data/spec/fortnox/api/types/model_spec.rb +56 -0
- data/spec/fortnox/api/types/nullable_spec.rb +57 -0
- data/spec/fortnox/api/types/order_row_spec.rb +13 -0
- data/spec/fortnox/api/types/required_spec.rb +42 -0
- data/spec/fortnox/api/types/sized_spec.rb +74 -0
- data/spec/fortnox/api_spec.rb +16 -15
- data/spec/spec_helper.rb +19 -9
- data/spec/support/helpers/dummy_class_helper.rb +19 -0
- data/spec/support/helpers/environment_helper.rb +7 -0
- data/spec/support/helpers/repository_helper.rb +8 -0
- data/spec/support/helpers/when_performing_helper.rb +5 -0
- data/spec/support/matchers.rb +1 -1
- data/spec/support/matchers/type.rb +17 -0
- data/spec/support/matchers/type/attribute_matcher.rb +39 -0
- data/spec/support/matchers/type/enum_matcher.rb +21 -0
- data/spec/support/matchers/type/have_account_number_matcher.rb +21 -0
- data/spec/support/matchers/type/have_country_code_matcher.rb +13 -0
- data/spec/support/matchers/type/have_currency_matcher.rb +7 -0
- data/spec/support/matchers/type/have_customer_type_matcher.rb +13 -0
- data/spec/support/matchers/type/have_default_delivery_type_matcher.rb +7 -0
- data/spec/support/matchers/type/have_discount_type_matcher.rb +7 -0
- data/spec/support/matchers/type/have_email_matcher.rb +22 -0
- data/spec/support/matchers/type/have_house_work_type_matcher.rb +7 -0
- data/spec/support/matchers/type/have_nullable_date_matcher.rb +58 -0
- data/spec/support/matchers/type/have_nullable_matcher.rb +52 -0
- data/spec/support/matchers/type/have_nullable_string_matcher.rb +49 -0
- data/spec/support/matchers/type/have_sized_float_matcher.rb +8 -0
- data/spec/support/matchers/type/have_sized_integer_matcher.rb +8 -0
- data/spec/support/matchers/type/have_sized_string_matcher.rb +35 -0
- data/spec/support/matchers/type/have_vat_type_matcher.rb +7 -0
- data/spec/support/matchers/type/numeric_matcher.rb +50 -0
- data/spec/support/matchers/type/require_attribute_matcher.rb +69 -0
- data/spec/support/matchers/type/type_matcher.rb +38 -0
- data/spec/vcr_cassettes/customers/all.yml +119 -9
- data/spec/vcr_cassettes/customers/find_id_1.yml +8 -9
- data/spec/vcr_cassettes/customers/find_new.yml +46 -0
- data/spec/vcr_cassettes/customers/save_new.yml +9 -11
- data/spec/vcr_cassettes/customers/save_old.yml +9 -12
- data/spec/vcr_cassettes/customers/save_with_specially_named_attribute.yml +45 -0
- data/spec/vcr_cassettes/customers/search_by_name.yml +66 -0
- data/spec/vcr_cassettes/customers/search_miss.yml +45 -0
- data/spec/vcr_cassettes/invoices/all.yml +104 -0
- data/spec/vcr_cassettes/invoices/filter_hit.yml +46 -0
- data/spec/vcr_cassettes/invoices/filter_invalid.yml +42 -0
- data/spec/vcr_cassettes/invoices/find_id_1.yml +47 -0
- data/spec/vcr_cassettes/invoices/find_new.yml +49 -0
- data/spec/vcr_cassettes/invoices/save_new.yml +48 -0
- data/spec/vcr_cassettes/invoices/save_old.yml +49 -0
- data/spec/vcr_cassettes/invoices/save_with_nested_model.yml +47 -0
- data/spec/vcr_cassettes/invoices/save_with_specially_named_attribute.yml +47 -0
- data/spec/vcr_cassettes/invoices/search_by_name.yml +48 -0
- data/spec/vcr_cassettes/invoices/search_miss.yml +45 -0
- data/spec/vcr_cassettes/orders/all.yml +144 -0
- data/spec/vcr_cassettes/orders/filter_hit.yml +48 -0
- data/spec/vcr_cassettes/orders/filter_invalid.yml +42 -0
- data/spec/vcr_cassettes/orders/find_id_1.yml +48 -0
- data/spec/vcr_cassettes/orders/find_new.yml +49 -0
- data/spec/vcr_cassettes/orders/house_work_type_babysitting.yml +47 -0
- data/spec/vcr_cassettes/orders/house_work_type_cleaning.yml +47 -0
- data/spec/vcr_cassettes/orders/house_work_type_construction.yml +47 -0
- data/spec/vcr_cassettes/orders/house_work_type_cooking.yml +43 -0
- data/spec/vcr_cassettes/orders/house_work_type_electricity.yml +47 -0
- data/spec/vcr_cassettes/orders/house_work_type_gardening.yml +47 -0
- data/spec/vcr_cassettes/orders/house_work_type_glassmetalwork.yml +47 -0
- data/spec/vcr_cassettes/orders/house_work_type_grounddrainagework.yml +47 -0
- data/spec/vcr_cassettes/orders/house_work_type_hvac.yml +47 -0
- data/spec/vcr_cassettes/orders/house_work_type_masonry.yml +47 -0
- data/spec/vcr_cassettes/orders/house_work_type_othercare.yml +47 -0
- data/spec/vcr_cassettes/orders/house_work_type_othercosts.yml +47 -0
- data/spec/vcr_cassettes/orders/house_work_type_paintingwallpapering.yml +47 -0
- data/spec/vcr_cassettes/orders/house_work_type_snowplowing.yml +47 -0
- data/spec/vcr_cassettes/orders/house_work_type_textileclothing.yml +47 -0
- data/spec/vcr_cassettes/orders/house_work_type_tutoring.yml +43 -0
- data/spec/vcr_cassettes/orders/save_new.yml +48 -0
- data/spec/vcr_cassettes/orders/save_old.yml +49 -0
- data/spec/vcr_cassettes/orders/save_with_nested_model.yml +47 -0
- data/spec/vcr_cassettes/orders/search_by_name.yml +47 -0
- data/spec/vcr_cassettes/orders/search_miss.yml +45 -0
- metadata +301 -71
- data/lib/fortnox/api/models/attributes/country_code.rb +0 -17
- data/lib/fortnox/api/models/attributes/currency.rb +0 -17
- data/lib/fortnox/api/models/edi_information.rb +0 -28
- data/lib/fortnox/api/models/email_information.rb +0 -25
- data/lib/fortnox/api/models/row.rb +0 -82
- data/lib/fortnox/api/repositories/base/json_convertion.rb +0 -68
- data/lib/fortnox/api/repositories/base/options.rb +0 -33
- data/lib/fortnox/api/validators.rb +0 -1
- data/lib/fortnox/api/validators/attributes/country_code.rb +0 -42
- data/lib/fortnox/api/validators/attributes/currency.rb +0 -38
- data/lib/fortnox/api/validators/base.rb +0 -70
- data/lib/fortnox/api/validators/constant.rb +0 -21
- data/lib/fortnox/api/validators/customer.rb +0 -29
- data/lib/fortnox/api/validators/edi_information.rb +0 -11
- data/lib/fortnox/api/validators/email_information.rb +0 -19
- data/lib/fortnox/api/validators/invoice.rb +0 -33
- data/lib/fortnox/api/validators/row.rb +0 -22
- data/spec/fortnox/api/models/attributes/country_code_spec.rb +0 -23
- data/spec/fortnox/api/models/attributes/currency_spec.rb +0 -23
- data/spec/fortnox/api/models/attributes/dummy_model_context.rb +0 -9
- data/spec/fortnox/api/models/row_spec.rb +0 -13
- data/spec/fortnox/api/repositories/context.rb +0 -10
- data/spec/fortnox/api/repositories/examples.rb +0 -16
- data/spec/fortnox/api/validators/attributes/country_code_spec.rb +0 -9
- data/spec/fortnox/api/validators/attributes/currency_spec.rb +0 -9
- data/spec/fortnox/api/validators/attributes/examples_for_validate.rb +0 -29
- data/spec/fortnox/api/validators/base_spec.rb +0 -61
- data/spec/fortnox/api/validators/constant_spec.rb +0 -12
- data/spec/fortnox/api/validators/context.rb +0 -102
- data/spec/fortnox/api/validators/customer_spec.rb +0 -31
- data/spec/fortnox/api/validators/edi_information_spec.rb +0 -18
- data/spec/fortnox/api/validators/email_information_spec.rb +0 -26
- data/spec/fortnox/api/validators/invoice_spec.rb +0 -36
- data/spec/fortnox/api/validators/row_spec.rb +0 -27
- data/spec/fortnox/api/validators/validator_examples.rb +0 -20
- data/spec/support/matchers/models.rb +0 -27
- data/spec/support/matchers/validators.rb +0 -36
@@ -0,0 +1,32 @@
|
|
1
|
+
# TODO: This will not work until we solve issue #62.
|
2
|
+
# Until then, these tests are pending.
|
3
|
+
# rubocop:disable RSpec/DescribeClass
|
4
|
+
shared_examples_for '.save with nested model' do |required_hash, nested_model_key, nested_model_hash, nested_entity|
|
5
|
+
describe '.save with nested model' do
|
6
|
+
let( :repository ){ described_class.new }
|
7
|
+
let( :new_hash ) do
|
8
|
+
required_hash.merge( nested_model_key => nested_entity )
|
9
|
+
end
|
10
|
+
let( :response ) do
|
11
|
+
VCR.use_cassette( "#{ vcr_dir }/save_with_nested_model" ) do
|
12
|
+
model = described_class::MODEL.new( new_hash )
|
13
|
+
repository.save( model )
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'does not raise any errors' do
|
18
|
+
expect{ response }.not_to raise_error
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'returned entity\'s nested model' do
|
22
|
+
subject(:returned_nested_model){ response.send(nested_model_key).first }
|
23
|
+
|
24
|
+
it 'has the wanted attributes' do
|
25
|
+
nested_model_hash.each do |attribute, value|
|
26
|
+
expect(returned_nested_model.send(attribute)).to eq(value)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
# rubocop:enable RSpec/DescribeClass
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# rubocop:disable RSpec/DescribeClass
|
2
|
+
# Test saving model with attributes that has specially names that needs to be mapped.
|
3
|
+
#
|
4
|
+
# NOTE: VCR cassette must be discarded when repositories are updated to reflect
|
5
|
+
# the changes!
|
6
|
+
shared_examples_for '.save with specially named attribute' do |required_hash, attribute, value|
|
7
|
+
describe '.save' do
|
8
|
+
context 'with specially named attribute' do
|
9
|
+
subject{ ->{ save_model } }
|
10
|
+
|
11
|
+
let( :new_model ){ described_class::MODEL.new( required_hash.merge(attribute => value) ) }
|
12
|
+
let( :save_model )do
|
13
|
+
VCR.use_cassette( "#{ vcr_dir }/save_with_specially_named_attribute" ) do
|
14
|
+
repository.save( new_model )
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it{ is_expected.not_to raise_error }
|
19
|
+
|
20
|
+
describe 'response' do
|
21
|
+
subject{ save_model.send(attribute) }
|
22
|
+
it{ is_expected.to eq(value) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
# rubocop:enable RSpec/DescribeClass
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# rubocop:disable RSpec/DescribeClass
|
2
|
+
shared_examples_for '.search' do |attribute_hash_key_name, value, matches|
|
3
|
+
describe '.search' do
|
4
|
+
|
5
|
+
describe 'search' do
|
6
|
+
context "with no matches" do
|
7
|
+
subject do
|
8
|
+
VCR.use_cassette( "#{ vcr_dir }/search_miss" ) do
|
9
|
+
repository.search( attribute_hash_key_name => 'nothing' )
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
it{ is_expected.to be_instance_of( Array ) }
|
14
|
+
it{ is_expected.to have(0).entries }
|
15
|
+
end
|
16
|
+
|
17
|
+
context "with #{ matches } match(es)" do
|
18
|
+
subject do
|
19
|
+
VCR.use_cassette( "#{ vcr_dir }/search_by_name" ) do
|
20
|
+
repository.search( attribute_hash_key_name => value )
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it{ is_expected.to be_instance_of( Array) }
|
25
|
+
it{ is_expected.to have(matches).entries }
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
# rubocop:enable RSpec/DescribeClass
|
@@ -1,10 +1,41 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'fortnox/api
|
2
|
+
require 'fortnox/api'
|
3
|
+
require 'fortnox/api/mappers'
|
3
4
|
require 'fortnox/api/repositories/invoice'
|
4
|
-
require 'fortnox/api/
|
5
|
+
require 'fortnox/api/repositories/examples/all'
|
6
|
+
require 'fortnox/api/repositories/examples/find'
|
7
|
+
require 'fortnox/api/repositories/examples/search'
|
8
|
+
require 'fortnox/api/repositories/examples/save'
|
9
|
+
require 'fortnox/api/repositories/examples/save_with_nested_model'
|
10
|
+
require 'fortnox/api/repositories/examples/save_with_specially_named_attribute'
|
11
|
+
require 'fortnox/api/repositories/examples/only'
|
5
12
|
|
6
|
-
describe Fortnox::API::Repository::Invoice do
|
7
|
-
|
13
|
+
describe Fortnox::API::Repository::Invoice, order: :defined, integration: true do
|
14
|
+
subject(:repository){ described_class.new }
|
8
15
|
|
9
|
-
|
16
|
+
required_hash = { customer_number: '1' }
|
17
|
+
|
18
|
+
include_examples '.save', :comments, required_hash
|
19
|
+
|
20
|
+
nested_model_hash = { price: 10, article_number: '0000' }
|
21
|
+
include_examples '.save with nested model',
|
22
|
+
required_hash,
|
23
|
+
:invoice_rows,
|
24
|
+
nested_model_hash,
|
25
|
+
[ Fortnox::API::Types::InvoiceRow.new( nested_model_hash ) ]
|
26
|
+
|
27
|
+
include_examples '.save with specially named attribute',
|
28
|
+
required_hash,
|
29
|
+
:ocr,
|
30
|
+
'426523791'
|
31
|
+
|
32
|
+
# It is not possible to delete Invoces. Therefore, expected nr of Orders
|
33
|
+
# when running .all will continue to increase (until 100, which is max by default).
|
34
|
+
include_examples '.all', 60
|
35
|
+
|
36
|
+
include_examples '.find', 1
|
37
|
+
|
38
|
+
include_examples '.search', :customername, 'Test', 3
|
39
|
+
|
40
|
+
include_examples '.only', :fullypaid, 1
|
10
41
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fortnox/api'
|
3
|
+
require 'fortnox/api/mappers'
|
4
|
+
require 'fortnox/api/repositories/order'
|
5
|
+
require 'fortnox/api/repositories/examples/all'
|
6
|
+
require 'fortnox/api/repositories/examples/find'
|
7
|
+
require 'fortnox/api/repositories/examples/only'
|
8
|
+
require 'fortnox/api/repositories/examples/save'
|
9
|
+
require 'fortnox/api/repositories/examples/save_with_nested_model'
|
10
|
+
require 'fortnox/api/repositories/examples/search'
|
11
|
+
|
12
|
+
describe Fortnox::API::Repository::Order, order: :defined, integration: true do
|
13
|
+
subject(:repository){ described_class.new }
|
14
|
+
|
15
|
+
required_hash = { customer_number: '1' }
|
16
|
+
|
17
|
+
include_examples '.save', :comments, required_hash
|
18
|
+
|
19
|
+
nested_model_hash = { price: 10, article_number: '0000', ordered_quantity: 1 }
|
20
|
+
include_examples '.save with nested model',
|
21
|
+
required_hash,
|
22
|
+
:order_rows,
|
23
|
+
nested_model_hash,
|
24
|
+
[ Fortnox::API::Types::OrderRow.new( nested_model_hash ) ]
|
25
|
+
|
26
|
+
# It is not possible to delete Orders. Therefore, expected nr of Orders
|
27
|
+
# when running .all will continue to increase (until 100, which is max by default).
|
28
|
+
include_examples '.all', 100
|
29
|
+
|
30
|
+
include_examples '.find', 1
|
31
|
+
|
32
|
+
include_examples '.search', :customername, 'A customer', 2
|
33
|
+
|
34
|
+
include_examples '.only', :cancelled, 3
|
35
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fortnox/api/types'
|
3
|
+
require 'fortnox/api/types/examples/types'
|
4
|
+
|
5
|
+
describe Fortnox::API::Types do
|
6
|
+
let( :klass ){ Fortnox::API::Types::AccountNumber }
|
7
|
+
|
8
|
+
context 'AccountNumber created with nil' do
|
9
|
+
subject{ klass[ nil ] }
|
10
|
+
it{ is_expected.to be_nil }
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'AccountNumber created with empty string' do
|
14
|
+
include_examples 'raises ConstraintError', ''
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'AccountNumber created with valid number' do
|
18
|
+
include_examples 'equals input', 1234
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'AccountNumber created with a too large number' do
|
22
|
+
include_examples 'raises ConstraintError', 10000
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'AccountNumber created with a negative number' do
|
26
|
+
include_examples 'raises ConstraintError', -1
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fortnox/api/types/default_delivery_types'
|
3
|
+
|
4
|
+
RSpec.describe Fortnox::API::Types::DefaultDeliveryTypes, type: :type do
|
5
|
+
subject{ described_class }
|
6
|
+
|
7
|
+
it{ is_expected.to have_default_delivery_type( :invoice ) }
|
8
|
+
it{ is_expected.to have_default_delivery_type( :order ) }
|
9
|
+
it{ is_expected.to have_default_delivery_type( :offer ) }
|
10
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fortnox/api/types/edi_information'
|
3
|
+
|
4
|
+
RSpec.describe Fortnox::API::Types::EDIInformation, type: :type do
|
5
|
+
subject{ described_class }
|
6
|
+
|
7
|
+
it{ is_expected.to have_nullable_string( :edi_global_location_number ) }
|
8
|
+
it{ is_expected.to have_nullable_string( :edi_global_location_number_delivery ) }
|
9
|
+
it{ is_expected.to have_nullable_string( :edi_invoice_extra1 ) }
|
10
|
+
it{ is_expected.to have_nullable_string( :edi_invoice_extra2 ) }
|
11
|
+
it{ is_expected.to have_nullable_string( :edi_our_electronic_reference ) }
|
12
|
+
it{ is_expected.to have_nullable_string( :edi_your_electronic_reference ) }
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fortnox/api/types/email_information'
|
3
|
+
|
4
|
+
RSpec.describe Fortnox::API::Types::EmailInformation, type: :type do
|
5
|
+
subject{ described_class }
|
6
|
+
|
7
|
+
it{ is_expected.to have_email( :email_address_to ) }
|
8
|
+
it{ is_expected.to have_email( :email_address_cc ) }
|
9
|
+
it{ is_expected.to have_email( :email_address_bcc ) }
|
10
|
+
|
11
|
+
it{ is_expected.to have_sized_string( :email_subject, 100 ) }
|
12
|
+
it{ is_expected.to have_sized_string( :email_body, 20000 ) }
|
13
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fortnox/api/types'
|
3
|
+
require 'fortnox/api/types/examples/types'
|
4
|
+
|
5
|
+
describe Fortnox::API::Types do
|
6
|
+
let( :klass ){ Fortnox::API::Types::Email }
|
7
|
+
|
8
|
+
context 'Email created with nil' do
|
9
|
+
subject{ klass[ nil ] }
|
10
|
+
it{ is_expected.to be_nil }
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'Email created with empty string' do
|
14
|
+
subject{ klass[ '' ] }
|
15
|
+
it{ is_expected.to eq('') }
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'Email created with valid email' do
|
19
|
+
subject{ klass[ input ] }
|
20
|
+
let( :input ){ 'test@example.com' }
|
21
|
+
it{ is_expected.to eq input }
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'Email created with more than 1024 characters' do
|
25
|
+
legal_characters = 'abcdefghijklmnopqrstuvwxyz-_+'.split('')
|
26
|
+
too_long_email = (legal_characters * 35).shuffle.join + '@example.com'
|
27
|
+
include_examples 'raises ConstraintError', too_long_email
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fortnox/api/types'
|
3
|
+
require 'fortnox/api/types/examples/enum'
|
4
|
+
|
5
|
+
describe Fortnox::API::Types do
|
6
|
+
it_behaves_like 'enum', 'CountryCode', 'CountryCodes', auto_crop: true
|
7
|
+
it_behaves_like 'enum', 'Currency', 'Currencies', auto_crop: true
|
8
|
+
it_behaves_like 'enum', 'CustomerType', 'CustomerTypes'
|
9
|
+
it_behaves_like 'enum', 'DiscountType', 'DiscountTypes'
|
10
|
+
it_behaves_like 'enum', 'HouseWorkType', 'HouseWorkTypes'
|
11
|
+
it_behaves_like 'enum', 'VATType', 'VATTypes'
|
12
|
+
it_behaves_like 'enum', 'DefaultDeliveryType', 'DefaultDeliveryTypeValues'
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
shared_examples_for 'DocumentRow' do |valid_hash|
|
2
|
+
it{ is_expected.to have_account_number( :account_number, valid_hash ) }
|
3
|
+
|
4
|
+
it{ is_expected.to have_sized_string( :article_number, 50, valid_hash ) }
|
5
|
+
it{ is_expected.to have_sized_string( :description, 50, valid_hash ) }
|
6
|
+
|
7
|
+
it{ is_expected.to have_sized_float( :delivered_quantity, 0.0, 9_999_999_999_999.0, valid_hash ) }
|
8
|
+
it{ is_expected.to have_sized_float( :price, 0.0, 99_999_999_999.0, valid_hash ) }
|
9
|
+
|
10
|
+
it{ is_expected.to have_discount_type( :discount_type, valid_hash ) }
|
11
|
+
|
12
|
+
it{ is_expected.to have_sized_integer( :house_work_hours_to_report, 0, 99_999, valid_hash ) }
|
13
|
+
|
14
|
+
it{ is_expected.to have_house_work_type( :house_work_type, valid_hash ) }
|
15
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'fortnox/api/types/examples/types'
|
2
|
+
|
3
|
+
shared_examples_for 'enum' do |name, values, auto_crop: false|
|
4
|
+
describe name do
|
5
|
+
let( :klass ){ Fortnox::API::Types.const_get(name) }
|
6
|
+
|
7
|
+
context 'created with nil' do
|
8
|
+
subject{ klass[ nil ] }
|
9
|
+
it{ is_expected.to be_nil }
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'created with' do
|
13
|
+
subject{ klass[ input ] }
|
14
|
+
|
15
|
+
let( :enum_value ){ Fortnox::API::Types.const_get(values).values.sample }
|
16
|
+
|
17
|
+
context 'a random member from then enum' do
|
18
|
+
let(:input){ enum_value }
|
19
|
+
it{ is_expected.to eq enum_value }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'a symoblised, random member from the enum' do
|
23
|
+
let( :input ){ enum_value.to_sym }
|
24
|
+
it{ is_expected.to eq enum_value }
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'a lower case, random member from the enum' do
|
28
|
+
let( :input ){ enum_value.downcase }
|
29
|
+
it{ is_expected.to eq enum_value }
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'a string that starts like a random member from the enum' do
|
33
|
+
let( :input ){ enum_value.downcase + 'more string' }
|
34
|
+
|
35
|
+
if auto_crop
|
36
|
+
it{ is_expected.to eq enum_value }
|
37
|
+
else
|
38
|
+
subject{ ->{ klass[ input ] } }
|
39
|
+
it{ is_expected.to raise_error(Dry::Types::ConstraintError) }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'created with invalid input' do
|
45
|
+
include_examples 'raises ConstraintError', 'r4nd0m'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
shared_examples_for 'equals input' do |input|
|
2
|
+
subject{ klass[ input ] }
|
3
|
+
it{ is_expected.to eq input }
|
4
|
+
end
|
5
|
+
|
6
|
+
shared_examples_for 'raises ConstraintError' do |input|
|
7
|
+
subject{ ->{ klass[ input ] } }
|
8
|
+
it{ is_expected.to raise_error(Dry::Types::ConstraintError) }
|
9
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'fortnox/api'
|
3
|
+
require 'fortnox/api/types'
|
4
|
+
require 'fortnox/api/repositories/order'
|
5
|
+
require 'fortnox/api/models/order'
|
6
|
+
require 'fortnox/api/types/order_row'
|
7
|
+
|
8
|
+
# rubocop:disable RSpec/DescribeClass
|
9
|
+
describe 'HouseWorkTypes', integration: true do
|
10
|
+
let(:repository){ Fortnox::API::Repository::Order.new }
|
11
|
+
let(:valid_model) do
|
12
|
+
Fortnox::API::Model::Order.new(customer_number: '1', order_rows: [order_row])
|
13
|
+
end
|
14
|
+
let(:order_row){ Fortnox::API::Types::OrderRow.new(ordered_quantity: 1,
|
15
|
+
article_number: '0000',
|
16
|
+
house_work_type: house_work_type)}
|
17
|
+
|
18
|
+
shared_examples_for 'house work type' do |type, legacy: false|
|
19
|
+
subject do
|
20
|
+
-> do
|
21
|
+
VCR.use_cassette( "orders/house_work_type_#{ type.downcase }" ) do
|
22
|
+
repository.save(valid_model)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:error_message){ 'Skattereduktion för en av de valda husarbetestyperna har upphört.' }
|
28
|
+
let(:house_work_type){ Fortnox::API::Types::HouseWorkTypes[type] }
|
29
|
+
|
30
|
+
context "when creating an OrderRow with house_work_type set to #{ type }" do
|
31
|
+
if legacy
|
32
|
+
it 'raises an error' do
|
33
|
+
is_expected.to raise_error(Fortnox::API::RemoteServerError, error_message)
|
34
|
+
end
|
35
|
+
else
|
36
|
+
it{ is_expected.not_to raise_error }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it_behaves_like 'house work type', 'CONSTRUCTION'
|
42
|
+
it_behaves_like 'house work type', 'ELECTRICITY'
|
43
|
+
it_behaves_like 'house work type', 'GLASSMETALWORK'
|
44
|
+
it_behaves_like 'house work type', 'GROUNDDRAINAGEWORK'
|
45
|
+
it_behaves_like 'house work type', 'MASONRY'
|
46
|
+
it_behaves_like 'house work type', 'PAINTINGWALLPAPERING'
|
47
|
+
it_behaves_like 'house work type', 'HVAC'
|
48
|
+
it_behaves_like 'house work type', 'CLEANING'
|
49
|
+
it_behaves_like 'house work type', 'TEXTILECLOTHING'
|
50
|
+
it_behaves_like 'house work type', 'CLEANING'
|
51
|
+
it_behaves_like 'house work type', 'SNOWPLOWING'
|
52
|
+
it_behaves_like 'house work type', 'GARDENING'
|
53
|
+
it_behaves_like 'house work type', 'BABYSITTING'
|
54
|
+
it_behaves_like 'house work type', 'OTHERCARE'
|
55
|
+
it_behaves_like 'house work type', 'OTHERCOSTS'
|
56
|
+
|
57
|
+
it_behaves_like 'house work type', 'COOKING', legacy: true
|
58
|
+
it_behaves_like 'house work type', 'TUTORING', legacy: true
|
59
|
+
end
|
60
|
+
# rubocop:enable RSpec/DescribeClass
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dry-struct'
|
3
|
+
require 'fortnox/api/types/model'
|
4
|
+
|
5
|
+
RSpec.describe Fortnox::API::Types::Model do
|
6
|
+
shared_examples_for 'raises error' do |error|
|
7
|
+
using_test_classes do
|
8
|
+
module Types
|
9
|
+
include Dry::Types.module
|
10
|
+
|
11
|
+
Age = Int.constrained(gt: 18).with(required: true)
|
12
|
+
end
|
13
|
+
|
14
|
+
class TypesModelUser < Fortnox::API::Types::Model
|
15
|
+
attribute :age, Types::Age
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "User inheriting from #{ described_class }" do
|
20
|
+
subject{ ->{ TypesModelUser.new(args) } }
|
21
|
+
|
22
|
+
it{ is_expected.to raise_error(error) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'without required keys' do
|
27
|
+
include_examples 'raises error', Fortnox::API::MissingAttributeError do
|
28
|
+
let(:args){ {} }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when omitting optional keys' do
|
33
|
+
using_test_class do
|
34
|
+
module Types
|
35
|
+
include Dry::Types.module
|
36
|
+
|
37
|
+
module Nullable
|
38
|
+
String = Types::Strict::String.optional
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class User < Fortnox::API::Types::Model
|
43
|
+
attribute :optional_string, Types::Nullable::String
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
subject{ ->{ User.new() } }
|
48
|
+
|
49
|
+
it{ is_expected.not_to raise_error }
|
50
|
+
|
51
|
+
describe 'optional attribute' do
|
52
|
+
subject{ User.new().optional_string }
|
53
|
+
it{ is_expected.to be nil }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|