restfully 0.3.2 → 0.4.0

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.
@@ -10,7 +10,7 @@ module Restfully
10
10
  end
11
11
  class Session
12
12
  include Parsing, HTTP::Headers
13
- attr_reader :base_uri, :root_path, :logger, :connection, :root, :default_headers
13
+ attr_reader :base_uri, :logger, :connection, :root, :default_headers
14
14
 
15
15
  # TODO: use CacheableResource
16
16
  def initialize(options = {})
@@ -18,38 +18,52 @@ module Restfully
18
18
  if (config_filename = options.delete(:configuration_file)) && File.exists?(File.expand_path(config_filename))
19
19
  config = YAML.load_file(File.expand_path(config_filename)).symbolize_keys
20
20
  options.merge!(config)
21
- end
22
- @base_uri = options.delete(:base_uri) || "http://localhost:8888"
23
- @root_path = options.delete(:root_path) || "/"
21
+ end
22
+ @base_uri = URI.parse(options.delete(:base_uri) || "http://localhost:8888") rescue nil
23
+ raise ArgumentError.new("#{@base_uri} is not a valid URI") if @base_uri.nil? || @base_uri.scheme !~ /^http/i
24
24
  @logger = options.delete(:logger) || NullLogger.new
25
+ @logger.level = options.delete(:verbose) ? Logger::DEBUG : @logger.level
25
26
  user_default_headers = sanitize_http_headers(options.delete(:default_headers) || {})
26
27
  @default_headers = {'User-Agent' => "Restfully/#{Restfully::VERSION}", 'Accept' => 'application/json'}.merge(user_default_headers)
27
- @connection = Restfully.adapter.new(@base_uri, options.merge(:logger => @logger))
28
- @root = Resource.new(URI.parse(@root_path), self)
28
+ @connection = Restfully.adapter.new(base_uri.to_s, options.merge(:logger => logger))
29
+ @root = Resource.new(@base_uri, self)
29
30
  yield @root.load, self if block_given?
30
31
  end
31
32
 
32
- # TODO: inspect response headers to determine which methods are available
33
+ # returns an HTTP::Response object or raise a Restfully::HTTP::Error
34
+ def head(path, options = {})
35
+ options = options.symbolize_keys
36
+ transmit :head, HTTP::Request.new(uri_for(path), :headers => options.delete(:headers), :query => options.delete(:query))
37
+ end
38
+
39
+ # returns an HTTP::Response object or raise a Restfully::HTTP::Error
33
40
  def get(path, options = {})
34
- path = path.to_s
35
41
  options = options.symbolize_keys
36
- uri = URI.parse(base_uri)
37
- path_uri = URI.parse(path)
38
- # if the given path is complete URL, forget the base_uri, else append the path to the base_uri
39
- unless path_uri.scheme.nil?
40
- uri = path_uri
41
- else
42
- uri.path << path
43
- end
44
- request = HTTP::Request.new(uri, :headers => options.delete(:headers) || {}, :query => options.delete(:query) || {})
45
- request.add_headers(@default_headers) unless @default_headers.empty?
46
- logger.info "GET #{request.uri}, #{request.headers.inspect}"
47
- response = connection.get(request)
48
- logger.debug "Response to GET #{request.uri}: #{response.headers.inspect}"
49
- response = deal_with_eventual_errors(response, request)
42
+ transmit :get, HTTP::Request.new(uri_for(path), :headers => options.delete(:headers), :query => options.delete(:query))
43
+ end
44
+
45
+ # returns an HTTP::Response object or raise a Restfully::HTTP::Error
46
+ def post(path, body, options = {})
47
+ options = options.symbolize_keys
48
+ uri = uri_for(path)
49
+ transmit :post, HTTP::Request.new(uri_for(path), :body => body, :headers => options.delete(:headers), :query => options.delete(:query))
50
+ end
51
+
52
+ # builds the complete URI, based on the given path and the session's base_uri
53
+ def uri_for(path)
54
+ URI.join(base_uri.to_s, path.to_s)
50
55
  end
51
56
 
52
57
  protected
58
+ def transmit(method, request)
59
+ request.add_headers(default_headers) unless default_headers.empty?
60
+ logger.info "#{method.to_s.upcase} #{request.uri}" +
61
+ "\nHeaders: #{request.headers.inspect}" +
62
+ "#{request.body ? "\nBody: #{request.body.length} bytes" : ""}"
63
+ response = connection.send(method.to_sym, request)
64
+ response = deal_with_eventual_errors(response, request)
65
+ end
66
+
53
67
  def deal_with_eventual_errors(response, request)
54
68
  case response.status
55
69
  when 400..499
data/restfully.gemspec CHANGED
@@ -1,15 +1,15 @@
1
1
  # Generated by jeweler
2
- # DO NOT EDIT THIS FILE
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{restfully}
8
- s.version = "0.3.2"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Cyril Rohr"]
12
- s.date = %q{2009-11-02}
12
+ s.date = %q{2009-11-16}
13
13
  s.default_executable = %q{restfully}
14
14
  s.description = %q{Experimental code for auto-generation of wrappers on top of RESTful APIs that follow HATEOAS principles and provide OPTIONS methods and/or Allow headers.}
15
15
  s.email = %q{cyril.rohr@gmail.com}
@@ -21,6 +21,7 @@ Gem::Specification.new do |s|
21
21
  s.files = [
22
22
  ".document",
23
23
  ".gitignore",
24
+ "CHANGELOG",
24
25
  "LICENSE",
25
26
  "README.rdoc",
26
27
  "Rakefile",
@@ -89,10 +90,14 @@ Gem::Specification.new do |s|
89
90
 
90
91
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
91
92
  s.add_runtime_dependency(%q<rest-client>, [">= 1.0"])
93
+ s.add_runtime_dependency(%q<backports>, [">= 0"])
92
94
  else
93
95
  s.add_dependency(%q<rest-client>, [">= 1.0"])
96
+ s.add_dependency(%q<backports>, [">= 0"])
94
97
  end
95
98
  else
96
99
  s.add_dependency(%q<rest-client>, [">= 1.0"])
100
+ s.add_dependency(%q<backports>, [">= 0"])
97
101
  end
98
102
  end
103
+
@@ -4,53 +4,54 @@ include Restfully
4
4
  describe Collection do
5
5
  describe "general behaviour" do
6
6
  before do
7
- @collection = Collection.new("uri", session=mock('session')).load(:raw => JSON.parse(fixture("grid5000-sites.json")))
7
+ @uri = URI.parse('http://api.local/x/y/z')
8
+ @collection = Collection.new(@uri, session=mock('session')).load(:body => JSON.parse(fixture("grid5000-sites.json")))
8
9
  end
9
10
  it "should be enumerable" do
10
11
  @collection.length.should == 9
12
+ @collection.size.should == 9
11
13
  @collection.map{|site| site["uid"]}.sort.should == ["bordeaux", "grenoble", "lille", "lyon", "nancy", "orsay", "rennes", "sophia", "toulouse"]
12
14
  end
13
15
 
14
- it "should have a :total method" do
15
- @collection.total.should == 9
16
+ it "should have a :total attribute" do
17
+ @collection["total"].should == 9
16
18
  end
17
19
 
18
- it "should have a :offset method" do
19
- @collection.offset.should == 0
20
+ it "should have a :offset attribute" do
21
+ @collection["offset"].should == 0
20
22
  end
21
23
  end
22
24
 
23
25
  describe "loading" do
24
26
  before(:all) do
27
+ @uri = URI.parse('http://api.local/x/y/z')
25
28
  @raw = fixture("grid5000-sites.json")
26
29
  @response_200 = Restfully::HTTP::Response.new(200, {'Content-Type' => 'application/json;charset=utf-8', 'Content-Length' => @raw.length}, @raw)
27
30
  @logger = Logger.new(STDOUT)
28
31
  end
29
32
  it "should not load if already loaded and no :reload" do
30
- collection = Collection.new("uri", mock("session"))
31
- collection.should_receive(:loaded?).and_return(true)
32
- collection.instance_variable_set(:@last_request_hash, [:get, {}].hash)
33
- collection.load(:reload => false).should == collection
33
+ collection = Collection.new(@uri, mock("session"))
34
+ options = {:headers => {'key' => 'value'}}
35
+ collection.should_receive(:executed_requests).and_return({'GET' => {'options' => options, 'body' => {"key", "value"}}})
36
+ collection.load(options.merge(:reload => false)).should == collection
34
37
  end
35
38
  it "should load when :reload param is true [already loaded]" do
36
- collection = Collection.new("uri", session=mock("session", :logger => Logger.new(STDOUT)))
37
- collection.should_receive(:loaded?).and_return(true)
39
+ collection = Collection.new(@uri, session=mock("session", :logger => Logger.new(STDOUT)))
38
40
  session.should_receive(:get).and_return(@response_200)
39
41
  collection.load(:reload => true).should == collection
40
42
  end
41
43
  it "should load when force_reload is true [not loaded]" do
42
- collection = Collection.new("uri", session=mock("session", :logger => Logger.new(STDOUT)))
43
- collection.should_receive(:loaded?).and_return(false)
44
+ collection = Collection.new(@uri, session=mock("session", :logger => Logger.new(STDOUT)))
44
45
  session.should_receive(:get).and_return(@response_200)
45
46
  collection.load(:reload => true).should == collection
46
47
  end
47
48
  it "should force reload when query parameters are given" do
48
- collection = Collection.new("uri", session=mock("session", :logger => Logger.new(STDOUT)))
49
+ collection = Collection.new(@uri, session=mock("session", :logger => Logger.new(STDOUT)))
49
50
  session.should_receive(:get).and_return(@response_200)
50
51
  collection.load(:query => {:q1 => 'v1'}).should == collection
51
52
  end
52
53
  it "should not initialize resources lacking a self link" do
53
- collection = Collection.new("uri", session = mock("session", :get => mock("restfully response", :body => {
54
+ collection = Collection.new(@uri, session = mock("session", :get => mock("restfully response", :body => {
54
55
  "total" => 1,
55
56
  "offset" => 0,
56
57
  "items" => [
@@ -64,10 +65,10 @@ describe Collection do
64
65
  }), :logger => @logger))
65
66
  Resource.should_not_receive(:new)
66
67
  collection.load
67
- collection.by_uid('rennes').should be_nil
68
+ collection.find{|i| i['uid'] == 'rennes'}.should be_nil
68
69
  end
69
70
  it "should initialize resources having a self link" do
70
- collection = Collection.new("uri", session = mock("session", :get => mock("restfully response", :body => {
71
+ collection = Collection.new(@uri, session = mock("session", :get => mock("restfully response", :body => {
71
72
  "total" => 1,
72
73
  "offset" => 0,
73
74
  "items" => [
@@ -82,17 +83,15 @@ describe Collection do
82
83
  }), :logger => @logger))
83
84
  collection.load
84
85
  collection.length.should == 1
85
- collection.by_uid('rennes').class.should == Restfully::Resource
86
+ collection.find{|i| i['uid'] == 'rennes'}.class.should == Restfully::Resource
86
87
  end
87
88
  it "should correctly initialize its resources [integration test]" do
88
- collection = Collection.new("uri", session=mock("session", :logger => Logger.new(STDOUT), :get => @response_200))
89
+ collection = Collection.new(@uri, session=mock("session", :logger => Logger.new(STDOUT), :get => @response_200))
89
90
  collection.load
90
- collection.should be_loaded
91
- collection.uri.should == "uri"
92
- collection.by_uid('rennes')["uid"].should == 'rennes'
93
- collection.by_uid('rennes')["type"].should == 'site'
94
- collection.by_uid.keys.should =~ ['rennes', 'lille', 'bordeaux', 'nancy', 'sophia', 'toulouse', 'lyon', 'grenoble', 'orsay']
95
- collection.by_uid('rennes', 'bordeaux').length.should == 2
91
+ collection.uri.should == @uri
92
+ collection.find{|i| i['uid'] == 'rennes'}["uid"].should == 'rennes'
93
+ collection.find{|i| i['uid'] == 'rennes'}["type"].should == 'site'
94
+ collection.map{|s| s['uid']}.should =~ ['rennes', 'lille', 'bordeaux', 'nancy', 'sophia', 'toulouse', 'lyon', 'grenoble', 'orsay']
96
95
  end
97
96
  end
98
97
 
@@ -4,16 +4,20 @@ describe Restfully::HTTP::Request do
4
4
  it "should correctly initialize the attributes" do
5
5
  request = Restfully::HTTP::Request.new(
6
6
  'https://api.grid5000.fr/sid/grid5000?q1=v1&q2=v2',
7
- :headers => {'accept' => 'application/json', :cache_control => 'max-age=0'},
8
- :query => {'custom_param1' => [3, 4, 5, 6], 'custom_param2' => 'value_custom_param2'}
7
+ :headers => {'accept' => 'application/json', :cache_control => 'max-age=0', 'Content-Type' => 'application/json'},
8
+ :query => {'custom_param1' => [3, 4, 5, 6], 'custom_param2' => 'value_custom_param2'},
9
+ :body => {"key" => "value"}.to_json
9
10
  )
10
11
  request.uri.should be_a URI
11
12
  request.uri.to_s.should == 'https://api.grid5000.fr/sid/grid5000?q1=v1&q2=v2&custom_param1=3,4,5,6&custom_param2=value_custom_param2'
12
13
  request.uri.query.should == "q1=v1&q2=v2&custom_param1=3,4,5,6&custom_param2=value_custom_param2"
13
14
  request.headers.should == {
15
+ "Content-Type"=>"application/json",
14
16
  'Accept' => 'application/json',
15
17
  'Cache-Control' => 'max-age=0'
16
18
  }
19
+ request.body.should == {"key" => "value"}
20
+ request.raw_body.should == "{\"key\":\"value\"}"
17
21
  request.retries.should == 0
18
22
  end
19
23
 
@@ -12,4 +12,8 @@ describe Restfully::HTTP::Response do
12
12
  'property2' => 'value2'
13
13
  }
14
14
  end
15
+ it "should return the unserialized body" do
16
+ response = Restfully::HTTP::Response.new(404, {:content_type => 'application/json;charset=utf-8'}, '{"property1": "value1", "property2": "value2"}')
17
+ response.raw_body.should == "{\"property1\": \"value1\", \"property2\": \"value2\"}"
18
+ end
15
19
  end
@@ -19,7 +19,7 @@ describe Restfully::HTTP::Adapters::RestClientAdapter do
19
19
  end
20
20
  it "should raise a not implemented error when trying to use functions not implemented yet" do
21
21
  adapter = Restfully::HTTP::Adapters::RestClientAdapter.new("https://api.grid5000.fr")
22
- lambda{adapter.post(mock("restfully request"))}.should raise_error NotImplementedError, "POST is not supported by your adapter."
22
+ lambda{adapter.delete(mock("restfully request"))}.should raise_error NotImplementedError, "DELETE is not supported by your adapter."
23
23
  end
24
24
  it "should rescue any RestClient::Exception and correctly populate the response" do
25
25
  res = mock(Net::HTTPResponse, :code => 404, :body => '{"message":"whatever"}', :to_hash => {'Content-Type' => 'application/json;charset=utf-8', 'Content-Length' => 22}, :[] => '')
@@ -28,6 +28,7 @@ describe Restfully::HTTP::Adapters::RestClientAdapter do
28
28
  response = adapter.get(mock("request", :uri => "uri"))
29
29
  response.status.should == 404
30
30
  response.headers.should == {'Content-Type' => 'application/json;charset=utf-8', 'Content-Length' => 22}
31
- response.body.should == {'message' => 'whatever'}
31
+ response.raw_body.should == '{"message":"whatever"}'
32
+ response.body.should == {"message"=>"whatever"}
32
33
  end
33
34
  end
data/spec/link_spec.rb CHANGED
@@ -2,7 +2,9 @@ require File.expand_path(File.dirname(__FILE__)+'/spec_helper')
2
2
 
3
3
  include Restfully
4
4
  describe Link do
5
-
5
+ before do
6
+ @uri = URI.parse('/x/y/z')
7
+ end
6
8
  it "should have a rel reader" do
7
9
  link = Link.new
8
10
  link.should_not respond_to(:rel=)
@@ -28,7 +30,7 @@ describe Link do
28
30
  link.should respond_to(:valid?)
29
31
  end
30
32
  it "should respond to resolved?" do
31
- link = Link.new
33
+ link = Link.new("href" => @uri)
32
34
  link.should respond_to(:resolved?)
33
35
  end
34
36
  it "should respond to resolvable?" do
@@ -43,9 +45,10 @@ describe Link do
43
45
  link = Link.new
44
46
  link.should_not be_resolved
45
47
  end
46
- it "should not be valid if there is no href" do
48
+ it "should be valid even if the href is ''" do
47
49
  link = Link.new 'rel' => 'collection', 'title' => 'my collection'
48
- link.should_not be_valid
50
+ link.should be_valid
51
+ link.href.should == URI.parse("")
49
52
  end
50
53
  it "should not be valid if there is no rel" do
51
54
  link = Link.new 'href' => '/', 'title' => 'my collection'
@@ -7,16 +7,6 @@ describe Resource do
7
7
  @logger = Logger.new(STDOUT)
8
8
  end
9
9
 
10
- it "should have all the methods of a hash" do
11
- resource = Resource.new("uri", session=mock('session'))
12
- resource.size.should == 0
13
- resource['whatever'] = 'thing'
14
- resource.size.should == 1
15
- resource.should == {'whatever' => 'thing'}
16
- resource.should respond_to(:each)
17
- resource.should respond_to(:length)
18
- end
19
-
20
10
  describe "accessors" do
21
11
  it "should have a reader on the session" do
22
12
  resource = Resource.new("uri", session=mock("session"))
@@ -26,17 +16,7 @@ describe Resource do
26
16
  it "should have a reader on the uri" do
27
17
  resource = Resource.new("uri", session=mock("session"))
28
18
  resource.should_not respond_to(:uri=)
29
- resource.uri.should == "uri"
30
- end
31
- it "should have a reader on the raw property" do
32
- resource = Resource.new("uri", session=mock("session"))
33
- resource.should_not respond_to(:raw=)
34
- resource.load('raw' => {:a => :b}).raw.should == {:a => :b}
35
- end
36
- it "should have a reader on the state property" do
37
- resource = Resource.new("uri", session=mock("session"))
38
- resource.should_not respond_to(:state=)
39
- resource.state.should == :unloaded
19
+ resource.uri.should == URI.parse("uri")
40
20
  end
41
21
  end
42
22
 
@@ -85,97 +65,92 @@ describe Resource do
85
65
  'model' => 'XYZ1b'
86
66
  }
87
67
  }
88
- }.to_json
89
- @response_200 = Restfully::HTTP::Response.new(200, {'Content-Type' => 'application/json;utf-8', 'Content-Length' => @raw.length}, @raw)
68
+ }
69
+ @response_200 = Restfully::HTTP::Response.new(200, {'Content-Type' => 'application/json;utf-8', 'Content-Length' => @raw.length}, @raw.to_json)
70
+ @uri = URI.parse("http://api.local/x/y/z")
90
71
  end
91
72
  it "should not be loaded in its initial state" do
92
- resource = Resource.new(mock("uri"), mock('session'))
93
- resource.should_not be_loaded
73
+ resource = Resource.new(@uri, mock('session'))
74
+ resource.executed_requests.should == {}
94
75
  end
95
76
  it "should get the raw representation of the resource via the session if it doesn't have it" do
96
- resource = Resource.new(uri=mock("uri"), session = mock("session", :logger => Logger.new(STDOUT)))
77
+ resource = Resource.new(@uri, session = mock("session", :logger => Logger.new(STDOUT)))
97
78
  resource.stub!(:define_link) # do not define links
98
- resource.raw.should be_nil
99
- session.should_receive(:get).with(uri, {}).and_return(@response_200)
79
+ session.should_receive(:get).with(@uri, {}).and_return(@response_200)
100
80
  resource.load
101
- resource.should be_loaded
102
81
  end
103
82
  it "should get the raw representation of the resource via the session if there are query parameters" do
104
- resource = Resource.new(uri=mock("uri"), session = mock("session", :logger => Logger.new(STDOUT)))
83
+ resource = Resource.new(@uri, session = mock("session", :logger => Logger.new(STDOUT)))
105
84
  resource.stub!(:define_link) # do not define links
106
- resource.stub!(:loaded?).and_return(true) # should force reload even if already loaded
107
- resource.raw.should be_nil
108
- session.should_receive(:get).with(uri, {:query => {:q1 => 'v1'}}).and_return(@response_200)
85
+ session.should_receive(:get).with(@uri, {:query => {:q1 => 'v1'}}).and_return(@response_200)
109
86
  resource.load(:query => {:q1 => 'v1'})
110
87
  end
111
88
  it "should get the raw representation of the resource if forced to do so" do
112
- resource = Resource.new(uri=mock("uri"), session = mock("session", :logger => Logger.new(STDOUT)))
89
+ resource = Resource.new(@uri, session = mock("session", :logger => Logger.new(STDOUT)))
113
90
  resource.stub!(:define_link) # do not define links
114
- resource.stub!(:loaded?).and_return(true) # should force reload even if already loaded
115
- resource.raw.should be_nil
116
- session.should_receive(:get).with(uri, {}).and_return(@response_200)
91
+ session.should_receive(:get).with(@uri, {}).and_return(@response_200)
117
92
  resource.load(:reload => true)
118
93
  end
119
94
  it "should correctly define the functions to access simple values" do
120
- resource = Resource.new("uri", session = mock("session", :get => @response_200, :logger => @logger))
95
+ resource = Resource.new(@uri, session = mock("session", :get => @response_200, :logger => @logger))
121
96
  resource.stub!(:define_link) # do not define links
122
97
  resource.load
123
98
  resource['whatever'].should == 'whatever'
124
- resource.uri.should == 'uri'
99
+ resource.uri.should == @uri
125
100
  resource["uid"].should == 'rennes'
126
101
  resource['an_array'].should be_a(SpecialArray)
127
102
  resource['an_array'].should == [1,2,3]
128
103
  lambda{resource.clusters}.should raise_error(NoMethodError)
129
104
  end
130
105
 
131
- it "should correctly define a collection association" do
132
- resource = Resource.new("uri", session = mock("session", :get => mock("restfully response", :body => {
106
+ it "should correctly define a collection link" do
107
+ resource = Resource.new(@uri, session = mock("session", :get => mock("restfully response", :body => {
133
108
  'links' => [
134
109
  {'rel' => 'self', 'href' => '/grid5000/sites/rennes'},
135
110
  {'rel' => 'collection', 'href' => '/grid5000/sites/rennes/versions', 'resolvable' => false, 'title' => 'versions'}
136
111
  ],
137
112
  'uid' => 'rennes'
138
113
  }), :logger => @logger))
139
- Collection.should_receive(:new).with('/grid5000/sites/rennes/versions', session, :title => 'versions', :raw => nil).and_return(collection=mock("restfully collection"))
114
+ Collection.should_receive(:new).with(@uri.merge('/grid5000/sites/rennes/versions'), session, :title => 'versions').and_return(collection=mock("restfully collection"))
140
115
  resource.load
141
- resource.associations['versions'].should == collection
116
+ resource.links['versions'].should == collection
142
117
  end
143
118
  it "should NOT update the URI with the self link" do
144
- resource = Resource.new("uri", session = mock("session", :get => mock("restfully response", :body => {
119
+ resource = Resource.new(@uri, session = mock("session", :get => mock("restfully response", :body => {
145
120
  'links' => [
146
121
  {'rel' => 'self', 'href' => '/grid5000/sites/rennes'}
147
122
  ],
148
123
  'uid' => 'rennes'
149
124
  }), :logger => @logger))
150
- resource.uri.should == "uri"
125
+ resource.uri.should == @uri
151
126
  resource.load
152
- resource.uri.should == "uri"
127
+ resource.uri.should == @uri
153
128
  end
154
129
  it "should correctly define a member association" do
155
- resource = Resource.new("uri", session = mock("session", :get => mock("restfully response", :body => {
130
+ resource = Resource.new(@uri, session = mock("session", :get => mock("restfully response", :body => {
156
131
  'links' => [
157
132
  {'rel' => 'member', 'href' => '/grid5000/sites/rennes/versions/123', 'title' => 'version'}
158
133
  ],
159
134
  'uid' => 'rennes'
160
135
  }), :logger => @logger))
161
- Resource.should_receive(:new).with('/grid5000/sites/rennes/versions/123', session, :title => 'version', :raw => nil).and_return(member=mock("restfully resource"))
136
+ Resource.should_receive(:new).with(@uri.merge('/grid5000/sites/rennes/versions/123'), session, :title => 'version').and_return(member=mock("restfully resource"))
162
137
  resource.load
163
- resource.associations['version'].should == member
138
+ resource.links['version'].should == member
164
139
  end
165
140
  it "should correctly define a parent association" do
166
- resource = Resource.new("uri", session = mock("session", :get => mock("restfully response", :body => {
141
+ resource = Resource.new(@uri, session = mock("session", :get => mock("restfully response", :body => {
167
142
  'links' => [
168
143
  {'rel' => 'self', 'href' => '/grid5000/sites/rennes'},
169
144
  {'rel' => 'parent', 'href' => '/grid5000'}
170
145
  ],
171
146
  'uid' => 'rennes'
172
147
  }), :logger => @logger))
173
- Resource.should_receive(:new).with('/grid5000', session).and_return(parent=mock("restfully resource"))
148
+ Resource.should_receive(:new).with(@uri.merge('/grid5000'), session).and_return(parent=mock("restfully resource"))
174
149
  resource.load
175
- resource.associations['parent'].should == parent
150
+ resource.links['parent'].should == parent
176
151
  end
177
152
  it "should ignore bad links" do
178
- resource = Resource.new("uri", session = mock("session", :get => mock("restfully response", :body => {
153
+ resource = Resource.new(@uri, session = mock("session", :get => mock("restfully response", :body => {
179
154
  'links' => [
180
155
  {'rel' => 'self', 'href' => '/grid5000/sites/rennes'},
181
156
  {'rel' => 'invalid_rel', 'href' => '/whatever'},
@@ -184,15 +159,15 @@ describe Resource do
184
159
  'uid' => 'rennes'
185
160
  }), :logger => @logger))
186
161
  resource.load
187
- resource.associations.should be_empty
162
+ resource.links.should be_empty
188
163
  end
189
164
 
190
165
  it "should correctly define the functions to access links [integration test]" do
191
- resource = Resource.new("uri", session = mock("session", :get => @response_200, :logger => @logger))
166
+ resource = Resource.new(@uri, session = mock("session", :get => @response_200, :logger => @logger))
192
167
  @logger.should_receive(:warn).with(/collection \/has\/no\/title has no title/)
193
168
  @logger.should_receive(:warn).with(/invalid_rel is not a valid link relationship/)
194
169
  resource.load
195
- resource.associations.keys.should =~ ['versions', 'clusters', 'environments', 'status', 'parent', 'version']
170
+ resource.links.keys.should =~ ['versions', 'clusters', 'environments', 'status', 'parent', 'version']
196
171
  end
197
172
  end
198
173
  end