Как проверить функцию, которая использует db и возвращает логическое значение в зависимости от параметров - PullRequest
1 голос
/ 19 февраля 2020

Я сделал функцию, чтобы проверить, есть ли у определенного пользователя c разрешения на какие-либо действия с ресурсом. Если у пользователя есть супер-права has_all_actions, has_all_resources, он может выполнить любое действие на любом ресурсе. Я не знаю, правильно ли я реализовал функцию, но с некоторыми ручными тестами, которые я сделал, она работает.

def check_if_user_has_permissions(user= None, resource = None, action = None):

    tmp = {}
    tmp["user"] = user
    tmp["resource"] = resource
    tmp["action"] = action
    data = []
    has_permission = db.session.query(RoleMember.user_uid, Permission.resource, Permission.action). \
        filter_by(user_uid=user). \
        join(Permission, Permission.role == RoleMember.role).all()
    if resource and action is not None:
        if has_permission == "":
            return False
        else:
            for info in has_permission:
                for item in info:
                    data.append(item)
            has_all_actions = "*"
            has_all_resources = "machines/*"
            if tmp["user"] in data and data[1] == has_all_resources and data[2] == has_all_actions:
                return True
            else:
                if tmp["user"] in data and tmp["resource"] in data and tmp["action"] in data:
                    return True
                else:
                    return False
    else:
        return False

Эта функция возвращает true или false в зависимости от того, есть ли у пользователя разрешения или нет, и всегда возвращает true, если пользователь имеет супер-права: has_all_actions, has_all_resources.

Моя база данных SqlAlchemy, но в данный момент я использую это SQLALCHEMY_DATABASE_URI: "sqlite://", поэтому у меня нет реальных данных, хранящихся в БД.

Теперь я хочу проверить эту функцию с помощью @pytest.mark.parametrize, поэтому я передаю различные параметры фактической функции и утверждаю, что это ложь или истина, в зависимости от данных, находящихся в базе данных.

Так что я думаю, что я тоже нужно смоделировать базу данных и добавить туда некоторые данные, чтобы я мог сделать этот тест? или есть способ без насмешек над БД?

Какие-нибудь примеры, которым я могу следовать? Я заблудился в этом.

Забыл показать мои модели:

class Role(db.Model):
    __tablename__ = "roles"
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(250), unique=True)
    description = db.Column(db.String(1000))
    permissions = db.relationship("Permission", lazy=True)
    members = db.relationship("RoleMember", lazy=True)


class Permission(db.Model):
    __tablename__ = "permissions"
    id = db.Column(db.Integer, primary_key=True)
    resource = db.Column(db.String(250))
    action = db.Column(db.String(250))
    role = db.Column(db.Integer, db.ForeignKey("roles.id"))


class RoleMember(db.Model):
    __tablename__ = "role_members"
    id = db.Column(db.Integer, primary_key=True)
    user_uid = db.Column(db.String(250))
    role = db.Column(db.Integer, db.ForeignKey("roles.id"))

1 Ответ

0 голосов
/ 21 февраля 2020

Итак, я нашел ответ, проблема была в том, что мой has_permission возвращал тип [(" ")], и я делал макет, возвращая тип [""].

Итак, решение было:

@patch("dev_maintenance.roles.db")
def test_check_if_user_has_permissions(db):

    tmp = {}
    tmp["user"] = "bender"
    tmp["resource"] = "machine/1"
    tmp["action"] = "delete"



    ##The mock
    db.session.query.return_value.filter_by.return_value.join.return_value.all.return_value = [(tmp["user"], tmp["resource"], tmp["action"])]
    ## check if the function is returning True

    assert check_if_user_has_permissions("bender","machine/1", "delete") == True
...