diff options
Diffstat (limited to 'parts/django/tests/modeltests/proxy_models/tests.py')
-rw-r--r-- | parts/django/tests/modeltests/proxy_models/tests.py | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/parts/django/tests/modeltests/proxy_models/tests.py b/parts/django/tests/modeltests/proxy_models/tests.py new file mode 100644 index 0000000..346a2a3 --- /dev/null +++ b/parts/django/tests/modeltests/proxy_models/tests.py @@ -0,0 +1,314 @@ +from django.test import TestCase +from django.db import models, DEFAULT_DB_ALIAS +from django.db.models import signals +from django.core import management +from django.core.exceptions import FieldError + +from django.contrib.contenttypes.models import ContentType + +from models import MyPerson, Person, StatusPerson, LowerStatusPerson +from models import MyPersonProxy, Abstract, OtherPerson, User, UserProxy +from models import UserProxyProxy, Country, State, StateProxy, TrackerUser +from models import BaseUser, Bug, ProxyTrackerUser, Improvement, ProxyProxyBug +from models import ProxyBug, ProxyImprovement + +class ProxyModelTests(TestCase): + def test_same_manager_queries(self): + """ + The MyPerson model should be generating the same database queries as + the Person model (when the same manager is used in each case). + """ + my_person_sql = MyPerson.other.all().query.get_compiler( + DEFAULT_DB_ALIAS).as_sql() + person_sql = Person.objects.order_by("name").query.get_compiler( + DEFAULT_DB_ALIAS).as_sql() + self.assertEqual(my_person_sql, person_sql) + + def test_inheretance_new_table(self): + """ + The StatusPerson models should have its own table (it's using ORM-level + inheritance). + """ + sp_sql = StatusPerson.objects.all().query.get_compiler( + DEFAULT_DB_ALIAS).as_sql() + p_sql = Person.objects.all().query.get_compiler( + DEFAULT_DB_ALIAS).as_sql() + self.assertNotEqual(sp_sql, p_sql) + + def test_basic_proxy(self): + """ + Creating a Person makes them accessible through the MyPerson proxy. + """ + Person.objects.create(name="Foo McBar") + self.assertEqual(len(Person.objects.all()), 1) + self.assertEqual(len(MyPerson.objects.all()), 1) + self.assertEqual(MyPerson.objects.get(name="Foo McBar").id, 1) + self.assertFalse(MyPerson.objects.get(id=1).has_special_name()) + + def test_no_proxy(self): + """ + Person is not proxied by StatusPerson subclass. + """ + Person.objects.create(name="Foo McBar") + self.assertEqual(list(StatusPerson.objects.all()), []) + + def test_basic_proxy_reverse(self): + """ + A new MyPerson also shows up as a standard Person. + """ + MyPerson.objects.create(name="Bazza del Frob") + self.assertEqual(len(MyPerson.objects.all()), 1) + self.assertEqual(len(Person.objects.all()), 1) + + LowerStatusPerson.objects.create(status="low", name="homer") + lsps = [lsp.name for lsp in LowerStatusPerson.objects.all()] + self.assertEqual(lsps, ["homer"]) + + def test_correct_type_proxy_of_proxy(self): + """ + Correct type when querying a proxy of proxy + """ + Person.objects.create(name="Foo McBar") + MyPerson.objects.create(name="Bazza del Frob") + LowerStatusPerson.objects.create(status="low", name="homer") + pp = sorted([mpp.name for mpp in MyPersonProxy.objects.all()]) + self.assertEqual(pp, ['Bazza del Frob', 'Foo McBar', 'homer']) + + def test_proxy_included_in_ancestors(self): + """ + Proxy models are included in the ancestors for a model's DoesNotExist + and MultipleObjectsReturned + """ + Person.objects.create(name="Foo McBar") + MyPerson.objects.create(name="Bazza del Frob") + LowerStatusPerson.objects.create(status="low", name="homer") + max_id = Person.objects.aggregate(max_id=models.Max('id'))['max_id'] + + self.assertRaises(Person.DoesNotExist, + MyPersonProxy.objects.get, + name='Zathras' + ) + self.assertRaises(Person.MultipleObjectsReturned, + MyPersonProxy.objects.get, + id__lt=max_id+1 + ) + self.assertRaises(Person.DoesNotExist, + StatusPerson.objects.get, + name='Zathras' + ) + + sp1 = StatusPerson.objects.create(name='Bazza Jr.') + sp2 = StatusPerson.objects.create(name='Foo Jr.') + max_id = Person.objects.aggregate(max_id=models.Max('id'))['max_id'] + + self.assertRaises(Person.MultipleObjectsReturned, + StatusPerson.objects.get, + id__lt=max_id+1 + ) + + def test_abc(self): + """ + All base classes must be non-abstract + """ + def build_abc(): + class NoAbstract(Abstract): + class Meta: + proxy = True + self.assertRaises(TypeError, build_abc) + + def test_no_cbc(self): + """ + The proxy must actually have one concrete base class + """ + def build_no_cbc(): + class TooManyBases(Person, Abstract): + class Meta: + proxy = True + self.assertRaises(TypeError, build_no_cbc) + + def test_no_base_classes(self): + def build_no_base_classes(): + class NoBaseClasses(models.Model): + class Meta: + proxy = True + self.assertRaises(TypeError, build_no_base_classes) + + def test_new_fields(self): + def build_new_fields(): + class NoNewFields(Person): + newfield = models.BooleanField() + class Meta: + proxy = True + self.assertRaises(FieldError, build_new_fields) + + def test_myperson_manager(self): + Person.objects.create(name="fred") + Person.objects.create(name="wilma") + Person.objects.create(name="barney") + + resp = [p.name for p in MyPerson.objects.all()] + self.assertEqual(resp, ['barney', 'fred']) + + resp = [p.name for p in MyPerson._default_manager.all()] + self.assertEqual(resp, ['barney', 'fred']) + + def test_otherperson_manager(self): + Person.objects.create(name="fred") + Person.objects.create(name="wilma") + Person.objects.create(name="barney") + + resp = [p.name for p in OtherPerson.objects.all()] + self.assertEqual(resp, ['barney', 'wilma']) + + resp = [p.name for p in OtherPerson.excluder.all()] + self.assertEqual(resp, ['barney', 'fred']) + + resp = [p.name for p in OtherPerson._default_manager.all()] + self.assertEqual(resp, ['barney', 'wilma']) + + def test_proxy_model_signals(self): + """ + Test save signals for proxy models + """ + output = [] + + def make_handler(model, event): + def _handler(*args, **kwargs): + output.append('%s %s save' % (model, event)) + return _handler + + h1 = make_handler('MyPerson', 'pre') + h2 = make_handler('MyPerson', 'post') + h3 = make_handler('Person', 'pre') + h4 = make_handler('Person', 'post') + + signals.pre_save.connect(h1, sender=MyPerson) + signals.post_save.connect(h2, sender=MyPerson) + signals.pre_save.connect(h3, sender=Person) + signals.post_save.connect(h4, sender=Person) + + dino = MyPerson.objects.create(name=u"dino") + self.assertEqual(output, [ + 'MyPerson pre save', + 'MyPerson post save' + ]) + + output = [] + + h5 = make_handler('MyPersonProxy', 'pre') + h6 = make_handler('MyPersonProxy', 'post') + + signals.pre_save.connect(h5, sender=MyPersonProxy) + signals.post_save.connect(h6, sender=MyPersonProxy) + + dino = MyPersonProxy.objects.create(name=u"pebbles") + + self.assertEqual(output, [ + 'MyPersonProxy pre save', + 'MyPersonProxy post save' + ]) + + signals.pre_save.disconnect(h1, sender=MyPerson) + signals.post_save.disconnect(h2, sender=MyPerson) + signals.pre_save.disconnect(h3, sender=Person) + signals.post_save.disconnect(h4, sender=Person) + signals.pre_save.disconnect(h5, sender=MyPersonProxy) + signals.post_save.disconnect(h6, sender=MyPersonProxy) + + def test_content_type(self): + ctype = ContentType.objects.get_for_model + self.assertTrue(ctype(Person) is ctype(OtherPerson)) + + def test_user_userproxy_userproxyproxy(self): + User.objects.create(name='Bruce') + + resp = [u.name for u in User.objects.all()] + self.assertEqual(resp, ['Bruce']) + + resp = [u.name for u in UserProxy.objects.all()] + self.assertEqual(resp, ['Bruce']) + + resp = [u.name for u in UserProxyProxy.objects.all()] + self.assertEqual(resp, ['Bruce']) + + def test_proxy_delete(self): + """ + Proxy objects can be deleted + """ + User.objects.create(name='Bruce') + u2 = UserProxy.objects.create(name='George') + + resp = [u.name for u in UserProxy.objects.all()] + self.assertEqual(resp, ['Bruce', 'George']) + + u2.delete() + + resp = [u.name for u in UserProxy.objects.all()] + self.assertEqual(resp, ['Bruce']) + + def test_select_related(self): + """ + We can still use `select_related()` to include related models in our + querysets. + """ + country = Country.objects.create(name='Australia') + state = State.objects.create(name='New South Wales', country=country) + + resp = [s.name for s in State.objects.select_related()] + self.assertEqual(resp, ['New South Wales']) + + resp = [s.name for s in StateProxy.objects.select_related()] + self.assertEqual(resp, ['New South Wales']) + + self.assertEqual(StateProxy.objects.get(name='New South Wales').name, + 'New South Wales') + + resp = StateProxy.objects.select_related().get(name='New South Wales') + self.assertEqual(resp.name, 'New South Wales') + + def test_proxy_bug(self): + contributor = TrackerUser.objects.create(name='Contributor', + status='contrib') + someone = BaseUser.objects.create(name='Someone') + Bug.objects.create(summary='fix this', version='1.1beta', + assignee=contributor, reporter=someone) + pcontributor = ProxyTrackerUser.objects.create(name='OtherContributor', + status='proxy') + Improvement.objects.create(summary='improve that', version='1.1beta', + assignee=contributor, reporter=pcontributor, + associated_bug=ProxyProxyBug.objects.all()[0]) + + # Related field filter on proxy + resp = ProxyBug.objects.get(version__icontains='beta') + self.assertEqual(repr(resp), '<ProxyBug: ProxyBug:fix this>') + + # Select related + filter on proxy + resp = ProxyBug.objects.select_related().get(version__icontains='beta') + self.assertEqual(repr(resp), '<ProxyBug: ProxyBug:fix this>') + + # Proxy of proxy, select_related + filter + resp = ProxyProxyBug.objects.select_related().get( + version__icontains='beta' + ) + self.assertEqual(repr(resp), '<ProxyProxyBug: ProxyProxyBug:fix this>') + + # Select related + filter on a related proxy field + resp = ProxyImprovement.objects.select_related().get( + reporter__name__icontains='butor' + ) + self.assertEqual(repr(resp), + '<ProxyImprovement: ProxyImprovement:improve that>' + ) + + # Select related + filter on a related proxy of proxy field + resp = ProxyImprovement.objects.select_related().get( + associated_bug__summary__icontains='fix' + ) + self.assertEqual(repr(resp), + '<ProxyImprovement: ProxyImprovement:improve that>' + ) + + def test_proxy_load_from_fixture(self): + management.call_command('loaddata', 'mypeople.json', verbosity=0, commit=False) + p = MyPerson.objects.get(pk=100) + self.assertEqual(p.name, 'Elvis Presley') |