restfully 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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