def test_notification_organisation_pid( org_martigny, notification_availability_martigny): """Test organisation pid has been added during the indexing.""" search = NotificationsSearch() pid = notification_availability_martigny.get('pid') notification = next(search.filter('term', pid=pid).scan()) assert notification.organisation.pid == org_martigny.pid # test notification can_delete assert notification_availability_martigny.get_links_to_me() == {} assert notification_availability_martigny.can_delete
def get_notifications(notification_type, processed=False, not_sent=False): """Returns specific notifications pids. :param notification_type: filter on the notification type. :param processed: filter on already processed notifications. :param not_sent: filter on not yet send notifications. :return a notification pid generator. """ query = NotificationsSearch()\ .filter('term', notification_type=notification_type) \ .source('pid') if not not_sent: query = query.filter('bool', must_not=[ Q('exists', field='notification_sent'), Q('term', notification_sent=False) ]) if processed: query = query.filter('exists', field='process_date') else: query = query.filter('bool', must_not=[Q('exists', field='process_date')]) for hit in query.scan(): yield hit.pid
def test_notification_es_mapping(dummy_notification, loan_validated_martigny): """Test notification elasticsearch mapping.""" search = NotificationsSearch() mapping = get_mapping(search.Meta.index) assert mapping notif = deepcopy(dummy_notification) validated_pid = loan_validated_martigny.get('pid') loan_ref = f'https://bib.rero.ch/api/loans/{validated_pid}' notif['context']['loan']['$ref'] = loan_ref Notification.create(notif, dbcommit=True, delete_pid=True, reindex=True) assert mapping == get_mapping(search.Meta.index)
def number_of_notifications_sent(loan, notification_type=NotificationType.OVERDUE): """Get the number of notifications sent for the given loan. :param loan: the parent loan. :param notification_type: the type of notification to find. :return notification counter. """ trans_date = ciso8601.parse_datetime(loan.get('transaction_date')) return NotificationsSearch()\ .filter('term', context__loan__pid=loan.pid)\ .filter('term', notification_type=notification_type) \ .filter('term', notification_sent=True) \ .filter('range', creation_date={'gt': trans_date}) \ .source().count()
def test_notification_es_mapping(dummy_notification, loan_validated_martigny): """Test notification elasticsearch mapping.""" search = NotificationsSearch() mapping = get_mapping(search.Meta.index) assert mapping notif = deepcopy(dummy_notification) notif_data = { 'loan_url': 'https://ils.rero.ch/api/loans/', 'pid': loan_validated_martigny.get('pid') } loan_ref = '{loan_url}{pid}'.format(**notif_data) notif['loan'] = {"$ref": loan_ref} Notification.create(notif, dbcommit=True, delete_pid=True, reindex=True) assert mapping == get_mapping(search.Meta.index)
def get_notification(loan, notification_type): """Returns specific notification from loan. :param loan: the parent loan. :param notification_type: the type of notification sent. """ from .api import Notification results = NotificationsSearch()\ .filter('term', context__loan__pid=loan.pid)\ .filter('term', notification_type=notification_type) \ .params(preserve_order=True) \ .sort({'creation_date': {"order": "desc"}}) \ .source().scan() try: pid = next(results).pid return Notification.get_record_by_pid(pid) except StopIteration: return None
def test_reminder_notifications_after_extend( item_lib_martigny, patron_martigny, loc_public_martigny, librarian_martigny, circulation_policies, mailbox, client ): """Test any reminder notification could be resend after loan extension.""" # STEP 1 - CREATE BASIC RESOURCES FOR THE TEST # * Create a loan and update it to be considerate as "due soon". # * Run the `notification-creation` task to create a DUE_SOON # notification params = { 'patron_pid': patron_martigny.pid, 'transaction_location_pid': loc_public_martigny.pid, 'transaction_user_pid': librarian_martigny.pid, 'pickup_location_pid': loc_public_martigny.pid } item, loan = item_record_to_a_specific_loan_state( item=item_lib_martigny, loan_state=LoanState.ITEM_ON_LOAN, params=params, copy_item=True) # get the related cipo and check than an due_soon reminder exists cipo = get_circ_policy(loan) due_soon_reminder = cipo.get_reminder(DUE_SOON_REMINDER_TYPE) assert due_soon_reminder # Update the loan delay = due_soon_reminder.get('days_delay') - 1 due_soon_date = datetime.now() - timedelta(days=delay) end_date = datetime.now() + timedelta(days=1) loan['due_soon_date'] = due_soon_date.astimezone(pytz.utc).isoformat() loan['end_date'] = end_date.astimezone(pytz.utc).isoformat() loan = loan.update(loan, dbcommit=True, reindex=True) assert loan.is_loan_due_soon() # run the create notification task and process notification. mailbox.clear() create_notifications(types=[NotificationType.DUE_SOON]) process_notifications(NotificationType.DUE_SOON) first_notification = get_notification(loan, NotificationType.DUE_SOON) assert first_notification \ and first_notification['status'] == NotificationStatus.DONE assert len(mailbox) == 1 counter = NotificationsSearch()\ .filter('term', context__loan__pid=loan.pid)\ .filter('term', notification_type=NotificationType.DUE_SOON)\ .count() assert counter == 1 # STEP 2 - CHECK NOTIFICATIONS CREATION # Run the `create_notification` task for DUE_SOON notification type. # As a notification already exists, no new DUE_SOON#1 notifications # should be created create_notifications(types=[NotificationType.DUE_SOON]) query = NotificationsSearch() \ .filter('term', context__loan__pid=loan.pid) \ .filter('term', notification_type=NotificationType.DUE_SOON) \ .source('pid').scan() notification_pids = [hit.pid for hit in query] assert len(notification_pids) == 1 assert notification_pids[0] == first_notification.pid # STEP 3 - EXTEND THE LOAN # * User has received the DUE_SOON message and extend the loan. # * Get the new 'due_soon_date' it will be used later to create # notifications login_user_via_session(client, librarian_martigny.user) params = dict( item_pid=item.pid, transaction_user_pid=librarian_martigny.pid, transaction_location_pid=loc_public_martigny.pid ) res, _ = postdata(client, 'api_item.extend_loan', params) assert res.status_code == 200 loan = Loan.get_record_by_pid(loan.pid) due_soon_date = ciso8601.parse_datetime(loan.get('due_soon_date')) # STEP 4 - CHECK NOTIFICATIONS CREATION # Run again the `create_notification` task, again for DUE_SOON # notification type. As the loan is extended, a new DUE_SOON # notification should be created about this loan. # Process the notification, check that this new notification isn't # cancelled and well processed. process_date = due_soon_date + timedelta(days=1) create_notifications( types=[NotificationType.DUE_SOON], tstamp=process_date ) counter = NotificationsSearch() \ .filter('term', context__loan__pid=loan.pid) \ .filter('term', notification_type=NotificationType.DUE_SOON) \ .count() assert counter == 2 process_notifications(NotificationType.DUE_SOON) assert len(mailbox) == 2 second_notification = get_notification(loan, NotificationType.DUE_SOON) assert second_notification \ and second_notification['status'] == NotificationStatus.DONE assert second_notification.pid != first_notification