~homeworkprod/byceps

42833a983a8d5887c576ee58e9fb57da57a3914f — Jochen Kupperschmidt 1 year, 1 month ago a5c18f5
Extract test fixture factory to create admin user with permissions and role
M byceps/services/authorization/service.py => byceps/services/authorization/service.py +25 -4
@@ 8,6 8,8 @@ byceps.services.authorization.service

from typing import Dict, List, Optional, Sequence, Set

from sqlalchemy.exc import IntegrityError

from ...database import db
from ...typing import UserID



@@ 22,12 24,18 @@ from .models import (
from .transfer.models import Permission, PermissionID, Role, RoleID


def create_permission(permission_id: PermissionID, title: str) -> Permission:
def create_permission(
    permission_id: PermissionID, title: str, *, ignore_if_exists: bool = False
) -> Permission:
    """Create a permission."""
    permission = DbPermission(permission_id, title)

    db.session.add(permission)
    db.session.commit()

    if ignore_if_exists:
        _commit_ignoring_integrity_error()
    else:
        db.session.commit()

    return _db_entity_to_permission(permission)



@@ 41,12 49,18 @@ def delete_permission(permission_id: PermissionID) -> None:
    db.session.commit()


def create_role(role_id: RoleID, title: str) -> Role:
def create_role(
    role_id: RoleID, title: str, *, ignore_if_exists: bool = False
) -> Role:
    """Create a role."""
    role = DbRole(role_id, title)

    db.session.add(role)
    db.session.commit()

    if ignore_if_exists:
        _commit_ignoring_integrity_error()
    else:
        db.session.commit()

    return _db_entity_to_role(role)



@@ 305,6 319,13 @@ def get_permissions_with_title_for_role(
    return [_db_entity_to_permission(permission) for permission in permissions]


def _commit_ignoring_integrity_error() -> None:
    try:
        db.session.commit()
    except IntegrityError:
        db.session.rollback()


def _db_entity_to_permission(permission: DbPermission) -> Permission:
    return Permission(
        permission.id,

M tests/conftest.py => tests/conftest.py +38 -1
@@ 4,11 4,13 @@
"""

from pathlib import Path
from secrets import token_hex
from tempfile import TemporaryDirectory
from typing import Optional
from typing import Optional, Set

import pytest

from byceps.services.authorization import service as authorization_service
from byceps.services.board import board_service
from byceps.services.brand import service as brand_service
from byceps.services.email import service as email_service


@@ 24,6 26,8 @@ from tests.database import set_up_database, tear_down_database
from tests.helpers import (
    create_brand,
    create_party,
    create_permissions,
    create_role_with_permissions_assigned,
    create_site,
    create_user,
    create_user_with_detail,


@@ 121,6 125,39 @@ def make_user_with_detail(admin_app):


@pytest.fixture(scope='session')
def make_admin(make_user):
    user_ids = set()
    created_permission_ids = set()
    created_role_ids = set()

    def _wrapper(screen_name: str, permission_ids: Set[str]):
        admin = make_user(screen_name)
        user_ids.add(admin.id)

        # Create permissions and role.
        role_id = f'admin_{token_hex(3)}'
        create_permissions(permission_ids)
        create_role_with_permissions_assigned(role_id, permission_ids)
        authorization_service.assign_role_to_user(role_id, admin.id)
        created_role_ids.add(role_id)

        return admin

    yield _wrapper

    # Remove permissions and role again.

    for user_id in user_ids:
        authorization_service.deassign_all_roles_from_user(user_id)

    for role_id in created_role_ids:
        authorization_service.delete_role(role_id)

    for permission_id in created_permission_ids:
        authorization_service.delete_permission(permission_id)


@pytest.fixture(scope='session')
def admin_user(make_user):
    return make_user('Admin')


M tests/helpers.py => tests/helpers.py +6 -2
@@ 86,11 86,15 @@ def create_user_with_detail(*args, **kwargs):

def create_permissions(permission_ids):
    for permission_id in permission_ids:
        authorization_service.create_permission(permission_id, permission_id)
        authorization_service.create_permission(
            permission_id, permission_id, ignore_if_exists=True
        )


def create_role_with_permissions_assigned(role_id, permission_ids):
    role = authorization_service.create_role(role_id, role_id)
    role = authorization_service.create_role(
        role_id, role_id, ignore_if_exists=True
    )

    for permission_id in permission_ids:
        authorization_service.assign_permission_to_role(permission_id, role_id)

M tests/integration/blueprints/admin/newsletter/test_views.py => tests/integration/blueprints/admin/newsletter/test_views.py +4 -22
@@ 8,7 8,6 @@ from datetime import datetime
import pytest

from byceps.database import db
from byceps.services.authorization import service as authorization_service
from byceps.services.newsletter.models import (
    SubscriptionUpdate as DbSubscriptionUpdate,
)


@@ 16,12 15,7 @@ from byceps.services.newsletter import command_service
from byceps.services.newsletter.types import SubscriptionState
from byceps.services.user import command_service as user_command_service

from tests.helpers import (
    create_permissions,
    create_role_with_permissions_assigned,
    http_client,
    login_user,
)
from tests.helpers import http_client, login_user


def test_export_subscribers(newsletter_list, subscribers, client):


@@ 102,23 96,11 @@ def test_export_subscriber_email_addresses(newsletter_list, subscribers, client)


@pytest.fixture(scope='module')
def newsletter_admin(make_user):
    admin = make_user('NewsletterAdmin')

def newsletter_admin(make_admin):
    permission_ids = {'admin.access', 'newsletter.export_subscribers'}
    role_id = 'newsletter_admin'
    create_permissions(permission_ids)
    create_role_with_permissions_assigned(role_id, permission_ids)
    authorization_service.assign_role_to_user(role_id, admin.id)

    admin = make_admin('NewsletterAdmin', permission_ids)
    login_user(admin.id)

    yield admin

    authorization_service.deassign_all_roles_from_user(admin.id, admin.id)
    authorization_service.delete_role(role_id)
    for permission_id in permission_ids:
        authorization_service.delete_permission(permission_id)
    return admin


@pytest.fixture(scope='module')

M tests/integration/blueprints/admin/shop/order/test_order_export.py => tests/integration/blueprints/admin/shop/order/test_order_export.py +4 -22
@@ 9,7 9,6 @@ from decimal import Decimal
from freezegun import freeze_time
import pytest

from byceps.services.authorization import service as authorization_service
from byceps.services.shop.article import service as article_service
from byceps.services.shop.cart.models import Cart
from byceps.services.shop.order.models.orderer import Orderer


@@ 17,35 16,18 @@ from byceps.services.shop.order import service as order_service
from byceps.services.shop.sequence import service as sequence_service
from byceps.services.shop.storefront import service as storefront_service

from tests.helpers import (
    create_permissions,
    create_role_with_permissions_assigned,
    http_client,
    login_user,
)
from tests.helpers import http_client, login_user
from tests.integration.services.shop.helpers import (
    create_article as _create_article,
)


@pytest.fixture(scope='module')
def admin_user(make_user):
    admin = make_user('ShopOrderExportAdmin')

def admin_user(make_admin):
    permission_ids = {'admin.access', 'shop_order.view'}
    role_id = 'order_admin'
    create_permissions(permission_ids)
    create_role_with_permissions_assigned(role_id, permission_ids)
    authorization_service.assign_role_to_user(role_id, admin.id)

    admin = make_admin('ShopOrderExportAdmin', permission_ids)
    login_user(admin.id)

    yield admin

    authorization_service.deassign_all_roles_from_user(admin.id, admin.id)
    authorization_service.delete_role(role_id)
    for permission_id in permission_ids:
        authorization_service.delete_permission(permission_id)
    return admin


@pytest.fixture

M tests/integration/blueprints/admin/shop/order/test_views.py => tests/integration/blueprints/admin/shop/order/test_views.py +4 -22
@@ 8,7 8,6 @@ from unittest.mock import patch
import pytest

from byceps.events.shop import ShopOrderCanceled, ShopOrderPaid
from byceps.services.authorization import service as authorization_service
from byceps.services.shop.article import service as article_service
from byceps.services.shop.cart.models import Cart
from byceps.services.shop.order.models.order import Order


@@ 19,39 18,22 @@ from byceps.services.shop.order.transfer.models import (
)
from testfixtures.shop_order import create_orderer

from tests.helpers import (
    create_permissions,
    create_role_with_permissions_assigned,
    http_client,
    login_user,
)
from tests.helpers import http_client, login_user
from tests.integration.services.shop.helpers import (
    create_article as _create_article,
)


@pytest.fixture(scope='module')
def admin(make_user):
    admin = make_user('ShopOrderAdmin')

def admin(make_admin):
    permission_ids = {
        'admin.access',
        'shop_order.cancel',
        'shop_order.mark_as_paid',
    }
    role_id = 'order_admin'
    create_permissions(permission_ids)
    create_role_with_permissions_assigned(role_id, permission_ids)
    authorization_service.assign_role_to_user(role_id, admin.id)

    admin = make_admin('ShopOrderAdmin', permission_ids)
    login_user(admin.id)

    yield admin

    authorization_service.deassign_all_roles_from_user(admin.id, admin.id)
    authorization_service.delete_role(role_id)
    for permission_id in permission_ids:
        authorization_service.delete_permission(permission_id)
    return admin


@pytest.fixture

M tests/integration/blueprints/site/board/conftest.py => tests/integration/blueprints/site/board/conftest.py +3 -23
@@ 5,7 5,6 @@

import pytest

from byceps.services.authorization import service as authorization_service
from byceps.services.board import (
    category_command_service,
    posting_command_service,


@@ 13,12 12,7 @@ from byceps.services.board import (
    topic_query_service,
)

from tests.helpers import (
    create_permissions,
    create_role_with_permissions_assigned,
    http_client,
    login_user,
)
from tests.helpers import http_client, login_user

from .helpers import create_category, create_posting, create_topic



@@ 65,31 59,17 @@ def board_poster(make_user):


@pytest.fixture(scope='session')
def moderator(make_user):
    moderator = make_user('BoardModerator')

def moderator(make_admin):
    permission_ids = {
        'board.hide',
        'board_topic.lock',
        'board_topic.move',
        'board_topic.pin',
    }
    role_id = 'moderator'
    create_permissions(permission_ids)
    create_role_with_permissions_assigned(role_id, permission_ids)
    authorization_service.assign_role_to_user(role_id, moderator.id)

    moderator = make_admin('BoardModerator', permission_ids)
    login_user(moderator.id)

    yield moderator

    authorization_service.deassign_all_roles_from_user(
        moderator.id, moderator.id
    )
    authorization_service.delete_role(role_id)
    for permission_id in permission_ids:
        authorization_service.delete_permission(permission_id)


@pytest.fixture(scope='session')
def moderator_client(site_app, moderator):