lingo: poll backend during asynchronous rendering (#57790)
This commit is contained in:
parent
0aac640e37
commit
f92b855774
|
@ -638,13 +638,16 @@ class BasketItem(models.Model):
|
|||
ordering = ['regie', 'extra_fee', 'subject']
|
||||
|
||||
@classmethod
|
||||
def get_items_to_be_paid(cls, user):
|
||||
def get_items_to_be_paid(cls, user, poll=False, raise_on_poll=False):
|
||||
qs = cls.objects.filter(
|
||||
user=user, payment_date__isnull=True, waiting_date__isnull=True, cancellation_date__isnull=True
|
||||
)
|
||||
for transaction in Transaction.objects.filter(items__in=qs):
|
||||
if transaction.can_poll_backend():
|
||||
transaction.poll_backend()
|
||||
if poll:
|
||||
for transaction in Transaction.objects.filter(items__in=qs):
|
||||
if transaction.can_poll_backend():
|
||||
if raise_on_poll:
|
||||
raise NothingInCacheException
|
||||
transaction.poll_backend()
|
||||
return qs
|
||||
|
||||
def notify(self, status):
|
||||
|
@ -1087,7 +1090,9 @@ class LingoBasketCell(CellBase):
|
|||
|
||||
def render(self, context):
|
||||
basket_template = template.loader.get_template('lingo/combo/basket.html')
|
||||
items = BasketItem.get_items_to_be_paid(context['request'].user)
|
||||
items = BasketItem.get_items_to_be_paid(
|
||||
context['request'].user, poll=True, raise_on_poll=not context.get('synchronous')
|
||||
)
|
||||
regies = {}
|
||||
for item in items:
|
||||
if not item.regie_id in regies:
|
||||
|
@ -1112,7 +1117,7 @@ class LingoRecentTransactionsCell(CellBase):
|
|||
def is_enabled(cls):
|
||||
return Regie.objects.exists()
|
||||
|
||||
def get_transactions_queryset(self, context):
|
||||
def get_transactions_queryset(self, context, poll=False):
|
||||
user = context['request'].user
|
||||
# list transactions :
|
||||
# * paid by the user
|
||||
|
@ -1120,9 +1125,12 @@ class LingoRecentTransactionsCell(CellBase):
|
|||
qs = Transaction.objects.filter(models.Q(user=user) | models.Q(items__user=user)).filter(
|
||||
start_date__gte=timezone.now() - datetime.timedelta(days=7)
|
||||
)
|
||||
for transaction in qs:
|
||||
if transaction.can_poll_backend() and transaction.is_running():
|
||||
transaction.poll_backend()
|
||||
if poll:
|
||||
for transaction in qs:
|
||||
if transaction.can_poll_backend() and transaction.is_running():
|
||||
if not context.get('synchronous'):
|
||||
raise NothingInCacheException
|
||||
transaction.poll_backend()
|
||||
return qs
|
||||
|
||||
def is_relevant(self, context):
|
||||
|
@ -1132,7 +1140,9 @@ class LingoRecentTransactionsCell(CellBase):
|
|||
|
||||
def render(self, context):
|
||||
recent_transactions_template = template.loader.get_template('lingo/combo/recent_transactions.html')
|
||||
context['transactions'] = self.get_transactions_queryset(context).distinct().order_by('-start_date')
|
||||
context['transactions'] = (
|
||||
self.get_transactions_queryset(context, poll=True).distinct().order_by('-start_date')
|
||||
)
|
||||
return recent_transactions_template.render(context)
|
||||
|
||||
|
||||
|
|
|
@ -70,4 +70,14 @@ def nocache(settings):
|
|||
|
||||
@pytest.fixture
|
||||
def synchronous_cells(settings):
|
||||
settings.COMBO_TEST_ALWAYS_RENDER_CELLS_SYNCHRONOUSLY = True
|
||||
class M:
|
||||
@staticmethod
|
||||
def on():
|
||||
settings.COMBO_TEST_ALWAYS_RENDER_CELLS_SYNCHRONOUSLY = True
|
||||
|
||||
@staticmethod
|
||||
def off():
|
||||
settings.COMBO_TEST_ALWAYS_RENDER_CELLS_SYNCHRONOUSLY = False
|
||||
|
||||
M.on()
|
||||
return M
|
||||
|
|
|
@ -2153,6 +2153,8 @@ class TestPolling:
|
|||
self,
|
||||
payment_status,
|
||||
app,
|
||||
user,
|
||||
synchronous_cells,
|
||||
):
|
||||
# Try to pay
|
||||
pay_resp = app.get('/test_basket_cell/')
|
||||
|
@ -2171,15 +2173,40 @@ class TestPolling:
|
|||
order_id=transaction.order_id,
|
||||
)
|
||||
|
||||
# Try to pay again
|
||||
# check get_items_to_be_paid() does not poll anymore
|
||||
BasketItem.get_items_to_be_paid(user)
|
||||
assert payment_status.call_count == 0
|
||||
|
||||
# Try to pay again, only with current information
|
||||
synchronous_cells.off()
|
||||
resp = app.get('/test_basket_cell/')
|
||||
assert 'foo item' not in resp
|
||||
assert 'Pay' not in resp
|
||||
assert 'Running' in resp
|
||||
assert 'Loading' in resp.pyquery('.lingo-basket-cell').text()
|
||||
assert 'Loading' in resp.pyquery('.lingo-recent-transactions-cell').text()
|
||||
resp = pay_resp.click('Pay').follow()
|
||||
assert 'Some items are already paid or' in resp
|
||||
assert 'foo item' not in resp
|
||||
assert 'Running' in resp
|
||||
assert len(resp.pyquery('.lingo-basket-cell')) == 0
|
||||
assert 'Loading' in resp.pyquery('.lingo-recent-transactions-cell').text()
|
||||
assert payment_status.call_count == 1 # pay made a call to payfip backend
|
||||
payment_status.reset_mock()
|
||||
|
||||
# Make rendering synchronous and retry
|
||||
synchronous_cells.on()
|
||||
resp = app.get('/test_basket_cell/')
|
||||
assert len(resp.pyquery('.lingo-basket-cell')) == 0
|
||||
assert 'Running' in resp.pyquery('.lingo-recent-transactions-cell').text()
|
||||
assert payment_status.call_count == 1 # transactions cell polled
|
||||
payment_status.reset_mock()
|
||||
|
||||
resp = pay_resp.click('Pay')
|
||||
assert payment_status.call_count == 1 # pay polled
|
||||
payment_status.reset_mock()
|
||||
|
||||
resp = resp.follow()
|
||||
assert 'Some items are already paid or' in resp
|
||||
assert len(resp.pyquery('.lingo-basket-cell')) == 0
|
||||
assert 'Running' in resp.pyquery('.lingo-recent-transactions-cell').text()
|
||||
assert payment_status.call_count == 1 # transactions cell polled
|
||||
payment_status.reset_mock()
|
||||
|
||||
# Simulate paid status on polling
|
||||
payment_status.return_value = eopayment.common.PaymentResponse(
|
||||
|
@ -2193,12 +2220,17 @@ class TestPolling:
|
|||
assert 'foo item: 42.00' in resp
|
||||
assert 'Pay' not in resp
|
||||
assert 'Running' not in resp
|
||||
assert len(resp.pyquery('.lingo-basket-cell')) == 0
|
||||
assert '42.00' in resp.pyquery('.lingo-recent-transactions-cell').text()
|
||||
assert payment_status.call_count == 1 # transactions cell polled
|
||||
payment_status.reset_mock()
|
||||
|
||||
@mock.patch('eopayment.payfip_ws.Payment.payment_status')
|
||||
def test_exception_during_polling(
|
||||
self,
|
||||
payment_status,
|
||||
app,
|
||||
synchronous_cells,
|
||||
caplog,
|
||||
):
|
||||
# Try to pay
|
||||
|
|
Loading…
Reference in New Issue