Passed
Push — master ( 634080...f658ea )
by Jochen
02:33
created

ShopAdminTestCase.test_cancel_after_paid()   B

Complexity

Conditions 3

Size

Total Lines 50
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 37
nop 4
dl 0
loc 50
rs 8.9919
c 0
b 0
f 0
1
"""
2
:Copyright: 2006-2019 Jochen Kupperschmidt
3
:License: Modified BSD, see LICENSE for details.
4
"""
5
6
from unittest.mock import patch
7
8
from byceps.services.shop.article.models.article import Article
9
from byceps.services.shop.cart.models import Cart
10
from byceps.services.shop.order.models.order import Order
11
from byceps.services.shop.order import service as order_service
12
from byceps.services.shop.order.transfer.models import (
13
    PaymentMethod,
14
    PaymentState,
15
)
16
17
from testfixtures.shop_order import create_orderer
18
19
from tests.base import CONFIG_FILENAME_TEST_ADMIN
20
from tests.helpers import (
21
    assign_permissions_to_user,
22
    create_brand,
23
    create_email_config,
24
    create_party,
25
    create_user,
26
    create_user_with_detail,
27
    http_client,
28
    login_user,
29
)
30
from tests.services.shop.base import ShopTestBase
31
32
33
class ShopAdminTestCase(ShopTestBase):
34
35
    def setUp(self):
36
        super().setUp(config_filename=CONFIG_FILENAME_TEST_ADMIN)
37
38
        self.admin = self.create_admin()
39
        self.orderer = create_user_with_detail('Besteller')
40
41
        create_email_config()
42
43
        self.shop = self.create_shop()
44
        self.create_order_number_sequence(self.shop.id, 'AEC-05-B')
45
        self.create_shop_fragment(self.shop.id, 'email_footer', 'kthxbye')
46
47
        brand = create_brand()
48
        party = create_party(brand.id)
49
50
    def create_admin(self):
51
        admin = create_user('Admin')
52
53
        permission_ids = {
54
            'admin.access',
55
            'shop_order.cancel',
56
            'shop_order.mark_as_paid',
57
        }
58
        assign_permissions_to_user(admin.id, 'admin', permission_ids)
59
60
        login_user(admin.id)
61
62
        return admin
63
64
    @patch('byceps.blueprints.shop.order.signals.order_canceled.send')
65
    @patch('byceps.blueprints.admin.shop.order.views.order_email_service')
66
    def test_cancel_before_paid(
67
        self, order_email_service_mock, order_canceled_signal_send_mock
68
    ):
69
        article_before = self.create_article(self.shop.id, quantity=8)
70
71
        quantified_articles_to_order = {(article_before, 3)}
72
        placed_order = self.place_order(quantified_articles_to_order)
73
        order_before = get_order(placed_order.id)
74
75
        assert article_before.quantity == 5
76
77
        assert_payment_is_open(order_before)
78
79
        url = '/admin/shop/orders/{}/cancel'.format(order_before.id)
80
        form_data = {
81
            'reason': 'Dein Vorname ist albern!',
82
            'send_email': 'y',
83
        }
84
        with http_client(self.app, user_id=self.admin.id) as client:
85
            response = client.post(url, data=form_data)
86
87
        order_afterwards = get_order(order_before.id)
88
        assert response.status_code == 302
89
        assert_payment(
90
            order_afterwards,
91
            PaymentMethod.bank_transfer,
92
            PaymentState.canceled_before_paid,
93
            self.admin.id,
94
        )
95
96
        article_afterwards = Article.query.get(article_before.id)
97
        assert article_afterwards.quantity == 8
98
99
        order_email_service_mock.send_email_for_canceled_order_to_orderer.assert_called_once_with(
100
            placed_order.id
101
        )
102
103
        order_canceled_signal_send_mock.assert_called_once_with(
104
            None, order_id=placed_order.id
105
        )
106
107
    @patch('byceps.blueprints.shop.order.signals.order_canceled.send')
108
    @patch('byceps.blueprints.admin.shop.order.views.order_email_service')
109
    def test_cancel_before_paid_without_sending_email(
110
        self, order_email_service_mock, order_canceled_signal_send_mock
111
    ):
112
        article_before = self.create_article(self.shop.id, quantity=8)
113
        quantified_articles_to_order = {(article_before, 3)}
114
        placed_order = self.place_order(quantified_articles_to_order)
115
116
        url = '/admin/shop/orders/{}/cancel'.format(placed_order.id)
117
        form_data = {
118
            'reason': 'Dein Vorname ist albern!',
119
            # Sending e-mail is not requested.
120
        }
121
        with http_client(self.app, user_id=self.admin.id) as client:
122
            response = client.post(url, data=form_data)
123
124
        assert response.status_code == 302
125
126
        # No e-mail should be send.
127
        order_email_service_mock.send_email_for_canceled_order_to_orderer.assert_not_called()
128
129
        order_canceled_signal_send_mock.assert_called_once_with(
130
            None, order_id=placed_order.id
131
        )
132
133
    @patch('byceps.blueprints.shop.order.signals.order_paid.send')
134
    @patch('byceps.blueprints.admin.shop.order.views.order_email_service')
135
    def test_mark_order_as_paid(
136
        self, order_email_service_mock, order_paid_signal_send_mock
137
    ):
138
        placed_order = self.place_order([])
139
        order_before = get_order(placed_order.id)
140
141
        assert_payment_is_open(order_before)
142
143
        url = '/admin/shop/orders/{}/mark_as_paid'.format(order_before.id)
144
        form_data = {'payment_method': 'direct_debit'}
145
        with http_client(self.app, user_id=self.admin.id) as client:
146
            response = client.post(url, data=form_data)
147
148
        order_afterwards = get_order(order_before.id)
149
        assert response.status_code == 302
150
        assert_payment(
151
            order_afterwards,
152
            PaymentMethod.direct_debit,
153
            PaymentState.paid,
154
            self.admin.id,
155
        )
156
157
        order_email_service_mock.send_email_for_paid_order_to_orderer.assert_called_once_with(
158
            placed_order.id
159
        )
160
161
        order_paid_signal_send_mock.assert_called_once_with(
162
            None, order_id=placed_order.id
163
        )
164
165
    @patch('byceps.blueprints.shop.order.signals.order_canceled.send')
166
    @patch('byceps.blueprints.shop.order.signals.order_paid.send')
167
    @patch('byceps.blueprints.admin.shop.order.views.order_email_service')
168
    def test_cancel_after_paid(
169
        self,
170
        order_email_service_mock,
171
        order_paid_signal_send_mock,
172
        order_canceled_signal_send_mock,
173
    ):
174
        article_before = self.create_article(self.shop.id, quantity=8)
175
176
        quantified_articles_to_order = {(article_before, 3)}
177
        placed_order = self.place_order(quantified_articles_to_order)
178
        order_before = get_order(placed_order.id)
179
180
        assert article_before.quantity == 5
181
182
        assert_payment_is_open(order_before)
183
184
        url = '/admin/shop/orders/{}/mark_as_paid'.format(order_before.id)
185
        form_data = {'payment_method': 'bank_transfer'}
186
        with http_client(self.app, user_id=self.admin.id) as client:
187
            response = client.post(url, data=form_data)
188
189
        url = '/admin/shop/orders/{}/cancel'.format(order_before.id)
190
        form_data = {
191
            'reason': 'Dein Vorname ist albern!',
192
            'send_email': 'n',
193
        }
194
        with http_client(self.app, user_id=self.admin.id) as client:
195
            response = client.post(url, data=form_data)
196
197
        order_afterwards = get_order(order_before.id)
198
        assert response.status_code == 302
199
        assert_payment(
200
            order_afterwards,
201
            PaymentMethod.bank_transfer,
202
            PaymentState.canceled_after_paid,
203
            self.admin.id,
204
        )
205
206
        article_afterwards = Article.query.get(article_before.id)
207
        assert article_afterwards.quantity == 8
208
209
        order_email_service_mock.send_email_for_canceled_order_to_orderer.assert_called_once_with(
210
            placed_order.id
211
        )
212
213
        order_canceled_signal_send_mock.assert_called_once_with(
214
            None, order_id=placed_order.id
215
        )
216
217
    # helpers
218
219
    def place_order(self, quantified_articles):
220
        orderer = create_orderer(self.orderer)
221
        payment_method = PaymentMethod.bank_transfer
222
        cart = Cart()
223
224
        for article, quantity_to_order in quantified_articles:
225
            cart.add_item(article, quantity_to_order)
226
227
        return order_service.place_order(
228
            self.shop.id, orderer, payment_method, cart
229
        )
230
231
232
def assert_payment_is_open(order):
233
    assert order.payment_method == PaymentMethod.bank_transfer  # default
234
    assert order.payment_state == PaymentState.open
235
    assert order.payment_state_updated_at is None
236
    assert order.payment_state_updated_by_id is None
237
238
239
def assert_payment(order, method, state, updated_by_id):
240
    assert order.payment_method == method
241
    assert order.payment_state == state
242
    assert order.payment_state_updated_at is not None
243
    assert order.payment_state_updated_by_id == updated_by_id
244
245
246
def get_order(order_id):
247
    return Order.query.get(order_id)
248