invenio-app-ils 4.5.0__py2.py3-none-any.whl → 5.0.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- invenio_app_ils/__init__.py +1 -1
- invenio_app_ils/assets/semantic-ui/less/theme.config +103 -0
- invenio_app_ils/circulation/api.py +9 -5
- invenio_app_ils/circulation/config.py +1 -0
- invenio_app_ils/circulation/loaders/schemas/json/loan_checkout.py +1 -1
- invenio_app_ils/circulation/loaders/schemas/json/loan_request.py +2 -2
- invenio_app_ils/circulation/notifications/api.py +9 -1
- invenio_app_ils/circulation/notifications/messages.py +2 -1
- invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/update_dates.html +19 -0
- invenio_app_ils/cli.py +92 -64
- invenio_app_ils/config.py +10 -2
- invenio_app_ils/documents/loaders/jsonschemas/document.py +1 -1
- invenio_app_ils/eitems/loaders/jsonschemas/eitems.py +2 -2
- invenio_app_ils/patrons/anonymization.py +0 -4
- invenio_app_ils/series/loaders/jsonschemas/series.py +1 -1
- invenio_app_ils/webpack.py +27 -0
- {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/METADATA +56 -43
- {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/RECORD +24 -112
- {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/entry_points.txt +3 -0
- {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/top_level.txt +0 -1
- invenio_app_ils/notifications/admin.py +0 -57
- tests/__init__.py +0 -8
- tests/api/__init__.py +0 -8
- tests/api/acquisition/__init__.py +0 -8
- tests/api/acquisition/test_acq_orders_crud.py +0 -99
- tests/api/acquisition/test_acq_orders_permissions.py +0 -104
- tests/api/acquisition/test_acq_providers_permissions.py +0 -83
- tests/api/circulation/__init__.py +0 -8
- tests/api/circulation/test_expired_loans.py +0 -88
- tests/api/circulation/test_loan_bulk_extend.py +0 -169
- tests/api/circulation/test_loan_checkout.py +0 -422
- tests/api/circulation/test_loan_default_durations.py +0 -43
- tests/api/circulation/test_loan_document_resolver.py +0 -18
- tests/api/circulation/test_loan_extend.py +0 -122
- tests/api/circulation/test_loan_item_permissions.py +0 -135
- tests/api/circulation/test_loan_item_resolver.py +0 -26
- tests/api/circulation/test_loan_list_permissions.py +0 -98
- tests/api/circulation/test_loan_patron_resolver.py +0 -38
- tests/api/circulation/test_loan_request.py +0 -338
- tests/api/circulation/test_loan_update.py +0 -150
- tests/api/circulation/test_notifications.py +0 -221
- tests/api/conftest.py +0 -227
- tests/api/document_requests/__init__.py +0 -8
- tests/api/document_requests/test_document_requests.py +0 -131
- tests/api/document_requests/test_document_requests_permissions.py +0 -159
- tests/api/document_requests/test_notifications_filter.py +0 -35
- tests/api/ill/__init__.py +0 -8
- tests/api/ill/test_ill_brw_crud.py +0 -74
- tests/api/ill/test_ill_brw_reqs_patron_loan_create_action.py +0 -198
- tests/api/ill/test_ill_brw_reqs_patron_loan_extension_actions.py +0 -280
- tests/api/ill/test_ill_brw_reqs_permissions.py +0 -163
- tests/api/ill/test_ill_providers_permissions.py +0 -82
- tests/api/ils/__init__.py +0 -8
- tests/api/ils/documents/__init__.py +0 -8
- tests/api/ils/documents/test_document_crud.py +0 -57
- tests/api/ils/documents/test_document_permissions.py +0 -100
- tests/api/ils/documents/test_document_resolvers.py +0 -35
- tests/api/ils/eitems/__init__.py +0 -8
- tests/api/ils/eitems/test_eitems_crud.py +0 -42
- tests/api/ils/eitems/test_eitems_permissions.py +0 -85
- tests/api/ils/eitems/test_files.py +0 -162
- tests/api/ils/items/__init__.py +0 -8
- tests/api/ils/items/test_apis.py +0 -43
- tests/api/ils/items/test_items_crud.py +0 -99
- tests/api/ils/items/test_items_permissions.py +0 -107
- tests/api/ils/records_relations/__init__.py +0 -8
- tests/api/ils/records_relations/helpers.py +0 -115
- tests/api/ils/records_relations/test_records_relations_parentchild.py +0 -560
- tests/api/ils/records_relations/test_records_relations_sequence.py +0 -294
- tests/api/ils/records_relations/test_records_relations_siblings.py +0 -751
- tests/api/ils/series/__init__.py +0 -8
- tests/api/ils/series/test_series_permissions.py +0 -95
- tests/api/ils/test_anonymization.py +0 -181
- tests/api/ils/test_apis.py +0 -76
- tests/api/ils/test_closures.py +0 -353
- tests/api/ils/test_errors.py +0 -125
- tests/api/ils/test_facets.py +0 -88
- tests/api/ils/test_internal_locations.py +0 -96
- tests/api/ils/test_loaders.py +0 -51
- tests/api/ils/test_metadata_extensions.py +0 -206
- tests/api/ils/test_notifications.py +0 -173
- tests/api/ils/test_notifications_mails.py +0 -37
- tests/api/ils/test_notifications_permissions.py +0 -55
- tests/api/ils/test_patrons.py +0 -102
- tests/api/ils/test_record_delete.py +0 -42
- tests/api/ils/test_record_permissions.py +0 -132
- tests/api/ils/test_resolvers.py +0 -205
- tests/api/ils/test_stats.py +0 -142
- tests/api/ils/test_tasks.py +0 -209
- tests/api/ils/test_vocabularies.py +0 -35
- tests/conftest.py +0 -221
- tests/data/acq_orders.json +0 -110
- tests/data/acq_providers.json +0 -12
- tests/data/document_requests.json +0 -77
- tests/data/documents.json +0 -238
- tests/data/eitems.json +0 -71
- tests/data/ill_borrowing_requests.json +0 -77
- tests/data/ill_providers.json +0 -12
- tests/data/internal_locations.json +0 -22
- tests/data/items.json +0 -304
- tests/data/loans.json +0 -133
- tests/data/loans_most_loaned.json +0 -128
- tests/data/locations.json +0 -26
- tests/data/series.json +0 -33
- tests/helpers.py +0 -107
- tests/templates/notifications/title_body.html +0 -8
- tests/templates/notifications/title_body_html.html +0 -13
- tests/templates/notifications/title_body_html_ctx.html +0 -13
- tests/templates/notifications/title_only.html +0 -3
- tests/test_post_logout_redirect.py +0 -23
- tests/test_version.py +0 -17
- /tests/templates/notifications/blank.html → /invenio_app_ils/assets/semantic-ui/templates/.gitkeep +0 -0
- {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/WHEEL +0 -0
- {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/licenses/AUTHORS.rst +0 -0
- {invenio_app_ils-4.5.0.dist-info → invenio_app_ils-5.0.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2020 CERN.
|
|
4
|
-
#
|
|
5
|
-
# invenio-app-ils is free software; you can redistribute it and/or modify it
|
|
6
|
-
# under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
-
|
|
8
|
-
"""Test acquisition orders."""
|
|
9
|
-
|
|
10
|
-
import json
|
|
11
|
-
|
|
12
|
-
from flask import url_for
|
|
13
|
-
|
|
14
|
-
from tests.helpers import user_login
|
|
15
|
-
|
|
16
|
-
_HTTP_OK = [200, 201, 204]
|
|
17
|
-
ORDER_PID = "acqoid-1"
|
|
18
|
-
ITEM_ENDPOINT = "invenio_records_rest.acqoid_item"
|
|
19
|
-
LIST_ENDPOINT = "invenio_records_rest.acqoid_list"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def test_acq_orders_permissions(client, testdata, json_headers, users):
|
|
23
|
-
"""Test orders endpoints permissions."""
|
|
24
|
-
dummy_acquisition_order = dict(
|
|
25
|
-
status="PENDING",
|
|
26
|
-
order_date="2020-02-25",
|
|
27
|
-
provider_pid="acq-provid-1",
|
|
28
|
-
order_lines=[
|
|
29
|
-
dict(
|
|
30
|
-
copies_ordered=3,
|
|
31
|
-
document_pid="docid-1",
|
|
32
|
-
medium="paper",
|
|
33
|
-
recipient="library",
|
|
34
|
-
)
|
|
35
|
-
],
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
def _test_list(expected_status):
|
|
39
|
-
"""Test get list."""
|
|
40
|
-
url = url_for(LIST_ENDPOINT)
|
|
41
|
-
res = client.get(url, headers=json_headers)
|
|
42
|
-
assert res.status_code in expected_status
|
|
43
|
-
|
|
44
|
-
def _test_create(expected_status, data, user):
|
|
45
|
-
"""Test record creation."""
|
|
46
|
-
url = url_for(LIST_ENDPOINT)
|
|
47
|
-
res = client.post(url, headers=json_headers, data=json.dumps(data))
|
|
48
|
-
assert res.status_code in expected_status
|
|
49
|
-
|
|
50
|
-
if res.status_code < 400:
|
|
51
|
-
ord = res.get_json()["metadata"]
|
|
52
|
-
assert ord["status"] == "PENDING"
|
|
53
|
-
expected_created_by = dict(type="user_id", value=str(user.id))
|
|
54
|
-
assert ord["created_by"] == expected_created_by
|
|
55
|
-
assert not ord.get("updated_by")
|
|
56
|
-
return ord["pid"]
|
|
57
|
-
|
|
58
|
-
def _test_update(expected_status, data, pid, user):
|
|
59
|
-
"""Test record update."""
|
|
60
|
-
pid_value = pid or ORDER_PID
|
|
61
|
-
url = url_for(ITEM_ENDPOINT, pid_value=pid_value)
|
|
62
|
-
res = client.put(url, headers=json_headers, data=json.dumps(data))
|
|
63
|
-
assert res.status_code in expected_status
|
|
64
|
-
if res.status_code < 400:
|
|
65
|
-
expected_changed_by = dict(type="user_id", value=str(user.id))
|
|
66
|
-
ord = res.get_json()["metadata"]
|
|
67
|
-
assert ord["created_by"] == expected_changed_by
|
|
68
|
-
assert ord["updated_by"] == expected_changed_by
|
|
69
|
-
|
|
70
|
-
def _test_read(expected_status, pid):
|
|
71
|
-
"""Test record read."""
|
|
72
|
-
pid_value = pid or ORDER_PID
|
|
73
|
-
url = url_for(ITEM_ENDPOINT, pid_value=pid_value)
|
|
74
|
-
res = client.get(url, headers=json_headers)
|
|
75
|
-
assert res.status_code in expected_status
|
|
76
|
-
|
|
77
|
-
def _test_delete(expected_status, pid):
|
|
78
|
-
"""Test record delete."""
|
|
79
|
-
url = url_for(ITEM_ENDPOINT, pid_value=pid)
|
|
80
|
-
res = client.delete(url, headers=json_headers)
|
|
81
|
-
assert res.status_code in expected_status
|
|
82
|
-
|
|
83
|
-
tests = [
|
|
84
|
-
("admin", _HTTP_OK, dummy_acquisition_order),
|
|
85
|
-
("librarian", _HTTP_OK, dummy_acquisition_order),
|
|
86
|
-
("patron1", [403], dummy_acquisition_order),
|
|
87
|
-
("anonymous", [401], dummy_acquisition_order),
|
|
88
|
-
]
|
|
89
|
-
for username, expected_status, data in tests:
|
|
90
|
-
user = user_login(client, username, users)
|
|
91
|
-
_test_list(expected_status)
|
|
92
|
-
pid = _test_create(expected_status, data, user)
|
|
93
|
-
_test_update(expected_status, data, pid, user)
|
|
94
|
-
_test_read(expected_status, pid)
|
|
95
|
-
|
|
96
|
-
tests = [
|
|
97
|
-
("patron1", [403]),
|
|
98
|
-
("anonymous", [401]),
|
|
99
|
-
("librarian", [403]),
|
|
100
|
-
("admin", [204]),
|
|
101
|
-
]
|
|
102
|
-
for username, expected_status in tests:
|
|
103
|
-
user_login(client, username, users)
|
|
104
|
-
_test_delete(expected_status, ORDER_PID)
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2020 CERN.
|
|
4
|
-
#
|
|
5
|
-
# invenio-app-ils is free software; you can redistribute it and/or modify it
|
|
6
|
-
# under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
-
|
|
8
|
-
"""Test acquisition provider."""
|
|
9
|
-
|
|
10
|
-
import json
|
|
11
|
-
|
|
12
|
-
from flask import url_for
|
|
13
|
-
|
|
14
|
-
from tests.helpers import user_login
|
|
15
|
-
|
|
16
|
-
_HTTP_OK = [200, 201, 204]
|
|
17
|
-
PROVIDER_PID = "acq-provid-1"
|
|
18
|
-
PROVIDER_NAME = "A provider"
|
|
19
|
-
PROVIDER_TYPE = "VENDOR"
|
|
20
|
-
ITEM_ENDPOINT = "invenio_records_rest.provid_item"
|
|
21
|
-
LIST_ENDPOINT = "invenio_records_rest.provid_list"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def test_acq_providers_permissions(client, testdata, json_headers, users):
|
|
25
|
-
"""Test providers endpoints permissions."""
|
|
26
|
-
dummy_acquisition_provider = dict(name=PROVIDER_NAME, type=PROVIDER_TYPE)
|
|
27
|
-
tests = [
|
|
28
|
-
("admin", _HTTP_OK, dummy_acquisition_provider),
|
|
29
|
-
("librarian", _HTTP_OK, dummy_acquisition_provider),
|
|
30
|
-
("patron1", [403], dummy_acquisition_provider),
|
|
31
|
-
("anonymous", [401], dummy_acquisition_provider),
|
|
32
|
-
]
|
|
33
|
-
|
|
34
|
-
def _test_list(expected_status):
|
|
35
|
-
"""Test get list."""
|
|
36
|
-
url = url_for(LIST_ENDPOINT)
|
|
37
|
-
res = client.get(url, headers=json_headers)
|
|
38
|
-
assert res.status_code in expected_status
|
|
39
|
-
|
|
40
|
-
def _test_create(expected_status, data):
|
|
41
|
-
"""Test record creation."""
|
|
42
|
-
url = url_for(LIST_ENDPOINT)
|
|
43
|
-
print("DICT", json.dumps(data))
|
|
44
|
-
res = client.post(url, headers=json_headers, data=json.dumps(data))
|
|
45
|
-
assert res.status_code in expected_status
|
|
46
|
-
|
|
47
|
-
if res.status_code < 400:
|
|
48
|
-
record = res.get_json()["metadata"]
|
|
49
|
-
assert record["name"] == PROVIDER_NAME
|
|
50
|
-
assert record["type"] == PROVIDER_TYPE
|
|
51
|
-
return record["pid"]
|
|
52
|
-
|
|
53
|
-
def _test_update(expected_status, data, pid):
|
|
54
|
-
"""Test record update."""
|
|
55
|
-
pid_value = pid or PROVIDER_PID
|
|
56
|
-
url = url_for(ITEM_ENDPOINT, pid_value=pid_value)
|
|
57
|
-
res = client.put(url, headers=json_headers, data=json.dumps(data))
|
|
58
|
-
assert res.status_code in expected_status
|
|
59
|
-
if res.status_code < 400:
|
|
60
|
-
record = res.get_json()["metadata"]
|
|
61
|
-
assert record["name"] == PROVIDER_NAME
|
|
62
|
-
|
|
63
|
-
def _test_read(expected_status, pid):
|
|
64
|
-
"""Test record read."""
|
|
65
|
-
pid_value = pid or PROVIDER_PID
|
|
66
|
-
url = url_for(ITEM_ENDPOINT, pid_value=pid_value)
|
|
67
|
-
res = client.get(url, headers=json_headers)
|
|
68
|
-
assert res.status_code in expected_status
|
|
69
|
-
|
|
70
|
-
def _test_delete(expected_status, pid):
|
|
71
|
-
"""Test record delete."""
|
|
72
|
-
pid_value = pid or PROVIDER_PID
|
|
73
|
-
url = url_for(ITEM_ENDPOINT, pid_value=pid_value)
|
|
74
|
-
res = client.delete(url, headers=json_headers)
|
|
75
|
-
assert res.status_code in expected_status
|
|
76
|
-
|
|
77
|
-
for username, expected_status, data in tests:
|
|
78
|
-
user_login(client, username, users)
|
|
79
|
-
_test_list(expected_status)
|
|
80
|
-
pid = _test_create(expected_status, data)
|
|
81
|
-
_test_update(expected_status, data, pid)
|
|
82
|
-
_test_read(expected_status, pid)
|
|
83
|
-
_test_delete(expected_status, pid)
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2020 CERN.
|
|
4
|
-
#
|
|
5
|
-
# invenio-app-ils is free software; you can redistribute it and/or modify it
|
|
6
|
-
# under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
-
|
|
8
|
-
"""Test transitions on expiring loans."""
|
|
9
|
-
|
|
10
|
-
from datetime import timedelta
|
|
11
|
-
|
|
12
|
-
import arrow
|
|
13
|
-
from flask import url_for
|
|
14
|
-
from invenio_indexer.api import RecordIndexer
|
|
15
|
-
from invenio_search import current_search
|
|
16
|
-
|
|
17
|
-
from invenio_app_ils.circulation.tasks import cancel_expired_loan_requests
|
|
18
|
-
from invenio_app_ils.patrons.api import SystemAgent
|
|
19
|
-
from tests.helpers import user_login
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def test_cancel_expired_loans(client, json_headers, db, users, testdata):
|
|
23
|
-
"""Test cancellation of loan requests after expiration date."""
|
|
24
|
-
|
|
25
|
-
user_login(client, "admin", users)
|
|
26
|
-
|
|
27
|
-
def prepare_data():
|
|
28
|
-
"""Prepare data."""
|
|
29
|
-
loans = testdata["loans"]
|
|
30
|
-
|
|
31
|
-
recs = []
|
|
32
|
-
now = arrow.utcnow()
|
|
33
|
-
|
|
34
|
-
def new_expiration_date(loan, date):
|
|
35
|
-
loan["request_expire_date"] = date.date().isoformat()
|
|
36
|
-
loan["state"] = "PENDING"
|
|
37
|
-
loan.commit()
|
|
38
|
-
recs.append(loan)
|
|
39
|
-
|
|
40
|
-
# expired loans
|
|
41
|
-
date = now - timedelta(days=1)
|
|
42
|
-
new_expiration_date(loans[0], date)
|
|
43
|
-
new_expiration_date(loans[1], date)
|
|
44
|
-
date = now - timedelta(days=2)
|
|
45
|
-
new_expiration_date(loans[2], date)
|
|
46
|
-
expired_pids = [loans[0]["pid"], loans[1]["pid"], loans[2]["pid"]]
|
|
47
|
-
|
|
48
|
-
# not expired loans
|
|
49
|
-
not_expired_pids = []
|
|
50
|
-
remaining_not_expired = loans[3:]
|
|
51
|
-
n_days = 0 # today
|
|
52
|
-
for loan in remaining_not_expired:
|
|
53
|
-
date = now + timedelta(days=n_days)
|
|
54
|
-
new_expiration_date(loan, date)
|
|
55
|
-
not_expired_pids.append(loan["pid"])
|
|
56
|
-
n_days += 1
|
|
57
|
-
db.session.commit()
|
|
58
|
-
|
|
59
|
-
indexer = RecordIndexer()
|
|
60
|
-
for rec in recs:
|
|
61
|
-
indexer.index(rec)
|
|
62
|
-
|
|
63
|
-
current_search.flush_and_refresh(index="*")
|
|
64
|
-
return expired_pids, not_expired_pids
|
|
65
|
-
|
|
66
|
-
expired_pids, not_expired_pids = prepare_data()
|
|
67
|
-
|
|
68
|
-
# trigger cancel expired loan requests
|
|
69
|
-
cancel_expired_loan_requests.apply_async()
|
|
70
|
-
|
|
71
|
-
for pid_value in expired_pids:
|
|
72
|
-
res = client.get(
|
|
73
|
-
url_for("invenio_records_rest.loanid_item", pid_value=pid_value),
|
|
74
|
-
headers=json_headers,
|
|
75
|
-
)
|
|
76
|
-
loan = res.get_json()["metadata"]
|
|
77
|
-
assert loan["state"] == "CANCELLED"
|
|
78
|
-
assert "cancel_reason" in loan
|
|
79
|
-
assert loan["transaction_user_pid"] == str(SystemAgent.id)
|
|
80
|
-
|
|
81
|
-
for pid_value in not_expired_pids:
|
|
82
|
-
res = client.get(
|
|
83
|
-
url_for("invenio_records_rest.loanid_item", pid_value=pid_value),
|
|
84
|
-
headers=json_headers,
|
|
85
|
-
)
|
|
86
|
-
loan = res.get_json()["metadata"]
|
|
87
|
-
assert loan["state"] == "PENDING"
|
|
88
|
-
assert "cancel_reason" not in loan
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2019-2020 CERN.
|
|
4
|
-
#
|
|
5
|
-
# invenio-app-ils is free software; you can redistribute it and/or modify it
|
|
6
|
-
# under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
-
|
|
8
|
-
"""Test bulk loan extension."""
|
|
9
|
-
|
|
10
|
-
from datetime import timedelta
|
|
11
|
-
|
|
12
|
-
import arrow
|
|
13
|
-
from flask import current_app
|
|
14
|
-
from invenio_circulation.api import Loan
|
|
15
|
-
from invenio_circulation.pidstore.pids import CIRCULATION_LOAN_PID_TYPE
|
|
16
|
-
from invenio_circulation.proxies import current_circulation
|
|
17
|
-
from invenio_search import current_search
|
|
18
|
-
|
|
19
|
-
from invenio_app_ils.circulation.api import bulk_extend_loans
|
|
20
|
-
from invenio_app_ils.items.api import ITEM_PID_TYPE, Item
|
|
21
|
-
from invenio_app_ils.proxies import current_app_ils
|
|
22
|
-
from tests.api.conftest import _create_records
|
|
23
|
-
from tests.helpers import user_login
|
|
24
|
-
|
|
25
|
-
pid_start_value = 200
|
|
26
|
-
amount_of_ongoing_loans = 3
|
|
27
|
-
amount_of_overdue_loans = 3
|
|
28
|
-
pid_end_value = pid_start_value + amount_of_ongoing_loans + amount_of_overdue_loans
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def create_loans(start=pid_start_value, end=pid_end_value):
|
|
32
|
-
ongoing_loans = []
|
|
33
|
-
overdue_loans = []
|
|
34
|
-
|
|
35
|
-
day_range_loan_extendable = current_app.config[
|
|
36
|
-
"ILS_CIRCULATION_LOAN_WILL_EXPIRE_DAYS"
|
|
37
|
-
]
|
|
38
|
-
|
|
39
|
-
now = arrow.utcnow()
|
|
40
|
-
|
|
41
|
-
start_date_expiring = now.isoformat()
|
|
42
|
-
start_date_overdue = (now - timedelta(days=5)).isoformat()
|
|
43
|
-
|
|
44
|
-
end_date_expiring = (
|
|
45
|
-
now + timedelta(days=day_range_loan_extendable - 1)
|
|
46
|
-
).isoformat()
|
|
47
|
-
end_date_overdue = (now - timedelta(days=2)).isoformat()
|
|
48
|
-
|
|
49
|
-
def loan_generator(pid_value, overdue_loan=False):
|
|
50
|
-
end_date = end_date_overdue if overdue_loan else end_date_expiring
|
|
51
|
-
start_date = start_date_overdue if overdue_loan else start_date_expiring
|
|
52
|
-
|
|
53
|
-
loan = {
|
|
54
|
-
"document_pid": "docid-1",
|
|
55
|
-
"end_date": end_date,
|
|
56
|
-
"item_pid": {"type": "pitmid", "value": f"itemid-{pid_value}"},
|
|
57
|
-
"patron_pid": "1",
|
|
58
|
-
"pickup_location_pid": "locid-1",
|
|
59
|
-
"pid": f"loanid-{pid_value}",
|
|
60
|
-
"start_date": start_date,
|
|
61
|
-
"state": "ITEM_ON_LOAN",
|
|
62
|
-
"transaction_location_pid": "locid-1",
|
|
63
|
-
"transaction_user_pid": "1",
|
|
64
|
-
"patron": {"email": "patron1@test.ch"},
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return loan
|
|
68
|
-
|
|
69
|
-
for number in range(start, end):
|
|
70
|
-
if len(ongoing_loans) < amount_of_ongoing_loans:
|
|
71
|
-
ongoing_loans.append(loan_generator(number))
|
|
72
|
-
elif len(overdue_loans) < amount_of_overdue_loans:
|
|
73
|
-
overdue_loans.append(loan_generator(number, True))
|
|
74
|
-
|
|
75
|
-
return ongoing_loans + overdue_loans
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def create_items(start=pid_start_value, end=pid_end_value):
|
|
79
|
-
items = []
|
|
80
|
-
|
|
81
|
-
def items_generator(pid_value):
|
|
82
|
-
item = {
|
|
83
|
-
"pid": f"itemid-{pid_value}",
|
|
84
|
-
"created_by": {"type": "script", "value": "demo"},
|
|
85
|
-
"barcode": f"123456{pid_value}89-1",
|
|
86
|
-
"document_pid": "docid-1",
|
|
87
|
-
"internal_location_pid": "ilocid-1",
|
|
88
|
-
"circulation_restriction": "NO_RESTRICTION",
|
|
89
|
-
"medium": "NOT_SPECIFIED",
|
|
90
|
-
"status": "CAN_CIRCULATE",
|
|
91
|
-
"document": {},
|
|
92
|
-
}
|
|
93
|
-
return item
|
|
94
|
-
|
|
95
|
-
for number in range(start, end):
|
|
96
|
-
items.append(items_generator(number))
|
|
97
|
-
|
|
98
|
-
return items
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def _prepare_data(db, repeated_run_number=0):
|
|
102
|
-
total_loans = amount_of_ongoing_loans + amount_of_overdue_loans
|
|
103
|
-
added_value = repeated_run_number * total_loans + repeated_run_number
|
|
104
|
-
|
|
105
|
-
new_pid_start_value = pid_start_value + added_value
|
|
106
|
-
new_pid_end_value = pid_end_value + added_value
|
|
107
|
-
|
|
108
|
-
loans = create_loans(new_pid_start_value, new_pid_end_value)
|
|
109
|
-
items = create_items(new_pid_start_value, new_pid_end_value)
|
|
110
|
-
|
|
111
|
-
bulk_index_items = _create_records(db, items, Item, ITEM_PID_TYPE)
|
|
112
|
-
bulk_index_loans = _create_records(db, loans, Loan, CIRCULATION_LOAN_PID_TYPE)
|
|
113
|
-
|
|
114
|
-
for item in bulk_index_items:
|
|
115
|
-
current_app_ils.item_indexer.index(item)
|
|
116
|
-
|
|
117
|
-
for loan in bulk_index_loans:
|
|
118
|
-
current_circulation.loan_indexer().index(loan)
|
|
119
|
-
|
|
120
|
-
current_search.flush_and_refresh(index="*")
|
|
121
|
-
|
|
122
|
-
return {"loans": bulk_index_loans, "items": bulk_index_items}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
def test_loan_extend_permissions(
|
|
126
|
-
client, json_headers, users, testdata, loan_params, db
|
|
127
|
-
):
|
|
128
|
-
def _run_asserts(extended_loans, loans, patron_pid="1"):
|
|
129
|
-
assert len(extended_loans) >= len(loans)
|
|
130
|
-
|
|
131
|
-
for extended_loan in extended_loans:
|
|
132
|
-
for loan in loans:
|
|
133
|
-
if loan["pid"] == extended_loan["pid"]:
|
|
134
|
-
assert extended_loan["state"] == "ITEM_ON_LOAN"
|
|
135
|
-
assert extended_loan["patron_pid"] == str(patron_pid)
|
|
136
|
-
assert extended_loan["end_date"] > loan["end_date"]
|
|
137
|
-
|
|
138
|
-
def test_patron1_can_extend_own_loans():
|
|
139
|
-
patron_1_ongoing_loans = _prepare_data(db)["loans"]
|
|
140
|
-
|
|
141
|
-
user_login(client, "patron1", users)
|
|
142
|
-
|
|
143
|
-
extended_loans, _ = bulk_extend_loans(patron_pid=1)
|
|
144
|
-
|
|
145
|
-
_run_asserts(extended_loans, patron_1_ongoing_loans)
|
|
146
|
-
|
|
147
|
-
def test_library_can_extend_any_loan():
|
|
148
|
-
patron_1_ongoing_loans = _prepare_data(db, repeated_run_number=1)["loans"]
|
|
149
|
-
|
|
150
|
-
user_login(client, "librarian", users)
|
|
151
|
-
|
|
152
|
-
extended_loans, _ = bulk_extend_loans(patron_pid=1)
|
|
153
|
-
|
|
154
|
-
_run_asserts(extended_loans, patron_1_ongoing_loans)
|
|
155
|
-
|
|
156
|
-
def test_patron2_cannot_extend_patron1_loans():
|
|
157
|
-
_prepare_data(db, repeated_run_number=2)
|
|
158
|
-
|
|
159
|
-
user_login(client, "patron2", users)
|
|
160
|
-
|
|
161
|
-
patron1_pid = "1"
|
|
162
|
-
|
|
163
|
-
extended_loans, _ = bulk_extend_loans(patron1_pid)
|
|
164
|
-
|
|
165
|
-
assert len(extended_loans) == 0
|
|
166
|
-
|
|
167
|
-
test_patron1_can_extend_own_loans()
|
|
168
|
-
test_library_can_extend_any_loan()
|
|
169
|
-
test_patron2_cannot_extend_patron1_loans()
|