restfully 0.7.1.rc5 → 0.7.1.rc6

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.
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