diff --git a/test/collection/test_config_update.py b/test/collection/test_config_update.py index c7ddd6ab4..b0f2ba11e 100644 --- a/test/collection/test_config_update.py +++ b/test/collection/test_config_update.py @@ -1,13 +1,55 @@ +from datetime import timedelta + import pytest from test.collection.schema import multi_vector_schema from weaviate.collections.classes.config import ( + Configure, Reconfigure, _CollectionConfigUpdate, ) from weaviate.exceptions import WeaviateInvalidInputError +@pytest.mark.parametrize("offset", [3600, -3600]) +def test_object_ttl_update_preserves_omitted_offset(offset: int) -> None: + schema = { + "objectTTLConfig": { + "enabled": True, + "deleteOn": "expiresAt", + "defaultTtl": offset, + "filterExpiredObjects": False, + } + } + update = _CollectionConfigUpdate( + object_ttl_config=Reconfigure.ObjectTTL.delete_by_date_property(filter_expired_objects=True) + ) + + merged = update.merge_with_existing(schema) + + assert merged["objectTTLConfig"] == { + "enabled": True, + "deleteOn": "expiresAt", + "defaultTtl": offset, + "filterExpiredObjects": True, + } + + +@pytest.mark.parametrize("offset", [0, -60, timedelta(seconds=120)]) +def test_object_ttl_update_applies_explicit_offset(offset: int | timedelta) -> None: + update = Reconfigure.ObjectTTL.delete_by_date_property(ttl_offset=offset) + merged = update.merge_with_existing({"deleteOn": "expiresAt", "defaultTtl": 3600}) + assert merged["defaultTtl"] == ( + int(offset.total_seconds()) if isinstance(offset, timedelta) else offset + ) + assert merged["deleteOn"] == "expiresAt" + + +def test_object_ttl_creation_defaults_to_zero_offset() -> None: + config = Configure.ObjectTTL.delete_by_date_property("expiresAt") + assert config._to_dict()["defaultTtl"] == 0 + + @pytest.mark.parametrize( "schema,should_error", [ diff --git a/weaviate/collections/classes/config_object_ttl.py b/weaviate/collections/classes/config_object_ttl.py index 86981f6dd..942b41a84 100644 --- a/weaviate/collections/classes/config_object_ttl.py +++ b/weaviate/collections/classes/config_object_ttl.py @@ -145,13 +145,11 @@ def delete_by_date_property( Args: property_name: The name of the date property to use for object expiration. - ttl_offset: The time-to-live for objects relative to the date (seconds if integer). Can be negative for indicating that objects should expire before the date property value. + ttl_offset: The time-to-live for objects relative to the date (seconds if integer). Can be negative for indicating that objects should expire before the date property value. If `None`, preserve the existing offset. Pass `0` to reset it. filter_expired_objects: If enabled, exclude expired but not deleted objects from search results. """ if isinstance(ttl_offset, datetime.timedelta): ttl_offset = int(ttl_offset.total_seconds()) - if ttl_offset is None: - ttl_offset = 0 return ObjectTTLConfigUpdate( enabled=True, deleteOn=property_name,