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,18 @@
1
+ module Levelup
2
+ module Endpoints
3
+ # The endpoint holding all functions related to orders for a specified user.
4
+ class UserOrders < Base
5
+ def list(user_access_token)
6
+ request = Requests::ListUserOrders.
7
+ new(user_access_token: user_access_token)
8
+ request.send_to_api(:get, endpoint_path)
9
+ end
10
+
11
+ private
12
+
13
+ def path
14
+ 'users/orders'
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ module Levelup
2
+ module Endpoints
3
+ # The endpoint serving as a bucket for all user-related functions.
4
+ class Users < Base
5
+ def orders
6
+ UserOrders.new
7
+ end
8
+
9
+ private
10
+
11
+ def path
12
+ 'users'
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,8 @@
1
+ module Levelup
2
+ module Errors
3
+ # An error generated by the LevelUp client when the user attempts a request
4
+ # that is in some way of invalid format.
5
+ class InvalidRequest < StandardError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Levelup
2
+ module Errors
3
+ # An error generated by the LevelUp client when the user attempts to
4
+ # perform an authorized action without an access token.
5
+ class Unauthenticated < StandardError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,19 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to generate an app access token.
4
+ class AuthenticateApp < Base
5
+ # The API key assigned to your app
6
+ attr_accessor :api_key
7
+ # The secret code assigned to your app
8
+ attr_accessor :client_secret
9
+
10
+ def auth_type
11
+ :none
12
+ end
13
+
14
+ def response_from_hash(hash)
15
+ Responses::Success.new(hash['access_token'])
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to generate a merchant access
4
+ # token.
5
+ class AuthenticateMerchant < Base
6
+ # Your merchant's API key (accepts app API key as well)
7
+ attr_accessor :api_key
8
+ # The username used to log into your merchant account
9
+ attr_accessor :username
10
+ # Your merchant account's password
11
+ attr_accessor :password
12
+
13
+ def auth_type
14
+ :none
15
+ end
16
+
17
+ def body
18
+ { access_token: to_hash }
19
+ end
20
+
21
+ def response_from_hash(hash)
22
+ Responses::Success.new(hash['access_token'])
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,87 @@
1
+ module Levelup
2
+ module Requests
3
+ # The class containing the base functionality of all requests.
4
+ class Base < Templates::DataParcel
5
+ ALLOWED_REQUEST_METHODS = [:delete, :get, :post, :put]
6
+
7
+ # One of :none, :merchant, :app, :merchant_and_user
8
+ def auth_type
9
+ raise NotImplementedError, 'Auth type not defined for request.'
10
+ end
11
+
12
+ # Returns the body of the request to send as a hash. By default, sends
13
+ # a hash of all assigned instance variables in the object.
14
+ def body
15
+ to_hash
16
+ end
17
+
18
+ # Contains any additional headers passed in a request to the API.
19
+ # Builds the headers for a request out of a request object.
20
+ # Extending classes wishing to add additional headers should build their
21
+ # headers hash and return my_headers.merge(super)
22
+ def headers
23
+ headers = DEFAULT_HEADERS.dup
24
+
25
+ auth = auth_header_value
26
+ if auth
27
+ headers['Authorization'] = auth
28
+ end
29
+
30
+ headers
31
+ end
32
+
33
+ # default values to exclude from request hashes (header values)
34
+ def self.instance_variables_excluded_from_hash
35
+ @excluded ||= super.concat([:app_access_token, :merchant_access_token,
36
+ :user_access_token])
37
+ end
38
+
39
+ def response_from_hash
40
+ raise NotImplementedError, 'Response generator not defined.'
41
+ end
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.
46
+ def send_to_api(method, endpoint)
47
+ unless ALLOWED_REQUEST_METHODS.include?(method)
48
+ raise Errors::InvalidRequest, 'Attempted to send a request to'\
49
+ " LevelUp API via invalid method #{method}"
50
+ end
51
+
52
+ response = HTTParty.public_send(method, endpoint,
53
+ body: JSON.generate(body), headers: headers)
54
+
55
+ if response.success?
56
+ response_from_hash(response.parsed_response)
57
+ else
58
+ Responses::Error.new(response.headers, response.parsed_response,
59
+ response.code)
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ DEFAULT_HEADERS = {
66
+ 'Accept' => 'application/json',
67
+ 'Content-Type' => 'application/json'
68
+ }
69
+
70
+ def auth_header_value
71
+ case auth_type
72
+ when :app
73
+ %{token #{app_access_token}}
74
+ when :merchant
75
+ %{token merchant="#{merchant_access_token}"}
76
+ when :merchant_v14
77
+ %{token #{merchant_access_token}}
78
+ when :merchant_and_user
79
+ %{token merchant="#{merchant_access_token}", } +
80
+ %{user="#{user_access_token}"}
81
+ when :user
82
+ %{token user="#{user_access_token}"}
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,19 @@
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
+ class CreateAddress < Base
7
+ include Templates::UserAddressData
8
+ include Templates::UserAuthenticated
9
+
10
+ def body
11
+ { user_address: to_hash }
12
+ end
13
+
14
+ def response_from_hash(hash)
15
+ Responses::Success.new(hash['user_address'])
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to add the first credit card to a specified user
4
+ # account. User access token must have the create_first_credit_card
5
+ # permission.
6
+ class CreateCard < Base
7
+ include Templates::UserAuthenticated
8
+
9
+ attr_accessor :encrypted_cvv, :encrypted_expiration_month,
10
+ :encrypted_expiration_year, :encrypted_number, :postal_code
11
+
12
+ def body
13
+ { credit_card: to_hash }
14
+ end
15
+
16
+ def response_from_hash(hash)
17
+ Response::Success.new(hash['credit_card'])
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,33 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to create an order for the specified user at the
4
+ # specified merchant.
5
+ class CreateOrder < Base
6
+ include Templates::MerchantAndUserAuthenticated
7
+ # An array of Item objects (or hashes representing them) representing all
8
+ # items purchased by this order.
9
+ attr_accessor :items
10
+ # A merchant-supplied unique ID for this order. Optional.
11
+ attr_accessor :identifier_from_merchant
12
+ # The LevelUp ID for the location from which this order was requested.
13
+ attr_accessor :location_id
14
+ # The total amount (in cents) spent on this order.
15
+ attr_accessor :spend_amount
16
+
17
+ def body
18
+ items = @items.map do |item|
19
+ { item: item }
20
+ end
21
+
22
+ order_hash = to_hash
23
+ order_hash[:items] = items
24
+
25
+ { order: order_hash }
26
+ end
27
+
28
+ def response_from_hash(hash)
29
+ Responses::Success.new(hash['order'])
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to create a new user with the specified list of
4
+ # permissions.
5
+ class CreateUser < Base
6
+ attr_accessor :app_access_token
7
+ # An array of Item objects (or hashes representing them) representing all
8
+ # items purchased by this order.
9
+ attr_accessor :email
10
+ attr_accessor :first_name
11
+ attr_accessor :last_name
12
+ attr_accessor :permission_keynames
13
+
14
+ def auth_type
15
+ :app
16
+ end
17
+
18
+ def body
19
+ user_hash = {
20
+ email: email,
21
+ first_name: first_name,
22
+ last_name: last_name
23
+ }
24
+ { user: user_hash, permission_keynames: permission_keynames }
25
+ end
26
+
27
+ def response_from_hash(hash)
28
+ hash['user'] = OpenStruct.new(hash['user'])
29
+
30
+ Responses::Success.new(hash)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,17 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to access information about a
4
+ # specific order under a merchant.
5
+ class GetOrder < Base
6
+ include Templates::MerchantAuthenticated
7
+
8
+ def auth_type
9
+ :merchant_v14
10
+ end
11
+
12
+ def response_from_hash(hash)
13
+ Responses::Success.new(hash['order'])
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to get a QR code for a user.
4
+ class GetQrCode < Base
5
+ include Templates::UserAuthenticated
6
+
7
+ def body
8
+ {}
9
+ end
10
+
11
+ def response_from_hash(hash)
12
+ Responses::Success.new(hash['qr_code'])
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to get information about a user.
4
+ # User access token must have the read_user_basic_info permission.
5
+ class GetUser < Base
6
+ include Templates::UserAuthenticated
7
+
8
+ def body
9
+ {}
10
+ end
11
+
12
+ def response_from_hash(hash)
13
+ Responses::Success.new(hash['user'])
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to grant merchant-funded credit to a user.
4
+ # Merchant access token must have the give_merchant_funded_credit
5
+ # permission.
6
+ class GiveMerchantCredit < Base
7
+ include Templates::MerchantAuthenticated
8
+ attr_accessor :email, :value_amount
9
+
10
+ def auth_type
11
+ :merchant
12
+ end
13
+
14
+ def body
15
+ { merchant_funded_credit: to_hash }
16
+ end
17
+
18
+ def response_from_hash(hash)
19
+ Responses::Success.new
20
+ end
21
+ end
22
+ end
23
+ end
@@ -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 manage_user_addresses permission.
7
+ class ListAddresses < Base
8
+ include Templates::UserAuthenticated
9
+
10
+ def body
11
+ {}
12
+ end
13
+
14
+ def response_from_hash(hash)
15
+ addresses = hash.map { |address| address['user_address'] }
16
+ Responses::Success.new(addresses: addresses)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to list all locations under
4
+ # a specified merchant. This is a v14 endpoint and should not be expected to
5
+ # remain functional indefinitely.
6
+ class ListLocations < Base
7
+ include Templates::MerchantAuthenticated
8
+
9
+ def auth_type
10
+ :merchant_v14
11
+ end
12
+
13
+ def response_from_hash(hash)
14
+ if hash.nil? # no locations found for this merchant
15
+ Responses::Success.new(locations: [])
16
+ else
17
+ locations =
18
+ hash.map { |location| OpenStruct.new(location['location']) }
19
+ Responses::Success.new(locations: locations)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ module Levelup
2
+ module Requests
3
+ # Represents a request to list all orders made at a
4
+ # specified location. This is a v14 request and should not be expected to
5
+ # remain functional indefinitely.
6
+ class ListOrders < Base
7
+ include Templates::MerchantAuthenticated
8
+
9
+ def auth_type
10
+ :merchant_v14
11
+ end
12
+
13
+ def response_from_hash(hash)
14
+ if hash.nil? # no orders found for this location
15
+ Responses::Success.new(orders: [])
16
+ else
17
+ orders = hash.map { |order| OpenStruct.new(order['order']) }
18
+ Responses::Success.new(orders: orders)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end