medium_sdk 0.0.1 → 0.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 27ae55e4729471ea5df5cb5ac7b6c1b9dcbbc3c9
4
- data.tar.gz: c426a99fa02d096d53e09483fef7312874d3a769
3
+ metadata.gz: afab6a1385d13e4a793053d8f316d0b833965c00
4
+ data.tar.gz: f5103cf9ef2728c0eee21fee3ebcedac80c706c5
5
5
  SHA512:
6
- metadata.gz: 4c977ab8bf32eeaea7b30094bec818aeee5280bfe20fe0e28a52ca2f696e15363dc844d2ce0ce89cef3d4bac27041f4bd22bfd4a01f3c0475903c8e2908f8504
7
- data.tar.gz: 53ec090b9bc602ad79483a1dce0e516bdbc8b55fe8b0e6df5b5752826c6f8cc0c2676908ab4e9fee743c796885e8c8b0a54bb5c5f777398563b0b6387de4db8b
6
+ metadata.gz: cbc6d536ea192bdd2e1fe99dfbaaa709411b3af6363316f2c7d66c12b07724747d41cae24eb73cebcb11882d26169ea05300cd98a28a40f8ab9620c78227b830
7
+ data.tar.gz: fb92b3958cb66cf4a3562c270ea72ba6f4961fcb932f9cc41b437fc327e0a9c7d7a0c8af9d4d1afc0da45c9b7dfd50f29e8f82e50fb7ef1e10b1d1ab2c88c58e
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- medium_sdk (0.0.1)
4
+ medium_sdk (0.0.2)
5
5
  faraday (~> 0.9, >= 0.9)
6
6
  faraday_middleware (~> 0, >= 0)
7
7
  faraday_middleware-oauth2_refresh (~> 0)
data/README.md CHANGED
@@ -15,9 +15,10 @@ Medium SDK for Ruby
15
15
 
16
16
  A Ruby SDK for the [Medium.com API](https://github.com/Medium/medium-api-docs) including:
17
17
 
18
- 1. Auth via OAuth 2.0 with token refresh and demo app
19
- 1. Auth via integration token
20
- 1. Get and Post APIs
18
+ 1. Auth via OAuth 2.0 with [automatic token refresh](https://github.com/grokify/faraday_middleware-oauth2_refresh) and [demo app](https://github.com/grokify/medium-sdk-ruby/tree/master/scripts/sinatra). This is necessary to request the `listPublications` or `uploadImage` access scopes.
19
+ 1. Auth via integration token with [demo app](https://github.com/grokify/medium-sdk-ruby/blob/master/scripts)
20
+ 1. Get and Post convenience APIs
21
+ 1. Raw APIs via Faraday HTTP client
21
22
 
22
23
  ## Installation
23
24
 
@@ -42,9 +43,10 @@ $ gem install medium_sdk
42
43
 
43
44
  #### Authorization Code Grant
44
45
 
45
- The OAuth 2.0 authorization code grant is designed for where authorization needs to be granted by a 3rd party resource owner.
46
+ The OAuth 2.0 authorization code grant is designed for where authorization needs to be granted by a 3rd party resource owner. This is required if your app wishes to request the `listPublications` or `uploadImage` scopes.
46
47
 
47
- Using the default authorization URL:
48
+ * Initializing the SDK with the `client_id` parameter will use `MediumSdk::Connection::AuthCode` to manage the connection
49
+ * Token refresh is automatically / transparently handled by `FaradayMiddleware::OAuth2Refresh`
48
50
 
49
51
  ```ruby
50
52
  require 'medium_sdk'
@@ -58,7 +60,7 @@ client = MediumSdk.new(
58
60
 
59
61
  # Retrieve OAuth authorize url using default redirect URL
60
62
  auth_url = client.connection.authorize_uri(
61
- scope: 'basicProfile,publishPost',
63
+ scope: 'basicProfile,listPublications,publishPost',
62
64
  state: 'myState'
63
65
  )
64
66
  ```
@@ -70,22 +72,43 @@ code = params['code'] # e.g. using Sinatra to retrieve code param in Redirect U
70
72
  client.connection.authorize_code(code)
71
73
  ```
72
74
 
75
+ You can also save and load tokens for use across SDK instances:
76
+
77
+ ```ruby
78
+ # Access `OAuth2::AccessToken` object as hash including `access_token`, `refresh_token`, etc.
79
+ token_hash = client.connection.token.to_hash
80
+
81
+ # set_token() accepts a hash or OAuth2::AccessToken object
82
+ client.connection.set_token(token_hash)
83
+ ```
84
+
73
85
  #### Integration Token
74
86
 
87
+ Initializing the SDK with the `integration_token` and not the `client_id` parameter will use `MediumSdk::Connection::IntegrationToken` to manage the connection.
88
+
75
89
  ```ruby
76
90
  require 'medium_sdk'
77
91
 
92
+ # Initialize SDK with integration token
78
93
  client = MediumSdk.new integration_token: token
94
+
95
+ # Set integration token after initialization
96
+ client.connection.token = token
79
97
  ```
80
98
 
81
99
  ### API Requests
82
100
 
101
+ #### Convenience Methods
102
+
103
+ Convenience methods are provided which return the `data` property of the response body.
104
+
83
105
  ```ruby
84
106
  # Getting the authenticated user’s details
85
107
  data = client.me
86
108
 
87
109
  # Listing the user’s publications
88
- data = client.user_publications 'user_id'
110
+ data = client.user_publications # uses authorized user's userId
111
+ data = client.user_publications 'user_id' # uses explicit userId
89
112
 
90
113
  # Fetching contributors for a publication
91
114
  data = client.publication_contributors 'publication_id'
@@ -99,17 +122,40 @@ data = client.post, {
99
122
  publishStatus: "draft"
100
123
  }
101
124
 
102
- # Creating a publication post
125
+ # Creating a backdated user post using `publishedAt` and `notifyFollowers`
126
+ data = client.post, {
127
+ title: "Hard things in software development",
128
+ contentFormat: "html",
129
+ content: "<p>Cache invalidation</p><p>Naming things</p>",
130
+ tags: ["development", "design"],
131
+ publishStatus: "public",
132
+ publishedAt: "2016-08-12T00:00:00+00:00",
133
+ notifyFollowers: false
134
+ }
135
+
136
+ # Creating a publication post using `publicationId`
103
137
  data = client.post, {
104
138
  title: "Hard things in software development",
105
139
  contentFormat: "html",
106
140
  content: "<p>Cache invalidation</p><p>Naming things</p>",
107
141
  tags: ["development", "design"],
108
- publishStatus: "draft",
142
+ publishStatus: "public",
109
143
  publicationId: "deadbeef"
110
144
  }
111
145
  ```
112
146
 
147
+ #### Raw Methods
148
+
149
+ The SDK's Faraday client can be accessed for sending raw requests:
150
+
151
+ ```ruby
152
+ response = client.connection.http.get 'me'
153
+
154
+ response = client.connection.http do |req|
155
+ req.url 'me'
156
+ end
157
+ ```
158
+
113
159
  ## Demos
114
160
 
115
161
  Demos are in the `scripts` directory and use `.env` files for configuration.
data/lib/medium_sdk.rb CHANGED
@@ -2,7 +2,7 @@ module MediumSdk
2
2
  autoload :Client, 'medium_sdk/client'
3
3
  autoload :Connection, 'medium_sdk/connection'
4
4
 
5
- VERSION = '0.0.1'
5
+ VERSION = '0.0.2'
6
6
 
7
7
  class << self
8
8
  def new(opts = {})
@@ -2,13 +2,11 @@ module MediumSdk
2
2
  class Client
3
3
  attr_accessor :connection
4
4
 
5
- attr_reader :me
6
-
7
5
  def initialize(opts = {})
8
- if opts.key? :integration_token
9
- @connection = MediumSdk::Connection::IntegrationToken.new opts
10
- elsif opts.key? :client_id
6
+ if opts.key? :client_id
11
7
  @connection = MediumSdk::Connection::AuthCode.new opts
8
+ elsif opts.key? :integration_token
9
+ @connection = MediumSdk::Connection::IntegrationToken.new opts
12
10
  end
13
11
  end
14
12
 
@@ -19,16 +17,30 @@ module MediumSdk
19
17
  end
20
18
 
21
19
  def body_key(res, key)
20
+ if res.status >= 400
21
+ raise "HTTP Error #{res.status} " + res.pretty_inspect
22
+ end
22
23
  return res.body.key?(key) ? res.body[key] : nil
23
24
  end
24
25
 
25
- def me()
26
- @me = body_key get_url('me'), 'data'
27
- return @me
26
+ def me(reload = nil)
27
+ if @_me.nil? || reload
28
+ @_me = body_key get_url('me'), 'data'
29
+ end
30
+ return @_me
31
+ end
32
+
33
+ def me_id
34
+ me unless @_me
35
+ unless @_me.is_a?(Hash) && @_me.key?('id') && @_me['id'].to_s.length>0
36
+ raise 'Authorized User Id is unknown'
37
+ end
38
+ return @_me['id']
28
39
  end
29
40
 
30
- def user_publications(user_id)
31
- res = get_url File.join 'users', user_id, 'publications'
41
+ def user_publications(user_id = nil)
42
+ user_id = me_id if user_id.nil?
43
+ res = get_url File.join 'users', user_id.to_s, 'publications'
32
44
  return body_key(res, 'data')
33
45
  end
34
46
 
@@ -39,12 +51,7 @@ module MediumSdk
39
51
  post.delete :publicationId
40
52
  url = File.join 'publications', publication_id, 'posts'
41
53
  else
42
- me unless @me
43
- unless @me.is_a?(Hash) && @me.key?('id') && @me['id'].to_s.length>0
44
- raise 'Authorized User Id is unknown'
45
- end
46
- id = @me['id']
47
- url = File.join 'users', id, 'posts'
54
+ url = File.join 'users', me_id(), 'posts'
48
55
  end
49
56
  res = @connection.http.post do |req|
50
57
  req.url url
@@ -13,6 +13,7 @@ module MediumSdk::Connection
13
13
 
14
14
  attr_reader :client_id
15
15
 
16
+ attr_accessor :authcode_client
16
17
  attr_accessor :oauth2client
17
18
  attr_accessor :oauth_redirect_uri
18
19
  attr_accessor :http
@@ -24,7 +25,9 @@ module MediumSdk::Connection
24
25
  @client_secret = opts[:client_secret] if opts.key? :client_secret
25
26
  @oauth_redirect_uri = opts[:redirect_uri] if opts.key? :redirect_uri
26
27
  @scope = opts[:scope] if opts.key? :scope
27
- @oauth2client = new_oauth2_client()
28
+ @instance_headers = opts[:instance_headers] if opts.key? :instance_headers
29
+ @oauth2client = new_oauth2_client
30
+ @authcode_client = new_auth_code_client
28
31
  end
29
32
 
30
33
  def init_attributes()
@@ -35,14 +38,14 @@ module MediumSdk::Connection
35
38
 
36
39
  def set_token(token)
37
40
  if token.is_a? Hash
38
- token = OAuth2::AccessToken::from_hash(@oauth2client, token)
41
+ token = OAuth2::AccessToken::from_hash @oauth2client, token
39
42
  elsif token.is_a? String
40
43
  if token =~ /^\s*{.+}\s*$/
41
44
  token_hash = MultiJson.decode(token)
42
- token = OAuth2::AccessToken::from_hash(@oauth2client, token_hash)
45
+ token = OAuth2::AccessToken::from_hash @oauth2client, token_hash
43
46
  else
44
47
  token = { 'access_token' => token }
45
- token = OAuth2::AccessToken::from_hash(@oauth2client, token)
48
+ token = OAuth2::AccessToken::from_hash @oauth2client, token
46
49
  end
47
50
  end
48
51
 
@@ -52,7 +55,7 @@ module MediumSdk::Connection
52
55
 
53
56
  @token = token
54
57
 
55
- @http = Faraday.new(url: api_version_url()) do |conn|
58
+ @http = Faraday.new(url: api_version_uri()) do |conn|
56
59
  conn.request :oauth2_refresh, @token
57
60
  conn.request :json
58
61
  if @instance_headers.is_a? Hash
@@ -66,7 +69,7 @@ module MediumSdk::Connection
66
69
  end
67
70
  end
68
71
 
69
- def api_version_url()
72
+ def api_version_uri()
70
73
  return File.join API_HOST, API_VERSION
71
74
  end
72
75
 
@@ -74,8 +77,10 @@ module MediumSdk::Connection
74
77
  @oauth2client = new_oauth2_client() unless @oauth2client
75
78
  opts.merge!({
76
79
  'client_id' => @client_id,
77
- 'response_type' => 'code',
78
- 'scope' => @scope })
80
+ 'response_type' => 'code'})
81
+ if ! opts.key(:scope) && ! opts.key('scope') && @scope
82
+ opts.merge!({ 'scope' => @scope })
83
+ end
79
84
  @oauth2client.auth_code.authorize_url _add_redirect_uri(opts)
80
85
  end
81
86
 
@@ -88,13 +93,6 @@ module MediumSdk::Connection
88
93
 
89
94
  def authorize_code(code, opts = {})
90
95
  #token = @oauth2client.auth_code.get_token(code, _add_redirect_uri(opts))
91
-
92
- conn = Faraday.new(:url => API_HOST) do |faraday|
93
- faraday.request :url_encoded # form-encode POST params
94
- faraday.response :json, content_type: /\bjson$/
95
- faraday.response :logger # log requests to STDOUT
96
- faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
97
- end
98
96
  params = {
99
97
  code: code,
100
98
  client_id: @client_id,
@@ -102,12 +100,21 @@ module MediumSdk::Connection
102
100
  redirect_uri: @oauth_redirect_uri,
103
101
  grant_type: 'authorization_code'
104
102
  }
105
- res = conn.post '/v1/tokens', params
103
+ res = @authcode_client.post '/v1/tokens', params
106
104
  set_token res.body
107
105
  return @token
108
106
  end
109
107
 
110
- def new_oauth2_client()
108
+ def new_auth_code_client
109
+ return Faraday.new(url: API_HOST) do |faraday|
110
+ faraday.request :url_encoded # form-encode POST params
111
+ faraday.response :json, content_type: /\bjson$/
112
+ faraday.response :logger # log requests to STDOUT
113
+ faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
114
+ end
115
+ end
116
+
117
+ def new_oauth2_client
111
118
  return OAuth2::Client.new(@client_id, @client_secret,
112
119
  site: OAUTH_HOST,
113
120
  authorize_url: OAUTH_AUTHZ_ENDPOINT,
@@ -0,0 +1,151 @@
1
+ require './test/test_base.rb'
2
+
3
+ require 'faraday'
4
+ require 'multi_json'
5
+
6
+ require 'pp'
7
+
8
+ class MediumSdkApiMeTest < Test::Unit::TestCase
9
+ def setup
10
+ body_me = MultiJson.decode('{
11
+ "data": {
12
+ "id": "5303d74c64f66366f00cb9b2a94f3251bf5",
13
+ "username": "majelbstoat",
14
+ "name": "Jamie Talbot",
15
+ "url": "https://medium.com/@majelbstoat",
16
+ "imageUrl": "https://images.medium.com/0*fkfQiTzT7TlUGGyI.png"
17
+ }
18
+ }')
19
+ body_user_publications = MultiJson.decode('{
20
+ "data": [
21
+ {
22
+ "id": "b969ac62a46b",
23
+ "name": "About Medium",
24
+ "description": "What is this thing and how does it work?",
25
+ "url": "https://medium.com/about",
26
+ "imageUrl": "https://cdn-images-1.medium.com/fit/c/200/200/0*ae1jbP_od0W6EulE.jpeg"
27
+ },
28
+ {
29
+ "id": "b45573563f5a",
30
+ "name": "Developers",
31
+ "description": "Medium’s Developer resources",
32
+ "url": "https://medium.com/developers",
33
+ "imageUrl": "https://cdn-images-1.medium.com/fit/c/200/200/1*ccokMT4VXmDDO1EoQQHkzg@2x.png"
34
+ }
35
+ ]
36
+ }')
37
+ body_publication_contributors = MultiJson.decode('{
38
+ "data": [
39
+ {
40
+ "publicationId": "b45573563f5a",
41
+ "userId": "13a06af8f81849c64dafbce822cbafbfab7ed7cecf82135bca946807ea351290d",
42
+ "role": "editor"
43
+ },
44
+ {
45
+ "publicationId": "b45573563f5a",
46
+ "userId": "1c9c63b15b874d3e354340b7d7458d55e1dda0f6470074df1cc99608a372866ac",
47
+ "role": "editor"
48
+ },
49
+ {
50
+ "publicationId": "b45573563f5a",
51
+ "userId": "1cc07499453463518b77d31650c0b53609dc973ad8ebd33690c7be9236e9384ad",
52
+ "role": "editor"
53
+ },
54
+ {
55
+ "publicationId": "b45573563f5a",
56
+ "userId": "196f70942410555f4b3030debc4f199a0d5a0309a7b9df96c57b8ec6e4b5f11d7",
57
+ "role": "writer"
58
+ },
59
+ {
60
+ "publicationId": "b45573563f5a",
61
+ "userId": "14d4a581f21ff537d245461b8ff2ae9b271b57d9554e25d863e3df6ef03ddd480",
62
+ "role": "writer"
63
+ }
64
+ ]
65
+ }')
66
+ @post_request = MultiJson.decode('{
67
+ "title": "Liverpool FC",
68
+ "contentFormat": "html",
69
+ "content": "<h1>Liverpool FC</h1><p>You’ll never walk alone.</p>",
70
+ "canonicalUrl": "http://jamietalbot.com/posts/liverpool-fc",
71
+ "tags": ["football", "sport", "Liverpool"],
72
+ "publishStatus": "public"
73
+ }')
74
+ body_post = MultiJson.decode('{
75
+ "data": {
76
+ "id": "e6f36a",
77
+ "title": "Liverpool FC",
78
+ "authorId": "5303d74c64f66366f00cb9b2a94f3251bf5",
79
+ "tags": ["football", "sport", "Liverpool"],
80
+ "url": "https://medium.com/@majelbstoat/liverpool-fc-e6f36a",
81
+ "canonicalUrl": "http://jamietalbot.com/posts/liverpool-fc",
82
+ "publishStatus": "public",
83
+ "publishedAt": 1442286338435,
84
+ "license": "all-rights-reserved",
85
+ "licenseUrl": "https://medium.com/policy/9db0094a1e0f"
86
+ }
87
+ }')
88
+ body_post_publication = MultiJson.decode('{
89
+ "data": {
90
+ "id": "e6f36a",
91
+ "title": "Liverpool FC",
92
+ "authorId": "5303d74c64f66366f00cb9b2a94f3251bf5",
93
+ "tags": ["football", "sport", "Liverpool"],
94
+ "url": "https://medium.com/@majelbstoat/liverpool-fc-e6f36a",
95
+ "canonicalUrl": "http://jamietalbot.com/posts/liverpool-fc",
96
+ "publishStatus": "public",
97
+ "publishedAt": 1442286338435000,
98
+ "license": "all-rights-reserved",
99
+ "licenseUrl": "https://medium.com/policy/9db0094a1e0f"
100
+ }
101
+ }')
102
+
103
+ stubs = Faraday::Adapter::Test::Stubs.new do |stub|
104
+ stub.get('me') { |env| [200, {}, body_me] }
105
+ stub.get('users/5303d74c64f66366f00cb9b2a94f3251bf5/publications') { |env| [200, {}, body_user_publications] }
106
+ stub.get('publications/b45573563f5a/contributors') { |env| [ 200, {}, body_publication_contributors ]}
107
+ stub.post('users/5303d74c64f66366f00cb9b2a94f3251bf5/posts') { |env| [ 200, {}, body_post ]}
108
+ stub.post('publications/b45573563f5a/posts') { |env| [ 200, {}, body_post_publication ]}
109
+ end
110
+ @client = Faraday.new do |builder|
111
+ builder.adapter :test, stubs do |stub|
112
+ stub.get('me') { |env| [ 200, {}, body_me ]}
113
+ stub.get('users/5303d74c64f66366f00cb9b2a94f3251bf5/publications') { |env| [200, {}, body_user_publications] }
114
+ stub.get('publications/b45573563f5a/contributors') { |env| [ 200, {}, body_publication_contributors ]}
115
+ stub.post('users/5303d74c64f66366f00cb9b2a94f3251bf5/posts') { |env| [ 200, {}, body_post ]}
116
+ stub.post('publications/b45573563f5a/posts') { |env| [ 200, {}, body_post_publication ]}
117
+ end
118
+ end
119
+
120
+ stubs.get('users/5303d74c64f66366f00cb9b2a94f3251bf5/publications') { |env| [ 200, {}, body_user_publications ]}
121
+ stubs.get('publications/b45573563f5a/contributors') { |env| [ 200, {}, body_publication_contributors ]}
122
+ stubs.post('users/5303d74c64f66366f00cb9b2a94f3251bf5/posts') { |env| [ 200, {}, body_post ]}
123
+ stubs.post('publications/b45573563f5a/posts') { |env| [ 200, {}, body_post_publication ]}
124
+
125
+ @token = 'deadbeef'
126
+ @sdk = MediumSdk.new integration_token: @token
127
+ @sdk.connection.http = @client
128
+ end
129
+
130
+ def test_main
131
+ data = @sdk.me
132
+ assert_equal 'majelbstoat', data['username']
133
+ id = '5303d74c64f66366f00cb9b2a94f3251bf5'
134
+ assert_equal id, data['id']
135
+
136
+ data2 = @sdk.user_publications
137
+ assert_equal 'b969ac62a46b', data2[0]['id']
138
+
139
+ data2 = @sdk.user_publications '5303d74c64f66366f00cb9b2a94f3251bf5'
140
+ assert_equal 'b969ac62a46b', data2[0]['id']
141
+
142
+ data3 = @sdk.publication_contributors 'b45573563f5a'
143
+ assert_equal '1c9c63b15b874d3e354340b7d7458d55e1dda0f6470074df1cc99608a372866ac', data3[1]['userId']
144
+
145
+ data4 = @sdk.post @post_request
146
+ assert_equal 1442286338435, data4['publishedAt']
147
+
148
+ data4 = @sdk.post @post_request.merge({publicationId: 'b45573563f5a'})
149
+ assert_equal 1442286338435000, data4['publishedAt']
150
+ end
151
+ end
@@ -0,0 +1,22 @@
1
+ require './test/test_base.rb'
2
+
3
+ require 'faraday'
4
+ require 'multi_json'
5
+
6
+ require 'pp'
7
+
8
+ class MediumSdkApiMeRaiseTest < Test::Unit::TestCase
9
+ def setup
10
+ @token = 'deadbeef'
11
+ @sdk = MediumSdk.new integration_token: @token
12
+
13
+ @sdk.connection.http = @client
14
+
15
+ end
16
+
17
+ def test_main
18
+ assert_raise do
19
+ @sdk.md_id
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,42 @@
1
+ require './test/test_base.rb'
2
+
3
+ require 'faraday'
4
+ require 'multi_json'
5
+ require 'pp'
6
+
7
+ class MediumSdkOAuthStubTest < Test::Unit::TestCase
8
+ def setup
9
+ @string = 'deadbeef'
10
+ @redirect_uri = 'https://example.com/callback'
11
+ @sdk = MediumSdk.new client_id: 'dead', client_secret: 'beef', redirect_uri: @redirect_uri
12
+
13
+ @body_token = MultiJson.decode('{
14
+ "token_type": "Bearer",
15
+ "access_token": "dead",
16
+ "refresh_token": "beef",
17
+ "scope": "listPublications",
18
+ "expires_at": 12345
19
+ }')
20
+
21
+ url = '/v1/tokens'
22
+ #url = '/m/oauth/authorize'
23
+ #url = 'tokens'
24
+ #url = 'v1/tokens'
25
+
26
+ stubs = Faraday::Adapter::Test::Stubs.new do |stub|
27
+ stub.post(url) { |env| [200, {}, @body_token] }
28
+ end
29
+ @client = Faraday.new do |builder|
30
+ builder.adapter :test, stubs do |stub|
31
+ stub.post(url) { |env| [ 200, {}, @body_token ]}
32
+ end
33
+ end
34
+ stubs.post(url) { |env| [ 200, {}, @body_token ]}
35
+ @sdk.connection.authcode_client = @client
36
+ end
37
+
38
+ def test_main
39
+ token = @sdk.connection.authorize_code 'myTestAuthCode'
40
+ assert_equal 12345, token.to_hash[:expires_at]
41
+ end
42
+ end
@@ -0,0 +1,53 @@
1
+ require './test/test_base.rb'
2
+
3
+ require 'faraday'
4
+ require 'multi_json'
5
+ require 'oauth2'
6
+
7
+ class MediumSdkSetupOAuthTest < Test::Unit::TestCase
8
+ def setup
9
+ @string = 'deadbeef'
10
+ @redirect_uri = 'https://example.com/callback'
11
+ @sdk = MediumSdk.new client_id: 'dead', client_secret: 'beef', redirect_uri: @redirect_uri
12
+ @sdk2 = MediumSdk.new client_id: 'dead', client_secret: 'beef', redirect_uri: @redirect_uri, scope: 'listPublications'
13
+ end
14
+
15
+ def test_main
16
+ assert_equal 'dead', @sdk.connection.client_id
17
+ assert_equal @redirect_uri, @sdk.connection.oauth_redirect_uri
18
+ assert_equal 'https://api.medium.com/v1', @sdk.connection.api_version_uri
19
+
20
+ token = {
21
+ 'access_token' => @string
22
+ }
23
+ @sdk.connection.set_token token
24
+ token2 = @sdk.connection.token.to_hash
25
+ assert_equal @string, token2[:access_token]
26
+
27
+ token = {
28
+ 'access_token' => @string + @string
29
+ }
30
+ token2 = MultiJson.encode token
31
+ @sdk.connection.set_token token2
32
+ token3 = @sdk.connection.token.to_hash
33
+ assert_equal (@string + @string), token3[:access_token]
34
+
35
+ @sdk.connection.set_token @string
36
+ token = @sdk.connection.token.to_hash
37
+ assert_equal @string, token[:access_token]
38
+
39
+ opts = {}
40
+ opts = @sdk.connection._add_redirect_uri opts
41
+ assert_equal @redirect_uri, opts[:redirect_uri]
42
+
43
+ auth_uri = @sdk.connection.authorize_uri
44
+ assert_equal 'https://medium.com/m/oauth/authorize?client_id=dead&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback&response_type=code', auth_uri
45
+
46
+ auth_uri = @sdk2.connection.authorize_uri
47
+ assert_equal 'https://medium.com/m/oauth/authorize?client_id=dead&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback&response_type=code&scope=listPublications', auth_uri
48
+
49
+ assert_raise do
50
+ @sdk2.connection.set_token(['fail'])
51
+ end
52
+ end
53
+ end
@@ -3,7 +3,7 @@ require './test/test_base.rb'
3
3
  require 'faraday'
4
4
  require 'oauth2'
5
5
 
6
- class MediumSdkSetupTest < Test::Unit::TestCase
6
+ class MediumSdkSetupTokenTest < Test::Unit::TestCase
7
7
  def setup
8
8
  @token = 'deadbeef'
9
9
  @sdk = MediumSdk.new integration_token: @token
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: medium_sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Wang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-11 00:00:00.000000000 Z
11
+ date: 2016-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -185,7 +185,11 @@ files:
185
185
  - lib/medium_sdk/connection.rb
186
186
  - lib/medium_sdk/connection/auth_code.rb
187
187
  - lib/medium_sdk/connection/integration_token.rb
188
+ - test/test_api_me_stub.rb
189
+ - test/test_api_me_unk.rb
188
190
  - test/test_base.rb
191
+ - test/test_oauth_stub.rb
192
+ - test/test_setup_oauth.rb
189
193
  - test/test_setup_token.rb
190
194
  homepage: https://github.com/grokify/
191
195
  licenses: