PageRenderTime 245ms CodeModel.GetById 91ms app.highlight 62ms RepoModel.GetById 89ms app.codeStats 0ms

/tests/modeltests/proxy_models/tests.py

https://code.google.com/p/mango-py/
Python | 314 lines | 295 code | 4 blank | 15 comment | 0 complexity | 8f9103d7fdef5c04017abfc80c106d6b MD5 | raw file
  1from django.test import TestCase
  2from django.db import models, DEFAULT_DB_ALIAS
  3from django.db.models import signals
  4from django.core import management
  5from django.core.exceptions import FieldError
  6
  7from django.contrib.contenttypes.models import ContentType
  8
  9from models import MyPerson, Person, StatusPerson, LowerStatusPerson
 10from models import MyPersonProxy, Abstract, OtherPerson, User, UserProxy
 11from models import UserProxyProxy, Country, State, StateProxy, TrackerUser
 12from models import BaseUser, Bug, ProxyTrackerUser, Improvement, ProxyProxyBug
 13from models import ProxyBug, ProxyImprovement
 14
 15class ProxyModelTests(TestCase):
 16    def test_same_manager_queries(self):
 17        """
 18        The MyPerson model should be generating the same database queries as
 19        the Person model (when the same manager is used in each case).
 20        """
 21        my_person_sql = MyPerson.other.all().query.get_compiler(
 22            DEFAULT_DB_ALIAS).as_sql()
 23        person_sql = Person.objects.order_by("name").query.get_compiler(
 24            DEFAULT_DB_ALIAS).as_sql()
 25        self.assertEqual(my_person_sql, person_sql)
 26
 27    def test_inheretance_new_table(self):
 28        """
 29        The StatusPerson models should have its own table (it's using ORM-level
 30        inheritance).
 31        """
 32        sp_sql = StatusPerson.objects.all().query.get_compiler(
 33            DEFAULT_DB_ALIAS).as_sql()
 34        p_sql = Person.objects.all().query.get_compiler(
 35            DEFAULT_DB_ALIAS).as_sql()
 36        self.assertNotEqual(sp_sql, p_sql)
 37
 38    def test_basic_proxy(self):
 39        """
 40        Creating a Person makes them accessible through the MyPerson proxy.
 41        """
 42        person = Person.objects.create(name="Foo McBar")
 43        self.assertEqual(len(Person.objects.all()), 1)
 44        self.assertEqual(len(MyPerson.objects.all()), 1)
 45        self.assertEqual(MyPerson.objects.get(name="Foo McBar").id, person.id)
 46        self.assertFalse(MyPerson.objects.get(id=person.id).has_special_name())
 47
 48    def test_no_proxy(self):
 49        """
 50        Person is not proxied by StatusPerson subclass.
 51        """
 52        Person.objects.create(name="Foo McBar")
 53        self.assertEqual(list(StatusPerson.objects.all()), [])
 54
 55    def test_basic_proxy_reverse(self):
 56        """
 57        A new MyPerson also shows up as a standard Person.
 58        """
 59        MyPerson.objects.create(name="Bazza del Frob")
 60        self.assertEqual(len(MyPerson.objects.all()), 1)
 61        self.assertEqual(len(Person.objects.all()), 1)
 62
 63        LowerStatusPerson.objects.create(status="low", name="homer")
 64        lsps = [lsp.name for lsp in LowerStatusPerson.objects.all()]
 65        self.assertEqual(lsps, ["homer"])
 66
 67    def test_correct_type_proxy_of_proxy(self):
 68        """
 69        Correct type when querying a proxy of proxy
 70        """
 71        Person.objects.create(name="Foo McBar")
 72        MyPerson.objects.create(name="Bazza del Frob")
 73        LowerStatusPerson.objects.create(status="low", name="homer")
 74        pp = sorted([mpp.name for mpp in MyPersonProxy.objects.all()])
 75        self.assertEqual(pp, ['Bazza del Frob', 'Foo McBar', 'homer'])
 76
 77    def test_proxy_included_in_ancestors(self):
 78        """
 79        Proxy models are included in the ancestors for a model's DoesNotExist
 80        and MultipleObjectsReturned
 81        """
 82        Person.objects.create(name="Foo McBar")
 83        MyPerson.objects.create(name="Bazza del Frob")
 84        LowerStatusPerson.objects.create(status="low", name="homer")
 85        max_id = Person.objects.aggregate(max_id=models.Max('id'))['max_id']
 86
 87        self.assertRaises(Person.DoesNotExist,
 88            MyPersonProxy.objects.get,
 89            name='Zathras'
 90        )
 91        self.assertRaises(Person.MultipleObjectsReturned,
 92            MyPersonProxy.objects.get,
 93            id__lt=max_id+1
 94        )
 95        self.assertRaises(Person.DoesNotExist,
 96            StatusPerson.objects.get,
 97            name='Zathras'
 98        )
 99
100        sp1 = StatusPerson.objects.create(name='Bazza Jr.')
101        sp2 = StatusPerson.objects.create(name='Foo Jr.')
102        max_id = Person.objects.aggregate(max_id=models.Max('id'))['max_id']
103
104        self.assertRaises(Person.MultipleObjectsReturned,
105            StatusPerson.objects.get,
106            id__lt=max_id+1
107        )
108
109    def test_abc(self):
110        """
111        All base classes must be non-abstract
112        """
113        def build_abc():
114            class NoAbstract(Abstract):
115                class Meta:
116                    proxy = True
117        self.assertRaises(TypeError, build_abc)
118
119    def test_no_cbc(self):
120        """
121        The proxy must actually have one concrete base class
122        """
123        def build_no_cbc():
124            class TooManyBases(Person, Abstract):
125                class Meta:
126                    proxy = True
127        self.assertRaises(TypeError, build_no_cbc)
128
129    def test_no_base_classes(self):
130        def build_no_base_classes():
131            class NoBaseClasses(models.Model):
132                class Meta:
133                    proxy = True
134        self.assertRaises(TypeError, build_no_base_classes)
135
136    def test_new_fields(self):
137        def build_new_fields():
138            class NoNewFields(Person):
139                newfield = models.BooleanField()
140                class Meta:
141                    proxy = True
142        self.assertRaises(FieldError, build_new_fields)
143
144    def test_myperson_manager(self):
145        Person.objects.create(name="fred")
146        Person.objects.create(name="wilma")
147        Person.objects.create(name="barney")
148
149        resp = [p.name for p in MyPerson.objects.all()]
150        self.assertEqual(resp, ['barney', 'fred'])
151
152        resp = [p.name for p in MyPerson._default_manager.all()]
153        self.assertEqual(resp, ['barney', 'fred'])
154
155    def test_otherperson_manager(self):
156        Person.objects.create(name="fred")
157        Person.objects.create(name="wilma")
158        Person.objects.create(name="barney")
159
160        resp = [p.name for p in OtherPerson.objects.all()]
161        self.assertEqual(resp, ['barney', 'wilma'])
162
163        resp = [p.name for p in OtherPerson.excluder.all()]
164        self.assertEqual(resp, ['barney', 'fred'])
165
166        resp = [p.name for p in OtherPerson._default_manager.all()]
167        self.assertEqual(resp, ['barney', 'wilma'])
168
169    def test_proxy_model_signals(self):
170        """
171        Test save signals for proxy models
172        """
173        output = []
174
175        def make_handler(model, event):
176            def _handler(*args, **kwargs):
177                output.append('%s %s save' % (model, event))
178            return _handler
179
180        h1 = make_handler('MyPerson', 'pre')
181        h2 = make_handler('MyPerson', 'post')
182        h3 = make_handler('Person', 'pre')
183        h4 = make_handler('Person', 'post')
184
185        signals.pre_save.connect(h1, sender=MyPerson)
186        signals.post_save.connect(h2, sender=MyPerson)
187        signals.pre_save.connect(h3, sender=Person)
188        signals.post_save.connect(h4, sender=Person)
189
190        dino = MyPerson.objects.create(name=u"dino")
191        self.assertEqual(output, [
192            'MyPerson pre save',
193            'MyPerson post save'
194        ])
195
196        output = []
197
198        h5 = make_handler('MyPersonProxy', 'pre')
199        h6 = make_handler('MyPersonProxy', 'post')
200
201        signals.pre_save.connect(h5, sender=MyPersonProxy)
202        signals.post_save.connect(h6, sender=MyPersonProxy)
203
204        dino = MyPersonProxy.objects.create(name=u"pebbles")
205
206        self.assertEqual(output, [
207            'MyPersonProxy pre save',
208            'MyPersonProxy post save'
209        ])
210
211        signals.pre_save.disconnect(h1, sender=MyPerson)
212        signals.post_save.disconnect(h2, sender=MyPerson)
213        signals.pre_save.disconnect(h3, sender=Person)
214        signals.post_save.disconnect(h4, sender=Person)
215        signals.pre_save.disconnect(h5, sender=MyPersonProxy)
216        signals.post_save.disconnect(h6, sender=MyPersonProxy)
217
218    def test_content_type(self):
219        ctype = ContentType.objects.get_for_model
220        self.assertTrue(ctype(Person) is ctype(OtherPerson))
221
222    def test_user_userproxy_userproxyproxy(self):
223        User.objects.create(name='Bruce')
224
225        resp = [u.name for u in User.objects.all()]
226        self.assertEqual(resp, ['Bruce'])
227
228        resp = [u.name for u in UserProxy.objects.all()]
229        self.assertEqual(resp, ['Bruce'])
230
231        resp = [u.name for u in UserProxyProxy.objects.all()]
232        self.assertEqual(resp, ['Bruce'])
233
234    def test_proxy_delete(self):
235        """
236        Proxy objects can be deleted
237        """
238        User.objects.create(name='Bruce')
239        u2 = UserProxy.objects.create(name='George')
240
241        resp = [u.name for u in UserProxy.objects.all()]
242        self.assertEqual(resp, ['Bruce', 'George'])
243
244        u2.delete()
245
246        resp = [u.name for u in UserProxy.objects.all()]
247        self.assertEqual(resp, ['Bruce'])
248
249    def test_select_related(self):
250        """
251        We can still use `select_related()` to include related models in our
252        querysets.
253        """
254        country = Country.objects.create(name='Australia')
255        state = State.objects.create(name='New South Wales', country=country)
256
257        resp = [s.name for s in State.objects.select_related()]
258        self.assertEqual(resp, ['New South Wales'])
259
260        resp = [s.name for s in StateProxy.objects.select_related()]
261        self.assertEqual(resp, ['New South Wales'])
262
263        self.assertEqual(StateProxy.objects.get(name='New South Wales').name,
264            'New South Wales')
265
266        resp = StateProxy.objects.select_related().get(name='New South Wales')
267        self.assertEqual(resp.name, 'New South Wales')
268
269    def test_proxy_bug(self):
270        contributor = TrackerUser.objects.create(name='Contributor',
271            status='contrib')
272        someone = BaseUser.objects.create(name='Someone')
273        Bug.objects.create(summary='fix this', version='1.1beta',
274            assignee=contributor, reporter=someone)
275        pcontributor = ProxyTrackerUser.objects.create(name='OtherContributor',
276            status='proxy')
277        Improvement.objects.create(summary='improve that', version='1.1beta',
278            assignee=contributor, reporter=pcontributor,
279            associated_bug=ProxyProxyBug.objects.all()[0])
280
281        # Related field filter on proxy
282        resp = ProxyBug.objects.get(version__icontains='beta')
283        self.assertEqual(repr(resp), '<ProxyBug: ProxyBug:fix this>')
284
285        # Select related + filter on proxy
286        resp = ProxyBug.objects.select_related().get(version__icontains='beta')
287        self.assertEqual(repr(resp), '<ProxyBug: ProxyBug:fix this>')
288
289        # Proxy of proxy, select_related + filter
290        resp = ProxyProxyBug.objects.select_related().get(
291            version__icontains='beta'
292        )
293        self.assertEqual(repr(resp), '<ProxyProxyBug: ProxyProxyBug:fix this>')
294
295        # Select related + filter on a related proxy field
296        resp = ProxyImprovement.objects.select_related().get(
297            reporter__name__icontains='butor'
298        )
299        self.assertEqual(repr(resp),
300            '<ProxyImprovement: ProxyImprovement:improve that>'
301        )
302
303        # Select related + filter on a related proxy of proxy field
304        resp = ProxyImprovement.objects.select_related().get(
305            associated_bug__summary__icontains='fix'
306        )
307        self.assertEqual(repr(resp),
308            '<ProxyImprovement: ProxyImprovement:improve that>'
309        )
310
311    def test_proxy_load_from_fixture(self):
312        management.call_command('loaddata', 'mypeople.json', verbosity=0, commit=False)
313        p = MyPerson.objects.get(pk=100)
314        self.assertEqual(p.name, 'Elvis Presley')