From dae9e662a57ed6c4e73a1aaa517b6d17a7bb9fcc Mon Sep 17 00:00:00 2001 From: Paul Uithol Date: Thu, 25 Jul 2013 14:30:20 +0200 Subject: [PATCH 1/4] Create test case for failing saves (wrong delta) with dbref=False --- tests/document/delta.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/tests/document/delta.py b/tests/document/delta.py index 3656d9e3..a5302f1a 100644 --- a/tests/document/delta.py +++ b/tests/document/delta.py @@ -313,17 +313,17 @@ class DeltaTest(unittest.TestCase): self.circular_reference_deltas_2(DynamicDocument, Document) self.circular_reference_deltas_2(DynamicDocument, DynamicDocument) - def circular_reference_deltas_2(self, DocClass1, DocClass2): + def circular_reference_deltas_2(self, DocClass1, DocClass2, dbref=True): class Person(DocClass1): name = StringField() - owns = ListField(ReferenceField('Organization')) - employer = ReferenceField('Organization') + owns = ListField(ReferenceField('Organization', dbref=dbref)) + employer = ReferenceField('Organization', dbref=dbref) class Organization(DocClass2): name = StringField() - owner = ReferenceField('Person') - employees = ListField(ReferenceField('Person')) + owner = ReferenceField('Person', dbref=dbref) + employees = ListField(ReferenceField('Person', dbref=dbref)) Person.drop_collection() Organization.drop_collection() @@ -355,6 +355,8 @@ class DeltaTest(unittest.TestCase): self.assertEqual(o.owner, p) self.assertEqual(e.employer, o) + return person, organization, employee + def test_delta_db_field(self): self.delta_db_field(Document) self.delta_db_field(DynamicDocument) @@ -686,6 +688,19 @@ class DeltaTest(unittest.TestCase): self.assertEqual(doc._get_changed_fields(), ['list_field']) self.assertEqual(doc._delta(), ({}, {'list_field': 1})) + def test_delta_with_dbref_true(self): + person, organization, employee = self.circular_reference_deltas_2(Document, Document, True) + employee.name = 'test' + changed = organization._get_changed_fields() + delta = organization._delta() + organization.save() + + def test_delta_with_dbref_false(self): + person, organization, employee = self.circular_reference_deltas_2(Document, Document, False) + employee.name = 'test' + changed = organization._get_changed_fields() + delta = organization._delta() + organization.save() if __name__ == '__main__': unittest.main() From 2ad5ffbda215f71f91261fa1cac3ebfaa978f904 Mon Sep 17 00:00:00 2001 From: Paul Uithol Date: Thu, 25 Jul 2013 14:51:09 +0200 Subject: [PATCH 2/4] Add asserts to `test_delta_with_dbref_*`, instead of relying on exceptions --- tests/document/delta.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tests/document/delta.py b/tests/document/delta.py index a5302f1a..fae65c94 100644 --- a/tests/document/delta.py +++ b/tests/document/delta.py @@ -691,15 +691,25 @@ class DeltaTest(unittest.TestCase): def test_delta_with_dbref_true(self): person, organization, employee = self.circular_reference_deltas_2(Document, Document, True) employee.name = 'test' - changed = organization._get_changed_fields() - delta = organization._delta() + + self.assertEqual(organization._get_changed_fields(), ['employees.0.name']) + + updates, removals = organization._delta() + self.assertEqual({}, removals) + self.assertIn('employees.0', updates) + organization.save() def test_delta_with_dbref_false(self): person, organization, employee = self.circular_reference_deltas_2(Document, Document, False) employee.name = 'test' - changed = organization._get_changed_fields() - delta = organization._delta() + + self.assertEqual(organization._get_changed_fields(), ['employees.0.name']) + + updates, removals = organization._delta() + self.assertEqual({}, removals) + self.assertIn('employees.0', updates) + organization.save() if __name__ == '__main__': From e27439be6adf4326177e7ff1530047c22a8e2831 Mon Sep 17 00:00:00 2001 From: Paul Uithol Date: Thu, 25 Jul 2013 14:52:03 +0200 Subject: [PATCH 3/4] Fix `BaseDocument._delta` when working with plain ObjectIds instead of DBRefs --- mongoengine/base/document.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index 536fc2f4..258b3f25 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -4,7 +4,7 @@ import numbers from functools import partial import pymongo -from bson import json_util +from bson import json_util, ObjectId from bson.dbref import DBRef from bson.son import SON @@ -454,7 +454,7 @@ class BaseDocument(object): d = doc new_path = [] for p in parts: - if isinstance(d, DBRef): + if isinstance(d, (ObjectId, DBRef)): break elif isinstance(d, list) and p.isdigit(): d = d[int(p)] From d143e50238c304c6aca9ce9142c59707c24e4572 Mon Sep 17 00:00:00 2001 From: Paul Uithol Date: Thu, 25 Jul 2013 15:34:58 +0200 Subject: [PATCH 4/4] Replace `assertIn` with an `assertTrue`; apparently missing in Python 2.6 --- tests/document/delta.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/document/delta.py b/tests/document/delta.py index fae65c94..c6efc028 100644 --- a/tests/document/delta.py +++ b/tests/document/delta.py @@ -696,7 +696,7 @@ class DeltaTest(unittest.TestCase): updates, removals = organization._delta() self.assertEqual({}, removals) - self.assertIn('employees.0', updates) + self.assertTrue('employees.0' in updates) organization.save() @@ -708,7 +708,7 @@ class DeltaTest(unittest.TestCase): updates, removals = organization._delta() self.assertEqual({}, removals) - self.assertIn('employees.0', updates) + self.assertTrue('employees.0' in updates) organization.save()