diff options
author | Rick Bradley <rick@rickbradley.com> | 2007-10-23 12:09:05 -0500 |
---|---|---|
committer | Rick Bradley <rick@rickbradley.com> | 2007-10-23 12:09:05 -0500 |
commit | e7bfe0bf9b525d6216cbb24be99357d33c0b87ec (patch) | |
tree | fc9b59dbb6ae9f77de3176a7b32343547e3b1d81 | |
parent | d28a9041039860beb9e19da267bbad40ecebf8f1 (diff) | |
download | puppet-e7bfe0bf9b525d6216cbb24be99357d33c0b87ec.tar.gz puppet-e7bfe0bf9b525d6216cbb24be99357d33c0b87ec.tar.xz puppet-e7bfe0bf9b525d6216cbb24be99357d33c0b87ec.zip |
Finish serializing successful results (via calls to to_yaml, etc.) for REST handlers. Refactor request building in REST handler specs.
-rw-r--r-- | lib/puppet/network/http/handler.rb | 14 | ||||
-rw-r--r-- | lib/puppet/network/http/mongrel/rest.rb | 1 | ||||
-rw-r--r-- | lib/puppet/network/http/webrick/rest.rb | 1 | ||||
-rw-r--r-- | spec/unit/network/http/mongrel/rest.rb | 147 | ||||
-rw-r--r-- | spec/unit/network/http/webrick/rest.rb | 149 |
5 files changed, 177 insertions, 135 deletions
diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index 9b21946c7..2a537c767 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -20,25 +20,31 @@ class Puppet::Network::HTTP::Handler def do_find(request, response) key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]") args = params(request) - encode_result(request, response, @model.find(key, args)) + result = @model.find(key, args).to_yaml + encode_result(request, response, result) end def do_search(request, response) args = params(request) - encode_result(request, response, @model.search(args)) + result = @model.search(args).collect {|obj| obj.to_yaml } + encode_result(request, response, result) + end def do_destroy(request, response) key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]") args = params(request) - encode_result(request, response, @model.destroy(key, args)) + result = @model.destroy(key, args) + encode_result(request, response, YAML.dump(result)) end def do_save(request, response) data = body(request) raise ArgumentError, "No data to save" if !data or data.empty? args = params(request) - encode_result(request, response, @model.new.save(args.merge(:data => data))) + obj = @model.new + result = obj.save(args.merge(:data => data)).to_yaml + encode_result(request, response, result) end def find_model_for_handler(handler) diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index 0d29a822e..f22b4c4c9 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -31,6 +31,7 @@ class Puppet::Network::HTTP::MongrelREST < Puppet::Network::HTTP::Handler def encode_result(request, response, result) response.start(200) do |head, body| + body.write(result) end end end diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index d30f9318b..8782df14f 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -36,5 +36,6 @@ class Puppet::Network::HTTP::WEBrickREST < Puppet::Network::HTTP::Handler def encode_result(request, response, result) response.status = 200 + response.body = result end end
\ No newline at end of file diff --git a/spec/unit/network/http/mongrel/rest.rb b/spec/unit/network/http/mongrel/rest.rb index 944b0896e..1cdc147dc 100644 --- a/spec/unit/network/http/mongrel/rest.rb +++ b/spec/unit/network/http/mongrel/rest.rb @@ -54,48 +54,68 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do confine "Mongrel is not available" => Puppet.features.mongrel? before do - @mock_request = mock('mongrel http request') - @mock_response = mock('mongrel http response') - @mock_response.stubs(:start) - @mock_model_class = mock('indirected model class') + @mock_request = stub('mongrel http request') + @mock_head = stub('response head') + @mock_body = stub('response body', :write => true) + @mock_response = stub('mongrel http response') + @mock_response.stubs(:start).yields(@mock_head, @mock_body) + @mock_model_class = stub('indirected model class') + @mock_mongrel = stub('mongrel http server', :register => true) Puppet::Indirector::Indirection.stubs(:model).with(:foo).returns(@mock_model_class) - @mock_mongrel = mock('mongrel http server') - @mock_mongrel.stubs(:register) @handler = Puppet::Network::HTTP::MongrelREST.new(:server => @mock_mongrel, :handler => :foo) end - it "should call the model find method if the request represents a singular HTTP GET" do + def setup_find_request(params = {}) @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', Mongrel::Const::REQUEST_PATH => '/foo/key', - 'QUERY_STRING' => ''}) + 'QUERY_STRING' => ''}.merge(params)) + @mock_model_class.stubs(:find) + end + + def setup_search_request(params = {}) + @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', + Mongrel::Const::REQUEST_PATH => '/foos', + 'QUERY_STRING' => '' }.merge(params)) + @mock_model_class.stubs(:search).returns([]) + end + + def setup_destroy_request(params = {}) + @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'DELETE', + Mongrel::Const::REQUEST_PATH => '/foo/key', + 'QUERY_STRING' => '' }.merge(params)) + @mock_model_class.stubs(:destroy) + end + + def setup_save_request(params = {}) + @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'PUT', + Mongrel::Const::REQUEST_PATH => '/foo', + 'QUERY_STRING' => '' }.merge(params)) + @mock_request.stubs(:body).returns('this is a fake request body') + @mock_model_instance = stub('indirected model instance', :save => true) + @mock_model_class.stubs(:new).returns(@mock_model_instance) + end + + it "should call the model find method if the request represents a singular HTTP GET" do + setup_find_request @mock_model_class.expects(:find).with('key', {}) @handler.process(@mock_request, @mock_response) end it "should call the model search method if the request represents a plural HTTP GET" do - @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', - Mongrel::Const::REQUEST_PATH => '/foos', - 'QUERY_STRING' => '' }) - @mock_model_class.expects(:search).with({}) + setup_search_request + @mock_model_class.expects(:search).with({}).returns([]) @handler.process(@mock_request, @mock_response) end it "should call the model destroy method if the request represents an HTTP DELETE" do - @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'DELETE', - Mongrel::Const::REQUEST_PATH => '/foo/key', - 'QUERY_STRING' => '' }) + setup_destroy_request @mock_model_class.expects(:destroy).with('key', {}) @handler.process(@mock_request, @mock_response) end it "should call the model save method if the request represents an HTTP PUT" do - @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'PUT', - Mongrel::Const::REQUEST_PATH => '/foo', - 'QUERY_STRING' => '' }) - @mock_request.stubs(:body).returns('this is a fake request body') - mock_model_instance = mock('indirected model instance') - mock_model_instance.expects(:save).with(:data => 'this is a fake request body') - @mock_model_class.expects(:new).returns(mock_model_instance) + setup_save_request + @mock_model_instance.expects(:save).with(:data => 'this is a fake request body') @handler.process(@mock_request, @mock_response) end @@ -135,9 +155,7 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do end it "should pass HTTP request parameters to model find" do - @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', - Mongrel::Const::REQUEST_PATH => '/foo/key', - 'QUERY_STRING' => 'foo=baz&bar=xyzzy'}) + setup_find_request('QUERY_STRING' => 'foo=baz&bar=xyzzy') @mock_model_class.expects(:find).with do |key, args| key == 'key' and args['foo'] == 'baz' and args['bar'] == 'xyzzy' end @@ -145,19 +163,15 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do end it "should pass HTTP request parameters to model search" do - @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', - Mongrel::Const::REQUEST_PATH => '/foos', - 'QUERY_STRING' => 'foo=baz&bar=xyzzy'}) + setup_search_request('QUERY_STRING' => 'foo=baz&bar=xyzzy') @mock_model_class.expects(:search).with do |args| args['foo'] == 'baz' and args['bar'] == 'xyzzy' - end + end.returns([]) @handler.process(@mock_request, @mock_response) end it "should pass HTTP request parameters to model delete" do - @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'DELETE', - Mongrel::Const::REQUEST_PATH => '/foo/key', - 'QUERY_STRING' => 'foo=baz&bar=xyzzy'}) + setup_destroy_request('QUERY_STRING' => 'foo=baz&bar=xyzzy') @mock_model_class.expects(:destroy).with do |key, args| key == 'key' and args['foo'] == 'baz' and args['bar'] == 'xyzzy' end @@ -165,64 +179,65 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do end it "should pass HTTP request parameters to model save" do - @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'PUT', - Mongrel::Const::REQUEST_PATH => '/foo', - 'QUERY_STRING' => 'foo=baz&bar=xyzzy'}) - @mock_request.stubs(:body).returns('this is a fake request body') - mock_model_instance = mock('indirected model instance') - mock_model_instance.expects(:save).with do |args| + setup_save_request('QUERY_STRING' => 'foo=baz&bar=xyzzy') + @mock_model_instance.expects(:save).with do |args| args[:data] == 'this is a fake request body' and args['foo'] == 'baz' and args['bar'] == 'xyzzy' end - @mock_model_class.expects(:new).returns(mock_model_instance) @handler.process(@mock_request, @mock_response) end it "should generate a 200 response when a model find call succeeds" do - @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', - Mongrel::Const::REQUEST_PATH => '/foo/key', - 'QUERY_STRING' => ''}) - @mock_model_class.stubs(:find) + setup_find_request @mock_response.expects(:start).with(200) @handler.process(@mock_request, @mock_response) end it "should generate a 200 response when a model search call succeeds" do - @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', - Mongrel::Const::REQUEST_PATH => '/foos', - 'QUERY_STRING' => ''}) - @mock_model_class.stubs(:search) + setup_search_request @mock_response.expects(:start).with(200) @handler.process(@mock_request, @mock_response) end it "should generate a 200 response when a model destroy call succeeds" do - @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'DELETE', - Mongrel::Const::REQUEST_PATH => '/foo/key', - 'QUERY_STRING' => ''}) - @mock_model_class.stubs(:destroy) - @mock_response.expects(:start).with(200) - @handler.process(@mock_request, @mock_response) + setup_destroy_request + @mock_response.expects(:start).with(200) + @handler.process(@mock_request, @mock_response) end it "should generate a 200 response when a model save call succeeds" do - @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'PUT', - Mongrel::Const::REQUEST_PATH => '/foo', - 'QUERY_STRING' => ''}) - @mock_request.stubs(:body).returns('this is a fake request body') - @mock_model_instance = mock('model instance') - @mock_model_instance.stubs(:save) - @mock_model_class.stubs(:new).returns(@mock_model_instance) - @mock_response.expects(:start).with(200) - @handler.process(@mock_request, @mock_response) + setup_save_request + @mock_response.expects(:start).with(200) + @handler.process(@mock_request, @mock_response) end - it "should return a serialized object when a model find call succeeds" + it "should return a serialized object when a model find call succeeds" do + setup_find_request + @mock_model_instance = stub('model instance') + @mock_model_instance.expects(:to_yaml) + @mock_model_class.stubs(:find).returns(@mock_model_instance) + @handler.process(@mock_request, @mock_response) + end - it "should return a list of serialized object matches when a model search call succeeds" + it "should return a list of serialized objects when a model search call succeeds" do + setup_search_request + mock_matches = [1..5].collect {|i| mock("model instance #{i}", :to_yaml => "model instance #{i}") } + @mock_model_class.stubs(:search).returns(mock_matches) + @handler.process(@mock_request, @mock_response) + end - it "should return a serialized success result when a model destroy call succeeds" + it "should return a serialized success result when a model destroy call succeeds" do + setup_destroy_request + @mock_model_class.stubs(:destroy).returns(true) + @mock_body.expects(:write).with("--- true\n") + @handler.process(@mock_request, @mock_response) + end - it "should return a serialized success result when a model save call succeeds" + it "should return a serialized object when a model save call succeeds" do + setup_save_request + @mock_model_instance.stubs(:save).returns(@mock_model_instance) + @mock_model_instance.expects(:to_yaml).returns('foo') + @handler.process(@mock_request, @mock_response) + end it "should serialize a controller exception when an exception is thrown by the handler" end diff --git a/spec/unit/network/http/webrick/rest.rb b/spec/unit/network/http/webrick/rest.rb index 9d1f5fc6b..14505f919 100644 --- a/spec/unit/network/http/webrick/rest.rb +++ b/spec/unit/network/http/webrick/rest.rb @@ -8,8 +8,7 @@ require 'puppet/network/http' describe Puppet::Network::HTTP::WEBrickREST, "when initializing" do before do - @mock_webrick = mock('WEBrick server') - @mock_webrick.stubs(:mount) + @mock_webrick = stub('WEBrick server', :mount => true) @mock_model = mock('indirected model') Puppet::Indirector::Indirection.stubs(:model).returns(@mock_model) @params = { :server => @mock_webrick, :handler => :foo } @@ -50,43 +49,60 @@ end describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do before do - @mock_request = mock('webrick http request') - @mock_request.stubs(:query).returns({}) - @mock_response = mock('webrick http response') - @mock_response.stubs(:status=) - @mock_model_class = mock('indirected model class') + @mock_request = stub('webrick http request', :query => {}) + @mock_response = stub('webrick http response', :status= => true, :body= => true) + @mock_model_class = stub('indirected model class') + @mock_webrick = stub('mongrel http server', :mount => true) Puppet::Indirector::Indirection.stubs(:model).with(:foo).returns(@mock_model_class) - @mock_webrick = mock('mongrel http server') - @mock_webrick.stubs(:mount) @handler = Puppet::Network::HTTP::WEBrickREST.new(:server => @mock_webrick, :handler => :foo) end + + def setup_find_request + @mock_request.stubs(:request_method).returns('GET') + @mock_request.stubs(:path).returns('/foo/key') + @mock_model_class.stubs(:find) + end - it "should call the model find method if the request represents a singular HTTP GET" do + def setup_search_request @mock_request.stubs(:request_method).returns('GET') + @mock_request.stubs(:path).returns('/foos') + @mock_model_class.stubs(:search).returns([]) + end + + def setup_destroy_request + @mock_request.stubs(:request_method).returns('DELETE') @mock_request.stubs(:path).returns('/foo/key') + @mock_model_class.stubs(:destroy) + end + + def setup_save_request + @mock_request.stubs(:request_method).returns('PUT') + @mock_request.stubs(:path).returns('/foo') + @mock_request.stubs(:body).returns('This is a fake request body') + @mock_model_instance = stub('indirected model instance', :save => true) + @mock_model_class.stubs(:new).returns(@mock_model_instance) + end + + it "should call the model find method if the request represents a singular HTTP GET" do + setup_find_request @mock_model_class.expects(:find).with('key', {}) @handler.service(@mock_request, @mock_response) end it "should call the model search method if the request represents a plural HTTP GET" do - @mock_request.stubs(:request_method).returns('GET') - @mock_request.stubs(:path).returns('/foos') - @mock_model_class.expects(:search) + setup_search_request + @mock_model_class.expects(:search).returns([]) @handler.service(@mock_request, @mock_response) end it "should call the model destroy method if the request represents an HTTP DELETE" do - @mock_request.stubs(:request_method).returns('DELETE') - @mock_request.stubs(:path).returns('/foo/key') + setup_destroy_request @mock_model_class.expects(:destroy).with('key', {}) @handler.service(@mock_request, @mock_response) end it "should call the model save method if the request represents an HTTP PUT" do - @mock_request.stubs(:request_method).returns('PUT') - @mock_request.stubs(:path).returns('/foo') - @mock_request.stubs(:body).returns('This is a fake request body') - @mock_model_instance = mock('indirected model instance') + setup_save_request @mock_model_instance.expects(:save).with(:data => 'This is a fake request body') @mock_model_class.expects(:new).returns(@mock_model_instance) @handler.service(@mock_request, @mock_response) @@ -102,6 +118,7 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do @mock_request.stubs(:request_method).returns('DELETE') @mock_request.stubs(:path).returns('/foos/key') Proc.new { @handler.process(@mock_request, @mock_response) }.should raise_error(ArgumentError) + @mock_request.stubs(:request_method).returns('PUT') @mock_request.stubs(:path).returns('/foos/key') Proc.new { @handler.process(@mock_request, @mock_response) }.should raise_error(ArgumentError) @@ -133,9 +150,8 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do end it "should pass HTTP request parameters to model find" do + setup_find_request @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy) - @mock_request.stubs(:request_method).returns('GET') - @mock_request.stubs(:path).returns('/foo/key') @mock_model_class.expects(:find).with do |key, args| key == 'key' and args[:foo] == :baz and args[:bar] == :xyzzy end @@ -143,19 +159,17 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do end it "should pass HTTP request parameters to model search" do + setup_search_request @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy) - @mock_request.stubs(:request_method).returns('GET') - @mock_request.stubs(:path).returns('/foos/key') @mock_model_class.expects(:search).with do |args| args[:foo] == :baz and args[:bar] == :xyzzy - end + end.returns([]) @handler.service(@mock_request, @mock_response) end it "should pass HTTP request parameters to model destroy" do + setup_destroy_request @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy) - @mock_request.stubs(:request_method).returns('DELETE') - @mock_request.stubs(:path).returns('/foo/key') @mock_model_class.expects(:destroy).with do |key, args| key == 'key' and args[:foo] == :baz and args[:bar] == :xyzzy end @@ -163,61 +177,66 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do end it "should pass HTTP request parameters to model save" do - @mock_request.stubs(:request_method).returns('PUT') - @mock_request.stubs(:path).returns('/foo') + setup_save_request @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy) - @mock_request.stubs(:body).returns('This is a fake request body') - @mock_model_instance = mock('indirected model instance') @mock_model_instance.expects(:save).with do |args| args[:data] == 'This is a fake request body' and args[:foo] == :baz and args[:bar] == :xyzzy end - @mock_model_class.expects(:new).returns(@mock_model_instance) @handler.service(@mock_request, @mock_response) end it "should generate a 200 response when a model find call succeeds" do - @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy) - @mock_request.stubs(:request_method).returns('GET') - @mock_request.stubs(:path).returns('/foo/key') - @mock_model_class.stubs(:find) - @mock_response.expects(:status=).with(200) - @handler.process(@mock_request, @mock_response) + setup_find_request + @mock_response.expects(:status=).with(200) + @handler.process(@mock_request, @mock_response) end it "should generate a 200 response when a model search call succeeds" do - @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy) - @mock_request.stubs(:request_method).returns('GET') - @mock_request.stubs(:path).returns('/foos/key') - @mock_model_class.stubs(:search) - @mock_response.expects(:status=).with(200) - @handler.process(@mock_request, @mock_response) + setup_search_request + @mock_response.expects(:status=).with(200) + @handler.process(@mock_request, @mock_response) end it "should generate a 200 response when a model destroy call succeeds" do - @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy) - @mock_request.stubs(:request_method).returns('DELETE') - @mock_request.stubs(:path).returns('/foo/key') - @mock_model_class.stubs(:destroy) - @mock_response.expects(:status=).with(200) - @handler.process(@mock_request, @mock_response) + setup_destroy_request + @mock_response.expects(:status=).with(200) + @handler.process(@mock_request, @mock_response) end it "should generate a 200 response when a model save call succeeds" do - @mock_request.stubs(:request_method).returns('PUT') - @mock_request.stubs(:path).returns('/foo') - @mock_request.stubs(:query).returns(:foo => :baz, :bar => :xyzzy) - @mock_request.stubs(:body).returns('This is a fake request body') - @mock_model_instance = mock('indirected model instance') - @mock_model_class.stubs(:new).returns(@mock_model_instance) - @mock_model_instance.stubs(:save) - @mock_response.expects(:status=).with(200) - @handler.process(@mock_request, @mock_response) - end - - - it "should return a serialized object when a model find call succeeds" - it "should return a list of serialized object matches when a model search call succeeds" - it "should return a serialized success result when a model destroy call succeeds" - it "should return a serialized success result when a model save call succeeds" + setup_save_request + @mock_response.expects(:status=).with(200) + @handler.process(@mock_request, @mock_response) + end + + it "should return a serialized object when a model find call succeeds" do + setup_find_request + @mock_model_instance = stub('model instance') + @mock_model_instance.expects(:to_yaml) + @mock_model_class.stubs(:find).returns(@mock_model_instance) + @handler.process(@mock_request, @mock_response) + end + + it "should return a list of serialized objects when a model search call succeeds" do + setup_search_request + mock_matches = [1..5].collect {|i| mock("model instance #{i}", :to_yaml => "model instance #{i}") } + @mock_model_class.stubs(:search).returns(mock_matches) + @handler.process(@mock_request, @mock_response) + end + + it "should return a serialized success result when a model destroy call succeeds" do + setup_destroy_request + @mock_model_class.stubs(:destroy).returns(true) + @mock_response.expects(:body=).with("--- true\n") + @handler.process(@mock_request, @mock_response) + end + + it "should return a serialized object when a model save call succeeds" do + setup_save_request + @mock_model_instance.stubs(:save).returns(@mock_model_instance) + @mock_model_instance.expects(:to_yaml).returns('foo') + @handler.process(@mock_request, @mock_response) + end + it "should serialize a controller exception when an exception is thrown by the handler" end |