fortnox-api 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -4
  3. data/fortnox-api.gemspec +4 -4
  4. data/lib/fortnox/api/mappers/article.rb +22 -0
  5. data/lib/fortnox/api/mappers/base/to_json.rb +2 -2
  6. data/lib/fortnox/api/models.rb +1 -0
  7. data/lib/fortnox/api/models/article.rb +133 -0
  8. data/lib/fortnox/api/repositories.rb +1 -0
  9. data/lib/fortnox/api/repositories/article.rb +16 -0
  10. data/lib/fortnox/api/repositories/base/savers.rb +1 -1
  11. data/lib/fortnox/api/types.rb +2 -0
  12. data/lib/fortnox/api/types/enums.rb +5 -2
  13. data/lib/fortnox/api/version.rb +1 -1
  14. data/spec/fortnox/api/mappers/article_spec.rb +15 -0
  15. data/spec/fortnox/api/mappers/base/to_json_spec.rb +1 -1
  16. data/spec/fortnox/api/models/article_spec.rb +7 -0
  17. data/spec/fortnox/api/repositories/article_spec.rb +35 -0
  18. data/spec/fortnox/api/repositories/examples/find.rb +0 -2
  19. data/spec/fortnox/api/repositories/examples/save.rb +4 -5
  20. data/spec/fortnox/api/repositories/examples/save_with_nested_model.rb +1 -0
  21. data/spec/fortnox/api/repositories/examples/save_with_specially_named_attribute.rb +2 -1
  22. data/spec/fortnox/api/repositories/invoice_spec.rb +1 -1
  23. data/spec/fortnox/api/repositories/order_spec.rb +1 -1
  24. data/spec/fortnox/api/repositories/project_spec.rb +3 -3
  25. data/spec/fortnox/api/types/enums_spec.rb +1 -0
  26. data/spec/vcr_cassettes/articles/all.yml +54 -0
  27. data/spec/vcr_cassettes/articles/find_by_hash_failure.yml +45 -0
  28. data/spec/vcr_cassettes/articles/find_failure.yml +45 -0
  29. data/spec/vcr_cassettes/articles/find_id_1.yml +45 -0
  30. data/spec/vcr_cassettes/articles/find_new.yml +46 -0
  31. data/spec/vcr_cassettes/articles/multi_param_find_by_hash.yml +45 -0
  32. data/spec/vcr_cassettes/articles/save_new.yml +45 -0
  33. data/spec/vcr_cassettes/articles/save_old.yml +46 -0
  34. data/spec/vcr_cassettes/articles/save_with_specially_named_attribute.yml +45 -0
  35. data/spec/vcr_cassettes/articles/search_by_name.yml +45 -0
  36. data/spec/vcr_cassettes/articles/search_miss.yml +45 -0
  37. data/spec/vcr_cassettes/articles/search_with_special_char.yml +45 -0
  38. data/spec/vcr_cassettes/articles/single_param_find_by_hash.yml +46 -0
  39. metadata +43 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 124c4cde46325d41cffa7a3bf092375697cb6b1d
4
- data.tar.gz: cb91dde384a1c59e4304f29dc9dbdd9ea0c64d4f
3
+ metadata.gz: 0e05948f9903dea9dc9b90deab6e51a9e610e0bb
4
+ data.tar.gz: b7205e9aef5625b36623652e1626c042d2ffedda
5
5
  SHA512:
6
- metadata.gz: 8f7bc215cb29128bb0c8385c3769f9aa3576006d69ac84d275b8df4a8799583148e73b77a788538ed4d0fee45e700b7144b803b0a3dca4a2cfe430da1206b0de
7
- data.tar.gz: d962b0e1dbb2e05900846866f69a585100b59ac993002dfb1bcef7d89dc8887ecb0e6eaa993be1355971d6d7e09cc4ae67b6881b2609b0a3abe260839aae5436
6
+ metadata.gz: 9d6b44d780e5eec9961b9c398f0ce7b289e8381eebb5bf5965e59c3d46cae5667b3a9b96dc9411b87bce6063d3354491c61fa0da7164acf8daa417cc1281cfec
7
+ data.tar.gz: a14a4ab461cdda2e0d50dc4851b69494c58744508aab9d065d237349f62dfaa63b0e3e16c413a6e0738cafcae1a4f59d2e516c5333fb3e4fec2766abff0b245e
data/README.md CHANGED
@@ -11,14 +11,14 @@
11
11
  [![Code Climate](https://img.shields.io/codeclimate/github/my-codeworks/fortnox-api.svg?style=flat-square)](https://codeclimate.com/github/my-codeworks/fortnox-api)
12
12
  [![Test coverage](https://img.shields.io/codeclimate/coverage/github/my-codeworks/fortnox-api.svg?style=flat-square)](https://codeclimate.com/github/my-codeworks/fortnox-api/coverage)
13
13
 
14
- The rough status of this project is as follows (as of November 2016):
14
+ The rough status of this project is as follows (as of October 2017):
15
15
  * In active development (just check out the commit log)
16
- * Two developers. At least twice as good as one.
16
+ * Three developers. At least thrice as good as one.
17
17
  * Basic structure complete. Things like getting customers and invoices, updating and saving etc.
18
18
  * Some advanced features implemented, for instance support for multiple Access Tokens and filtering entities.
19
19
  * Advanced features around the corner. Things like sorting entities, pagination of results etc.
20
- * A few models implemented. Right now we have nearly full support for `Customer`, `Invoice` and `Order`. Adding more models in general is quick and easy, see the developer guide further down.
21
- * Massive refactorings no longer occurs weakly :) We are running this gem in production for live test.
20
+ * A few models implemented. Right now we have nearly full support for `Customer`, `Invoice`, `Order`, `Article`, `Label` and `Project`. Adding more models in general is quick and easy, see the developer guide further down.
21
+ * Massive refactorings no longer occurs weekly :) We are running this gem in production for live test.
22
22
 
23
23
  The goal is to have a production ready version that covers at least the `Invoice`, `Order`, `Customer` and `Project` models by January.
24
24
 
@@ -65,12 +65,20 @@ customer.name == "New Name" # => false
65
65
  ```
66
66
  This is how all the models work, they are all immutable.
67
67
 
68
+ ### Exceptions
69
+
70
+ Models can throw `Fortnox::API::AttributeError` if an attribute is invalid in some way (for instance if you try to assign a too long string to a limited string attribute) and `Fortnox::API::MissingAttributeError` if a required attribute is missing.
71
+
68
72
  ## Type
69
73
  The types automatically enforce the constraints on values, lengths and, in some cases, content of the model attributes. Types forces your models to be correct before sending data to the API, which saves you a lot of API calls and rescuing the exception we throw when we get a 4xx/5xx response from the server (you can still get errors from the server; our implementation is not perfect. Also, Fortnox sometimes requires a specific combination of attributes).
70
74
 
71
75
  ## Repositories
72
76
  Used to load, update, create and delete model instances. These are what is actually wrapping the HTTP REST API requests against Fortnox's server.
73
77
 
78
+ ### Exceptions
79
+
80
+ Repositories can throw `Fortnox::API::RemoteServerError` if something went wrong at Fortnox.
81
+
74
82
  ## Mappers
75
83
  These are responsible for the mapping between our plain old Ruby object models and Fortnox JSON requests. The repositories use the mappers to map models to JSON requests and JSON to model instances when working with the Fortnox API, you will not need to use them directly.
76
84
 
@@ -3,10 +3,10 @@ lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'fortnox/api/version'
5
5
 
6
- Gem::Specification.new do |spec|
6
+ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
7
7
  spec.name = "fortnox-api"
8
8
  spec.version = Fortnox::API::VERSION
9
- spec.authors = ["Jonas Schubert Erlandsson", "Hannes Elvemyr"]
9
+ spec.authors = ["Jonas Schubert Erlandsson", "Hannes Elvemyr", "Felix Holmgren"]
10
10
  spec.email = ["jonas.schubert.erlandsson@my-codeworks.com"]
11
11
  spec.summary = "Gem to use Fortnox REST API in Ruby."
12
12
  spec.description = "This gem uses the HTTParty library to abstract away the REST calls. It gives you access to a number of objects that behave a lot like ActiveRecord instances, giving you access to methods like `all`, `find`, `find_by_...` and so on. And each individual instance can be easaly persistable to Fortnox again using the `save` method."
@@ -35,7 +35,7 @@ Gem::Specification.new do |spec|
35
35
  spec.add_development_dependency "vcr", "~> 3.0"
36
36
  spec.add_development_dependency "pry", "~> 0"
37
37
  spec.add_development_dependency "codeclimate-test-reporter", "~> 0"
38
- spec.add_development_dependency "rubocop", "~> 0.41"
39
- spec.add_development_dependency "rubocop-rspec", "~> 1.7"
38
+ spec.add_development_dependency "rubocop", "~> 0.46.0"
39
+ spec.add_development_dependency "rubocop-rspec", "~> 1.8.0"
40
40
 
41
41
  end
@@ -0,0 +1,22 @@
1
+ require "fortnox/api/mappers/base"
2
+
3
+ module Fortnox
4
+ module API
5
+ module Mapper
6
+ class Article < Fortnox::API::Mapper::Base
7
+
8
+ KEY_MAP = {
9
+ ean: 'EAN',
10
+ eu_account: 'EUAccount',
11
+ eu_vat_account: 'EUVATAccount',
12
+ vat: 'VAT'
13
+ }.freeze
14
+ JSON_ENTITY_WRAPPER = 'Article'.freeze
15
+ JSON_COLLECTION_WRAPPER = 'Articles'.freeze
16
+
17
+ end
18
+
19
+ Registry.register( Article.canonical_name_sym, Article )
20
+ end
21
+ end
22
+ end
@@ -47,10 +47,10 @@ module Fortnox
47
47
  def entity_to_hash( entity, keys_to_filter )
48
48
  entity_json_hash = Registry[ mapper_name_for( entity ) ]
49
49
  .call( entity, keys_to_filter )
50
- wrapp_entity_json_hash( entity_json_hash )
50
+ wrap_entity_json_hash( entity_json_hash )
51
51
  end
52
52
 
53
- def wrapp_entity_json_hash( entity_json_hash )
53
+ def wrap_entity_json_hash( entity_json_hash )
54
54
  { self.class::JSON_ENTITY_WRAPPER => entity_json_hash }
55
55
  end
56
56
 
@@ -1,3 +1,4 @@
1
+ require "fortnox/api/models/article"
1
2
  require "fortnox/api/models/customer"
2
3
  require "fortnox/api/models/invoice"
3
4
  require "fortnox/api/models/order"
@@ -0,0 +1,133 @@
1
+ require "fortnox/api/types"
2
+ require "fortnox/api/models/base"
3
+
4
+ module Fortnox
5
+ module API
6
+ module Model
7
+ class Article < Fortnox::API::Model::Base
8
+
9
+ UNIQUE_ID = :article_number
10
+ STUB = { description: '' }.freeze
11
+
12
+ #Url Direct URL to the record
13
+ attribute :url, Fortnox::API::Types::Nullable::String.with( read_only: true )
14
+
15
+ #Active If the article is active
16
+ attribute :active, Fortnox::API::Types::Nullable::Boolean
17
+
18
+ #ArticleNumber Article number. 50 characters
19
+ attribute :article_number, Fortnox::API::Types::Sized::String[ 50 ]
20
+
21
+ #Bulky If the article is bulky.
22
+ attribute :bulky, Fortnox::API::Types::Nullable::Boolean
23
+
24
+ #ConstructionAccount Account number for construction work (special VAT rules in Sweden).
25
+ # The number must be of an existing account.
26
+ attribute :construction_account, Types::Sized::Integer[ 0, 9_999 ]
27
+
28
+ #Depth The depth of the article in millimeters
29
+ attribute :depth, Types::Sized::Integer[ 0, 99_999_999 ]
30
+
31
+ #Description The description of the article
32
+ attribute :description, Fortnox::API::Types::Sized::String[ 200 ].with( required: true )
33
+
34
+ #DisposableQuantity Disposable quantity of the article.
35
+ attribute :disposable_quantity, Fortnox::API::Types::Nullable::Float.with( read_only: true )
36
+
37
+ #EAN EAN bar code
38
+ attribute :ean, Fortnox::API::Types::Sized::String[ 30 ]
39
+
40
+ #EUAccount Account number for the sales account to EU.
41
+ # The number must be of an existing account.
42
+ attribute :eu_account, Types::Sized::Integer[ 0, 9_999 ]
43
+
44
+ #EUVATAccount Account number for the sales account to EU with VAT.
45
+ # The number must be of an existing account.
46
+ attribute :eu_vat_account, Types::Sized::Integer[ 0, 9_999 ]
47
+
48
+ #ExportAccount Account number for the sales account outside EU
49
+ # The number must be of an existing account.
50
+ attribute :export_account, Types::Sized::Integer[ 0, 9_999 ]
51
+
52
+ #Height The height of the article in millimeters
53
+ attribute :height, Types::Sized::Integer[ 0, 99_999_999 ]
54
+
55
+ #Housework If the article is housework
56
+ attribute :housework, Fortnox::API::Types::Nullable::Boolean
57
+
58
+ #HouseWorkType The type of house work.
59
+ attribute :house_work_type, Types::HouseWorkType
60
+
61
+ #Manufacturer The manufacturer of the article
62
+ attribute :manufacturer, Fortnox::API::Types::Sized::String[ 50 ]
63
+
64
+ #ManufacturerArticleNumber The manufacturer's article number
65
+ attribute :manufacturer_article_number, Fortnox::API::Types::Sized::String[ 50 ]
66
+
67
+ #Note Text note
68
+ attribute :note, Fortnox::API::Types::Sized::String[ 10_000 ]
69
+
70
+ #PurchaseAccount Account number for purchase.
71
+ # The number must be of an existing account.
72
+ attribute :purchase_account, Types::Sized::Integer[ 0, 9_999 ]
73
+
74
+ #PurchasePrice Purchase price of the article
75
+ attribute :purchase_price, Fortnox::API::Types::Sized::Float[ 0.0, 99_999_999_999_999.9 ]
76
+
77
+ #QuantityInStock Quantity in stock of the article
78
+ attribute :quantity_in_stock, Fortnox::API::Types::Sized::Float[ 0.0, 99_999_999_999_999.9 ]
79
+
80
+ #ReservedQuantity Reserved quantity of the article
81
+ attribute :reserved_quantity, Fortnox::API::Types::Nullable::Float.with( read_only: true )
82
+
83
+ #SalesAccount Account number for the sales account in Sweden.
84
+ # The number must be of an existing account.
85
+ attribute :sales_account, Types::Sized::Integer[ 0, 9_999 ]
86
+
87
+ #SalesPrice Price of article for its default price list
88
+ attribute :sales_price, Fortnox::API::Types::Nullable::Float.with( read_only: true )
89
+
90
+ #StockGoods If the article is stock goods
91
+ attribute :stock_goods, Fortnox::API::Types::Nullable::Boolean
92
+
93
+ #StockPlace Storage place for the article
94
+ attribute :stock_place, Fortnox::API::Types::Sized::String[ 100 ]
95
+
96
+ #StockValue Value in stock of the article
97
+ attribute :stock_value, Fortnox::API::Types::Nullable::Float.with( read_only: true )
98
+
99
+ #StockWarning When to start warning for low quantity in stock
100
+ attribute :stock_warning, Fortnox::API::Types::Sized::Float[ 0.0, 99_999_999_999_999.9 ]
101
+
102
+ #SupplierName Name of the supplier
103
+ attribute :supplier_name, Fortnox::API::Types::Nullable::String.with( read_only: true )
104
+
105
+ #SupplierNumber Supplier number for the article.
106
+ # The number must be of an existing supplier.
107
+ attribute :supplier_number, Fortnox::API::Types::Nullable::String
108
+
109
+ #Type The type of the article
110
+ attribute :type, Types::ArticleType
111
+
112
+ #Unit Unit code for the article.
113
+ # The code must be of an existing unit.
114
+ attribute :unit, Fortnox::API::Types::Nullable::String
115
+
116
+ #VAT VAT percent, this is predefined by the VAT for the sales account
117
+ attribute :vat, Fortnox::API::Types::Nullable::Float
118
+
119
+ #WebshopArticle If the article is a webshop article
120
+ attribute :webshop_article, Fortnox::API::Types::Nullable::Boolean
121
+
122
+ #Weight Weight of the article in grams
123
+ attribute :weight, Types::Sized::Integer[ 0, 99_999_999 ]
124
+
125
+ #Width Width of the article in millimeters.
126
+ attribute :width, Types::Sized::Integer[ 0, 99_999_999 ]
127
+
128
+ #Expired If the article has expired
129
+ attribute :expired, Fortnox::API::Types::Nullable::Boolean
130
+ end
131
+ end
132
+ end
133
+ end
@@ -1,3 +1,4 @@
1
+ require "fortnox/api/repositories/article"
1
2
  require "fortnox/api/repositories/customer"
2
3
  require "fortnox/api/repositories/invoice"
3
4
  require "fortnox/api/repositories/order"
@@ -0,0 +1,16 @@
1
+ require "fortnox/api/repositories/base"
2
+ require "fortnox/api/models/article"
3
+ require "fortnox/api/mappers/article"
4
+
5
+ module Fortnox
6
+ module API
7
+ module Repository
8
+ class Article < Fortnox::API::Repository::Base
9
+
10
+ MODEL = Fortnox::API::Model::Article
11
+ MAPPER = Fortnox::API::Mapper::Article
12
+ URI = '/articles/'.freeze
13
+ end
14
+ end
15
+ end
16
+ end
@@ -33,7 +33,7 @@ module Fortnox
33
33
  hash = @mapper.entity_to_hash( entity, @keys_filtered_on_save )
34
34
  parent_hash = @mapper.entity_to_hash( entity.parent, @keys_filtered_on_save )
35
35
 
36
- @mapper.wrapp_entity_json_hash( @mapper.diff( hash, parent_hash ) )
36
+ @mapper.wrap_entity_json_hash( @mapper.diff( hash, parent_hash ) )
37
37
  end
38
38
 
39
39
  def get_update_url_for( entity )
@@ -18,6 +18,8 @@ module Fortnox
18
18
 
19
19
  AccountNumber = Strict::Int.constrained( gt: 0, lteq: 9999 ).optional
20
20
 
21
+ ArticleType = Strict::String.constrained( included_in: ArticleTypes.values ).optional.constructor( EnumConstructors.default )
22
+
21
23
  CountryCode = Strict::String.constrained( included_in: CountryCodes.values ).optional.constructor( EnumConstructors.sized(2) )
22
24
  Currency = Strict::String.constrained( included_in: Currencies.values ).optional.constructor( EnumConstructors.sized(3) )
23
25
  CustomerType = Strict::String.constrained( included_in: CustomerTypes.values ).optional.constructor( EnumConstructors.default )
@@ -4,14 +4,17 @@ module Fortnox
4
4
 
5
5
  module EnumConstructors
6
6
  def self.sized( size )
7
- -> (value){ return nil if value == ''; value.to_s.upcase[0...size] unless value.nil? }
7
+ ->(value){ return nil if value == ''; value.to_s.upcase[0...size] unless value.nil? }
8
8
  end
9
9
 
10
10
  def self.default
11
- -> (value){ return nil if value == ''; value.to_s.upcase unless value.nil? }
11
+ ->(value){ return nil if value == ''; value.to_s.upcase unless value.nil? }
12
12
  end
13
13
  end
14
14
 
15
+ ArticleTypes = Types::Strict::String.enum(
16
+ 'SERVICE','STOCK'
17
+ )
15
18
  DiscountTypes = Types::Strict::String.enum(
16
19
  'AMOUNT','PERCENT'
17
20
  )
@@ -1,5 +1,5 @@
1
1
  module Fortnox
2
2
  module API
3
- VERSION = "0.3.0".freeze
3
+ VERSION = "0.4.0".freeze
4
4
  end
5
5
  end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+ require 'fortnox/api'
3
+ require 'fortnox/api/mappers/customer'
4
+ require 'fortnox/api/mappers/examples/mapper'
5
+
6
+ describe Fortnox::API::Mapper::Article do
7
+ key_map = Fortnox::API::Mapper::Article::KEY_MAP
8
+
9
+ json_entity_type = 'Article'
10
+ json_entity_collection = 'Articles'
11
+
12
+ it_behaves_like 'mapper', key_map, json_entity_type, json_entity_collection do
13
+ let(:mapper){ described_class.new }
14
+ end
15
+ end
@@ -8,7 +8,7 @@ describe Fortnox::API::Mapper::ToJSON do
8
8
  # "NoMethodError: undefined method `call\' for Test::ProductMapper:Class`"
9
9
  it 'should be tested when random error is fixed!'
10
10
 
11
- describe 'wrapp_entity_json_hash' do
11
+ describe 'wrap_entity_json_hash' do
12
12
  it 'should be tested'
13
13
  end
14
14
 
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+ require 'fortnox/api/models/article'
3
+ require 'fortnox/api/models/examples/model'
4
+
5
+ describe Fortnox::API::Model::Article, type: :model do
6
+ it_behaves_like 'a model', '1'
7
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'fortnox/api'
3
+ require 'fortnox/api/mappers'
4
+ require 'fortnox/api/repositories/customer'
5
+ require 'fortnox/api/repositories/examples/all'
6
+ require 'fortnox/api/repositories/examples/find'
7
+ require 'fortnox/api/repositories/examples/save'
8
+ require 'fortnox/api/repositories/examples/save_with_specially_named_attribute'
9
+ require 'fortnox/api/repositories/examples/search'
10
+
11
+ describe Fortnox::API::Repository::Article, order: :defined, integration: true do
12
+ subject(:repository){ described_class.new }
13
+
14
+ include_examples '.save',
15
+ :description,
16
+ additional_attrs: { sales_account: 1250 }
17
+
18
+ include_examples '.save with specially named attribute',
19
+ { description: 'Test article' },
20
+ :ean,
21
+ '5901234123457'
22
+
23
+ include_examples '.all', 12
24
+
25
+ include_examples '.find', '1' do
26
+ let( :find_by_hash_failure ){ { description: 'Not Found' } }
27
+ let( :single_param_find_by_hash ){ { find_hash: { articlenumber: 1 }, matches: 3 } }
28
+
29
+ let( :multi_param_find_by_hash ) do
30
+ { find_hash: { articlenumber: 1, description: 'Cykelpump' }, matches: 1 }
31
+ end
32
+ end
33
+
34
+ include_examples '.search', :description, 'Testartikel', 2
35
+ end
@@ -1,4 +1,3 @@
1
- # rubocop:disable RSpec/DescribeClass
2
1
  shared_examples_for '.find' do |searched_entity_id|
3
2
  describe '.find by id' do
4
3
  let( :returned_object ) do
@@ -77,4 +76,3 @@ shared_examples_for '.find' do |searched_entity_id|
77
76
  end
78
77
  end
79
78
  end
80
- # rubocop:enable RSpec/DescribeClass
@@ -1,14 +1,13 @@
1
- # rubocop:disable RSpec/DescribeClass
2
1
  #######################################
3
2
  # SPEC IS DEPENDENT ON DEFINED ORDER!
4
3
  #######################################
5
4
  #
6
5
  # Assumes that attribute is a string attribute without restrictions.
7
- shared_examples_for '.save' do |attribute, required_attributes = {}|
6
+
7
+ # rubocop:disable RSpec/DescribeClass
8
+ shared_examples_for '.save' do |attribute, additional_attrs: {}|
8
9
  describe '.save' do
9
- let( :new_hash ) do
10
- required_attributes.merge( attribute => value )
11
- end
10
+ let( :new_hash ){ additional_attrs.merge( attribute => value ) }
12
11
  let( :new_model ){ described_class::MODEL.new( new_hash ) }
13
12
  let( :save_new ){ VCR.use_cassette( "#{ vcr_dir }/save_new" ){ repository.save( new_model ) } }
14
13
  let( :entity_wrapper ){ repository.mapper.class::JSON_ENTITY_WRAPPER }
@@ -1,5 +1,6 @@
1
1
  # TODO: This will not work until we solve issue #62.
2
2
  # Until then, these tests are pending.
3
+
3
4
  # rubocop:disable RSpec/DescribeClass
4
5
  shared_examples_for '.save with nested model' do |required_hash, nested_model_key, nested_model_hash, nested_entity|
5
6
  describe '.save with nested model' do
@@ -1,8 +1,9 @@
1
- # rubocop:disable RSpec/DescribeClass
2
1
  # Test saving model with attributes that has specially names that needs to be mapped.
3
2
  #
4
3
  # NOTE: VCR cassette must be discarded when repositories are updated to reflect
5
4
  # the changes!
5
+
6
+ # rubocop:disable RSpec/DescribeClass
6
7
  shared_examples_for '.save with specially named attribute' do |required_hash, attribute, value|
7
8
  describe '.save' do
8
9
  context 'with specially named attribute' do