easy_meli 0.3.0 → 0.6.1

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
  SHA256:
3
- metadata.gz: d17badfe56ecab178ff6cb784e9d78bb8c0cd4ac9421e5ea356a52212622c76a
4
- data.tar.gz: 4f40821e57261ade83265e971ea8a45a85db038fff68b26744daeaedf80c87fd
3
+ metadata.gz: 8c8dc1140d9368b076baf0a49a9742aea8de95565a90512152c9c58ec2b98723
4
+ data.tar.gz: 543cbed2c4789b0259b62f11d332a02c3b5b281feb2c5b60c5f87fd8640c0754
5
5
  SHA512:
6
- metadata.gz: 8b95637656926bd1b393ed569c136cb5f486b2c76ec46ef733eabb1746ef52a062d4f669c0b068ca93c2dd0dc52641483b9866304fa10a9e8c22847254971387
7
- data.tar.gz: 5c2310fbd9282c91f5777596d05f3504585cd394f3f31a59a1a514a41953593cd5422c87db971f4b3a5ce77b6989e8251676d7bd6257135fff79d24915ca3e30
6
+ metadata.gz: c2a7ecfa32beed3a9329b01312b1cfd4ed70fceb26469dc90e8d0d2c3b42186a9c1ec06f115f1dc5fa15236aa48d99b7e074a089fad7f710bddaf2bcb324680a
7
+ data.tar.gz: dfc01a8544c0f2d23711888fdfa3fb6a6f6f68196782d41cb501c1f50d53900882fb5c1b8d7a9f88e610eb1fafc8112447943ff87b8793af7fccd29e800a6d17
@@ -0,0 +1,32 @@
1
+ name: CI
2
+ on:
3
+ pull_request:
4
+ branches: [ master ]
5
+ push:
6
+ branches: [ master ]
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ matrix:
12
+ ruby_version: [ '2.6' ]
13
+ steps:
14
+ - name: Checkout
15
+ uses: actions/checkout@v2
16
+ - name: Setup ruby ${{ matrix.ruby_version }}
17
+ uses: actions/setup-ruby@v1
18
+ with:
19
+ ruby-version: ${{ matrix.ruby_version }}
20
+ - name: Setup cache key and directory for gems cache
21
+ uses: actions/cache@v1
22
+ with:
23
+ path: vendor/bundle
24
+ key: ${{ runner.os }}-gem-use-ruby-${{ matrix.ruby_version }}-${{ hashFiles('**/Gemfile.lock') }}
25
+ - name: Bundle install
26
+ run: |
27
+ gem install bundler:1.17.0
28
+ bundle config path vendor/bundle
29
+ bundle install --jobs 4 --retry 3
30
+ - name: Run tests
31
+ run: |
32
+ bundle exec rake test
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ ## V 0.6.1
4
+ - Fix a bug in the error raising in the authorization client introduced in V 0.6.0
5
+
6
+ ## V 0.6.0
7
+ - Classify an `invalid_token` response as an `InvalidTokenError`.
8
+ - `Malformed access_token` error changed from `AuthenticationError` to `InvalidTokenError`.
9
+
10
+ ## V 0.5.0
11
+ - `self.api_client` Prevent access_token override when initialize together with a refresh_token.
12
+ - Raises a EasyMeli::TooManyRequestsError if a 429 response status is returned.
data/README.md CHANGED
@@ -32,26 +32,26 @@ end
32
32
  To get the authorization url that the end-user uses to give your app authorization to access MercadoLibre on your part call the `authorization_url` with the desired country and the url to redirect to in order to complete the authorization.
33
33
 
34
34
  ```ruby
35
- EasyMeli::AuthorizationClient.authorization_url('MX', 'your_redirect_url')
35
+ EasyMeli.authorization_url('MX', 'your_redirect_url')
36
36
  ```
37
37
 
38
38
  Once MercadoLibre calls your redirect url you can get a refresh token by calling
39
39
 
40
40
  ```ruby
41
- response = EasyMeli::AuthorizationClient.new.create_token('the_code_in_the_redirect', 'the_same_redirect_url_as_above')
41
+ response = EasyMeli.create_token('the_code_in_the_redirect', 'the_same_redirect_url_as_above')
42
42
  ```
43
43
  This will return a response object with a json body that you can easily access via `response.to_h`.
44
44
 
45
- If you want to refresh the token call
45
+ If you want to refresh the token call
46
46
 
47
47
  ```ruby
48
- response = EasyMeli::AuthorizationClient.new.refresh_token('a_refresh_token')
48
+ access_token = EasyMeli.access_token('a_refresh_token')
49
49
  ```
50
50
 
51
51
  Once you can have an access token you can create a client and call the supported http verb methods.
52
52
 
53
53
  ```ruby
54
- client = EasyMeli::ApiClient.new(access_token)
54
+ client = EasyMeli.api_client(access_token: access_token)
55
55
 
56
56
  client.get(path, query: { a: 1 })
57
57
  client.post(path, query: { a: 1 }, body: { b: 1 })
@@ -59,25 +59,21 @@ client.put(path, query: { a: 1 }, body: { b: 1 })
59
59
  client.delete(path, query: { a: 1 })
60
60
  ```
61
61
 
62
- You can also pass a logger when instantiating the `EasyMeli::ApiClient` or `EasyMeli::AuthorizationClient`. The logger class must implement a `log` method which will be called with the [HTTParty response](https://www.rubydoc.info/github/jnunemaker/httparty/HTTParty/Response) for every remote request sent.
62
+ You can also pass a logger to any methods that make remote calls. The logger class must implement a `log` method which will be called with the [HTTParty response](https://www.rubydoc.info/github/jnunemaker/httparty/HTTParty/Response) for every remote request sent.
63
63
 
64
64
  ```ruby
65
- EasyMeli::AuthorizationClient.new(logger: my_logger)
66
- EasyMeli::ApiClient.new(access_token, logger: my_logger)
65
+ EasyMeli.create_token('the_code_in_the_redirect', 'the_same_redirect_url_as_above', logger: my_logger)
66
+ EasyMeli.api_client(refresh_token: refresh_token, logger: my_logger)
67
67
  ```
68
68
 
69
- ### Complete example showing how to retrieve a user profile
69
+ ### Example of how to retrieve a user profile
70
70
  ```ruby
71
71
  EasyMeli.configure do |config|
72
72
  config.application_id = "your_app_id"
73
73
  config.secret_key = "your_secret_key"
74
74
  end
75
75
 
76
- authorization_client = EasyMeli::AuthorizationClient.new
77
- token = authorization_client.refresh_token(previously_stored_refresh_token).to_h['access_token']
78
-
79
- api_client = EasyMeli::ApiClient.new(token)
80
-
76
+ api_client = EasyMeli.api_client(refresh_token: refresh_token)
81
77
  response = api_client.get('/users/me')
82
78
 
83
79
  ```
@@ -1,12 +1,14 @@
1
1
  require 'httparty'
2
2
 
3
3
  require 'easy_meli/version'
4
+ require 'easy_meli/constants'
4
5
  require 'easy_meli/errors'
5
6
  require 'easy_meli/configuration'
6
7
  require 'easy_meli/authorization_client'
7
8
  require 'easy_meli/api_client'
8
9
 
9
10
  module EasyMeli
11
+
10
12
  def self.configuration
11
13
  @configuration ||= Configuration.new
12
14
  end
@@ -14,4 +16,21 @@ module EasyMeli
14
16
  def self.configure
15
17
  yield(configuration)
16
18
  end
19
+
20
+ def self.authorization_url(country_code, redirect_uri)
21
+ EasyMeli::AuthorizationClient.authorization_url(country_code, redirect_uri)
22
+ end
23
+
24
+ def self.create_token(code, redirect_uri, logger: nil)
25
+ EasyMeli::AuthorizationClient.create_token(code, redirect_uri, logger: logger)
26
+ end
27
+
28
+ def self.access_token(refresh_token, logger: nil)
29
+ EasyMeli::AuthorizationClient.access_token(refresh_token, logger: logger)
30
+ end
31
+
32
+ def self.api_client(access_token: nil, refresh_token: nil, logger: nil)
33
+ access_token ||= self.access_token(refresh_token, logger: logger) if refresh_token
34
+ EasyMeli::ApiClient.new(access_token, logger: logger)
35
+ end
17
36
  end
@@ -5,18 +5,24 @@ class EasyMeli::ApiClient
5
5
 
6
6
  API_ROOT_URL = 'https://api.mercadolibre.com'
7
7
 
8
- TOKEN_ERRORS = {
9
- 'invalid_grant' => 'Invalid Grant',
10
- 'forbidden' => 'Forbidden',
11
- 'Malformed access_token' => 'Malformed access token'
8
+ ERROR_LIST = {
9
+ 'invalid_grant' => EasyMeli::InvalidGrantError,
10
+ 'forbidden' => EasyMeli::ForbiddenError,
11
+ 'invalid_token' => EasyMeli::InvalidTokenError,
12
+ 'Malformed access_token' => EasyMeli::MalformedTokenError
12
13
  }
13
14
 
14
- base_uri API_ROOT_URL
15
+ STATUS_ERRORS = {
16
+ 429 => EasyMeli::TooManyRequestsError
17
+ }
18
+
19
+ base_uri API_ROOT_URL
20
+ headers EasyMeli::DEFAULT_HEADERS
15
21
  format :json
16
22
 
17
23
  attr_reader :logger, :access_token
18
24
 
19
- def initialize(access_token, logger: nil)
25
+ def initialize(access_token = nil, logger: nil)
20
26
  @logger = logger
21
27
  @access_token = access_token
22
28
  end
@@ -41,20 +47,23 @@ class EasyMeli::ApiClient
41
47
 
42
48
  def send_request(verb, path = '', params = {})
43
49
  query = params[:query] || params['query'] || {}
44
- query[:access_token] = access_token
50
+ query[:access_token] = access_token if access_token
51
+
45
52
  self.class.send(verb, path, params.merge(query)).tap do |response|
46
53
  logger&.log response
47
54
  check_authentication(response)
55
+ check_status(response)
48
56
  end
49
57
  end
50
58
 
51
59
  def check_authentication(response)
52
- response_message = error_message_from_body(response.to_h)
60
+ response_message = error_message_from_body(response.to_h) if response.parsed_response.is_a? Hash
53
61
  return if response_message.to_s.empty?
54
-
55
- TOKEN_ERRORS.keys.each do |key|
62
+
63
+ ERROR_LIST.keys.each do |key|
56
64
  if response_message.include?(key)
57
- raise EasyMeli::AuthenticationError.new(TOKEN_ERRORS[key], response)
65
+ exception = ERROR_LIST[key]
66
+ raise exception.new(response)
58
67
  end
59
68
  end
60
69
  end
@@ -63,4 +72,9 @@ class EasyMeli::ApiClient
63
72
  return if body.nil?
64
73
  body['error'].to_s.empty? ? body['message'] : body['error']
65
74
  end
66
- end
75
+
76
+ def check_status(response)
77
+ status_error = STATUS_ERRORS[response.code]
78
+ raise status_error.new(response) if status_error
79
+ end
80
+ end
@@ -20,7 +20,9 @@ class EasyMeli::AuthorizationClient
20
20
  PT: 'https://auth.mercadolibre.com.pt',
21
21
  DO: 'https://auth.mercadolibre.com.do'
22
22
  }
23
+ ACCESS_TOKEN_KEY = 'access_token'
23
24
 
25
+ headers EasyMeli::DEFAULT_HEADERS
24
26
  format :json
25
27
 
26
28
  attr_reader :logger
@@ -33,12 +35,30 @@ class EasyMeli::AuthorizationClient
33
35
  params = {
34
36
  client_id: EasyMeli.configuration.application_id,
35
37
  response_type: 'code',
36
- redirect_uri: redirect_uri
38
+ redirect_uri: redirect_uri
37
39
  }
38
40
  HTTParty::Request.new(:get, country_auth_url(country_code), query: params).uri.to_s
39
41
  end
40
42
 
41
- def create_token(code, redirect_uri)
43
+ def self.create_token(code, redirect_uri, logger: nil)
44
+ response = self.new(logger: logger).create_token_with_response(code, redirect_uri)
45
+ if response.success?
46
+ response.to_h
47
+ else
48
+ raise EasyMeli::CreateTokenError.new(response)
49
+ end
50
+ end
51
+
52
+ def self.access_token(refresh_token, logger: nil)
53
+ response = self.new(logger: logger).access_token_with_response(refresh_token)
54
+ if response.success?
55
+ response.to_h[EasyMeli::AuthorizationClient::ACCESS_TOKEN_KEY]
56
+ else
57
+ raise EasyMeli::InvalidTokenError.new(response)
58
+ end
59
+ end
60
+
61
+ def create_token_with_response(code, redirect_uri)
42
62
  query_params = merge_auth_params(
43
63
  grant_type: 'authorization_code',
44
64
  code: code,
@@ -47,7 +67,7 @@ class EasyMeli::AuthorizationClient
47
67
  post_auth(query_params)
48
68
  end
49
69
 
50
- def refresh_token(refresh_token)
70
+ def access_token_with_response(refresh_token)
51
71
  query_params = merge_auth_params(
52
72
  grant_type: 'refresh_token',
53
73
  refresh_token: refresh_token
@@ -64,7 +84,7 @@ class EasyMeli::AuthorizationClient
64
84
  end
65
85
 
66
86
  def self.country_auth_url(country_code)
67
- url = BASE_AUTH_URLS[country_code.to_s.upcase.to_sym] ||
87
+ url = BASE_AUTH_URLS[country_code.to_s.upcase.to_sym] ||
68
88
  (raise ArgumentError.new('%s is an invalid country code' % country_code))
69
89
  [url, AUTH_PATH].join
70
90
  end
@@ -75,4 +95,4 @@ class EasyMeli::AuthorizationClient
75
95
  client_secret: EasyMeli.configuration.secret_key
76
96
  )
77
97
  end
78
- end
98
+ end
@@ -0,0 +1,8 @@
1
+ module EasyMeli
2
+ USER_AGENT = "EasyMeli-%s" % VERSION
3
+ DEFAULT_HEADERS = {
4
+ 'Content-Type' => 'application/json',
5
+ 'Accept' => 'application/json',
6
+ 'User-Agent' => USER_AGENT
7
+ }
8
+ end
@@ -2,11 +2,67 @@ module EasyMeli
2
2
  class Error < StandardError
3
3
  attr_reader :response
4
4
 
5
- def initialize(message, response)
5
+ def initialize(response)
6
6
  @response = response
7
- super(message)
7
+ super(local_message)
8
+ end
9
+
10
+ private
11
+
12
+ def local_message
13
+ raise NotImplementedError
8
14
  end
9
15
  end
10
16
 
11
17
  class AuthenticationError < Error; end
12
- end
18
+
19
+ class CreateTokenError < AuthenticationError
20
+ private
21
+
22
+ def local_message
23
+ 'Error Creating Token'
24
+ end
25
+ end
26
+
27
+ class InvalidGrantError < AuthenticationError
28
+ private
29
+
30
+ def local_message
31
+ 'Invalid Grant'
32
+ end
33
+ end
34
+
35
+ class ForbiddenError < AuthenticationError
36
+ private
37
+
38
+ def local_message
39
+ 'Forbidden'
40
+ end
41
+ end
42
+
43
+ class AccessTokenError < Error; end
44
+
45
+ class InvalidTokenError < AccessTokenError
46
+ private
47
+
48
+ def local_message
49
+ 'Invalid Token'
50
+ end
51
+ end
52
+
53
+ class MalformedTokenError < AccessTokenError
54
+ private
55
+
56
+ def local_message
57
+ 'Malformed access token'
58
+ end
59
+ end
60
+
61
+ class TooManyRequestsError < Error
62
+ private
63
+
64
+ def local_message
65
+ 'Too many requests'
66
+ end
67
+ end
68
+ end
@@ -1,3 +1,3 @@
1
1
  module EasyMeli
2
- VERSION = "0.3.0"
2
+ VERSION = "0.6.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easy_meli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Northam
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-15 00:00:00.000000000 Z
11
+ date: 2021-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -108,14 +108,16 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
- description:
111
+ description:
112
112
  email:
113
113
  - eric@northam.us
114
114
  executables: []
115
115
  extensions: []
116
116
  extra_rdoc_files: []
117
117
  files:
118
+ - ".github/workflows/ci.yml"
118
119
  - ".gitignore"
120
+ - CHANGELOG.md
119
121
  - Gemfile
120
122
  - LICENSE.txt
121
123
  - README.md
@@ -127,6 +129,7 @@ files:
127
129
  - lib/easy_meli/api_client.rb
128
130
  - lib/easy_meli/authorization_client.rb
129
131
  - lib/easy_meli/configuration.rb
132
+ - lib/easy_meli/constants.rb
130
133
  - lib/easy_meli/errors.rb
131
134
  - lib/easy_meli/version.rb
132
135
  homepage: https://github.com/easybroker/easy_meli
@@ -134,7 +137,7 @@ licenses:
134
137
  - MIT
135
138
  metadata:
136
139
  homepage_uri: https://github.com/easybroker/easy_meli
137
- post_install_message:
140
+ post_install_message:
138
141
  rdoc_options: []
139
142
  require_paths:
140
143
  - lib
@@ -149,8 +152,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
152
  - !ruby/object:Gem::Version
150
153
  version: '0'
151
154
  requirements: []
152
- rubygems_version: 3.0.3
153
- signing_key:
155
+ rubygems_version: 3.1.4
156
+ signing_key:
154
157
  specification_version: 4
155
158
  summary: A simple gem to work with MercadoLibre's API
156
159
  test_files: []