def test_out_of_regex(self): """An expiration_date in the past should make it sad.""" request = mock.Mock() request.errors = Errors() request.validated = { 'eol': date(3120, 11, 5)} validators.validate_eol_date(request) assert request.errors == [ {'location': 'body', 'name': 'eol', 'description': 'End-of-life date may not be in the right range of years (2000-2100)'} ] assert request.errors.status == exceptions.HTTPBadRequest.code
def test_length_above_range(self): """We don't allow too verbose notes.""" request = mock.Mock() request.errors = Errors() request.validated = { 'notes': 'n' * 2001} validators.validate_override_notes(request) assert request.errors == [ {'location': 'body', 'name': 'notes', 'description': 'Notes may not contain more than 2000 chars'} ] assert request.errors.status == exceptions.HTTPBadRequest.code
def test_higherthanLimit(self): """An expiration_date higher than limit should report an error.""" request = mock.Mock() request.errors = Errors() request.validated = { 'expiration_date': datetime.utcnow() + timedelta(days=32)} validators.validate_expiration_date(request) assert request.errors == [ {'location': 'body', 'name': 'expiration_date', 'description': 'Expiration date may not be longer than 31'} ] assert request.errors.status == exceptions.HTTPBadRequest.code
def test_extra_params_qs_strict(self): schema = CorniceSchema.from_colander(StrictQsSchema) dummy_request = MockRequest('', {'foo': 'test', 'bar': 'test'}) setattr(dummy_request, 'errors', Errors(dummy_request)) validate_colander_schema(schema, dummy_request) errors = dummy_request.errors self.assertEqual(len(errors), 1) self.assertEqual(errors[0], {'description': 'bar is not allowed', 'location': 'querystring', 'name': 'bar'}) expected = {'foo': 'test'} self.assertEqual(expected, dummy_request.validated)
def __init__(self, real_request): """ Initialize the object to look a lot like the real_request, but hiding the errors. Args: real_request (pyramid.request.Request): The request we are trying to mimic, while hiding its errors. """ # Hide errors added to this from the real request self.errors = Errors() # But proxy other attributes to the real request self.real_request = real_request for attr in ['db', 'registry', 'validated', 'buildinfo', 'user']: setattr(self, attr, getattr(self.real_request, attr))
def test_update_found_but_not_update_object(self, mock_update_get): """It should 404 if the update not none, but is not an Update""" request = mock.Mock() request.errors = Errors() request.validated = {'testcase_feedback': [{'testcase_name': 'invalid'}], 'update': 'FEDORA-2020-abcdef1231'} mock_update_get.return_value = models.Update.query.first() validators.validate_testcase_feedback(request) assert request.errors == [ {'location': 'querystring', 'name': 'testcase_feedback', 'description': 'Invalid testcase names specified: invalid'} ] assert request.errors.status == exceptions.HTTPBadRequest.code
def test_past(self): """An expiration_date in the past should make it sad.""" request = mock.Mock() request.errors = Errors() request.validated = { 'expiration_date': datetime.utcnow() - timedelta(days=1)} validators.validate_expiration_date(request) assert request.errors == [ {'location': 'body', 'name': 'expiration_date', 'description': 'Expiration date in the past'} ] assert request.errors.status == exceptions.HTTPBadRequest.code
def test_invalid(self): """An invalid comment_id should add an error to the request.""" request = mock.Mock() request.errors = Errors() request.matchdict = {'id': '42'} validators.validate_comment_id(request) assert request.errors == [{ 'location': 'url', 'name': 'id', 'description': 'Invalid comment id' }] assert request.errors.status == exceptions.HTTPNotFound.code
def test_invalid(self): """An invalid release should add an error to the request.""" request = mock.Mock() request.db = self.db request.errors = Errors() request.validated = {'release': 'invalid'} validators.validate_release(request) assert request.errors == [ {'location': 'querystring', 'name': 'release', 'description': 'Invalid release specified: invalid'} ] assert request.errors.status == exceptions.HTTPBadRequest.code
def test_no_nvrs_given(self): """If the request has no nvrs, it should add an error to the request.""" request = mock.Mock() request.db = self.db request.errors = Errors() request.validated = {'nvr': ''} validators.validate_override_builds(request) assert request.errors == [ {'location': 'body', 'name': 'nvr', 'description': 'A comma-separated list of NVRs is required.'} ] assert request.errors.status == exceptions.HTTPBadRequest.code
def test_validate_associations_invalid_type(self): associations_in = { 'users': [{ 'document_id': self.user_profile1.document_id, 'is_parent': True }] } errors = Errors() associations = _validate_associations(associations_in, WAYPOINT_TYPE, errors) # users are ignored for waypoints self.assertEquals(associations, {})
def wrap_request(event): """Adds a "validated" dict, a custom "errors" object and an "info" dict to the request object if they don't already exists """ request = event.request request.add_response_callback(apply_filters) if not hasattr(request, 'validated'): setattr(request, 'validated', {}) if not hasattr(request, 'errors'): setattr(request, 'errors', Errors(request)) if not hasattr(request, 'info'): setattr(request, 'info', {})
def test_invalid(self): """An invalid testcase should add an error to the request.""" request = mock.Mock() request.db = self.db request.errors = Errors() request.validated = {'testcase_feedback': [{'testcase_name': 'invalid'}], 'update': models.Update.query.first()} validators.validate_testcase_feedback(request) assert request.errors == [ {'location': 'querystring', 'name': 'testcase_feedback', 'description': 'Invalid testcase names specified: invalid'} ] assert request.errors.status == exceptions.HTTPBadRequest.code
def test_invalid_nvrs_given(self): """If the request has invalid nvrs, it should add an error to the request.""" request = mock.Mock() request.db = self.db request.errors = Errors() request.koji.listTags.return_value = [{'name': 'invalid'}] request.validated = {'nvr': 'invalid'} validators.validate_override_builds(request) assert request.errors == [ {'location': 'body', 'name': 'nvr', 'description': 'Invalid build'} ] assert request.errors.status == exceptions.HTTPBadRequest.code
def get_mock_request(self): """ A helper function that creates a mock request. :return: a Mock object representing a request """ update = self.db.query( models.Update).filter_by(title=u'bodhi-2.0-1.fc17').one() user = self.db.query(models.User).filter_by(id=1).one() mock_request = mock.Mock() mock_request.user = user mock_request.db = self.db mock_request.errors = Errors() mock_request.validated = {'update': update} mock_request.buildinfo = {'bodhi-2.0-1.fc17': {}} return mock_request
def test_no_release(self): """If a build does not have a Release, the validator should set one.""" release = models.Release.query.first() request = mock.Mock() request.db = self.db request.errors = Errors() request.koji.listTags.return_value = [{'name': release.candidate_tag}] build = models.Build.query.first() build.release = None self.db.commit() validators._validate_override_build(request, build.nvr, self.db) self.assertEqual(len(request.errors), 0) build = models.Build.query.filter_by(nvr=build.nvr).one() self.assertEqual(build.release.name, release.name)
def test_collection_post_error(self, mock_method): mock_method.side_effect = GitCommandError('git clone', 'Boom!', stderr='mocked response') request = testing.DummyRequest({}) request.validated = { 'repo_url': 'git://example.org/bar.git', 'repo_name': None } request.errors = Errors() resource = RepositoryResource(request) resource.collection_post() [error] = request.errors self.assertEqual(error['location'], 'body') self.assertEqual(error['name'], 'repo_url') self.assertEqual(error['description'], 'mocked response')
def test_no_build_exception(self): """Assert exception handling when the build is not found and koji is unavailable.""" request = mock.Mock() request.db = self.db request.errors = Errors() request.koji.listTags.side_effect = IOError('You forgot to pay your ISP.') request.validated = {'edited': None} validators._validate_override_build(request, 'does not exist', self.db) assert request.errors == [ {'location': 'body', 'name': 'nvr', 'description': ("Couldn't determine koji tags for does not exist, 'You forgot to pay " "your ISP.'")} ] assert request.errors.status == exceptions.HTTPBadRequest.code
def get_dummy_json_put_request(self, data, schema=None): ''' Useful method, returns a typical put request ''' request = self.get_dummy_request() request.method = 'PUT' request.errors = Errors() if schema: if isinstance(data['_id'], basestring): data['_id'] = ObjectId(data['_id']) request.validated = schema().serialize(data) request.validated['_id'] = ObjectId(request.validated['_id']) data['_id'] = unicode(data['_id']) request.json = json.dumps(data) request.path = '/api/%ss/%s/' % (data['type'], data['_id']) return request
def test_no_value(self): """Assert that an error is added to the request if the captcha value is missing.""" request = mock.Mock() request.errors = Errors() request.user = None request.validated = {'captcha_key': 'some_key'} validators.validate_captcha(request) self.assertEqual(request.errors, [{ 'location': 'body', 'name': 'captcha_value', 'description': 'You must provide a captcha_value.' }]) self.assertEqual(request.errors.status, exceptions.HTTPBadRequest.code)
def test_error_handler(self): errors = Errors(403) errors.add('body', 'data', "Can't update resource in current (draft) status") request = mock.MagicMock() request.matchdict = {'a': 'b'} request.errors = errors response = error_handler(request) self.assertEqual( response.body, '{"status": "error", "errors": [{"location": "body", "name": "data", "description": "Can\'t update resource in current (draft) status"}]}' ) self.assertEqual(response.content_type, 'application/json') self.assertEqual(response.status, '403 Forbidden')
def test_colander_strict_schema(self): schema = CorniceSchema.from_colander(StrictSchema) dummy_request = MockRequest('''{"bar": "required_data", "foo": "optional_data", "other": "not_wanted_data"}''') setattr(dummy_request, 'errors', Errors(dummy_request)) validate_colander_schema(schema, dummy_request) errors = dummy_request.errors self.assertEqual(len(errors), 1) self.assertEqual(errors[0], {'description': 'other is not allowed', 'location': 'body', 'name': 'other'}) self.assertIn('foo', dummy_request.validated) self.assertIn('bar', dummy_request.validated)
def validate_associations_in(associations_in, document_type, errors): """Validate the provided associations: - Check that the linked documents exist. - Check that the linked documents have the right document type (e.g. a document listed as route association must really be a route). - Check that only valid association combinations are given. Returns the validated associations. """ new_errors = Errors() associations = {} _add_associations(associations, associations_in, document_type, 'users', USERPROFILE_TYPE, new_errors) _add_associations(associations, associations_in, document_type, 'routes', ROUTE_TYPE, new_errors) _add_associations(associations, associations_in, document_type, 'waypoints', WAYPOINT_TYPE, new_errors) _add_associations(associations, associations_in, document_type, 'images', IMAGE_TYPE, new_errors) _add_associations(associations, associations_in, document_type, 'articles', ARTICLE_TYPE, new_errors) _add_associations(associations, associations_in, document_type, 'waypoint_children', WAYPOINT_TYPE, new_errors) _add_associations(associations, associations_in, document_type, 'areas', AREA_TYPE, new_errors) _add_associations(associations, associations_in, document_type, 'outings', OUTING_TYPE, new_errors) _add_associations(associations, associations_in, document_type, 'books', BOOK_TYPE, new_errors) _add_associations(associations, associations_in, document_type, 'xreports', XREPORT_TYPE, new_errors) if new_errors: errors.extend(new_errors) return None _check_for_valid_documents_ids(associations, new_errors) if new_errors: errors.extend(new_errors) return None else: return associations
def test_captcha_validate_success(self): """Assert an error when the captcha fails validation.""" request = mock.Mock() request.errors = Errors() request.errors.status = None request.registry.settings = validators.config request.user = None # We'll cheat since we know the captcha.secret and figure out the solution. plainkey, value = captcha.math_generator(None, validators.config) cipherkey = captcha.encrypt(plainkey, validators.config) request.session = {'captcha': cipherkey} request.validated = {'captcha_key': cipherkey, 'captcha_value': value} validators.validate_captcha(request) self.assertEqual(request.errors, []) self.assertEqual(request.errors.status, None) self.assertTrue('captcha' not in request.session)
def test_test_gating_status_is_failed(self): """If a build's test gating status is failed, the validator should complain.""" request = mock.Mock() request.db = self.db request.errors = Errors() request.validated = {'edited': None} build = models.Build.query.first() build.update.test_gating_status = models.TestGatingStatus.failed self.db.commit() validators._validate_override_build(request, build.nvr, self.db) assert request.errors == [ {'location': 'body', 'name': 'nvr', 'description': "Cannot create a buildroot override if build's " "test gating status is failed."} ] assert request.errors.status == exceptions.HTTPBadRequest.code
def test_validate_associations_invalid_document_type(self): associations_in = { 'routes': [{ 'document_id': self.waypoint1.document_id }] } errors = Errors() associations = _validate_associations(associations_in, ROUTE_TYPE, errors) self.assertIsNone(associations) self.assertEquals(len(errors), 1) error = errors[0] self.assertEqual(error['name'], 'associations.routes') self.assertEqual( error['description'], 'document "' + str(self.waypoint1.document_id) + '" is not of type "r"')
def test_wrong_tag(self, get_session): """If a build does not have a candidate or testing tag, the validator should complain.""" release = models.Release.query.first() request = mock.Mock() request.db = self.db request.errors = Errors() request.koji.listTags.return_value = [{'name': release.stable_tag}] request.validated = {'edited': None} get_session.return_value.listTags.return_value = request.koji.listTags.return_value build = models.Build.query.first() validators._validate_override_build(request, build.nvr, self.db) assert request.errors == [ {'location': 'body', 'name': 'nvr', 'description': "Invalid build. It must be tagged as either candidate or testing."} ] assert request.errors.status == exceptions.HTTPBadRequest.code
def setUp(self): self.workspace = self.mk_workspace() schema_string = serialize(TestPerson) schema = json.loads(schema_string) self.workspace.sm.store_data( os.path.join( '_schemas', '%(namespace)s.%(name)s.avsc' % schema), schema_string, 'Writing the schema.') self.person = TestPerson({'name': 'Foo', 'age': 1}) self.request = testing.DummyRequest() self.request.errors = Errors() self.config = testing.setUp( settings={ 'repo.storage_path': self.WORKING_DIR, }, request=self.request)
def test_update_not_found(self): """It should 404 if the update is not found.""" request = mock.Mock() request.errors = Errors() request.validated = { 'testcase_feedback': [{ 'testcase_name': 'invalid' }], 'update': None } validators.validate_testcase_feedback(request) assert request.errors == [{ 'location': 'url', 'name': 'id', 'description': 'Invalid update' }] assert request.errors.status == exceptions.HTTPNotFound.code
def test_colander_nested_schema(self): schema = CorniceSchema.from_colander(NestedSchema) dummy_request = MockRequest('{"ham": {"bar": "POST"}}', {'egg.bar': 'GET'}) setattr(dummy_request, 'errors', Errors(dummy_request)) validate_colander_schema(schema, dummy_request) qs_fields = schema.get_attributes(location="querystring") errors = dummy_request.errors self.assertEqual(len(errors), 0, errors) self.assertEqual(len(qs_fields), 1) expected = {'egg': {'bar': 'GET'}, 'ham': {'bar': 'POST'}, } self.assertEqual(expected, dummy_request.validated)