levelup 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fffe35cc46fcd692944cc88cceb1685b374cec2f
4
- data.tar.gz: fc77b72ad732430eae0d59cc57149293d5139ff4
3
+ metadata.gz: 238e90b50ace8d0dda415d36dcd75b7d0af2023f
4
+ data.tar.gz: a6d9b1a494b008804eafece8a06e45a788c61dd3
5
5
  SHA512:
6
- metadata.gz: 0ea9f4468368ea50a351f85538c6017cb959bf682ea53e64fa5763b18f0945d44907094caf073a4cbf28813f0029e8e177a83856820f57a92e0d01d079586f34
7
- data.tar.gz: 76119e8ab76d59bfd30c9069b2886237bc7d83778dd8d469338efe078898bebf25d71c2ca1b80ae2c7f07cccd40d3c0cfb04084436b2081801e461b24010773d
6
+ metadata.gz: 32ccd34e752ccdd08d5e474a68522bc16259dd4d50341f6550bbdcedc68196a00854bdc2a40928d71b1316073ad637830f3215fd6688e39fab33da17579a3006
7
+ data.tar.gz: 4779600aa8094b8af4fca1a07d5580feffe665e5fa0b76f8b2a17c5821c36e78107de0219a31450bdf36654c7f34f1a07b2603d2c0bd3349291c8717044bcb34
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- levelup (0.9.2)
4
+ levelup (0.9.3)
5
5
  httparty (~> 0.13.1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -73,8 +73,28 @@ response = api.orders.create(
73
73
  user_access_token: 'user-token')
74
74
  ```
75
75
 
76
- All other functions of the Ruby SDK mirror the v15 LevelUp API described at http://developer.thelevelup.com/
77
- as well as a very small number of v14 endpoints.
76
+ The LevelUp Ruby SDK mirrors the API as closely as possible, so the call for any given endpoint can be inferred from its URL.
77
+ For instance:
78
+ ```ruby
79
+ api.apps.permissions_requests.create # points to /v15/apps/permissions_requests/ POST
80
+ api.user_addresses.list # points to /v15/user_addresses/ GET
81
+ api.orders(uuid).refund # points to /v15/orders/:uuid/refund/ POST
82
+ ```
83
+
84
+ ## Pagination
85
+
86
+ Some requests that return large lists are paginated and only return a small number of values per request.
87
+ The LevelUp Ruby SDK handles this by allowing you to request the next page from the paginated response.
88
+
89
+ For instance:
90
+ ```ruby
91
+ locs_response = api.apps(123).locations.list # gets a page of locations associated with an app
92
+ locs_response.locations # => [location 1, location 2...location 10]
93
+
94
+ locs_response.next_page? # => true if there is another page of results to load
95
+
96
+ next_page_response = locs_response.next # gets the next page of results
97
+ ```
78
98
 
79
99
  ## Errors
80
100
 
@@ -6,6 +6,7 @@ require 'levelup/configuration'
6
6
 
7
7
  require 'levelup/templates/data_parcel'
8
8
  require 'levelup/templates/user_address_data'
9
+ require 'levelup/templates/app_authenticated'
9
10
  require 'levelup/templates/merchant_authenticated'
10
11
  require 'levelup/templates/merchant_and_user_authenticated'
11
12
  require 'levelup/templates/user_authenticated'
@@ -21,6 +22,7 @@ require 'levelup/requests/get_order'
21
22
  require 'levelup/requests/get_qr_code'
22
23
  require 'levelup/requests/get_user'
23
24
  require 'levelup/requests/give_merchant_credit'
25
+ require 'levelup/requests/list_app_locations'
24
26
  require 'levelup/requests/list_addresses'
25
27
  require 'levelup/requests/list_locations'
26
28
  require 'levelup/requests/list_orders'
@@ -30,10 +32,12 @@ require 'levelup/requests/request_permissions'
30
32
  require 'levelup/requests/show_permissions_request'
31
33
 
32
34
  require 'levelup/responses/success'
35
+ require 'levelup/responses/success_paginated'
33
36
  require 'levelup/responses/error'
34
37
 
35
38
  require 'levelup/endpoints/base'
36
39
  require 'levelup/endpoints/access_tokens'
40
+ require 'levelup/endpoints/app_locations'
37
41
  require 'levelup/endpoints/app_users'
38
42
  require 'levelup/endpoints/apps'
39
43
  require 'levelup/endpoints/credit_cards'
@@ -44,6 +48,7 @@ require 'levelup/endpoints/merchant_orders'
44
48
  require 'levelup/endpoints/orders'
45
49
  require 'levelup/endpoints/permissions_requests'
46
50
  require 'levelup/endpoints/qr_codes'
51
+ require 'levelup/endpoints/specific_app'
47
52
  require 'levelup/endpoints/specific_location'
48
53
  require 'levelup/endpoints/specific_merchant'
49
54
  require 'levelup/endpoints/specific_order'
@@ -30,8 +30,12 @@ module Levelup
30
30
  end
31
31
 
32
32
  # Generates an interface for the +apps+ endpoint.
33
- def apps
34
- Endpoints::Apps.new(app_access_token)
33
+ def apps(app_id = nil)
34
+ if app_id
35
+ Endpoints::SpecificApp.new(app_id)
36
+ else
37
+ Endpoints::Apps.new(app_access_token)
38
+ end
35
39
  end
36
40
 
37
41
  # Verifies if an access token is present for app-authenticated endpoints
@@ -1,6 +1,6 @@
1
1
  module Levelup
2
2
  class Configuration
3
- VERSION = '0.9.2'
3
+ VERSION = '0.9.3'
4
4
  DEFAULT_API_VERSION = :v15
5
5
 
6
6
  class << self
@@ -0,0 +1,27 @@
1
+ module Levelup
2
+ module Endpoints
3
+ # The endpoint holding all functions relating to a specific app's locations.
4
+ # This endpoint is a v14 endpoint and should not be expected to remain
5
+ # accessible indefinitely.
6
+ class AppLocations < Base
7
+ def initialize(id)
8
+ self.id = id
9
+ end
10
+
11
+ # Provides a list of locations controlled by this app. This list is
12
+ # paginated.
13
+ def list
14
+ request = Requests::ListAppLocations.new
15
+ request.send_to_api(:get, endpoint_path(:v14))
16
+ end
17
+
18
+ private
19
+
20
+ attr_accessor :id
21
+
22
+ def path
23
+ "apps/#{id}/locations"
24
+ end
25
+ end
26
+ end
27
+ end
@@ -4,7 +4,7 @@ module Levelup
4
4
  # requests.
5
5
  class PermissionsRequests < Base
6
6
  def initialize(app_access_token)
7
- @app_access_token = app_access_token
7
+ self.app_access_token = app_access_token
8
8
  end
9
9
 
10
10
  # Requests a set of permissions from the specified user.
@@ -18,7 +18,7 @@ module Levelup
18
18
 
19
19
  private
20
20
 
21
- attr_reader :app_access_token
21
+ attr_accessor :app_access_token
22
22
 
23
23
  def path
24
24
  'apps/permissions_requests'
@@ -0,0 +1,23 @@
1
+ module Levelup
2
+ module Endpoints
3
+ # The endpoint serving as a bucket for all functions related to a specific
4
+ # app.
5
+ class SpecificApp < Base
6
+ def initialize(id)
7
+ self.id = id
8
+ end
9
+
10
+ def locations
11
+ AppLocations.new(id)
12
+ end
13
+
14
+ private
15
+
16
+ attr_accessor :id
17
+
18
+ def path
19
+ "apps/#{id}"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -2,9 +2,8 @@ module Levelup
2
2
  module Endpoints
3
3
  # Endpoint holding all functions relating to a specified order.
4
4
  class SpecificOrder < Base
5
- attr_reader :uuid
6
5
  def initialize(order_uuid)
7
- @uuid = order_uuid
6
+ self.uuid = order_uuid
8
7
  end
9
8
 
10
9
  # Refunds the order specified by this endpoint.
@@ -20,6 +19,8 @@ module Levelup
20
19
 
21
20
  private
22
21
 
22
+ attr_accessor :uuid
23
+
23
24
  def path
24
25
  "orders/#{uuid}"
25
26
  end
@@ -8,9 +8,9 @@ module Levelup
8
8
  self.request_id = request_id
9
9
  end
10
10
 
11
- def show
11
+ def show(app_token = nil)
12
12
  request = Requests::ShowPermissionsRequest.
13
- new(app_access_token: app_access_token)
13
+ new(app_access_token: app_access_token || app_token)
14
14
  request.send_to_api(:get, endpoint_path)
15
15
  end
16
16
 
@@ -40,10 +40,22 @@ module Levelup
40
40
  raise NotImplementedError, 'Response generator not defined.'
41
41
  end
42
42
 
43
- # Makes a call by the specified method to the specified endpoint, sending
44
- # this request object. If successful, builds a response object according
45
- # to response_from_hash. If unsuccessful, simply returns an ErrorResponse.
43
+ # Calls send_via_httparty, returning either an error response or the
44
+ # response as generated by this request's response_from_hash function.
45
+ # This function can be overridden to control how a request builds its
46
+ # response.
46
47
  def send_to_api(method, endpoint)
48
+ send_via_httparty(method, endpoint) do |response|
49
+ response_from_hash(response.parsed_response)
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ # Makes a call by the specified method to the specified endpoint, sending
56
+ # this request object. If successful, yields the HTTParty response to the
57
+ # calling method. If unsuccessful, simply returns an ErrorResponse.
58
+ def send_via_httparty(method, endpoint)
47
59
  unless ALLOWED_REQUEST_METHODS.include?(method)
48
60
  raise Errors::InvalidRequest, 'Attempted to send a request to'\
49
61
  " LevelUp API via invalid method #{method}"
@@ -53,15 +65,13 @@ module Levelup
53
65
  body: JSON.generate(body), headers: headers)
54
66
 
55
67
  if response.success?
56
- response_from_hash(response.parsed_response)
68
+ yield response
57
69
  else
58
70
  Responses::Error.new(response.headers, response.parsed_response,
59
71
  response.code)
60
72
  end
61
73
  end
62
74
 
63
- private
64
-
65
75
  DEFAULT_HEADERS = {
66
76
  'Accept' => 'application/json',
67
77
  'Content-Type' => 'application/json'
@@ -15,7 +15,11 @@ module Levelup
15
15
  attr_accessor :spend_amount
16
16
 
17
17
  def body
18
- items = @items.map do |item|
18
+ items = (@items || []).map do |item|
19
+ if item.empty?
20
+ next
21
+ end
22
+
19
23
  { item: item }
20
24
  end
21
25
 
@@ -3,7 +3,7 @@ module Levelup
3
3
  # Represents a request to create a new user with the specified list of
4
4
  # permissions.
5
5
  class CreateUser < Base
6
- attr_accessor :app_access_token
6
+ include Templates::AppAuthenticated
7
7
  # An array of Item objects (or hashes representing them) representing all
8
8
  # items purchased by this order.
9
9
  attr_accessor :email
@@ -11,10 +11,6 @@ module Levelup
11
11
  attr_accessor :last_name
12
12
  attr_accessor :permission_keynames
13
13
 
14
- def auth_type
15
- :app
16
- end
17
-
18
14
  def body
19
15
  user_hash = {
20
16
  email: email,
@@ -7,10 +7,6 @@ module Levelup
7
7
  include Templates::MerchantAuthenticated
8
8
  attr_accessor :email, :value_amount
9
9
 
10
- def auth_type
11
- :merchant
12
- end
13
-
14
10
  def body
15
11
  { merchant_funded_credit: to_hash }
16
12
  end
@@ -0,0 +1,35 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to list all locations under
4
+ # a specified app. The list is paginated.
5
+ class ListAppLocations < Base
6
+ def auth_type
7
+ :none
8
+ end
9
+
10
+ def response_from_hash(hash)
11
+ if hash.nil? # no locations found for this app
12
+ Responses::SuccessPaginated.new(locations: [])
13
+ else
14
+ locations =
15
+ hash.map { |location| OpenStruct.new(location['location']) }
16
+ Responses::SuccessPaginated.new(locations: locations)
17
+ end
18
+ end
19
+
20
+ def send_to_api(method, endpoint)
21
+ send_via_httparty(method, endpoint) do |response|
22
+ paginated_response = response_from_hash(response)
23
+
24
+ if response.headers['Link']
25
+ paginated_response.next_page =
26
+ /\<([^>]+)\>/.match(response.headers['Link'])[1]
27
+ paginated_response.next_page_request = ListAppLocations.new
28
+ end
29
+
30
+ paginated_response
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -3,7 +3,7 @@ module Levelup
3
3
  # Represents a request to request a set of permissions
4
4
  # from a specified account (merchant or user).
5
5
  class RequestPermissions < Base
6
- attr_accessor :app_access_token
6
+ include Templates::AppAuthenticated
7
7
  # The email address of the requested user or merchant.
8
8
  attr_accessor :email
9
9
  # An array of strings representing desired permissions from the user or
@@ -11,10 +11,6 @@ module Levelup
11
11
  # 'manage_merchant_orders'
12
12
  attr_accessor :permission_keynames
13
13
 
14
- def auth_type
15
- :app
16
- end
17
-
18
14
  def body
19
15
  { permissions_request: to_hash }
20
16
  end
@@ -3,11 +3,7 @@ module Levelup
3
3
  # Represents a request to show the status of a specified permissions
4
4
  # request.
5
5
  class ShowPermissionsRequest < Base
6
- attr_accessor :app_access_token
7
-
8
- def auth_type
9
- :app
10
- end
6
+ include Templates::AppAuthenticated
11
7
 
12
8
  def body
13
9
  {}
@@ -21,7 +21,8 @@ module Levelup
21
21
  OpenStruct.new(error['error'])
22
22
  end
23
23
  else
24
- @errors = [{ message: 'Could not parse error body' }]
24
+ @errors = [OpenStruct.new(message: 'The API returned an unexpected '\
25
+ 'response. This is likely due to an incorrectly defined base URL.')]
25
26
  end
26
27
 
27
28
  @status_code = status_code
@@ -0,0 +1,26 @@
1
+ module Levelup
2
+ module Responses
3
+ # Class that encapsulates a successful response from a paginated endpoint
4
+ # of the LevelUp API.
5
+ class SuccessPaginated < Success
6
+ attr_writer :next_page_request, :next_page
7
+
8
+ def next_page?
9
+ !next_page_request.nil? && !next_page.nil?
10
+ end
11
+
12
+ def next
13
+ unless next_page?
14
+ raise Errors::InvalidRequest, 'Attempted to fetch next page at '\
15
+ 'final page of list'
16
+ end
17
+
18
+ next_page_request.send_to_api(:get, next_page)
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :next_page_request, :next_page
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ module Levelup
2
+ module Templates
3
+ # A template to apply to any requests requiring app authentication.
4
+ #
5
+ # Authentication template - only apply one authentication template per
6
+ # request.
7
+ module AppAuthenticated
8
+ # An access token for an app.
9
+ attr_accessor :app_access_token
10
+
11
+ def auth_type
12
+ :app
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Levelup::Responses::SuccessPaginated', vcr: true do
4
+ before do
5
+ example_paginated_url = "#{Levelup::Configuration.api_url(:v14)}/apps/"\
6
+ "#{TestConfig.app_id}/locations"
7
+ @has_next_response = Levelup::Responses::SuccessPaginated.new
8
+ @has_next_response.next_page = example_paginated_url
9
+ @has_next_response.next_page_request =
10
+ Levelup::Requests::ListAppLocations.new
11
+
12
+ @no_next_response = Levelup::Responses::SuccessPaginated.new
13
+ end
14
+
15
+ describe '#success?' do
16
+ it 'returns true' do
17
+ expect(@has_next_response).to be_success
18
+ end
19
+ end
20
+
21
+ describe '#next_page?' do
22
+ context 'with no next page' do
23
+ it 'returns false' do
24
+ expect(@no_next_response.next_page?).to be_false
25
+ end
26
+ end
27
+
28
+ context 'with another page to retrieve' do
29
+ it 'returns true' do
30
+ expect(@has_next_response.next_page?).to be_true
31
+ end
32
+ end
33
+ end
34
+
35
+ describe '#next' do
36
+ context 'with no next page' do
37
+ it 'raises an InvalidRequest error' do
38
+ expect { @no_next_response.next }.
39
+ to raise_error(Levelup::Errors::InvalidRequest)
40
+ end
41
+ end
42
+
43
+ context 'with a next page' do
44
+ it 'successfully returns the next page' do
45
+ next_page_response = @has_next_response.next
46
+
47
+ expect(next_page_response).to be_success
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Levelup::Endpoints::AppLocations', vcr: true do
4
+ describe '#list' do
5
+ it 'fetches a list of locations' do
6
+ response = @test_client.apps(TestConfig.app_id).locations.list
7
+
8
+ expect(response).to be_success
9
+ expect(response.locations.length).to be > 0
10
+ end
11
+
12
+ it 'fetches a second page of locations' do
13
+ next_response = @test_client.apps(TestConfig.app_id).locations.list.next
14
+
15
+ expect(next_response).to be_success
16
+ end
17
+ end
18
+ end
@@ -2,6 +2,7 @@
2
2
  api_key_valid: key
3
3
  secret_valid: secret
4
4
  location_id: 123
5
+ app_id: 456
5
6
  merchant_token_with_grant_credit_perms: token
6
7
  merchant_token_with_manage_orders_perms: token (can be same as other merchant token)
7
8
  merchant_api_key: token_v14
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: levelup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - LevelUp POS Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-19 00:00:00.000000000 Z
11
+ date: 2014-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -150,7 +150,6 @@ files:
150
150
  - ".rubocop.yml"
151
151
  - Gemfile
152
152
  - Gemfile.lock
153
- - LICENSE
154
153
  - LICENSE.txt
155
154
  - README.md
156
155
  - Rakefile
@@ -159,6 +158,7 @@ files:
159
158
  - lib/levelup/api.rb
160
159
  - lib/levelup/configuration.rb
161
160
  - lib/levelup/endpoints/access_tokens.rb
161
+ - lib/levelup/endpoints/app_locations.rb
162
162
  - lib/levelup/endpoints/app_users.rb
163
163
  - lib/levelup/endpoints/apps.rb
164
164
  - lib/levelup/endpoints/base.rb
@@ -170,6 +170,7 @@ files:
170
170
  - lib/levelup/endpoints/orders.rb
171
171
  - lib/levelup/endpoints/permissions_requests.rb
172
172
  - lib/levelup/endpoints/qr_codes.rb
173
+ - lib/levelup/endpoints/specific_app.rb
173
174
  - lib/levelup/endpoints/specific_location.rb
174
175
  - lib/levelup/endpoints/specific_merchant.rb
175
176
  - lib/levelup/endpoints/specific_order.rb
@@ -191,6 +192,7 @@ files:
191
192
  - lib/levelup/requests/get_user.rb
192
193
  - lib/levelup/requests/give_merchant_credit.rb
193
194
  - lib/levelup/requests/list_addresses.rb
195
+ - lib/levelup/requests/list_app_locations.rb
194
196
  - lib/levelup/requests/list_locations.rb
195
197
  - lib/levelup/requests/list_orders.rb
196
198
  - lib/levelup/requests/list_user_orders.rb
@@ -199,6 +201,8 @@ files:
199
201
  - lib/levelup/requests/show_permissions_request.rb
200
202
  - lib/levelup/responses/error.rb
201
203
  - lib/levelup/responses/success.rb
204
+ - lib/levelup/responses/success_paginated.rb
205
+ - lib/levelup/templates/app_authenticated.rb
202
206
  - lib/levelup/templates/data_parcel.rb
203
207
  - lib/levelup/templates/merchant_and_user_authenticated.rb
204
208
  - lib/levelup/templates/merchant_authenticated.rb
@@ -214,7 +218,9 @@ files:
214
218
  - spec/data_objects/requests/request_permissions_spec.rb
215
219
  - spec/data_objects/responses/error_spec.rb
216
220
  - spec/data_objects/responses/response_spec.rb
221
+ - spec/data_objects/responses/success_paginated_spec.rb
217
222
  - spec/endpoints/access_tokens_spec.rb
223
+ - spec/endpoints/app_locations_spec.rb
218
224
  - spec/endpoints/app_users_spec.rb
219
225
  - spec/endpoints/location_orders_spec.rb
220
226
  - spec/endpoints/merchant_funded_credits_spec.rb
@@ -264,7 +270,9 @@ test_files:
264
270
  - spec/data_objects/requests/request_permissions_spec.rb
265
271
  - spec/data_objects/responses/error_spec.rb
266
272
  - spec/data_objects/responses/response_spec.rb
273
+ - spec/data_objects/responses/success_paginated_spec.rb
267
274
  - spec/endpoints/access_tokens_spec.rb
275
+ - spec/endpoints/app_locations_spec.rb
268
276
  - spec/endpoints/app_users_spec.rb
269
277
  - spec/endpoints/location_orders_spec.rb
270
278
  - spec/endpoints/merchant_funded_credits_spec.rb
data/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2014 LevelUp
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.