vend 0.0.8 → 0.0.9

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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +57 -0
  3. data/README.rdoc +1 -1
  4. data/Rakefile +1 -1
  5. data/example.rb +3 -3
  6. data/lib/vend.rb +2 -1
  7. data/lib/vend/base.rb +12 -12
  8. data/lib/vend/base_factory.rb +2 -6
  9. data/lib/vend/client.rb +5 -5
  10. data/lib/vend/http_client.rb +30 -31
  11. data/lib/vend/null_logger.rb +9 -5
  12. data/lib/vend/oauth2/auth_code.rb +7 -10
  13. data/lib/vend/oauth2/client.rb +1 -5
  14. data/lib/vend/pagination_info.rb +2 -1
  15. data/lib/vend/resource/customer.rb +1 -3
  16. data/lib/vend/resource/outlet.rb +0 -2
  17. data/lib/vend/resource/payment_type.rb +0 -2
  18. data/lib/vend/resource/product.rb +0 -2
  19. data/lib/vend/resource/register.rb +0 -2
  20. data/lib/vend/resource/register_sale.rb +2 -5
  21. data/lib/vend/resource/register_sale_product.rb +1 -1
  22. data/lib/vend/resource/supplier.rb +23 -0
  23. data/lib/vend/resource/tax.rb +0 -2
  24. data/lib/vend/resource/user.rb +0 -2
  25. data/lib/vend/resource_collection.rb +11 -15
  26. data/lib/vend/scope.rb +1 -2
  27. data/lib/vend/version.rb +1 -1
  28. data/spec/integration/customer_spec.rb +12 -9
  29. data/spec/integration/outlet_spec.rb +2 -3
  30. data/spec/integration/payment_types_spec.rb +1 -2
  31. data/spec/integration/product_spec.rb +26 -29
  32. data/spec/integration/register_sale_spec.rb +9 -10
  33. data/spec/integration/register_spec.rb +1 -2
  34. data/spec/integration/supplier_spec.rb +14 -0
  35. data/spec/integration/tax_spec.rb +1 -2
  36. data/spec/integration/user_spec.rb +1 -2
  37. data/spec/mock_responses/suppliers.json +36 -0
  38. data/spec/spec_helper.rb +1 -2
  39. data/spec/support/matchers/have_attributes.rb +3 -3
  40. data/spec/support/shared_examples/integration.rb +7 -9
  41. data/spec/support/shared_examples/logger.rb +21 -10
  42. data/spec/vend/base_factory_spec.rb +11 -12
  43. data/spec/vend/base_spec.rb +22 -23
  44. data/spec/vend/client_spec.rb +40 -39
  45. data/spec/vend/http_client_spec.rb +70 -62
  46. data/spec/vend/null_logger_spec.rb +1 -1
  47. data/spec/vend/oauth2/auth_code_spec.rb +18 -17
  48. data/spec/vend/oauth2/client_spec.rb +21 -21
  49. data/spec/vend/pagination_info_spec.rb +40 -17
  50. data/spec/vend/resource/register_sale_product_spec.rb +8 -6
  51. data/spec/vend/resource/register_sale_spec.rb +7 -8
  52. data/spec/vend/resource_collection_spec.rb +108 -95
  53. data/spec/vend/scope_spec.rb +20 -12
  54. data/vend.gemspec +5 -6
  55. metadata +10 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 36886eb6986fbeb8cea81493ff3f87cfc75d2e7c
4
- data.tar.gz: d0bc6a8d32403071b1bcead22e49bd74771cb83b
3
+ metadata.gz: 64137299cf2287fec6feb5741e6f94d867ba0d43
4
+ data.tar.gz: 94ac4b34cb4b594b161bc19a8f7ad0733b25357e
5
5
  SHA512:
6
- metadata.gz: de2eeb7b4b76dd5d1fbbad65784fb63df20c1cd80314886e7cf9bbc5e69642c92340bbcd94c7ff9988d13f07481b9b38cabaac129094e81129bc8d414e352a44
7
- data.tar.gz: e1539bfb0b731bb01b9ce40a38d888518b32db7dc66bc259fb223bc5b31048a07f388e52f6c22889641f4adb8e280a7c9e06645f6405e4c5cc01b9f461b885f3
6
+ metadata.gz: 22537fdc5eec7d1be785e5b4b3a4c4b9926df3b1da3509fa52f4c1f7af4171289ab42c2f65c8047d59e8ba9837675431ba4c2e70d672953720d8b1b3c5ccdcb2
7
+ data.tar.gz: 4b7ac00c0663fbd08df7b16308d49bd0394319f8c1bcb9598d6a6c14b36ec2028ffe497a2cef8603ca83b5cbde3e15063dc5eb19e6ecafdf88da1596ddf5a0f4
@@ -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
@@ -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://docs.google.com/document/pub?id=13JiV6771UcrkmawFRxzvVl3tf5PGSTBH56RYy0-5cps
8
+ https://developers.vendhq.com/documentation
9
9
 
10
10
  == Using Vend API via Oauth 2.0
11
11
 
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require 'rdoc/task'
6
6
 
7
7
  Dir.glob('lib/tasks/*.rake').each { |r| import r }
8
8
 
9
- task :default => [:spec]
9
+ task default: [:spec]
10
10
 
11
11
  desc "Run RSpec tests"
12
12
  RSpec::Core::RakeTask.new(:spec)
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 and USERNAME and PASSWORD
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', :method => :put, :body => '{"foo":"bar"}')
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', :method => :post, :body => '{"customer_code":"foo"}')
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 ######"
@@ -1,4 +1,4 @@
1
- $: << File.expand_path(File.dirname(__FILE__))
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'
@@ -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 ; self ; end).instance_eval do
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, :url_params => { field.to_sym => query }
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, :attrs => attrs)
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(:url_params => {:page_size => 500})
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, *args, &block)
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, :method => :delete)
193
+ client.request(singular_name, method: :delete)
195
194
  true
196
195
  end
197
196
 
198
- protected
197
+ protected
198
+
199
199
  def attribute_value_for(attribute_name)
200
- if self.class.attribute_casts.has_key? attribute_name
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
@@ -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
@@ -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
- :base_url => base_url, :username => username, :password => password
78
+ base_url: base_url, username: username, password: password
77
79
  )
78
80
  end
79
-
80
81
  end
81
-
82
82
  end
@@ -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
- alias :verify_ssl? :verify_ssl
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.has_key?(:verify_ssl)
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', :method => :post) will perform a POST request for
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', :url_params => {:bar => "baz"}) will request
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', :method => :delete, :id => 1) will request
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', :method => :post, :body => '{\"baz\":\"baloo\"}'
61
+ # request('foo', method: :post, body: '{\"baz\":\"baloo\"}'
63
62
  #
64
63
  def request(path, options = {})
65
- options = {:method => :get, :redirect_count => 0}.merge options
64
+ options = {method: :get, redirect_count: 0}.merge options
66
65
  raise RedirectionLimitExceeded if options[:redirect_count] > 10
67
- url = if path.kind_of?(URI)
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.kind_of?(Net::HTTPRedirection)
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.kind_of?(Net::HTTPUnauthorized)
91
- raise HTTPError.new(response) unless response.kind_of?(Net::HTTPSuccess)
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? or response.body.empty?
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
- # Internal method to parse URL parameters.
107
- # Returns an empty string from a nil argument
108
- #
109
- # E.g. url_params_for({:field => "value"}) will return ?field=value
110
- # url_params_for({:field => ["value1","value2"]}) will return ?field[]=value1&field[]=value2
111
- protected
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 = Array.new
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::escape(key.to_s)}" }.join('&')
118
+ ary << value.collect { |key| "#{option}%5B%5D=#{CGI.escape(key.to_s)}" }.join('&')
118
119
  else
119
- ary << "#{option}=#{CGI::escape(value.to_s)}"
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
- protected
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
- path += "/#{options[:id]}"
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
@@ -1,9 +1,13 @@
1
1
  module Vend
2
2
  class NullLogger
3
- def debug(*args) ; end
4
- def info(*args) ; end
5
- def warn(*args) ; end
6
- def error(*args) ; end
7
- def fatal(*args) ; end
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