Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion fortnox-api.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength

spec.required_ruby_version = '>= 2.3'
spec.add_dependency 'dry-struct', '~> 0.1'
spec.add_dependency 'dry-types', '~> 0.8'
spec.add_dependency 'dry-types', '~> 0.8', '< 0.13.0'
# TODO: Temporary lockdown. See issue #103 for more info.
spec.add_dependency 'httparty', '~> 0.14.0'

Expand Down
20 changes: 20 additions & 0 deletions lib/fortnox/api/mappers/metadata.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

require 'fortnox/api/mappers/base'

module Fortnox
module API
module Mapper
class Metadata < Fortnox::API::Mapper::Base
KEY_MAP = {
total_resources: '@TotalResources',
total_pages: '@TotalPages',
current_page: '@CurrentPage'
}.freeze
JSON_ENTITY_WRAPPER = 'MetaInformation'
end

Registry.register(Metadata.canonical_name_sym, Metadata)
end
end
end
1 change: 1 addition & 0 deletions lib/fortnox/api/models.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
require 'fortnox/api/models/project'
require 'fortnox/api/models/unit'
require 'fortnox/api/models/terms_of_payment'
require 'fortnox/api/models/metadata'
21 changes: 21 additions & 0 deletions lib/fortnox/api/models/metadata.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

require 'fortnox/api/types'

module Fortnox
module API
module Model
class Metadata < Model::Base
STUB = {
current_page: '',
total_resources: '',
total_pages: ''
}.freeze

attribute :current_page, Types::Required::Integer.is(:read_only)
attribute :total_resources, Types::Required::Integer.is(:read_only)
attribute :total_pages, Types::Required::Integer.is(:read_only)
end
end
end
end
6 changes: 5 additions & 1 deletion lib/fortnox/api/repositories/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
require 'fortnox/api/request_handling'
require 'fortnox/api/repositories/base/loaders'
require 'fortnox/api/repositories/base/savers'
require 'fortnox/api/repositories/base/pagination'
require 'fortnox/api/mappers/metadata'

module Fortnox
module API
Expand All @@ -13,6 +15,7 @@ class Base
include Fortnox::API::RequestHandling
include Loaders
include Savers
include Pagination

HTTParty::Parser::SupportedFormats['text/html'] = :json

Expand All @@ -24,7 +27,7 @@ class Base
HTTP_METHODS = %i[get put post delete].freeze

attr_accessor :headers
attr_reader :mapper, :keys_filtered_on_save
attr_reader :mapper, :keys_filtered_on_save, :metadata

def self.set_headers(headers = {}) # rubocop:disable Naming/AccessorMethodName
self.headers.merge!(headers)
Expand All @@ -49,6 +52,7 @@ def initialize(keys_filtered_on_save: [:url], token_store: :default)
@keys_filtered_on_save = keys_filtered_on_save
@token_store = token_store
@mapper = Registry[Mapper::Base.canonical_name_sym(self.class::MODEL)].new
@metadata_mapper = Mapper::Metadata.new
end

def next_access_token
Expand Down
14 changes: 12 additions & 2 deletions lib/fortnox/api/repositories/base/loaders.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,15 @@ module API
module Repository
module Loaders
def all
response_hash = get(self.class::URI)
instantiate_collection_response(response_hash)
results = []

loop do
response_hash = get(self.class::URI, query: { page: next_page })
results += instantiate_collection_response(response_hash)
break if last_page?
end

results
end

def only(filter)
Expand Down Expand Up @@ -53,6 +60,9 @@ def escape(key, value)
private

def instantiate_collection_response(response_hash)
metadata_hash = @metadata_mapper.wrapped_json_hash_to_entity_hash(response_hash)
@metadata = Model::Metadata.new(metadata_hash)

entities_hash = @mapper.wrapped_json_collection_to_entities_hash(response_hash)
entities_hash.map do |entity_hash|
instantiate(entity_hash)
Expand Down
25 changes: 25 additions & 0 deletions lib/fortnox/api/repositories/base/pagination.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

module Fortnox
module API
module Repository
module Pagination
def last_page?
current_page == total_pages
end

def next_page
current_page + 1
end

def current_page
metadata&.current_page || 0
end

def total_pages
metadata&.total_pages || 0
end
end
end
end
end
15 changes: 15 additions & 0 deletions spec/fortnox/api/mappers/metadata_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

require 'spec_helper'
require 'fortnox/api'
require 'fortnox/api/mappers/metadata'
require 'fortnox/api/mappers/examples/mapper'

describe Fortnox::API::Mapper::Metadata do
key_map = Fortnox::API::Mapper::Metadata::KEY_MAP
json_entity_type = 'MetaInformation'

it_behaves_like 'mapper', key_map, json_entity_type, nil do
let(:mapper) { described_class.new }
end
end
19 changes: 19 additions & 0 deletions spec/fortnox/api/models/metadata_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

require 'spec_helper'
require 'fortnox/api/models/metadata'
require 'fortnox/api/models/examples/model'

describe Fortnox::API::Model::Metadata, type: :model do
let(:required_attributes) do
{
current_page: 1,
total_resources: 2,
total_pages: 1
}
end

it 'can be initialized' do
expect { described_class.new(required_attributes) }.not_to raise_error
end
end
2 changes: 1 addition & 1 deletion spec/fortnox/api/repositories/article_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
:ean,
'5901234123457'

include_examples '.all', 12
include_examples '.all', 20

include_examples '.find', '1' do
let(:find_by_hash_failure) { { description: 'Not Found' } }
Expand Down
2 changes: 1 addition & 1 deletion spec/fortnox/api/repositories/base_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ class Test < Fortnox::API::Repository::Base

context 'when raising error from remote server' do
error_message = 'Räkenskapsår finns inte upplagt. '\
'För att kunna skapa en faktura krävs det att det finns ett räkenskapsår'
'För att kunna skapa en faktura krävs det att det finns ett räkenskapsår'

before do
Fortnox::API.configure do |conf|
Expand Down
2 changes: 1 addition & 1 deletion spec/fortnox/api/repositories/customer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
# It is not yet possible to delete Customers. Therefore, expected nr of
# Customers when running .all will continue to increase
# (until 100, which is max by default).
include_examples '.all', 100
include_examples '.all', 209

include_examples '.find', '1' do
let(:find_by_hash_failure) { { city: 'Not Found' } }
Expand Down
2 changes: 1 addition & 1 deletion spec/fortnox/api/repositories/invoice_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

# It is not possible to delete Invoces. Therefore, expected nr of Orders
# when running .all will continue to increase (until 100, which is max by default).
include_examples '.all', 60
include_examples '.all', 84

include_examples '.find', 1 do
let(:find_by_hash_failure) { { yourreference: 'Not found' } }
Expand Down
2 changes: 1 addition & 1 deletion spec/fortnox/api/repositories/order_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

# It is not possible to delete Orders. Therefore, expected nr of Orders
# when running .all will continue to increase (until 100, which is max by default).
include_examples '.all', 100
include_examples '.all', 325

include_examples '.find', 1 do
let(:find_by_hash_failure) { { ourreference: 'Not found' } }
Expand Down
2 changes: 1 addition & 1 deletion spec/fortnox/api/repositories/project_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
# It is not yet possible to delete Projects. Therefore, expected nr of
# Projects when running .all will continue to increase
# (until 100, which is max by default).
include_examples '.all', 8
include_examples '.all', 26

include_examples '.find', '1' do
let(:find_by_hash_failure) { { offset: 10_000 } }
Expand Down
2 changes: 1 addition & 1 deletion spec/fortnox/api/repositories/terms_of_payment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

include_examples '.save', :description, additional_attrs: required_hash

include_examples '.all', 9
include_examples '.all', 10

include_examples '.find', '15DAYS', find_by_hash: false do
let(:find_by_hash_failure) { { code: '15days' } }
Expand Down
2 changes: 1 addition & 1 deletion spec/fortnox/api/repositories/unit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
:code,
'woooh'

include_examples '.all', 6
include_examples '.all', 8

include_examples '.find', 'blarg', find_by_hash: false do
let(:find_by_hash_failure) { { code: 'notfound' } }
Expand Down
24 changes: 16 additions & 8 deletions spec/vcr_cassettes/articles/all.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading