restfully 0.7.1.rc5 → 0.7.1.rc6

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE CHANGED
@@ -1,5 +1,4 @@
1
- Copyright (c) 2009 Cyril Rohr
2
- Copyright (c) 2009 INRIA Rennes - Bretagne Atlantique
1
+ Copyright (c) 2009-2011 Cyril Rohr, INRIA Rennes - Bretagne Atlantique
3
2
 
4
3
  Permission is hereby granted, free of charge, to any person obtaining
5
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,134 +1,78 @@
1
- # restfully
2
-
3
- An attempt at dynamically providing wrappers on top of RESTful APIs that follow the principle of Hyperlinks As The Engine Of Application State (HATEOAS).
4
- It does not require to use specific (and often complex) server-side libraries, but a few constraints and conventions must be followed:
5
-
6
- 1. Return sensible HTTP status codes;
7
- 2. Make use of GET, POST, PUT, DELETE HTTP methods;
8
- 3. Return a Location HTTP header in 201 or 202 responses;
9
- 4. Return a <tt>links</tt> property in all responses to a GET request, that contains a list of link objects:
10
-
11
- {
12
- "property": "value",
13
- "links": [
14
- {"rel": "self", "href": "uri/to/resource", "type": "application/vnd.whatever+json;level=1,application/json"},
15
- {"rel": "parent", "href": "uri/to/parent/resource", "type": "application/json"}
16
- {"rel": "collection", "href": "uri/to/collection", "title": "my_collection", "type": "application/json"},
17
- {"rel": "member", "href": "uri/to/member", "title": "member_title", "type": "application/json"}
18
- ]
19
- }
20
-
21
- * Adding a <tt>parent</tt> link automatically creates a <tt>#parent</tt> method on the current resource.
22
- * Adding a <tt>collection</tt> link automatically creates a <tt>#my_collection</tt> method that will fetch the Collection when called.
23
- * Adding a <tt>member</tt> link automatically creates a <tt>#member_title</tt> method that will fetch the Resource when called.
24
-
25
- 5. Advertise allowed HTTP methods in the response to GET requests by returning a <tt>Allow</tt> HTTP header containing a comma-separated list of the HTTP methods that can be used on the resource. This will allow the automatic generation of methods to interact with the resource. e.g.: advertising a <tt>POST</tt> method (<tt>Allow: GET, POST</tt>) will result in the creation of a <tt>submit</tt> method on the resource.
1
+ # Restfully
2
+ Restfully is a general-purpose client library for RESTful APIs. It is written in Ruby. Its goal is to abstract the nitty-gritty details of exchanging HTTP requests between the user-agent and the server. It also discovers resources at runtime, which means should the API change and add a new functionality, the client will automatically discover it.
3
+
4
+ It works on simple concepts:
5
+
6
+ 1. All APIs are made of **resources**, and **collections of resources**.
7
+ 2. The **media-type** of a resource dictates the relationships between that resource and the other resources, and what it is possible to do with them.
8
+
9
+ Therefore, Restfully can work with any reasonably RESTful API provided that:
10
+
11
+ * The API returns semantically correct HTTP status codes;
12
+ * The API make use of `GET`, `POST`, `PUT`, `DELETE` HTTP methods;
13
+ * The API returns a valid `Content-Type` header in all responses;
14
+ * The API returns a `Location` HTTP header on 201 and 202 responses;
15
+ * The API returns links to other resources in all responses (the so-called HATEOAS constraint of REST).
16
+
17
+ If one of the API `Content-Type` is not already supported by one of the `Restfully::MediaType` objects (see `lib/restfully/media_type`), then you just have to build it and register it with Restfully.
26
18
 
27
19
  ## Installation
28
20
 
29
21
  $ gem install restfully
30
22
 
23
+ If you require media-types that need an XML parser, you must also install the `libxml-ruby` library:
24
+
25
+ $ gem install libxml-ruby
26
+
31
27
  ## Usage
32
28
 
33
29
  ### Command line
34
30
 
35
31
  $ export RUBYOPT="-rubygems"
36
- $ restfully base_uri [-u username] [-p password]
32
+ $ restfully URI [-u username] [-p password]
37
33
 
38
- e.g., for the Grid5000 API:
34
+ e.g., for the [Grid'5000 API](https://www.grid5000.fr/mediawiki/index.php/API):
39
35
 
40
36
  $ restfully https://api.grid5000.fr/sid/grid5000 -u username -p password
41
37
 
42
38
  If the connection was successful, you should get a prompt. You may enter:
43
39
 
44
- irb(main):001:0> pp root
45
-
46
- to get back a pretty-printed output of the root resource:
47
-
48
- #<Restfully::Resource:0x91f08c
49
- @uri=#<URI::HTTP:0x123e30c URL:http://api.local/sid/grid5000>
50
- LINKS
51
- @environments=#<Restfully::Collection:0x917666>,
52
- @sites=#<Restfully::Collection:0x9170d0>,
53
- @version=#<Restfully::Resource:0x91852a>,
54
- @versions=#<Restfully::Collection:0x917e68>
40
+ ruby-1.8.7-p249 > pp root
41
+ #<Resource:0x8108399c uri=https://api.grid5000.fr/sid/grid5000
42
+ RELATIONSHIPS
43
+ environments, self, sites, version, versions
55
44
  PROPERTIES
56
- "uid"=>"grid5000",
57
- "type"=>"grid",
58
- "version"=>"4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8">
45
+ "uid"=>"grid5000"
46
+ "type"=>"grid"
47
+ "version"=>"da6abdd13e2e626f64502a648b784372eac790b1">
48
+ => nil
59
49
 
60
- You can see the `LINKS` and `PROPERTIES` headers that respectively indicate what links you can follow from there (by calling `root.link_name`) and what properties are available (by calling `root[property_name]`).
50
+ And then follow the links advertised under the `RELATIONSHIPS` header to discover the other API resources. For instance, the `sites` resource can be accessed as follows:
61
51
 
62
- Let's say you want to access the collection of `sites`, you would enter:
63
-
64
- irb(main):002:0> pp root.sites
65
-
66
- and get back:
67
-
68
- #<Restfully::Collection:0x9170d0
69
- @uri=#<URI::HTTP:0x122e128 URL:http://api.local/sid/grid5000/sites>
70
- LINKS
71
- @version=#<Restfully::Resource:0x8f553e>,
72
- @versions=#<Restfully::Collection:0x8f52be>
73
- PROPERTIES
74
- "total"=>9,
75
- "version"=>"4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
76
- "offset"=>0
52
+ ruby-1.8.7-p249 > pp root.sites
53
+ #<Collection:0x8106d55c uri=https://api.grid5000.fr/sid/grid5000/sites
54
+ RELATIONSHIPS
55
+ self, version, versions
77
56
  ITEMS (0..9)/9
78
- #<Restfully::Resource:0x9058bc uid="bordeaux">,
79
- #<Restfully::Resource:0x903d0a uid="grenoble">,
80
- #<Restfully::Resource:0x901cc6 uid="lille">,
81
- #<Restfully::Resource:0x8fff0c uid="lyon">,
82
- #<Restfully::Resource:0x8fe288 uid="nancy">,
83
- #<Restfully::Resource:0x8fc4a6 uid="orsay">,
84
- #<Restfully::Resource:0x8fa782 uid="rennes">,
85
- #<Restfully::Resource:0x8f8bb2 uid="sophia">,
86
- #<Restfully::Resource:0x8f6c9a uid="toulouse">>
87
-
88
- A Restfully::Collection is a special kind of Resource, which includes the Enumerable module, which means you can call all of its methods on the `Restfully::Collection` object.
89
- For example:
90
-
91
- irb(main):003:0> pp root.sites.find{|s| s['uid'] == 'rennes'}
92
- #<Restfully::Resource:0x8fa782
93
- @uri=#<URI::HTTP:0x11f4e64 URL:http://api.local/sid/grid5000/sites/rennes>
94
- LINKS
95
- @environments=#<Restfully::Collection:0x8f9ab2>,
96
- @parent=#<Restfully::Resource:0x8f981e>,
97
- @deployments=#<Restfully::Collection:0x8f935a>,
98
- @clusters=#<Restfully::Collection:0x8f9d46>,
99
- @version=#<Restfully::Resource:0x8fa354>,
100
- @versions=#<Restfully::Collection:0x8fa0b6>,
101
- @status=#<Restfully::Collection:0x8f95ee>
102
- PROPERTIES
103
- "name"=>"Rennes",
104
- "latitude"=>48.1,
105
- "location"=>"Rennes, France",
106
- "security_contact"=>"rennes-staff@lists.grid5000.fr",
107
- "uid"=>"rennes",
108
- "type"=>"site",
109
- "user_support_contact"=>"rennes-staff@lists.grid5000.fr",
110
- "version"=>"4fe96b25d2cbfee16abe5a4fb999c82dbafc2ee8",
111
- "description"=>"",
112
- "longitude"=>-1.6667,
113
- "compilation_server"=>false,
114
- "email_contact"=>"rennes-staff@lists.grid5000.fr",
115
- "web"=>"http://www.irisa.fr",
116
- "sys_admin_contact"=>"rennes-staff@lists.grid5000.fr">
57
+ #<Resource:0x81055a9c uri=https://api.grid5000.fr/sid/grid5000/sites/bordeaux>
58
+ #<Resource:0x81040d54 uri=https://api.grid5000.fr/sid/grid5000/sites/grenoble>
59
+ #<Resource:0x8102c070 uri=https://api.grid5000.fr/sid/grid5000/sites/lille>
60
+ #<Resource:0x8101738c uri=https://api.grid5000.fr/sid/grid5000/sites/lyon>
61
+ #<Resource:0x81002658 uri=https://api.grid5000.fr/sid/grid5000/sites/nancy>
62
+ #<Resource:0x80fed924 uri=https://api.grid5000.fr/sid/grid5000/sites/orsay>
63
+ #<Resource:0x80fd8bb4 uri=https://api.grid5000.fr/sid/grid5000/sites/rennes>
64
+ #<Resource:0x80fc3dcc uri=https://api.grid5000.fr/sid/grid5000/sites/sophia>
65
+ #<Resource:0x80faf070 uri=https://api.grid5000.fr/sid/grid5000/sites/toulouse>>
66
+ => nil
117
67
 
118
- or:
68
+ Note that we're using `pp` to pretty-print the output, but it's not required.
119
69
 
120
- irb(main):006:0> root.sites.map{|s| s['uid']}.grep(/re/)
121
- => ["grenoble", "rennes"]
70
+ A Collection is a specific kind of Resource, and it has access to all the methods provided by the Ruby [Enumerable](http://www.rubydoc.info/stdlib/core/1.9.2/Enumerable) module.
122
71
 
123
- A shortcut is available to find a specific entry in a collection, by entering the searched `uid` as a Symbol:
124
-
125
- irb(main):007:0> root.sites[:rennes]
126
- # will find the item whose uid is "rennes"
127
-
128
- For ease of use and better security, you may prefer to use a configuration file to avoid re-entering the options every time you use the client:
72
+ For ease of use and better security, you may prefer to use a configuration file to avoid re-entering the Restfully options every time:
129
73
 
130
74
  $ echo '
131
- base_uri: https://api.grid5000.fr/sid/grid5000
75
+ uri: https://api.grid5000.fr/sid/grid5000
132
76
  username: MYLOGIN
133
77
  password: MYPASSWORD
134
78
  ' > ~/.restfully/api.grid5000.fr.yml && chmod 600 ~/.restfully/api.grid5000.fr.yml
@@ -140,12 +84,6 @@ And then:
140
84
  ### As a library
141
85
  See the `examples` directory for examples.
142
86
 
143
- ## Discovering the API capabilities
144
- A `Restfully::Resource` (and by extension its child `Restfully::Collection`) has the following methods available for introspection:
145
-
146
- * `links` will return a hash whose keys are the name of the methods that can be called to navigate between resources;
147
- * `http_methods` will return an array containing the list of the HTTP methods that are allowed on the resource;
148
-
149
87
  ## Development
150
88
 
151
89
  ### Testing
@@ -163,4 +101,5 @@ A `Restfully::Resource` (and by extension its child `Restfully::Collection`) has
163
101
 
164
102
  ## Copyright
165
103
 
166
- Copyright (c) 2009 Cyril Rohr, INRIA Rennes - Bretagne Atlantique. See LICENSE for details.
104
+ Copyright (c) 2009-2011 [Cyril Rohr](http://crohr.me), INRIA Rennes - Bretagne Atlantique.
105
+ See LICENSE for details.
@@ -2,9 +2,9 @@ module Restfully
2
2
  # This class represents a Resource, which can be accessed and manipulated
3
3
  # via HTTP methods.
4
4
  #
5
- # The <tt>#load</tt> method must have been called on the resource before
6
- # trying to access its attributes or links.
7
- #
5
+ # Some resources can be collection of other resources.
6
+ # In that case the <tt>Restfully::Collection</tt> module is included in the <tt>Restfully::Resource</tt> class.
7
+ # See the corresponding documentation for the list of additional methods that you can use on a collection resource.
8
8
  class Resource
9
9
  attr_reader :response, :request, :session
10
10
 
@@ -17,11 +17,10 @@ module Restfully
17
17
  @associations = {}
18
18
  end
19
19
 
20
- # == Description
21
20
  # Returns the value corresponding to the specified key,
22
- # among the list of resource properties
21
+ # among the list of resource properties.
23
22
  #
24
- # == Usage
23
+ # e.g.:
25
24
  # resource["uid"]
26
25
  # => "rennes"
27
26
  def [](key)
@@ -31,26 +30,32 @@ module Restfully
31
30
  media_type.property(key)
32
31
  end
33
32
 
33
+ # Returns the resource URI.
34
34
  def uri
35
35
  request.uri
36
36
  end
37
37
 
38
+ # Returns the Restfully::MediaType object that was used to parse the response.
38
39
  def media_type
39
40
  response.media_type
40
41
  end
41
-
42
+
43
+ # Does this resource contain only a fragment of the full resource?
42
44
  def complete?
43
45
  media_type.complete?
44
46
  end
45
47
 
48
+ # Is this resource a collection of items?
46
49
  def collection?
47
50
  media_type.collection?
48
51
  end
49
-
52
+
53
+ # Returns the resource kind: "Collection" or "Resource".
50
54
  def kind
51
55
  collection? ? "Collection" : "Resource"
52
56
  end
53
-
57
+
58
+ # Returns the "signature" of the resource. Used for (pretty-)inspection.
54
59
  def signature(closed=true)
55
60
  s = "#<#{kind}:0x#{object_id.to_s(16)}"
56
61
  s += " uri=#{uri.to_s}"
@@ -58,6 +63,9 @@ module Restfully
58
63
  s
59
64
  end
60
65
 
66
+ # Load the resource. The <tt>options</tt> Hash can contain any number of parameters among which:
67
+ # <tt>:head</tt>:: a Hash of HTTP headers to pass when fetching the resource.
68
+ # <tt>:query</tt>:: a Hash of query parameters to add to the URI when fetching the resource.
61
69
  def load(options = {})
62
70
  # Send a GET request only if given a different set of options
63
71
  if @request.update!(options) || @request.no_cache?
@@ -72,28 +80,29 @@ module Restfully
72
80
 
73
81
  build
74
82
  end
75
-
83
+
84
+ # Returns the list of relationships for this resource, extracted from the resource links ("rel" attribute).
76
85
  def relationships
77
86
  response.links.map(&:id).sort
78
87
  end
79
-
88
+
89
+ # Returns the Hash of properties for this resource.
80
90
  def properties
81
91
  media_type.property.reject{|k,v|
82
92
  # do not return keys used for internal use
83
93
  k.to_s =~ HIDDEN_PROPERTIES_REGEXP
84
94
  }
85
95
  end
86
-
87
- # For the following methods, maybe it's better to always go through the
88
- # cache instead of explicitly saying @request.no_cache! (and update the
89
- # #load method accordingly)
90
-
91
- # Force reloading of the request
96
+
97
+ # Force reloading of the resource.
92
98
  def reload
93
99
  @request.no_cache!
94
100
  load
95
101
  end
96
102
 
103
+ # POST some payload on that resource URI.
104
+ # Either you pass a serialized payload as first argument, followed by an optional Hash of <tt>:head</tt> and <tt>:query</tt> parameters.
105
+ # Or you pass your payload as a Hash, and the serialization will occur based on the Content-Type you set (and only if a corresponding MediaType can be found in the MediaType catalog).
97
106
  def submit(*args)
98
107
  if allow?("POST")
99
108
  @request.no_cache!
@@ -104,6 +113,8 @@ module Restfully
104
113
  end
105
114
  end
106
115
 
116
+ # Send a DELETE HTTP request on the resource URI.
117
+ # See <tt>#load</tt> for the list of arguments this method can take.
107
118
  def delete(options = {})
108
119
  if allow?("DELETE")
109
120
  @request.no_cache!
@@ -113,6 +124,8 @@ module Restfully
113
124
  end
114
125
  end
115
126
 
127
+ # Send a PUT HTTP request with some payload on the resource URI.
128
+ # See <tt>#submit</tt> for the list of arguments this method can take.
116
129
  def update(*args)
117
130
  if allow?("PUT")
118
131
  @request.no_cache!
@@ -123,6 +136,7 @@ module Restfully
123
136
  end
124
137
  end
125
138
 
139
+ # Returns true if the resource supports the given HTTP <tt>method</tt> (String or Symbol).
126
140
  def allow?(method)
127
141
  response.allow?(method) || reload.response.allow?(method)
128
142
  end
@@ -173,8 +187,7 @@ module Restfully
173
187
  nil
174
188
  end
175
189
 
176
-
177
-
190
+ # Build the resource after loading.
178
191
  def build
179
192
  metaclass = class << self; self; end
180
193
  # only build once
@@ -192,7 +205,8 @@ module Restfully
192
205
  # end
193
206
  self
194
207
  end
195
-
208
+
209
+ # Reload itself if the resource is not <tt>#complete?</tt>.
196
210
  def expand
197
211
  reload unless complete?
198
212
  self
@@ -13,9 +13,34 @@ module Restfully
13
13
  attr_reader :config
14
14
  attr_writer :default_headers
15
15
 
16
+ # Builds a new client session.
17
+ # Takes a number of <tt>options</tt> as input.
18
+ # Yields or return the <tt>root</tt> Restfully::Resource object, and the Restfully::Session object.
19
+ #
20
+ # <tt>:configuration_file</tt>:: the location of a YAML configuration file that contains any of the parameters below.
21
+ # <tt>:uri</tt>:: the entry-point URI for this session.
22
+ # <tt>:logger</tt>:: a Logger object, used to display information.
23
+ # <tt>:require</tt>:: an Array of Restfully::MediaType objects to automatically require for this session.
24
+ # <tt>:retry_on_error</tt>:: the maximum number of attempts to make when a server (502,502,504) or connection error occurs.
25
+ # <tt>:wait_before_retry</tt>:: the number of seconds to wait before making another attempt when a server or connection error occurs.
26
+ # <tt>:default_headers</tt>:: a Hash of default HTTP headers to send with each request.
27
+ # <tt>:cache</tt>:: a Hash of parameters to configure the caching component. See <http://rtomayko.github.com/rack-cache/configuration> for more information.
28
+ #
29
+ # e.g.
30
+ # Restfully::Session.new(
31
+ # :uri => "https://api.bonfire-project.eu:444/",
32
+ # :username => "crohr",
33
+ # :password => "PASSWORD",
34
+ # :require => ['ApplicationVndBonfireXml']
35
+ # ) {|root, session| p root}
36
+ #
16
37
  def initialize(options = {})
17
38
  @config = options.symbolize_keys
18
- @logger = @config.delete(:logger) || Logger.new(STDERR)
39
+ @logger = @config.delete(:logger)
40
+ if @logger.nil?
41
+ @logger = Logger.new(STDERR)
42
+ @logger.level = Logger::INFO
43
+ end
19
44
 
20
45
  # Read configuration from file:
21
46
  config_file = @config.delete(:configuration_file) || ENV['RESTFULLY_CONFIG']
@@ -46,25 +71,30 @@ module Restfully
46
71
 
47
72
  disable RestClient::Rack::Compatibility
48
73
  authenticate(@config)
49
- setup_cache
74
+ setup_cache((@config.delete(:cache) || {}).symbolize_keys)
50
75
 
51
76
  yield root, self if block_given?
52
77
  end
53
78
 
79
+ # Enable a RestClient Rack component.
54
80
  def enable(rack, *args)
55
81
  logger.info "Enabling #{rack.inspect}."
56
82
  RestClient.enable rack, *args
57
83
  end
58
84
 
85
+ # Disable a RestClient Rack component.
59
86
  def disable(rack, *args)
60
87
  logger.info "Disabling #{rack.inspect}."
61
88
  RestClient.disable rack, *args
62
89
  end
63
90
 
91
+ # Returns the list of middleware components enabled.
92
+ # See rest-client-components for more information.
64
93
  def middleware
65
94
  RestClient.components.map{|(rack, args)| rack}
66
95
  end
67
96
 
97
+ # Authnenticates the request using Basic Authentication.
68
98
  def authenticate(options = {})
69
99
  if options[:username]
70
100
  enable(
@@ -80,6 +110,7 @@ module Restfully
80
110
  Addressable::URI.join(uri.to_s, path.to_s)
81
111
  end
82
112
 
113
+ # Return the Hash of default HTTP headers that are sent with each request.
83
114
  def default_headers
84
115
  @default_headers ||= {
85
116
  'Accept' => '*/*',
@@ -87,6 +118,7 @@ module Restfully
87
118
  }
88
119
  end
89
120
 
121
+ # Returns the root Restfully::Resource.
90
122
  def root
91
123
  get(uri.path).load
92
124
  end
@@ -153,8 +185,9 @@ module Restfully
153
185
  end
154
186
 
155
187
  protected
156
- def setup_cache
157
- enable ::Rack::Cache, :verbose => (logger.level <= Logger::INFO)
188
+ def setup_cache(options = {})
189
+ opts = {:verbose => (logger.level <= Logger::INFO)}.merge(options)
190
+ enable ::Rack::Cache, opts
158
191
  end
159
192
 
160
193
  def error_message(request, response)
@@ -1,3 +1,3 @@
1
1
  module Restfully
2
- VERSION = "0.7.1.rc5"
2
+ VERSION = "0.7.1.rc6"
3
3
  end
@@ -11,17 +11,47 @@ describe Restfully::Session do
11
11
  }
12
12
  end
13
13
 
14
- it "should initialize a session with the correct properties" do
15
- session = Restfully::Session.new(@config.merge("key" => "value"))
16
- session.logger.should == @logger
17
- session.uri.should == Addressable::URI.parse(@uri)
18
- session.config.should == {:wait_before_retry=>5, :key=>"value", :retry_on_error=>5}
19
- end
14
+ describe "intialization" do
15
+ it "should initialize a session with the correct properties" do
16
+ session = Restfully::Session.new(@config.merge("key" => "value"))
17
+ session.logger.should == @logger
18
+ session.uri.should == Addressable::URI.parse(@uri)
19
+ session.config.should == {:wait_before_retry=>5, :key=>"value", :retry_on_error=>5}
20
+ end
20
21
 
21
- it "should raise an error if no URI given" do
22
- lambda{
23
- Restfully::Session.new(@config.merge(:uri => ""))
24
- }.should raise_error(ArgumentError)
22
+ it "should raise an error if no URI given" do
23
+ lambda{
24
+ Restfully::Session.new(@config.merge(:uri => ""))
25
+ }.should raise_error(ArgumentError)
26
+ end
27
+
28
+ it "should add or replace additional headers to the default set" do
29
+ session = Restfully::Session.new(
30
+ @config.merge(:default_headers => {
31
+ 'Accept' => 'application/xml',
32
+ 'Cache-Control' => 'no-cache'
33
+ })
34
+ )
35
+ session.default_headers.should == {
36
+ 'Accept' => 'application/xml',
37
+ 'Cache-Control' => 'no-cache',
38
+ 'Accept-Encoding' => 'gzip, deflate'
39
+ }
40
+ end
41
+
42
+ it "should pass configuration options to Rack::Cache" do
43
+ session = Restfully::Session.new(@config.merge({
44
+ :cache => {
45
+ :metastore => 'file:/var/cache/rack/meta',
46
+ :entitystore => 'file:/var/cache/rack/body'
47
+ }
48
+ }))
49
+ RestClient.components.should == [[Rack::Cache, [{
50
+ :verbose => true,
51
+ :metastore => 'file:/var/cache/rack/meta',
52
+ :entitystore => 'file:/var/cache/rack/body'
53
+ }]]]
54
+ end
25
55
  end
26
56
 
27
57
  it "should fetch the root path [no URI path]" do
@@ -42,20 +72,6 @@ describe Restfully::Session do
42
72
  session.root.should == res
43
73
  end
44
74
 
45
- it "should add or replace additional headers to the default set" do
46
- session = Restfully::Session.new(
47
- @config.merge(:default_headers => {
48
- 'Accept' => 'application/xml',
49
- 'Cache-Control' => 'no-cache'
50
- })
51
- )
52
- session.default_headers.should == {
53
- 'Accept' => 'application/xml',
54
- 'Cache-Control' => 'no-cache',
55
- 'Accept-Encoding' => 'gzip, deflate'
56
- }
57
- end
58
-
59
75
  describe "middleware" do
60
76
  it "should only have Rack::Cache enabled by default" do
61
77
  session = Restfully::Session.new(@config)
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: restfully
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15424103
4
+ hash: 15424097
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 0
8
8
  - 7
9
9
  - 1
10
10
  - rc
11
- - 5
12
- version: 0.7.1.rc5
11
+ - 6
12
+ version: 0.7.1.rc6
13
13
  platform: ruby
14
14
  authors:
15
15
  - Cyril Rohr
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2011-05-16 00:00:00 +02:00
20
+ date: 2011-05-17 00:00:00 +02:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency