diff --git a/api/features/versioning/managers.py b/api/features/versioning/managers.py index 1cb8371f32da..d78131907460 100644 --- a/api/features/versioning/managers.py +++ b/api/features/versioning/managers.py @@ -2,6 +2,7 @@ from pathlib import Path from django.db.models.query import QuerySet, RawQuerySet +from django.utils import timezone from softdelete.models import SoftDeleteManager if typing.TYPE_CHECKING: @@ -53,5 +54,14 @@ def _get_latest_versions( return self.raw( get_latest_versions_sql, - params={"environment_id": environment_id, "api_key": environment_api_key}, + params={ + "environment_id": environment_id, + "api_key": environment_api_key, + # TODO: + # It seems as though there is a timezone issue when using postgres's + # built in now() function, so we pass in the current time from python. + # Using <= now() in the SQL query returns incorrect results. + # More investigation is needed here to understand the cause. + "live_from_before": timezone.now().isoformat(), + }, ) diff --git a/api/features/versioning/sql/get_latest_versions.sql b/api/features/versioning/sql/get_latest_versions.sql index a9516e73881d..08ca0e8919da 100644 --- a/api/features/versioning/sql/get_latest_versions.sql +++ b/api/features/versioning/sql/get_latest_versions.sql @@ -14,6 +14,7 @@ join ( where efv2."deleted_at" is null and efv2."published_at" is not null + and efv2."live_from" <= %(live_from_before)s group by efv2."feature_id", efv2."environment_id" diff --git a/api/tests/unit/features/versioning/test_unit_versioning_models.py b/api/tests/unit/features/versioning/test_unit_versioning_models.py index f369eb751b09..ee26cc905e4f 100644 --- a/api/tests/unit/features/versioning/test_unit_versioning_models.py +++ b/api/tests/unit/features/versioning/test_unit_versioning_models.py @@ -1,4 +1,5 @@ import typing +from datetime import timedelta import pytest from django.utils import timezone @@ -248,3 +249,31 @@ def test_update_version_webhooks_triggered_when_version_published( kwargs={"environment_feature_version_uuid": str(new_version.uuid)}, delay_until=new_version.live_from, ) + + +def test_get_latest_versions_does_not_return_versions_scheduled_for_the_future( + environment_v2_versioning: Environment, + feature: "Feature", + admin_user: "FFAdminUser", +) -> None: + # Given + version_0 = EnvironmentFeatureVersion.objects.get( + environment=environment_v2_versioning, feature=feature + ) + + # Let's create a version scheduled for the future, that we'll publish + scheduled_version = EnvironmentFeatureVersion.objects.create( + environment=environment_v2_versioning, + feature=feature, + live_from=timezone.now() + timedelta(hours=1), + ) + scheduled_version.publish(admin_user) + + # When + latest_versions = EnvironmentFeatureVersion.objects.get_latest_versions_as_queryset( + environment_id=environment_v2_versioning.id + ) + + # Then + assert latest_versions.count() == 1 + assert latest_versions.first() == version_0