invenio-app-rdm 13.0.0rc4__py2.py3-none-any.whl → 13.0.0rc6__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 (55) hide show
  1. invenio_app_rdm/__init__.py +1 -1
  2. invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/macros/doi.html +7 -5
  3. invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/components/CopyButton.js +38 -19
  4. invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/ExportDropdown.js +7 -2
  5. invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/theme.js +4 -0
  6. invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/theme.js +9 -0
  7. invenio_app_rdm/theme/assets/semantic-ui/less/invenio_app_rdm/theme/globals/site.overrides +6 -1
  8. invenio_app_rdm/theme/webpack.py +0 -1
  9. invenio_app_rdm/upgrade_scripts/migrate_12_0_to_13_0.py +94 -65
  10. {invenio_app_rdm-13.0.0rc4.dist-info → invenio_app_rdm-13.0.0rc6.dist-info}/METADATA +17 -2
  11. {invenio_app_rdm-13.0.0rc4.dist-info → invenio_app_rdm-13.0.0rc6.dist-info}/RECORD +15 -55
  12. {invenio_app_rdm-13.0.0rc4.dist-info → invenio_app_rdm-13.0.0rc6.dist-info}/top_level.txt +0 -1
  13. invenio_app_rdm/theme/assets/semantic-ui/translations/invenio_app_rdm/i18next-scanner.config.js +0 -64
  14. invenio_app_rdm/theme/assets/semantic-ui/translations/invenio_app_rdm/package-lock.json +0 -2129
  15. invenio_app_rdm/theme/assets/semantic-ui/translations/invenio_app_rdm/scripts/compileCatalog.js +0 -118
  16. invenio_app_rdm/theme/assets/semantic-ui/translations/invenio_app_rdm/scripts/fixTrailingNewlines.js +0 -23
  17. invenio_app_rdm/theme/assets/semantic-ui/translations/invenio_app_rdm/scripts/initCatalog.js +0 -20
  18. invenio_app_rdm/theme/assets/semantic-ui/translations/invenio_app_rdm/scripts/postExtractMessages.js +0 -36
  19. tests/__init__.py +0 -8
  20. tests/api/__init__.py +0 -8
  21. tests/api/conftest.py +0 -24
  22. tests/api/test_protect_files_rest.py +0 -73
  23. tests/api/test_record_api.py +0 -175
  24. tests/api/test_stats_api.py +0 -26
  25. tests/conftest.py +0 -390
  26. tests/fixtures/__init__.py +0 -8
  27. tests/fixtures/app_data/oai_sets.yaml +0 -3
  28. tests/fixtures/app_data/pages/about.html +0 -1
  29. tests/fixtures/app_data/pages.yaml +0 -4
  30. tests/fixtures/conftest.py +0 -27
  31. tests/fixtures/test_cli.py +0 -25
  32. tests/fixtures/test_fixtures.py +0 -46
  33. tests/mock_module/__init__.py +0 -7
  34. tests/mock_module/templates/mock_mail.html +0 -27
  35. tests/mock_module/views.py +0 -32
  36. tests/redirector/__init__.py +0 -8
  37. tests/redirector/conftest.py +0 -54
  38. tests/redirector/test_redirector.py +0 -28
  39. tests/test_tasks.py +0 -209
  40. tests/test_utils.py +0 -67
  41. tests/test_version.py +0 -16
  42. tests/test_views.py +0 -43
  43. tests/ui/__init__.py +0 -8
  44. tests/ui/conftest.py +0 -115
  45. tests/ui/test_deposits.py +0 -115
  46. tests/ui/test_export_formats.py +0 -37
  47. tests/ui/test_file_download.py +0 -73
  48. tests/ui/test_filters.py +0 -10
  49. tests/ui/test_robotstxt.py +0 -35
  50. tests/ui/test_signposting_ui.py +0 -95
  51. tests/ui/test_sitemaps.py +0 -85
  52. tests/ui/test_stats_ui.py +0 -92
  53. {invenio_app_rdm-13.0.0rc4.dist-info → invenio_app_rdm-13.0.0rc6.dist-info}/WHEEL +0 -0
  54. {invenio_app_rdm-13.0.0rc4.dist-info → invenio_app_rdm-13.0.0rc6.dist-info}/entry_points.txt +0 -0
  55. {invenio_app_rdm-13.0.0rc4.dist-info → invenio_app_rdm-13.0.0rc6.dist-info}/licenses/LICENSE +0 -0
tests/ui/test_filters.py DELETED
@@ -1,10 +0,0 @@
1
- from invenio_app_rdm.records_ui.views.filters import get_scheme_label
2
-
3
-
4
- def test_get_scheme_label(app):
5
- # just test a couple of schemes
6
- assert "PMID" == get_scheme_label("pmid")
7
-
8
- assert "arXiv" == get_scheme_label("arxiv")
9
-
10
- assert "Bibcode" == get_scheme_label("ads")
@@ -1,35 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2022 CERN.
4
- # Copyright (C) 2025 Northwestern University.
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
- import pytest
10
- from invenio_cache import current_cache
11
- from invenio_sitemap import SitemapIndexCache
12
-
13
-
14
- @pytest.fixture
15
- def cache_for_sitemap_index(app):
16
- """Primed cache with a sitemap index entry."""
17
- try:
18
- cache = SitemapIndexCache(current_cache)
19
- cache.delete_included_and_higher(0)
20
- cache.set(0, "unimportant data")
21
- yield cache
22
- finally:
23
- cache.delete_included_and_higher(0)
24
-
25
-
26
- def test_robotstxt(app, client, cache_for_sitemap_index):
27
- """Check if robots.txt returns a string response."""
28
- response = client.get("/robots.txt")
29
-
30
- assert 200 == response.status_code
31
- assert type(response.text) == str
32
- assert "Disallow: /search" in response.text
33
- assert "Disallow: /api" in response.text
34
- assert "Disallow: /administration" in response.text
35
- assert "Sitemap: https://127.0.0.1:5000/sitemap_index_0.xml" in response.text
@@ -1,95 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2023 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 Signposting.
9
-
10
- See https://signposting.org/FAIR/#level2 for more information on Signposting
11
- """
12
- import pytest
13
-
14
-
15
- @pytest.mark.parametrize("http_method", ["head", "get"])
16
- @pytest.mark.parametrize("level_1_enabled", [True, False])
17
- def test_link_in_landing_page_response_headers(
18
- running_app, app, client, record_with_file, http_method, level_1_enabled
19
- ):
20
- previous_config = app.config[
21
- "APP_RDM_RECORD_LANDING_PAGE_FAIR_SIGNPOSTING_LEVEL_1_ENABLED"
22
- ]
23
-
24
- if level_1_enabled:
25
- app.config["APP_RDM_RECORD_LANDING_PAGE_FAIR_SIGNPOSTING_LEVEL_1_ENABLED"] = (
26
- True
27
- )
28
-
29
- client_http_method = getattr(client, http_method)
30
- res = client_http_method(f"/records/{record_with_file.id}")
31
-
32
- # The link headers are already tested in details in `invenio-rdm-records` (see `test_signposting_serializer`).
33
- # Here we still want to issue the HTTP call to the URL in order to make sure that the decorator is working properly,
34
- # but the assertions are less detailed to avoid having to adapt this test every time we modify the logic in `invenio-rdm-records`.
35
- link_headers = res.headers["Link"].split(" , ")
36
-
37
- # The test record does not have:
38
- # - an author with an identifier.
39
- # - a cite-as since it has no DOI.
40
- # - a license.
41
-
42
- # There should be at least one link to a linkset (e.g. "application/linkset" and/or "application/linkset+json")
43
- assert sum('; rel="linkset" ;' in header for header in link_headers) >= 1
44
-
45
- if level_1_enabled:
46
- # There should be at least 10 export formats supported (e.g. "application/dcat+xml", "application/x-bibtex", etc.).
47
- assert sum('; rel="describedby" ;' in header for header in link_headers) >= 10
48
-
49
- # There should be at least one file in the record.
50
- assert sum('; rel="item" ;' in header for header in link_headers) >= 1
51
-
52
- # There should be at least one description of the type of the record (e.g. "https://schema.org/Photograph").
53
- assert sum('; rel="type"' in header for header in link_headers) >= 1
54
- else:
55
- # The only link headers should be linkset headers.
56
- assert sum('; rel="linkset" ;' in header for header in link_headers) == len(
57
- link_headers
58
- )
59
-
60
- app.config["APP_RDM_RECORD_LANDING_PAGE_FAIR_SIGNPOSTING_LEVEL_1_ENABLED"] = (
61
- previous_config
62
- )
63
-
64
-
65
- @pytest.mark.parametrize("http_method", ["head", "get"])
66
- def test_link_in_content_resource_response_headers(
67
- running_app, client, record_with_file, http_method
68
- ):
69
- ui_url = f"https://127.0.0.1:5000/records/{record_with_file.id}"
70
- api_url = f"https://127.0.0.1:5000/api/records/{record_with_file.id}"
71
- filename = "article.txt"
72
-
73
- client_http_method = getattr(client, http_method)
74
- res = client_http_method(f"/records/{record_with_file.id}/files/{filename}")
75
-
76
- assert res.headers["Link"].split(" , ") == [
77
- f'<{ui_url}> ; rel="collection" ; type="text/html"',
78
- f'<{api_url}> ; rel="linkset" ; type="application/linkset+json"',
79
- ]
80
-
81
-
82
- @pytest.mark.parametrize("http_method", ["head", "get"])
83
- def test_link_in_metadata_resource_response_headers(
84
- running_app, client, record, http_method
85
- ):
86
- ui_url = f"https://127.0.0.1:5000/records/{record.id}"
87
- api_url = f"https://127.0.0.1:5000/api/records/{record.id}"
88
-
89
- client_http_method = getattr(client, http_method)
90
- res = client_http_method(f"/records/{record.id}/export/bibtex")
91
-
92
- assert res.headers["Link"].split(" , ") == [
93
- f'<{ui_url}> ; rel="describes" ; type="text/html"',
94
- f'<{api_url}> ; rel="linkset" ; type="application/linkset+json"',
95
- ]
tests/ui/test_sitemaps.py DELETED
@@ -1,85 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2025 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 sitemaps."""
9
-
10
- import datetime
11
-
12
- import time_machine
13
- from invenio_communities.proxies import current_communities
14
-
15
- from invenio_app_rdm.communities_ui.sitemap import SitemapSectionOfCommunities
16
- from invenio_app_rdm.records_ui.sitemap import SitemapSectionOfRDMRecords
17
-
18
-
19
- def test_sitemap_section_of_communities(running_app, community_input, create_community):
20
- # by default converted to UTC w/ time 00:00:00
21
- with time_machine.travel(datetime.date(2025, 3, 27)):
22
- community_input["slug"] = "my-test-community-1"
23
- c1 = create_community(data=community_input)
24
- community_input["slug"] = "my-test-community-2"
25
- community_input["access"]["visibility"] = "restricted"
26
- c2 = create_community(data=community_input)
27
- with time_machine.travel(datetime.date(2025, 3, 28)):
28
- community_input["slug"] = "my-test-community-3"
29
- community_input["access"]["visibility"] = "public"
30
- community_input["metadata"]["page"] = "A page to be indexed."
31
- c3 = create_community(data=community_input)
32
-
33
- current_communities.service.indexer.refresh() # index in search engine
34
- section = SitemapSectionOfCommunities()
35
-
36
- entries = [section.to_dict(entity) for entity in section.iter_entities()]
37
-
38
- expected_entries = [
39
- {
40
- "loc": "https://127.0.0.1:5000/communities/my-test-community-3/records",
41
- "lastmod": "2025-03-28T00:00:00Z",
42
- },
43
- {
44
- "loc": "https://127.0.0.1:5000/communities/my-test-community-3/about",
45
- "lastmod": "2025-03-28T00:00:00Z",
46
- },
47
- {
48
- "loc": "https://127.0.0.1:5000/communities/my-test-community-1/records",
49
- "lastmod": "2025-03-27T00:00:00Z",
50
- },
51
- ]
52
- assert expected_entries == entries
53
-
54
-
55
- def test_sitemap_section_of_records(
56
- running_app, minimal_record, create_record, records_service
57
- ):
58
- # by default converted to UTC w/ time 00:00:00
59
- with time_machine.travel(datetime.date(2025, 3, 27)):
60
- minimal_record["title"] = "my-test-record-1"
61
- r1 = create_record(data=minimal_record)
62
- minimal_record["title"] = "my-test-record-2"
63
- minimal_record["access"]["record"] = "restricted"
64
- r2 = create_record(data=minimal_record)
65
- with time_machine.travel(datetime.date(2025, 3, 28)):
66
- minimal_record["title"] = "my-test-record-3"
67
- minimal_record["access"]["record"] = "public"
68
- r3 = create_record(data=minimal_record)
69
-
70
- records_service.indexer.refresh()
71
- section = SitemapSectionOfRDMRecords()
72
-
73
- entries = [section.to_dict(entity) for entity in section.iter_entities()]
74
-
75
- expected_entries = [
76
- {
77
- "loc": f"https://127.0.0.1:5000/records/{r3.id}",
78
- "lastmod": "2025-03-28T00:00:00Z",
79
- },
80
- {
81
- "loc": f"https://127.0.0.1:5000/records/{r1.id}",
82
- "lastmod": "2025-03-27T00:00:00Z",
83
- },
84
- ]
85
- assert expected_entries == entries
tests/ui/test_stats_ui.py DELETED
@@ -1,92 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2023 TU Wien.
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 the statistics integration."""
9
-
10
- import time
11
- from datetime import datetime, timedelta
12
-
13
- import pytest
14
- from flask import current_app
15
- from invenio_search.engine import dsl
16
- from invenio_stats.proxies import current_stats
17
- from invenio_stats.tasks import process_events
18
-
19
-
20
- @pytest.fixture()
21
- def empty_event_queues(running_app):
22
- """Make sure the event queues exist and are empty."""
23
- for event in current_stats.events:
24
- queue = current_stats.events[event].queue
25
- queue.queue.declare()
26
- queue.consume()
27
-
28
-
29
- def test_record_view_events(
30
- client, running_app, index_templates, record, empty_event_queues
31
- ):
32
- """Test that landing page visits trigger events."""
33
- res = client.get(f"/records/{record.id}")
34
- assert res.status_code == 200
35
-
36
- # as per current default configuration, only UI-based visits should
37
- # trigger events to be sent off to the queue
38
- # (API calls such as the CSL export on the landing page are ignored)
39
- queue = current_stats.events["record-view"].queue
40
- events = list(queue.consume())
41
- event = events[0]
42
- assert len(events) == 1
43
- assert event["recid"] == record.id
44
- assert event["via_api"] is False
45
-
46
-
47
- def test_record_view_statistics(
48
- client, running_app, index_templates, record, empty_event_queues
49
- ):
50
- """Test that landing page visits triggers events and indexes them."""
51
- event_cfg = current_stats.events["record-view"]
52
- event = event_cfg.cls(**event_cfg.params, double_click_window=0)
53
- agg_cfg = current_stats.aggregations["record-view-agg"]
54
- agg = agg_cfg.cls(agg_cfg.name, **agg_cfg.params)
55
- query_cfg = current_stats.queries["record-view"]
56
- query = query_cfg.cls(name=query_cfg.name, **query_cfg.params)
57
-
58
- for i in range(3):
59
- if i != 0:
60
- # we need to sleep for a little while here because invenio-stats trims
61
- # the sub-second part from the events before indexing them,
62
- # (and thus collapses similar events if they are too close in time)
63
- time.sleep(1.25)
64
-
65
- res = client.get(f"/records/{record.id}")
66
- assert res.status_code == 200
67
-
68
- # process the event
69
- processing_result = event.run()
70
- assert processing_result == (1, 0)
71
-
72
- # refresh the index and check if the event was properly indexed
73
- dsl.Index(event.index, using=event.client).refresh()
74
- indexed_events = dsl.Search(using=event.client, index=event.index).execute(
75
- ignore_cache=True
76
- )
77
- indexed_event = indexed_events.hits[0]
78
- assert indexed_events.hits.total.value == (i + 1)
79
- assert indexed_event["recid"] == record.id
80
- assert indexed_event["parent_recid"] == record["parent"]["id"]
81
- assert indexed_event["via_api"] is False
82
-
83
- # calculate the aggregations and check if the query is correct
84
- yesterday = datetime.today() - timedelta(days=1)
85
- tomorrow = datetime.today() + timedelta(days=1)
86
- agg.run(start_date=yesterday, end_date=tomorrow, update_bookmark=False)
87
- dsl.Index(agg.index, using=agg.client).refresh()
88
- query_result = query.run(recid=record.id)
89
- assert query_result["recid"] == record.id
90
- assert query_result["parent_recid"] == record["parent"]["id"]
91
- assert query_result["views"] == (i + 1)
92
- assert query_result["unique_views"] == 1