levelup 0.9.2

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