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

ticket_quantity()   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
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