def test_only_one_api_provided(self): router = RestModelRouter() DB = copy.deepcopy(settings.DATABASES) del DB['api2'] del DB['apifail'] router.databases = DB self.assertEqual(router.api_database_name, 'api')
def test_no_api_provided(self): router = RestModelRouter() DB = copy.deepcopy(settings.DATABASES) del DB['api2'] del DB['api'] del DB['apifail'] router.databases = DB self.assertRaises(ImproperlyConfigured, getattr, router, "api_database_name")
def test_api_db_not_provided(self): with self.modify_settings(INSTALLED_APPS={'append': "testappsimple"}): from testappsimple.models import ModelA self.assertIn('api2', settings.DATABASES) self.assertRaises(ImproperlyConfigured, ModelA.objects.all().count) router = RestModelRouter() self.assertRaises(ImproperlyConfigured, getattr, router, "api_database_name")
def test_allow_migration(self): router = RestModelRouter() self.assertFalse(router.allow_migrate('api', 'testapp', 'Pizza')) # api model on api db self.assertFalse(router.allow_migrate('api2', 'testapp', 'Pizza')) # api model on api db self.assertFalse(router.allow_migrate('default', 'testapp', 'Pizza')) # api model on legacy db self.assertIsNone(router.allow_migrate('default', 'testapi', 'Pizza')) # legacy model on legacy db self.assertFalse(router.allow_migrate('api', 'testapi', 'Pizza')) # legacy model on api db self.assertIsNone(router.allow_migrate('default', 'testapi')) # final model not provided : don't know
def test_allow_relation(self): router = RestModelRouter() UserModel = get_user_model() self.assertFalse(router.allow_relation(client_models.Pizza, client_models.Topping)) self.assertFalse(router.allow_relation(client_models.Topping, client_models.Pizza)) self.assertFalse(router.allow_relation(client_models.Pizza, UserModel)) self.assertFalse(router.allow_relation(UserModel, client_models.Pizza)) self.assertFalse(router.allow_relation(client_models.Bookmark, client_models.Pizza)) self.assertIsNone(router.allow_relation(UserModel, client_models.Bookmark))
def is_api_model(self): return RestModelRouter.is_api_model(self.query.model)
def api_struct_check(app_configs, **kwargs): from rest_models.backend.compiler import get_resource_path # NOQA from rest_models.router import RestModelRouter # NOQA errors = [] all_models = [] if app_configs is None: all_models.extend(apps.get_models()) else: for app_config in app_configs: all_models.extend(app_config.get_models()) router = RestModelRouter() models = ((router.get_api_connexion(model).cursor(), model) for model in all_models if router.is_api_model(model) and not bool( router.get_api_connexion(model).settings_dict['OPTIONS'].get( 'SKIP_CHECK', False))) for db, rest_model in models: url = get_resource_path(rest_model) res = db.options(url) if res.status_code != 200: errors.append( Error( 'the remote api does not respond to us. OPTIONS %s%s => %s' % (db.url, url, res.status_code), hint= 'check the url for the remote api or the resource_path', obj=rest_model, id='rest_models.E001')) continue options = res.json() missings = { 'include[]', 'exclude[]', 'filter{}', 'page', 'per_page', 'sort[]' } - set(options.get("features", [])) if missings: errors.append( Error( 'the remote api does not support the folowing features: %s' % missings, hint='is the api on %s/%s running with dynamic-rest ?' % (db.url, url), obj=rest_model, id='rest_models.E002')) continue for field in rest_model._meta.get_fields(): field_name = field.concrete and field.db_column or field.name if field.is_relation: if router.is_api_model(field.related_model): if field_name not in options['properties']: errors.append( Error( 'the field %s.%s in not present on the remote serializer' % (rest_model.__name__, field_name), obj="%s.%s" % (rest_model.__name__, field_name), hint= 'check if the serializer on %s/%s has a field "%s"' % (db.url, url, field_name), id='rest_models.E003')) else: type_is_many = options['properties'][field_name][ 'type'] == 'many' type_is_one = options['properties'][field_name][ 'type'] == 'one' if (type_is_many and not (field.one_to_many or field.many_to_many) or type_is_one and not (field.one_to_one or field.many_to_one)): errors.append( Error( 'the field %s.%s many does not match the api' % (rest_model.__name__, field_name), obj="%s.%s" % (rest_model.__name__, field_name), hint= 'check if the serializer at %s%s have a Serializer.many ' 'value corresponding to the local model %s' % (db.url, url, field_name), id='rest_models.E005')) choice_count = len( options['properties'][field_name].get( 'choices', [])) if choice_count > 100: errors.append( Warning( 'the field %s.%s has many choices values (%s) in OPTIONS ' 'and it slow down the check' % (rest_model.__name__, field_name, choice_count), obj="%s.%s" % (rest_model.__name__, field_name), hint= 'check if the serializer at %s%s provide ' 'a choices with less values for %s' % (db.url, url, field_name), id='rest_models.W001')) elif field_name not in options['properties']: errors.append( Error( 'the field %s.%s in not present on the remote serializer' % (rest_model.__name__, field_name), hint='check if the serializer on %s%s has a field "%s"' % (db.url, url, field_name), id='rest_models.E006')) return errors