From 672ff18a7c01a556bcab9e77d6a3f7e4c228262f Mon Sep 17 00:00:00 2001 From: Mark Powers Date: Mon, 11 Nov 2024 15:20:35 -0600 Subject: [PATCH] Fix slug generation (#207) * Fix slug generation Slugs are intended to be human-readable and unique for an artifact. However when a user submitted multiple versions they often got duplicated slugs. This was because our check for an existing version was based on the artifacts date, not the version date. We attempted to fix in #133, but the issue persisted. I just happened to notice this filter code seemed wrong. * Fix black formatting --- trovi/models.py | 2 +- trovi/settings.py | 6 ++++-- util/sql_format.py | 1 + util/test.py | 19 ++++++++++++------- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/trovi/models.py b/trovi/models.py index c997e6f..59736c0 100644 --- a/trovi/models.py +++ b/trovi/models.py @@ -300,7 +300,7 @@ def generate_slug(instance: "ArtifactVersion", created: bool = False, **_): with transaction.atomic(): if instance.artifact: versions_today_query = instance.artifact.versions.filter( - artifact__created_at__date=instance.created_at.date(), + created_at__date=instance.created_at.date(), ).select_for_update() versions_today = versions_today_query.exclude( slug__exact="" diff --git a/trovi/settings.py b/trovi/settings.py index 63a0628..f08050f 100644 --- a/trovi/settings.py +++ b/trovi/settings.py @@ -14,6 +14,7 @@ from pathlib import Path # Build paths inside the project like this: BASE_DIR / 'subdir'. +import sys from urllib.parse import urlparse BASE_DIR = Path(__file__).resolve().parent.parent @@ -124,7 +125,7 @@ # Plugins "rest_framework", "drf_spectacular", - 'corsheaders', + "corsheaders", # Trovi "trovi.apps.TroviConfig", "trovi.api.apps.ApiConfig", @@ -191,8 +192,9 @@ # Database # https://docs.djangoproject.com/en/3.2/ref/settings/#databases +TESTING = "test" in sys.argv or "test_coverage" in sys.argv -if os.getenv("DB_ENGINE"): +if not TESTING and os.getenv("DB_ENGINE"): DATABASES = { "default": { "ENGINE": os.getenv("DB_ENGINE"), diff --git a/util/sql_format.py b/util/sql_format.py index 3ddcaf5..b7826ae 100644 --- a/util/sql_format.py +++ b/util/sql_format.py @@ -1,4 +1,5 @@ """Pretty-Print SQL queries for console output.""" + from logging import Formatter from django.conf import settings diff --git a/util/test.py b/util/test.py index 56e54c7..e775f35 100644 --- a/util/test.py +++ b/util/test.py @@ -3,6 +3,7 @@ Not meant to be robust, and mostly unvalidated, but helpful to avoid having to reference dicts with strings repeatedly in tests. """ + import datetime import logging import os @@ -160,6 +161,8 @@ def fake_tag() -> str: is_reproducible=True, repro_access_hours=3, ) +artifact_don_quixote.created_at -= datetime.timedelta(days=2) + version_don_quixote_1 = ArtifactVersion( artifact=artifact_don_quixote, contents_urn=f"urn:trovi:contents:chameleon:{uuid4()}", @@ -270,9 +273,9 @@ def generate_fake_artifact() -> list[models.Model]: ArtifactEvent( artifact_version=random.choice(artifact_versions), event_type=random.choice(ArtifactEvent.EventType.values), - event_origin=None - if fake.boolean(chance_of_getting_true=90) - else fake_user_urn(), + event_origin=( + None if fake.boolean(chance_of_getting_true=90) else fake_user_urn() + ), ) for _ in range(random.randint(0, 40)) ] @@ -282,10 +285,12 @@ def _verified() -> dict[str, Union[bool, Optional[datetime.datetime]]]: verified = fake.boolean(chance_of_getting_true=20) return { "verified": verified, - "verified_at": None - if not verified - else fake.date_time_between( - datetime.date.min, datetime.date.max, timezone.utc + "verified_at": ( + None + if not verified + else fake.date_time_between( + datetime.date.min, datetime.date.max, timezone.utc + ) ), }