right_api_client 1.6.1 → 1.6.2
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.
- checksums.yaml +4 -4
- data/.rspec +3 -0
- data/CHANGELOG.md +10 -1
- data/Gemfile +6 -7
- data/README.md +8 -4
- data/VERSION +1 -1
- data/bin/console +40 -0
- data/bin/setup +5 -0
- data/config/login.yml.example +43 -0
- data/lib/right_api_client/client.rb +12 -3
- data/lib/right_api_client/errors.rb +6 -2
- data/login_to_client_irb.rb +1 -1
- data/right_api_client.gemspec +95 -0
- data/spec/functional/client_spec.rb +181 -0
- data/spec/spec_helper.rb +25 -0
- data/spec/support/mock_spec_helper.rb +40 -0
- data/spec/unit/client_spec.rb +23 -0
- data/spec/unit/helper_spec.rb +214 -0
- data/spec/unit/instance_facing_spec.rb +25 -0
- data/spec/unit/resource_detail_spec.rb +93 -0
- data/spec/unit/resource_spec.rb +78 -0
- data/spec/unit/resources_spec.rb +60 -0
- metadata +48 -33
- data/Gemfile.lock +0 -99
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'coveralls'
|
2
|
+
Coveralls.wear!
|
3
|
+
|
4
|
+
require 'pp'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
$: << File.expand_path('../../lib', __FILE__)
|
8
|
+
|
9
|
+
require 'right_api_client'
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
#
|
13
|
+
# include helpers
|
14
|
+
|
15
|
+
$config = config
|
16
|
+
|
17
|
+
Dir[File.expand_path('../support/**/*.rb', __FILE__)].each do |path|
|
18
|
+
require(path)
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# misc
|
23
|
+
|
24
|
+
config.mock_with :flexmock
|
25
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module MockSpecHelper
|
2
|
+
|
3
|
+
def mock_rest_client
|
4
|
+
@api_version = RightApi::Client::API_VERSION
|
5
|
+
@test_account_id = '1'
|
6
|
+
@rest_client = RestClient::Resource.new(RightApi::Client::DEFAULT_API_URL)
|
7
|
+
flexmock(RestClient::Resource).should_receive(:new).and_return(@rest_client)
|
8
|
+
@session = flexmock(:cookies => {})
|
9
|
+
@header = {'X-Api-Version' => @api_version, 'X-Account' => @test_account_id, :cookies => {}, :accept => :json}
|
10
|
+
end
|
11
|
+
|
12
|
+
def given_user_facing_client
|
13
|
+
mock_rest_client
|
14
|
+
flexmock(@rest_client).should_receive(:post).with(
|
15
|
+
{'email' => 'email', 'password' => 'password', 'account_href' => '/api/accounts/1'},
|
16
|
+
{'X-Api-Version' => @api_version}, Proc).and_return(@session)
|
17
|
+
flexmock(@rest_client).should_receive(:get).with(@header, Proc).once.and_return(['', '{"links": [
|
18
|
+
{
|
19
|
+
"href": "/api/servers",
|
20
|
+
"rel": "servers"
|
21
|
+
}]}'])
|
22
|
+
@client = RightApi::Client.new(:email => 'email', :password => 'password', :account_id => @test_account_id)
|
23
|
+
end
|
24
|
+
|
25
|
+
def given_instance_facing_client
|
26
|
+
mock_rest_client
|
27
|
+
flexmock(@rest_client).should_receive(:post).with(
|
28
|
+
{'instance_token' => 'instance_token', 'account_href' => '/api/accounts/1'},
|
29
|
+
{'X-Api-Version' => @api_version}, Proc).and_return(@session)
|
30
|
+
flexmock(@rest_client).should_receive(:get).with(@header, Proc).once.and_return(['', '{"links": [
|
31
|
+
{
|
32
|
+
"href": "/api/clouds/1/instances/1",
|
33
|
+
"rel": "self"
|
34
|
+
}]}'])
|
35
|
+
@client = RightApi::Client.new(:instance_token => 'instance_token', :account_id => @test_account_id)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
$config.include MockSpecHelper
|
40
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe RightApi::Client, :unit=>true do
|
4
|
+
context 'when the RightScale API misbehaves by sending empty bodies with 200 response' do
|
5
|
+
before(:each) do
|
6
|
+
given_user_facing_client
|
7
|
+
@result = Net::HTTPOK.new('1.1', '200', 'OK')
|
8
|
+
@result.set_content_type('application/vnd.rightscale.server+json')
|
9
|
+
@request = RestClient::Request.new(:method => 'GET', :headers => {}, :url => '/api/servers/1')
|
10
|
+
@response = RestClient::Response.create('', @result, {}, @request)
|
11
|
+
flexmock(@rest_client).should_receive(:get).with(Hash, Proc).and_yield(@response, @request, @result)
|
12
|
+
flexmock(@rest_client).should_receive(:post).with(Hash, Hash, Proc).and_yield(@response, @request, @result)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'raises an empty body error for a GET' do
|
16
|
+
expect { @client.servers(:id => 1).show }.to raise_error(RightApi::EmptyBodyError)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'raises an empty body error for a POST' do
|
20
|
+
expect { @client.servers.create }.to raise_error(RightApi::EmptyBodyError)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
include RightApi::Helper
|
3
|
+
|
4
|
+
describe RightApi::Helper, :unit=>true do
|
5
|
+
|
6
|
+
API_MEDIA_TYPES = %w{audit_entry ip_address process server}
|
7
|
+
|
8
|
+
context ".define_instance_method" do
|
9
|
+
it "defines method" do
|
10
|
+
flexmock(RightApi::Helper).should_receive(:define_method)
|
11
|
+
define_instance_method('show') {1}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context ".api_methods" do
|
16
|
+
it "returns api methods" do
|
17
|
+
api_methods.should == RightApi::Helper.methods(false)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context ".has_id" do
|
22
|
+
it "returns false when params have no :id" do
|
23
|
+
params = {}
|
24
|
+
has_id(params).should == false
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns true when params have no :id" do
|
28
|
+
params = {:id => 1}
|
29
|
+
has_id(params).should == true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context ".add_id_and_params_to_path" do
|
34
|
+
it "adds id to the path" do
|
35
|
+
path = "/api/hello"
|
36
|
+
params = {:id => 1}
|
37
|
+
result = "/api/hello/1"
|
38
|
+
add_id_and_params_to_path(path,params).should == result
|
39
|
+
end
|
40
|
+
|
41
|
+
it "adds params to the path" do
|
42
|
+
path = "/api/hello"
|
43
|
+
params = {:right => "scale"}
|
44
|
+
result = "/api/hello?right=scale"
|
45
|
+
add_id_and_params_to_path(path,params).should == result
|
46
|
+
end
|
47
|
+
|
48
|
+
it "adds filters to the path" do
|
49
|
+
path = "/api/hello"
|
50
|
+
params = {:filter => ["first_name==Right", "last_name==Scale"]}
|
51
|
+
result = "/api/hello?filter[]=first_name%3D%3DRight&filter[]=last_name%3D%3DScale"
|
52
|
+
add_id_and_params_to_path(path,params).should == result
|
53
|
+
end
|
54
|
+
|
55
|
+
it "adds id/params/filters to the path" do
|
56
|
+
path = "/api/hello"
|
57
|
+
params = {
|
58
|
+
:id => 1,
|
59
|
+
:param => "params",
|
60
|
+
:filter => ["first_name==Right", "last_name==Scale"]
|
61
|
+
}
|
62
|
+
result = "/api/hello/1?filter[]=first_name%3D%3DRight&filter[]=last_name%3D%3DScale¶m=params"
|
63
|
+
add_id_and_params_to_path(path,params).should == result
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context ".insert_in_path" do
|
68
|
+
it "inserts term in front of first ? in path" do
|
69
|
+
path = "aa?bb?cc?dd???"
|
70
|
+
term = "term"
|
71
|
+
result = "aa/term?bb?cc?dd???"
|
72
|
+
insert_in_path(path,term).should == result
|
73
|
+
end
|
74
|
+
|
75
|
+
it "appends term to the end of path" do
|
76
|
+
path = "helloThisIsAPath"
|
77
|
+
term = "term"
|
78
|
+
result = "helloThisIsAPath/term"
|
79
|
+
insert_in_path(path,term).should == result
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context ".is_singular?" do
|
84
|
+
API_MEDIA_TYPES.each do |media_type|
|
85
|
+
it "identifies media type #{media_type} as singular" do
|
86
|
+
is_singular?(media_type).should == true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context ".get_href_from_links" do
|
92
|
+
it "returns nil for empty links" do
|
93
|
+
links = []
|
94
|
+
get_href_from_links(links).should == nil
|
95
|
+
end
|
96
|
+
|
97
|
+
it "returns href of self link" do
|
98
|
+
links = [
|
99
|
+
{"rel" => "network", "href" => "/api/networks/aaa"},
|
100
|
+
{"rel" => "self", "href" => "/api/self"}
|
101
|
+
]
|
102
|
+
get_href_from_links(links).should == "/api/self"
|
103
|
+
|
104
|
+
links.should == [
|
105
|
+
{"rel" => "network", "href" => "/api/networks/aaa"},
|
106
|
+
{"rel" => "self", "href" => "/api/self"}
|
107
|
+
]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context ".get_and_delete_href_from_links" do
|
112
|
+
it "returns nil for empty links " do
|
113
|
+
links = []
|
114
|
+
get_and_delete_href_from_links(links).should == nil
|
115
|
+
end
|
116
|
+
|
117
|
+
it "returns and delete href of self link from links" do
|
118
|
+
links = [
|
119
|
+
{"rel" => "network", "href" => "/api/networks/aaa"},
|
120
|
+
{"rel" => "self", "href" => "/api/self"}
|
121
|
+
]
|
122
|
+
get_and_delete_href_from_links(links).should == "/api/self"
|
123
|
+
|
124
|
+
links.should == [{"rel" => "network", "href" => "/api/networks/aaa"}]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context ".simple_singularize" do
|
129
|
+
it "returns hardcoded values for special words" do
|
130
|
+
pair = {
|
131
|
+
"audit_entries" => "audit_entry",
|
132
|
+
"ip_addresses" => "ip_address",
|
133
|
+
"processes" => "process"
|
134
|
+
}
|
135
|
+
pair.keys.each do |key|
|
136
|
+
simple_singularize(key).should == pair[key]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
it "returns choped word for general work" do
|
141
|
+
word = "RightScale"
|
142
|
+
simple_singularize(word).should == word.chop
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context ".get_singular" do
|
147
|
+
it "returns downcased singular form of word" do
|
148
|
+
word = "RightScale"
|
149
|
+
get_singular(word).should == simple_singularize(word.to_s.downcase)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context ".fix_array_of_hashes" do
|
154
|
+
it "fixes all the keys that have the value as array of hashes" do
|
155
|
+
res = fix_array_of_hashes(
|
156
|
+
'a' => '1',
|
157
|
+
'b' => [1, 2, 3],
|
158
|
+
'c' => {1 => 2, 3 => 4},
|
159
|
+
'd' => [
|
160
|
+
{5 => 6, 7 => 8},
|
161
|
+
{9 => 10, 11 => 12}
|
162
|
+
]
|
163
|
+
)
|
164
|
+
|
165
|
+
res.should == {
|
166
|
+
'a' => '1',
|
167
|
+
'b' => [1, 2, 3],
|
168
|
+
'c' => {1 => 2, 3 => 4},
|
169
|
+
'd[]' => [
|
170
|
+
{5 => 6, 7 => 8},
|
171
|
+
{9 => 10, 11 => 12}
|
172
|
+
]
|
173
|
+
}
|
174
|
+
end
|
175
|
+
|
176
|
+
it "fixes key that have a top-level array of hashes as value" do
|
177
|
+
res = fix_array_of_hashes(
|
178
|
+
'a' => [
|
179
|
+
{1 => 2},
|
180
|
+
{3 => 4}
|
181
|
+
]
|
182
|
+
)
|
183
|
+
|
184
|
+
res.should == {
|
185
|
+
'a[]' => [
|
186
|
+
{1 => 2},
|
187
|
+
{3 => 4}
|
188
|
+
]
|
189
|
+
}
|
190
|
+
end
|
191
|
+
|
192
|
+
it "fixes key that have a nested array of hashes as value" do
|
193
|
+
res = fix_array_of_hashes(
|
194
|
+
'a' => {
|
195
|
+
'b' => [
|
196
|
+
{1 => 2},
|
197
|
+
{3 => 4}
|
198
|
+
]
|
199
|
+
}
|
200
|
+
)
|
201
|
+
|
202
|
+
res.should == {
|
203
|
+
'a' => {
|
204
|
+
'b' => {
|
205
|
+
'' => [
|
206
|
+
{1 => 2},
|
207
|
+
{3 => 4}
|
208
|
+
]
|
209
|
+
}
|
210
|
+
}
|
211
|
+
}
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe RightApi::Client, :unit=>true do
|
4
|
+
context "given an instance-facing logged in RightScale user" do
|
5
|
+
before(:each) do
|
6
|
+
given_instance_facing_client
|
7
|
+
end
|
8
|
+
|
9
|
+
it "has the required methods for the client" do
|
10
|
+
@client.api_methods.sort.collect{|s| s.to_s}.should == ["backups", "get_instance", "live_tasks", "tags","volume_attachments", "volume_snapshots", "volume_types", "volumes"]
|
11
|
+
end
|
12
|
+
|
13
|
+
it "returns an instance of the Resource class when user provides an id" do
|
14
|
+
@client.volumes(:id => 1).class.should == RightApi::Resource
|
15
|
+
@client.backups(:id => 1).class.should == RightApi::Resource
|
16
|
+
@client.live_tasks(:id => 1).class.should == RightApi::Resource
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns an instance of the Resources class when user does not provide an id" do
|
20
|
+
@client.volumes.class.should == RightApi::Resources
|
21
|
+
@client.backups.class.should == RightApi::Resources
|
22
|
+
@client.tags.class.should == RightApi::Resources
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe RightApi::ResourceDetail, :unit=>true do
|
4
|
+
before(:each) do
|
5
|
+
given_user_facing_client
|
6
|
+
end
|
7
|
+
|
8
|
+
subject {RightApi::ResourceDetail.new(@client, 'resource_detail', '/api/resource_detail', {})}
|
9
|
+
|
10
|
+
context "attributes" do
|
11
|
+
its(:client) {should eq @client}
|
12
|
+
its(:attributes) {should eq Set.new << :links}
|
13
|
+
its(:resource_type) {should eq 'resource_detail'}
|
14
|
+
its(:associations) {should eq Set.new}
|
15
|
+
its(:actions) {should eq Set.new}
|
16
|
+
its(:raw) {should eq Hash.new}
|
17
|
+
end
|
18
|
+
|
19
|
+
context ".inspect" do
|
20
|
+
let(:resource_detail){RightApi::ResourceDetail.new(@client, 'resource_detail', '/api/resource_detail', {})}
|
21
|
+
it "returns correct inspect infos" do
|
22
|
+
inspect_text = "#<#{resource_detail.class.name} resource_type=\"#{resource_detail.resource_type}\">"
|
23
|
+
resource_detail.inspect.should == inspect_text
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "given a logged in RightScale user" do
|
28
|
+
|
29
|
+
it "has the required methods for instances of the ResourceDetail class" do
|
30
|
+
resource = RightApi::ResourceDetail.new(@client, 'deployment', '/api/deployments/1', {})
|
31
|
+
resource.api_methods.sort.collect{|s| s.to_s}.should == ["destroy", "links", "show", "update"]
|
32
|
+
end
|
33
|
+
|
34
|
+
it "has resource-specific methods for instances of the ResourceDetail class" do
|
35
|
+
resource = RightApi::ResourceDetail.new(@client, 'deployment', '/api/deployments/1',
|
36
|
+
{:attribute1 => 'value1', :attribute2 => 'value2'})
|
37
|
+
resource.api_methods.sort.collect{|s| s.to_s}.should == ["attribute1", "attribute2", "destroy", "links", "show", "update"]
|
38
|
+
end
|
39
|
+
|
40
|
+
it "has the links for instances of the ResourceDetail class" do
|
41
|
+
resource = RightApi::ResourceDetail.new(@client, 'deployment', '/api/deployments/1',
|
42
|
+
{'links' => [{'rel' => 'link1', 'href' => 'link1_href'},
|
43
|
+
{'rel' => 'link2', 'href' => 'link2_href'}]})
|
44
|
+
resource.api_methods.sort.collect{|s| s.to_s}.should == ["destroy", "link1", "link2", "links", "show", "update"]
|
45
|
+
end
|
46
|
+
|
47
|
+
it "has the actions for instances of the ResourceDetail class" do
|
48
|
+
resource = RightApi::ResourceDetail.new(@client, 'deployment', '/api/deployments/1',
|
49
|
+
{'links' => [{'rel' => 'self', 'href' => 'self'}],
|
50
|
+
'actions' => [{'rel' => 'action1'}, {'rel' => 'action2'}]})
|
51
|
+
resource.api_methods.sort.collect{|s| s.to_s}.should == ["action1", "action2", "destroy", "href", "links", "show", "update"]
|
52
|
+
|
53
|
+
flexmock(@rest_client).should_receive(:post).with({}, @header, Proc).and_return('ok')
|
54
|
+
resource.action1.should == 'ok'
|
55
|
+
end
|
56
|
+
|
57
|
+
it "has live_tasks for the 'instance' resource" do
|
58
|
+
resource = RightApi::ResourceDetail.new(@client, 'instance', '/api/instances/1', {})
|
59
|
+
resource.api_methods.sort.collect{|s| s.to_s}.should == ["destroy", "links", "live_tasks", "show", "update"]
|
60
|
+
flexmock(RightApi::Resource).should_receive(:process).with(@client, 'live_task', '/api/instances/1/live/tasks/1').and_return('ok')
|
61
|
+
resource.live_tasks(:id => '1').should == 'ok'
|
62
|
+
end
|
63
|
+
|
64
|
+
it "adds methods for child resources from detailed views" do
|
65
|
+
resource = RightApi::ResourceDetail.new(@client, 'server', '/api/servers/1', {
|
66
|
+
'links' => [
|
67
|
+
{'href' => '/api/servers/1', 'rel' => 'self'},
|
68
|
+
{'href' => '/api/clouds/1/instances/1', 'rel' => 'current_instance'}],
|
69
|
+
'current_instance' => {'links' => [{'href' => '/api/clouds/1/instances/1', 'rel' => 'self'}]}})
|
70
|
+
resource.api_methods.collect{|s| s.to_s}.sort.should == ["current_instance", "destroy", "href", "links", "show", "update"]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context ".[]" do
|
75
|
+
let(:resource) { RightApi::ResourceDetail.new(@client, 'deployment', '/api/deployments/1',
|
76
|
+
{'links' => [{'rel' => 'link1', 'href' => 'link1_href'}],
|
77
|
+
'real_attribute'=>'hi mom',
|
78
|
+
'link1' => 'sneaky'}) }
|
79
|
+
|
80
|
+
it 'reads attributes whose name overlaps with a link' do
|
81
|
+
resource['link1'].should == 'sneaky'
|
82
|
+
resource.link1.should_not == resource['link1']
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'accepts String keys' do
|
86
|
+
resource['real_attribute'].should == 'hi mom'
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'accepts Symbol keys' do
|
90
|
+
resource[:real_attribute].should == 'hi mom'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe RightApi::Resource, :unit=>true do
|
4
|
+
before(:each) do
|
5
|
+
given_user_facing_client
|
6
|
+
end
|
7
|
+
|
8
|
+
subject {RightApi::Resource.new(@client, 'resource', '/api/resource')}
|
9
|
+
|
10
|
+
context "attributes" do
|
11
|
+
its(:client) {should eq @client}
|
12
|
+
its(:href) {should eq '/api/resource'}
|
13
|
+
its(:resource_type) {should eq 'resource'}
|
14
|
+
end
|
15
|
+
|
16
|
+
context "#process" do
|
17
|
+
it "creates resource_detail with data" do
|
18
|
+
flexmock(RightApi::ResourceDetail).should_receive(:new)
|
19
|
+
RightApi::Resource.process(@client, 'resource', '/api/resource', :right => ['scale'])
|
20
|
+
end
|
21
|
+
|
22
|
+
it "creates resource without data" do
|
23
|
+
flexmock(RightApi::Resource).should_receive(:new)
|
24
|
+
RightApi::Resource.process(@client, 'resource', '/api/resource')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "#process_detailed" do
|
29
|
+
it "calls process with data array" do
|
30
|
+
flexmock(RightApi::Resource).should_receive(:process)
|
31
|
+
RightApi::Resource.process(@client, 'resource', '/api/resource', :right => ['scale'])
|
32
|
+
end
|
33
|
+
|
34
|
+
it "calls process with data array" do
|
35
|
+
flexmock(RightApi::Resource).should_receive(:process)
|
36
|
+
RightApi::Resource.process(@client, 'resource', '/api/resource')
|
37
|
+
end
|
38
|
+
|
39
|
+
it "creates new process detail with data links" do
|
40
|
+
flexmock(RightApi::ResourceDetail).should_receive(:new)
|
41
|
+
RightApi::Resource.process(@client, 'resource', '/api/resource', 'links' => 'scale')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context ".inspect" do
|
46
|
+
let(:resource) {RightApi::Resource.new(@client, 'resource', '/api/resource')}
|
47
|
+
it "returns correct inspect text" do
|
48
|
+
inspect_text = "#<#{resource.class.name} resource_type=\"#{resource.resource_type}\">"
|
49
|
+
resource.inspect.should == inspect_text
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context ".method_missing" do
|
54
|
+
it "sends correct post request" do
|
55
|
+
client = flexmock(@client)
|
56
|
+
resource = RightApi::Resource.new(client, 'resource', '/api/resource')
|
57
|
+
client.should_receive(:send).with(:do_post, "#{resource.href}/method")
|
58
|
+
resource.method_missing('method')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "given a logged in RightScale user" do
|
63
|
+
it "has the required methods for instances of the Resource class" do
|
64
|
+
resource = RightApi::Resource.process(@client, 'deployment', '/api/deployments/1')
|
65
|
+
resource.api_methods.sort.map(&:to_s).should == %w[ destroy show update ]
|
66
|
+
end
|
67
|
+
|
68
|
+
it "has destroy/show/update for all instances of the Resource class" do
|
69
|
+
resource = RightApi::Resource.process(@client, 'session', '/api/session')
|
70
|
+
resource.api_methods.sort.map(&:to_s).should == %w[ destroy show update ]
|
71
|
+
end
|
72
|
+
|
73
|
+
it "has an array of ResourceDetail instances for index calls" do
|
74
|
+
resources = RightApi::Resource.process(@client, 'deployment', '/api/deployments', [{}])
|
75
|
+
resources.first.class.should == RightApi::ResourceDetail
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|