diff --git a/refstack/api/validators.py b/refstack/api/validators.py index 555fc046..faa032e7 100644 --- a/refstack/api/validators.py +++ b/refstack/api/validators.py @@ -123,6 +123,16 @@ class TestResultValidator(BaseValidator): data_hash.update(request.body.encode('utf-8')) if not signer.verify(data_hash, sign): raise api_exc.ValidationError('Signature verification failed') + if self._is_empty_result(request): + raise api_exc.ValidationError('Uploaded results must contain at ' + 'least one passing test.') + + def _is_empty_result(self, request): + """Check if the test results list is empty.""" + body = json.loads(request.body) + if len(body['results']) != 0: + return False + return True @staticmethod def assert_id(_id): diff --git a/refstack/tests/api/test_api.py b/refstack/tests/api/test_api.py index 2451504c..ba1d0208 100644 --- a/refstack/tests/api/test_api.py +++ b/refstack/tests/api/test_api.py @@ -36,6 +36,13 @@ FAKE_TESTS_RESULT = { ] } +FAKE_JSON_WITH_EMPTY_RESULTS = { + 'cpid': 'foo', + 'duration_seconds': 20, + 'results': [ + ] +} + class TestResultsController(api.FunctionalTest): """Test case for ResultsController.""" @@ -57,6 +64,14 @@ class TestResultsController(api.FunctionalTest): except ValueError: self.fail("actual_response doesn't contain test_id") + def test_post_with_empty_result(self): + """Test results endpoint with empty test results request.""" + results = json.dumps(FAKE_JSON_WITH_EMPTY_RESULTS) + self.assertRaises(webtest.app.AppError, + self.post_json, + self.URL, + params=results) + def test_post_with_invalid_schema(self): """Test post request with invalid schema.""" results = json.dumps({ diff --git a/refstack/tests/unit/test_validators.py b/refstack/tests/unit/test_validators.py index 74f5c526..c3535b61 100644 --- a/refstack/tests/unit/test_validators.py +++ b/refstack/tests/unit/test_validators.py @@ -74,6 +74,13 @@ class TestResultValidatorTestCase(base.BaseTestCase): ] } + FAKE_JSON_WITH_EMPTY_RESULTS = { + 'cpid': 'foo', + 'duration_seconds': 20, + 'results': [ + ] + } + def setUp(self): super(TestResultValidatorTestCase, self).setUp() self.validator = validators.TestResultValidator() @@ -134,6 +141,13 @@ class TestResultValidatorTestCase(base.BaseTestCase): except api_exc.ValidationError as e: self.assertIsInstance(e.exc, jsonschema.ValidationError) + def test_validation_fail_with_empty_result(self): + wrong_request = mock.Mock() + wrong_request.body = json.dumps(self.FAKE_JSON_WITH_EMPTY_RESULTS) + self.assertRaises(api_exc.ValidationError, + self.validator.validate, + wrong_request) + @mock.patch('jsonschema.validate') def test_validation_with_broken_signature(self, mock_validate): if six.PY3: