invenio-app-rdm 13.0.0b3.dev4__py2.py3-none-any.whl → 13.0.0b3.dev6__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/administration/audit_logs/__init__.py +12 -0
- invenio_app_rdm/administration/audit_logs/audit_logs.py +77 -0
- invenio_app_rdm/administration/templates/semantic-ui/invenio_app_rdm/administration/audit_logs.html +14 -0
- invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/details.html +2 -2
- invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/licenses.html +50 -36
- invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/macros/detail.html +9 -0
- invenio_app_rdm/records_ui/views/__init__.py +2 -0
- invenio_app_rdm/records_ui/views/decorators.py +10 -7
- invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/auditLogs/ViewAction.js +0 -0
- invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/auditLogs/index.js +29 -0
- invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/auditLogs/search/SearchResultItemLayout.js +71 -0
- invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/auditLogs/search/index.js +9 -0
- invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/deposit/RDMDepositForm.js +8 -1
- invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/ShareOptions/AccessUsersGroups/AccessUsersGroups.js +1 -1
- invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/ShareOptions/AccessUsersGroups/UserGroupAccessSearchResultItem.js +1 -1
- invenio_app_rdm/theme/templates/semantic-ui/invenio_app_rdm/files_integrity_report/email/files_integrity_report.html +10 -11
- invenio_app_rdm/theme/webpack.py +1 -0
- {invenio_app_rdm-13.0.0b3.dev4.dist-info → invenio_app_rdm-13.0.0b3.dev6.dist-info}/METADATA +21 -6
- {invenio_app_rdm-13.0.0b3.dev4.dist-info → invenio_app_rdm-13.0.0b3.dev6.dist-info}/RECORD +29 -22
- {invenio_app_rdm-13.0.0b3.dev4.dist-info → invenio_app_rdm-13.0.0b3.dev6.dist-info}/WHEEL +1 -1
- {invenio_app_rdm-13.0.0b3.dev4.dist-info → invenio_app_rdm-13.0.0b3.dev6.dist-info}/entry_points.txt +1 -0
- tests/conftest.py +0 -41
- tests/mock_module/templates/mock_mail.html +3 -4
- tests/test_tasks.py +121 -16
- tests/ui/conftest.py +17 -5
- tests/ui/test_file_download.py +73 -0
- invenio_app_rdm/urls.py +0 -72
- {invenio_app_rdm-13.0.0b3.dev4.dist-info → invenio_app_rdm-13.0.0b3.dev6.dist-info}/licenses/LICENSE +0 -0
- {invenio_app_rdm-13.0.0b3.dev4.dist-info → invenio_app_rdm-13.0.0b3.dev6.dist-info}/top_level.txt +0 -0
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
invenio_app_rdm/__init__.py,sha256=
|
|
1
|
+
invenio_app_rdm/__init__.py,sha256=kJtcmQy4EcdGAs8fKNBkktlToihpPYxSR6rtNjBoJX8,699
|
|
2
2
|
invenio_app_rdm/cli.py,sha256=G6QqNU2W6n6ICtTMnpeKFXIsdorncDmVXwwwsGH5F2k,2746
|
|
3
3
|
invenio_app_rdm/config.py,sha256=Sv6Q8VEP-KYNuvC6kASLOYC-gYRByYN-hwPmbCxQWKc,50624
|
|
4
4
|
invenio_app_rdm/ext.py,sha256=PkZhATGJDgYqBJQh41NdvBZWR83mgI3Eej6rj10UVJE,5278
|
|
5
5
|
invenio_app_rdm/tasks.py,sha256=FyrIQXVuPjms-dNEnLrVmmdwrX_IykJ87gcSNgOR6O0,1373
|
|
6
|
-
invenio_app_rdm/urls.py,sha256=8S95QSs4yS0rtORsd4veo--rF3LSLwZenoowJ5ubbmM,2496
|
|
7
6
|
invenio_app_rdm/views.py,sha256=SDr9NwZEWQcgT_3GFRYdDf6eUaK9DfnoafIkhUf9nSI,785
|
|
8
7
|
invenio_app_rdm/administration/__init__.py,sha256=8r9LeoE9fNHZSVS5QsCfVhRU7MAiEOWJk9MA3Y--4F8,251
|
|
8
|
+
invenio_app_rdm/administration/audit_logs/__init__.py,sha256=jsBXeKSY5YNn1juF9sFyHPYo_XYpwdP3Dye-de7cMK0,318
|
|
9
|
+
invenio_app_rdm/administration/audit_logs/audit_logs.py,sha256=vgrGQ1lLE5uSuoJCx9kIMQPshjxJzZlCZ4v5cZEcKus,2156
|
|
9
10
|
invenio_app_rdm/administration/domains/__init__.py,sha256=Qob5kqjRPxpuSE5yDV2tesN6tmaKp5JcxCxGA8Mrcak,487
|
|
10
11
|
invenio_app_rdm/administration/domains/domains.py,sha256=vafLa-mqkg_tQLjx328E64P_4mksB5kjBlsfunvdatg,5599
|
|
11
12
|
invenio_app_rdm/administration/records/__init__.py,sha256=WpNHBm_Mk9FF8GzvrXWjL79URMSgBhpqgxvrLXNooqg,434
|
|
12
13
|
invenio_app_rdm/administration/records/records.py,sha256=BFxxnB4acN8Fd3A6CWuyRUjo3bvdWmNSkcxuVZYzTaA,5357
|
|
14
|
+
invenio_app_rdm/administration/templates/semantic-ui/invenio_app_rdm/administration/audit_logs.html,sha256=kLP3lfZiwLB8N-78_xINymnD8TIjGMzeJIO1a1zO130,346
|
|
13
15
|
invenio_app_rdm/administration/templates/semantic-ui/invenio_app_rdm/administration/domains_search.html,sha256=NP8HPfOQPIR9psNDMFRXJH8fjok2AbXCentD_3Q1wWw,338
|
|
14
16
|
invenio_app_rdm/administration/templates/semantic-ui/invenio_app_rdm/administration/user_moderation.html,sha256=koXd8lV_KBgAl1Wll7aM3xR0NgYcOl2PiFqD2Xkcp2w,348
|
|
15
17
|
invenio_app_rdm/administration/templates/semantic-ui/invenio_app_rdm/administration/user_moderation_details.html,sha256=g6YZh9yWqDfzd5kMgIrO4c5k4iKa61y04RsuT_ZbMJI,350
|
|
@@ -63,25 +65,25 @@ invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details
|
|
|
63
65
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/subjects.html,sha256=Wu7MCXzGj41K38-VXi-kStvc8fm3Ck68uJ1egfFK0dw,1509
|
|
64
66
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/citations.html,sha256=5Sdg_gwGOgm0qLRv4-CUmDNx7PYlOsa5XPGjDdx7k20,258
|
|
65
67
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/communities.html,sha256=GxxKbXxVg5lKcSEzVeYJXyz7qUL7yhsZnhXY3lE-vNU,1561
|
|
66
|
-
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/details.html,sha256=
|
|
68
|
+
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/details.html,sha256=Ip3wBnfpS8U9fBH2q9nZbt7znAzUKvVrbz3QkeBUMUM,1988
|
|
67
69
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/export.html,sha256=DoDrQFd_OJcJzqBEQ2FRbcfJpD3TLRjESU68mBLWVyU,1392
|
|
68
70
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/external_resources.html,sha256=Ia92YMRlxuGRTMsWU4hQTLJDeRy8BX8bnSSaLXKst4Y,1934
|
|
69
71
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/keywords_subjects.html,sha256=LvsA6JiosfwSSwUUg6--3xx1OZepvN7mxQdIWyl9caE,708
|
|
70
|
-
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/licenses.html,sha256=
|
|
72
|
+
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/licenses.html,sha256=ktAwgEUpB6X8uMk9-ThNEg0_CkyTqfBurTudXNd6mFo,3131
|
|
71
73
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/locations.html,sha256=i1EnmQrnmSAYfocoMYtneAB7JyUI309whyu3bZJTR6M,715
|
|
72
74
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/manage_menu.html,sha256=CiqcUTXKnbcZASIweFCHeqaRqO0M0k_wjM9Q-S9z0i4,1297
|
|
73
75
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/metrics.html,sha256=3OptZ6iQYaQ3GjNw5O-h9FloISUzFE0nSNTmazjTQgQ,520
|
|
74
76
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/technical_metadata.html,sha256=N5VUwCygKG-zXvyu0YeFJb7A0eHIcKWuMAVm9Kbrb_M,658
|
|
75
77
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/details/side_bar/versions.html,sha256=sPYG81XFcU1ND6roeYmN4SY419iyvQj9ozCv9Pctw5E,932
|
|
76
78
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/macros/creatibutors.html,sha256=N53nwtlEZjxweCx70qFJa1s6uL1pPSzWZgk8p1vodE4,4277
|
|
77
|
-
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/macros/detail.html,sha256=
|
|
79
|
+
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/macros/detail.html,sha256=YEF5tR22t2QUO-tKpjsS4gKhYMZpfyjbO6wWf8LKhJw,10598
|
|
78
80
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/macros/doi.html,sha256=NZUtJSCwQScJsmz7vxglslEVqPwG7Ldul_wl7yce0fg,1489
|
|
79
81
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/macros/files.html,sha256=Xsq_HiM_cTGKgmoE1HAXje8iYe3d0wIJoesk22Xn7vU,8761
|
|
80
82
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/macros/locations.html,sha256=27-KyPqb05pu-yRXHvxCgZWRSi5bFP6xf7XBn91sbeA,1741
|
|
81
83
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/macros/stats_popup.html,sha256=5SVzfIS15Aro2Itd2BiaLbMXm0cvvwk6ZCdYjuSwhBw,625
|
|
82
84
|
invenio_app_rdm/records_ui/templates/semantic-ui/invenio_app_rdm/records/macros/version.html,sha256=eA8-n81XUezkwPXvcG5v2sgLPQNTgr7hB36-_Gr-tVI,758
|
|
83
|
-
invenio_app_rdm/records_ui/views/__init__.py,sha256=
|
|
84
|
-
invenio_app_rdm/records_ui/views/decorators.py,sha256=
|
|
85
|
+
invenio_app_rdm/records_ui/views/__init__.py,sha256=9DaDls04IQv7fYttDjLofIWGsRRjk-FwUYnIfxV3OWk,5840
|
|
86
|
+
invenio_app_rdm/records_ui/views/decorators.py,sha256=MUUmgGuigmFMigcpyJbNvM0yPKUyeAw5LE6MJ69BoFA,15883
|
|
85
87
|
invenio_app_rdm/records_ui/views/deposits.py,sha256=KRR_fpl98EhNZie0Q-_uZtgG2QKsQAW2fhb-kvnQ4s4,21561
|
|
86
88
|
invenio_app_rdm/records_ui/views/filters.py,sha256=Rm55fXJv97cqq8B_6KCe-3PxxHUH4VRu-jd9fTea6r4,6994
|
|
87
89
|
invenio_app_rdm/records_ui/views/records.py,sha256=GdxG3JnXrV1QT0KxOqeYWoDGIiZRZ9w5poihPPd-wTo,16428
|
|
@@ -103,9 +105,13 @@ invenio_app_rdm/requests_ui/views/requests.py,sha256=grC2bQWF36xzeftdOSjy_vBWAGS
|
|
|
103
105
|
invenio_app_rdm/requests_ui/views/ui.py,sha256=DBysYQa__gOCg-pikO6HmoVLmRmMAVWeTBiYhPa7PmA,2359
|
|
104
106
|
invenio_app_rdm/theme/__init__.py,sha256=QbkxNjjOmGKRlie96HfTXgnFeVQjOX0GdiZnHP7pIhs,277
|
|
105
107
|
invenio_app_rdm/theme/views.py,sha256=Ucn6o7mF8qR7gtOeliKC73gIBhy5LgY65rvteC1Uiog,4312
|
|
106
|
-
invenio_app_rdm/theme/webpack.py,sha256=
|
|
108
|
+
invenio_app_rdm/theme/webpack.py,sha256=5oi0YBD84y8246JYGtSNmNbRUH-bz_G8WrSRRDEyplw,5201
|
|
107
109
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/theme.js,sha256=LSswk1IkVgUxTT3Arw_QF-mNQ16vVYDf2B90h6FZfFw,4431
|
|
108
110
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/utils.js,sha256=oTCQkmr7j6FwVsOfM6hsKrPHfadW7m9IurrqYVDgxDw,3628
|
|
111
|
+
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/auditLogs/ViewAction.js,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
112
|
+
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/auditLogs/index.js,sha256=7glSWacd986Zu6l_Ob7IXp4uNWA0f51FBfRv4HZxjYU,965
|
|
113
|
+
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/auditLogs/search/SearchResultItemLayout.js,sha256=wXwMfu8u02A3KT_xZbalntDGvLwVFc9AlorUTuiSqdQ,2268
|
|
114
|
+
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/auditLogs/search/index.js,sha256=q1WaQ-kNNMvNdnsONMw2c4GWobizoPWsmIdWL2fRCPc,283
|
|
109
115
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/components/CompareRevisionsDropdown.js,sha256=BNdMxfFYPhlrGKPg47oc4X8ILllfCngN61L1b7Yt_8Q,2483
|
|
110
116
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/components/ImpersonateUser.js,sha256=1tnHc9PaCQvVS1PVsDWtfpWzVxJJ5_eltn9WJEYygiY,2366
|
|
111
117
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/administration/components/ImpersonateUserForm.js,sha256=Z21KrMyAJ1rKF5IEzM088-pTvTga21LBnG4GPYvh5g4,6890
|
|
@@ -160,7 +166,7 @@ invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/components/CopyButto
|
|
|
160
166
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/components/DisplayPartOfCommunities.js,sha256=bSmhuwSWk4CW80mqa4ZZbjfa-_NsiJ1IxQ9veDy6sAM,2751
|
|
161
167
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/components/DisplayVerifiedCommunity.js,sha256=m3rT8jJ3440ZX22zZog8bHatWltYXwvmw_tu6tJUM9k,1506
|
|
162
168
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/components/RecordsResultsListItem.js,sha256=RTSQBlGQY7ww7fVGHDvDfWQNyJ07mnEoyboTGIcCgD4,6694
|
|
163
|
-
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/deposit/RDMDepositForm.js,sha256=
|
|
169
|
+
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/deposit/RDMDepositForm.js,sha256=92Mg5PAjOHZ8pMNHJjyqdHMXLXuaAF6FT12UTJzy9XQ,32295
|
|
164
170
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/deposit/ShareDraftButton.js,sha256=ICMV4Ixe-nTe6q7COZ0oyAQf2nVp2cez_-iUZobwUD0,1998
|
|
165
171
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/deposit/config.js,sha256=a9Im0S72ne6LGDzM8C-pP9fIhcMihIbOJ5Ez5SwSn9A,1456
|
|
166
172
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/deposit/index.js,sha256=gA0BaUFpaJr9nkmHSWoxuwKDfSD3JUTPcadj2TKHN24,1587
|
|
@@ -197,11 +203,11 @@ invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/ShareOp
|
|
|
197
203
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/ShareOptions/AccessLinks/LinksSearchResultContainer.js,sha256=xr5dfml-v7NU2PzCKIB2_BeYFnFghnsqwKMgLErONQI,6786
|
|
198
204
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/ShareOptions/AccessLinks/LinksTab.js,sha256=Ki1HN02B4_xFNy3YdPp3Mz2YLO-LxUhmNqRKKrvtVlQ,2883
|
|
199
205
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/ShareOptions/AccessRequests/AccessRequestsTab.js,sha256=tbSeqk7tnApZqLFi7NEegrwAGFKJ0sficF_3DB1Ld-0,8405
|
|
200
|
-
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/ShareOptions/AccessUsersGroups/AccessUsersGroups.js,sha256=
|
|
206
|
+
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/ShareOptions/AccessUsersGroups/AccessUsersGroups.js,sha256=tqUTVCNmfTZqY6aqDvZ3FOFl13EwT23AUWASpccdwMY,6886
|
|
201
207
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/ShareOptions/AccessUsersGroups/AddUserGroupAccessModal.js,sha256=qpaeKpIX2FUhztkBJtD03WlZ_YOziE0_1CF4cGwMb6Y,5839
|
|
202
208
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/ShareOptions/AccessUsersGroups/GroupsTab.js,sha256=ZqiuZjjr1SZnTs3cBhX7ZckixAVa2KErEZXKY00A3oE,2358
|
|
203
209
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/ShareOptions/AccessUsersGroups/PeopleTab.js,sha256=yk5anjYE7CNQ9_io3qIAgE_6oeFYvMn0hmc2McpEF_g,2348
|
|
204
|
-
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/ShareOptions/AccessUsersGroups/UserGroupAccessSearchResultItem.js,sha256=
|
|
210
|
+
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/ShareOptions/AccessUsersGroups/UserGroupAccessSearchResultItem.js,sha256=TYluO2lRliHcIoJBiTnAy8H4B-sEsa5h2TZ6mC1Xb7I,5750
|
|
205
211
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/landing_page/ShareOptions/api/api.js,sha256=WpRWWdlN_8TqeaMdB7RV2rQJSluetA91qIuJcAddfLY,926
|
|
206
212
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/overridableRegistry/index.js,sha256=xktX9vqs7xPTrKmGD93T-faSmg07LNsmK3GepA9F6j0,424
|
|
207
213
|
invenio_app_rdm/theme/assets/semantic-ui/js/invenio_app_rdm/overridableRegistry/mapping.js,sha256=kRIVYx1pkzq6kNry3M6Cn5hykDkNJAaG7sQ0BdwGSj8,434
|
|
@@ -374,7 +380,7 @@ invenio_app_rdm/theme/templates/semantic-ui/invenio_app_rdm/page.html,sha256=zwI
|
|
|
374
380
|
invenio_app_rdm/theme/templates/semantic-ui/invenio_app_rdm/page_cover.html,sha256=D-NNfCX38wRjHOq1kzPPncKKUd0b9U1al-NMy48dKvU,357
|
|
375
381
|
invenio_app_rdm/theme/templates/semantic-ui/invenio_app_rdm/searchbar.html,sha256=tvzez_2CE86wl_lipD44MD1swZcZw5uYqXEvvPMkBIo,2222
|
|
376
382
|
invenio_app_rdm/theme/templates/semantic-ui/invenio_app_rdm/site_footer.html,sha256=C0xluZe7KCkvRKeeMIt6P8v_EfWyuMCQ_JQvlI0M9Xw,1037
|
|
377
|
-
invenio_app_rdm/theme/templates/semantic-ui/invenio_app_rdm/files_integrity_report/email/files_integrity_report.html,sha256=
|
|
383
|
+
invenio_app_rdm/theme/templates/semantic-ui/invenio_app_rdm/files_integrity_report/email/files_integrity_report.html,sha256=mwbLrf2xabxq0dLQzUNWGHeYVoySo9GaaydT-FKC9g8,1237
|
|
378
384
|
invenio_app_rdm/theme/templates/semantic-ui/invenio_app_rdm/help/search.de.html,sha256=gefXaGv-ylkBUbvXXJe5EcTS66qoY0-v0XesXICX5_E,9310
|
|
379
385
|
invenio_app_rdm/theme/templates/semantic-ui/invenio_app_rdm/help/search.en.html,sha256=-EZdjhc4JslSq37_QN3KRL01LBwLJENkRtwBJ-PLSzc,8792
|
|
380
386
|
invenio_app_rdm/theme/templates/semantic-ui/invenio_app_rdm/help/search.sv.html,sha256=PHSLAuYtRTtsDgArshe5SIDs_M-dw8MUrSIrnNky2gw,9123
|
|
@@ -469,10 +475,10 @@ invenio_app_rdm/users_ui/views/__init__.py,sha256=SMdY2NJj9GICfr3Xuok7qdNYVtA2bJ
|
|
|
469
475
|
invenio_app_rdm/users_ui/views/dashboard.py,sha256=iUn2PrODAwb8ugmMosJKAjPhUzjCiWiAWoXQr9RUFuc,1793
|
|
470
476
|
invenio_app_rdm/users_ui/views/ui.py,sha256=W_eXM8dLVIrNHQB2UEh37C9BYoHauft6RyvcDNFHovA,1742
|
|
471
477
|
invenio_app_rdm/utils/files.py,sha256=CruDyO2gDVadSlWEJD-WHpWHeOQ0juh-Ei9jz3D9yjc,3923
|
|
472
|
-
invenio_app_rdm-13.0.0b3.
|
|
478
|
+
invenio_app_rdm-13.0.0b3.dev6.dist-info/licenses/LICENSE,sha256=AZXFHRrZa5s4m9DV7zZr4bPGTMUvcEPCodeV_AmFI8k,1204
|
|
473
479
|
tests/__init__.py,sha256=yKVf0yYRuxmXvyAtLjmfpHGVCsEkZOhs_FojAAM_w-8,244
|
|
474
|
-
tests/conftest.py,sha256=
|
|
475
|
-
tests/test_tasks.py,sha256=
|
|
480
|
+
tests/conftest.py,sha256=FQ_aSBxGo0gNfV64RJ117GcmgjVbZKwpxF9_3VNdNJY,7931
|
|
481
|
+
tests/test_tasks.py,sha256=YAf2mryFK6Vfzk2053XLBA2e92vbNCTWqJ6ThWhGOuQ,6645
|
|
476
482
|
tests/test_utils.py,sha256=nvj59DibjRZgLzwnch83tyCw9R1DEuDSQhU7v7mEOT0,1897
|
|
477
483
|
tests/test_version.py,sha256=c_ayM-WLlD0Q6z939sBnFpMTY160TmFg-9-hGsPa7FE,410
|
|
478
484
|
tests/test_views.py,sha256=Q0mSOqd6xVrAxQMdc0MAdZRUnxv7gFAkKcBQY-gQtUI,1420
|
|
@@ -490,20 +496,21 @@ tests/fixtures/app_data/pages.yaml,sha256=t4pyjwMBVI6MxEkwCtg9urMXo5fh0mzWy-Zr8N
|
|
|
490
496
|
tests/fixtures/app_data/pages/about.html,sha256=obB_g3uL1ligwguh0a0-tRLRBB-eGXN1NE-3odp2j-E,11
|
|
491
497
|
tests/mock_module/__init__.py,sha256=gu6vRcXqYTKCXZjvAIHZRv2w1IvpGiDs7atQJbij5M0,236
|
|
492
498
|
tests/mock_module/views.py,sha256=TWJQfcql5XaBNtdR9phVl4tHB0YG6g5IG5n08VZTzXE,770
|
|
493
|
-
tests/mock_module/templates/mock_mail.html,sha256=
|
|
499
|
+
tests/mock_module/templates/mock_mail.html,sha256=w7eiZbbs1gErCXelGN7NeiTavcDM9yUM702Mygz0oAc,943
|
|
494
500
|
tests/redirector/__init__.py,sha256=yKVf0yYRuxmXvyAtLjmfpHGVCsEkZOhs_FojAAM_w-8,244
|
|
495
501
|
tests/redirector/conftest.py,sha256=KAbp0R8tgGoNvMr8mJ1G2AZX6PzLw-PChtbucrLn5_o,1676
|
|
496
502
|
tests/redirector/test_redirector.py,sha256=iATYglIw3QSoUKpspQCAM4SaG_WmzjL7r1Nmew_KlGY,1002
|
|
497
503
|
tests/ui/__init__.py,sha256=yKVf0yYRuxmXvyAtLjmfpHGVCsEkZOhs_FojAAM_w-8,244
|
|
498
|
-
tests/ui/conftest.py,sha256=
|
|
504
|
+
tests/ui/conftest.py,sha256=3Msw0lfBoboQ7X-oZv_wGN7UF6StUpHPRVzRvbjhpoI,3472
|
|
499
505
|
tests/ui/test_deposits.py,sha256=BehQzo1r3_f4Uc9jcXRddd9bS5GfQ3jRRYOM0AMbi3w,3792
|
|
500
506
|
tests/ui/test_export_formats.py,sha256=pCXJCTp9ykEWb2oB-ynGjQDhFaVsOs31ym0stwfWCaQ,909
|
|
507
|
+
tests/ui/test_file_download.py,sha256=o4JHkFyJxZDaQ5NHRZR_PV98jS9UtklbOZPpduzwWKw,2436
|
|
501
508
|
tests/ui/test_filters.py,sha256=Q90wsJffjMVir7wNX8taGf2KZleLtPbXZXHLTkBpzLA,284
|
|
502
509
|
tests/ui/test_signposting_ui.py,sha256=KCSjQlMD2VKlwQCyZYDwYjtVNL35x3u-ZC4ceD5y21w,3847
|
|
503
510
|
tests/ui/test_static.py,sha256=vO3OQAOhrQESJifnQfM1pw7JYz3J874O8BAb7Cc_PPA,868
|
|
504
511
|
tests/ui/test_stats_ui.py,sha256=LHa_0hjvpYvliSk_jknWy-90CO82jVElUfK5Ua_ZmfA,3554
|
|
505
|
-
invenio_app_rdm-13.0.0b3.
|
|
506
|
-
invenio_app_rdm-13.0.0b3.
|
|
507
|
-
invenio_app_rdm-13.0.0b3.
|
|
508
|
-
invenio_app_rdm-13.0.0b3.
|
|
509
|
-
invenio_app_rdm-13.0.0b3.
|
|
512
|
+
invenio_app_rdm-13.0.0b3.dev6.dist-info/METADATA,sha256=0IFV1dDonrTlILr6xmZMYIm1o3Ff2EkJ4t1IT8WVzb0,13139
|
|
513
|
+
invenio_app_rdm-13.0.0b3.dev6.dist-info/WHEEL,sha256=oSJJyWjO7Z2XSScFQUpXG1HL-N0sFMqqeKVVbZTPkWc,109
|
|
514
|
+
invenio_app_rdm-13.0.0b3.dev6.dist-info/entry_points.txt,sha256=rfzEeOEdtGy99NlpWzeW-32CoO5XrEpBvlZwLD2Th88,2158
|
|
515
|
+
invenio_app_rdm-13.0.0b3.dev6.dist-info/top_level.txt,sha256=NqTqrntInEAci7EXcNBvouXFMqwyjVQhEI0b7izYRBY,22
|
|
516
|
+
invenio_app_rdm-13.0.0b3.dev6.dist-info/RECORD,,
|
{invenio_app_rdm-13.0.0b3.dev4.dist-info → invenio_app_rdm-13.0.0b3.dev6.dist-info}/entry_points.txt
RENAMED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
rdm = invenio_app_rdm.cli:rdm
|
|
3
3
|
|
|
4
4
|
[invenio_administration.views]
|
|
5
|
+
invenio_app_rdm_audit_logs = invenio_app_rdm.administration.audit_logs:AuditLogListView
|
|
5
6
|
invenio_app_rdm_drafts_list = invenio_app_rdm.administration.records:DraftAdminListView
|
|
6
7
|
invenio_app_rdm_records_list = invenio_app_rdm.administration.records:RecordAdminListView
|
|
7
8
|
invenio_requests_user_moderation_detail = invenio_app_rdm.administration.user_moderation:UserModerationRequestDetailView
|
tests/conftest.py
CHANGED
|
@@ -27,8 +27,6 @@ except AttributeError:
|
|
|
27
27
|
|
|
28
28
|
security.safe_str_cmp = hmac.compare_digest
|
|
29
29
|
|
|
30
|
-
import shutil
|
|
31
|
-
import tempfile
|
|
32
30
|
from collections import namedtuple
|
|
33
31
|
|
|
34
32
|
import pytest
|
|
@@ -41,7 +39,6 @@ from invenio_accounts.proxies import current_datastore
|
|
|
41
39
|
from invenio_accounts.testutils import login_user_via_session
|
|
42
40
|
from invenio_app.factory import create_app as _create_app
|
|
43
41
|
from invenio_db import db
|
|
44
|
-
from invenio_files_rest.models import Bucket, FileInstance, Location, ObjectVersion
|
|
45
42
|
from invenio_records_resources.proxies import current_service_registry
|
|
46
43
|
from invenio_vocabularies.contrib.subjects.api import Subject
|
|
47
44
|
from invenio_vocabularies.proxies import current_service as vocabulary_service
|
|
@@ -273,41 +270,3 @@ RunningApp = namedtuple(
|
|
|
273
270
|
def running_app(app, location, resource_type_item, language_item, subject_item):
|
|
274
271
|
"""Fixture mimicking a running app."""
|
|
275
272
|
return RunningApp(app, location, resource_type_item, language_item, subject_item)
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
@pytest.yield_fixture()
|
|
279
|
-
def dummy_location(db):
|
|
280
|
-
"""File system location."""
|
|
281
|
-
tmppath = tempfile.mkdtemp()
|
|
282
|
-
|
|
283
|
-
loc = Location(name="testloc", uri=tmppath, default=True)
|
|
284
|
-
db.session.add(loc)
|
|
285
|
-
db.session.commit()
|
|
286
|
-
|
|
287
|
-
yield loc
|
|
288
|
-
|
|
289
|
-
shutil.rmtree(tmppath)
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
@pytest.fixture
|
|
293
|
-
def invalid_file_instance(db, dummy_location):
|
|
294
|
-
"""Creates a file instance."""
|
|
295
|
-
# Create a Bucket and ObjectVersion
|
|
296
|
-
b1 = Bucket.create(location=dummy_location)
|
|
297
|
-
with open("README.rst", "rb") as fp:
|
|
298
|
-
obj = ObjectVersion.create(b1, "README.rst", stream=fp)
|
|
299
|
-
db.session.commit()
|
|
300
|
-
file_id = obj.file_id
|
|
301
|
-
|
|
302
|
-
# Get FileInstance from file ID
|
|
303
|
-
f = FileInstance.query.get(file_id)
|
|
304
|
-
|
|
305
|
-
# Force an invalid checksum
|
|
306
|
-
f.checksum = "invalid"
|
|
307
|
-
f.verify_checksum()
|
|
308
|
-
db.session.commit()
|
|
309
|
-
|
|
310
|
-
# Retrieve the file instance (with updated last_check)
|
|
311
|
-
f = FileInstance.query.get(file_id)
|
|
312
|
-
|
|
313
|
-
return f
|
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
#
|
|
4
4
|
# Copyright (C) 2022 CERN.
|
|
5
|
+
# Copyright (C) 2025 Northwestern University.
|
|
5
6
|
#
|
|
6
7
|
# Invenio App RDM is free software; you can redistribute it and/or modify it
|
|
7
8
|
# under the terms of the MIT License; see LICENSE file for more details.
|
|
8
9
|
-#}
|
|
9
10
|
|
|
10
|
-
{% set BASE_URL = config.SITE_UI_URL %}
|
|
11
|
-
|
|
12
11
|
{%- for entry in entries -%}
|
|
13
12
|
{{ "ID: %s" | format(entry.file.id) }}
|
|
14
13
|
{{ "URI: %s" | format(entry.file.uri) }}
|
|
@@ -19,10 +18,10 @@
|
|
|
19
18
|
{{ "Checksum: %s" | format(entry.file.checksum) }}
|
|
20
19
|
{{ "Last check: %s" | format(entry.file.last_check_at) }}
|
|
21
20
|
{%- if 'record' in entry %}
|
|
22
|
-
{{ "Record: %s
|
|
21
|
+
{{ "Record: %s" | format(invenio_url_for("invenio_app_rdm_records.record_detail", pid_value=entry.record.id)) }}
|
|
23
22
|
{%- endif %}
|
|
24
23
|
{%- if 'draft' in entry %}
|
|
25
|
-
{{ "Draft: %s
|
|
24
|
+
{{ "Draft: %s" | format(invenio_url_for("invenio_app_rdm_records.deposit_edit", pid_value=entry.draft.id)) }}
|
|
26
25
|
{%- endif %}
|
|
27
26
|
{{ "-" * 80 }}
|
|
28
27
|
{% endfor %}
|
tests/test_tasks.py
CHANGED
|
@@ -1,16 +1,102 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
#
|
|
3
3
|
# Copyright (C) 2022-2024 CERN.
|
|
4
|
+
# Copyright (C) 2025 Northwestern University.
|
|
4
5
|
#
|
|
5
6
|
# Invenio App RDM is free software; you can redistribute it and/or modify it
|
|
6
7
|
# under the terms of the MIT License; see LICENSE file for more details.
|
|
7
8
|
"""Test invenio-app-rdm celery tasks."""
|
|
8
9
|
|
|
9
|
-
from
|
|
10
|
+
from io import BytesIO
|
|
11
|
+
|
|
12
|
+
import pytest
|
|
13
|
+
from invenio_access.permissions import system_identity
|
|
14
|
+
from invenio_db import db
|
|
15
|
+
from invenio_files_rest.models import Bucket, FileInstance, Location, ObjectVersion
|
|
16
|
+
from invenio_rdm_records.proxies import current_rdm_records
|
|
10
17
|
|
|
18
|
+
from invenio_app_rdm.tasks import file_integrity_report
|
|
11
19
|
|
|
12
|
-
|
|
20
|
+
# Fixtures
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@pytest.fixture
|
|
24
|
+
def draft_with_file_instance(running_app, minimal_record):
|
|
25
|
+
"""Create draft with file and return (Draft, FileInstance)."""
|
|
26
|
+
minimal_record["files"] = {"enabled": True}
|
|
27
|
+
|
|
28
|
+
record_service = current_rdm_records.records_service
|
|
29
|
+
file_service = record_service.draft_files
|
|
30
|
+
|
|
31
|
+
draft = record_service.create(system_identity, minimal_record)
|
|
32
|
+
file_to_initialise = [
|
|
33
|
+
{
|
|
34
|
+
"key": "article.txt",
|
|
35
|
+
"checksum": "md5:c785060c866796cc2a1708c997154c8e",
|
|
36
|
+
"size": 17, # 2kB
|
|
37
|
+
"metadata": {
|
|
38
|
+
"description": "Published article PDF.",
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
file_service.init_files(system_identity, draft.id, file_to_initialise)
|
|
43
|
+
content = BytesIO(b"test file content")
|
|
44
|
+
file_service.set_file_content(
|
|
45
|
+
system_identity,
|
|
46
|
+
draft.id,
|
|
47
|
+
file_to_initialise[0]["key"],
|
|
48
|
+
content,
|
|
49
|
+
content.getbuffer().nbytes,
|
|
50
|
+
)
|
|
51
|
+
file_item = file_service.commit_file(system_identity, draft.id, "article.txt")
|
|
52
|
+
# fmt: off
|
|
53
|
+
id_of_file_instance = (
|
|
54
|
+
file_item
|
|
55
|
+
._record
|
|
56
|
+
.files
|
|
57
|
+
.entries["article.txt"]
|
|
58
|
+
.object_version.file_id
|
|
59
|
+
)
|
|
60
|
+
# fmt: on
|
|
61
|
+
f = FileInstance.query.get(id_of_file_instance)
|
|
62
|
+
return draft, f
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@pytest.fixture
|
|
66
|
+
def draft_with_invalid_file_instance(draft_with_file_instance):
|
|
67
|
+
# Force an invalid checksum
|
|
68
|
+
draft, f = draft_with_file_instance
|
|
69
|
+
f.checksum = "invalid"
|
|
70
|
+
f.verify_checksum()
|
|
71
|
+
db.session.commit()
|
|
72
|
+
|
|
73
|
+
# Retrieve the file instance (with updated last_check)
|
|
74
|
+
f = FileInstance.query.get(f.id)
|
|
75
|
+
|
|
76
|
+
return draft, f
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@pytest.fixture
|
|
80
|
+
def record_with_invalid_file_instance(draft_with_invalid_file_instance):
|
|
81
|
+
draft, f = draft_with_invalid_file_instance
|
|
82
|
+
record_service = current_rdm_records.records_service
|
|
83
|
+
return record_service.publish(system_identity, draft.id), f
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@pytest.fixture
|
|
87
|
+
def invalid_file_instance(record_with_invalid_file_instance):
|
|
88
|
+
draft, f = record_with_invalid_file_instance
|
|
89
|
+
return f
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# Tests
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_task_file_integrity_report(
|
|
96
|
+
app, record_with_invalid_file_instance, set_app_config_fn_scoped
|
|
97
|
+
):
|
|
13
98
|
"""Test celery task for file integrity reports."""
|
|
99
|
+
record, invalid_file_instance = record_with_invalid_file_instance
|
|
14
100
|
assert invalid_file_instance.last_check is False
|
|
15
101
|
|
|
16
102
|
# A report must be generated for the file
|
|
@@ -20,7 +106,6 @@ def test_task_file_integrity_report(app, invalid_file_instance):
|
|
|
20
106
|
recipients = "test@invenio.org"
|
|
21
107
|
sender = "test@invenio.org"
|
|
22
108
|
|
|
23
|
-
file_name = invalid_file_instance.objects[0].key
|
|
24
109
|
uri = invalid_file_instance.uri
|
|
25
110
|
file_id = invalid_file_instance.id
|
|
26
111
|
file_name = invalid_file_instance.objects[0].key
|
|
@@ -28,9 +113,13 @@ def test_task_file_integrity_report(app, invalid_file_instance):
|
|
|
28
113
|
|
|
29
114
|
with mail.record_messages() as outbox:
|
|
30
115
|
# Configure email and validate that email was sent
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
116
|
+
set_app_config_fn_scoped(
|
|
117
|
+
{
|
|
118
|
+
"APP_RDM_FILES_INTEGRITY_REPORT_TEMPLATE": "mock_mail.html",
|
|
119
|
+
"APP_RDM_ADMIN_EMAIL_RECIPIENT": recipients,
|
|
120
|
+
"MAIL_DEFAULT_SENDER": sender,
|
|
121
|
+
}
|
|
122
|
+
)
|
|
34
123
|
|
|
35
124
|
file_integrity_report()
|
|
36
125
|
assert len(outbox) == 1
|
|
@@ -41,9 +130,12 @@ def test_task_file_integrity_report(app, invalid_file_instance):
|
|
|
41
130
|
assert "URI: {}".format(uri) in mail_sent.body
|
|
42
131
|
assert "ID: {}".format(str(file_id)) in mail_sent.body
|
|
43
132
|
assert "Name: {}".format(file_name) in mail_sent.body
|
|
133
|
+
assert f"Record: https://127.0.0.1:5000/records/{record.id}" in mail_sent.body
|
|
44
134
|
|
|
45
135
|
|
|
46
|
-
def test_integrity_report_invalid_template(
|
|
136
|
+
def test_integrity_report_invalid_template(
|
|
137
|
+
app, invalid_file_instance, set_app_config_fn_scoped
|
|
138
|
+
):
|
|
47
139
|
"""Test non-existant e-mail template."""
|
|
48
140
|
assert invalid_file_instance.last_check is False
|
|
49
141
|
|
|
@@ -52,12 +144,15 @@ def test_integrity_report_invalid_template(app, invalid_file_instance):
|
|
|
52
144
|
|
|
53
145
|
with mail.record_messages() as outbox:
|
|
54
146
|
# Remove the template, no e-mail is sent
|
|
55
|
-
|
|
147
|
+
set_app_config_fn_scoped({"APP_RDM_FILES_INTEGRITY_REPORT_TEMPLATE": None})
|
|
148
|
+
|
|
56
149
|
file_integrity_report()
|
|
57
150
|
assert len(outbox) == 0
|
|
58
151
|
|
|
59
152
|
|
|
60
|
-
def test_integrity_report_invalid_addresses(
|
|
153
|
+
def test_integrity_report_invalid_addresses(
|
|
154
|
+
app, invalid_file_instance, set_app_config_fn_scoped
|
|
155
|
+
):
|
|
61
156
|
"""Test invalid recipient address."""
|
|
62
157
|
assert invalid_file_instance.last_check is False
|
|
63
158
|
|
|
@@ -65,17 +160,24 @@ def test_integrity_report_invalid_addresses(app, invalid_file_instance):
|
|
|
65
160
|
assert mail
|
|
66
161
|
|
|
67
162
|
with mail.record_messages() as outbox:
|
|
68
|
-
|
|
69
|
-
|
|
163
|
+
set_app_config_fn_scoped(
|
|
164
|
+
{
|
|
165
|
+
# Use mock template
|
|
166
|
+
"APP_RDM_FILES_INTEGRITY_REPORT_TEMPLATE": "mock_mail.html",
|
|
167
|
+
# Recipient is not set, mail is not sent.
|
|
168
|
+
"APP_RDM_ADMIN_EMAIL_RECIPIENT": None,
|
|
169
|
+
}
|
|
170
|
+
)
|
|
70
171
|
|
|
71
|
-
# Recipient is not set, mail is not sent.
|
|
72
|
-
app.config["APP_RDM_ADMIN_EMAIL_RECIPIENT"] = None
|
|
73
172
|
file_integrity_report()
|
|
74
173
|
assert len(outbox) == 0
|
|
75
174
|
|
|
76
175
|
|
|
77
|
-
def test_integrity_report_default_template(
|
|
176
|
+
def test_integrity_report_default_template(
|
|
177
|
+
app, draft_with_invalid_file_instance, set_app_config_fn_scoped
|
|
178
|
+
):
|
|
78
179
|
"""Test invalid recipient address."""
|
|
180
|
+
draft, invalid_file_instance = draft_with_invalid_file_instance
|
|
79
181
|
assert invalid_file_instance.last_check is False
|
|
80
182
|
|
|
81
183
|
mail = app.extensions.get("mail")
|
|
@@ -91,8 +193,10 @@ def test_integrity_report_default_template(app, invalid_file_instance):
|
|
|
91
193
|
|
|
92
194
|
with mail.record_messages() as outbox:
|
|
93
195
|
# Use default template
|
|
94
|
-
|
|
95
|
-
|
|
196
|
+
set_app_config_fn_scoped(
|
|
197
|
+
{"APP_RDM_ADMIN_EMAIL_RECIPIENT": recipients, "MAIL_DEFAULT_SENDER": sender}
|
|
198
|
+
)
|
|
199
|
+
|
|
96
200
|
file_integrity_report()
|
|
97
201
|
assert len(outbox) == 1
|
|
98
202
|
mail_sent = outbox[0]
|
|
@@ -102,3 +206,4 @@ def test_integrity_report_default_template(app, invalid_file_instance):
|
|
|
102
206
|
assert "URI: {}".format(uri) in mail_sent.body
|
|
103
207
|
assert "ID: {}".format(str(file_id)) in mail_sent.body
|
|
104
208
|
assert "Name: {}".format(file_name) in mail_sent.body
|
|
209
|
+
assert f"Draft: https://127.0.0.1:5000/uploads/{draft.id}" in mail_sent.body
|
tests/ui/conftest.py
CHANGED
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
from io import BytesIO
|
|
13
13
|
|
|
14
14
|
import pytest
|
|
15
|
+
from flask_principal import Identity
|
|
15
16
|
from flask_webpackext.manifest import (
|
|
16
17
|
JinjaManifest,
|
|
17
18
|
JinjaManifestEntry,
|
|
18
19
|
JinjaManifestLoader,
|
|
19
20
|
)
|
|
20
|
-
from invenio_access.permissions import system_identity
|
|
21
|
+
from invenio_access.permissions import any_user, authenticated_user, system_identity
|
|
21
22
|
from invenio_app.factory import create_ui
|
|
22
23
|
from invenio_rdm_records.proxies import current_rdm_records
|
|
23
24
|
from invenio_search import current_search
|
|
@@ -74,14 +75,18 @@ def record(running_app, minimal_record):
|
|
|
74
75
|
|
|
75
76
|
|
|
76
77
|
@pytest.fixture()
|
|
77
|
-
def
|
|
78
|
-
"""Create
|
|
78
|
+
def draft_with_file(running_app, minimal_record, users):
|
|
79
|
+
"""Create a draft with a file."""
|
|
79
80
|
minimal_record["files"] = {"enabled": True}
|
|
80
81
|
|
|
82
|
+
# Use a user's identity to make sure the record has an owner
|
|
83
|
+
user_identity = Identity(users["user1"].id)
|
|
84
|
+
user_identity.provides.add(any_user)
|
|
85
|
+
user_identity.provides.add(authenticated_user)
|
|
81
86
|
record_service = current_rdm_records.records_service
|
|
82
87
|
file_service = record_service.draft_files
|
|
83
88
|
|
|
84
|
-
draft = record_service.create(
|
|
89
|
+
draft = record_service.create(user_identity, minimal_record)
|
|
85
90
|
file_to_initialise = [
|
|
86
91
|
{
|
|
87
92
|
"key": "article.txt",
|
|
@@ -102,4 +107,11 @@ def record_with_file(running_app, minimal_record):
|
|
|
102
107
|
content.getbuffer().nbytes,
|
|
103
108
|
)
|
|
104
109
|
file_service.commit_file(system_identity, draft.id, "article.txt")
|
|
105
|
-
return
|
|
110
|
+
return draft
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@pytest.fixture()
|
|
114
|
+
def record_with_file(draft_with_file):
|
|
115
|
+
"""Create and publish a record with file."""
|
|
116
|
+
record_service = current_rdm_records.records_service
|
|
117
|
+
return record_service.publish(system_identity, draft_with_file.id)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (C) 2025 CERN.
|
|
4
|
+
# Copyright (C) 2025 KTH Royal Institute of Technology.
|
|
5
|
+
#
|
|
6
|
+
# Invenio-App-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
|
+
from flask import url_for
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_file_download_with_and_without_preview_flag(
|
|
13
|
+
client_with_login, draft_with_file
|
|
14
|
+
):
|
|
15
|
+
"""Test file download both with and without preview flag."""
|
|
16
|
+
client = client_with_login
|
|
17
|
+
draft_id = draft_with_file["id"]
|
|
18
|
+
file_name = "article.txt"
|
|
19
|
+
|
|
20
|
+
# The draft's owner should be able to download its file from the preview page
|
|
21
|
+
url_with_preview = url_for(
|
|
22
|
+
"invenio_app_rdm_records.record_file_download",
|
|
23
|
+
pid_value=draft_id,
|
|
24
|
+
filename=file_name,
|
|
25
|
+
download=1,
|
|
26
|
+
preview=1,
|
|
27
|
+
)
|
|
28
|
+
response = client.get(url_with_preview)
|
|
29
|
+
assert (
|
|
30
|
+
response.status_code == 200
|
|
31
|
+
), "File download with preview flag should return 200"
|
|
32
|
+
|
|
33
|
+
# But since the draft isn't published yet, it can't be found without preview=1
|
|
34
|
+
url_without_preview = url_for(
|
|
35
|
+
"invenio_app_rdm_records.record_file_download",
|
|
36
|
+
pid_value=draft_id,
|
|
37
|
+
filename=file_name,
|
|
38
|
+
download=1,
|
|
39
|
+
)
|
|
40
|
+
response = client.get(url_without_preview)
|
|
41
|
+
assert (
|
|
42
|
+
response.status_code == 404
|
|
43
|
+
), "File download without preview flag should return 404"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_nonexistent_file_returns_404(client_with_login, draft_with_file):
|
|
47
|
+
"""Test that requesting a non-existent file returns 404 via the NoResultFound handler."""
|
|
48
|
+
client = client_with_login
|
|
49
|
+
draft_id = draft_with_file["id"]
|
|
50
|
+
fake_file = "nonexistent-file.pdf"
|
|
51
|
+
|
|
52
|
+
# Downloads for files that don't exist should return a 404, both without...
|
|
53
|
+
url_without_preview = url_for(
|
|
54
|
+
"invenio_app_rdm_records.record_file_download",
|
|
55
|
+
pid_value=draft_id,
|
|
56
|
+
filename=fake_file,
|
|
57
|
+
download=1,
|
|
58
|
+
)
|
|
59
|
+
response = client.get(url_without_preview)
|
|
60
|
+
assert response.status_code == 404, "Non-existent file should return 404"
|
|
61
|
+
|
|
62
|
+
# ... as well as with the preview=1 flag
|
|
63
|
+
url_with_preview = url_for(
|
|
64
|
+
"invenio_app_rdm_records.record_file_download",
|
|
65
|
+
pid_value=draft_id,
|
|
66
|
+
filename=fake_file,
|
|
67
|
+
download=1,
|
|
68
|
+
preview=1,
|
|
69
|
+
)
|
|
70
|
+
response = client.get(url_with_preview)
|
|
71
|
+
assert (
|
|
72
|
+
response.status_code == 404
|
|
73
|
+
), "Non-existent file with preview flag should return 404"
|
invenio_app_rdm/urls.py
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# Copyright (C) 2023 Northwestern University.
|
|
4
|
-
#
|
|
5
|
-
# This file is lifted from Invenio-RDM-Records .
|
|
6
|
-
#
|
|
7
|
-
# Invenio-RDM-Records is free software; you can redistribute it and/or modify
|
|
8
|
-
# it under the terms of the MIT License; see LICENSE file for more details.
|
|
9
|
-
|
|
10
|
-
"""Convenient URL generation.
|
|
11
|
-
|
|
12
|
-
InvenioRDM poses challenges to url generation that Flask's url_for cannot handle out
|
|
13
|
-
of the gate.
|
|
14
|
-
|
|
15
|
-
- InvenioRDM is actually 2 applications mounted on different url_prefixes:
|
|
16
|
-
`url_for` in the API application isn't aware of the UI application endpoints
|
|
17
|
-
- The endpoint names are relatively hidden / spread out and APP_RDM_ROUTES is usually
|
|
18
|
-
the interface to name them.
|
|
19
|
-
- Need to be able to generate urls outside of request context without thinking about it,
|
|
20
|
-
|
|
21
|
-
This module contains minimal methods to generate URLs correctly without much
|
|
22
|
-
engineering. Over time, it can be made more abstract, complex and powerful and even
|
|
23
|
-
extracted into its own package to solve url generation across InvenioRDM once and for
|
|
24
|
-
all.
|
|
25
|
-
|
|
26
|
-
Design decisions:
|
|
27
|
-
|
|
28
|
-
- Generated urls are absolute for now
|
|
29
|
-
"""
|
|
30
|
-
|
|
31
|
-
import unicodedata
|
|
32
|
-
from urllib.parse import quote
|
|
33
|
-
|
|
34
|
-
from flask import current_app
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def record_url_for(_app="ui", pid_value=""):
|
|
38
|
-
"""Return url for record route."""
|
|
39
|
-
assert _app in ["ui", "api"]
|
|
40
|
-
|
|
41
|
-
site_app = _app.upper()
|
|
42
|
-
url_prefix = current_app.config.get(f"SITE_{site_app}_URL", "")
|
|
43
|
-
|
|
44
|
-
# We use [] so that this fails and brings to attention the configuration
|
|
45
|
-
# problem if APP_RDM_ROUTES.record_detail is missing
|
|
46
|
-
url_path = current_app.config["APP_RDM_ROUTES"]["record_detail"].replace(
|
|
47
|
-
"<pid_value>", pid_value
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
return "/".join(p.strip("/") for p in [url_prefix, url_path])
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def download_url_for(pid_value="", filename=""):
|
|
54
|
-
"""Return url for download route."""
|
|
55
|
-
url_prefix = current_app.config.get("SITE_UI_URL", "")
|
|
56
|
-
|
|
57
|
-
# see https://github.com/pallets/werkzeug/blob/main/src/werkzeug/utils.py#L456-L465
|
|
58
|
-
try:
|
|
59
|
-
filename.encode("ascii")
|
|
60
|
-
except UnicodeEncodeError:
|
|
61
|
-
# safe = RFC 5987 attr-char
|
|
62
|
-
filename = quote(filename, safe="!#$&+-.^_`|~")
|
|
63
|
-
|
|
64
|
-
# We use [] so that this fails and brings to attention the configuration
|
|
65
|
-
# problem if APP_RDM_ROUTES.record_file_download is missing
|
|
66
|
-
url_path = (
|
|
67
|
-
current_app.config["APP_RDM_ROUTES"]["record_file_download"]
|
|
68
|
-
.replace("<pid_value>", pid_value)
|
|
69
|
-
.replace("<path:filename>", filename)
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
return "/".join(p.strip("/") for p in [url_prefix, url_path])
|