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

test_create_tickets()   B

Complexity

Conditions 2

Size

Total Lines 51
Code Lines 39

Duplication

Lines 51
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
eloc 39
nop 9
dl 51
loc 51
rs 8.9439
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 unittest.mock import patch
7
8
from flask import Flask
9
import pytest
10
from pytest import raises
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 import ticket_service
20
from byceps.services.ticketing.ticket_creation_service import (
21
    TicketCreationFailed,
22
)
23
from byceps.services.ticketing.transfer.models import TicketCategory
24
from byceps.services.user.transfer.models import User
25
26
from ...helpers import create_ticket_article
27
28
from .helpers import get_tickets_for_order, mark_order_as_paid, place_order
29
30
31
@pytest.fixture
32
def article(shop: Shop, ticket_category: TicketCategory) -> Article:
33
    return create_ticket_article(shop.id, ticket_category.id)
34
35
36
@pytest.fixture(scope='module')
37
def ticket_quantity() -> int:
38
    return 4
39
40
41
@pytest.fixture
42
def order(
43
    article: Article, ticket_quantity, storefront: Storefront, orderer: Orderer
44
) -> Order:
45
    articles_with_quantity = [(article, ticket_quantity)]
46
    return place_order(storefront.id, orderer, articles_with_quantity)
47
48
49 View Code Duplication
@patch('byceps.signals.ticketing.tickets_sold.send')
50
def test_create_tickets(
51
    tickets_sold_signal_send_mock,
52
    admin_app: Flask,
53
    article: Article,
54
    ticket_category: TicketCategory,
55
    ticket_quantity: int,
56
    admin_user: User,
57
    orderer_user: User,
58
    orderer: Orderer,
59
    order: Order,
60
) -> None:
61
    tickets_before_paid = get_tickets_for_order(order)
62
    assert len(tickets_before_paid) == 0
63
64
    shop_order_paid_event = mark_order_as_paid(order.id, admin_user.id)
65
66
    tickets_after_paid = get_tickets_for_order(order)
67
    assert len(tickets_after_paid) == ticket_quantity
68
69
    for ticket in tickets_after_paid:
70
        assert ticket.owned_by_id == orderer.user_id
71
        assert ticket.used_by_id == orderer.user_id
72
73
    log_entries = order_log_service.get_entries_for_order(order.id)
74
    ticket_created_log_entries = [
75
        entry for entry in log_entries if entry.event_type == 'ticket-created'
76
    ]
77
    assert len(ticket_created_log_entries) == ticket_quantity
78
79
    line_items_after = order_service.get_order(order.id).line_items
80
    assert len(line_items_after) == 1
81
82
    ticket_line_item = line_items_after[0]
83
    assert ticket_line_item.processing_result == {
84
        'ticket_ids': list(
85
            sorted(str(ticket.id) for ticket in tickets_after_paid)
86
        ),
87
    }
88
89
    tickets_sold_event = TicketsSold(
90
        occurred_at=shop_order_paid_event.occurred_at,
91
        initiator_id=admin_user.id,
92
        initiator_screen_name=admin_user.screen_name,
93
        party_id=ticket_category.party_id,
94
        owner_id=orderer_user.id,
95
        owner_screen_name=orderer_user.screen_name,
96
        quantity=ticket_quantity,
97
    )
98
    tickets_sold_signal_send_mock.assert_called_once_with(
99
        None, event=tickets_sold_event
100
    )
101
102
103
@patch('byceps.services.ticketing.ticket_code_service._generate_ticket_code')
104
def test_create_tickets_with_same_code_fails(
105
    generate_ticket_code_mock,
106
    admin_app: Flask,
107
    article: Article,
108
    ticket_category: TicketCategory,
109
    ticket_quantity: int,
110
    admin_user: User,
111
    orderer: Orderer,
112
    order: Order,
113
) -> None:
114
    generate_ticket_code_mock.side_effect = lambda: 'EQUAL'
115
116
    with raises(TicketCreationFailed):
117
        mark_order_as_paid(order.id, admin_user.id)
118
119
120 View Code Duplication
@patch('byceps.services.ticketing.ticket_code_service._generate_ticket_code')
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
121
def test_create_tickets_with_temporarily_equal_code_and_retry_succeeds(
122
    generate_ticket_code_mock,
123
    admin_app: Flask,
124
    article: Article,
125
    ticket_category: TicketCategory,
126
    ticket_quantity: int,
127
    admin_user: User,
128
    orderer: Orderer,
129
    order: Order,
130
) -> None:
131
    code_generation_retries = 4  # Depends on implemented default value.
132
    necessary_outer_retries = 5  # Depends on argument to `retry` decorator.
133
    codes = ['EQUAL'] * code_generation_retries * necessary_outer_retries
134
    codes += ['TCKT1', 'TCKT2', 'TCKT3', 'TCKT4']
135
    codes_iter = iter(codes)
136
    generate_ticket_code_mock.side_effect = lambda: next(codes_iter)
137
138
    tickets_before_paid = get_tickets_for_order(order)
139
    assert len(tickets_before_paid) == 0
140
141
    mark_order_as_paid(order.id, admin_user.id)
142
143
    tickets_after_paid = get_tickets_for_order(order)
144
    assert len(tickets_after_paid) == ticket_quantity
145