0001-lingo-poll-backend-during-asynchronous-rendering-577.patch
combo/apps/lingo/models.py | ||
---|---|---|
638 | 638 |
ordering = ['regie', 'extra_fee', 'subject'] |
639 | 639 | |
640 | 640 |
@classmethod |
641 |
def get_items_to_be_paid(cls, user): |
|
641 |
def get_items_to_be_paid(cls, user, poll=False, raise_on_poll=False):
|
|
642 | 642 |
qs = cls.objects.filter( |
643 | 643 |
user=user, payment_date__isnull=True, waiting_date__isnull=True, cancellation_date__isnull=True |
644 | 644 |
) |
645 |
for transaction in Transaction.objects.filter(items__in=qs): |
|
646 |
if transaction.can_poll_backend(): |
|
647 |
transaction.poll_backend() |
|
645 |
if poll: |
|
646 |
for transaction in Transaction.objects.filter(items__in=qs): |
|
647 |
if transaction.can_poll_backend(): |
|
648 |
if raise_on_poll: |
|
649 |
raise NothingInCacheException |
|
650 |
transaction.poll_backend() |
|
648 | 651 |
return qs |
649 | 652 | |
650 | 653 |
def notify(self, status): |
... | ... | |
1087 | 1090 | |
1088 | 1091 |
def render(self, context): |
1089 | 1092 |
basket_template = template.loader.get_template('lingo/combo/basket.html') |
1090 |
items = BasketItem.get_items_to_be_paid(context['request'].user) |
|
1093 |
items = BasketItem.get_items_to_be_paid( |
|
1094 |
context['request'].user, poll=True, raise_on_poll=not context.get('synchronous') |
|
1095 |
) |
|
1091 | 1096 |
regies = {} |
1092 | 1097 |
for item in items: |
1093 | 1098 |
if not item.regie_id in regies: |
... | ... | |
1112 | 1117 |
def is_enabled(cls): |
1113 | 1118 |
return Regie.objects.exists() |
1114 | 1119 | |
1115 |
def get_transactions_queryset(self, context): |
|
1120 |
def get_transactions_queryset(self, context, poll=False):
|
|
1116 | 1121 |
user = context['request'].user |
1117 | 1122 |
# list transactions : |
1118 | 1123 |
# * paid by the user |
... | ... | |
1120 | 1125 |
qs = Transaction.objects.filter(models.Q(user=user) | models.Q(items__user=user)).filter( |
1121 | 1126 |
start_date__gte=timezone.now() - datetime.timedelta(days=7) |
1122 | 1127 |
) |
1123 |
for transaction in qs: |
|
1124 |
if transaction.can_poll_backend() and transaction.is_running(): |
|
1125 |
transaction.poll_backend() |
|
1128 |
if poll: |
|
1129 |
for transaction in qs: |
|
1130 |
if transaction.can_poll_backend() and transaction.is_running(): |
|
1131 |
if not context.get('synchronous'): |
|
1132 |
raise NothingInCacheException |
|
1133 |
transaction.poll_backend() |
|
1126 | 1134 |
return qs |
1127 | 1135 | |
1128 | 1136 |
def is_relevant(self, context): |
... | ... | |
1132 | 1140 | |
1133 | 1141 |
def render(self, context): |
1134 | 1142 |
recent_transactions_template = template.loader.get_template('lingo/combo/recent_transactions.html') |
1135 |
context['transactions'] = self.get_transactions_queryset(context).distinct().order_by('-start_date') |
|
1143 |
context['transactions'] = ( |
|
1144 |
self.get_transactions_queryset(context, poll=True).distinct().order_by('-start_date') |
|
1145 |
) |
|
1136 | 1146 |
return recent_transactions_template.render(context) |
1137 | 1147 | |
1138 | 1148 |
tests/conftest.py | ||
---|---|---|
70 | 70 | |
71 | 71 |
@pytest.fixture |
72 | 72 |
def synchronous_cells(settings): |
73 |
settings.COMBO_TEST_ALWAYS_RENDER_CELLS_SYNCHRONOUSLY = True |
|
73 |
class M: |
|
74 |
@staticmethod |
|
75 |
def on(): |
|
76 |
settings.COMBO_TEST_ALWAYS_RENDER_CELLS_SYNCHRONOUSLY = True |
|
77 | ||
78 |
@staticmethod |
|
79 |
def off(): |
|
80 |
settings.COMBO_TEST_ALWAYS_RENDER_CELLS_SYNCHRONOUSLY = False |
|
81 | ||
82 |
M.on() |
|
83 |
return M |
tests/test_lingo_payment.py | ||
---|---|---|
2153 | 2153 |
self, |
2154 | 2154 |
payment_status, |
2155 | 2155 |
app, |
2156 |
user, |
|
2157 |
synchronous_cells, |
|
2156 | 2158 |
): |
2157 | 2159 |
# Try to pay |
2158 | 2160 |
pay_resp = app.get('/test_basket_cell/') |
... | ... | |
2171 | 2173 |
order_id=transaction.order_id, |
2172 | 2174 |
) |
2173 | 2175 | |
2174 |
# Try to pay again |
|
2176 |
# check get_items_to_be_paid() does not poll anymore |
|
2177 |
BasketItem.get_items_to_be_paid(user) |
|
2178 |
assert payment_status.call_count == 0 |
|
2179 | ||
2180 |
# Try to pay again, only with current information |
|
2181 |
synchronous_cells.off() |
|
2175 | 2182 |
resp = app.get('/test_basket_cell/') |
2176 |
assert 'foo item' not in resp |
|
2177 |
assert 'Pay' not in resp |
|
2178 |
assert 'Running' in resp |
|
2183 |
assert 'Loading' in resp.pyquery('.lingo-basket-cell').text() |
|
2184 |
assert 'Loading' in resp.pyquery('.lingo-recent-transactions-cell').text() |
|
2179 | 2185 |
resp = pay_resp.click('Pay').follow() |
2180 | 2186 |
assert 'Some items are already paid or' in resp |
2181 |
assert 'foo item' not in resp |
|
2182 |
assert 'Running' in resp |
|
2187 |
assert len(resp.pyquery('.lingo-basket-cell')) == 0 |
|
2188 |
assert 'Loading' in resp.pyquery('.lingo-recent-transactions-cell').text() |
|
2189 |
assert payment_status.call_count == 1 # pay made a call to payfip backend |
|
2190 |
payment_status.reset_mock() |
|
2191 | ||
2192 |
# Make rendering synchronous and retry |
|
2193 |
synchronous_cells.on() |
|
2194 |
resp = app.get('/test_basket_cell/') |
|
2195 |
assert len(resp.pyquery('.lingo-basket-cell')) == 0 |
|
2196 |
assert 'Running' in resp.pyquery('.lingo-recent-transactions-cell').text() |
|
2197 |
assert payment_status.call_count == 1 # transactions cell polled |
|
2198 |
payment_status.reset_mock() |
|
2199 | ||
2200 |
resp = pay_resp.click('Pay') |
|
2201 |
assert payment_status.call_count == 1 # pay polled |
|
2202 |
payment_status.reset_mock() |
|
2203 | ||
2204 |
resp = resp.follow() |
|
2205 |
assert 'Some items are already paid or' in resp |
|
2206 |
assert len(resp.pyquery('.lingo-basket-cell')) == 0 |
|
2207 |
assert 'Running' in resp.pyquery('.lingo-recent-transactions-cell').text() |
|
2208 |
assert payment_status.call_count == 1 # transactions cell polled |
|
2209 |
payment_status.reset_mock() |
|
2183 | 2210 | |
2184 | 2211 |
# Simulate paid status on polling |
2185 | 2212 |
payment_status.return_value = eopayment.common.PaymentResponse( |
... | ... | |
2193 | 2220 |
assert 'foo item: 42.00' in resp |
2194 | 2221 |
assert 'Pay' not in resp |
2195 | 2222 |
assert 'Running' not in resp |
2223 |
assert len(resp.pyquery('.lingo-basket-cell')) == 0 |
|
2224 |
assert '42.00' in resp.pyquery('.lingo-recent-transactions-cell').text() |
|
2225 |
assert payment_status.call_count == 1 # transactions cell polled |
|
2226 |
payment_status.reset_mock() |
|
2196 | 2227 | |
2197 | 2228 |
@mock.patch('eopayment.payfip_ws.Payment.payment_status') |
2198 | 2229 |
def test_exception_during_polling( |
2199 | 2230 |
self, |
2200 | 2231 |
payment_status, |
2201 | 2232 |
app, |
2233 |
synchronous_cells, |
|
2202 | 2234 |
caplog, |
2203 | 2235 |
): |
2204 | 2236 |
# Try to pay |
2205 |
- |