44
55import httpx
66
7- from pyDataverse .api import NativeApi
7+ from pyDataverse .api import DataAccessApi , NativeApi
88from pyDataverse .models import Datafile
99
1010
@@ -132,9 +132,9 @@ def test_bulk_file_upload(self, create_mock_file):
132132 # Assert
133133 assert response .status_code == 200 , "File upload failed."
134134
135- def test_file_replacement (self ):
135+ def test_file_replacement_wo_metadata (self ):
136136 """
137- Test case for replacing a file in a dataset.
137+ Test case for replacing a file in a dataset without metadata .
138138
139139 Steps:
140140 1. Create a dataset using the provided metadata.
@@ -151,6 +151,7 @@ def test_file_replacement(self):
151151 metadata = json .load (open ("tests/data/file_upload_ds_minimum.json" ))
152152 pid = self ._create_dataset (BASE_URL , API_TOKEN , metadata )
153153 api = NativeApi (BASE_URL , API_TOKEN )
154+ data_api = DataAccessApi (BASE_URL , API_TOKEN )
154155
155156 # Perform file upload
156157 df = Datafile ({"pid" : pid , "filename" : "datafile.txt" })
@@ -161,7 +162,64 @@ def test_file_replacement(self):
161162 )
162163
163164 # Retrieve file ID
164- file_id = self ._get_file_id (BASE_URL , API_TOKEN , pid )
165+ file_id = response .json ()["data" ]["files" ][0 ]["dataFile" ]["id" ]
166+
167+ # Act
168+ with tempfile .TemporaryDirectory () as tempdir :
169+ original = open ("tests/data/replace.xyz" ).read ()
170+ mutated = "Z" + original [1 ::]
171+ mutated_path = os .path .join (tempdir , "replace.xyz" )
172+
173+ with open (mutated_path , "w" ) as f :
174+ f .write (mutated )
175+
176+ json_data = {}
177+
178+ response = api .replace_datafile (
179+ identifier = file_id ,
180+ filename = mutated_path ,
181+ json_str = json .dumps (json_data ),
182+ is_filepid = False ,
183+ )
184+
185+ # Assert
186+ file_id = response .json ()["data" ]["files" ][0 ]["dataFile" ]["id" ]
187+ content = data_api .get_datafile (file_id , is_pid = False ).text
188+
189+ assert response .status_code == 200 , "File replacement failed."
190+ assert content == mutated , "File content does not match the expected content."
191+
192+ def test_file_replacement_w_metadata (self ):
193+ """
194+ Test case for replacing a file in a dataset with metadata.
195+
196+ Steps:
197+ 1. Create a dataset using the provided metadata.
198+ 2. Upload a datafile to the dataset.
199+ 3. Replace the uploaded datafile with a mutated version.
200+ 4. Verify that the file replacement was successful and the content matches the expected content.
201+ """
202+
203+ # Arrange
204+ BASE_URL = os .getenv ("BASE_URL" ).rstrip ("/" )
205+ API_TOKEN = os .getenv ("API_TOKEN" )
206+
207+ # Create dataset
208+ metadata = json .load (open ("tests/data/file_upload_ds_minimum.json" ))
209+ pid = self ._create_dataset (BASE_URL , API_TOKEN , metadata )
210+ api = NativeApi (BASE_URL , API_TOKEN )
211+ data_api = DataAccessApi (BASE_URL , API_TOKEN )
212+
213+ # Perform file upload
214+ df = Datafile ({"pid" : pid , "filename" : "datafile.txt" })
215+ response = api .upload_datafile (
216+ identifier = pid ,
217+ filename = "tests/data/replace.xyz" ,
218+ json_str = df .json (),
219+ )
220+
221+ # Retrieve file ID
222+ file_id = response .json ()["data" ]["files" ][0 ]["dataFile" ]["id" ]
165223
166224 # Act
167225 with tempfile .TemporaryDirectory () as tempdir :
@@ -187,26 +245,19 @@ def test_file_replacement(self):
187245 )
188246
189247 # Assert
190- replaced_id = self ._get_file_id (BASE_URL , API_TOKEN , pid )
191- file_metadata = self ._get_file_metadata (BASE_URL , API_TOKEN , replaced_id )
192- data_file = file_metadata ["dataFile" ]
193- replaced_content = self ._fetch_datafile_content (
194- BASE_URL ,
195- API_TOKEN ,
196- replaced_id ,
197- )
248+ file_id = response .json ()["data" ]["files" ][0 ]["dataFile" ]["id" ]
249+ data_file = api .get_dataset (pid ).json ()["data" ]["latestVersion" ]["files" ][0 ]
250+ content = data_api .get_datafile (file_id , is_pid = False ).text
198251
199252 assert (
200253 data_file ["description" ] == "My description."
201254 ), "Description does not match."
202255 assert data_file ["categories" ] == ["Data" ], "Categories do not match."
203256 assert (
204- file_metadata ["directoryLabel" ] == "some/other"
257+ data_file ["directoryLabel" ] == "some/other"
205258 ), "Directory label does not match."
206259 assert response .status_code == 200 , "File replacement failed."
207- assert (
208- replaced_content == mutated
209- ), "File content does not match the expected content."
260+ assert content == mutated , "File content does not match the expected content."
210261
211262 @staticmethod
212263 def _create_dataset (
@@ -238,82 +289,3 @@ def _create_dataset(
238289 response .raise_for_status ()
239290
240291 return response .json ()["data" ]["persistentId" ]
241-
242- @staticmethod
243- def _get_file_id (
244- BASE_URL : str ,
245- API_TOKEN : str ,
246- pid : str ,
247- ):
248- """
249- Retrieves the file ID for a given persistent identifier (PID) in Dataverse.
250-
251- Args:
252- BASE_URL (str): The base URL of the Dataverse instance.
253- API_TOKEN (str): The API token for authentication.
254- pid (str): The persistent identifier (PID) of the dataset.
255-
256- Returns:
257- str: The file ID of the latest version of the dataset.
258-
259- Raises:
260- HTTPError: If the HTTP request to retrieve the file ID fails.
261- """
262- response = httpx .get (
263- url = f"{ BASE_URL } /api/datasets/:persistentId/?persistentId={ pid } " ,
264- headers = {"X-Dataverse-key" : API_TOKEN },
265- )
266-
267- response .raise_for_status ()
268-
269- return response .json ()["data" ]["latestVersion" ]["files" ][0 ]["dataFile" ]["id" ]
270-
271- @staticmethod
272- def _fetch_datafile_content (
273- BASE_URL : str ,
274- API_TOKEN : str ,
275- id : str ,
276- ):
277- """
278- Fetches the content of a datafile from the specified BASE_URL using the provided API_TOKEN.
279-
280- Args:
281- BASE_URL (str): The base URL of the Dataverse instance.
282- API_TOKEN (str): The API token for authentication.
283- id (str): The ID of the datafile.
284-
285- Returns:
286- str: The content of the datafile as a decoded UTF-8 string.
287- """
288- url = f"{ BASE_URL } /api/access/datafile/{ id } "
289- headers = {"X-Dataverse-key" : API_TOKEN }
290- response = httpx .get (url , headers = headers )
291- response .raise_for_status ()
292-
293- return response .content .decode ("utf-8" )
294-
295- @staticmethod
296- def _get_file_metadata (
297- BASE_URL : str ,
298- API_TOKEN : str ,
299- id : str ,
300- ):
301- """
302- Retrieves the metadata for a file in Dataverse.
303-
304- Args:
305- BASE_URL (str): The base URL of the Dataverse instance.
306- API_TOKEN (str): The API token for authentication.
307- id (str): The ID of the file.
308-
309- Returns:
310- dict: The metadata for the file.
311- """
312- response = httpx .get (
313- url = f"{ BASE_URL } /api/files/{ id } " ,
314- headers = {"X-Dataverse-key" : API_TOKEN },
315- )
316-
317- response .raise_for_status ()
318-
319- return response .json ()["data" ]
0 commit comments