vend 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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