From 1275b7bdecff7a18047bf490c230ee343a75cc0c Mon Sep 17 00:00:00 2001 From: Nathan Franklin Date: Mon, 13 May 2024 09:53:03 -0500 Subject: [PATCH] task/DES-2767: fix file metadata route path issue (#1235) * Normalize path to be consistent * Remove some unneeded fixgtures --------- Co-authored-by: Jake Rosenberg --- designsafe/apps/api/filemeta/models.py | 14 ++++++++++++- designsafe/apps/api/filemeta/tests.py | 27 ++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/designsafe/apps/api/filemeta/models.py b/designsafe/apps/api/filemeta/models.py index e9a9e41e0e..1f8992bea4 100644 --- a/designsafe/apps/api/filemeta/models.py +++ b/designsafe/apps/api/filemeta/models.py @@ -5,6 +5,16 @@ from django.utils import timezone +def _get_normalized_path(path) -> str: + """ Return a file path that begins with /" + + For example, "file.jpg" becomes "/file.jpg" + """ + if not path.startswith('/'): + path = '/' + path + return path + + class FileMetaModel(models.Model): """Model for File Meta""" @@ -41,7 +51,8 @@ def create_or_update_file_meta(cls, value): - tuple (instance, created): The FileMetaModel instance and a boolean indicating if it was created (True) or updated (False). """ system = value.get("system") - path = value.get("path") + path = _get_normalized_path(value.get("path")) + value["path"] = path # Use a transaction to ensure atomicity with transaction.atomic(): @@ -64,4 +75,5 @@ def get_by_path_and_system(cls, system, path): Raises: - DoesNotExist: if file metadata entry not found """ + path = _get_normalized_path(path) return cls.objects.get(value__system=system, value__path=path) diff --git a/designsafe/apps/api/filemeta/tests.py b/designsafe/apps/api/filemeta/tests.py index aea44dd3a1..cba2d9d0e5 100644 --- a/designsafe/apps/api/filemeta/tests.py +++ b/designsafe/apps/api/filemeta/tests.py @@ -179,8 +179,6 @@ def test_create_file_meta_update_existing_entry( def test_create_file_metadata_missing_system_or_path( client, authenticated_user, - filemeta_db_mock, - filemeta_value_mock, mock_access_success, ): value_missing_system_path = {"foo": "bar"} @@ -191,3 +189,28 @@ def test_create_file_metadata_missing_system_or_path( content_type="application/json", ) assert response.status_code == 400 + + +@pytest.mark.django_db +def test_create_using_path_without_starting_slashes_issue_DES_2767 ( + filemeta_value_mock, +): + # testing that "file.txt" and "/file.txt" are referring to the same + # file and that "file.txt" is normalized to "/file.txt" + filemeta_value_mock["path"] = "file.txt" + + file_meta, created = FileMetaModel.create_or_update_file_meta(filemeta_value_mock) + assert created + assert file_meta.value["path"] == "/file.txt" + + +@pytest.mark.django_db +def test_get_using_path_with_or_without_starting_slashes_issue_DES_2767( + filemeta_value_mock, +): + filemeta_value_mock["path"] = "file.txt" + FileMetaModel.create_or_update_file_meta(filemeta_value_mock) + + system = filemeta_value_mock["system"] + FileMetaModel.get_by_path_and_system(system, "file.txt") + FileMetaModel.get_by_path_and_system(system, "/file.txt")