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.
Files changed (50) hide show
  1. invenio_app_rdm/__init__.py +1 -1
  2. invenio_app_rdm/config.py +4 -2
  3. invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/meta.html +3 -1
  4. invenio_app_rdm/records_ui/views/decorators.py +91 -8
  5. invenio_app_rdm/records_ui/views/records.py +7 -4
  6. invenio_app_rdm/tasks.py +6 -2
  7. invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/components/CompareRevisionsDropdown.js +6 -0
  8. invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/components/RevisionsDiffViewer.js +5 -0
  9. invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/records/CompareRevisions.js +10 -9
  10. invenio_app_rdm/theme/assets/semantic-ui/less/invenio_app_rdm/theme/globals/site.overrides +1 -1
  11. invenio_app_rdm/theme/templates/semantic-ui/invenio_app_rdm/help/search.en.html +1 -1
  12. invenio_app_rdm/urls.py +11 -1
  13. {invenio_app_rdm-13.0.0b2.dev2.dist-info → invenio_app_rdm-13.0.0b2.dev4.dist-info}/METADATA +20 -1
  14. {invenio_app_rdm-13.0.0b2.dev2.dist-info → invenio_app_rdm-13.0.0b2.dev4.dist-info}/RECORD +50 -18
  15. {invenio_app_rdm-13.0.0b2.dev2.dist-info → invenio_app_rdm-13.0.0b2.dev4.dist-info}/WHEEL +1 -1
  16. {invenio_app_rdm-13.0.0b2.dev2.dist-info → invenio_app_rdm-13.0.0b2.dev4.dist-info}/top_level.txt +1 -0
  17. tests/__init__.py +8 -0
  18. tests/api/__init__.py +8 -0
  19. tests/api/conftest.py +24 -0
  20. tests/api/test_protect_files_rest.py +73 -0
  21. tests/api/test_record_api.py +175 -0
  22. tests/api/test_stats_api.py +26 -0
  23. tests/conftest.py +313 -0
  24. tests/fixtures/__init__.py +8 -0
  25. tests/fixtures/app_data/oai_sets.yaml +3 -0
  26. tests/fixtures/app_data/pages/about.html +1 -0
  27. tests/fixtures/app_data/pages.yaml +4 -0
  28. tests/fixtures/conftest.py +27 -0
  29. tests/fixtures/test_cli.py +25 -0
  30. tests/fixtures/test_fixtures.py +46 -0
  31. tests/mock_module/__init__.py +7 -0
  32. tests/mock_module/templates/mock_mail.html +28 -0
  33. tests/mock_module/views.py +32 -0
  34. tests/redirector/__init__.py +8 -0
  35. tests/redirector/conftest.py +54 -0
  36. tests/redirector/test_redirector.py +28 -0
  37. tests/test_tasks.py +104 -0
  38. tests/test_utils.py +67 -0
  39. tests/test_version.py +16 -0
  40. tests/test_views.py +43 -0
  41. tests/ui/__init__.py +8 -0
  42. tests/ui/conftest.py +105 -0
  43. tests/ui/test_deposits.py +115 -0
  44. tests/ui/test_export_formats.py +37 -0
  45. tests/ui/test_filters.py +10 -0
  46. tests/ui/test_signposting_ui.py +95 -0
  47. tests/ui/test_static.py +25 -0
  48. tests/ui/test_stats_ui.py +92 -0
  49. {invenio_app_rdm-13.0.0b2.dev2.dist-info → invenio_app_rdm-13.0.0b2.dev4.dist-info}/LICENSE +0 -0
  50. {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,7 @@
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 entry point."""
@@ -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,8 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2025 Graz University of Technology.
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."""
@@ -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
@@ -0,0 +1,8 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2025 Graz University of Technology.
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."""
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