Coverage for tests / test_export_zenodo_csv.py: 100%
44 statements
« prev ^ index » next coverage.py v7.12.0, created at 2026-07-17 16:43 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2026-07-17 16:43 +0000
1# SPDX-FileCopyrightText: 2025-2026 Arcangelo Massari <arcangelo.massari@unibo.it>
2#
3# SPDX-License-Identifier: ISC
5import json
6from unittest.mock import call, patch
8import pytest
9import requests
11from changes_metadata_manager.export_zenodo_csv import export_zenodo_csv
14def _draft(record_id: str) -> dict:
15 return {
16 "draft_id": record_id,
17 "config_file": "/missing/stale-config.yaml",
18 "title": "Stale local title",
19 "zenodo_url": "https://zenodo.org/api",
20 "access_token": "token",
21 "user_agent": "agent",
22 "status": "published",
23 "doi": "stale-doi",
24 "record_url": "stale-url",
25 }
28def _record(record_id: str, title: str, creators: list[dict]) -> dict:
29 return {
30 "metadata": {
31 "title": title,
32 "publication_date": "2026-07-17",
33 "publisher": "Zenodo",
34 "resource_type": {"id": "dataset", "title": {"en": "Dataset"}},
35 "creators": creators,
36 "rights": [
37 {
38 "title": {
39 "en": "Creative Commons Zero v1.0 Universal (Metadata license)"
40 },
41 "link": ("https://creativecommons.org/publicdomain/zero/1.0/"),
42 },
43 {
44 "title": {
45 "en": "Creative Commons Attribution 4.0 International "
46 "(Content license)"
47 },
48 "link": "https://creativecommons.org/licenses/by/4.0/",
49 },
50 ],
51 },
52 "pids": {"doi": {"identifier": f"10.5281/zenodo.{record_id}"}},
53 "links": {"self_html": f"https://zenodo.org/records/{record_id}"},
54 }
57GIRELLI = {
58 "person_or_org": {
59 "type": "personal",
60 "family_name": "Girelli",
61 "given_name": "Valentina Alena",
62 "identifiers": [{"scheme": "orcid", "identifier": "0000-0001-9257-9803"}],
63 }
64}
66MANGANELLI = {
67 "person_or_org": {
68 "type": "personal",
69 "family_name": "Manganelli Del Fà",
70 "given_name": "Rachele",
71 "identifiers": [{"scheme": "orcid", "identifier": "0009-0007-4401-9323"}],
72 }
73}
76@patch("changes_metadata_manager.export_zenodo_csv.time.sleep")
77@patch("changes_metadata_manager.export_zenodo_csv.fetch_latest_published_record")
78def test_exports_latest_remote_versions_in_drafts_order(
79 mock_fetch, mock_sleep, tmp_path
80):
81 drafts_path = tmp_path / "drafts.json"
82 drafts = [
83 _draft("101"),
84 {
85 **_draft(""),
86 "status": "failed",
87 "zenodo_url": "",
88 "access_token": "",
89 "user_agent": "",
90 },
91 _draft("102"),
92 ]
93 drafts_path.write_text(json.dumps(drafts))
94 mock_fetch.side_effect = [
95 _record("201", "Corrected remote title A", [GIRELLI, MANGANELLI]),
96 _record("202", "Corrected remote title B", [MANGANELLI]),
97 ]
99 csv_path = export_zenodo_csv(drafts_path)
101 assert csv_path == tmp_path / "doi_table.csv"
102 assert csv_path.read_text() == (
103 "Numero su DMP,Caso di studio,Autore/i,Tipo,Titolo,Data pubblicazione,"
104 "DOI,URL,Repository,Licenza,Note\n"
105 ',Aldrovandi,"Girelli, Valentina Alena [orcid:0000-0001-9257-9803]; '
106 'Manganelli Del Fà, Rachele [orcid:0009-0007-4401-9323]",Dataset,'
107 "Corrected remote title A,2026-07-17,10.5281/zenodo.201,"
108 "https://zenodo.org/records/201,Zenodo,"
109 "cc0-1.0 (Metadata license); cc-by-4.0 (Content license),\n"
110 ',Aldrovandi,"Manganelli Del Fà, Rachele '
111 '[orcid:0009-0007-4401-9323]",Dataset,Corrected remote title B,'
112 "2026-07-17,10.5281/zenodo.202,https://zenodo.org/records/202,"
113 "Zenodo,cc0-1.0 (Metadata license); cc-by-4.0 (Content license),\n"
114 )
115 assert mock_fetch.call_args_list == [
116 call("https://zenodo.org/api", "101", "token", "agent"),
117 call("https://zenodo.org/api", "102", "token", "agent"),
118 ]
119 assert mock_sleep.call_args_list == [call(0.5), call(0.5)]
122@patch("changes_metadata_manager.export_zenodo_csv.time.sleep")
123@patch("changes_metadata_manager.export_zenodo_csv.fetch_latest_published_record")
124def test_writes_to_requested_output(mock_fetch, mock_sleep, tmp_path):
125 drafts_path = tmp_path / "drafts.json"
126 drafts_path.write_text(json.dumps([_draft("101")]))
127 mock_fetch.return_value = _record("201", "Remote title", [GIRELLI])
128 output_path = tmp_path / "silvio.csv"
130 result = export_zenodo_csv(drafts_path, output_path)
132 assert result == output_path
133 assert output_path.exists()
134 mock_sleep.assert_called_once_with(0.5)
137@patch("changes_metadata_manager.export_zenodo_csv.fetch_latest_published_record")
138def test_http_error_preserves_existing_csv(mock_fetch, tmp_path):
139 drafts_path = tmp_path / "drafts.json"
140 drafts_path.write_text(json.dumps([_draft("404")]))
141 output_path = tmp_path / "doi_table.csv"
142 output_path.write_text("previous export\n")
143 mock_fetch.side_effect = requests.HTTPError("404 Client Error")
145 with pytest.raises(requests.HTTPError, match="404 Client Error"):
146 export_zenodo_csv(drafts_path)
148 assert output_path.read_text() == "previous export\n"