def test_handle_deferred(self): @inlineCallbacks def get(**_): yield succeed(None) returnValue(("body", OK)) request = DummyRequest() resource = Resource() resource.ALLOWED_CONTENT_TYPE = frozenset([""]) resource.ALLOWED_ACCEPT = frozenset(["*/*"]) resource.get = get with nested( patch.object(resource, "error"), patch.object(resource, "render_tuple"), patch.object(resource, "render_deferred"), ) as (error, render_tuple, render_deferred): response = resource.render(request) self.assertEqual(response, NOT_DONE_YET) self.assertFalse(error.called) self.assertFalse(render_tuple.called) self.assertEqual(render_deferred.call_count, 1) self.assertIs(render_deferred.call_args[0][0], request) self.assertIsInstance(render_deferred.call_args[0][1], Deferred)
def test_data_schema_validation_failed(self): for method in ("POST", "PUT"): request = DummyRequest() request.method = method request.requestHeaders.setRawHeaders( "Content-Type", ["application/json"]) request.requestHeaders.setRawHeaders( "Accept", ["application/json"]) request.set_content(json.dumps({"bar": ""})) resource = Resource() resource.ALLOWED_CONTENT_TYPE = frozenset(["application/json"]) resource.ALLOWED_ACCEPT = frozenset(["application/json"]) resource.SCHEMAS = { method: Schema({Required("foo"): str}) } method_impl = Mock(return_value=("", OK)) setattr(resource, method.lower(), method_impl) with patch.object(resource, "error") as error: response = resource.render(request) self.assertEqual(response, NOT_DONE_YET) error.assert_called_once_with( request, BAD_REQUEST, "Failed to validate the request data against the schema: extra " "keys not allowed @ data[u'bar']" ) self.assertFalse(method_impl.called)
def test_data_is_not_json(self): for method in ("POST", "PUT"): request = DummyRequest() request.method = method request.requestHeaders.setRawHeaders( "Content-Type", ["application/json"]) request.requestHeaders.setRawHeaders( "Accept", ["application/json"]) request.set_content("/") resource = Resource() resource.ALLOWED_CONTENT_TYPE = frozenset(["application/json"]) resource.ALLOWED_ACCEPT = frozenset(["application/json"]) method_impl = Mock() setattr(resource, method.lower(), method_impl) with patch.object(resource, "error") as error: response = resource.render(request) self.assertEqual(response, NOT_DONE_YET) error.assert_called_once_with( request, BAD_REQUEST, "Failed to decode json data: " "ValueError('No JSON object could be decoded',)" ) self.assertFalse(method_impl.called)
def test_call(self): resource = Resource() child = Resource() with patch.object(_Resource, "putChild") as putChild: resource.putChild("/", child) putChild.assert_called_with(resource, "/", child)
def test_method_not_allowed(self): resource = Resource() request = DummyRequest() request.method = "foobar" with patch.object(resource, "error") as error: response = resource.render(request) self.assertEqual(response, NOT_DONE_YET) error.assert_called_once_with( request, METHOD_NOT_ALLOWED, "Method %s is not supported" % request.method )
def test_default_content_type(self): """ If the Content-Type response header is not already set, set it based on the defaults """ request = DummyRequest() resource = Resource() resource.DEFAULT_CONTENT_TYPE = frozenset(["application/pyfarm"]) resource.render_tuple(request, ("body", OK, {})) self.assertEqual( request.responseHeaders.getRawHeaders("Content-Type"), ["application/pyfarm"] )
def test_content_type_already_set(self): """ If the Content-Type response header is already set, do not set it again. """ request = DummyRequest() resource = Resource() resource.DEFAULT_CONTENT_TYPE = frozenset(["application/foobar"]) resource.render_tuple( request, ("body", OK, {"Content-Type": ["application/pyfarm"]}) ) self.assertEqual( request.responseHeaders.getRawHeaders("Content-Type"), ["application/pyfarm"] )
def test_unsupported_media_type(self): resource = Resource() resource.ALLOWED_CONTENT_TYPE = frozenset("") resource.ALLOWED_ACCEPT = frozenset("") resource.get = lambda **_: "" request = DummyRequest() request.requestHeaders.setRawHeaders("Accept", ["foobar"]) request.set_content("hello") with patch.object(resource, "error") as error: response = resource.render(request) self.assertEqual(response, NOT_DONE_YET) error.assert_called_once_with( request, UNSUPPORTED_MEDIA_TYPE, "Can only support content type(s) frozenset([])" )
def test_exception_in_handler_method(self): def get(**_): raise ValueError("error") request = DummyRequest() resource = Resource() resource.ALLOWED_CONTENT_TYPE = frozenset(["application/json"]) resource.ALLOWED_ACCEPT = frozenset(["*/*"]) resource.get = get with patch.object(resource, "error") as error: response = resource.render(request) self.assertEqual(response, NOT_DONE_YET) error.assert_called_once_with( request, INTERNAL_SERVER_ERROR, "Unhandled error while rendering response: error" )
def test_handle_tuple(self): request = DummyRequest() resource = Resource() resource.ALLOWED_CONTENT_TYPE = frozenset([""]) resource.ALLOWED_ACCEPT = frozenset(["*/*"]) resource.get = lambda **_: ("body", OK) with nested( patch.object(resource, "error"), patch.object(resource, "render_tuple"), patch.object(resource, "render_deferred"), ) as (error, render_tuple, render_deferred): response = resource.render(request) self.assertEqual(response, NOT_DONE_YET) self.assertFalse(error.called) render_tuple.assert_called_once_with(request, ("body", OK)) self.assertFalse(render_deferred.called)
def test_default_content_type(self): """ If the Content-Type response header is not already set, set it based on the defaults """ request = DummyRequest() resource = Resource() resource.DEFAULT_CONTENT_TYPE = frozenset(["application/pyfarm"]) @inlineCallbacks def render(): yield succeed(None) returnValue(("body", OK)) yield resource.render_deferred(request, render()) self.assertEqual( request.responseHeaders.getRawHeaders("Content-Type"), ["application/pyfarm"] )
def test_data_empty(self): for method in ("POST", "PUT"): request = DummyRequest() request.method = method request.requestHeaders.setRawHeaders( "Content-Type", ["application/json"]) request.requestHeaders.setRawHeaders( "Accept", ["application/json"]) resource = Resource() resource.ALLOWED_CONTENT_TYPE = frozenset(["application/json"]) resource.ALLOWED_ACCEPT = frozenset(["application/json"]) resource.SCHEMAS = { method: Schema({Required("foo"): str}) } method_impl = Mock(return_value=("", OK)) setattr(resource, method.lower(), method_impl) response = resource.render(request) self.assertEqual(response, NOT_DONE_YET) method_impl.assert_called_once_with(request=request)
def test_handle_unknown_return_value(self): request = DummyRequest() resource = Resource() resource.ALLOWED_CONTENT_TYPE = frozenset([""]) resource.ALLOWED_ACCEPT = frozenset(["*/*"]) resource.get = lambda **_: None with nested( patch.object(resource, "error"), patch.object(resource, "render_tuple"), patch.object(resource, "render_deferred"), ) as (error, render_tuple, render_deferred): response = resource.render(request) self.assertEqual(response, NOT_DONE_YET) error.assert_called_once_with( request, INTERNAL_SERVER_ERROR, "Unhandled %r in response" % None ) self.assertFalse(render_tuple.called) self.assertFalse(render_deferred.called)
def build_http_resource(self): svclog.debug("Building HTTP Service") root = Resource() # static endpoints to redirect resources # to the right objects root.putChild( "favicon.ico", StaticPath(join(config["agent_static_root"], "favicon.ico"), defaultType="image/x-icon")) root.putChild( "static", StaticPath(config["agent_static_root"])) # external endpoints root.putChild("", Index()) root.putChild("configuration", Configuration()) # api endpoints api = root.putChild("api", APIRoot()) api.putChild("versions", Versions()) v1 = api.putChild("v1", APIRoot()) # Top level api endpoints v1.putChild("assign", Assign(self)) v1.putChild("tasks", Tasks()) v1.putChild("config", Config()) v1.putChild("task_logs", TaskLogs()) # Endpoints which are generally used for status # and operations. v1.putChild("status", Status()) v1.putChild("stop", Stop()) v1.putChild("restart", Restart()) v1.putChild("update", Update()) v1.putChild("check_software", CheckSoftware()) return root
def test_default_content_type(self): """ If the Content-Type response header is not already set, set it based on the defaults """ request = DummyRequest() resource = Resource() request.requestHeaders.setRawHeaders("Accept", ["application/json"]) resource.ALLOWED_ACCEPT = frozenset(["application/json"]) resource.ALLOWED_CONTENT_TYPE = frozenset(["application/json"]) resource.DEFAULT_CONTENT_TYPE = frozenset(["application/pyfarm"]) resource.get = lambda *_, **__: "" resource.render(request) self.assertEqual( request.responseHeaders.getRawHeaders("Content-Type"), ["application/pyfarm"] )
def test_assertion_invalid_path(self): resource = Resource() with self.assertRaises(AssertionError): resource.putChild(None, Resource())
def test_ignores_twisted_named_methods(self): resource = Resource() resource.render_GET = lambda self: None resource.render_PUT = lambda self: None resource.delete = lambda self: None self.assertEqual(set(resource.methods()), set(["delete"]))
def test_non_callable_method(self): resource = Resource() resource.get = lambda self: None resource.put = lambda self: None resource.delete = None self.assertEqual(set(resource.methods()), set(["get", "put"]))
def test_returns_child(self): resource = Resource() child = Resource() self.assertIs(resource.putChild("/", child), child)
def test_adds_child(self): resource = Resource() child = Resource() resource.putChild("/", child) self.assertIn("/", resource.children) self.assertIs(resource.children["/"], child)
def test_methods(self): resource = Resource() resource.get = lambda self: None resource.put = lambda self: None self.assertEqual(set(resource.methods()), set(["get", "put"]))
def test_assertion_invalid_child(self): resource = Resource() with self.assertRaises(AssertionError): resource.putChild("/", None)