Exemplo n.º 1
0
def test_loan_utils(client, patron_martigny_no_email,
                    patron2_martigny_no_email, circulation_policies,
                    loan_pending_martigny, item_lib_martigny):
    """Test loan utils."""
    loan = {
        'item_pid': item_lib_martigny.pid,
        'patron_pid': patron_martigny_no_email.pid
    }
    assert can_be_requested(loan)

    del loan['item_pid']
    with pytest.raises(Exception):
        assert can_be_requested(loan)

    assert loan_pending_martigny.patron_pid == patron2_martigny_no_email.pid
    assert not loan_pending_martigny.is_active

    with pytest.raises(TypeError):
        assert get_loans_by_patron_pid()
    assert get_loans_by_patron_pid(patron2_martigny_no_email.pid)

    with pytest.raises(TypeError):
        assert get_last_transaction_loc_for_item()

    assert loan_pending_martigny.organisation_pid

    new_loan = deepcopy(loan_pending_martigny)
    assert new_loan.organisation_pid
    del new_loan['item_pid']
    assert not new_loan.organisation_pid
Exemplo n.º 2
0
def test_due_soon_loans(client, librarian_martigny, patron_martigny,
                        loc_public_martigny, item_type_standard_martigny,
                        item_lib_martigny, circ_policy_short_martigny):
    """Test overdue loans."""
    login_user_via_session(client, librarian_martigny.user)
    item = item_lib_martigny
    item_pid = item.pid
    patron_pid = patron_martigny.pid

    assert not get_last_transaction_loc_for_item(item_pid)

    assert not item.patron_has_an_active_loan_on_item(patron_martigny)
    assert item.can_delete
    assert item.available

    from rero_ils.modules.circ_policies.api import CircPolicy
    circ_policy = CircPolicy.provide_circ_policy(
        item.organisation_pid, item.library_pid,
        patron_martigny.patron_type_pid, item.item_type_pid)
    circ_policy['reminders'][0]['days_delay'] = 7
    circ_policy['checkout_duration'] = 3
    circ_policy.update(circ_policy, dbcommit=True, reindex=True)

    # checkout
    res, data = postdata(
        client, 'api_item.checkout',
        dict(
            item_pid=item_pid,
            patron_pid=patron_pid,
            transaction_location_pid=loc_public_martigny.pid,
            transaction_user_pid=librarian_martigny.pid,
        ))
    assert res.status_code == 200
    loan_pid = data.get('action_applied')[LoanAction.CHECKOUT].get('pid')
    due_soon_loans = get_due_soon_loans()
    assert due_soon_loans[0].get('pid') == loan_pid

    # test due date regarding multiple timezones
    checkout_loan = Loan.get_record_by_pid(loan_pid)
    loan_date = ciso8601.parse_datetime(checkout_loan.get('end_date'))

    # as instance timezone is Europe/Zurich, it should be either 21 or 22
    check_timezone_date(pytz.utc, loan_date, [21, 22])

    # should be 14:59/15:59 in US/Pacific (because of daylight saving time)

    check_timezone_date(pytz.timezone('US/Pacific'), loan_date, [14, 15])
    check_timezone_date(pytz.timezone('Europe/Amsterdam'), loan_date)

    # checkin the item to put it back to it's original state
    res, _ = postdata(
        client, 'api_item.checkin',
        dict(item_pid=item_pid,
             pid=loan_pid,
             transaction_location_pid=loc_public_martigny.pid,
             transaction_user_pid=librarian_martigny.pid))
    assert res.status_code == 200
Exemplo n.º 3
0
def test_loan_utils(client, patron_martigny_no_email,
                    patron2_martigny_no_email, circulation_policies,
                    loan_pending_martigny, item_lib_martigny,
                    loc_public_martigny):
    """Test loan utils."""
    loan_metadata = dict(item_lib_martigny)
    if 'item_pid' not in loan_metadata:
        loan_metadata['item_pid'] = item_lib_martigny.pid
    if 'patron_pid' not in loan_metadata:
        loan_metadata['patron_pid'] = patron_martigny_no_email.pid
    # Create "virtual" Loan (not registered)
    loan = Loan(loan_metadata)
    assert can_be_requested(loan)

    del loan['item_pid']
    with pytest.raises(Exception):
        assert can_be_requested(loan)

    assert loan_pending_martigny.patron_pid == patron2_martigny_no_email.pid
    assert not loan_pending_martigny.is_active

    with pytest.raises(TypeError):
        assert get_loans_by_patron_pid()
    assert get_loans_by_patron_pid(patron2_martigny_no_email.pid)

    with pytest.raises(TypeError):
        assert get_last_transaction_loc_for_item()

    assert loan_pending_martigny.organisation_pid

    new_loan = deepcopy(loan_pending_martigny)
    assert new_loan.organisation_pid
    del new_loan['item_pid']
    with pytest.raises(IlsRecordError.PidDoesNotExist):
        new_loan.organisation_pid

    new_loan = deepcopy(loan_pending_martigny)
    assert can_be_requested(new_loan)
    loc_public_martigny['allow_request'] = False
    loc_public_martigny.update(
        loc_public_martigny,
        dbcommit=True,
        reindex=True
    )
    flush_index(LocationsSearch.Meta.index)
    assert not can_be_requested(new_loan)

    loc_public_martigny['allow_request'] = True
    loc_public_martigny.update(
        loc_public_martigny,
        dbcommit=True,
        reindex=True
    )
    flush_index(LocationsSearch.Meta.index)
Exemplo n.º 4
0
def test_loan_utils(client, patron_martigny_no_email,
                    patron2_martigny_no_email, circulation_policies,
                    item_lib_martigny, librarian_martigny_no_email,
                    loc_public_martigny):
    """Test loan utils methods."""
    loan_metadata = dict(item_lib_martigny)
    loan_metadata['item_pid'] = item_pid_to_object(item_lib_martigny.pid)
    if 'patron_pid' not in loan_metadata:
        loan_metadata['patron_pid'] = patron_martigny_no_email.pid
    # Create "virtual" Loan (not registered)
    loan = Loan(loan_metadata)
    # test that loan can successfully move to the pending state
    assert can_be_requested(loan)

    # test that loan without an item may not move to the pending state
    del loan['item_pid']
    with pytest.raises(Exception):
        assert can_be_requested(loan)

    # test a pending loan will be attached at the right organisation and
    # will not be considered as an active loan
    params = {
        'patron_pid': patron2_martigny_no_email.pid,
        'transaction_location_pid': loc_public_martigny.pid,
        'transaction_user_pid': librarian_martigny_no_email.pid,
        'pickup_location_pid': loc_public_martigny.pid
    }
    item, loan_pending_martigny = item_record_to_a_specific_loan_state(
        item=item_lib_martigny, loan_state=LoanState.PENDING,
        params=params, copy_item=True)

    assert loan_pending_martigny.patron_pid == patron2_martigny_no_email.pid
    assert not loan_pending_martigny.is_active
    assert loan_pending_martigny.organisation_pid

    # test required parameters for get_loans_by_patron_pid
    with pytest.raises(TypeError):
        assert get_loans_by_patron_pid()
    assert get_loans_by_patron_pid(patron2_martigny_no_email.pid)

    # test required parameters for get_last_transaction_loc_for_item
    with pytest.raises(TypeError):
        assert get_last_transaction_loc_for_item()

    # test the organisation of the loan is based on the item
    new_loan = deepcopy(loan_pending_martigny)
    assert new_loan.organisation_pid
    del new_loan['item_pid']
    with pytest.raises(IlsRecordError.PidDoesNotExist):
        new_loan.organisation_pid
    assert not can_be_requested(loan_pending_martigny)

    # test the allow request at the location level
    loc_public_martigny['allow_request'] = False
    loc_public_martigny.update(
        loc_public_martigny,
        dbcommit=True,
        reindex=True
    )
    flush_index(LocationsSearch.Meta.index)
    new_loan = {
        'patron_pid': patron_martigny_no_email.pid,
        'transaction_location_pid': loc_public_martigny.pid,
        'transaction_user_pid': librarian_martigny_no_email.pid,
        'pickup_location_pid': loc_public_martigny.pid
    }
    with pytest.raises(RecordCannotBeRequestedError):
        item, loan_pending_martigny = item_record_to_a_specific_loan_state(
            item=item_lib_martigny, loan_state=LoanState.PENDING,
            params=params, copy_item=True)

    loc_public_martigny['allow_request'] = True
    loc_public_martigny.update(
        loc_public_martigny,
        dbcommit=True,
        reindex=True
    )
    flush_index(LocationsSearch.Meta.index)
    item, loan_pending_martigny = item_record_to_a_specific_loan_state(
        item=item_lib_martigny, loan_state=LoanState.PENDING,
        params=params, copy_item=True)
    assert loan_pending_martigny['state'] == LoanState.PENDING
Exemplo n.º 5
0
def test_due_soon_loans(client, librarian_martigny, lib_martigny_data,
                        lib_martigny, patron_martigny, loc_public_martigny,
                        item_type_standard_martigny, item_lib_martigny,
                        circ_policy_short_martigny, yesterday):
    """Test overdue loans."""
    login_user_via_session(client, librarian_martigny.user)
    item = item_lib_martigny
    item_pid = item.pid
    patron_pid = patron_martigny.pid
    can, reasons = item.can_delete
    assert can
    assert reasons == {}
    assert item.available
    assert not get_last_transaction_loc_for_item(item_pid)
    assert not item.patron_has_an_active_loan_on_item(patron_martigny)

    from rero_ils.modules.circ_policies.api import CircPolicy
    circ_policy = CircPolicy.provide_circ_policy(
        item.organisation_pid, item.library_pid,
        patron_martigny.patron_type_pid, item.item_type_pid)
    circ_policy['reminders'][0]['days_delay'] = 7
    circ_policy['checkout_duration'] = 3
    circ_policy.update(circ_policy, dbcommit=True, reindex=True)

    # Remove library exception date to ensure to not been annoyed by
    # closed dates.
    custom_lib_data = deepcopy(lib_martigny_data)
    custom_lib_data['exception_dates'] = []
    lib_martigny.update(custom_lib_data, dbcommit=True, reindex=True)
    flush_index(LibrariesSearch.Meta.index)

    # checkout
    res, data = postdata(
        client, 'api_item.checkout',
        dict(
            item_pid=item_pid,
            patron_pid=patron_pid,
            transaction_location_pid=loc_public_martigny.pid,
            transaction_user_pid=librarian_martigny.pid,
        ))
    assert res.status_code == 200
    loan_pid = data.get('action_applied')[LoanAction.CHECKOUT].get('pid')
    # To be considerate as 'due_soon', we need to update the loan start date
    # to figure than start_date occurs before due_date.
    loan = Loan.get_record_by_pid(loan_pid)
    start_date = ciso8601.parse_datetime(loan.get('start_date'))
    loan['start_date'] = (start_date - timedelta(days=30)).isoformat()
    loan.update(loan, dbcommit=True, reindex=True)

    due_soon_loans = list(get_due_soon_loans())
    assert due_soon_loans[0].get('pid') == loan_pid

    # test due date regarding multiple timezones
    checkout_loan = Loan.get_record_by_pid(loan_pid)
    loan_date = ciso8601.parse_datetime(checkout_loan.get('end_date'))

    # as instance timezone is Europe/Zurich, it should be either 21 or 22
    check_timezone_date(pytz.utc, loan_date, [21, 22])

    # should be 14:59/15:59 in US/Pacific (because of daylight saving time)
    check_timezone_date(pytz.timezone('US/Pacific'), loan_date, [14, 15])
    check_timezone_date(pytz.timezone('Europe/Amsterdam'), loan_date)

    # checkin the item to put it back to it's original state
    res, _ = postdata(
        client, 'api_item.checkin',
        dict(item_pid=item_pid,
             pid=loan_pid,
             transaction_location_pid=loc_public_martigny.pid,
             transaction_user_pid=librarian_martigny.pid))
    assert res.status_code == 200

    # reset lib
    lib_martigny.update(lib_martigny_data, dbcommit=True, reindex=True)