fortnox-api 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +3 -17
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +127 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +1 -1
- data/README.md +131 -7
- data/Rakefile +5 -1
- data/fortnox-api.gemspec +13 -3
- data/lib/fortnox/api.rb +11 -1
- data/lib/fortnox/api/base.rb +56 -0
- data/lib/fortnox/api/class_methods.rb +62 -0
- data/lib/fortnox/api/customer.rb +15 -0
- data/lib/fortnox/api/customer/entity.rb +179 -0
- data/lib/fortnox/api/customer/repository.rb +28 -0
- data/lib/fortnox/api/customer/validator.rb +26 -0
- data/lib/fortnox/api/entity.rb +45 -0
- data/lib/fortnox/api/repository/base.rb +27 -0
- data/lib/fortnox/api/repository/json_convertion.rb +55 -0
- data/lib/fortnox/api/repository/loaders.rb +49 -0
- data/lib/fortnox/api/repository/savers.rb +15 -0
- data/lib/fortnox/api/validator.rb +32 -0
- data/lib/fortnox/api/version.rb +1 -1
- data/spec/fortnox/api/base_spec.rb +93 -0
- data/spec/fortnox/api/customer/repository_spec.rb +0 -0
- data/spec/fortnox/api/customer/validator_spec.rb +32 -0
- data/spec/fortnox/api/entity_spec.rb +62 -0
- data/spec/spec_helper.rb +19 -0
- metadata +163 -8
@@ -0,0 +1,49 @@
|
|
1
|
+
require "cgi"
|
2
|
+
|
3
|
+
module Fortnox
|
4
|
+
module API
|
5
|
+
module Repository
|
6
|
+
module Loaders
|
7
|
+
|
8
|
+
def all
|
9
|
+
response_hash = get( @base_uri )
|
10
|
+
entities_hash = response_hash[ @json_list_wrapper ]
|
11
|
+
entities_hash.map do |entity_hash|
|
12
|
+
hash_to_entity( entity_hash )
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def find( id_or_hash )
|
17
|
+
return find_all_by( id_or_hash ) if id_or_hash.is_a? Hash
|
18
|
+
|
19
|
+
id = Integer( id_or_hash )
|
20
|
+
find_one_by( id )
|
21
|
+
|
22
|
+
catch ArgumentError
|
23
|
+
raise ArgumentError, "find only accepts a number or hash as argument"
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_one_by( id )
|
27
|
+
response_hash = get( @base_uri + id )
|
28
|
+
entity_hash = response_hash[ @json_entity_wrapper ]
|
29
|
+
hash_to_entity( entity_hash )
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_all_by( hash )
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_query( hash )
|
37
|
+
hash.collect do |key, value|
|
38
|
+
escape( key, value )
|
39
|
+
end.sort * '&'
|
40
|
+
end
|
41
|
+
|
42
|
+
def escape( key, value )
|
43
|
+
"#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "vanguard"
|
2
|
+
|
3
|
+
module Fortnox
|
4
|
+
module API
|
5
|
+
module Validator
|
6
|
+
|
7
|
+
def validate( instance )
|
8
|
+
raise ArgumentError, "No validator given for #{name}" unless @validator
|
9
|
+
|
10
|
+
validation_result = @validator.call( instance )
|
11
|
+
@violations = validation_result.violations
|
12
|
+
|
13
|
+
return validation_result.valid?
|
14
|
+
end
|
15
|
+
|
16
|
+
def violations
|
17
|
+
@violations ||= Set.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def using_validations &block
|
21
|
+
@validator = Vanguard::Validator.build &block
|
22
|
+
end
|
23
|
+
|
24
|
+
def instance
|
25
|
+
raise ArgumentError, "No validator given for #{name}" unless @validator
|
26
|
+
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/fortnox/api/version.rb
CHANGED
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fortnox::API do
|
4
|
+
|
5
|
+
describe 'creation' do
|
6
|
+
context 'without parameters' do
|
7
|
+
it 'fails when given as argument' do
|
8
|
+
expect{
|
9
|
+
Fortnox::API.new()
|
10
|
+
}.to raise_error(
|
11
|
+
ArgumentError,
|
12
|
+
/base url/
|
13
|
+
)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'with only client_secret' do
|
18
|
+
it 'fails when given as argument' do
|
19
|
+
expect{
|
20
|
+
Fortnox::API.new(
|
21
|
+
base_url: ''
|
22
|
+
)
|
23
|
+
}.to raise_error(
|
24
|
+
ArgumentError,
|
25
|
+
/client secret/
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'fails when given as ENV' do
|
30
|
+
stub_const('ENV', ENV.to_hash.merge('FORTNOX_API_BASE_URL' => 'xxx'))
|
31
|
+
expect{
|
32
|
+
Fortnox::API.new()
|
33
|
+
}.to raise_error(
|
34
|
+
ArgumentError,
|
35
|
+
/client secret/
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with both base url and client secret' do
|
41
|
+
it 'fails when given as argument' do
|
42
|
+
expect{
|
43
|
+
Fortnox::API.new(
|
44
|
+
base_url: '',
|
45
|
+
client_secret: '',
|
46
|
+
)
|
47
|
+
}.to raise_error(
|
48
|
+
ArgumentError,
|
49
|
+
/access token/
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'fails when given as ENV' do
|
54
|
+
stub_const('ENV', ENV.to_hash.merge('FORTNOX_API_CLIENT_SECRET' => 'xxx', 'FORTNOX_API_ACCESS_TOKEN' => 'xxx'))
|
55
|
+
expect{
|
56
|
+
Fortnox::API.new()
|
57
|
+
}.to raise_error(
|
58
|
+
ArgumentError,
|
59
|
+
/base url/
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'get access token' do
|
67
|
+
it 'works' do
|
68
|
+
stub_request(
|
69
|
+
:get,
|
70
|
+
'http://api.fortnox.se/3/',
|
71
|
+
).with(
|
72
|
+
headers: {
|
73
|
+
'Authorisation-Code' => 'ea3862b0-189c-464b-8e23-1b9702365ea1',
|
74
|
+
'Client-Secret' => 'P5K5vE3Kun',
|
75
|
+
'Accept' => 'application/json',
|
76
|
+
}
|
77
|
+
).to_return(
|
78
|
+
status: 200,
|
79
|
+
body: { 'Authorisation' => { 'AccessToken' => '3f08d038-f380-4893-94a0-a08f6e60e67a' }}.to_json,
|
80
|
+
headers: { 'Content-Type' => 'application/json' },
|
81
|
+
)
|
82
|
+
|
83
|
+
response = Fortnox::API.get_access_token(
|
84
|
+
base_url: 'http://api.fortnox.se/3/',
|
85
|
+
client_secret: 'P5K5vE3Kun',
|
86
|
+
authorization_code: 'ea3862b0-189c-464b-8e23-1b9702365ea1',
|
87
|
+
)
|
88
|
+
|
89
|
+
response.should == "3f08d038-f380-4893-94a0-a08f6e60e67a"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
File without changes
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Fortnox::API::Customer::Validator do
|
4
|
+
|
5
|
+
describe '.validate' do
|
6
|
+
context 'Customer with valid, simple attributes' do
|
7
|
+
it 'is valid' do
|
8
|
+
customer = Fortnox::API::Customer.new( name: 'Test' )
|
9
|
+
validator = Fortnox::API::Customer::Validator
|
10
|
+
|
11
|
+
expect( validator.validate( customer )).to eql( true )
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'Customer with invalid sales_account' do
|
16
|
+
|
17
|
+
let( :customer ){ Fortnox::API::Customer.new( sales_account: 99999 )}
|
18
|
+
let( :validator ){ Fortnox::API::Customer::Validator }
|
19
|
+
|
20
|
+
it 'is invalid' do
|
21
|
+
expect( validator.validate( customer )).to eql( false )
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'includes "sales_account" in violations' do
|
25
|
+
validator.validate( customer )
|
26
|
+
|
27
|
+
expect( validator.violations.inspect ).to include( 'sales_account' )
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class TestEntity < Fortnox::API::Entity
|
4
|
+
attribute :private, String, writer: :private
|
5
|
+
attribute :string, String
|
6
|
+
attribute :number, Integer, default: 42
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Fortnox::API::Entity do
|
10
|
+
|
11
|
+
describe '.new' do
|
12
|
+
context 'with basic attribute' do
|
13
|
+
it 'works' do
|
14
|
+
test = TestEntity.new( string: 'Test' )
|
15
|
+
|
16
|
+
expect( test.class ).to eql( TestEntity )
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '.update' do
|
22
|
+
context 'with new, simple value' do
|
23
|
+
it 'returns a new object' do
|
24
|
+
original = TestEntity.new( string: 'Test' )
|
25
|
+
variant = original.update( string: 'Variant' )
|
26
|
+
|
27
|
+
expect( variant ).to_not eql( original )
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns a object of the same class' do
|
31
|
+
original = TestEntity.new( string: 'Test' )
|
32
|
+
variant = original.update( string: 'Variant' )
|
33
|
+
|
34
|
+
expect( variant.class ).to eql( original.class )
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'returns a object with the new value' do
|
38
|
+
original = TestEntity.new( string: 'Test' )
|
39
|
+
variant = original.update( string: 'Variant' )
|
40
|
+
|
41
|
+
expect( variant.string ).to eql( 'Variant' )
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'with the same, simple value' do
|
46
|
+
it 'returns the same object' do
|
47
|
+
original = TestEntity.new( string: 'Test' )
|
48
|
+
variant = original.update( string: 'Test' )
|
49
|
+
|
50
|
+
expect( variant ).to eql( original )
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'returns a object with the same value' do
|
54
|
+
original = TestEntity.new( string: 'Test' )
|
55
|
+
variant = original.update( string: 'Test' )
|
56
|
+
|
57
|
+
expect( variant.string ).to eql( 'Test' )
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
ENV['RUBY_ENV'] = 'test'
|
2
|
+
|
3
|
+
require 'fortnox/api'
|
4
|
+
require 'webmock/rspec'
|
5
|
+
require 'pry'
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.run_all_when_everything_filtered = true
|
9
|
+
config.filter_run :focus
|
10
|
+
|
11
|
+
# Run specs in random order to surface order dependencies. If you find an
|
12
|
+
# order dependency and want to debug it, you can fix the order by providing
|
13
|
+
# the seed, which is printed after each run.
|
14
|
+
# --seed 1234
|
15
|
+
config.order = 'random'
|
16
|
+
end
|
17
|
+
|
18
|
+
# Force disable the dotenv gem
|
19
|
+
ENV = {}
|
metadata
CHANGED
@@ -1,31 +1,157 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fortnox-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonas Schubert Erlandsson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-04-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.13'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.13'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dotenv
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: virtus
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: vanguard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.0'
|
13
69
|
- !ruby/object:Gem::Dependency
|
14
70
|
name: bundler
|
15
71
|
requirement: !ruby/object:Gem::Requirement
|
16
72
|
requirements:
|
17
73
|
- - "~>"
|
18
74
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
75
|
+
version: '1.9'
|
20
76
|
type: :development
|
21
77
|
prerelease: false
|
22
78
|
version_requirements: !ruby/object:Gem::Requirement
|
23
79
|
requirements:
|
24
80
|
- - "~>"
|
25
81
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
82
|
+
version: '1.9'
|
27
83
|
- !ruby/object:Gem::Dependency
|
28
84
|
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '10.4'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '10.4'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.2'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.2'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: guard
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '2.12'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '2.12'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: guard-rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '4.5'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '4.5'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: webmock
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '1.21'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '1.21'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: pry
|
29
155
|
requirement: !ruby/object:Gem::Requirement
|
30
156
|
requirements:
|
31
157
|
- - ">="
|
@@ -38,9 +164,11 @@ dependencies:
|
|
38
164
|
- - ">="
|
39
165
|
- !ruby/object:Gem::Version
|
40
166
|
version: '0'
|
41
|
-
description: This gem uses
|
42
|
-
|
43
|
-
|
167
|
+
description: This gem uses the HTTParty library to abstract away the REST calls. It
|
168
|
+
gives you access to a number of objects that behave a lot like ActiveRecord instances,
|
169
|
+
giving you access to methods like `all`, `find`, `find_by_...` and so on. And each
|
170
|
+
individual instance can be easaly persistable to Fortnox again using the `save`
|
171
|
+
method.
|
44
172
|
email:
|
45
173
|
- jonas.schubert.erlandsson@my-codeworks.com
|
46
174
|
executables: []
|
@@ -48,13 +176,35 @@ extensions: []
|
|
48
176
|
extra_rdoc_files: []
|
49
177
|
files:
|
50
178
|
- ".gitignore"
|
179
|
+
- ".rspec"
|
180
|
+
- ".ruby-version"
|
181
|
+
- ".travis.yml"
|
51
182
|
- Gemfile
|
183
|
+
- Gemfile.lock
|
184
|
+
- Guardfile
|
52
185
|
- LICENSE.txt
|
53
186
|
- README.md
|
54
187
|
- Rakefile
|
55
188
|
- fortnox-api.gemspec
|
56
189
|
- lib/fortnox/api.rb
|
190
|
+
- lib/fortnox/api/base.rb
|
191
|
+
- lib/fortnox/api/class_methods.rb
|
192
|
+
- lib/fortnox/api/customer.rb
|
193
|
+
- lib/fortnox/api/customer/entity.rb
|
194
|
+
- lib/fortnox/api/customer/repository.rb
|
195
|
+
- lib/fortnox/api/customer/validator.rb
|
196
|
+
- lib/fortnox/api/entity.rb
|
197
|
+
- lib/fortnox/api/repository/base.rb
|
198
|
+
- lib/fortnox/api/repository/json_convertion.rb
|
199
|
+
- lib/fortnox/api/repository/loaders.rb
|
200
|
+
- lib/fortnox/api/repository/savers.rb
|
201
|
+
- lib/fortnox/api/validator.rb
|
57
202
|
- lib/fortnox/api/version.rb
|
203
|
+
- spec/fortnox/api/base_spec.rb
|
204
|
+
- spec/fortnox/api/customer/repository_spec.rb
|
205
|
+
- spec/fortnox/api/customer/validator_spec.rb
|
206
|
+
- spec/fortnox/api/entity_spec.rb
|
207
|
+
- spec/spec_helper.rb
|
58
208
|
homepage: http://github.com/my-codeworks/fortnox-api
|
59
209
|
licenses:
|
60
210
|
- MIT
|
@@ -79,4 +229,9 @@ rubygems_version: 2.2.2
|
|
79
229
|
signing_key:
|
80
230
|
specification_version: 4
|
81
231
|
summary: Gem to use Fortnox REST API in Ruby.
|
82
|
-
test_files:
|
232
|
+
test_files:
|
233
|
+
- spec/fortnox/api/base_spec.rb
|
234
|
+
- spec/fortnox/api/customer/repository_spec.rb
|
235
|
+
- spec/fortnox/api/customer/validator_spec.rb
|
236
|
+
- spec/fortnox/api/entity_spec.rb
|
237
|
+
- spec/spec_helper.rb
|