diff options
-rw-r--r-- | lib/puppet/network/http/handler.rb | 42 | ||||
-rw-r--r-- | lib/puppet/network/http/mongrel/rest.rb | 10 | ||||
-rw-r--r-- | lib/puppet/network/http/webrick/rest.rb | 10 | ||||
-rw-r--r-- | spec/unit/network/http/mongrel/rest.rb | 34 | ||||
-rw-r--r-- | spec/unit/network/http/webrick/rest.rb | 36 |
5 files changed, 107 insertions, 25 deletions
diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index 77df113e6..fb7b5c323 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -8,15 +8,35 @@ class Puppet::Network::HTTP::Handler # handle an HTTP request coming from Mongrel def process(request, response) - return @model.find if get?(request) and singular?(request) - return @model.search if get?(request) and plural?(request) - return @model.destroy if delete?(request) and singular?(request) - return @model.new.save if put?(request) and singular?(request) + return do_find(request, response) if get?(request) and singular?(request) + return do_search(request, response) if get?(request) and plural?(request) + return do_destroy(request, response) if delete?(request) and singular?(request) + return do_save(request, response) if put?(request) and singular?(request) raise ArgumentError, "Did not understand HTTP #{http_method(request)} request for '#{path(request)}'" end private + def do_find(request, response) + key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]") + @model.find(key) + end + + def do_search(request, response) + @model.search + end + + def do_destroy(request, response) + key = request_key(request) || raise(ArgumentError, "Could not locate lookup key in request path [#{path}]") + @model.destroy(key) + end + + def do_save(request, response) + data = body(request) + raise ArgumentError, "No data to save" if !data or data.empty? + @model.new.save(:data => data) + end + def find_model_for_handler(handler) Puppet::Indirector::Indirection.model(handler) || raise(ArgumentError, "Cannot locate indirection [#{handler}].") @@ -45,14 +65,22 @@ class Puppet::Network::HTTP::Handler # methods specific to a given web server def register_handler - raise UnimplementedError + raise NotImplementedError end def http_method(request) - raise UnimplementedError + raise NotImplementedError end def path(request) - raise UnimplementedError + raise NotImplementedError end + + def request_key(request) + raise NotImplementedError + end + + def body(request) + raise NotImplementedError + end end diff --git a/lib/puppet/network/http/mongrel/rest.rb b/lib/puppet/network/http/mongrel/rest.rb index 4c795481b..f7807b19f 100644 --- a/lib/puppet/network/http/mongrel/rest.rb +++ b/lib/puppet/network/http/mongrel/rest.rb @@ -14,6 +14,14 @@ class Puppet::Network::HTTP::MongrelREST < Puppet::Network::HTTP::Handler end def path(request) - request.params[Mongrel::Const::REQUEST_PATH] + '/' + request.params[Mongrel::Const::REQUEST_PATH].split('/')[1] + end + + def request_key(request) + request.params[Mongrel::Const::REQUEST_PATH].split('/')[2] + end + + def body(request) + request.body end end diff --git a/lib/puppet/network/http/webrick/rest.rb b/lib/puppet/network/http/webrick/rest.rb index ed29cfb75..bfcd0784d 100644 --- a/lib/puppet/network/http/webrick/rest.rb +++ b/lib/puppet/network/http/webrick/rest.rb @@ -19,6 +19,14 @@ class Puppet::Network::HTTP::WEBrickREST < Puppet::Network::HTTP::Handler end def path(request) - request.path + '/' + request.path.split('/')[1] + end + + def request_key(request) + request.path.split('/')[2] + end + + def body(request) + request.body 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 5bb40d777..15ee06c7e 100644 --- a/spec/unit/network/http/mongrel/rest.rb +++ b/spec/unit/network/http/mongrel/rest.rb @@ -60,8 +60,8 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do end it "should call the model find method if the request represents a singular HTTP GET" do - @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', Mongrel::Const::REQUEST_PATH => '/foo'}) - @mock_model_class.expects(:find) + @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', Mongrel::Const::REQUEST_PATH => '/foo/key'}) + @mock_model_class.expects(:find).with('key') @handler.process(@mock_request, @mock_response) end @@ -72,15 +72,16 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do 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'}) - @mock_model_class.expects(:destroy) + @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'DELETE', Mongrel::Const::REQUEST_PATH => '/foo/key'}) + @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'}) + @mock_request.stubs(:body).returns('this is a fake request body') mock_model_instance = mock('indirected model instance') - mock_model_instance.expects(:save) + mock_model_instance.expects(:save).with(:data => 'this is a fake request body') @mock_model_class.expects(:new).returns(mock_model_instance) @handler.process(@mock_request, @mock_response) end @@ -91,17 +92,34 @@ describe Puppet::Network::HTTP::MongrelREST, "when receiving a request" do end it "should fail if the request's pluralization is wrong" do - @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'DELETE', Mongrel::Const::REQUEST_PATH => '/foos'}) + @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'DELETE', Mongrel::Const::REQUEST_PATH => '/foos/key'}) Proc.new { @handler.process(@mock_request, @mock_response) }.should raise_error(ArgumentError) - @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'PUT', Mongrel::Const::REQUEST_PATH => '/foos'}) + @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'PUT', Mongrel::Const::REQUEST_PATH => '/foos/key'}) Proc.new { @handler.process(@mock_request, @mock_response) }.should raise_error(ArgumentError) end it "should fail if the request is for an unknown path" do - @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', Mongrel::Const::REQUEST_PATH => '/bar'}) + @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', Mongrel::Const::REQUEST_PATH => '/bar/key'}) Proc.new { @handler.process(@mock_request, @mock_response) }.should raise_error(ArgumentError) end + + it "should fail to find model if key is not specified" do + @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'GET', Mongrel::Const::REQUEST_PATH => '/foo'}) + Proc.new { @handler.process(@mock_request, @mock_response) }.should raise_error(ArgumentError) + end + + it "should fail to destroy model if key is not specified" do + @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'DELETE', Mongrel::Const::REQUEST_PATH => '/foo'}) + Proc.new { @handler.process(@mock_request, @mock_response) }.should raise_error(ArgumentError) + end + + it "should fail to save model if data is not specified" do + @mock_request.stubs(:params).returns({ Mongrel::Const::REQUEST_METHOD => 'PUT', Mongrel::Const::REQUEST_PATH => '/foo'}) + @mock_request.stubs(:body).returns('') + Proc.new { @handler.process(@mock_request, @mock_response) }.should raise_error(ArgumentError) + end + it "should unpack request information from Mongrel" it "should unpack parameters from the request for passing to controller methods" diff --git a/spec/unit/network/http/webrick/rest.rb b/spec/unit/network/http/webrick/rest.rb index 6eb44f4be..1a2faa95f 100644 --- a/spec/unit/network/http/webrick/rest.rb +++ b/spec/unit/network/http/webrick/rest.rb @@ -61,8 +61,8 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do it "should call the model find method if the request represents a singular HTTP GET" do @mock_request.stubs(:request_method).returns('GET') - @mock_request.stubs(:path).returns('/foo') - @mock_model_class.expects(:find) + @mock_request.stubs(:path).returns('/foo/key') + @mock_model_class.expects(:find).with('key') @handler.service(@mock_request, @mock_response) end @@ -75,16 +75,17 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do 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') - @mock_model_class.expects(:destroy) + @mock_request.stubs(:path).returns('/foo/key') + @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') - mock_model_instance.expects(:save) + 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) end @@ -97,18 +98,37 @@ describe Puppet::Network::HTTP::WEBrickREST, "when receiving a request" do it "should fail if the request's pluralization is wrong" do @mock_request.stubs(:request_method).returns('DELETE') - @mock_request.stubs(:path).returns('/foos') + @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') + @mock_request.stubs(:path).returns('/foos/key') Proc.new { @handler.process(@mock_request, @mock_response) }.should raise_error(ArgumentError) end it "should fail if the request is for an unknown path" do @mock_request.stubs(:request_method).returns('GET') - @mock_request.stubs(:path).returns('/bar') + @mock_request.stubs(:path).returns('/bar/key') + Proc.new { @handler.process(@mock_request, @mock_response) }.should raise_error(ArgumentError) + end + + it "should fail to find model if key is not specified" do + @mock_request.stubs(:request_method).returns('GET') + @mock_request.stubs(:path).returns('/foo') Proc.new { @handler.process(@mock_request, @mock_response) }.should raise_error(ArgumentError) end + + it "should fail to destroy model if key is not specified" do + @mock_request.stubs(:request_method).returns('DELETE') + @mock_request.stubs(:path).returns('/foo') + Proc.new { @handler.process(@mock_request, @mock_response) }.should raise_error(ArgumentError) + end + + it "should fail to save model if data is not specified" do + @mock_request.stubs(:request_method).returns('PUT') + @mock_request.stubs(:path).returns('/foo') + @mock_request.stubs(:body).returns('') + Proc.new { @handler.process(@mock_request, @mock_response) }.should raise_error(ArgumentError) + end it "should unpack request information from WEBrick" |