def setUp(self): self.id_property = model_property.ModelProperty( SubclassOfBaseModel, SubclassOfBaseModel.id) self.ndb_property = model_property.ModelProperty( SubclassOfBaseModel, SubclassOfBaseModel.value) self.ndb_repeated_property = model_property.ModelProperty( RepeatedValueModel, RepeatedValueModel.values)
def __call__(self, model_relationships): """Registers the property relationships of self._model_kind yielded by the generator. See RelationshipsOf's docstring for a usage example. Args: model_relationships: callable. Expected to yield tuples of type (Property, list(class)), where the properties are from the argument provided to the function. Returns: generator. The same object. """ self._validate_name_of_model_relationships(model_relationships) yielded_items = model_relationships(self._model_class) for property_instance, referenced_models in yielded_items: property_of_model = model_property.ModelProperty( self._model_class, property_instance) self._ID_REFERENCING_PROPERTIES[property_of_model].update( self._get_model_kind(m) for m in referenced_models if m is not self._model_class) return model_relationships
def test_hash(self): model_property_set = { model_property.ModelProperty(SubclassOfBaseModel, SubclassOfBaseModel.value), } self.assertIn(self.model_property, model_property_set) self.assertNotIn(self.repeated_model_property, model_property_set)
def test_equality(self): self.assertNotEqual(self.id_property, self.ndb_property) self.assertNotEqual(self.ndb_property, self.ndb_repeated_property) self.assertNotEqual(self.ndb_repeated_property, self.id_property) self.assertEqual( self.id_property, model_property.ModelProperty( SubclassOfBaseModel, SubclassOfBaseModel.id)) self.assertEqual( self.ndb_property, model_property.ModelProperty( SubclassOfBaseModel, SubclassOfBaseModel.value)) self.assertEqual( self.ndb_repeated_property, model_property.ModelProperty( RepeatedValueModel, RepeatedValueModel.values))
def test_hash_of_ndb_repeated_property(self): ndb_repeated_property_set = { model_property.ModelProperty( RepeatedValueModel, RepeatedValueModel.values), } self.assertIn(self.ndb_repeated_property, ndb_repeated_property_set) self.assertNotIn(self.id_property, ndb_repeated_property_set) self.assertNotIn(self.ndb_property, ndb_repeated_property_set)
def test_message(self): error = base_validation_errors.ModelRelationshipError( model_property.ModelProperty(FooModel, FooModel.bar_id), '123', 'BarModel', '123') self.assertEqual( error.stderr, 'ModelRelationshipError in FooModel(id="123"): ' 'FooModel.bar_id="123" should correspond to the ID of an ' 'existing BarModel, but no such model exists')
def test_hash_of_ndb_property(self): ndb_property_set = { model_property.ModelProperty( SubclassOfBaseModel, SubclassOfBaseModel.value), } self.assertIn(self.ndb_property, ndb_property_set) self.assertNotIn(self.id_property, ndb_property_set) self.assertNotIn(self.ndb_repeated_property, ndb_property_set)
def test_message(self): error = audit_errors.ModelRelationshipError( model_property.ModelProperty(FooModel, FooModel.bar_id), '123', 'BarModel', '123') self.assertEqual( error.message, 'ModelRelationshipError in FooModel(id=\'123\'): ' 'FooModel.bar_id=\'123\' should correspond to the ID of an ' 'existing BarModel, but no such model exists')
def get_property_of(self, model_class, property_name): """Helper method to create a ModelProperty. Args: model_class: *. A subclass of BaseModel. property_name: str. The name of the property to get. Returns: ModelProperty. An object that encodes both property and the model it belongs to. """ return model_property.ModelProperty( model_class, getattr(model_class, property_name))
def get_model_kind_references(cls, model_kind, property_name): """Returns the kinds of models referenced by the given property. Args: model_kind: str. The kind of model the property belongs to. property_name: str. The property's name. Returns: list(str). The kinds of models referenced by the given property. """ model_cls = job_utils.get_model_class(model_kind) prop = model_property.ModelProperty(model_cls, getattr(model_cls, property_name)) return cls._ID_REFERENCING_PROPERTIES.get(prop, set())
def test_reports_error_when_id_property_target_does_not_exist(self): self.model_io_stub.put_multi([ # UserEmailPreferencesModel.id -> UserSettingsModel.id. self.create_model(user_models.UserEmailPreferencesModel, id=self.VALID_USER_ID), # UserSettingsModel missing. ]) self.assert_job_output_is([ audit_errors.ModelRelationshipError( model_property.ModelProperty( user_models.UserEmailPreferencesModel, user_models.UserEmailPreferencesModel.id), self.VALID_USER_ID, 'UserSettingsModel', self.VALID_USER_ID), ])
def test_reports_missing_id_property_target_even_if_sibling_property_is_valid(self): # pylint: disable=line-too-long self.put_multi([ self.create_model( auth_models.UserAuthDetailsModel, id=self.VALID_USER_ID, # Value is not None, so UserIdentifiersModel must exist. gae_id='abc', # Value is None, so missing UserIdByFirebaseAuthIdModel is OK. firebase_auth_id=None), self.create_model( auth_models.UserIdentifiersModel, user_id=self.VALID_USER_ID, # Should be gae_id='abc', so error will occur. id='123'), ]) self.assert_job_output_is([ base_validation_errors.ModelRelationshipError( model_property.ModelProperty( auth_models.UserAuthDetailsModel, auth_models.UserAuthDetailsModel.gae_id), self.VALID_USER_ID, 'UserIdentifiersModel', 'abc'), ])
def test_init_raises_value_error_when_property_is_not_in_model(self): with self.assertRaisesRegexp(ValueError, 'not a property of'): model_property.ModelProperty( SubclassOfBaseModel, SubclassOfNdbModel.value)
def test_init_raises_type_error_when_property_is_not_an_ndb_property(self): model = SubclassOfBaseModel(value='123') with self.assertRaisesRegexp(TypeError, 'not an NDB Property'): model_property.ModelProperty(SubclassOfBaseModel, model.value)
def test_init_raises_type_error_when_model_is_unrelated_to_base_model(self): with self.assertRaisesRegexp(TypeError, 'not a subclass of BaseModel'): model_property.ModelProperty( SubclassOfNdbModel, SubclassOfNdbModel.value)
def test_init_raises_type_error_when_model_is_not_a_class(self): model = SubclassOfBaseModel() with self.assertRaisesRegexp(TypeError, 'not a model class'): model_property.ModelProperty(model, SubclassOfBaseModel.value)
def test_init_with_ndb_repeated_property(self): # Does not raise. model_property.ModelProperty( RepeatedValueModel, RepeatedValueModel.values)
def test_init_with_ndb_property(self): # Does not raise. model_property.ModelProperty( SubclassOfBaseModel, SubclassOfBaseModel.value)
def test_equality(self): self.assertNotEqual(self.model_property, self.repeated_model_property) self.assertEqual( self.model_property, model_property.ModelProperty(SubclassOfBaseModel, SubclassOfBaseModel.value))
def test_init_with_base_model_id(self): # Does not raise. model_property.ModelProperty(SubclassOfBaseModel, SubclassOfBaseModel.id)
def test_init_raises_type_error_when_property_is_not_ndb_property(self): with self.assertRaisesRegexp(TypeError, 'not a property'): model_property.ModelProperty(SubclassOfBaseModel, 'value')