Coverage for expo_notifications/tasks/check_receipts_task.py: 30%

30 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-16 14:48 +0000

1from celery import shared_task 

2from django.utils import timezone 

3from exponent_server_sdk import ( 

4 DeviceNotRegisteredError, 

5 PushClient, 

6 PushReceipt, 

7 PushServerError, 

8 PushTicketError, 

9) 

10from requests.exceptions import ConnectionError, HTTPError 

11 

12from expo_notifications.conf import settings 

13from expo_notifications.models import Receipt, Ticket 

14from expo_notifications.tasks.session import session 

15 

16 

17@shared_task( 

18 bind=True, 

19 ignore_result=True, 

20 max_retries=settings.checking_task_max_retries, 

21 default_retry_delay=settings.checking_task_retry_delay.total_seconds(), 

22) 

23def check_receipts(self, ticket_pks: list[str]) -> None: 

24 tickets = Ticket.objects.filter(pk__in=ticket_pks).exclude(external_id="") 

25 

26 push_tickets = [ticket.to_push_ticket() for ticket in tickets] 

27 

28 push_client = PushClient(session=session) 

29 

30 try: 

31 push_receipts: list[PushReceipt] = push_client.check_receipts_multiple( 

32 push_tickets 

33 ) 

34 except PushServerError: 

35 raise self.retry() 

36 except (ConnectionError, HTTPError): 

37 raise self.retry() 

38 

39 receipts: list[Receipt] = [] 

40 

41 for push_receipt in push_receipts: 

42 ticket = tickets.get(external_id=push_receipt.id) 

43 

44 try: 

45 push_receipt.validate_response() 

46 except DeviceNotRegisteredError: 

47 ticket.message.device.is_active = False 

48 ticket.message.device.save() 

49 except PushTicketError: 

50 pass 

51 

52 receipts.append( 

53 Receipt( 

54 ticket=ticket, 

55 is_success=push_receipt.is_success(), 

56 error_message=push_receipt.message, 

57 date_checked=timezone.now(), 

58 ) 

59 ) 

60 

61 Receipt.objects.bulk_create(receipts)