Merge "Make middleware enforce and validate content-type"
This commit is contained in:
commit
0e0d96ef71
@ -73,7 +73,6 @@ class BucketsResource(api_base.BaseResource):
|
|||||||
if created_documents:
|
if created_documents:
|
||||||
resp.body = self.view_builder.list(created_documents)
|
resp.body = self.view_builder.list(created_documents)
|
||||||
resp.status = falcon.HTTP_200
|
resp.status = falcon.HTTP_200
|
||||||
resp.append_header('Content-Type', 'application/x-yaml')
|
|
||||||
|
|
||||||
def _prepare_secret_documents(self, secret_documents):
|
def _prepare_secret_documents(self, secret_documents):
|
||||||
# Encrypt data for secret documents, if any.
|
# Encrypt data for secret documents, if any.
|
||||||
|
@ -18,6 +18,7 @@ import falcon
|
|||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_serialization import jsonutils as json
|
from oslo_serialization import jsonutils as json
|
||||||
|
import six
|
||||||
|
|
||||||
import deckhand.context
|
import deckhand.context
|
||||||
from deckhand import errors
|
from deckhand import errors
|
||||||
@ -114,7 +115,26 @@ class YAMLTranslator(HookableMiddlewareMixin, object):
|
|||||||
``falcon`` middleware.
|
``falcon`` middleware.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def process_request(self, req, resp):
|
||||||
|
"""Performs content type enforcement on behalf of REST verbs."""
|
||||||
|
valid_content_types = ['application/x-yaml']
|
||||||
|
content_type = (req.content_type.split(';', 1)[0].strip()
|
||||||
|
if req.content_type else '')
|
||||||
|
|
||||||
|
if not content_type:
|
||||||
|
raise falcon.HTTPMissingHeader('Content-Type')
|
||||||
|
elif content_type not in valid_content_types:
|
||||||
|
message = (
|
||||||
|
"Unexpected content type: {type}. Expected content types "
|
||||||
|
"are: {expected}."
|
||||||
|
).format(
|
||||||
|
type=six.b(req.content_type).decode('utf-8'),
|
||||||
|
expected=valid_content_types
|
||||||
|
)
|
||||||
|
raise falcon.HTTPUnsupportedMediaType(description=message)
|
||||||
|
|
||||||
def process_response(self, req, resp, resource):
|
def process_response(self, req, resp, resource):
|
||||||
|
"""Converts responses to ``application/x-yaml`` content type."""
|
||||||
resp.set_header('Content-Type', 'application/x-yaml')
|
resp.set_header('Content-Type', 'application/x-yaml')
|
||||||
|
|
||||||
for attr in ('body', 'data'):
|
for attr in ('body', 'data'):
|
||||||
|
@ -37,5 +37,4 @@ class RevisionDiffingResource(api_base.BaseResource):
|
|||||||
raise falcon.HTTPNotFound(description=e.format_message())
|
raise falcon.HTTPNotFound(description=e.format_message())
|
||||||
|
|
||||||
resp.status = falcon.HTTP_200
|
resp.status = falcon.HTTP_200
|
||||||
resp.append_header('Content-Type', 'application/x-yaml')
|
|
||||||
resp.body = resp_body
|
resp.body = resp_body
|
||||||
|
@ -61,7 +61,6 @@ class RevisionDocumentsResource(api_base.BaseResource):
|
|||||||
raise falcon.HTTPNotFound(description=e.format_message())
|
raise falcon.HTTPNotFound(description=e.format_message())
|
||||||
|
|
||||||
resp.status = falcon.HTTP_200
|
resp.status = falcon.HTTP_200
|
||||||
resp.append_header('Content-Type', 'application/x-yaml')
|
|
||||||
resp.body = self.view_builder.list(documents)
|
resp.body = self.view_builder.list(documents)
|
||||||
|
|
||||||
|
|
||||||
@ -108,5 +107,4 @@ class RenderedDocumentsResource(api_base.BaseResource):
|
|||||||
rendered_documents = secrets_substitution.substitute_all()
|
rendered_documents = secrets_substitution.substitute_all()
|
||||||
|
|
||||||
resp.status = falcon.HTTP_200
|
resp.status = falcon.HTTP_200
|
||||||
resp.append_header('Content-Type', 'application/x-yaml')
|
|
||||||
resp.body = self.view_builder.list(rendered_documents)
|
resp.body = self.view_builder.list(rendered_documents)
|
||||||
|
@ -51,7 +51,6 @@ class RevisionTagsResource(api_base.BaseResource):
|
|||||||
|
|
||||||
resp_body = revision_tag_view.ViewBuilder().show(resp_tag)
|
resp_body = revision_tag_view.ViewBuilder().show(resp_tag)
|
||||||
resp.status = falcon.HTTP_201
|
resp.status = falcon.HTTP_201
|
||||||
resp.append_header('Content-Type', 'application/x-yaml')
|
|
||||||
resp.body = resp_body
|
resp.body = resp_body
|
||||||
|
|
||||||
def on_get(self, req, resp, revision_id, tag=None):
|
def on_get(self, req, resp, revision_id, tag=None):
|
||||||
@ -72,7 +71,6 @@ class RevisionTagsResource(api_base.BaseResource):
|
|||||||
|
|
||||||
resp_body = revision_tag_view.ViewBuilder().show(resp_tag)
|
resp_body = revision_tag_view.ViewBuilder().show(resp_tag)
|
||||||
resp.status = falcon.HTTP_200
|
resp.status = falcon.HTTP_200
|
||||||
resp.append_header('Content-Type', 'application/x-yaml')
|
|
||||||
resp.body = resp_body
|
resp.body = resp_body
|
||||||
|
|
||||||
@policy.authorize('deckhand:list_tags')
|
@policy.authorize('deckhand:list_tags')
|
||||||
@ -85,7 +83,6 @@ class RevisionTagsResource(api_base.BaseResource):
|
|||||||
|
|
||||||
resp_body = revision_tag_view.ViewBuilder().list(resp_tags)
|
resp_body = revision_tag_view.ViewBuilder().list(resp_tags)
|
||||||
resp.status = falcon.HTTP_200
|
resp.status = falcon.HTTP_200
|
||||||
resp.append_header('Content-Type', 'application/x-yaml')
|
|
||||||
resp.body = resp_body
|
resp.body = resp_body
|
||||||
|
|
||||||
def on_delete(self, req, resp, revision_id, tag=None):
|
def on_delete(self, req, resp, revision_id, tag=None):
|
||||||
@ -104,7 +101,6 @@ class RevisionTagsResource(api_base.BaseResource):
|
|||||||
errors.RevisionTagNotFound) as e:
|
errors.RevisionTagNotFound) as e:
|
||||||
raise falcon.HTTPNotFound(description=e.format_message())
|
raise falcon.HTTPNotFound(description=e.format_message())
|
||||||
|
|
||||||
resp.append_header('Content-Type', 'application/x-yaml')
|
|
||||||
resp.status = falcon.HTTP_204
|
resp.status = falcon.HTTP_204
|
||||||
|
|
||||||
@policy.authorize('deckhand:delete_tags')
|
@policy.authorize('deckhand:delete_tags')
|
||||||
@ -115,5 +111,4 @@ class RevisionTagsResource(api_base.BaseResource):
|
|||||||
except errors.RevisionNotFound as e:
|
except errors.RevisionNotFound as e:
|
||||||
raise falcon.HTTPNotFound(description=e.format_message())
|
raise falcon.HTTPNotFound(description=e.format_message())
|
||||||
|
|
||||||
resp.append_header('Content-Type', 'application/x-yaml')
|
|
||||||
resp.status = falcon.HTTP_204
|
resp.status = falcon.HTTP_204
|
||||||
|
@ -53,7 +53,6 @@ class RevisionsResource(api_base.BaseResource):
|
|||||||
|
|
||||||
revision_resp = self.view_builder.show(revision)
|
revision_resp = self.view_builder.show(revision)
|
||||||
resp.status = falcon.HTTP_200
|
resp.status = falcon.HTTP_200
|
||||||
resp.append_header('Content-Type', 'application/x-yaml')
|
|
||||||
resp.body = revision_resp
|
resp.body = revision_resp
|
||||||
|
|
||||||
@policy.authorize('deckhand:list_revisions')
|
@policy.authorize('deckhand:list_revisions')
|
||||||
@ -63,11 +62,9 @@ class RevisionsResource(api_base.BaseResource):
|
|||||||
revisions_resp = self.view_builder.list(revisions)
|
revisions_resp = self.view_builder.list(revisions)
|
||||||
|
|
||||||
resp.status = falcon.HTTP_200
|
resp.status = falcon.HTTP_200
|
||||||
resp.append_header('Content-Type', 'application/x-yaml')
|
|
||||||
resp.body = revisions_resp
|
resp.body = revisions_resp
|
||||||
|
|
||||||
@policy.authorize('deckhand:delete_revisions')
|
@policy.authorize('deckhand:delete_revisions')
|
||||||
def on_delete(self, req, resp):
|
def on_delete(self, req, resp):
|
||||||
db_api.revision_delete_all()
|
db_api.revision_delete_all()
|
||||||
resp.append_header('Content-Type', 'application/x-yaml')
|
|
||||||
resp.status = falcon.HTTP_204
|
resp.status = falcon.HTTP_204
|
||||||
|
@ -47,5 +47,4 @@ class RollbackResource(api_base.BaseResource):
|
|||||||
|
|
||||||
revision_resp = self.view_builder.show(rollback_revision)
|
revision_resp = self.view_builder.show(rollback_revision)
|
||||||
resp.status = falcon.HTTP_201
|
resp.status = falcon.HTTP_201
|
||||||
resp.append_header('Content-Type', 'application/x-yaml')
|
|
||||||
resp.body = revision_resp
|
resp.body = revision_resp
|
||||||
|
@ -20,11 +20,10 @@ from deckhand.control import base as api_base
|
|||||||
class VersionsResource(api_base.BaseResource):
|
class VersionsResource(api_base.BaseResource):
|
||||||
|
|
||||||
def on_get(self, req, resp):
|
def on_get(self, req, resp):
|
||||||
resp.body = self.to_yaml_body({
|
resp.body = {
|
||||||
'v1.0': {
|
'v1.0': {
|
||||||
'path': '/api/v1.0',
|
'path': '/api/v1.0',
|
||||||
'status': 'stable'
|
'status': 'stable'
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
resp.append_header('Content-Type', 'application/x-yaml')
|
|
||||||
resp.status = falcon.HTTP_200
|
resp.status = falcon.HTTP_200
|
||||||
|
@ -40,8 +40,10 @@ class TestBucketsController(test_base.BaseControllerTest):
|
|||||||
}
|
}
|
||||||
payload = documents_factory.gen_test(document_mapping)
|
payload = documents_factory.gen_test(document_mapping)
|
||||||
|
|
||||||
resp = self.app.simulate_put('/api/v1.0/bucket/mop/documents',
|
resp = self.app.simulate_put(
|
||||||
body=yaml.safe_dump_all(payload))
|
'/api/v1.0/bucket/mop/documents',
|
||||||
|
headers={'Content-Type': 'application/x-yaml'},
|
||||||
|
body=yaml.safe_dump_all(payload))
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
created_documents = list(yaml.safe_load_all(resp.text))
|
created_documents = list(yaml.safe_load_all(resp.text))
|
||||||
self.assertEqual(3, len(created_documents))
|
self.assertEqual(3, len(created_documents))
|
||||||
@ -53,8 +55,10 @@ class TestBucketsController(test_base.BaseControllerTest):
|
|||||||
|
|
||||||
def test_put_bucket_with_secret(self):
|
def test_put_bucket_with_secret(self):
|
||||||
def _do_test(payload):
|
def _do_test(payload):
|
||||||
resp = self.app.simulate_put('/api/v1.0/bucket/mop/documents',
|
resp = self.app.simulate_put(
|
||||||
body=yaml.safe_dump_all(payload))
|
'/api/v1.0/bucket/mop/documents',
|
||||||
|
headers={'Content-Type': 'application/x-yaml'},
|
||||||
|
body=yaml.safe_dump_all(payload))
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
created_documents = list(yaml.safe_load_all(resp.text))
|
created_documents = list(yaml.safe_load_all(resp.text))
|
||||||
self.assertEqual(1, len(created_documents))
|
self.assertEqual(1, len(created_documents))
|
||||||
@ -123,8 +127,10 @@ schema:
|
|||||||
'.*mapping values are not allowed here.*']
|
'.*mapping values are not allowed here.*']
|
||||||
|
|
||||||
for idx, payload in enumerate(invalid_payloads):
|
for idx, payload in enumerate(invalid_payloads):
|
||||||
resp = self.app.simulate_put('/api/v1.0/bucket/mop/documents',
|
resp = self.app.simulate_put(
|
||||||
body=payload)
|
'/api/v1.0/bucket/mop/documents',
|
||||||
|
headers={'Content-Type': 'application/x-yaml'},
|
||||||
|
body=payload)
|
||||||
self.assertEqual(400, resp.status_code)
|
self.assertEqual(400, resp.status_code)
|
||||||
self.assertRegexpMatches(resp.text, error_re[idx])
|
self.assertRegexpMatches(resp.text, error_re[idx])
|
||||||
|
|
||||||
@ -141,8 +147,10 @@ class TestBucketsControllerNegativeRBAC(test_base.BaseControllerTest):
|
|||||||
documents_factory = factories.DocumentFactory(2, [1, 1])
|
documents_factory = factories.DocumentFactory(2, [1, 1])
|
||||||
payload = documents_factory.gen_test({})
|
payload = documents_factory.gen_test({})
|
||||||
|
|
||||||
resp = self.app.simulate_put('/api/v1.0/bucket/mop/documents',
|
resp = self.app.simulate_put(
|
||||||
body=yaml.safe_dump_all(payload))
|
'/api/v1.0/bucket/mop/documents',
|
||||||
|
headers={'Content-Type': 'application/x-yaml'},
|
||||||
|
body=yaml.safe_dump_all(payload))
|
||||||
self.assertEqual(403, resp.status_code)
|
self.assertEqual(403, resp.status_code)
|
||||||
|
|
||||||
def test_put_bucket_cleartext_secret_except_forbidden(self):
|
def test_put_bucket_cleartext_secret_except_forbidden(self):
|
||||||
@ -152,8 +160,10 @@ class TestBucketsControllerNegativeRBAC(test_base.BaseControllerTest):
|
|||||||
secrets_factory = factories.DocumentSecretFactory()
|
secrets_factory = factories.DocumentSecretFactory()
|
||||||
payload = [secrets_factory.gen_test('Certificate', 'cleartext')]
|
payload = [secrets_factory.gen_test('Certificate', 'cleartext')]
|
||||||
|
|
||||||
resp = self.app.simulate_put('/api/v1.0/bucket/mop/documents',
|
resp = self.app.simulate_put(
|
||||||
body=yaml.safe_dump_all(payload))
|
'/api/v1.0/bucket/mop/documents',
|
||||||
|
headers={'Content-Type': 'application/x-yaml'},
|
||||||
|
body=yaml.safe_dump_all(payload))
|
||||||
self.assertEqual(403, resp.status_code)
|
self.assertEqual(403, resp.status_code)
|
||||||
|
|
||||||
def test_put_bucket_encrypted_secret_except_forbidden(self):
|
def test_put_bucket_encrypted_secret_except_forbidden(self):
|
||||||
@ -163,6 +173,8 @@ class TestBucketsControllerNegativeRBAC(test_base.BaseControllerTest):
|
|||||||
secrets_factory = factories.DocumentSecretFactory()
|
secrets_factory = factories.DocumentSecretFactory()
|
||||||
payload = [secrets_factory.gen_test('Certificate', 'encrypted')]
|
payload = [secrets_factory.gen_test('Certificate', 'encrypted')]
|
||||||
|
|
||||||
resp = self.app.simulate_put('/api/v1.0/bucket/mop/documents',
|
resp = self.app.simulate_put(
|
||||||
body=yaml.safe_dump_all(payload))
|
'/api/v1.0/bucket/mop/documents',
|
||||||
|
headers={'Content-Type': 'application/x-yaml'},
|
||||||
|
body=yaml.safe_dump_all(payload))
|
||||||
self.assertEqual(403, resp.status_code)
|
self.assertEqual(403, resp.status_code)
|
||||||
|
73
deckhand/tests/unit/control/test_middleware.py
Normal file
73
deckhand/tests/unit/control/test_middleware.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
from deckhand.tests.unit.control import base as test_base
|
||||||
|
|
||||||
|
|
||||||
|
class TestYAMLTranslator(test_base.BaseControllerTest):
|
||||||
|
|
||||||
|
def test_request_with_correct_content_type(self):
|
||||||
|
resp = self.app.simulate_get(
|
||||||
|
'/versions', headers={'Content-Type': 'application/x-yaml'})
|
||||||
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
|
def test_request_with_correct_content_type_plus_encoding(self):
|
||||||
|
resp = self.app.simulate_get(
|
||||||
|
'/versions',
|
||||||
|
headers={'Content-Type': 'application/x-yaml;encoding=utf-8'})
|
||||||
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
|
|
||||||
|
class TestYAMLTranslatorNegative(test_base.BaseControllerTest):
|
||||||
|
|
||||||
|
def test_request_without_content_type_raises_exception(self):
|
||||||
|
resp = self.app.simulate_get('/versions')
|
||||||
|
self.assertEqual(400, resp.status_code)
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
'description': 'The Content-Type header is required.',
|
||||||
|
'title': 'Missing header value'
|
||||||
|
}
|
||||||
|
self.assertEqual(expected, yaml.safe_load(resp.content))
|
||||||
|
|
||||||
|
def test_request_with_invalid_content_type_raises_exception(self):
|
||||||
|
resp = self.app.simulate_get(
|
||||||
|
'/versions', headers={'Content-Type': 'application/json'})
|
||||||
|
self.assertEqual(415, resp.status_code)
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
'description': "Unexpected content type: application/json. "
|
||||||
|
"Expected content types are: "
|
||||||
|
"['application/x-yaml'].",
|
||||||
|
'title': 'Unsupported media type'
|
||||||
|
}
|
||||||
|
self.assertEqual(expected, yaml.safe_load(resp.content))
|
||||||
|
|
||||||
|
def test_request_with_invalid_yaml_content_type_raises_exception(self):
|
||||||
|
"""Only application/x-yaml should be supported, not application/yaml,
|
||||||
|
because it hasn't been registered as an official MIME type yet.
|
||||||
|
"""
|
||||||
|
resp = self.app.simulate_get(
|
||||||
|
'/versions', headers={'Content-Type': 'application/yaml'})
|
||||||
|
self.assertEqual(415, resp.status_code)
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
'description': "Unexpected content type: application/yaml. "
|
||||||
|
"Expected content types are: "
|
||||||
|
"['application/x-yaml'].",
|
||||||
|
'title': 'Unsupported media type'
|
||||||
|
}
|
||||||
|
self.assertEqual(expected, yaml.safe_load(resp.content))
|
@ -61,8 +61,10 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
if not payload:
|
if not payload:
|
||||||
documents_factory = factories.DocumentFactory(2, [1, 1])
|
documents_factory = factories.DocumentFactory(2, [1, 1])
|
||||||
payload = documents_factory.gen_test({})
|
payload = documents_factory.gen_test({})
|
||||||
resp = self.app.simulate_put('/api/v1.0/bucket/mop/documents',
|
resp = self.app.simulate_put(
|
||||||
body=yaml.safe_dump_all(payload))
|
'/api/v1.0/bucket/mop/documents',
|
||||||
|
headers={'Content-Type': 'application/x-yaml'},
|
||||||
|
body=yaml.safe_dump_all(payload))
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
revision_id = list(yaml.safe_load_all(resp.text))[0]['status'][
|
revision_id = list(yaml.safe_load_all(resp.text))[0]['status'][
|
||||||
'revision']
|
'revision']
|
||||||
@ -72,7 +74,7 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
resp = self.app.simulate_post(
|
resp = self.app.simulate_post(
|
||||||
'/api/v1.0/revisions/%s/validations/%s' % (revision_id,
|
'/api/v1.0/revisions/%s/validations/%s' % (revision_id,
|
||||||
validation_name),
|
validation_name),
|
||||||
body=policy)
|
headers={'Content-Type': 'application/x-yaml'}, body=policy)
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
def test_create_validation(self):
|
def test_create_validation(self):
|
||||||
@ -103,7 +105,8 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
revision_id = self._create_revision()
|
revision_id = self._create_revision()
|
||||||
|
|
||||||
resp = self.app.simulate_get(
|
resp = self.app.simulate_get(
|
||||||
'/api/v1.0/revisions/%s/validations' % revision_id)
|
'/api/v1.0/revisions/%s/validations' % revision_id,
|
||||||
|
headers={'Content-Type': 'application/x-yaml'})
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
# Validate that the internal deckhand validation was created already.
|
# Validate that the internal deckhand validation was created already.
|
||||||
@ -132,7 +135,8 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
VALIDATION_RESULT)
|
VALIDATION_RESULT)
|
||||||
|
|
||||||
resp = self.app.simulate_get(
|
resp = self.app.simulate_get(
|
||||||
'/api/v1.0/revisions/%s/validations' % revision_id)
|
'/api/v1.0/revisions/%s/validations' % revision_id,
|
||||||
|
headers={'Content-Type': 'application/x-yaml'})
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
body = yaml.safe_load(resp.text)
|
body = yaml.safe_load(resp.text)
|
||||||
@ -164,7 +168,8 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
# /api/v1.0/revisions/1/validations/deckhand-schema-validation
|
# /api/v1.0/revisions/1/validations/deckhand-schema-validation
|
||||||
resp = self.app.simulate_get(
|
resp = self.app.simulate_get(
|
||||||
'/api/v1.0/revisions/%s/validations/%s' % (
|
'/api/v1.0/revisions/%s/validations/%s' % (
|
||||||
revision_id, types.DECKHAND_SCHEMA_VALIDATION))
|
revision_id, types.DECKHAND_SCHEMA_VALIDATION),
|
||||||
|
headers={'Content-Type': 'application/x-yaml'})
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
body = yaml.safe_load(resp.text)
|
body = yaml.safe_load(resp.text)
|
||||||
expected_body = {
|
expected_body = {
|
||||||
@ -181,7 +186,8 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
# Validate that the entry is present.
|
# Validate that the entry is present.
|
||||||
resp = self.app.simulate_get(
|
resp = self.app.simulate_get(
|
||||||
'/api/v1.0/revisions/%s/validations/%s' % (revision_id,
|
'/api/v1.0/revisions/%s/validations/%s' % (revision_id,
|
||||||
validation_name))
|
validation_name),
|
||||||
|
headers={'Content-Type': 'application/x-yaml'})
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
body = yaml.safe_load(resp.text)
|
body = yaml.safe_load(resp.text)
|
||||||
@ -207,7 +213,8 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
# Validate that the entry is present.
|
# Validate that the entry is present.
|
||||||
resp = self.app.simulate_get(
|
resp = self.app.simulate_get(
|
||||||
'/api/v1.0/revisions/%s/validations/%s' % (revision_id,
|
'/api/v1.0/revisions/%s/validations/%s' % (revision_id,
|
||||||
validation_name))
|
validation_name),
|
||||||
|
headers={'Content-Type': 'application/x-yaml'})
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
body = yaml.safe_load(resp.text)
|
body = yaml.safe_load(resp.text)
|
||||||
@ -224,7 +231,8 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
# Validate that 2 entries now exist.
|
# Validate that 2 entries now exist.
|
||||||
resp = self.app.simulate_get(
|
resp = self.app.simulate_get(
|
||||||
'/api/v1.0/revisions/%s/validations/%s' % (revision_id,
|
'/api/v1.0/revisions/%s/validations/%s' % (revision_id,
|
||||||
validation_name))
|
validation_name),
|
||||||
|
headers={'Content-Type': 'application/x-yaml'})
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
body = yaml.safe_load(resp.text)
|
body = yaml.safe_load(resp.text)
|
||||||
expected_body = {
|
expected_body = {
|
||||||
@ -250,7 +258,8 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
|
|
||||||
resp = self.app.simulate_get(
|
resp = self.app.simulate_get(
|
||||||
'/api/v1.0/revisions/%s/validations/%s' % (revision_id,
|
'/api/v1.0/revisions/%s/validations/%s' % (revision_id,
|
||||||
validation_name))
|
validation_name),
|
||||||
|
headers={'Content-Type': 'application/x-yaml'})
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
body = yaml.safe_load(resp.text)
|
body = yaml.safe_load(resp.text)
|
||||||
@ -275,7 +284,8 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
|
|
||||||
resp = self.app.simulate_get(
|
resp = self.app.simulate_get(
|
||||||
'/api/v1.0/revisions/%s/validations/%s/0' % (revision_id,
|
'/api/v1.0/revisions/%s/validations/%s/0' % (revision_id,
|
||||||
validation_name))
|
validation_name),
|
||||||
|
headers={'Content-Type': 'application/x-yaml'})
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
body = yaml.safe_load(resp.text)
|
body = yaml.safe_load(resp.text)
|
||||||
@ -329,7 +339,8 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
|
|
||||||
# Validate that the internal deckhand validation was created.
|
# Validate that the internal deckhand validation was created.
|
||||||
resp = self.app.simulate_get(
|
resp = self.app.simulate_get(
|
||||||
'/api/v1.0/revisions/%s/validations' % revision_id)
|
'/api/v1.0/revisions/%s/validations' % revision_id,
|
||||||
|
headers={'Content-Type': 'application/x-yaml'})
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
body = yaml.safe_load(resp.text)
|
body = yaml.safe_load(resp.text)
|
||||||
expected_body = {
|
expected_body = {
|
||||||
@ -353,7 +364,8 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
|
|
||||||
# Validate that the validation was created and passed.
|
# Validate that the validation was created and passed.
|
||||||
resp = self.app.simulate_get(
|
resp = self.app.simulate_get(
|
||||||
'/api/v1.0/revisions/%s/validations' % revision_id)
|
'/api/v1.0/revisions/%s/validations' % revision_id,
|
||||||
|
headers={'Content-Type': 'application/x-yaml'})
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
body = yaml.safe_load(resp.text)
|
body = yaml.safe_load(resp.text)
|
||||||
expected_body = {
|
expected_body = {
|
||||||
@ -390,7 +402,8 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
|
|
||||||
# Validate that the internal deckhand validation was created.
|
# Validate that the internal deckhand validation was created.
|
||||||
resp = self.app.simulate_get(
|
resp = self.app.simulate_get(
|
||||||
'/api/v1.0/revisions/%s/validations' % revision_id)
|
'/api/v1.0/revisions/%s/validations' % revision_id,
|
||||||
|
headers={'Content-Type': 'application/x-yaml'})
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
body = yaml.safe_load(resp.text)
|
body = yaml.safe_load(resp.text)
|
||||||
expected_body = {
|
expected_body = {
|
||||||
@ -414,7 +427,8 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
|
|
||||||
# Validate that the validation was created and reports failure.
|
# Validate that the validation was created and reports failure.
|
||||||
resp = self.app.simulate_get(
|
resp = self.app.simulate_get(
|
||||||
'/api/v1.0/revisions/%s/validations' % revision_id)
|
'/api/v1.0/revisions/%s/validations' % revision_id,
|
||||||
|
headers={'Content-Type': 'application/x-yaml'})
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
body = yaml.safe_load(resp.text)
|
body = yaml.safe_load(resp.text)
|
||||||
expected_body = {
|
expected_body = {
|
||||||
@ -451,7 +465,8 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
|
|
||||||
# Validate that the internal deckhand validation was created.
|
# Validate that the internal deckhand validation was created.
|
||||||
resp = self.app.simulate_get(
|
resp = self.app.simulate_get(
|
||||||
'/api/v1.0/revisions/%s/validations' % revision_id)
|
'/api/v1.0/revisions/%s/validations' % revision_id,
|
||||||
|
headers={'Content-Type': 'application/x-yaml'})
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
body = yaml.safe_load(resp.text)
|
body = yaml.safe_load(resp.text)
|
||||||
expected_body = {
|
expected_body = {
|
||||||
@ -478,7 +493,8 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
# Validate that the validation reports failure since `fail_doc`
|
# Validate that the validation reports failure since `fail_doc`
|
||||||
# should've failed validation.
|
# should've failed validation.
|
||||||
resp = self.app.simulate_get(
|
resp = self.app.simulate_get(
|
||||||
'/api/v1.0/revisions/%s/validations' % revision_id)
|
'/api/v1.0/revisions/%s/validations' % revision_id,
|
||||||
|
headers={'Content-Type': 'application/x-yaml'})
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
body = yaml.safe_load(resp.text)
|
body = yaml.safe_load(resp.text)
|
||||||
expected_body = {
|
expected_body = {
|
||||||
@ -509,7 +525,8 @@ class TestValidationsController(test_base.BaseControllerTest):
|
|||||||
# Validate that the entry is present.
|
# Validate that the entry is present.
|
||||||
resp = self.app.simulate_get(
|
resp = self.app.simulate_get(
|
||||||
'/api/v1.0/revisions/%s/validations/%s' % (
|
'/api/v1.0/revisions/%s/validations/%s' % (
|
||||||
revision_id, types.DECKHAND_SCHEMA_VALIDATION))
|
revision_id, types.DECKHAND_SCHEMA_VALIDATION),
|
||||||
|
headers={'Content-Type': 'application/x-yaml'})
|
||||||
self.assertEqual(200, resp.status_code)
|
self.assertEqual(200, resp.status_code)
|
||||||
|
|
||||||
body = yaml.safe_load(resp.text)
|
body = yaml.safe_load(resp.text)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user