roar 0.12.2 → 0.12.3

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: 04161ea9b3e943c2369825c6a3c426cfae97550d
4
- data.tar.gz: f7a7a96c45646273d7355938becde08c0549d8b1
3
+ metadata.gz: 36037871272f0ad904505c747eeabb1a09c96c58
4
+ data.tar.gz: 964389ed57a09eb10a95f02a292865c909bda5d1
5
5
  SHA512:
6
- metadata.gz: 766eddbf40e6931caaf003a895598799c1d40efea0ba4854a1938995c0a7c0a41b96cfe1e69593c9a89538b9426305aff2f34dcd617a60a95f14840398296e54
7
- data.tar.gz: ec8585e4bc27fb429895db8d2026c70aade0b360d5b6d741d4d67c7eddc0306194947514061f8f1fe6361822ddceb5e1370b6ff671430c9628b5af5781c791e4
6
+ metadata.gz: 33c07296b014315ac382722598061026f629d95ce212e6c6f98f49068a9eb5c0939eef39fc26d54b7a267f9e5e4c266f0fc7a4391787ad7958b1451ed4614a1f
7
+ data.tar.gz: 7391c7bc51baee1d3bf8c3c6eb3b37762b4182c36cdb8474e3f0a027e5184156e1153d37890c68a7b2bc5c3ca92d943cf7ffc20151279fe74efae38baf627914
@@ -1,10 +1,8 @@
1
1
  matrix:
2
2
  include:
3
3
  - rvm: 1.9.3
4
- gemfile: gemfiles/Gemfile.representable-1.6.ruby-1.9
4
+ gemfile: gemfiles/Gemfile.representable-1.7
5
5
  - rvm: 2.0.0
6
- gemfile: gemfiles/Gemfile.representable-1.6.ruby-1.9
7
- # - rvm: 1.8.7
8
- # gemfile: gemfiles/Gemfile.representable-1.5.ruby-1.8
6
+ gemfile: gemfiles/Gemfile.representable-1.7
9
7
  notifications:
10
8
  irc: "irc.freenode.org#cells"
@@ -1,3 +1,15 @@
1
+ # 0.12.3
2
+
3
+ * Allow basic authentication with `basic_auth: [:admin, :password]`.
4
+ * Allow HTTPS.
5
+ * Removed `NetHTTP#do_request`. It is in `NetHTTP::Request` now.
6
+
7
+ ### Changes for `HttpVerbs#get` and friends:
8
+
9
+ * They now yield the request object to add headers etc before request is sent.
10
+ * They NO LONGER support positional arguments but one hash with `uri: "https://roar.de", body:, .. as: ..` and so on.
11
+
12
+
1
13
  # 0.12.2
2
14
 
3
15
  * Fix a bug where hyperlinks from nested objects weren't rendered in XML.
data/Gemfile CHANGED
@@ -3,5 +3,5 @@ source "http://rubygems.org"
3
3
  # Specify your gem's dependencies in roar.gemspec
4
4
  gemspec
5
5
 
6
- gem "representable", :path => "../representable"
7
- gem "sinatra", path: "../sinatra"
6
+ #gem "representable", :path => "../representable"
7
+ gem "sinatra-contrib", :git => "git@github.com:apotonick/sinatra-contrib.git", :branch => "runner"
@@ -476,13 +476,13 @@ class Song < OpenStruct
476
476
  end
477
477
  ```
478
478
 
479
- ### HTTP Support
479
+ ## HTTP Support
480
480
 
481
481
  The `Feature::Client` module mixes all necessary methods into the client class, e.g. it provides HTTP support
482
482
 
483
483
  ```ruby
484
484
  song = Song.new(title: "Roxanne")
485
- song.post("http://localhost:4567/songs", "application/json")
485
+ song.post(uri: "http://localhost:4567/songs", as: "application/json")
486
486
 
487
487
  song.id #=> 42
488
488
  ```
@@ -500,7 +500,7 @@ Roar works with all HTTP request types, check out `GET`.
500
500
 
501
501
  ```ruby
502
502
  song = Client::Song.new
503
- song.get("http://localhost:4567/songs/1", "application/json")
503
+ song.get(uri: "http://localhost:4567/songs/1", as: "application/json")
504
504
 
505
505
  song.title #=> "Roxanne"
506
506
  song.links[:self].href #=> http://localhost/songs/1
@@ -508,6 +508,31 @@ song.links[:self].href #=> http://localhost/songs/1
508
508
 
509
509
  As `GET` is not supposed to send any data, you can use `#get` on an empty object to populate it with the server data.
510
510
 
511
+ ### HTTPS
512
+
513
+ Roar supports SSL connections - they are automatically detected via the protocol.
514
+
515
+ ```ruby
516
+ song.get(uri: "https://localhost:4567/songs/1")`
517
+ ```
518
+
519
+ ### Basic Authentication
520
+
521
+ The HTTP verbs allow you to specify credentials for HTTP basic auth.
522
+
523
+ ```ruby
524
+ song.get(uri: "http://localhost:4567/songs/1", basic_auth: ["username", "secret_password"])
525
+ ```
526
+
527
+ ### Request customization
528
+
529
+ All verbs yield the request object before the request is sent, allowing to modify it. It is a `Net::HTTP::Request` instance (unless you use Faraday).
530
+
531
+ ```ruby
532
+ song.get(uri: "http://localhost:4567/songs/1") do |req|
533
+ req.add_field("Cookie", "Yumyum")
534
+ end
535
+ ```
511
536
 
512
537
  ## XML
513
538
 
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec path: '../'
4
+
5
+ gem 'representable', '~> 1.7.0'
6
+ gem "sinatra-contrib", :git => "git@github.com:apotonick/sinatra-contrib.git", :branch => "runner"
@@ -5,9 +5,6 @@ module Roar
5
5
  module Representer
6
6
  module Feature
7
7
  module HttpVerbs
8
- # TODO:
9
- # req.basic_auth 'user', 'pass'
10
- # Net::HTTP.start(uri.host, uri.port, use_ssl: true
11
8
 
12
9
  class << self
13
10
  attr_accessor :transport_engine
@@ -34,33 +31,33 @@ module Roar
34
31
 
35
32
  # Serializes the object, POSTs it to +url+ with +format+, deserializes the returned document
36
33
  # and updates properties accordingly.
37
- def post(url, format)
38
- response = http.post_uri(url, serialize, format)
34
+ def post(url, format, options={}, &block)
35
+ response = http.post_uri(options.merge(:uri => url, :body => serialize, :as => format), &block)
39
36
  handle_response(response)
40
37
  end
41
38
 
42
39
  # GETs +url+ with +format+, deserializes the returned document and updates properties accordingly.
43
- def get(url, format)
44
- response = http.get_uri(url, format)
40
+ def get(url, format, options={}, &block)
41
+ response = http.get_uri(options.merge(:uri => url, :as => format), &block)
45
42
  handle_response(response)
46
43
  end
47
44
 
48
45
  # Serializes the object, PUTs it to +url+ with +format+, deserializes the returned document
49
46
  # and updates properties accordingly.
50
- def put(url, format)
51
- response = http.put_uri(url, serialize, format)
47
+ def put(url, format, options={}, &block)
48
+ response = http.put_uri(options.merge(:uri => url, :body => serialize, :as => format), &block)
52
49
  handle_response(response)
53
50
  self
54
51
  end
55
52
 
56
- def patch(url, format)
57
- response = http.patch_uri(url, serialize, format)
53
+ def patch(url, format, options={}, &block)
54
+ response = http.patch_uri(options.merge(:uri => url, :body => serialize, :as => format), &block)
58
55
  handle_response(response)
59
56
  self
60
57
  end
61
58
 
62
- def delete(url, format)
63
- http.delete_uri(url, format)
59
+ def delete(url, format, options={}, &block)
60
+ http.delete_uri(options.merge(:uri => url, :as => format), &block)
64
61
  self
65
62
  end
66
63
 
@@ -13,27 +13,27 @@ module Roar
13
13
  # @see http://rubydoc.info/gems/faraday/file/README.md Faraday README
14
14
  class Faraday
15
15
 
16
- def get_uri(uri, as)
16
+ def get_uri(uri, as, *args)
17
17
  build_connection(uri, as).get
18
18
  end
19
19
 
20
- def post_uri(uri, body, as)
20
+ def post_uri(uri, body, as, *args)
21
21
  build_connection(uri, as).post(nil, body)
22
22
  end
23
23
 
24
- def put_uri(uri, body, as)
24
+ def put_uri(uri, body, as, *args)
25
25
  build_connection(uri, as).put(nil, body)
26
26
  end
27
27
 
28
- def patch_uri(uri, body, as)
28
+ def patch_uri(uri, body, as, *args)
29
29
  build_connection(uri, as).patch(nil, body)
30
30
  end
31
31
 
32
- def delete_uri(uri, as)
32
+ def delete_uri(uri, as, *args)
33
33
  build_connection(uri, as).delete
34
34
  end
35
35
 
36
- private
36
+ private
37
37
 
38
38
  def build_connection(uri, as)
39
39
  ::Faraday::Connection.new(
@@ -5,49 +5,112 @@ module Roar
5
5
  module Representer
6
6
  # Implements the (HTTP) transport interface with Net::HTTP.
7
7
  module Transport
8
- # Definitions: every call returns a Response object responding to #body.
8
+ # Low-level interface for HTTP. The #get_uri and friends accept an options and an optional block, invoke
9
+ # the HTTP request and return the request object.
10
+ #
11
+ # The following options are available:
9
12
  class NetHTTP
10
- # TODO: generically handle return codes.
11
- def get_uri(uri, as)
12
- do_request(Net::HTTP::Get, uri, as)
13
+ class Request # TODO: implement me.
14
+ def initialize(options)
15
+ @uri = parse_uri(options[:uri]) # TODO: add :uri.
16
+ @as = options[:as]
17
+ @body = options[:body]
18
+ @options = options
19
+
20
+ @http = Net::HTTP.new(uri.host, uri.port)
21
+ end
22
+
23
+ def call(what)
24
+ @req = what.new(uri.request_uri)
25
+
26
+ # if options[:ssl]
27
+ # uri.port = Net::HTTP.https_default_port()
28
+ # end
29
+ https!
30
+ basic_auth!
31
+
32
+ req.content_type = as
33
+ req["accept"] = as # TODO: test me. # DISCUSS: if Accept is not set, rails treats this request as as "text/html".
34
+ req.body = body if body
35
+
36
+ yield req if block_given?
37
+
38
+ http.request(req).tap do |res|
39
+ raise UnauthorizedError if res.is_a?(Net::HTTPUnauthorized) # FIXME: make this better. # DISCUSS: abstract all that crap here?
40
+ end
41
+ end
42
+
43
+ def get
44
+ call(Net::HTTP::Get)
45
+ end
46
+
47
+ private
48
+ attr_reader :uri, :as, :body, :options, :req, :http
49
+
50
+ def parse_uri(url)
51
+ uri = URI(url)
52
+ raise "Incorrect URL `#{url}`. Maybe you forgot http://?" if uri.instance_of?(URI::Generic)
53
+ uri
54
+ end
55
+
56
+ def https!
57
+ return unless uri.scheme == 'https'
58
+
59
+ @http.use_ssl = true
60
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
61
+ end
62
+
63
+ def basic_auth!
64
+ return unless options[:basic_auth]
65
+
66
+ @req.basic_auth(*options[:basic_auth])
67
+ end
13
68
  end
14
69
 
15
- def post_uri(uri, body, as)
16
- do_request(Net::HTTP::Post, uri, as, body)
70
+
71
+ def get_uri(*options, &block)
72
+ call(Net::HTTP::Get, *options, &block)
17
73
  end
18
74
 
19
- def put_uri(uri, body, as)
20
- do_request(Net::HTTP::Put, uri, as, body)
75
+ def post_uri(*options, &block)
76
+ call(Net::HTTP::Post, *options, &block)
21
77
  end
22
78
 
23
- def patch_uri(uri, body, as)
24
- do_request(Net::HTTP::Patch, uri, as, body)
79
+ def put_uri(*options, &block)
80
+ call(Net::HTTP::Put, *options, &block)
25
81
  end
26
82
 
27
- def delete_uri(uri, as)
28
- do_request(Net::HTTP::Delete, uri, as)
83
+ def delete_uri(*options, &block)
84
+ call(Net::HTTP::Delete, *options, &block)
29
85
  end
30
86
 
31
- private
32
- def do_request(what, uri, as, body="")
33
- # DISCUSS: can this be made easier?
34
- uri = parse_uri(uri)
35
- http = Net::HTTP.new(uri.host, uri.port)
36
- req = what.new(uri.request_uri)
87
+ def patch_uri(*options, &block)
88
+ call(Net::HTTP::Patch, *options, &block)
89
+ end
37
90
 
91
+ private
92
+ def call(what, *args, &block)
93
+ options = handle_deprecated_args(args)
94
+ # TODO: generically handle return codes.
95
+ Request.new(options).call(what, &block)
96
+ end
38
97
 
39
- req.content_type = as
40
- req["accept"] = as # TODO: test me. # DISCUSS: if Accept is not set, rails treats this request as as "text/html".
41
- req.body = body if body
98
+ def handle_deprecated_args(args) # TODO: remove in 1.0.
99
+ if args.size > 1
100
+ warn %{DEPRECATION WARNING: #get_uri, #post_uri, #put_uri, #delete_uri and #patch_uri no longer accept positional arguments. Please call them as follows:
101
+ get_uri(uri: "http://localhost/songs", as: "application/json")
102
+ post_uri(uri: "http://localhost/songs", as: "application/json", body: "{'id': 1}")
103
+ Thank you and have a lovely day.}
104
+ return {:uri => args[0], :as => args[1]} if args.size == 2
105
+ return {:uri => args[0], :as => args[2], :body => args[1]}
106
+ end
42
107
 
43
- http.request(req)
108
+ args.first
44
109
  end
45
110
 
46
- def parse_uri(url)
47
- uri = URI(url)
48
- raise "Incorrect URL `#{url}`. Maybe you forgot http://?" if uri.instance_of?(URI::Generic)
49
- uri
50
- end
111
+ end
112
+
113
+ class UnauthorizedError < RuntimeError # TODO: raise this from Faraday, too.
51
114
  end
52
115
  end
53
116
  end
@@ -1,3 +1,3 @@
1
1
  module Roar
2
- VERSION = "0.12.2"
2
+ VERSION = "0.12.3"
3
3
  end
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
23
23
 
24
24
  s.add_development_dependency "rake", ">= 0.10.1"
25
25
  s.add_development_dependency "test_xml", ">= 0.1.6"
26
- s.add_development_dependency "minitest", ">= 5.0.0"
26
+ s.add_development_dependency "minitest", "= 5.0.0"
27
27
  s.add_development_dependency "sinatra"
28
28
  s.add_development_dependency "virtus"
29
29
  s.add_development_dependency "faraday"
@@ -4,8 +4,6 @@ require 'roar/representer/json/collection_json'
4
4
  class CollectionJsonTest < MiniTest::Spec
5
5
  let(:song) { OpenStruct.new(:title => "scarifice", :length => 43) }
6
6
 
7
- # FIXME: test absence of ::items, ::template, etc.
8
-
9
7
  representer_for([Roar::Representer::JSON::CollectionJSON]) do
10
8
  version "1.0"
11
9
  href { "//songs/" }
@@ -50,7 +48,7 @@ class CollectionJsonTest < MiniTest::Spec
50
48
  },
51
49
 
52
50
  "queries"=>[
53
- {:rel=>:search, :href=>"//search",
51
+ {:rel=>:search, :href=>"//search",
54
52
  :data=>[
55
53
  {:name=>"q", :value=>""}
56
54
  ]
@@ -120,7 +120,9 @@ class HalJsonTest < MiniTest::Spec
120
120
  it "doesn't require _links and _embedded to be present" do
121
121
  @album.from_json("{\"id\":2}")
122
122
  assert_equal 2, @album.id
123
- assert_equal [], @album.songs
123
+
124
+ # in newer representables, this is not overwritten to an empty [] anymore.
125
+ assert_equal ["Beer"], @album.songs.map(&:title)
124
126
  @album.links.must_equal({})
125
127
  end
126
128
  end
@@ -10,6 +10,8 @@ class HttpVerbsTest < MiniTest::Spec
10
10
  attr_accessor :name, :label
11
11
  end
12
12
 
13
+ let (:band) { OpenStruct.new(:name => "bodyjar").extend(Roar::Representer::Feature::HttpVerbs, BandRepresenter) }
14
+
13
15
 
14
16
  describe "HttpVerbs" do
15
17
  before do
@@ -105,7 +107,42 @@ class HttpVerbsTest < MiniTest::Spec
105
107
  end
106
108
  end
107
109
 
108
- # HEAD, OPTIONs?
110
+ describe "HTTPS and Authentication" do
111
+ let (:song) { OpenStruct.new(:name => "bodyjar").extend(Roar::Representer::Feature::HttpVerbs, BandRepresenter) }
112
+
113
+ describe "Basic Auth: passing manually" do
114
+
115
+ end
116
+
117
+ describe "HTTPS: passing manually" do
118
+ verbs do |verb|
119
+ it "allows #{verb}" do
120
+ song.send(verb, "https://localhost:8443/bands/bodyjar", "application/json")
121
+
122
+ if verb == "delete"
123
+ song.name.must_equal "bodyjar"
124
+ else
125
+ song.name.must_equal "Bodyjar"
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ describe "HTTPS+Basic Auth: passing manually" do
132
+ it "allows GET" do
133
+ song.get("https://localhost:8443/protected", "application/json", :basic_auth => [:admin, :password])
134
+
135
+ song.name.must_equal "Bodyjar"
136
+ end
137
+ end
138
+ end
109
139
 
140
+ describe "request customization" do
141
+ it "yields the request object" do
142
+ band.get("http://localhost:4567/cookies", "application/json") do |req|
143
+ req.add_field("Cookie", "Yumyum")
144
+ end.name.must_equal "Bodyjar"
145
+ end
146
+ end
110
147
  end
111
148
  end
@@ -1,30 +1,41 @@
1
1
  require "integration/band_representer"
2
- #require '/home/nick/projects/sinatra/test/integration_helper'
3
- class ServerRunner# < IntegrationHelper::Server
2
+ require 'sinatra/runner'
3
+
4
+ class ServerRunner < Sinatra::Runner
4
5
  def app_file
5
6
  File.expand_path("../server.rb", __FILE__)
6
7
  end
7
8
 
8
- def run
9
- puts command
10
- puts @pipe = IO.popen(command)
11
- sleep 2
9
+ def command
10
+ "bundle exec ruby #{app_file} -p #{port} -e production"
12
11
  end
13
12
 
13
+ def ping_path # to be overwritten
14
+ '/ping'
15
+ end
16
+ end
17
+
18
+ class SslServerRunner < ServerRunner
14
19
  def command
15
- "cd #{File.expand_path("..", __FILE__)} && bundle exec ruby #{app_file} -p 4567 -e production"
20
+ "bundle exec ruby #{File.expand_path("../ssl_server.rb", __FILE__)}"
16
21
  end
17
22
 
18
- def kill
19
- puts "Killling : #{@pipe.pid.inspect}"
20
- Process.kill("KILL", @pipe.pid)
23
+ def port
24
+ 8443
25
+ end
26
+
27
+ def protocol
28
+ "https"
21
29
  end
22
30
  end
23
- runner = ServerRunner.new
24
- #at_exit { puts "killing it:"; runner.kill }
25
31
 
32
+ runner = ServerRunner.new
26
33
  runner.run
27
34
 
35
+ ssl_runner = SslServerRunner.new
36
+ ssl_runner.run
37
+
28
38
  MiniTest::Unit.after_tests do
29
39
  runner.kill
40
+ ssl_runner.kill
30
41
  end
@@ -2,6 +2,7 @@ require "bundler/setup"
2
2
  require "sinatra"
3
3
  require "ostruct"
4
4
  require "roar/representer/json"
5
+ require "sinatra/multi_route"
5
6
 
6
7
  require File.expand_path("../band_representer.rb", __FILE__)
7
8
 
@@ -75,3 +76,34 @@ end
75
76
  delete '/bands/metallica' do
76
77
  status 204
77
78
  end
79
+
80
+
81
+ helpers do
82
+ def protected!
83
+ return if authorized?
84
+ headers['WWW-Authenticate'] = 'Basic realm="Restricted Area"'
85
+ halt 401, "Not authorized\n"
86
+ end
87
+
88
+ def authorized?
89
+ @auth ||= Rack::Auth::Basic::Request.new(request.env)
90
+ @auth.provided? and @auth.basic? and @auth.credentials and @auth.credentials == ['admin', 'password']
91
+ end
92
+ end
93
+
94
+ route :get, :post, :put, :delete, "/protected/bands/bodyjar" do
95
+ protected!
96
+
97
+ OpenStruct.new(:name => "Bodyjar").
98
+ extend(Integration::BandRepresenter).
99
+ to_json
100
+ end
101
+
102
+ route :get, :post, :put, :delete, "/cookies" do
103
+ raise "No cookies!" unless request.env["HTTP_COOKIE"] == "Yumyum"
104
+ %{{"name": "Bodyjar"}}
105
+ end
106
+
107
+ get "/ping" do
108
+ "1"
109
+ end
@@ -0,0 +1,60 @@
1
+ require 'sinatra/base'
2
+ require 'webrick'
3
+ require 'webrick/https'
4
+ require 'openssl'
5
+ require 'sinatra/multi_route'
6
+
7
+ name = "/C=US/ST=SomeState/L=SomeCity/O=Organization/OU=Unit/CN=localhost"
8
+ ca = OpenSSL::X509::Name.parse(name)
9
+ key = OpenSSL::PKey::RSA.new(1024)
10
+ crt = OpenSSL::X509::Certificate.new
11
+ crt.version = 2
12
+ crt.serial = 1
13
+ crt.subject = ca
14
+ crt.issuer = ca
15
+ crt.public_key = key.public_key
16
+ crt.not_before = Time.now
17
+ crt.not_after = Time.now + 1 * 365 * 24 * 60 * 60 # 1 year
18
+ webrick_options = {
19
+ :Port => 8443,
20
+ :SSLEnable => true,
21
+ :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
22
+ :SSLCertificate => crt,
23
+ :SSLPrivateKey => key,
24
+ :SSLCertName => [[ "CN", WEBrick::Utils::getservername ]],
25
+ }
26
+
27
+ class SslServer < Sinatra::Base
28
+ register Sinatra::MultiRoute
29
+
30
+ get '/ping' do
31
+ "1"
32
+ end
33
+
34
+ route :get, :post, :put, :delete, "/bands/bodyjar" do
35
+ %{{"name": "Bodyjar"}}
36
+ end
37
+
38
+ # FIXME: redundant with server.rb.
39
+ helpers do
40
+ def protected!
41
+ return if authorized?
42
+ headers['WWW-Authenticate'] = 'Basic realm="Restricted Area"'
43
+ halt 401, "Not authorized\n"
44
+ end
45
+
46
+ def authorized?
47
+ @auth ||= Rack::Auth::Basic::Request.new(request.env)
48
+ @auth.provided? and @auth.basic? and @auth.credentials and @auth.credentials == ['admin', 'password']
49
+ end
50
+ end
51
+
52
+ get "/protected" do
53
+ protected!
54
+
55
+ %{{"name": "Bodyjar"}}
56
+ end
57
+ end
58
+ server = ::Rack::Handler::WEBrick
59
+
60
+ server.run(SslServer, webrick_options)
@@ -5,44 +5,80 @@ class NetHTTPTransportTest < MiniTest::Spec
5
5
  let(:url) { "http://localhost:4567/method" }
6
6
  let(:body) { "booty" }
7
7
  let(:as) { "application/xml" }
8
- before do
9
- @transport = Roar::Representer::Transport::NetHTTP.new
10
- end
8
+ let (:transport) { Roar::Representer::Transport::NetHTTP.new }
11
9
 
12
10
  it "#get_uri returns response" do
13
- @transport.get_uri(url, as).must_match_net_response :get, url, as
11
+ transport.get_uri(:uri => url, :as => as).must_match_net_response :get, url, as
14
12
  end
15
13
 
16
14
  it "#post_uri returns response" do
17
- @transport.post_uri(url, body, as).must_match_net_response :post, url, as, body
15
+ transport.post_uri(:uri => url, :as => as, :body => body).must_match_net_response :post, url, as, body
18
16
  end
19
17
 
20
18
  it "#put_uri returns response" do
21
- @transport.put_uri(url, body, as).must_match_net_response :put, url, as, body
19
+ transport.put_uri(:uri => url, :as => as, :body => body).must_match_net_response :put, url, as, body
22
20
  end
23
21
 
24
22
  it "#delete_uri returns response" do
25
- @transport.delete_uri(url, as).must_match_net_response :delete, url, as
23
+ transport.delete_uri(:uri => url, :as => as).must_match_net_response :delete, url, as
26
24
  end
27
25
 
28
26
  it "#patch_uri returns response" do
29
- @transport.patch_uri(url, body, as).must_match_net_response :patch, url, as, body
27
+ transport.patch_uri(:uri => url, :as => as, :body => body).must_match_net_response :patch, url, as, body
30
28
  end
31
29
 
32
30
  it "complains with invalid URL" do
33
31
  assert_raises RuntimeError do
34
- @transport.get_uri("example.com", as)
32
+ transport.get_uri(:uri => "example.com", :as => as)
33
+ end
34
+ end
35
+
36
+ # TODO: test all verbs.
37
+ describe "request customization" do
38
+ #verbs do |verb|
39
+ verb = "get"
40
+ it "#{verb} yields the request object" do
41
+ transport.send("#{verb}_uri", :uri => "http://localhost:4567/cookies", :as => "application/json") do |req|
42
+ req.add_field("Cookie", "Yumyum")
43
+ end.body.must_equal %{{"name": "Bodyjar"}}
44
+ end
45
+ #end
46
+ end
47
+
48
+ describe "basic auth" do
49
+ it "raises when no credentials provided" do
50
+ assert_raises Roar::Representer::Transport::UnauthorizedError do
51
+ transport.get_uri(:uri => "http://localhost:4567/protected/bands/bodyjar", :as => "application/json")
52
+ end
53
+ end
54
+
55
+ it "raises when wrong credentials provided" do
56
+ assert_raises Roar::Representer::Transport::UnauthorizedError do
57
+ transport.get_uri(:uri => "http://localhost:4567/protected/bands/bodyjar", :as => "application/json", :basic_auth => ["admin", "wrong--!!!--password"])
58
+ end
59
+ end
60
+
61
+ it "what" do
62
+ transport.get_uri(:uri => "http://localhost:4567/protected/bands/bodyjar", :as => "application/json", :basic_auth => ["admin", "password"])
63
+ end
64
+ end
65
+
66
+ describe "deprecations" do
67
+ it "old GET API still works" do
68
+ transport.get_uri(url, as).must_match_net_response :get, url, as
69
+ end
70
+
71
+ it "old POST API still works" do
72
+ transport.post_uri(url, body, as).must_match_net_response :post, url, as, body
35
73
  end
36
74
  end
37
75
  end
38
76
 
39
77
  module MiniTest::Assertions
40
-
41
78
  def assert_net_response(type, response, url, as, body = nil)
42
79
  # TODO: Assert headers
43
80
  assert_equal "<method>#{type}#{(' - ' + body) if body}</method>", response.body
44
81
  end
45
-
46
82
  end
47
83
 
48
84
  Net::HTTPOK.infect_an_assertion :assert_net_response, :must_match_net_response
@@ -46,6 +46,10 @@ MiniTest::Spec.class_eval do
46
46
  def self.representer!(*args)
47
47
  representer_for(*args)
48
48
  end
49
+
50
+ def self.verbs(&block)
51
+ %w(get post put delete).each(&block)
52
+ end
49
53
  end
50
54
 
51
55
  Roar::Representer::Feature::Hypermedia::Hyperlink.class_eval do
metadata CHANGED
@@ -1,125 +1,125 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.2
4
+ version: 0.12.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-19 00:00:00.000000000 Z
11
+ date: 2014-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: representable
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 1.6.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 1.6.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.10.1
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.10.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: test_xml
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: 0.1.6
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.1.6
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: minitest
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - '='
60
60
  - !ruby/object:Gem::Version
61
61
  version: 5.0.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - '='
67
67
  - !ruby/object:Gem::Version
68
68
  version: 5.0.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: sinatra
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: virtus
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: faraday
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: json
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - '>='
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
117
  version: '0'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - '>='
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  description: Streamlines the development of RESTful, resource-oriented architectures
@@ -130,8 +130,8 @@ executables: []
130
130
  extensions: []
131
131
  extra_rdoc_files: []
132
132
  files:
133
- - .gitignore
134
- - .travis.yml
133
+ - ".gitignore"
134
+ - ".travis.yml"
135
135
  - CHANGES.markdown
136
136
  - Gemfile
137
137
  - LICENSE
@@ -140,9 +140,7 @@ files:
140
140
  - TODO.markdown
141
141
  - examples/example.rb
142
142
  - examples/example_server.rb
143
- - gemfiles/Gemfile.representable-1.5.ruby-1.8
144
- - gemfiles/Gemfile.representable-1.5.ruby-1.9
145
- - gemfiles/Gemfile.representable-1.6.ruby-1.9
143
+ - gemfiles/Gemfile.representable-1.7
146
144
  - lib/roar.rb
147
145
  - lib/roar/decorator.rb
148
146
  - lib/roar/representer.rb
@@ -165,13 +163,14 @@ files:
165
163
  - test/faraday_http_transport_test.rb
166
164
  - test/hal_json_test.rb
167
165
  - test/hal_links_test.rb
168
- - test/http_verbs_feature_test.rb
166
+ - test/http_verbs_test.rb
169
167
  - test/hypermedia_feature_test.rb
170
168
  - test/hypermedia_test.rb
171
169
  - test/integration/Gemfile
172
170
  - test/integration/band_representer.rb
173
171
  - test/integration/runner.rb
174
172
  - test/integration/server.rb
173
+ - test/integration/ssl_server.rb
175
174
  - test/json_representer_test.rb
176
175
  - test/net_http_transport_test.rb
177
176
  - test/representer_test.rb
@@ -187,18 +186,38 @@ require_paths:
187
186
  - lib
188
187
  required_ruby_version: !ruby/object:Gem::Requirement
189
188
  requirements:
190
- - - '>='
189
+ - - ">="
191
190
  - !ruby/object:Gem::Version
192
191
  version: '0'
193
192
  required_rubygems_version: !ruby/object:Gem::Requirement
194
193
  requirements:
195
- - - '>='
194
+ - - ">="
196
195
  - !ruby/object:Gem::Version
197
196
  version: '0'
198
197
  requirements: []
199
198
  rubyforge_project: roar
200
- rubygems_version: 2.0.3
199
+ rubygems_version: 2.2.1
201
200
  signing_key:
202
201
  specification_version: 4
203
202
  summary: Resource-oriented architectures in Ruby.
204
- test_files: []
203
+ test_files:
204
+ - test/client_test.rb
205
+ - test/coercion_feature_test.rb
206
+ - test/collection_json_test.rb
207
+ - test/decorator_test.rb
208
+ - test/faraday_http_transport_test.rb
209
+ - test/hal_json_test.rb
210
+ - test/hal_links_test.rb
211
+ - test/http_verbs_test.rb
212
+ - test/hypermedia_feature_test.rb
213
+ - test/hypermedia_test.rb
214
+ - test/integration/Gemfile
215
+ - test/integration/band_representer.rb
216
+ - test/integration/runner.rb
217
+ - test/integration/server.rb
218
+ - test/integration/ssl_server.rb
219
+ - test/json_representer_test.rb
220
+ - test/net_http_transport_test.rb
221
+ - test/representer_test.rb
222
+ - test/test_helper.rb
223
+ - test/xml_representer_test.rb
@@ -1,6 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gemspec :path => '../'
4
-
5
- gem 'representable', '~> 1.5.2'
6
- gem 'json'
@@ -1,5 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gemspec path: '../'
4
-
5
- gem 'representable', '~> 1.5.2'
@@ -1,5 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gemspec path: '../'
4
-
5
- gem 'representable', '~> 1.6.0'