invenio-app-rdm 13.0.0b2.dev2__py2.py3-none-any.whl → 13.0.0b2.dev4__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_rdm/__init__.py +1 -1
- invenio_app_rdm/config.py +4 -2
- invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/meta.html +3 -1
- invenio_app_rdm/records_ui/views/decorators.py +91 -8
- invenio_app_rdm/records_ui/views/records.py +7 -4
- invenio_app_rdm/tasks.py +6 -2
- invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/components/CompareRevisionsDropdown.js +6 -0
- invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/components/RevisionsDiffViewer.js +5 -0
- invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/records/CompareRevisions.js +10 -9
- invenio_app_rdm/theme/assets/semantic-ui/less/invenio_app_rdm/theme/globals/site.overrides +1 -1
- invenio_app_rdm/theme/templates/semantic-ui/invenio_app_rdm/help/search.en.html +1 -1
- invenio_app_rdm/urls.py +11 -1
- {invenio_app_rdm-13.0.0b2.dev2.dist-info → invenio_app_rdm-13.0.0b2.dev4.dist-info}/METADATA +20 -1
- {invenio_app_rdm-13.0.0b2.dev2.dist-info → invenio_app_rdm-13.0.0b2.dev4.dist-info}/RECORD +50 -18
- {invenio_app_rdm-13.0.0b2.dev2.dist-info → invenio_app_rdm-13.0.0b2.dev4.dist-info}/WHEEL +1 -1
- {invenio_app_rdm-13.0.0b2.dev2.dist-info → invenio_app_rdm-13.0.0b2.dev4.dist-info}/top_level.txt +1 -0
- tests/__init__.py +8 -0
- tests/api/__init__.py +8 -0
- tests/api/conftest.py +24 -0
- tests/api/test_protect_files_rest.py +73 -0
- tests/api/test_record_api.py +175 -0
- tests/api/test_stats_api.py +26 -0
- tests/conftest.py +313 -0
- tests/fixtures/__init__.py +8 -0
- tests/fixtures/app_data/oai_sets.yaml +3 -0
- tests/fixtures/app_data/pages/about.html +1 -0
- tests/fixtures/app_data/pages.yaml +4 -0
- tests/fixtures/conftest.py +27 -0
- tests/fixtures/test_cli.py +25 -0
- tests/fixtures/test_fixtures.py +46 -0
- tests/mock_module/__init__.py +7 -0
- tests/mock_module/templates/mock_mail.html +28 -0
- tests/mock_module/views.py +32 -0
- tests/redirector/__init__.py +8 -0
- tests/redirector/conftest.py +54 -0
- tests/redirector/test_redirector.py +28 -0
- tests/test_tasks.py +104 -0
- tests/test_utils.py +67 -0
- tests/test_version.py +16 -0
- tests/test_views.py +43 -0
- tests/ui/__init__.py +8 -0
- tests/ui/conftest.py +105 -0
- tests/ui/test_deposits.py +115 -0
- tests/ui/test_export_formats.py +37 -0
- tests/ui/test_filters.py +10 -0
- tests/ui/test_signposting_ui.py +95 -0
- tests/ui/test_static.py +25 -0
- tests/ui/test_stats_ui.py +92 -0
- {invenio_app_rdm-13.0.0b2.dev2.dist-info → invenio_app_rdm-13.0.0b2.dev4.dist-info}/LICENSE +0 -0
- {invenio_app_rdm-13.0.0b2.dev2.dist-info → invenio_app_rdm-13.0.0b2.dev4.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2022 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio App RDM is free software; you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
+
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from invenio_access.permissions import system_identity
|
|
11
|
+
from invenio_pages.proxies import current_pages_service
|
|
12
|
+
from invenio_rdm_records.proxies import current_oaipmh_server_service
|
|
13
|
+
|
|
14
|
+
from invenio_app_rdm.fixtures import StaticPages
|
|
15
|
+
from invenio_app_rdm.fixtures.oai_sets import OAICustomSets
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_load_oai_sets(app):
|
|
19
|
+
dir_ = Path(__file__).parent
|
|
20
|
+
service = current_oaipmh_server_service
|
|
21
|
+
oai_sets = OAICustomSets(
|
|
22
|
+
[dir_ / "app_data", dir_.parent.parent / "invenio_app_rdm/fixtures/data"],
|
|
23
|
+
"oai_sets.yaml",
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
oai_sets.load()
|
|
27
|
+
|
|
28
|
+
res_set = service.search(system_identity, params={"q": f"set1"})
|
|
29
|
+
|
|
30
|
+
assert res_set.total == 1
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_load_pages(app):
|
|
34
|
+
dir_ = Path(__file__).parent
|
|
35
|
+
StaticPages(
|
|
36
|
+
[dir_ / "app_data", dir_.parent.parent / "invenio_app_rdm/fixtures/data"],
|
|
37
|
+
"pages.yaml",
|
|
38
|
+
[dir_ / "app_data/pages", dir_ / "pages"],
|
|
39
|
+
force=True,
|
|
40
|
+
).load()
|
|
41
|
+
|
|
42
|
+
pages = current_pages_service.search(system_identity)
|
|
43
|
+
|
|
44
|
+
assert pages.total == 1
|
|
45
|
+
|
|
46
|
+
assert pages.to_dict()["hits"]["hits"][0]["title"] == "About"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{#
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2022 CERN.
|
|
5
|
+
#
|
|
6
|
+
# Invenio App RDM is free software; you can redistribute it and/or modify it
|
|
7
|
+
# under the terms of the MIT License; see LICENSE file for more details.
|
|
8
|
+
-#}
|
|
9
|
+
|
|
10
|
+
{% set BASE_URL = config.SITE_UI_URL %}
|
|
11
|
+
|
|
12
|
+
{%- for entry in entries -%}
|
|
13
|
+
{{ "ID: %s" | format(entry.file.id) }}
|
|
14
|
+
{{ "URI: %s" | format(entry.file.uri) }}
|
|
15
|
+
{%- if 'filename' in entry %}
|
|
16
|
+
{{ "Name: %s" | format(entry.filename) }}
|
|
17
|
+
{%- endif %}
|
|
18
|
+
{{ "Created: %s" | format(entry.file.created) }}
|
|
19
|
+
{{ "Checksum: %s" | format(entry.file.checksum) }}
|
|
20
|
+
{{ "Last check: %s" | format(entry.file.last_check_at) }}
|
|
21
|
+
{%- if 'record' in entry %}
|
|
22
|
+
{{ "Record: %s/records/%s" | format(BASE_URL, entry.record.id) }}
|
|
23
|
+
{%- endif %}
|
|
24
|
+
{%- if 'draft' in entry %}
|
|
25
|
+
{{ "Draft: %s/uploads/%s" | format(BASE_URL, entry.draft.id) }}
|
|
26
|
+
{%- endif %}
|
|
27
|
+
{{ "-" * 80 }}
|
|
28
|
+
{% endfor %}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2022 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio App RDM 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
|
+
"""Mock module blueprint."""
|
|
8
|
+
|
|
9
|
+
from flask import Blueprint
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def create_blueprint(app):
|
|
13
|
+
"""Creates a blueprint for mock module and registers a mock url rule."""
|
|
14
|
+
blueprint = Blueprint(
|
|
15
|
+
"app_rdm_mock_module",
|
|
16
|
+
__name__,
|
|
17
|
+
template_folder="templates",
|
|
18
|
+
static_folder="static",
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
blueprint.add_url_rule(
|
|
22
|
+
"/test_app_rdm/mock",
|
|
23
|
+
endpoint="test_app_rdm_mock_endpoint",
|
|
24
|
+
view_func=mock_view_func,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
return blueprint
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def mock_view_func(mock_arg):
|
|
31
|
+
"""Mock view function."""
|
|
32
|
+
return mock_arg
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2022 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio App RDM 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
|
+
"""Redirector test fixtures."""
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.fixture(scope="module")
|
|
13
|
+
def app_config(app_config, redirection_rules):
|
|
14
|
+
"""Override pytest-invenio app_config fixture to disable CSRF check."""
|
|
15
|
+
app_config["REDIRECTOR_RULES"] = redirection_rules
|
|
16
|
+
|
|
17
|
+
return app_config
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@pytest.fixture(scope="module")
|
|
21
|
+
def redirection_rules():
|
|
22
|
+
"""Creates a dictionary of redirection rules."""
|
|
23
|
+
|
|
24
|
+
def internal_view_function_str():
|
|
25
|
+
"""Generates a redirection url to a mock endpoint."""
|
|
26
|
+
from flask import request, url_for
|
|
27
|
+
|
|
28
|
+
values = request.view_args
|
|
29
|
+
_type = values["type"]
|
|
30
|
+
values["mock_arg"] = _type
|
|
31
|
+
target = url_for("app_rdm_mock_module.test_app_rdm_mock_endpoint", **values)
|
|
32
|
+
return target
|
|
33
|
+
|
|
34
|
+
def internal_view_function_str():
|
|
35
|
+
"""Generates a redirection tuple(url, code) to a mock endpoint."""
|
|
36
|
+
from flask import request, url_for
|
|
37
|
+
|
|
38
|
+
values = request.view_args
|
|
39
|
+
_type = values["type"]
|
|
40
|
+
values["mock_arg"] = _type
|
|
41
|
+
target = url_for("app_rdm_mock_module.test_app_rdm_mock_endpoint", **values)
|
|
42
|
+
return (target, 302)
|
|
43
|
+
|
|
44
|
+
rules = {
|
|
45
|
+
"test_redirector_endpoint_external": {
|
|
46
|
+
"source": "/test/redirect_external",
|
|
47
|
+
"target": "https://cern.ch/",
|
|
48
|
+
},
|
|
49
|
+
"test_redirector_endpoint_internal": {
|
|
50
|
+
"source": "/test/redirect_internal/<type>",
|
|
51
|
+
"target": internal_view_function_str,
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
return rules
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2022 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio App RDM 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
|
+
"""Redirector tests."""
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_redirector(client_with_login, redirection_rules):
|
|
11
|
+
"""Tests redirector resource."""
|
|
12
|
+
client = client_with_login
|
|
13
|
+
for endpoint, rule in redirection_rules.items():
|
|
14
|
+
source = rule["source"]
|
|
15
|
+
target = rule["target"]
|
|
16
|
+
response = client.get(source)
|
|
17
|
+
expected_url = target
|
|
18
|
+
expected_code = 301
|
|
19
|
+
# Target can be either a url or a function that returns a tuple(url, code)
|
|
20
|
+
if callable(target):
|
|
21
|
+
target_output = target()
|
|
22
|
+
if type(target_output) == tuple:
|
|
23
|
+
expected_url, expected_code = target_output
|
|
24
|
+
else:
|
|
25
|
+
expected_url = target_output
|
|
26
|
+
|
|
27
|
+
assert response.status_code == expected_code
|
|
28
|
+
assert response.headers["location"] == expected_url
|
tests/test_tasks.py
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2022-2024 CERN.
|
|
4
|
+
#
|
|
5
|
+
# Invenio App RDM 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
|
+
"""Test invenio-app-rdm celery tasks."""
|
|
8
|
+
|
|
9
|
+
from invenio_app_rdm.tasks import file_integrity_report
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_task_file_integrity_report(app, invalid_file_instance):
|
|
13
|
+
"""Test celery task for file integrity reports."""
|
|
14
|
+
assert invalid_file_instance.last_check is False
|
|
15
|
+
|
|
16
|
+
# A report must be generated for the file
|
|
17
|
+
mail = app.extensions.get("mail")
|
|
18
|
+
assert mail
|
|
19
|
+
|
|
20
|
+
recipients = "test@invenio.org"
|
|
21
|
+
sender = "test@invenio.org"
|
|
22
|
+
|
|
23
|
+
file_name = invalid_file_instance.objects[0].key
|
|
24
|
+
uri = invalid_file_instance.uri
|
|
25
|
+
file_id = invalid_file_instance.id
|
|
26
|
+
file_name = invalid_file_instance.objects[0].key
|
|
27
|
+
checksum = invalid_file_instance.checksum
|
|
28
|
+
|
|
29
|
+
with mail.record_messages() as outbox:
|
|
30
|
+
# Configure email and validate that email was sent
|
|
31
|
+
app.config["APP_RDM_FILES_INTEGRITY_REPORT_TEMPLATE"] = "mock_mail.html"
|
|
32
|
+
app.config["APP_RDM_ADMIN_EMAIL_RECIPIENT"] = recipients
|
|
33
|
+
app.config["MAIL_DEFAULT_SENDER"] = sender
|
|
34
|
+
|
|
35
|
+
file_integrity_report()
|
|
36
|
+
assert len(outbox) == 1
|
|
37
|
+
mail_sent = outbox[0]
|
|
38
|
+
assert mail_sent.recipients == [recipients]
|
|
39
|
+
assert mail_sent.sender == sender
|
|
40
|
+
assert "Checksum: {}".format(checksum) in mail_sent.body
|
|
41
|
+
assert "URI: {}".format(uri) in mail_sent.body
|
|
42
|
+
assert "ID: {}".format(str(file_id)) in mail_sent.body
|
|
43
|
+
assert "Name: {}".format(file_name) in mail_sent.body
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_integrity_report_invalid_template(app, invalid_file_instance):
|
|
47
|
+
"""Test non-existant e-mail template."""
|
|
48
|
+
assert invalid_file_instance.last_check is False
|
|
49
|
+
|
|
50
|
+
mail = app.extensions.get("mail")
|
|
51
|
+
assert mail
|
|
52
|
+
|
|
53
|
+
with mail.record_messages() as outbox:
|
|
54
|
+
# Remove the template, no e-mail is sent
|
|
55
|
+
app.config["APP_RDM_FILES_INTEGRITY_REPORT_TEMPLATE"] = None
|
|
56
|
+
file_integrity_report()
|
|
57
|
+
assert len(outbox) == 0
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def test_integrity_report_invalid_addresses(app, invalid_file_instance):
|
|
61
|
+
"""Test invalid recipient address."""
|
|
62
|
+
assert invalid_file_instance.last_check is False
|
|
63
|
+
|
|
64
|
+
mail = app.extensions.get("mail")
|
|
65
|
+
assert mail
|
|
66
|
+
|
|
67
|
+
with mail.record_messages() as outbox:
|
|
68
|
+
# Use mock template
|
|
69
|
+
app.config["APP_RDM_FILES_INTEGRITY_REPORT_TEMPLATE"] = "mock_mail.html"
|
|
70
|
+
|
|
71
|
+
# Recipient is not set, mail is not sent.
|
|
72
|
+
app.config["APP_RDM_ADMIN_EMAIL_RECIPIENT"] = None
|
|
73
|
+
file_integrity_report()
|
|
74
|
+
assert len(outbox) == 0
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def test_integrity_report_default_template(app, invalid_file_instance):
|
|
78
|
+
"""Test invalid recipient address."""
|
|
79
|
+
assert invalid_file_instance.last_check is False
|
|
80
|
+
|
|
81
|
+
mail = app.extensions.get("mail")
|
|
82
|
+
assert mail
|
|
83
|
+
|
|
84
|
+
recipients = "test@invenio.org"
|
|
85
|
+
sender = "test@invenio.org"
|
|
86
|
+
|
|
87
|
+
uri = invalid_file_instance.uri
|
|
88
|
+
file_id = invalid_file_instance.id
|
|
89
|
+
file_name = invalid_file_instance.objects[0].key
|
|
90
|
+
checksum = invalid_file_instance.checksum
|
|
91
|
+
|
|
92
|
+
with mail.record_messages() as outbox:
|
|
93
|
+
# Use default template
|
|
94
|
+
app.config["APP_RDM_ADMIN_EMAIL_RECIPIENT"] = recipients
|
|
95
|
+
app.config["MAIL_DEFAULT_SENDER"] = sender
|
|
96
|
+
file_integrity_report()
|
|
97
|
+
assert len(outbox) == 1
|
|
98
|
+
mail_sent = outbox[0]
|
|
99
|
+
assert mail_sent.recipients == [recipients]
|
|
100
|
+
assert mail_sent.sender == sender
|
|
101
|
+
assert "Checksum: {}".format(checksum) in mail_sent.body
|
|
102
|
+
assert "URI: {}".format(uri) in mail_sent.body
|
|
103
|
+
assert "ID: {}".format(str(file_id)) in mail_sent.body
|
|
104
|
+
assert "Name: {}".format(file_name) in mail_sent.body
|
tests/test_utils.py
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2021 TU Wien.
|
|
4
|
+
#
|
|
5
|
+
# Invenio App RDM 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
|
+
"""Tests for utility functions."""
|
|
9
|
+
|
|
10
|
+
from datetime import datetime
|
|
11
|
+
|
|
12
|
+
from invenio_app_rdm.records_ui.utils import set_default_value
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_set_default_value__value():
|
|
16
|
+
"""Test setting a value."""
|
|
17
|
+
dict_ = {"metadata": {"publication_date": None}}
|
|
18
|
+
value = "1939-01-01"
|
|
19
|
+
path = "publication_date"
|
|
20
|
+
|
|
21
|
+
set_default_value(dict_, value, path)
|
|
22
|
+
|
|
23
|
+
assert dict_["metadata"]["publication_date"] == value
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_set_default_value__callable():
|
|
27
|
+
"""Test setting a value via a callable."""
|
|
28
|
+
dict_ = {"metadata": {"publication_date": None}}
|
|
29
|
+
|
|
30
|
+
def func():
|
|
31
|
+
return datetime.now().strftime("%Y-%m-%d")
|
|
32
|
+
|
|
33
|
+
path = "publication_date"
|
|
34
|
+
today = func()
|
|
35
|
+
|
|
36
|
+
set_default_value(dict_, func, path)
|
|
37
|
+
|
|
38
|
+
assert dict_["metadata"]["publication_date"] == today
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_set_default_value__no_path_prefix():
|
|
42
|
+
"""Test setting a value for an unprefixed path."""
|
|
43
|
+
dict_ = {"metadata": {"publication_date": None}}
|
|
44
|
+
value = "1939-01-01"
|
|
45
|
+
path = ".publication_date"
|
|
46
|
+
|
|
47
|
+
set_default_value(dict_, value, path)
|
|
48
|
+
|
|
49
|
+
assert dict_["metadata"]["publication_date"] is None
|
|
50
|
+
assert dict_["publication_date"] == value
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_set_default_value__explicit_and_automatic_prefix():
|
|
54
|
+
"""Compare values set with auto-prefix and explicit prefix."""
|
|
55
|
+
dict1 = {"metadata": {"publication_date": None}}
|
|
56
|
+
dict2 = dict1.copy()
|
|
57
|
+
value = "1939-01-01"
|
|
58
|
+
path1 = "publication_date"
|
|
59
|
+
path2 = ".metadata.publication_date"
|
|
60
|
+
|
|
61
|
+
set_default_value(dict1, value, path1)
|
|
62
|
+
set_default_value(dict2, value, path2)
|
|
63
|
+
|
|
64
|
+
assert (
|
|
65
|
+
dict1["metadata"]["publication_date"] == dict2["metadata"]["publication_date"]
|
|
66
|
+
)
|
|
67
|
+
assert dict1["metadata"]["publication_date"] == value
|
tests/test_version.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2019 CERN.
|
|
4
|
+
# Copyright (C) 2019 Northwestern University.
|
|
5
|
+
#
|
|
6
|
+
# Invenio App RDM is free software; you can redistribute it and/or modify it
|
|
7
|
+
# under the terms of the MIT License; see LICENSE file for more details.
|
|
8
|
+
|
|
9
|
+
"""Simple test of version import."""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_version():
|
|
13
|
+
"""Test version import."""
|
|
14
|
+
from invenio_app_rdm import __version__
|
|
15
|
+
|
|
16
|
+
assert __version__
|
tests/test_views.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2024 CERN.
|
|
4
|
+
# Copyright (C) 2024 KTH Royal Institute of Technology.
|
|
5
|
+
#
|
|
6
|
+
# Invenio-RDM is free software; you can redistribute it and/or modify
|
|
7
|
+
# it under the terms of the MIT License; see LICENSE file for more details.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from unittest.mock import Mock, patch
|
|
11
|
+
|
|
12
|
+
import pytest
|
|
13
|
+
|
|
14
|
+
from invenio_app_rdm.theme.views import add_static_page_routes
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def test_add_static_page_routes():
|
|
18
|
+
"""Test add_static_page_routes function."""
|
|
19
|
+
|
|
20
|
+
# Mocking the blueprint and app objects
|
|
21
|
+
mock_blueprint = Mock()
|
|
22
|
+
mock_app = Mock()
|
|
23
|
+
mock_app.config = {"APP_RDM_PAGES": {"endpoint1": "/path1", "endpoint2": "/path2"}}
|
|
24
|
+
|
|
25
|
+
# Mocking the create_page_view function
|
|
26
|
+
with patch("invenio_app_rdm.theme.views.create_page_view") as mock_create_page_view:
|
|
27
|
+
mock_create_page_view.side_effect = lambda x: f"view_func_{x}"
|
|
28
|
+
|
|
29
|
+
add_static_page_routes(mock_blueprint, mock_app)
|
|
30
|
+
|
|
31
|
+
mock_blueprint.add_url_rule.assert_any_call(
|
|
32
|
+
"/path1", endpoint="endpoint1", view_func="view_func_/path1"
|
|
33
|
+
)
|
|
34
|
+
mock_blueprint.add_url_rule.assert_any_call(
|
|
35
|
+
"/path2", endpoint="endpoint2", view_func="view_func_/path2"
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# Check if was called with the right arguments
|
|
39
|
+
mock_create_page_view.assert_any_call("/path1")
|
|
40
|
+
mock_create_page_view.assert_any_call("/path2")
|
|
41
|
+
|
|
42
|
+
# Check if was called the right number of times
|
|
43
|
+
assert mock_blueprint.add_url_rule.call_count == 2
|
tests/ui/__init__.py
ADDED
tests/ui/conftest.py
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2019 CERN.
|
|
4
|
+
# Copyright (C) 2019 Northwestern University.
|
|
5
|
+
# Copyright (C) 2024 Graz University of Technology.
|
|
6
|
+
#
|
|
7
|
+
# Invenio App RDM is free software; you can redistribute it and/or modify it
|
|
8
|
+
# under the terms of the MIT License; see LICENSE file for more details.
|
|
9
|
+
|
|
10
|
+
"""Pytest fixtures and plugins for the UI application."""
|
|
11
|
+
|
|
12
|
+
from io import BytesIO
|
|
13
|
+
|
|
14
|
+
import pytest
|
|
15
|
+
from flask_webpackext.manifest import (
|
|
16
|
+
JinjaManifest,
|
|
17
|
+
JinjaManifestEntry,
|
|
18
|
+
JinjaManifestLoader,
|
|
19
|
+
)
|
|
20
|
+
from invenio_access.permissions import system_identity
|
|
21
|
+
from invenio_app.factory import create_ui
|
|
22
|
+
from invenio_rdm_records.proxies import current_rdm_records
|
|
23
|
+
from invenio_search import current_search
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# Mock the webpack manifest to avoid having to compile the full assets.
|
|
28
|
+
#
|
|
29
|
+
class MockJinjaManifest(JinjaManifest):
|
|
30
|
+
"""Mock manifest."""
|
|
31
|
+
|
|
32
|
+
def __getitem__(self, key):
|
|
33
|
+
"""Get a manifest entry."""
|
|
34
|
+
return JinjaManifestEntry(key, [key])
|
|
35
|
+
|
|
36
|
+
def __getattr__(self, name):
|
|
37
|
+
"""Get a manifest entry."""
|
|
38
|
+
return JinjaManifestEntry(name, [name])
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class MockManifestLoader(JinjaManifestLoader):
|
|
42
|
+
"""Manifest loader creating a mocked manifest."""
|
|
43
|
+
|
|
44
|
+
def load(self, filepath):
|
|
45
|
+
"""Load the manifest."""
|
|
46
|
+
return MockJinjaManifest()
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@pytest.fixture(scope="module")
|
|
50
|
+
def app_config(app_config):
|
|
51
|
+
"""Create test app."""
|
|
52
|
+
app_config["WEBPACKEXT_MANIFEST_LOADER"] = MockManifestLoader
|
|
53
|
+
return app_config
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@pytest.fixture(scope="module")
|
|
57
|
+
def create_app():
|
|
58
|
+
"""Create test app."""
|
|
59
|
+
return create_ui
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@pytest.fixture()
|
|
63
|
+
def index_templates(running_app):
|
|
64
|
+
"""Ensure the index templates are in place."""
|
|
65
|
+
list(current_search.put_templates(ignore=[400]))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@pytest.fixture()
|
|
69
|
+
def record(running_app, minimal_record):
|
|
70
|
+
"""Create and publish a record."""
|
|
71
|
+
s = current_rdm_records.records_service
|
|
72
|
+
draft = s.create(system_identity, minimal_record)
|
|
73
|
+
return s.publish(system_identity, draft.id)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@pytest.fixture()
|
|
77
|
+
def record_with_file(running_app, minimal_record):
|
|
78
|
+
"""Create and publish a record with file."""
|
|
79
|
+
minimal_record["files"] = {"enabled": True}
|
|
80
|
+
|
|
81
|
+
record_service = current_rdm_records.records_service
|
|
82
|
+
file_service = record_service.draft_files
|
|
83
|
+
|
|
84
|
+
draft = record_service.create(system_identity, minimal_record)
|
|
85
|
+
file_to_initialise = [
|
|
86
|
+
{
|
|
87
|
+
"key": "article.txt",
|
|
88
|
+
"checksum": "md5:c785060c866796cc2a1708c997154c8e",
|
|
89
|
+
"size": 17, # 2kB
|
|
90
|
+
"metadata": {
|
|
91
|
+
"description": "Published article PDF.",
|
|
92
|
+
},
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
file_service.init_files(system_identity, draft.id, file_to_initialise)
|
|
96
|
+
content = BytesIO(b"test file content")
|
|
97
|
+
file_service.set_file_content(
|
|
98
|
+
system_identity,
|
|
99
|
+
draft.id,
|
|
100
|
+
file_to_initialise[0]["key"],
|
|
101
|
+
content,
|
|
102
|
+
content.getbuffer().nbytes,
|
|
103
|
+
)
|
|
104
|
+
file_service.commit_file(system_identity, draft.id, "article.txt")
|
|
105
|
+
return record_service.publish(system_identity, draft.id)
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2021 Northwestern University.
|
|
4
|
+
#
|
|
5
|
+
# Invenio-App-RDM is free software; you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the MIT License; see LICENSE file for more details.
|
|
7
|
+
|
|
8
|
+
"""Test deposit views."""
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
from invenio_access.permissions import system_identity
|
|
12
|
+
from invenio_search.engine import dsl
|
|
13
|
+
from invenio_vocabularies.proxies import current_service as vocabulary_service
|
|
14
|
+
from invenio_vocabularies.records.api import Vocabulary
|
|
15
|
+
|
|
16
|
+
from invenio_app_rdm.records_ui.views.deposits import VocabulariesOptions
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@pytest.fixture()
|
|
20
|
+
def additional_resource_types(running_app):
|
|
21
|
+
"""Resource type vocabulary record."""
|
|
22
|
+
vocabulary_service.create(
|
|
23
|
+
system_identity,
|
|
24
|
+
{
|
|
25
|
+
"id": "publication",
|
|
26
|
+
"icon": "file alternate",
|
|
27
|
+
"props": {
|
|
28
|
+
"csl": "report",
|
|
29
|
+
"datacite_general": "Text",
|
|
30
|
+
"datacite_type": "",
|
|
31
|
+
"eurepo": "info:eu-repo/semantics/other",
|
|
32
|
+
"openaire_resourceType": "17",
|
|
33
|
+
"openaire_type": "publication",
|
|
34
|
+
"schema.org": "https://schema.org/CreativeWork",
|
|
35
|
+
"subtype": "",
|
|
36
|
+
"type": "publication",
|
|
37
|
+
},
|
|
38
|
+
"title": {"en": "Publication"},
|
|
39
|
+
"tags": ["depositable", "linkable"],
|
|
40
|
+
"type": "resourcetypes",
|
|
41
|
+
},
|
|
42
|
+
)
|
|
43
|
+
vocabulary_service.create(
|
|
44
|
+
system_identity,
|
|
45
|
+
{
|
|
46
|
+
"id": "publication-annotationcollection",
|
|
47
|
+
"icon": "file alternate",
|
|
48
|
+
"props": {
|
|
49
|
+
"csl": "report",
|
|
50
|
+
"datacite_general": "Collection",
|
|
51
|
+
"datacite_type": "",
|
|
52
|
+
"eurepo": "info:eu-repo/semantics/technicalDocumentation",
|
|
53
|
+
"openaire_resourceType": "9",
|
|
54
|
+
"openaire_type": "publication",
|
|
55
|
+
"schema.org": "https://schema.org/Collection",
|
|
56
|
+
"subtype": "publication-annotationcollection",
|
|
57
|
+
"type": "publication",
|
|
58
|
+
},
|
|
59
|
+
"title": {"en": "Annotation collection"},
|
|
60
|
+
"tags": ["depositable", "linkable"],
|
|
61
|
+
"type": "resourcetypes",
|
|
62
|
+
},
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
Vocabulary.index.refresh()
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def test_resource_types(app, client_with_login, additional_resource_types):
|
|
69
|
+
options = VocabulariesOptions()
|
|
70
|
+
expected = [
|
|
71
|
+
# If no corresponding parent type entry (e.g. image-photo), type_name
|
|
72
|
+
# is own title and subtype_name is empty.
|
|
73
|
+
{
|
|
74
|
+
"icon": "chart bar outline",
|
|
75
|
+
"id": "image-photo",
|
|
76
|
+
"subtype_name": "",
|
|
77
|
+
"type_name": "Photo",
|
|
78
|
+
},
|
|
79
|
+
# If parent type is itself (e.g. Publication), type_name is own title
|
|
80
|
+
# and subtype_name is empty.
|
|
81
|
+
{
|
|
82
|
+
"icon": "file alternate",
|
|
83
|
+
"id": "publication",
|
|
84
|
+
"subtype_name": "",
|
|
85
|
+
"type_name": "Publication",
|
|
86
|
+
},
|
|
87
|
+
# If corresponding parent type entry, type_name is parent's title
|
|
88
|
+
# and subtype_name is own title.
|
|
89
|
+
{
|
|
90
|
+
"icon": "file alternate",
|
|
91
|
+
"id": "publication-annotationcollection",
|
|
92
|
+
"subtype_name": "Annotation collection",
|
|
93
|
+
"type_name": "Publication",
|
|
94
|
+
},
|
|
95
|
+
]
|
|
96
|
+
|
|
97
|
+
# the choice of this filter isn't important for the test
|
|
98
|
+
result = options._resource_types(dsl.Q("term", tags="depositable"))
|
|
99
|
+
|
|
100
|
+
sorted_result = sorted(result, key=lambda e: e["id"])
|
|
101
|
+
assert expected == sorted_result
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def test_dump_subjects_vocabulary(running_app):
|
|
105
|
+
options = VocabulariesOptions()
|
|
106
|
+
expected = {
|
|
107
|
+
"limit_to": [
|
|
108
|
+
{"text": "All", "value": "all"},
|
|
109
|
+
{"text": "MeSH", "value": "MeSH"},
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
result = options.subjects()
|
|
114
|
+
|
|
115
|
+
assert expected == result
|