levelup 0.9.2

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 (85) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +36 -0
  3. data/.rubocop.yml +427 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +58 -0
  6. data/LICENSE +21 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +113 -0
  9. data/Rakefile +1 -0
  10. data/levelup.gemspec +32 -0
  11. data/lib/levelup.rb +55 -0
  12. data/lib/levelup/api.rb +102 -0
  13. data/lib/levelup/configuration.rb +23 -0
  14. data/lib/levelup/endpoints/access_tokens.rb +40 -0
  15. data/lib/levelup/endpoints/app_users.rb +30 -0
  16. data/lib/levelup/endpoints/apps.rb +30 -0
  17. data/lib/levelup/endpoints/base.rb +25 -0
  18. data/lib/levelup/endpoints/credit_cards.rb +26 -0
  19. data/lib/levelup/endpoints/location_orders.rb +32 -0
  20. data/lib/levelup/endpoints/merchant_funded_credits.rb +19 -0
  21. data/lib/levelup/endpoints/merchant_locations.rb +32 -0
  22. data/lib/levelup/endpoints/merchant_orders.rb +28 -0
  23. data/lib/levelup/endpoints/orders.rb +19 -0
  24. data/lib/levelup/endpoints/permissions_requests.rb +28 -0
  25. data/lib/levelup/endpoints/qr_codes.rb +28 -0
  26. data/lib/levelup/endpoints/specific_location.rb +24 -0
  27. data/lib/levelup/endpoints/specific_merchant.rb +28 -0
  28. data/lib/levelup/endpoints/specific_order.rb +28 -0
  29. data/lib/levelup/endpoints/specific_permissions_request.rb +26 -0
  30. data/lib/levelup/endpoints/user_addresses.rb +25 -0
  31. data/lib/levelup/endpoints/user_orders.rb +18 -0
  32. data/lib/levelup/endpoints/users.rb +16 -0
  33. data/lib/levelup/errors/invalid_request.rb +8 -0
  34. data/lib/levelup/errors/unauthenticated.rb +8 -0
  35. data/lib/levelup/requests/authenticate_app.rb +19 -0
  36. data/lib/levelup/requests/authenticate_merchant.rb +26 -0
  37. data/lib/levelup/requests/base.rb +87 -0
  38. data/lib/levelup/requests/create_address.rb +19 -0
  39. data/lib/levelup/requests/create_card.rb +21 -0
  40. data/lib/levelup/requests/create_order.rb +33 -0
  41. data/lib/levelup/requests/create_user.rb +34 -0
  42. data/lib/levelup/requests/get_order.rb +17 -0
  43. data/lib/levelup/requests/get_qr_code.rb +16 -0
  44. data/lib/levelup/requests/get_user.rb +17 -0
  45. data/lib/levelup/requests/give_merchant_credit.rb +23 -0
  46. data/lib/levelup/requests/list_addresses.rb +20 -0
  47. data/lib/levelup/requests/list_locations.rb +24 -0
  48. data/lib/levelup/requests/list_orders.rb +23 -0
  49. data/lib/levelup/requests/list_user_orders.rb +20 -0
  50. data/lib/levelup/requests/refund_order.rb +21 -0
  51. data/lib/levelup/requests/request_permissions.rb +27 -0
  52. data/lib/levelup/requests/show_permissions_request.rb +21 -0
  53. data/lib/levelup/responses/error.rb +36 -0
  54. data/lib/levelup/responses/success.rb +11 -0
  55. data/lib/levelup/templates/data_parcel.rb +41 -0
  56. data/lib/levelup/templates/merchant_and_user_authenticated.rb +21 -0
  57. data/lib/levelup/templates/merchant_authenticated.rb +19 -0
  58. data/lib/levelup/templates/user_address_data.rb +20 -0
  59. data/lib/levelup/templates/user_authenticated.rb +17 -0
  60. data/spec/data_objects/requests/authenticate_app_spec.rb +13 -0
  61. data/spec/data_objects/requests/authenticate_merchant_spec.rb +14 -0
  62. data/spec/data_objects/requests/create_order_spec.rb +14 -0
  63. data/spec/data_objects/requests/get_order_spec.rb +13 -0
  64. data/spec/data_objects/requests/list_locations_spec.rb +13 -0
  65. data/spec/data_objects/requests/list_orders_spec.rb +13 -0
  66. data/spec/data_objects/requests/refund_order_spec.rb +19 -0
  67. data/spec/data_objects/requests/request_permissions_spec.rb +21 -0
  68. data/spec/data_objects/responses/error_spec.rb +67 -0
  69. data/spec/data_objects/responses/response_spec.rb +13 -0
  70. data/spec/endpoints/access_tokens_spec.rb +81 -0
  71. data/spec/endpoints/app_users_spec.rb +43 -0
  72. data/spec/endpoints/location_orders_spec.rb +34 -0
  73. data/spec/endpoints/merchant_funded_credits_spec.rb +16 -0
  74. data/spec/endpoints/merchant_locations_spec.rb +35 -0
  75. data/spec/endpoints/orders_spec.rb +37 -0
  76. data/spec/endpoints/permissions_requests_spec.rb +22 -0
  77. data/spec/endpoints/qr_codes_spec.rb +12 -0
  78. data/spec/endpoints/specific_order_spec.rb +33 -0
  79. data/spec/endpoints/specific_permissions_request_spec.rb +24 -0
  80. data/spec/endpoints/user_addresses_spec.rb +41 -0
  81. data/spec/endpoints/user_orders_spec.rb +12 -0
  82. data/spec/fixtures/keys.yml.example +15 -0
  83. data/spec/spec_helper.rb +28 -0
  84. data/spec/support/vcr_filter_sensitive_data.rb +53 -0
  85. metadata +281 -0
@@ -0,0 +1,20 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to create an address for a
4
+ # specific user. For information about its parameters, see UserAddressData
5
+ # and UserAuthenticated.
6
+ # User access token must have the read_user_orders permission.
7
+ class ListUserOrders < Base
8
+ include Templates::UserAuthenticated
9
+
10
+ def body
11
+ {}
12
+ end
13
+
14
+ def response_from_hash(hash)
15
+ orders = hash.map { |order| OpenStruct.new(order['order']) }
16
+ Responses::Success.new(orders: orders)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to refund a specified order.
4
+ # Merchant access token must have the manage_merchant_orders permission.
5
+ class RefundOrder < Base
6
+ include Templates::MerchantAuthenticated
7
+
8
+ # If your merchant account is configured to require one, a confirmation
9
+ # code permitting this refund.
10
+ attr_accessor :manager_confirmation
11
+
12
+ def body
13
+ { refund: to_hash }
14
+ end
15
+
16
+ def response_from_hash(hash)
17
+ Responses::Success.new(hash['order'])
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to request a set of permissions
4
+ # from a specified account (merchant or user).
5
+ class RequestPermissions < Base
6
+ attr_accessor :app_access_token
7
+ # The email address of the requested user or merchant.
8
+ attr_accessor :email
9
+ # An array of strings representing desired permissions from the user or
10
+ # merchant. Common permissions include 'create_orders' and
11
+ # 'manage_merchant_orders'
12
+ attr_accessor :permission_keynames
13
+
14
+ def auth_type
15
+ :app
16
+ end
17
+
18
+ def body
19
+ { permissions_request: to_hash }
20
+ end
21
+
22
+ def response_from_hash(hash)
23
+ Responses::Success.new(hash['permissions_request'])
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to show the status of a specified permissions
4
+ # request.
5
+ class ShowPermissionsRequest < Base
6
+ attr_accessor :app_access_token
7
+
8
+ def auth_type
9
+ :app
10
+ end
11
+
12
+ def body
13
+ {}
14
+ end
15
+
16
+ def response_from_hash(hash)
17
+ Responses::Success.new(hash['permissions_request'])
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,36 @@
1
+ module Levelup
2
+ module Responses
3
+ # Encapsulates a response to an unsuccessful request.
4
+ class Error < Templates::DataParcel
5
+ # An array of error hashes with the properties 'object' (the LevelUp API
6
+ # object causing the error), 'property' (the property of that object
7
+ # causing the error), and 'message' (a human-readable error message).
8
+ attr_reader :errors
9
+ # The HTTP status code returned by the API
10
+ attr_reader :status_code
11
+ # Any HTTP headers returned by the API, in hash form.
12
+ attr_reader :headers
13
+
14
+ # Builds the error from the raw JSON response and the specified status
15
+ # code.
16
+ def initialize(headers, errors, status_code)
17
+ @headers = headers
18
+
19
+ if errors.is_a?(Array) || !errors
20
+ @errors = (errors || []).map do |error|
21
+ OpenStruct.new(error['error'])
22
+ end
23
+ else
24
+ @errors = [{ message: 'Could not parse error body' }]
25
+ end
26
+
27
+ @status_code = status_code
28
+ end
29
+
30
+ # Errors are always unsuccessful.
31
+ def success?
32
+ false
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,11 @@
1
+ module Levelup
2
+ module Responses
3
+ # Class that encapsulates a successful response from the LevelUp API.
4
+ class Success < OpenStruct
5
+ # Whether the response represents a successful API call.
6
+ def success?
7
+ true
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,41 @@
1
+ module Levelup
2
+ module Templates
3
+ # A series of methods used to convert objects to/from hashes.
4
+ class DataParcel
5
+ def initialize(hash = {})
6
+ assign_instance_variables_from_hash hash
7
+ end
8
+
9
+ # Determines if the specified instance variable is excluded from this
10
+ # object's generated hash.
11
+ def self.excluded?(instance_variable)
12
+ instance_variables_excluded_from_hash.include? instance_variable
13
+ end
14
+
15
+ def self.instance_variables_excluded_from_hash
16
+ [:excluded_from_hash]
17
+ end
18
+
19
+ private
20
+
21
+ # hash: A hash mapping instance variable names to their desired values
22
+ def assign_instance_variables_from_hash(hash)
23
+ hash.each { |key, value| public_send("#{key}=", value) }
24
+ end
25
+
26
+ def to_hash
27
+ body = {}
28
+
29
+ instance_variables.each do |variable|
30
+ instance_variable_name = variable.to_s.delete('@').to_sym
31
+
32
+ unless self.class.excluded?(instance_variable_name)
33
+ body[instance_variable_name] = instance_variable_get(variable)
34
+ end
35
+ end
36
+
37
+ body
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,21 @@
1
+ module Levelup
2
+ module Templates
3
+ # A template to apply to any requests requiring both merchant and user
4
+ # authentication.
5
+ #
6
+ # Authentication template - only apply one authentication template per
7
+ # request.
8
+ module MerchantAndUserAuthenticated
9
+ # An access token for a merchant that has granted you
10
+ # 'manage_merchant_orders' permissions.
11
+ attr_accessor :merchant_access_token
12
+ # An access token for a user that has granted you 'create_orders'
13
+ # permissions.
14
+ attr_accessor :user_access_token
15
+
16
+ def auth_type
17
+ :merchant_and_user
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ module Levelup
2
+ module Templates
3
+ # A template to apply to any requests requiring v15 merchant authentication.
4
+ # If your request requires v14 merchant authentication, include this module
5
+ # and define auth_type as :merchant_v14.
6
+ #
7
+ # Authentication template - only apply one authentication template per
8
+ # request.
9
+ module MerchantAuthenticated
10
+ # An access token for a merchant that has granted you
11
+ # 'manage_merchant_orders' permissions.
12
+ attr_accessor :merchant_access_token
13
+
14
+ def auth_type
15
+ :merchant
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ module Levelup
2
+ module Templates
3
+ # Apply this template to any request/response that handles all data for a
4
+ # user address.
5
+ module UserAddressData
6
+ # The 'type' of this address, e.g. 'home' or 'work'.
7
+ attr_accessor :address_type
8
+ # The number and street name of this address.
9
+ attr_accessor :street_address
10
+ # The second line of the address, e.g. 'Suite #40'.
11
+ attr_accessor :extended_address
12
+ # The city (or some equivalent) of this address.
13
+ attr_accessor :locality
14
+ # The state, province, or some other equivalent for this address.
15
+ attr_accessor :region
16
+ # The postal code for this address.
17
+ attr_accessor :postal_code
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ module Levelup
2
+ module Templates
3
+ # A template to apply to any requests requiring user authentication.
4
+ #
5
+ # Authentication template - only apply one authentication template per
6
+ # request.
7
+ module Templates::UserAuthenticated
8
+ # An access token for a user that has granted you appropriate
9
+ # permissions.
10
+ attr_accessor :user_access_token
11
+
12
+ def auth_type
13
+ :user
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Levelup::Requests::AuthenticateApp' do
4
+ before do
5
+ @test_authenticate_request = Levelup::Requests::AuthenticateApp.new
6
+ end
7
+
8
+ describe '#auth_type' do
9
+ it 'returns :none' do
10
+ expect(@test_authenticate_request.auth_type).to eq(:none)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Levelup::Requests::AuthenticateMerchant' do
4
+ before do
5
+ @test_merchant_authenticate_request = \
6
+ Levelup::Requests::AuthenticateMerchant.new({})
7
+ end
8
+
9
+ describe '#auth_type' do
10
+ it 'returns :none' do
11
+ expect(@test_merchant_authenticate_request.auth_type).to be :none
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Levelup::Requests::CreateOrder' do
4
+ before do
5
+ @test_app_order_request = Levelup::Requests::CreateOrder.new(
6
+ user_access_token: 'some access token', location_id: 256)
7
+ end
8
+
9
+ describe '#auth_type' do
10
+ it 'returns :merchant_and_user' do
11
+ expect(@test_app_order_request.auth_type).to be :merchant_and_user
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Levelup::Requests::GetOrder' do
4
+ before do
5
+ @test_order_deets_request = Levelup::Requests::GetOrder.new
6
+ end
7
+
8
+ describe '#auth_type' do
9
+ it 'returns :merchant_v14' do
10
+ expect(@test_order_deets_request.auth_type).to eq(:merchant_v14)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Levelup::Requests::ListLocations' do
4
+ before do
5
+ @test_list_locs_request = Levelup::Requests::ListLocations.new
6
+ end
7
+
8
+ describe '#auth_type' do
9
+ it 'returns :merchant_v14' do
10
+ @test_list_locs_request.auth_type.should eq(:merchant_v14)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Levelup::Requests::ListOrders' do
4
+ before do
5
+ @test_list_orders_request = Levelup::Requests::ListOrders.new
6
+ end
7
+
8
+ describe '#auth_type' do
9
+ it 'returns :merchant_v14' do
10
+ @test_list_orders_request.auth_type.should eq(:merchant_v14)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Levelup::Requests::RefundOrder' do
4
+ before do
5
+ @test_app_refund_request = Levelup::Requests::RefundOrder.new({})
6
+ end
7
+
8
+ describe '#auth_type' do
9
+ it 'returns :merchant' do
10
+ expect(@test_app_refund_request.auth_type).to be :merchant
11
+ end
12
+ end
13
+
14
+ describe '#body' do
15
+ it 'returns a hash wrapped in a refund tag' do
16
+ expect(@test_app_refund_request.body[:refund]).to_not be_nil
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Levelup::Requests::RequestPermissions' do
4
+ before do
5
+ @test_user_permissions_request =
6
+ Levelup::Requests::RequestPermissions.new({})
7
+ end
8
+
9
+ describe '#auth_type' do
10
+ it 'returns :app' do
11
+ expect(@test_user_permissions_request.auth_type).to be :app
12
+ end
13
+ end
14
+
15
+ describe '#body' do
16
+ it 'returns a hash wrapped in a permissions_request tag' do
17
+ expect(@test_user_permissions_request.body[:permissions_request]).
18
+ to_not be_nil
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Levelup::Responses::Error' do
4
+ before do
5
+ @empty_response = Levelup::Responses::Error.new({}, [], 404)
6
+
7
+ @nonempty_response = Levelup::Responses::Error.new(
8
+ {
9
+ 'header' => 'value',
10
+ 'otherHeader' => 'secondValue'
11
+ },
12
+ [{
13
+ 'error' => {
14
+ 'property' => 'whatever',
15
+ 'object' => 'Elbereth',
16
+ 'message' => 'some message'
17
+ }
18
+ },
19
+ {
20
+ 'error' => {
21
+ 'property' => 'some_prop',
22
+ 'object' => 'some_object',
23
+ 'message' => 'some other message'
24
+ }
25
+ }],
26
+ 404)
27
+ end
28
+
29
+ describe '#errors' do
30
+ context 'for an object with no body hash' do
31
+ it 'has no errors' do
32
+ expect(@empty_response.errors).to eq([])
33
+ end
34
+ end
35
+
36
+ context 'for an object with two full errors in its body hash' do
37
+ it 'has two full errors' do
38
+ expect(@nonempty_response).to have(2).errors
39
+ @nonempty_response.errors.each do |error|
40
+ expect(error['property']).to_not be_nil
41
+ expect(error['object']).to_not be_nil
42
+ expect(error['message']).to_not be_nil
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ describe '#headers' do
49
+ context 'for an object with an empty supplied header' do
50
+ it 'has empty headers' do
51
+ expect(@empty_response.headers).to eq({})
52
+ end
53
+ end
54
+
55
+ context 'for an object with a nonempty supplied header' do
56
+ it 'has non-empty headers' do
57
+ expect(@nonempty_response.headers).to_not be_empty
58
+ end
59
+ end
60
+ end
61
+
62
+ describe '#success?' do
63
+ it 'returns false' do
64
+ expect(@empty_response.success?).to be_false
65
+ end
66
+ end
67
+ end