Commits

Rajeesh Nair committed 4ac1b7a

Django-monitor: Fixed #3

* Issue #3 was about django_monitor not respecting the presence of custom
model_admin.queryset methods. Added tests for it and fixed the same.
Refer issues section in bitbucker repo for details.

  • Participants
  • Parent commits 18583f6

Comments (0)

Files changed (5)

 Through the changesets from 18 to 28, we have introduced the following changes
 to Django-monitor.
 
+* BUGFIX: Fixed issues upto #3.
+
 * This app is now available over python applications index, pypi.python.org.
 
 * BUGFIX: ``setup.py`` was not working as expected. Fixed.

File django_monitor/admin.py

         The 'change list' admin view is overridden to return a page showing the
         moderation summary aggregated for each model.
         """
-        query_set = self.queryset(request)
         model_list = []
         for model in queued_models():
-            c_type = ContentType.objects.get_for_model(model)
-            q_set = query_set.filter(content_type = c_type)
-            ip_count = q_set.filter(status = PENDING_STATUS).count()
-            ch_count = q_set.filter(status = CHALLENGED_STATUS).count() 
+            # I do not like to access private objects. No other option here!
+            # Get only those objects developer wish to let user see..
+            try:
+                model_admin = self.admin_site._registry[model]
+            except KeyError:
+                # This may happen at test-time. There the ``queued_models``
+                # come from the project where the test is actually being run
+                # but the admin_site registry knows only those models in
+                # ``django_monitor.tests.apps.testapp.models``.
+                continue
+
+            ip_count = model_admin.queryset(request).pending().count()
+            ch_count = model_admin.queryset(request).challenged().count()
+
             app_label = model._meta.app_label
             if ip_count or ch_count:
                 model_list.append({

File django_monitor/tests/apps/testapp/admin.py

 from django.contrib import admin
 
 from django_monitor.tests.apps.testapp.models import (
-    Author, Book, EBook, Supplement, Publisher
+    Author, Book, EBook, Supplement, Publisher, Reader
 )
 from django_monitor.admin import MonitorAdmin
 
     """ Model not monitored. Use the built-in admin"""
     pass
 
+class ReaderAdmin(MonitorAdmin):
+    """ To test the custom queryset """
+
+    def queryset(self, request):
+        """ Returns the reader that corresponds to user"""
+        qset = super(ReaderAdmin, self).queryset(request)
+        return qset.filter(user = request.user)
+
 admin.site.register(Author, AuthorAdmin)
 admin.site.register(Book, BookAdmin)
 admin.site.register(EBook, EBookAdmin)
 admin.site.register(Publisher, PubAdmin)
+admin.site.register(Reader, ReaderAdmin)
 

File django_monitor/tests/apps/testapp/models.py

 from django.db import models
 from django.contrib import admin
+from django.contrib.auth.models import User
+
 import django_monitor
 
 class Author(models.Model):
 
 django_monitor.nq(Supplement)
 
+class Reader(models.Model):
+    """ To test an issue with custom querysets. See admin & tests """
+    name = models.CharField(max_length = 100)
+    user = models.ForeignKey(User)
+
+django_monitor.nq(Reader)
+

File django_monitor/tests/apps/testapp/tests.py

 from django_monitor.conf import (
     PENDING_STATUS, CHALLENGED_STATUS, APPROVED_STATUS
 )
+from django_monitor.models import MonitorEntry
 from django_monitor.tests.utils.testsettingsmanager import SettingsTestCase
 from django_monitor.tests.apps.testapp.models import (
-    Author, Book, EBook, Supplement, Publisher
+    Author, Book, EBook, Supplement, Publisher, Reader
 )
 
 def get_perm(Model, perm):
         mod_ebk_perm = get_perm(EBook, 'moderate_ebook')
         add_sup_perm = get_perm(Supplement, 'add_supplement')
         mod_sup_perm = get_perm(Supplement, 'moderate_supplement')
+        ch_reader_perm = get_perm(Reader, 'change_reader')
+        ch_me_perm = get_perm(MonitorEntry, 'change_monitorentry')
 
         self.adder = User.objects.create_user(
             username = 'adder', email = 'adder@monitor.com',
             password = 'adder'
         )
         self.adder.user_permissions = [
-            add_auth_perm, add_bk_perm, add_ebk_perm, add_sup_perm, ch_auth_perm
+            add_auth_perm, add_bk_perm, add_ebk_perm, add_sup_perm,
+            ch_auth_perm, ch_reader_perm, ch_me_perm
         ]
         self.adder.is_staff = True
         self.adder.save()
         self.moderator.user_permissions = [
             add_auth_perm, add_bk_perm, add_ebk_perm, add_sup_perm,
             mod_auth_perm, mod_bk_perm, mod_ebk_perm, mod_sup_perm,
-            ch_auth_perm, ch_bk_perm, ch_ebk_perm
+            ch_auth_perm, ch_bk_perm, ch_ebk_perm, ch_reader_perm, ch_me_perm
         ]
         self.moderator.is_staff = True
         self.moderator.save()
         auth1 = Author.objects.get(pk=1)
         self.assertEquals(auth1.signal_emitted, True)
 
+    def test_7_moderation_queue_count(self):
+        """
+        moderation queue counts all pending or challenged objects of each
+        monitored model and displays those counts in the changelist. The
+        developer may have written some of the model_admins in a way that a
+        user is able to view only a subset of all objects. eg, only those
+        objects the user has created herself. Our queue should respect such
+        customizations. So the counts must be prepared only after consulting
+        the model_admin.queryset.
+        """
+        reader1 = Reader.objects.create(name = 'r1', user = self.adder)
+        reader2 = Reader.objects.create(name = 'r2', user = self.adder)
+        reader3 = Reader.objects.create(name = 'r3', user = self.moderator)
+        reader4 = Reader.objects.create(name = 'r4', user = self.moderator)
+        reader5 = Reader.objects.create(name = 'r5', user = self.moderator)
+        # User 1, adder logs in
+        logged_in = self.client.login(username = 'adder', password = 'adder')
+        self.assertEquals(logged_in, True)
+        # model_admin allows user to view just 2 objects that belong to her.
+        response = self.client.get('/admin/testapp/reader/', follow = True)
+        self.assertEquals(response.status_code, 200)
+        result_count = len(response.context[-1]['cl'].result_list)
+        self.assertEquals(result_count, 2)
+        # Now is the time to test monitor_queue. Same result expected.
+        response = self.client.get(
+            '/admin/django_monitor/monitorentry/', follow = True
+        )
+        self.assertEquals(response.status_code, 200)
+        queued_reader = filter(
+            lambda x: x['model_name'] == 'reader',
+            response.context[-1]['model_list']
+        )[0]
+        self.assertEquals(queued_reader['pending'], 2)
+        self.assertEquals(queued_reader['challenged'], 0)
+        self.client.logout()
+
+        # User 2, moderator, repeats the same.
+        logged_in = self.client.login(username = 'moder', password = 'moder')
+        self.assertEquals(logged_in, True)
+        response = self.client.get(
+            '/admin/django_monitor/monitorentry/', follow = True
+        )
+        self.assertEquals(response.status_code, 200)
+        queued_reader = filter(
+            lambda x: x['model_name'] == 'reader',
+            response.context[-1]['model_list']
+        )[0]
+        self.assertEquals(queued_reader['pending'], 3)
+        self.assertEquals(queued_reader['challenged'], 0)
+        self.client.logout()