Passed
Push — main ( 0cab68...b2ce89 )
by Jochen
06:38
created

test_create_ticket_bundles()   B

Complexity

Conditions 2

Size

Total Lines 60
Code Lines 45

Duplication

Lines 60
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
eloc 45
nop 10
dl 60
loc 60
rs 8.8
c 0
b 0
f 0

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
"""
2
:Copyright: 2006-2022 Jochen Kupperschmidt
3
:License: Revised BSD (see `LICENSE` file for details)
4
"""
5
6
from __future__ import annotations
7
from unittest.mock import patch
8
9
from flask import Flask
10
import pytest
11
12
from byceps.events.ticketing import TicketsSold
13
from byceps.services.shop.article.transfer.models import Article
14
from byceps.services.shop.order import log_service as order_log_service
15
from byceps.services.shop.order import service as order_service
16
from byceps.services.shop.order.transfer.order import Order, Orderer
17
from byceps.services.shop.shop.transfer.models import Shop
18
from byceps.services.shop.storefront.transfer.models import Storefront
19
from byceps.services.ticketing.dbmodels.ticket import Ticket as DbTicket
20
from byceps.services.ticketing import ticket_service, ticket_bundle_service
21
from byceps.services.ticketing.transfer.models import TicketCategory
22
from byceps.services.user.transfer.models import User
23
24
from ...helpers import create_ticket_bundle_article
25
26
from .helpers import get_tickets_for_order, mark_order_as_paid, place_order
27
28
29
@pytest.fixture(scope='module')
30
def ticket_quantity_per_bundle() -> int:
31
    return 5
32
33
34
@pytest.fixture
35
def article(
36
    shop: Shop, ticket_category: TicketCategory, ticket_quantity_per_bundle: int
37
) -> Article:
38
    return create_ticket_bundle_article(
39
        shop.id, ticket_category.id, ticket_quantity_per_bundle
40
    )
41
42
43
@pytest.fixture(scope='module')
44
def bundle_quantity() -> int:
45
    return 2
46
47
48
@pytest.fixture
49
def order(
50
    article: Article,
51
    bundle_quantity: int,
52
    storefront: Storefront,
53
    orderer: Orderer,
54
) -> Order:
55
    articles_with_quantity = [(article, bundle_quantity)]
56
    return place_order(storefront.id, orderer, articles_with_quantity)
57
58
59 View Code Duplication
@patch('byceps.signals.ticketing.tickets_sold.send')
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
60
def test_create_ticket_bundles(
61
    tickets_sold_signal_send_mock,
62
    admin_app: Flask,
63
    article: Article,
64
    ticket_category: TicketCategory,
65
    ticket_quantity_per_bundle: int,
66
    bundle_quantity: int,
67
    admin_user: User,
68
    orderer_user: User,
69
    orderer: Orderer,
70
    order: Order,
71
) -> None:
72
    expected_ticket_total = 10
73
74
    tickets_before_paid = get_tickets_for_order(order)
75
    assert len(tickets_before_paid) == 0
76
77
    shop_order_paid_event = mark_order_as_paid(order.id, admin_user.id)
78
79
    tickets_after_paid = get_tickets_for_order(order)
80
    assert len(tickets_after_paid) == expected_ticket_total
81
82
    for ticket in tickets_after_paid:
83
        assert ticket.owned_by_id == orderer.user_id
84
        assert ticket.used_by_id == orderer.user_id
85
86
    log_entries = order_log_service.get_entries_for_order(order.id)
87
    ticket_bundle_created_log_entries = [
88
        entry
89
        for entry in log_entries
90
        if entry.event_type == 'ticket-bundle-created'
91
    ]
92
    assert len(ticket_bundle_created_log_entries) == bundle_quantity
93
94
    line_items_after = order_service.get_order(order.id).line_items
95
    assert len(line_items_after) == 1
96
97
    bundle_ids = {ticket.bundle_id for ticket in tickets_after_paid}
98
    ticket_bundle_line_item = line_items_after[0]
99
    assert ticket_bundle_line_item.processing_result == {
100
        'ticket_bundle_ids': list(
101
            sorted(str(bundle_id) for bundle_id in bundle_ids)
102
        ),
103
    }
104
105
    tickets_sold_event = TicketsSold(
106
        occurred_at=shop_order_paid_event.occurred_at,
107
        initiator_id=admin_user.id,
108
        initiator_screen_name=admin_user.screen_name,
109
        party_id=ticket_category.party_id,
110
        owner_id=orderer_user.id,
111
        owner_screen_name=orderer_user.screen_name,
112
        quantity=expected_ticket_total,
113
    )
114
    tickets_sold_signal_send_mock.assert_called_once_with(
115
        None, event=tickets_sold_event
116
    )
117
118
    tear_down_bundles(tickets_after_paid)
119
120
121
# helpers
122
123
124
def tear_down_bundles(tickets: list[DbTicket]) -> None:
125
    bundle_ids = {t.bundle_id for t in tickets}
126
127
    for ticket in tickets:
128
        ticket_service.delete_ticket(ticket.id)
129
130
    for bundle_id in bundle_ids:
131
        ticket_bundle_service.delete_bundle(bundle_id)
132