heroics 0.0.4 → 0.0.5

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
  SHA1:
3
- metadata.gz: 259b6035c675a64b2a0c1243765f22f1c3358844
4
- data.tar.gz: e698d60d9f9f1afb43530587b5f54e3ad5da1765
3
+ metadata.gz: c560efe3fc3a956cf69a67b4a9c18e635148e4de
4
+ data.tar.gz: daf31b6ace54f1f25a3a813976cae85c1b34526a
5
5
  SHA512:
6
- metadata.gz: 93fa2f9040ad82ee8572ac916e156fe3948dc3db45248e1c875d3e808d5b4589b6d21468993a7eb4acab46c80fd6653e633e3342bc908d185ecac84c87e5ad03
7
- data.tar.gz: c9baf8841b6386ec09f1cbacf12b4a6cbad2839bb09f2b176f75440e8d62cbb64aee40512f1d79d01bf34f61cfa8eeacddf3d437598d7399673ae425952e93ac
6
+ metadata.gz: 0db8243ab8d5176c0d50b48e0271b9cf66cebda01a1f12732f7e8ec33da3975be6d665bc61d88f20654a3b83a2e2652182e8dbb45109e27be30f93f522dbfbcc
7
+ data.tar.gz: 0d8c324bd42763d58e492f1cb50d54c384667192e3bb05c59e626a759cded66cf04aa40c1f5ce615e8a45b90b9f23704e384d099bcc357183ebdeff3ab4ffb93
data/README.md CHANGED
@@ -19,12 +19,11 @@ Or install it yourself as:
19
19
 
20
20
  ## Usage
21
21
 
22
- ### Instantiate a client from a JSON schema
22
+ ### Instantiate a client from a JSON schema with basic credentials
23
23
 
24
24
  Heroics instantiates an HTTP client from a JSON schema. The client
25
25
  will make requests to the API using the credentials from the URL. The
26
- default headers will also be included in all requests (including the
27
- one to download the schema and all subsequent requests).
26
+ default headers will also be included in all requests.
28
27
 
29
28
  ```ruby
30
29
  require 'cgi'
@@ -33,13 +32,27 @@ require 'heroics'
33
32
 
34
33
  username = CGI.escape('username')
35
34
  token = 'token'
36
- url = "https://#{username}:#{token}@api.heroku.com/schema"
35
+ url = "https://#{username}:#{token}@api.heroku.com"
37
36
  options = {default_headers: {'Accept' => 'application/vnd.heroku+json; version=3'}}
38
37
  data = JSON.parse(File.read('schema.json'))
39
38
  schema = Heroics::Schema.new(data)
40
39
  client = Heroics.client_from_schema(schema, url, options)
41
40
  ```
42
41
 
42
+ ### Instantiate a client from a JSON schema with an OAuth token
43
+
44
+ The client will make requests to the API using an OAuth token when one is
45
+ provided.
46
+
47
+ ```ruby
48
+ oauth_token = 'token'
49
+ url = "https://api.heroku.com"
50
+ options = {default_headers: {'Accept' => 'application/vnd.heroku+json; version=3'}}
51
+ data = JSON.parse(File.read('schema.json'))
52
+ schema = Heroics::Schema.new(data)
53
+ client = Heroics.oauth_client_from_schema(oauth_token, schema, url, options)
54
+ ```
55
+
43
56
  ### Client-side caching
44
57
 
45
58
  Heroics handles ETags and will cache data on the client if you provide
data/lib/heroics.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'base64'
1
2
  require 'excon'
2
3
  require 'moneta'
3
4
  require 'multi_json'
@@ -55,4 +55,29 @@ module Heroics
55
55
  end
56
56
  Client.new(resources, url)
57
57
  end
58
+
59
+ # Create an HTTP client with OAuth credentials from a JSON schema.
60
+ #
61
+ # @param oauth_token [String] The OAuth token to pass using the `Bearer`
62
+ # authorization mechanism.
63
+ # @param schema [Schema] The JSON schema to build an HTTP client for.
64
+ # @param url [String] The URL the generated client should use when making
65
+ # requests.
66
+ # @param options [Hash] Configuration for links. Possible keys include:
67
+ # - default_headers: Optionally, a set of headers to include in every
68
+ # request made by the client. Default is no custom headers.
69
+ # - cache: Optionally, a Moneta-compatible cache to store ETags. Default
70
+ # is no caching.
71
+ # @return [Client] A client with resources and links from the JSON schema.
72
+ def self.oauth_client_from_schema(oauth_token, schema, url, options={})
73
+ encoded_token = Base64.strict_encode64(":#{oauth_token}")
74
+ authorization = "Bearer #{encoded_token}"
75
+ # Don't mutate user-supplied data.
76
+ options = Marshal.load(Marshal.dump(options))
77
+ if !options.has_key?(:default_headers)
78
+ options[:default_headers] = {}
79
+ end
80
+ options[:default_headers].merge!({"Authorization" => authorization})
81
+ client_from_schema(schema, url, options)
82
+ end
58
83
  end
@@ -33,6 +33,12 @@ module Heroics
33
33
  def resources
34
34
  @resources.values
35
35
  end
36
+
37
+ # Get a simple human-readable representation of this client instance.
38
+ def inspect
39
+ "#<Heroics::Schema description=\"#{@schema['description']}\">"
40
+ end
41
+ alias to_s inspect
36
42
  end
37
43
 
38
44
  # A wrapper around a bare resource element in a JSON schema to make it
@@ -1,3 +1,3 @@
1
1
  module Heroics
2
- VERSION = '0.0.4'
2
+ VERSION = '0.0.5'
3
3
  end
data/test/client_test.rb CHANGED
@@ -137,3 +137,51 @@ class ClientFromSchemaTest < MiniTest::Unit::TestCase
137
137
  assert_equal(body, client.resource.list)
138
138
  end
139
139
  end
140
+
141
+ class OAuthClientFromSchemaTest < MiniTest::Unit::TestCase
142
+ include ExconHelper
143
+
144
+ # oauth_client_from_schema injects an Authorization header, built from the
145
+ # specified OAuth token, into the default header options.
146
+ def test_oauth_client_from_schema
147
+ body = {'Hello' => 'World!'}
148
+ Excon.stub(method: :get) do |request|
149
+ assert_equal(
150
+ 'Bearer OmM1NWVmMGQ4LTQwYjYtNDc1OS1iMWJmLTRhNmY5NDE5MGE2Ng==',
151
+ request[:headers]['Authorization'])
152
+ Excon.stubs.pop
153
+ {status: 200, headers: {'Content-Type' => 'application/json'},
154
+ body: MultiJson.dump(body)}
155
+ end
156
+
157
+ oauth_token = 'c55ef0d8-40b6-4759-b1bf-4a6f94190a66'
158
+ schema = Heroics::Schema.new(SAMPLE_SCHEMA)
159
+ client = Heroics.oauth_client_from_schema(oauth_token, schema,
160
+ 'https://example.com')
161
+ assert_equal(body, client.resource.list)
162
+ end
163
+
164
+ # oauth_client_from_schema doesn't mutate the options object, and in
165
+ # particular, it doesn't mutate the :default_headers Hash in that object.
166
+ def test_oauth_client_from_schema_with_options
167
+ body = {'Hello' => 'World!'}
168
+ Excon.stub(method: :get) do |request|
169
+ assert_equal('application/vnd.heroku+json; version=3',
170
+ request[:headers]['Accept'])
171
+ assert_equal(
172
+ 'Bearer OmM1NWVmMGQ4LTQwYjYtNDc1OS1iMWJmLTRhNmY5NDE5MGE2Ng==',
173
+ request[:headers]['Authorization'])
174
+ Excon.stubs.pop
175
+ {status: 200, headers: {'Content-Type' => 'application/json'},
176
+ body: MultiJson.dump(body)}
177
+ end
178
+
179
+ oauth_token = 'c55ef0d8-40b6-4759-b1bf-4a6f94190a66'
180
+ options = {
181
+ default_headers: {'Accept' => 'application/vnd.heroku+json; version=3'}}
182
+ schema = Heroics::Schema.new(SAMPLE_SCHEMA)
183
+ client = Heroics.oauth_client_from_schema(oauth_token, schema,
184
+ 'https://example.com', options)
185
+ assert_equal(body, client.resource.list)
186
+ end
187
+ end
data/test/helper.rb CHANGED
@@ -23,6 +23,7 @@ end
23
23
 
24
24
  # A simple JSON schema for testing purposes.
25
25
  SAMPLE_SCHEMA = {
26
+ 'description' => 'Sample schema for use in tests.',
26
27
  'definitions' => {
27
28
  'resource' => {
28
29
  'description' => 'A sample resource to use in tests.',
data/test/schema_test.rb CHANGED
@@ -1,6 +1,15 @@
1
1
  require 'helper'
2
2
 
3
3
  class SchemaTest < MiniTest::Unit::TestCase
4
+ # Schema.to_s returns a simple human-readable description of the schema
5
+ # instance with the description embedded in it.
6
+ def test_to_s
7
+ schema = Heroics::Schema.new(SAMPLE_SCHEMA)
8
+ assert_equal(
9
+ '#<Heroics::Schema description="Sample schema for use in tests.">',
10
+ schema.to_s)
11
+ end
12
+
4
13
  # Schema.resource returns a ResourceSchema for the named resource.
5
14
  def test_resource
6
15
  schema = Heroics::Schema.new(SAMPLE_SCHEMA)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heroics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - geemus
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-03-14 00:00:00.000000000 Z
12
+ date: 2014-03-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler