summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/puppet/network/http/handler.rb42
-rw-r--r--lib/puppet/network/http/mongrel/rest.rb10
-rw-r--r--lib/puppet/network/http/webrick/rest.rb10
-rw-r--r--spec/unit/network/http/mongrel/rest.rb34
-rw-r--r--spec/unit/network/http/webrick/rest.rb36
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"