def test_brwreq_accept_decline_extension_only_librarian( client, testdata, json_headers, users): """Test that only librarian can accept or decline an extension.""" tests = [_accept_extension_action, _decline_extension_action] for action in tests: user_login(client, "librarian", users) # create request brwreq, brwreq_pid = _create_on_loan_brwreq_with_pending_extension( "1", client, json_headers) loan_end_date = arrow.utcnow() + timedelta(days=15) data = dict(loan_end_date=loan_end_date.date().isoformat()) # accept/decline # anonymous, forbidden user_logout(client) res = action(brwreq_pid, data, client, json_headers) assert res.status_code == 401 # patron, forbidden user_login(client, "patron1", users) res = action(brwreq_pid, data, client, json_headers) assert res.status_code == 403 # librarian, success user_login(client, "librarian", users) res = action(brwreq_pid, data, client, json_headers) assert res.status_code == 200
def test_brwreq_request_extension_only_owner(client, testdata, json_headers, users): """Test that patron can request extension only for his own loan.""" user_login(client, "librarian", users) brwreq, brwreq_pid = _create_on_loan_brwreq_random_dates( "1", client, json_headers) # anonymous, forbidden user_logout(client) res = _request_extension_action(brwreq_pid, client, json_headers) assert res.status_code == 401 # patron2 is not the owner, forbidden user_login(client, "patron2", users) res = _request_extension_action(brwreq_pid, client, json_headers) assert res.status_code == 403 # patron1 is the owner, success user_login(client, "patron1", users) res = _request_extension_action(brwreq_pid, client, json_headers) assert res.status_code == 200 extension = res.get_json()["metadata"]["patron_loan"]["extension"] assert extension["status"] == "PENDING" assert extension["request_date"] == arrow.now().date().isoformat() # create a new one with patron2 owner, librarian can request extension user_login(client, "librarian", users) brwreq, brwreq_pid = _create_on_loan_brwreq_random_dates( "2", client, json_headers) res = _request_extension_action(brwreq_pid, client, json_headers) assert res.status_code == 200 assert extension["status"] == "PENDING" assert extension["request_date"] == arrow.now().date().isoformat()
def test_stats_downloads_views_permissions(client, json_headers, users, testdata, mocker): """Test permissions on downloads/views stats.""" # mock record_viewed signal because travis timed out and the signal does # not need to be tested here mocker.patch("invenio_app_ils.signals.record_viewed.send", ) url_open_access = url_for("ils_document_stats.docid_stats", pid_value="docid-open-access") url_closed_access = url_for("ils_document_stats.docid_stats", pid_value="docid-closed-access") params = {} params["event"] = "record-view" # permission for librarian user_login(client, "librarian", users) res = client.post(url_open_access, headers=json_headers, data=json.dumps(params)) assert res.status_code == 202 res = client.post(url_closed_access, headers=json_headers, data=json.dumps(params)) assert res.status_code == 202 user_logout(client) # permission for patron user_login(client, "patron1", users) res = client.post(url_open_access, headers=json_headers, data=json.dumps(params)) assert res.status_code == 202 res = client.post(url_closed_access, headers=json_headers, data=json.dumps(params)) assert res.status_code == 403 user_logout(client) # permission for unauthenticated user res = client.post(url_open_access, headers=json_headers, data=json.dumps(params)) assert res.status_code == 202 res = client.post(url_closed_access, headers=json_headers, data=json.dumps(params)) assert res.status_code == 401
def test_most_loaned_permissions(client, json_headers, users, testdata): """Test that only the backoffice is able to list the most loaned items.""" url = url_for("invenio_app_ils_circulation_stats.most-loaned") tests = [ ("admin", 200), ("librarian", 200), ("patron1", 403), ("anonymous", 401), ] for username, status in tests: user_login(client, username, users) res = client.get(url, headers=json_headers) assert res.status_code == status user_logout(client)
def test_anonymization(app, client, json_headers, users, testdata): """Test anonymization of a user.""" # Anonymize patron patron_pid = users["patron3"].id check_user_exists(patron_pid) cancel_active_loans(patron_pid, client, users) anonymize_patron_data(patron_pid) check_user_deleted(patron_pid) user_login(client, "admin", users) check_user_activity(app, patron_pid, client, json_headers) user_logout(client) # Anonymize librarian librarian_pid = users["librarian"].id check_user_exists(librarian_pid) cancel_active_loans(librarian_pid, client, users) anonymize_patron_data(librarian_pid) check_user_deleted(librarian_pid) # Anonymize patron while logged in patron_pid = users["patron2"].id user_login(client, "patron2", users) check_user_exists(patron_pid) cancel_active_loans(patron_pid, client, users) anonymize_patron_data(patron_pid) check_user_deleted(patron_pid) # It should fail when anonymizing patron with active loans patron_pid = users["patron1"].id check_user_exists(patron_pid) with pytest.raises(AnonymizationActiveLoansError): assert anonymize_patron_data(patron_pid)
def test_loan_update_date(client, json_headers, users, testdata): """Test the edition of the dates on a loan.""" pid = testdata["loans"][4]["pid"] # Item on loan # Patron cannot update loan user_login(client, "patron1", users) res = _post_loan_update(client, json_headers, pid) assert res.status_code == 403 user_logout(client) # Librarian can user_login(client, "librarian", users) old_loan = _load_result(client.get(_url_loan(pid), headers=json_headers)) res = _post_loan_update(client, json_headers, pid) assert res.status_code == 202 new_loan = _load_result(res) assert old_loan["updated"] < new_loan["updated"] # Liveness check # Update both values start_date = "2020-01-01" end_date = _today(+1) res = _post_loan_update(client, json_headers, pid, start_date=start_date, end_date=end_date) assert res.status_code == 202 new_loan_meta = _load_result(res)["metadata"] assert new_loan_meta["start_date"] == start_date assert new_loan_meta["end_date"] == end_date # Start date after today start_date = _today(+2) end_date = _today(+3) res = _post_loan_update(client, json_headers, pid, start_date=start_date, end_date=end_date) assert res.status_code == 400 # No relative constraints on non-active loans pid = testdata["loans"][3]["pid"] # Pending res = _post_loan_update(client, json_headers, pid, request_start_date=start_date, request_expire_date=end_date) assert res.status_code == 202 new_loan_meta = _load_result(res)["metadata"] assert new_loan_meta["request_start_date"] == start_date assert new_loan_meta["request_expire_date"] == end_date # Negative date range start_date = "2000-02-01" end_date = "2000-01-01" res = _post_loan_update(client, json_headers, pid, request_start_date=start_date, request_expire_date=end_date) assert res.status_code == 400 # Illegal combination of parameters start_date = _today(-2) end_date = _today(+2) res = _post_loan_update(client, json_headers, pid, start_date=start_date, end_date=end_date, request_start_date=start_date, request_expire_date=end_date) assert res.status_code == 400
def test_email_on_overdue_loans(app_with_mail, db, users, testdata, mocker, client, json_headers): """Test that an email is sent for a loan that is overdue.""" mocker.patch( "invenio_app_ils.patrons.api.Patron.get_patron", return_value=Patron(users["patron1"].id), ) def prepare_data(): """Prepare data.""" days = current_app.config[ "ILS_CIRCULATION_MAIL_OVERDUE_REMINDER_INTERVAL"] loans = testdata["loans"] recs = [] now = arrow.utcnow() def new_end_date(loan, date): loan["end_date"] = date.date().isoformat() loan["state"] = "ITEM_ON_LOAN" loan.commit() recs.append(loan) # overdue loans date = now - timedelta(days=days) new_end_date(loans[0], date) date = now - timedelta(days=days * 2) new_end_date(loans[1], date) # not overdue date = now - timedelta(days=-1) new_end_date(loans[2], date) # not overdue or overdue but not to be notified remaining_not_overdue = loans[3:] for loan in remaining_not_overdue: days = random.choice([-1, 0, 1]) date = now - timedelta(days=days) new_end_date(loan, date) db.session.commit() indexer = RecordIndexer() for rec in recs: indexer.index(rec) current_search.flush_and_refresh(index="*") user_login(client, "librarian", users) # test individual overdue loan prepare_data() loans = testdata["loans"] email_url = url_for( "invenio_app_ils_circulation.loanid_email", pid_value=loans[0]["pid"], ) res = client.post(email_url, headers=json_headers) assert res.status_code == 202 # test individual not overdue loan email_url = url_for( "invenio_app_ils_circulation.loanid_email", pid_value=loans[2]["pid"], ) res = client.post(email_url, headers=json_headers) assert res.status_code == 400 user_logout(client) # test all loans with app_with_mail.extensions["mail"].record_messages() as outbox: assert len(outbox) == 0 send_overdue_loans_mail_reminder.apply_async() assert len(outbox) == 2