vend 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +57 -0
- data/README.rdoc +1 -1
- data/Rakefile +1 -1
- data/example.rb +3 -3
- data/lib/vend.rb +2 -1
- data/lib/vend/base.rb +12 -12
- data/lib/vend/base_factory.rb +2 -6
- data/lib/vend/client.rb +5 -5
- data/lib/vend/http_client.rb +30 -31
- data/lib/vend/null_logger.rb +9 -5
- data/lib/vend/oauth2/auth_code.rb +7 -10
- data/lib/vend/oauth2/client.rb +1 -5
- data/lib/vend/pagination_info.rb +2 -1
- data/lib/vend/resource/customer.rb +1 -3
- data/lib/vend/resource/outlet.rb +0 -2
- data/lib/vend/resource/payment_type.rb +0 -2
- data/lib/vend/resource/product.rb +0 -2
- data/lib/vend/resource/register.rb +0 -2
- data/lib/vend/resource/register_sale.rb +2 -5
- data/lib/vend/resource/register_sale_product.rb +1 -1
- data/lib/vend/resource/supplier.rb +23 -0
- data/lib/vend/resource/tax.rb +0 -2
- data/lib/vend/resource/user.rb +0 -2
- data/lib/vend/resource_collection.rb +11 -15
- data/lib/vend/scope.rb +1 -2
- data/lib/vend/version.rb +1 -1
- data/spec/integration/customer_spec.rb +12 -9
- data/spec/integration/outlet_spec.rb +2 -3
- data/spec/integration/payment_types_spec.rb +1 -2
- data/spec/integration/product_spec.rb +26 -29
- data/spec/integration/register_sale_spec.rb +9 -10
- data/spec/integration/register_spec.rb +1 -2
- data/spec/integration/supplier_spec.rb +14 -0
- data/spec/integration/tax_spec.rb +1 -2
- data/spec/integration/user_spec.rb +1 -2
- data/spec/mock_responses/suppliers.json +36 -0
- data/spec/spec_helper.rb +1 -2
- data/spec/support/matchers/have_attributes.rb +3 -3
- data/spec/support/shared_examples/integration.rb +7 -9
- data/spec/support/shared_examples/logger.rb +21 -10
- data/spec/vend/base_factory_spec.rb +11 -12
- data/spec/vend/base_spec.rb +22 -23
- data/spec/vend/client_spec.rb +40 -39
- data/spec/vend/http_client_spec.rb +70 -62
- data/spec/vend/null_logger_spec.rb +1 -1
- data/spec/vend/oauth2/auth_code_spec.rb +18 -17
- data/spec/vend/oauth2/client_spec.rb +21 -21
- data/spec/vend/pagination_info_spec.rb +40 -17
- data/spec/vend/resource/register_sale_product_spec.rb +8 -6
- data/spec/vend/resource/register_sale_spec.rb +7 -8
- data/spec/vend/resource_collection_spec.rb +108 -95
- data/spec/vend/scope_spec.rb +20 -12
- data/vend.gemspec +5 -6
- metadata +10 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 64137299cf2287fec6feb5741e6f94d867ba0d43
|
4
|
+
data.tar.gz: 94ac4b34cb4b594b161bc19a8f7ad0733b25357e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22537fdc5eec7d1be785e5b4b3a4c4b9926df3b1da3509fa52f4c1f7af4171289ab42c2f65c8047d59e8ba9837675431ba4c2e70d672953720d8b1b3c5ccdcb2
|
7
|
+
data.tar.gz: 4b7ac00c0663fbd08df7b16308d49bd0394319f8c1bcb9598d6a6c14b36ec2028ffe497a2cef8603ca83b5cbde3e15063dc5eb19e6ecafdf88da1596ddf5a0f4
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# class Example
|
2
|
+
# ...
|
3
|
+
# private
|
4
|
+
# ...
|
5
|
+
# end
|
6
|
+
Style/AccessModifierIndentation:
|
7
|
+
EnforcedStyle: outdent
|
8
|
+
|
9
|
+
# Allows foo(bar: baz)
|
10
|
+
Style/BracesAroundHashParameters:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Style/DotPosition:
|
14
|
+
EnforcedStyle: leading
|
15
|
+
|
16
|
+
Style/IndentHash:
|
17
|
+
EnforcedStyle: consistent
|
18
|
+
|
19
|
+
Style/LineLength:
|
20
|
+
Max: 120
|
21
|
+
|
22
|
+
Style/RedundantSelf:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
# We like neatly-aligned code
|
26
|
+
Style/SingleSpaceBeforeFirstArg:
|
27
|
+
Enabled: false
|
28
|
+
|
29
|
+
Style/SpaceAroundEqualsInParameterDefault:
|
30
|
+
Enabled: false
|
31
|
+
|
32
|
+
Style/SpaceInsideHashLiteralBraces:
|
33
|
+
Enabled: false
|
34
|
+
|
35
|
+
# Allow single or double quotes
|
36
|
+
Style/StringLiterals:
|
37
|
+
Enabled: false
|
38
|
+
|
39
|
+
# Disable this until we can work out how to allow aligning of assignments
|
40
|
+
# https://github.com/bbatsov/rubocop/blob/master/spec/rubocop/cop/style/extra_spacing_spec.rb#L23
|
41
|
+
Style/ExtraSpacing:
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
Style/WordArray:
|
45
|
+
Enabled: false
|
46
|
+
|
47
|
+
Style/NumericLiterals:
|
48
|
+
Enabled: false
|
49
|
+
|
50
|
+
Style/SignalException:
|
51
|
+
Enabled: false
|
52
|
+
|
53
|
+
Metrics/ClassLength:
|
54
|
+
Enabled: false
|
55
|
+
|
56
|
+
Style/MultilineOperationIndentation:
|
57
|
+
Enabled: false
|
data/README.rdoc
CHANGED
@@ -5,7 +5,7 @@ This gem provides access to Vend's REST API.
|
|
5
5
|
== Vend API Documentation
|
6
6
|
|
7
7
|
At the time of writing, this is located at
|
8
|
-
https://
|
8
|
+
https://developers.vendhq.com/documentation
|
9
9
|
|
10
10
|
== Using Vend API via Oauth 2.0
|
11
11
|
|
data/Rakefile
CHANGED
data/example.rb
CHANGED
@@ -5,7 +5,7 @@ STORE = ARGV[0]
|
|
5
5
|
USERNAME = ARGV[1]
|
6
6
|
PASSWORD = ARGV[2]
|
7
7
|
|
8
|
-
unless STORE
|
8
|
+
unless STORE && USERNAME && PASSWORD
|
9
9
|
$stderr.puts "Usage: example.rb store username password"
|
10
10
|
exit 1
|
11
11
|
end
|
@@ -16,7 +16,7 @@ logger = Log4r::Logger.new 'vend'
|
|
16
16
|
logger.outputters = Log4r::Outputter.stdout
|
17
17
|
client.http_client.logger = client.logger = logger
|
18
18
|
|
19
|
-
# puts client.request('products', :
|
19
|
+
# puts client.request('products', method: :put, body: '{"foo":"bar"}')
|
20
20
|
|
21
21
|
# puts "###### Products ######"
|
22
22
|
# client.Product.all.each do |product|
|
@@ -29,7 +29,7 @@ client.http_client.logger = client.logger = logger
|
|
29
29
|
# end
|
30
30
|
#
|
31
31
|
# puts "###### Creating a Customer ######"
|
32
|
-
# response = client.request('customers', :
|
32
|
+
# response = client.request('customers', method: :post, body: '{"customer_code":"foo"}')
|
33
33
|
# puts response
|
34
34
|
#
|
35
35
|
# puts "###### Finding a Customer by name ######"
|
data/lib/vend.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
$LOAD_PATH << File.expand_path(File.dirname(__FILE__))
|
2
2
|
require 'active_support/inflector'
|
3
3
|
|
4
4
|
require 'vend/exception'
|
@@ -19,6 +19,7 @@ require 'vend/resource/register_sale'
|
|
19
19
|
require 'vend/resource/register_sale_product'
|
20
20
|
require 'vend/resource/tax'
|
21
21
|
require 'vend/resource/user'
|
22
|
+
require 'vend/resource/supplier'
|
22
23
|
|
23
24
|
require 'vend/http_client'
|
24
25
|
require 'vend/client'
|
data/lib/vend/base.rb
CHANGED
@@ -5,7 +5,6 @@ module Vend
|
|
5
5
|
# Not all CRUD actions are available for every resource, and at current there
|
6
6
|
# is no PUT endpoint and hence no update action
|
7
7
|
class Base
|
8
|
-
|
9
8
|
# Reference to the Vend::Client client object providing the HTTP interface to the
|
10
9
|
# API
|
11
10
|
attr_reader :client
|
@@ -26,6 +25,7 @@ module Vend
|
|
26
25
|
def self.attribute_casts
|
27
26
|
@attribute_casts ||= {}
|
28
27
|
end
|
28
|
+
|
29
29
|
# Returns the endpoint name for the resource, used in API urls when making
|
30
30
|
# requests.
|
31
31
|
def self.endpoint_name
|
@@ -82,7 +82,7 @@ module Vend
|
|
82
82
|
#
|
83
83
|
# And return the corresponding collection of resources
|
84
84
|
def self.url_scope(method_name)
|
85
|
-
(class << self
|
85
|
+
(class << self; self; end).instance_eval do
|
86
86
|
define_method(method_name) do |client, arg|
|
87
87
|
initialize_collection(client, collection_name).scope(method_name, arg)
|
88
88
|
end
|
@@ -91,26 +91,26 @@ module Vend
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def self.findable_by(field, options = {})
|
94
|
-
|
95
|
-
(class << self ; self ; end).instance_eval do
|
94
|
+
(class << self; self; end).instance_eval do
|
96
95
|
define_method("find_by_#{field}") do |client, *args|
|
97
96
|
search(client, options[:as] || field, *args)
|
98
97
|
end
|
99
98
|
end
|
100
99
|
end
|
100
|
+
|
101
101
|
# Sends a search request to the API and initializes a collection of Resources
|
102
102
|
# from the response.
|
103
103
|
# This method is only used internally by find_by_field methods.
|
104
104
|
def self.search(client, field, query)
|
105
105
|
initialize_collection(
|
106
|
-
client, collection_name, :
|
106
|
+
client, collection_name, url_params: { field.to_sym => query }
|
107
107
|
)
|
108
108
|
end
|
109
109
|
|
110
110
|
# Builds a new instance of the described resource using the specified
|
111
111
|
# attributes.
|
112
112
|
def self.build(client, attrs)
|
113
|
-
self.new(client, :
|
113
|
+
self.new(client, attrs: attrs)
|
114
114
|
end
|
115
115
|
|
116
116
|
# Builds a collection of instances from a JSON response
|
@@ -131,7 +131,6 @@ module Vend
|
|
131
131
|
ResourceCollection.new(client, self, endpoint, args)
|
132
132
|
end
|
133
133
|
|
134
|
-
|
135
134
|
# Attempts to pull a singular object from Vend through the singular GET
|
136
135
|
# endpoint.
|
137
136
|
def self.find(client, id)
|
@@ -150,7 +149,7 @@ module Vend
|
|
150
149
|
# request. I.e, to default to 500 items per page:
|
151
150
|
#
|
152
151
|
# def default_collection_request_args
|
153
|
-
# super.merge(:
|
152
|
+
# super.merge(url_params: {page_size: 500})
|
154
153
|
# end
|
155
154
|
#
|
156
155
|
def self.default_collection_request_args
|
@@ -169,7 +168,7 @@ module Vend
|
|
169
168
|
|
170
169
|
# Overrides method_missing to query the attrs hash for the value stored
|
171
170
|
# at the specified key before proxying it to the object
|
172
|
-
def method_missing(method_name, *
|
171
|
+
def method_missing(method_name, *_args, &_block)
|
173
172
|
if attrs.keys.include? method_name.to_s
|
174
173
|
attribute_value_for(method_name)
|
175
174
|
else
|
@@ -191,13 +190,14 @@ module Vend
|
|
191
190
|
def delete!
|
192
191
|
raise(Vend::Resource::IllegalAction,
|
193
192
|
"#{self.class.name} has no unique ID") unless attrs['id']
|
194
|
-
client.request(singular_name, :
|
193
|
+
client.request(singular_name, method: :delete)
|
195
194
|
true
|
196
195
|
end
|
197
196
|
|
198
|
-
|
197
|
+
protected
|
198
|
+
|
199
199
|
def attribute_value_for(attribute_name)
|
200
|
-
if self.class.attribute_casts.
|
200
|
+
if self.class.attribute_casts.key? attribute_name
|
201
201
|
case self.class.attribute_casts[attribute_name].to_s
|
202
202
|
when "Float"
|
203
203
|
return attrs[attribute_name.to_s].to_f
|
data/lib/vend/base_factory.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
module Vend
|
2
|
-
|
3
2
|
class BaseFactory
|
4
|
-
|
5
3
|
attr_reader :client, :target_class
|
6
4
|
|
7
5
|
def initialize(client, target_class)
|
@@ -22,13 +20,11 @@ module Vend
|
|
22
20
|
end
|
23
21
|
|
24
22
|
## Generates find_by_field methods which call a search on the target class
|
25
|
-
#def self.findable_by(field, options = {})
|
23
|
+
# def self.findable_by(field, options = {})
|
26
24
|
# url_param = options[:as] || field
|
27
25
|
# define_method "find_by_#{field.to_s}" do |*args|
|
28
26
|
# target_class.send(:search, @client, url_param, *args)
|
29
27
|
# end
|
30
|
-
#end
|
31
|
-
|
28
|
+
# end
|
32
29
|
end
|
33
|
-
|
34
30
|
end
|
data/lib/vend/client.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
|
3
3
|
module Vend #:nodoc:
|
4
|
-
|
5
4
|
# Main access point which allows resources within the Vend gem to
|
6
5
|
# make HTTP requests to the Vend API.
|
7
6
|
#
|
@@ -10,7 +9,6 @@ module Vend #:nodoc:
|
|
10
9
|
# * a valid username and password
|
11
10
|
#
|
12
11
|
class Client
|
13
|
-
|
14
12
|
DEFAULT_OPTIONS = {}
|
15
13
|
|
16
14
|
extend Forwardable
|
@@ -61,6 +59,10 @@ module Vend #:nodoc:
|
|
61
59
|
Vend::BaseFactory.new(self, Resource::User)
|
62
60
|
end
|
63
61
|
|
62
|
+
def Supplier #:nodoc:
|
63
|
+
Vend::BaseFactory.new(self, Resource::Supplier)
|
64
|
+
end
|
65
|
+
|
64
66
|
# Returns the base API url for the client.
|
65
67
|
# E.g. for the store 'foo', it returns https://foo.vendhq.com/api/
|
66
68
|
def base_url
|
@@ -73,10 +75,8 @@ module Vend #:nodoc:
|
|
73
75
|
|
74
76
|
def http_client_options
|
75
77
|
options.merge(
|
76
|
-
:
|
78
|
+
base_url: base_url, username: username, password: password
|
77
79
|
)
|
78
80
|
end
|
79
|
-
|
80
81
|
end
|
81
|
-
|
82
82
|
end
|
data/lib/vend/http_client.rb
CHANGED
@@ -3,7 +3,6 @@ require 'json'
|
|
3
3
|
require 'cgi'
|
4
4
|
module Vend
|
5
5
|
class HttpClient
|
6
|
-
|
7
6
|
UNAUTHORIZED_MESSAGE = "Client not authorized. Check your store credentials are correct and try again."
|
8
7
|
# Read timeout in seconds
|
9
8
|
READ_TIMEOUT = 240
|
@@ -11,14 +10,14 @@ module Vend
|
|
11
10
|
include Logable
|
12
11
|
|
13
12
|
attr_accessor :base_url, :verify_ssl, :username, :password, :auth_token
|
14
|
-
|
13
|
+
alias_method :verify_ssl?, :verify_ssl
|
15
14
|
|
16
15
|
def initialize(options = {})
|
17
16
|
@base_url = options[:base_url]
|
18
17
|
@username = options[:username]
|
19
18
|
@password = options[:password]
|
20
19
|
@auth_token = options[:auth_token]
|
21
|
-
@verify_ssl = if options.
|
20
|
+
@verify_ssl = if options.key?(:verify_ssl)
|
22
21
|
options[:verify_ssl]
|
23
22
|
else
|
24
23
|
true
|
@@ -44,27 +43,27 @@ module Vend
|
|
44
43
|
#
|
45
44
|
# An optional hash of arguments may be specified. Possible options include:
|
46
45
|
# :method - The HTTP method
|
47
|
-
# E.g. request('foo', :
|
46
|
+
# E.g. request('foo', method: :post) will perform a POST request for
|
48
47
|
# http://storeurl.vendhq.com/api/foo
|
49
48
|
#
|
50
49
|
# :url_params - The URL parameters for GET requests.
|
51
|
-
# E.g. request('foo', :
|
50
|
+
# E.g. request('foo', url_params: {bar: "baz"}) will request
|
52
51
|
# http://storeurl.vendhq.com/api/foo?bar=baz
|
53
52
|
#
|
54
53
|
# :id - The ID required for performing actions on specific resources
|
55
54
|
# (e.g. delete).
|
56
|
-
# E.g. request('foos', :
|
55
|
+
# E.g. request('foos', method: :delete, id: 1) will request
|
57
56
|
# DELETE http://storeurl.vendhq.com/api/foos/1
|
58
57
|
#
|
59
58
|
# :body - The request body
|
60
59
|
# E.g. For submitting a POST to http://storeurl.vendhq.com/api/foo
|
61
60
|
# with the JSON data {"baz":"baloo"} we would call
|
62
|
-
# request('foo', :
|
61
|
+
# request('foo', method: :post, body: '{\"baz\":\"baloo\"}'
|
63
62
|
#
|
64
63
|
def request(path, options = {})
|
65
|
-
options = {:
|
64
|
+
options = {method: :get, redirect_count: 0}.merge options
|
66
65
|
raise RedirectionLimitExceeded if options[:redirect_count] > 10
|
67
|
-
url = if path.
|
66
|
+
url = if path.is_a?(URI)
|
68
67
|
path
|
69
68
|
else
|
70
69
|
URI.parse(base_url + path)
|
@@ -72,7 +71,7 @@ module Vend
|
|
72
71
|
ssl = (url.scheme == 'https')
|
73
72
|
http = get_http_connection(url.host, url.port, ssl)
|
74
73
|
|
75
|
-
# FIXME extract method
|
74
|
+
# FIXME: extract method
|
76
75
|
method = ("Net::HTTP::" + options[:method].to_s.classify).constantize
|
77
76
|
request = method.new(url.path + url_params_for(options[:url_params]))
|
78
77
|
request.basic_auth username, password if username && password
|
@@ -81,16 +80,16 @@ module Vend
|
|
81
80
|
request.body = options[:body] if options[:body]
|
82
81
|
logger.debug url
|
83
82
|
response = http.request(request)
|
84
|
-
if response.
|
83
|
+
if response.is_a?(Net::HTTPRedirection)
|
85
84
|
location = URI.parse(response['location'])
|
86
85
|
logger.debug "Following redirect to %s" % [location]
|
87
86
|
options[:redirect_count] = options[:redirect_count] + 1
|
88
87
|
request(location, options)
|
89
88
|
else
|
90
|
-
raise Unauthorized.new(UNAUTHORIZED_MESSAGE) if response.
|
91
|
-
raise HTTPError.new(response) unless response.
|
89
|
+
raise Unauthorized.new(UNAUTHORIZED_MESSAGE) if response.is_a?(Net::HTTPUnauthorized)
|
90
|
+
raise HTTPError.new(response) unless response.is_a?(Net::HTTPSuccess)
|
92
91
|
logger.debug response
|
93
|
-
JSON.parse response.body unless response.body.nil?
|
92
|
+
JSON.parse response.body unless response.body.nil? || response.body.empty?
|
94
93
|
end
|
95
94
|
end
|
96
95
|
|
@@ -103,20 +102,22 @@ module Vend
|
|
103
102
|
end
|
104
103
|
end
|
105
104
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
105
|
+
# Internal method to parse URL parameters.
|
106
|
+
# Returns an empty string from a nil argument
|
107
|
+
#
|
108
|
+
# E.g. url_params_for({field: "value"}) will return ?field=value
|
109
|
+
# url_params_for({field: ["value1","value2"]}) will return ?field[]=value1&field[]=value2
|
110
|
+
|
111
|
+
protected
|
112
|
+
|
112
113
|
def url_params_for(options)
|
113
|
-
ary =
|
114
|
+
ary = []
|
114
115
|
if !options.nil?
|
115
|
-
options.each do |option,value|
|
116
|
+
options.each do |option, value|
|
116
117
|
if value.class == Array
|
117
|
-
ary << value.collect { |key| "#{option}%5B%5D=#{CGI
|
118
|
+
ary << value.collect { |key| "#{option}%5B%5D=#{CGI.escape(key.to_s)}" }.join('&')
|
118
119
|
else
|
119
|
-
ary << "#{option}=#{CGI
|
120
|
+
ary << "#{option}=#{CGI.escape(value.to_s)}"
|
120
121
|
end
|
121
122
|
end
|
122
123
|
'?'.concat(ary.join('&'))
|
@@ -125,15 +126,13 @@ module Vend
|
|
125
126
|
end
|
126
127
|
end
|
127
128
|
|
128
|
-
|
129
|
+
protected
|
130
|
+
|
129
131
|
# Modifies path with the provided options
|
130
132
|
def expand_path_with_options(path, options)
|
131
|
-
# FIXME - Remove from here
|
132
|
-
if options[:id]
|
133
|
-
|
134
|
-
end
|
135
|
-
return path
|
133
|
+
# FIXME: - Remove from here
|
134
|
+
path += "/#{options[:id]}" if options[:id]
|
135
|
+
path
|
136
136
|
end
|
137
|
-
|
138
137
|
end
|
139
138
|
end
|
data/lib/vend/null_logger.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
module Vend
|
2
2
|
class NullLogger
|
3
|
-
def debug(*
|
4
|
-
|
5
|
-
def
|
6
|
-
|
7
|
-
def
|
3
|
+
def debug(*_args); end
|
4
|
+
|
5
|
+
def info(*_args); end
|
6
|
+
|
7
|
+
def warn(*_args); end
|
8
|
+
|
9
|
+
def error(*_args); end
|
10
|
+
|
11
|
+
def fatal(*_args); end
|
8
12
|
end
|
9
13
|
end
|