vending-machine 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8804a13fd883e7691d53c92783030068937095f5
4
+ data.tar.gz: 2bc3e2c3f83d0931b8c4b21a3cd6027f676afdb0
5
+ SHA512:
6
+ metadata.gz: 20adbb6dceb11c22a30fdcb12749b60f80e9da9aebd55a5a40eb9676cfe19985b75b364cedb7522afef6e1214d966b8172287e5cc456ae4b82bc54e8539f1175
7
+ data.tar.gz: 6539ab4faa6cce8598c6a5c10fb0256e6224df8ef102e695e74219c3e7db618099f8cd2913231e0b8e08877749e2987d5f2c5810447742d1290b77b07f9d2e83
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/README.md CHANGED
@@ -2,9 +2,12 @@
2
2
 
3
3
  Access your [Vend Store](http://vendhq.com) in Ruby! Vending Machine turns the [Vend API](http://docs.vendhq.com/) into Ruby objects, including type coercion and nested objects.
4
4
 
5
+
5
6
  ```ruby
6
- # Create an instance of your store
7
- store = Vend::Store.new('store_name', 'user_name', 'password')
7
+ # Create an instance of your store with Basic Auth
8
+ store = Vend::Store.new({:store_name => 'store_name', :username => 'user_name', :password => 'password'})
9
+ # Create an instance of your store with OAuth
10
+ store = Vend::Store.new({:store_name => 'store_name', :auth_token => 'auth_token'})
8
11
 
9
12
  # Get all your products
10
13
  store.products.order('name', 'ASC').map &:name
@@ -35,13 +38,27 @@ Or install it yourself as:
35
38
 
36
39
  ## Usage
37
40
 
41
+ ### Basic Auth and Oauth Support
42
+ Authentication defaults to Basic Auth. You can switch to Oauth by adding the following code to an initializer.
43
+
44
+ ```ruby
45
+ # config/vending_machine.rb
46
+ Vend.config do |config|
47
+ config.auth_method = :oauth # defaults to :basic_auth
48
+ end
49
+
50
+ ```
51
+
38
52
  ### Get a store instance
39
53
 
40
54
  All usage revolves around your store, as per Vend itself
41
55
 
42
56
 
43
57
  ```ruby
44
- store = Vend::Store.new('store_name', 'user_name', 'password')
58
+ # Create an instance of your store with Basic Auth
59
+ store = Vend::Store.new({:store_name => 'store_name', :username => 'user_name', :password => 'password'})
60
+ #Or Create an instance of your store with OAuth
61
+ store = Vend::Store.new({:store_name => 'store_name', :auth_token => 'auth_token'})
45
62
  ```
46
63
 
47
64
  Once you have a store instance you can retrieve your objects
@@ -114,6 +131,28 @@ product.save!
114
131
  => true
115
132
  ```
116
133
 
134
+ #### Creating a Product Variant
135
+
136
+ Product variants have the same `handle` as another product, but a different `sku`. You can create a variant of a product easily with the `#build_variant`, `#create_variant` and `#create_variant!` methods.
137
+
138
+ Underneath the hood, it's simply copying attributes to a new instance, then changing the `sku` to either a provided new sku, or appending an incrementing integer to an existing `sku`.
139
+
140
+ ```ruby
141
+ product.sku = 'my-product'
142
+ product.build_variant(sku: 'my-product-alt')
143
+ => #<Vend::Product>
144
+
145
+ product.build_variant(sku: 'my-product-alt').sku
146
+ => 'my-product-alt'
147
+
148
+ product.build_variant.sku
149
+ => 'my-product-1'
150
+
151
+ product.sku = 'my-product-3'
152
+ product.build_variant.sku
153
+ => 'my-product-4'
154
+ ```
155
+
117
156
  ### Register Sales
118
157
 
119
158
  ```ruby
@@ -136,6 +175,18 @@ store.registers.map &:name
136
175
  => ["Main Register", "Back office Register"]
137
176
  ```
138
177
 
178
+ #### Open register
179
+
180
+ ```ruby
181
+ store.registers.first.open!
182
+ ```
183
+
184
+ #### Close register
185
+
186
+ ```ruby
187
+ store.registers.first.close!
188
+ ```
189
+
139
190
  ### Suppliers
140
191
 
141
192
  ```ruby
@@ -164,12 +215,25 @@ store.users.map &:name
164
215
  => ["A cashier", "Mal Curtis", "Joe Bloggs"]
165
216
  ```
166
217
 
218
+ ## Tips
219
+
220
+ ### Figuring out what attributes a resource has
221
+ Want to know what attributes are on a particular resource? Use `#attributes`. Vending Machine will map all returned attributes to a resource, only a portion of which are defined in the resource’s code (for validation and type coercion).
222
+
223
+ ```ruby
224
+ store.taxes.first.attributes
225
+ => {:id=>"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
226
+ :rate=>0.15,
227
+ :default=>true,
228
+ :name=>"NZ GST"}
229
+ ```
230
+
167
231
  ## Status
168
232
  * COMPLETE: GET index resources are implemented, with the exception of Stock Control
169
233
  * IN PROGRESS: find singular resources `store.products.find('some_id')`
170
234
  * IN PROGRESS: create register sales `store.sale.create products: [product1, product2]`
171
235
  * COMPLETE: create products
172
- * IN PROGRESS: Create Product Variants (This seems to happen when posting a new product with a same handle, but different sku)
236
+ * COMPLETE: Create Product Variants (This seems to happen when posting a new product with a same handle, but different sku)
173
237
  * TODO: Delete resources
174
238
  * TODO: Scopes for Customer and Register Sales
175
239
 
@@ -2,6 +2,7 @@ $: << File.expand_path(File.dirname(__FILE__))
2
2
  %w{
3
3
  version
4
4
  errors
5
+ config
5
6
 
6
7
  modules/declarative_setters
7
8
  modules/finders
@@ -42,5 +43,13 @@ module Vend
42
43
  def domain
43
44
  @domain || "vendhq.com"
44
45
  end
46
+
47
+ def config(&block)
48
+ if block_given?
49
+ block.call(Vend::Config)
50
+ else
51
+ Vend::Config
52
+ end
53
+ end
45
54
  end
46
55
  end
@@ -0,0 +1,22 @@
1
+ module Vend
2
+ module Config
3
+ class << self
4
+
5
+ VALID_AUTHENTICATION_METHODS = %i(basic_auth oauth)
6
+ DEFAULT_AUTHENTICATION_METHOD = :basic_auth
7
+
8
+ def auth_method=(method)
9
+ if VALID_AUTHENTICATION_METHODS.include?(method.to_sym)
10
+ @auth_method = method.to_sym
11
+ else
12
+ raise Vend::InvalidConfig("%s is not a valid authentication method" % method)
13
+ end
14
+ end
15
+
16
+ def auth_method
17
+ @auth_method || DEFAULT_AUTHENTICATION_METHOD
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -9,4 +9,6 @@ module Vend
9
9
 
10
10
  class ServerError < Error; end
11
11
 
12
+ class InvalidConfig < Error; end
13
+
12
14
  end
@@ -31,6 +31,14 @@ module Vend::Paths
31
31
  [ self.class.collection_api_path, id ].compact.join("/")
32
32
  end
33
33
 
34
+ def close_path
35
+ [ self.class.collection_api_path, id, 'close' ].compact.join("/")
36
+ end
37
+
38
+ def open_path
39
+ [ self.class.collection_api_path, id, 'open' ].compact.join("/")
40
+ end
41
+
34
42
  def self.included(base)
35
43
  base.extend(ClassMethods)
36
44
  end
@@ -18,7 +18,7 @@ module Vend
18
18
 
19
19
  def save!
20
20
  save_path = id ? update_path : self.class.create_path
21
- method = id ? :put : :post
21
+ method = id ? :post : :post
22
22
  response = store.send(method, path: save_path,
23
23
  data: sendable_attributes.to_json,
24
24
  status: 200
@@ -41,6 +41,8 @@ module Vend
41
41
  self
42
42
  end
43
43
 
44
+
45
+
44
46
  private
45
47
 
46
48
  def sendable_attributes
@@ -59,7 +59,26 @@ module Vend
59
59
  end
60
60
 
61
61
  def remote_records
62
- http_response.data.first.last
62
+ # Is there pagination info?
63
+ pagination = http_response.data["pagination"]
64
+
65
+ if pagination
66
+ # Get all pages
67
+ data = []
68
+ page = 1
69
+ pages = pagination["pages"]
70
+ while page <= pages
71
+ http_response.data.delete("pagination")
72
+ data.concat(http_response.data.first.last)
73
+ @_http_response = nil
74
+ page += 1
75
+ (@parameters ||= {})[:page] = page
76
+ end
77
+ @parameters.delete(:page)
78
+ data
79
+ else
80
+ http_response.data.first.last
81
+ end
63
82
  end
64
83
 
65
84
  def records
@@ -74,3 +93,4 @@ module Vend
74
93
  end
75
94
  end
76
95
  end
96
+
@@ -5,5 +5,23 @@ module Vend
5
5
  attribute :register_close_time, DateTime
6
6
  attribute :register_open_time, DateTime
7
7
  attribute :register_open_count_sequence, Integer
8
+
9
+ # Close register
10
+ def close!
11
+ self.attributes = store.post(
12
+ path: close_path,
13
+ status: 200
14
+ ).data
15
+ self
16
+ end
17
+
18
+ # Open register
19
+ def open!
20
+ self.attributes = store.post(
21
+ path: open_path,
22
+ status: 200
23
+ ).data
24
+ self
25
+ end
8
26
  end
9
27
  end
@@ -6,8 +6,14 @@ module Vend
6
6
  class Store
7
7
  include HasResources
8
8
 
9
- def initialize name, username, password
10
- @name, @credentials = name, [ username, password ]
9
+ def initialize(credentials={})
10
+ @authenticator = Vend::Config.auth_method
11
+ case @authenticator
12
+ when :basic_auth
13
+ @name, @credentials = credentials[:store_name], [credentials[:username], credentials[:password]]
14
+ when :oauth
15
+ @name, @auth_token = credentials[:store_name], credentials[:auth_token]
16
+ end
11
17
  end
12
18
 
13
19
  ##
@@ -47,6 +53,7 @@ module Vend
47
53
  response.headers,
48
54
  response.body
49
55
  )
56
+
50
57
  end
51
58
 
52
59
  ##
@@ -95,7 +102,12 @@ module Vend
95
102
  @_faraday ||= Faraday.new(url) do |conn|
96
103
  conn.request :json
97
104
  conn.response :json
98
- conn.basic_auth *@credentials
105
+ case @authenticator
106
+ when :basic_auth
107
+ conn.basic_auth *@credentials
108
+ when :oauth
109
+ conn.authorization :Bearer, @auth_token
110
+ end
99
111
  conn.adapter Faraday.default_adapter
100
112
  end
101
113
  end
@@ -1,3 +1,3 @@
1
1
  module Vend
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -4,18 +4,28 @@ module Vend
4
4
  describe Store do
5
5
  describe "#url" do
6
6
  it "should be the store api endpoint" do
7
- store = Vend::Store.new('test-store', :a, :a)
7
+ store = Vend::Store.new({:store_name => 'test-store', :username => :a, :password => :a})
8
8
  store.send(:url).must_equal "https://test-store.vendhq.com/api"
9
9
  end
10
10
  end
11
11
 
12
- describe "#faraday" do
12
+ describe "#faraday with basic auth" do
13
13
  it "should be an authorized Faraday client" do
14
- store = Vend::Store.new('test-store', "abc", "123")
14
+ store = Vend::Store.new({:store_name => 'test-store', :username => 'abc', :password => '123'})
15
15
  conn = store.send(:faraday)
16
16
  assert auth = conn.headers['Authorization']
17
17
  assert_equal Faraday::Request::BasicAuthentication.header("abc", "123"), auth
18
18
  end
19
19
  end
20
+
21
+ describe "#faraday with oauth" do
22
+ it "should be an authorized Faraday client" do
23
+ Vend::Config.auth_method = :oauth
24
+ store = Vend::Store.new({:store_name => 'test-store', :auth_token => 'my-dummy-token'})
25
+ conn = store.send(:faraday)
26
+ assert auth = conn.headers['Authorization']
27
+ assert_equal Faraday::Request::Authorization.header("Bearer", "my-dummy-token"), auth
28
+ end
29
+ end
20
30
  end
21
31
  end
metadata CHANGED
@@ -1,158 +1,139 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vending-machine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
5
- prerelease:
4
+ version: 0.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Mal Curtis
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-12-16 00:00:00.000000000 Z
11
+ date: 2014-08-20 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: faraday
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: faraday_middleware
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: addressable
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - ">="
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - ">="
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: virtus
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ~>
59
+ - - "~>"
68
60
  - !ruby/object:Gem::Version
69
61
  version: 0.5.3
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ~>
66
+ - - "~>"
76
67
  - !ruby/object:Gem::Version
77
68
  version: 0.5.3
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: minitest
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ! '>='
73
+ - - ">="
84
74
  - !ruby/object:Gem::Version
85
75
  version: '0'
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ! '>='
80
+ - - ">="
92
81
  - !ruby/object:Gem::Version
93
82
  version: '0'
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: ansi
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
- - - ! '>='
87
+ - - ">="
100
88
  - !ruby/object:Gem::Version
101
89
  version: '0'
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
- - - ! '>='
94
+ - - ">="
108
95
  - !ruby/object:Gem::Version
109
96
  version: '0'
110
97
  - !ruby/object:Gem::Dependency
111
98
  name: turn
112
99
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
100
  requirements:
115
- - - ! '>='
101
+ - - ">="
116
102
  - !ruby/object:Gem::Version
117
103
  version: '0'
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
107
  requirements:
123
- - - ! '>='
108
+ - - ">="
124
109
  - !ruby/object:Gem::Version
125
110
  version: '0'
126
111
  - !ruby/object:Gem::Dependency
127
112
  name: rake
128
113
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
114
  requirements:
131
- - - ! '>='
115
+ - - ">="
132
116
  - !ruby/object:Gem::Version
133
117
  version: '0'
134
118
  type: :development
135
119
  prerelease: false
136
120
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
121
  requirements:
139
- - - ! '>='
122
+ - - ">="
140
123
  - !ruby/object:Gem::Version
141
124
  version: '0'
142
125
  - !ruby/object:Gem::Dependency
143
126
  name: webmock
144
127
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
128
  requirements:
147
- - - ! '>='
129
+ - - ">="
148
130
  - !ruby/object:Gem::Version
149
131
  version: '0'
150
132
  type: :development
151
133
  prerelease: false
152
134
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
135
  requirements:
155
- - - ! '>='
136
+ - - ">="
156
137
  - !ruby/object:Gem::Version
157
138
  version: '0'
158
139
  description: Client for the Vend API
@@ -162,12 +143,14 @@ executables: []
162
143
  extensions: []
163
144
  extra_rdoc_files: []
164
145
  files:
165
- - .gitignore
146
+ - ".gitignore"
147
+ - ".rspec"
166
148
  - Gemfile
167
149
  - LICENSE
168
150
  - README.md
169
151
  - Rakefile
170
152
  - lib/vend.rb
153
+ - lib/vend/config.rb
171
154
  - lib/vend/errors.rb
172
155
  - lib/vend/has_resources.rb
173
156
  - lib/vend/modules/declarative_setters.rb
@@ -205,27 +188,26 @@ files:
205
188
  - vending-machine.gemspec
206
189
  homepage: https://github.com/snikch/vending-machine
207
190
  licenses: []
191
+ metadata: {}
208
192
  post_install_message:
209
193
  rdoc_options: []
210
194
  require_paths:
211
195
  - lib
212
196
  required_ruby_version: !ruby/object:Gem::Requirement
213
- none: false
214
197
  requirements:
215
- - - ! '>='
198
+ - - ">="
216
199
  - !ruby/object:Gem::Version
217
200
  version: '0'
218
201
  required_rubygems_version: !ruby/object:Gem::Requirement
219
- none: false
220
202
  requirements:
221
- - - ! '>='
203
+ - - ">="
222
204
  - !ruby/object:Gem::Version
223
205
  version: '0'
224
206
  requirements: []
225
207
  rubyforge_project:
226
- rubygems_version: 1.8.23
208
+ rubygems_version: 2.2.2
227
209
  signing_key:
228
- specification_version: 3
210
+ specification_version: 4
229
211
  summary: Exposes the Vend API as an object model
230
212
  test_files:
231
213
  - spec/resource_spec.rb
@@ -234,4 +216,3 @@ test_files:
234
216
  - spec/store_spec.rb
235
217
  - spec/support/url_assertions.rb
236
218
  - spec/support/webmock.rb
237
- has_rdoc: