Ejemplo n.º 1
0
    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")
Ejemplo n.º 3
0
 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))
Ejemplo n.º 6
0
 def is_api_model(self):
     return RestModelRouter.is_api_model(self.query.model)
Ejemplo n.º 7
0
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