~homeworkprod/byceps

49e4dfb595899f0239aea1297c6ec3c898973c6d — Jochen Kupperschmidt 2 years ago 54b4453
Add API endpoint to award user badge
M byceps/application.py => byceps/application.py +1 -0
@@ 135,6 135,7 @@ def _get_blueprints(app):
        ('api.tourney.avatar',          '/api/tourney/avatars'      ),
        ('api.tourney.match',           '/api/tourney/matches'      ),
        ('api.user',                    '/api/users'                ),
        ('api.user_badge',              '/api/user_badges'          ),
    ]

    # metrics

A byceps/blueprints/api/user_badge/__init__.py => byceps/blueprints/api/user_badge/__init__.py +0 -0
A byceps/blueprints/api/user_badge/views.py => byceps/blueprints/api/user_badge/views.py +74 -0
@@ 0,0 1,74 @@
"""
byceps.blueprints.api.user_badge.views
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:Copyright: 2006-2019 Jochen Kupperschmidt
:License: Modified BSD, see LICENSE for details.
"""

from flask import abort, request

from ....services.user import service as user_service
from ....services.user_badge import (
    command_service as badge_command_service,
    service as badge_service,
)
from ....util.framework.blueprint import create_blueprint
from ....util.views import respond_no_content

from ..decorators import api_token_required

from ...user_badge import signals


blueprint = create_blueprint('api_user_badge', __name__)


@blueprint.route('/<uuid:badge_id>/awardings', methods=['POST'])
@api_token_required
@respond_no_content
def award_badge_to_user(badge_id):
    """Award the badge to a user."""
    badge = _get_badge_or_404(badge_id)

    user = _get_user_or_400()
    initiator = _get_initiator_or_400()

    _, event = badge_command_service.award_badge_to_user(
        badge.id, user.id, initiator_id=initiator.id
    )

    signals.user_badge_awarded.send(None, event=event)


def _get_badge_or_404(badge_id):
    badge = badge_service.find_badge(badge_id)

    if badge is None:
        abort(404)

    return badge


def _get_user_or_400():
    user_id = request.form['user_id'].strip()
    if not user_id:
        abort(400, 'User ID missing')

    user = user_service.find_user(user_id)
    if not user:
        abort(400, 'User ID unknown')

    return user


def _get_initiator_or_400():
    initiator_id = request.form['initiator_id'].strip()
    if not initiator_id:
        abort(400, 'Initiator ID missing')

    initiator = user_service.find_user(initiator_id)
    if not initiator:
        abort(400, 'Initiator ID unknown')

    return initiator

M config/test_admin.py => config/test_admin.py +2 -0
@@ 16,3 16,5 @@ MAIL_DEFAULT_SENDER = 'BYCEPS <noreply@example.com>'
MAIL_SUPPRESS_SEND = True

JOBS_ASYNC = False

API_TOKEN = 'just-say-PLEASE'

A tests/blueprints/api/user_badge/__init__.py => tests/blueprints/api/user_badge/__init__.py +0 -0
A tests/blueprints/api/user_badge/test_award_badge.py => tests/blueprints/api/user_badge/test_award_badge.py +42 -0
@@ 0,0 1,42 @@
"""
:Copyright: 2006-2019 Jochen Kupperschmidt
:License: Modified BSD, see LICENSE for details.
"""

from byceps.services.user_badge import (
    command_service as badge_command_service,
    service as badge_service,
)
from byceps.services.user_badge.transfer.models import QuantifiedBadgeAwarding

from tests.api_helpers import assemble_authorization_header
from tests.helpers import (
    create_email_config,
    create_site,
    create_user,
    http_client,
    login_user,
)


def test_award_badge(admin_app_with_db, normal_user, admin_user):
    badge = badge_command_service.create_badge(
        'supporter', 'Supporter', 'supporter.svg'
    )

    before = badge_service.get_awardings_of_badge(badge.id)
    assert before == set()

    url = f'/api/user_badges/{badge.id}/awardings'
    headers = [assemble_authorization_header('just-say-PLEASE')]
    form_data = {
        'user_id': str(normal_user.id),
        'initiator_id': str(admin_user.id),
    }

    with admin_app_with_db.test_client() as client:
        response = client.post(url, headers=headers, data=form_data)
    assert response.status_code == 204

    actual = badge_service.get_awardings_of_badge(badge.id)
    assert actual == {QuantifiedBadgeAwarding(badge.id, normal_user.id, 1)}