From e9fde1e4be2b9d7f7ae69fca818c23542a1c8df6 Mon Sep 17 00:00:00 2001 From: yh-0 Date: Thu, 17 Jul 2025 11:17:35 +0200 Subject: [PATCH] Various tests --- ravendb/documents/commands/revisions.py | 2 +- .../indexes/abstract_index_creation_tasks.py | 2 +- .../in_memory_document_session_operations.py | 2 +- ravendb/documents/session/misc.py | 4 +- ravendb/documents/smuggler/backup_utils.py | 25 +++++++ ...riodic_backup_file_extension_comparator.py | 20 ++++++ .../subscriptions/document_subscriptions.py | 9 +++ ravendb/primitives/constants.py | 13 ++++ .../test_caching_of_document_include.py | 18 +++++ .../client_tests/test_patch.py | 18 ++++- .../client_tests/test_query.py | 29 ++++++++ .../client_tests/test_smuggler.py | 25 +++++++ .../issues_tests/test_ravenDB_10638.py | 25 +++++++ .../issues_tests/test_ravenDB_11770.py | 53 +++++++++++++++ .../issues_tests/test_ravenDB_12932.py | 43 ++++++++++++ .../issues_tests/test_ravenDB_13682.py | 39 ++++++++++- .../issues_tests/test_ravenDB_14276.py | 67 +++++++++++++++++++ .../issues_tests/test_ravenDB_14724.py | 52 ++++++++++++++ .../mailing_list_tests/test_no_tracking.py | 47 +++++++++++++ .../spatial_tests/test_spatial_query.py | 17 ++++- 20 files changed, 502 insertions(+), 8 deletions(-) create mode 100644 ravendb/documents/smuggler/backup_utils.py create mode 100644 ravendb/documents/smuggler/periodic_backup_file_extension_comparator.py create mode 100644 ravendb/tests/jvm_migrated_tests/client_tests/test_smuggler.py create mode 100644 ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_10638.py create mode 100644 ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_11770.py create mode 100644 ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_12932.py create mode 100644 ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_14276.py create mode 100644 ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_14724.py create mode 100644 ravendb/tests/jvm_migrated_tests/mailing_list_tests/test_no_tracking.py diff --git a/ravendb/documents/commands/revisions.py b/ravendb/documents/commands/revisions.py index 7b9e9ded..b92fbf61 100644 --- a/ravendb/documents/commands/revisions.py +++ b/ravendb/documents/commands/revisions.py @@ -92,7 +92,7 @@ def get_request_query_string(self, path_builder: List[str]) -> None: path_builder.append(Utils.escape(change_vector)) if self._before is not None: - path_builder.append("&before") + path_builder.append("&before=") path_builder.append(Utils.datetime_to_string(self._before)) if self._start is not None: diff --git a/ravendb/documents/indexes/abstract_index_creation_tasks.py b/ravendb/documents/indexes/abstract_index_creation_tasks.py index 66acf7f6..137d11c7 100644 --- a/ravendb/documents/indexes/abstract_index_creation_tasks.py +++ b/ravendb/documents/indexes/abstract_index_creation_tasks.py @@ -268,7 +268,7 @@ def __set_suggestions(options: IndexFieldOptions, value: bool): return index_definition except Exception as e: - raise RuntimeError(f"Failed to create index {self._index_name}", e) # todo: IndexCompilationException + raise RuntimeError(f"Failed to create index {self._index_name}", e) # todo: IndexCompilationException class IndexDefinitionBuilder(AbstractIndexDefinitionBuilder[IndexDefinition]): diff --git a/ravendb/documents/session/document_session_operations/in_memory_document_session_operations.py b/ravendb/documents/session/document_session_operations/in_memory_document_session_operations.py index 3c212ca2..521d51d3 100644 --- a/ravendb/documents/session/document_session_operations/in_memory_document_session_operations.py +++ b/ravendb/documents/session/document_session_operations/in_memory_document_session_operations.py @@ -1887,7 +1887,7 @@ def with_timeout(self, timeout: datetime.timedelta) -> InMemoryDocumentSessionOp return self def throw_on_timeout(self, should_throw: bool) -> InMemoryDocumentSessionOperations.IndexesWaitOptsBuilder: - self.get_options().index_options.throw_on_timeout_in_wait_for_replicas = should_throw + self.get_options().index_options.throw_on_timeout_in_wait_for_indexes = should_throw return self def wait_for_indexes(self, *indexes: str) -> InMemoryDocumentSessionOperations.IndexesWaitOptsBuilder: diff --git a/ravendb/documents/session/misc.py b/ravendb/documents/session/misc.py index 4cf1327b..4a8b3bcf 100644 --- a/ravendb/documents/session/misc.py +++ b/ravendb/documents/session/misc.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: from ravendb.http.request_executor import RequestExecutor - from ravendb.documents.queries.misc import Query + from ravendb.documents.session.query import DocumentQuery from ravendb.documents.session.operations.query import QueryOperation from ravendb.documents.session.document_session_operations.in_memory_document_session_operations import ( InMemoryDocumentSessionOperations, @@ -153,7 +153,7 @@ def __init__( class DocumentQueryCustomization: - def __init__(self, query: Query): + def __init__(self, query: DocumentQuery): self.query = query self.query_operation: QueryOperation = None diff --git a/ravendb/documents/smuggler/backup_utils.py b/ravendb/documents/smuggler/backup_utils.py new file mode 100644 index 00000000..72c2eb80 --- /dev/null +++ b/ravendb/documents/smuggler/backup_utils.py @@ -0,0 +1,25 @@ +from pathlib import Path + +from ravendb.documents.smuggler.periodic_backup_file_extension_comparator import PeriodicBackupFileExtensionComparator + + +class BackupUtils: + + @staticmethod + def file_comparator(file1: Path, file2: Path) -> int: + base_name1 = file1.stem + base_name2 = file2.stem + + if base_name1 != base_name2: + return (base_name1 > base_name2) - (base_name1 < base_name2) + + ext1 = file1.suffix[1:] if file1.suffix.startswith('.') else file1.suffix + ext2 = file2.suffix[1:] if file2.suffix.startswith('.') else file2.suffix + + if ext1 != ext2: + return PeriodicBackupFileExtensionComparator.compare(file1, file2) + + last_modified1 = file1.stat().st_mtime + last_modified2 = file2.stat().st_mtime + + return (last_modified1 > last_modified2) - (last_modified1 < last_modified2) diff --git a/ravendb/documents/smuggler/periodic_backup_file_extension_comparator.py b/ravendb/documents/smuggler/periodic_backup_file_extension_comparator.py new file mode 100644 index 00000000..8f095dd8 --- /dev/null +++ b/ravendb/documents/smuggler/periodic_backup_file_extension_comparator.py @@ -0,0 +1,20 @@ +from pathlib import Path + +from ravendb.primitives.constants import PeriodicBackup + +class PeriodicBackupFileExtensionComparator: + + @staticmethod + def compare(file1: Path, file2: Path) -> int: + if file1.resolve() == file2.resolve(): + return 0 + + ext1 = file1.suffix[1:].lower() if file1.suffix.startswith('.') else file1.suffix.lower() + + if ext1 == PeriodicBackup.SNAPSHOT_EXTENSION: + return -1 + + if ext1 == PeriodicBackup.FULL_BACKUP_EXTENSION: + return -1 + + return 1 \ No newline at end of file diff --git a/ravendb/documents/subscriptions/document_subscriptions.py b/ravendb/documents/subscriptions/document_subscriptions.py index e18cdc70..21f53dda 100644 --- a/ravendb/documents/subscriptions/document_subscriptions.py +++ b/ravendb/documents/subscriptions/document_subscriptions.py @@ -73,6 +73,15 @@ def create_for_class( options = options or SubscriptionCreationOptions() return self.create_for_options(self.ensure_criteria(options, object_type, False), database) + def create_for_revisions( + self, + object_type: Type[_T], + options: Optional[SubscriptionCreationOptions] = None, + database: Optional[str] = None, + ) -> str: + options = options or SubscriptionCreationOptions() + return self.create_for_options(self.ensure_criteria(options, object_type, True), database) + def ensure_criteria(self, criteria: SubscriptionCreationOptions, object_type: Type[_T], revisions: bool): if criteria is None: criteria = SubscriptionCreationOptions() diff --git a/ravendb/primitives/constants.py b/ravendb/primitives/constants.py index 2c83a056..5d324eca 100644 --- a/ravendb/primitives/constants.py +++ b/ravendb/primitives/constants.py @@ -114,3 +114,16 @@ def configuration_to_method_name(source: VectorEmbeddingType, dest: VectorEmbedd DEFAULT_EMBEDDING_TYPE = VectorEmbeddingType.SINGLE DEFAULT_IS_EXACT = False + +class PeriodicBackup: + FULL_BACKUP_EXTENSION = "ravendb-full-backup" + SNAPSHOT_EXTENSION = "ravendb-snapshot" + ENCRYPTED_FULL_BACKUP_EXTENSION = ".ravendb-encrypted-full-backup" + ENCRYPTED_SNAPSHOT_EXTENSION = ".ravendb-encrypted-snapshot" + INCREMENTAL_BACKUP_EXTENSION = "ravendb-incremental-backup" + ENCRYPTED_INCREMENTAL_BACKUP_EXTENSION = ".ravendb-encrypted-incremental-backup" + + class Folders: + INDEXES = "Indexes" + DOCUMENTS = "Documents" + CONFIGURATION = "Configuration" diff --git a/ravendb/tests/jvm_migrated_tests/bugs_tests/caching_tests/test_caching_of_document_include.py b/ravendb/tests/jvm_migrated_tests/bugs_tests/caching_tests/test_caching_of_document_include.py index 83af7f21..7433646c 100644 --- a/ravendb/tests/jvm_migrated_tests/bugs_tests/caching_tests/test_caching_of_document_include.py +++ b/ravendb/tests/jvm_migrated_tests/bugs_tests/caching_tests/test_caching_of_document_include.py @@ -28,6 +28,24 @@ class CachingOfDocumentsIncludeTest(TestBase): def setUp(self): super().setUp() + def test_can_cache_document_with_includes(self): + with self.store.open_session() as session: + user = User(name="Ayende") + session.store(user) + + partner = User(partner_id="users/1-A") + session.store(partner) + + session.save_changes() + + with self.store.open_session() as session: + session.include("partnerId").load("users/2-A", User) + session.save_changes() + + with self.store.open_session() as session: + session.include("partnerId").load("users/2-A", User) + self.assertEqual(len(session.advanced.request_executor.cache), 1) + def test_can_avoid_using_server_for_load_with_include_if_everything_is_in_session_cacheLazy(self): with self.store.open_session() as session: user = User(name="Ayende") diff --git a/ravendb/tests/jvm_migrated_tests/client_tests/test_patch.py b/ravendb/tests/jvm_migrated_tests/client_tests/test_patch.py index 5afe00a5..83063fe1 100644 --- a/ravendb/tests/jvm_migrated_tests/client_tests/test_patch.py +++ b/ravendb/tests/jvm_migrated_tests/client_tests/test_patch.py @@ -1,4 +1,4 @@ -from ravendb import PatchByQueryOperation, PatchOperation, PatchRequest, PatchStatus +from ravendb import PatchByQueryOperation, PatchOperation, PatchRequest, PatchStatus, InMemoryDocumentSessionOperations from ravendb.infrastructure.entities import User from ravendb.tests.test_base import TestBase @@ -37,3 +37,19 @@ def test_can_patch_single_document(self): with self.store.open_session() as session: loaded_user = session.load("users/1", User) self.assertEqual("Patched", loaded_user.name) + + def test_can_wait_for_index_after_patch(self): + with self.store.open_session() as session: + user = User(name="RavenDB") + session.store(user, "users/1") + session.save_changes() + + def wait_for_indexes_options(options: InMemoryDocumentSessionOperations.IndexesWaitOptsBuilder): + options.wait_for_indexes("Users/ByName") + + with self.store.open_session() as session: + session.advanced.wait_for_indexes_after_save_changes(wait_for_indexes_options) + + user = session.load("users/1", User) + session.advanced.patch(user, "name", "New Name") + session.save_changes() diff --git a/ravendb/tests/jvm_migrated_tests/client_tests/test_query.py b/ravendb/tests/jvm_migrated_tests/client_tests/test_query.py index 58c4fdc4..a238ad46 100644 --- a/ravendb/tests/jvm_migrated_tests/client_tests/test_query.py +++ b/ravendb/tests/jvm_migrated_tests/client_tests/test_query.py @@ -1,5 +1,7 @@ from typing import Optional +from ravendb.documents.queries.misc import SearchOperator +from ravendb.documents.session.event_args import BeforeQueryEventArgs from ravendb.documents.indexes.abstract_index_creation_tasks import AbstractIndexCreationTask from ravendb.documents.session.query_group_by import GroupByField from ravendb.infrastructure.entities import User @@ -61,6 +63,33 @@ def __add_users(self): def setUp(self): super().setUp() + def test_query_create_clauses_for_query_dynamically_with_on_before_query_event(self): + with self.store.open_session() as session: + id1 = "users/1" + id2 = "users/2" + + article1 = Article("foo", "bar", False) + session.store(article1, id1) + + article2 = Article("foo", "bar", True) + session.store(article2, id2) + + session.save_changes() + + def on_before_query(event_args: BeforeQueryEventArgs): + query_to_be_executed = event_args.query_customization.query + query_to_be_executed.and_also() + query_to_be_executed.where_equals("deleted", True) + + with self.store.open_session() as session: + session.add_before_query(on_before_query) + + query = session.query(object_type=Article).search("title", "foo", SearchOperator.OR).search("description", "bar") + result = list(query) + + self.assertEqual("from 'Articles' where search(title, $p0) or search(description, $p1) and deleted = $p2", query._to_string()) + self.assertEqual(2, len(result)) + def test_query_create_clauses_for_query_dynamically_when_the_query_empty(self): with self.store.open_session() as session: id1 = "users/1" diff --git a/ravendb/tests/jvm_migrated_tests/client_tests/test_smuggler.py b/ravendb/tests/jvm_migrated_tests/client_tests/test_smuggler.py new file mode 100644 index 00000000..2fc7a1bd --- /dev/null +++ b/ravendb/tests/jvm_migrated_tests/client_tests/test_smuggler.py @@ -0,0 +1,25 @@ +import functools + +from ravendb.documents.smuggler.backup_utils import BackupUtils +from ravendb.tests.test_base import TestBase + +from pathlib import Path + + +class TestSmuggler(TestBase): + def setUp(self): + super(TestSmuggler, self).setUp() + + def test_can_sort_files(self): + files = [ + "2018-11-08-10-47.ravendb-incremental-backup", + "2018-11-08-10-46.ravendb-incremental-backup", + "2018-11-08-10-46.ravendb-full-backup" + ] + + mapped_files = [Path(file) for file in files] + sorted_files = sorted(mapped_files, key=functools.cmp_to_key(BackupUtils.file_comparator)) + + self.assertEqual("2018-11-08-10-46.ravendb-full-backup", sorted_files[0].name) + self.assertEqual("2018-11-08-10-46.ravendb-incremental-backup", sorted_files[1].name) + self.assertEqual("2018-11-08-10-47.ravendb-incremental-backup", sorted_files[2].name) \ No newline at end of file diff --git a/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_10638.py b/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_10638.py new file mode 100644 index 00000000..1a18c945 --- /dev/null +++ b/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_10638.py @@ -0,0 +1,25 @@ +from ravendb.documents.queries.query import QueryResult + +from ravendb.tests.test_base import TestBase, User + + +class TestRavenDB10638(TestBase): + def setUp(self): + super(TestRavenDB10638, self).setUp() + + def test_after_query_executed_should_be_executed_only_once(self): + with self.store.open_session() as session: + counter = 0 + + def on_after_query_executed(event_args: QueryResult): + nonlocal counter + counter += 1 + + results = list( + session.query(object_type=User) + .add_after_query_executed_listener(on_after_query_executed) + .where_equals("name", "Doe") + ) + + self.assertEqual(0, len(results)) + self.assertEqual(1, counter) \ No newline at end of file diff --git a/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_11770.py b/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_11770.py new file mode 100644 index 00000000..747d6818 --- /dev/null +++ b/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_11770.py @@ -0,0 +1,53 @@ +import datetime +import time + +from ravendb.tests.test_base import TestBase, Company + + +class TestRavenDB11770(TestBase): + def setUp(self): + super(TestRavenDB11770, self).setUp() + + def test_can_get_revisions_by_date(self): + print(self.store.identifier.split("(")[0]) + + with self.store.open_session() as session: + id = "users/1" + + self.setup_revisions(self.store, False, 1000) + + company = Company(name="Fitzchak") + session.store(company, id) + session.save_changes() + + time.sleep(2) + + fst = datetime.datetime.now(datetime.UTC) + + for i in range(3): + with self.store.open_session() as session: + user = session.load(id, object_type=Company) + user.name = f"Fitzchak {i}" + session.save_changes() + + time.sleep(2) + + snd = datetime.datetime.now(datetime.UTC) + + for i in range(3): + with self.store.open_session() as session: + user = session.load(id, object_type=Company) + user.name = f"Oren {i}" + session.save_changes() + + time.sleep(2) + + with self.store.open_session() as session: + rev1 = session.advanced.revisions.get_by_before_date(id, fst, object_type=Company) + self.assertEqual("Fitzchak", rev1.name) + + rev2 = session.advanced.revisions.get_by_before_date(id, snd, object_type=Company) + self.assertEqual("Fitzchak 2", rev2.name) + + rev3 = session.advanced.revisions.get_by_before_date(id, datetime.datetime.now(datetime.UTC), object_type=Company) + self.assertEqual("Oren 2", rev3.name) diff --git a/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_12932.py b/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_12932.py new file mode 100644 index 00000000..67065fc0 --- /dev/null +++ b/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_12932.py @@ -0,0 +1,43 @@ +from ravendb.documents.operations.indexes import GetIndexOperation + +from ravendb.documents.indexes.abstract_index_creation_tasks import AbstractIndexCreationTask + +from ravendb.tests.test_base import TestBase + + +class Orders_ProfitByProductAndOrderedAt(AbstractIndexCreationTask): + def __init__(self, references_collection_name: str): + super().__init__() + self.map = """docs.Orders.SelectMany(order => order.Lines, (order, line) => new { + Product = line.Product, + OrderedAt = order.OrderedAt, + Profit = (((decimal) line.Quantity) * line.PricePerUnit) * (1M - line.Discount) + })""" + + self.reduce = """results.GroupBy(r => new { + OrderedAt = r.OrderedAt, + Product = r.Product + }).Select(g => new { + Product = g.Key.Product, + OrderedAt = g.Key.OrderedAt, + Profit = Enumerable.Sum(g, r => ((decimal) r.Profit)) + })""" + + self._output_reduce_to_collection = "Profits" + self._pattern_for_output_reduce_to_collection_references = "reports/daily/{OrderedAt:yyyy-MM-dd}" + self._pattern_references_collection_name = references_collection_name + + +class TestRavenDB12932(TestBase): + def setUp(self): + super(TestRavenDB12932, self).setUp() + + def test_can_persist_pattern_for_output_reduce_to_collection_references(self): + index_to_create = Orders_ProfitByProductAndOrderedAt("CustomCollection") + index_to_create.execute(self.store) + + index_definition = self.store.maintenance.send(GetIndexOperation("Orders/ProfitByProductAndOrderedAt")) + + self.assertEqual(index_definition.output_reduce_to_collection, "Profits") + self.assertEqual(index_definition.pattern_for_output_reduce_to_collection_references, "reports/daily/{OrderedAt:yyyy-MM-dd}") + self.assertEqual(index_definition.pattern_references_collection_name, "CustomCollection") \ No newline at end of file diff --git a/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_13682.py b/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_13682.py index 80a791ef..77f4ae43 100644 --- a/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_13682.py +++ b/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_13682.py @@ -1,6 +1,10 @@ +from ravendb.documents.smuggler.common import DatabaseItemType + +from ravendb.infrastructure.operations import CreateSampleDataOperation + from ravendb.documents.indexes.abstract_index_creation_tasks import AbstractIndexCreationTask from ravendb.documents.queries.spatial import PointField -from ravendb.tests.test_base import TestBase +from ravendb.tests.test_base import TestBase, Order class Item: @@ -86,3 +90,36 @@ def test_can_query_by_rounded_spatial_ranges(self): self.assertEqual("c", result[0].name) self.assertEqual("a", result[1].name) self.assertEqual("b", result[2].name) + + def test_can_use_dynamic_query_order_by_spatial_with_alias(self): + self.store.maintenance.send(CreateSampleDataOperation({DatabaseItemType.DOCUMENTS, DatabaseItemType.INDEXES})) + + with self.store.open_session() as session: + d = session.advanced.raw_query( + "from Orders as a\n" + + "order by spatial.distance(\n" + + " spatial.point(a.ShipTo.Location.Latitude, a.ShipTo.Location.Longitude),\n" + + " spatial.point(35.2, -107.2 )\n" + + ")\n", + object_type=Order + ).first() + + metadata = session.advanced.get_metadata_for(d) + spatial = metadata["@spatial"] + + self.assertAlmostEqual(spatial["Distance"], 48.99, 2) + + def test_can_get_distance_from_spatial_query(self): + self.store.maintenance.send(CreateSampleDataOperation({DatabaseItemType.DOCUMENTS, DatabaseItemType.INDEXES})) + self.wait_for_indexing(self.store) + + with self.store.open_session() as session: + d = session.query_index("Orders/ByShipment/Location", object_type=Order) \ + .where_equals("id()", "orders/830-A") \ + .order_by_distance("ShipmentLocation", 35.2, -107.1) \ + .single() + + metadata = session.advanced.get_metadata_for(d) + spatial = metadata["@spatial"] + + self.assertAlmostEqual(spatial["Distance"], 40.1, 1) diff --git a/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_14276.py b/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_14276.py new file mode 100644 index 00000000..4a0e1ecf --- /dev/null +++ b/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_14276.py @@ -0,0 +1,67 @@ +from ravendb.documents.session.event_args import BeforeStoreEventArgs + +from ravendb.tests.test_base import TestBase, User + + +class TestRavenDB14276(TestBase): + def setUp(self): + super(TestRavenDB14276, self).setUp() + self.dictionary = {"123": {"aaaa": 1}, "321": {"bbbb": 2}} + + @staticmethod + def on_before_store(event_args: BeforeStoreEventArgs): + event_args.document_metadata["Some-MetadataEntry"] = "Updated" + + def verify_data(self, doc_id: str): + with self.store.open_session() as session: + user = session.load(doc_id, object_type=User) + self.assertEqual("Updated document", user.name) + + metadata = session.advanced.get_metadata_for(user) + dictionary = metadata["Custom-Metadata"] + + nested_dictionary = dictionary["123"] + self.assertEqual(1, nested_dictionary["aaaa"]) + + nested_dictionary = dictionary["321"] + self.assertEqual(2, nested_dictionary["bbbb"]) + + + def test_can_update_metadata_with_nested_dictionary(self): + doc_id = "users/1" + + with self.store.open_session() as session: + session.add_before_store(self.on_before_store) + + user = User("Some document") + session.store(user, doc_id) + + metadata = session.advanced.get_metadata_for(user) + metadata["Custom-Metadata"] = self.dictionary + session.save_changes() + + with self.store.open_session() as session: + user = session.load(doc_id, object_type=User) + user.name = "Updated document" + session.save_changes() + + self.verify_data(doc_id) + + def test_can_update_metadata_with_nested_dictionary_same_session(self): + doc_id = "users/1" + + with self.store.open_session() as session: + session.add_before_store(self.on_before_store) + + saved_user = User("Some document") + session.store(saved_user, doc_id) + + metadata = session.advanced.get_metadata_for(saved_user) + metadata["Custom-Metadata"] = self.dictionary + session.save_changes() + + user = session.load(doc_id, object_type=User) + user.name = "Updated document" + session.save_changes() + + self.verify_data(doc_id) diff --git a/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_14724.py b/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_14724.py new file mode 100644 index 00000000..98e1f1b1 --- /dev/null +++ b/ravendb/tests/jvm_migrated_tests/issues_tests/test_ravenDB_14724.py @@ -0,0 +1,52 @@ +from ravendb.documents.operations.revisions import RevisionsConfiguration, ConfigureRevisionsOperation + +from ravendb.tests.test_base import TestBase, User + +from ravendb.primitives.constants import Documents + + +class TestRavenDB14724(TestBase): + def setUp(self): + super(TestRavenDB14724, self).setUp() + + def test_delete_document_and_revisions(self): + user = User("Raven") + id = "user/1" + + self.setup_revisions(self.store, True, 5) + + with self.store.open_session() as session: + session.store(user, id) + session.save_changes() + + with self.store.open_session() as session: + user = session.load(id, object_type=User) + user.age = 10 + + session.store(user) + session.save_changes() + + metadata = session.advanced.get_metadata_for(user) + + self.assertEqual("HasRevisions", metadata[Documents.Metadata.FLAGS]) + + revisions = session.advanced.revisions.get_for(id, object_type=User) + self.assertEqual(2, len(revisions)) + + session.delete(id) + session.save_changes() + + configuration = RevisionsConfiguration() + operation = ConfigureRevisionsOperation(configuration) + self.store.maintenance.send(operation) + + with self.store.open_session() as session: + session.store(user, id) + session.save_changes() + + self.setup_revisions(self.store, True, 5) + + with self.store.open_session() as session: + user = session.load(id, object_type=User) + revisions = session.advanced.revisions.get_for(id, object_type=User) + self.assertEqual(0, len(revisions)) \ No newline at end of file diff --git a/ravendb/tests/jvm_migrated_tests/mailing_list_tests/test_no_tracking.py b/ravendb/tests/jvm_migrated_tests/mailing_list_tests/test_no_tracking.py new file mode 100644 index 00000000..fabb5b60 --- /dev/null +++ b/ravendb/tests/jvm_migrated_tests/mailing_list_tests/test_no_tracking.py @@ -0,0 +1,47 @@ +from typing import List + +from ravendb.documents.session.event_args import BeforeQueryEventArgs + +from ravendb.tests.test_base import TestBase + + +class AA: + def __init__(self, id: str, bs: List[str]): + self.id = id + self.bs = bs + + +class B: + def __init__(self, id: str): + self.id = id + + +class TestQuery(TestBase): + def setUp(self): + super().setUp() + + def create_data(self): + with self.store.open_session() as session: + a = AA("a/1", ["b/1"]) + b = B("b/1") + session.store(a) + session.store(b) + session.save_changes() + + def test_can_load_entities_with_no_tracking(self): + self.create_data() + + def on_before_query(event_args: BeforeQueryEventArgs): + query_to_be_executed = event_args.query_customization.query + query_to_be_executed.no_tracking() + + with self.store.open_session() as session: + session.add_before_query(on_before_query) + + result: List[AA] = list(session.query(object_type=AA).include("bs")) + + self.assertEqual(1, len(result)) + + result[0].bs.clear() + + self.assertFalse(session.advanced.has_changed(result[0])) diff --git a/ravendb/tests/jvm_migrated_tests/spatial_tests/test_spatial_query.py b/ravendb/tests/jvm_migrated_tests/spatial_tests/test_spatial_query.py index 282b60de..441b6262 100644 --- a/ravendb/tests/jvm_migrated_tests/spatial_tests/test_spatial_query.py +++ b/ravendb/tests/jvm_migrated_tests/spatial_tests/test_spatial_query.py @@ -1,8 +1,19 @@ -from ravendb import IndexDefinition, PutIndexesOperation +from ravendb import IndexDefinition, PutIndexesOperation, AbstractIndexCreationTask from ravendb.documents.indexes.spatial.configuration import SpatialUnits from ravendb.tests.test_base import TestBase +class SpatialQueriesInMemoryTestIdx(AbstractIndexCreationTask): + def __init__(self): + super().__init__() + self.map = """docs.Listings.Select(listingItem => new { + classCodes = listingItem.classCodes, + latitude = listingItem.latitude, + longitude = listingItem.longitude, + coordinates = this.CreateSpatialField(((double ? )((double)(listingItem.latitude))), ((double ? )((double)(listingItem.longitude)))) + })""" + + class DummyGeoDoc: def __init__(self, Id: str = None, latitude: float = None, longitude: float = None): self.Id = Id @@ -14,6 +25,10 @@ class TestSpatialQuery(TestBase): def setUp(self): super(TestSpatialQuery, self).setUp() + def test_can_run_spatial_queries_in_memory(self): + index = SpatialQueriesInMemoryTestIdx() + index.execute(self.store) + def test_can_successfully_query_by_miles(self): my_house = DummyGeoDoc(latitude=44.757767, longitude=-93.355322) # The gym is about 7.32 miles (11.79 kilometers) from my house.