зеркало из https://github.com/mozilla/kitsune.git
[bug 627781] Move object_id back into Watch and test for cascading deletes.
Also add missing migration (accidentally removed in previous commit).
This commit is contained in:
Родитель
ab3758b182
Коммит
b812a931a9
|
@ -2,6 +2,7 @@ import hashlib
|
|||
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes import generic
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from sumo.models import ModelBase, LocaleField
|
||||
|
@ -58,6 +59,8 @@ class Watch(ModelBase):
|
|||
|
||||
# Optional reference to a content type:
|
||||
content_type = models.ForeignKey(ContentType, null=True, blank=True)
|
||||
object_id = models.PositiveIntegerField(db_index=True, null=True)
|
||||
content_object = generic.GenericForeignKey('content_type', 'object_id')
|
||||
|
||||
user = models.ForeignKey(User, null=True, blank=True)
|
||||
|
||||
|
@ -81,3 +84,15 @@ class WatchFilter(ModelBase):
|
|||
# Either ints or hashes of enumerated strings. All we can't represent
|
||||
# easily with this schema is arbitrary (open-vocab) strings.
|
||||
value = models.IntegerField()
|
||||
|
||||
|
||||
class NotificationsMixin(models.Model):
|
||||
"""Mixin for notifications models that adds watches as a generic relation.
|
||||
|
||||
So we get cascading deletes for free, yay!
|
||||
|
||||
"""
|
||||
watches = generic.GenericRelation(Watch)
|
||||
|
||||
class Meta(object):
|
||||
abstract = True
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
from django.conf import settings
|
||||
from django.core.management import call_command
|
||||
from django.db.models import loading
|
||||
|
||||
from notifications.models import Watch, WatchFilter
|
||||
from sumo.tests import TestCase
|
||||
from users.tests import user
|
||||
|
||||
|
||||
|
@ -21,3 +26,34 @@ def watch_filter(save=False, **kwargs):
|
|||
if save:
|
||||
f.save()
|
||||
return f
|
||||
|
||||
|
||||
class ModelsTestCase(TestCase):
|
||||
"""Does some pre-setup and post-teardown work to create tables for any
|
||||
of your test models.
|
||||
|
||||
Simply subclass this and set self.apps to a tuple of *additional*
|
||||
installed apps. These will be added *after* the ones in
|
||||
settings.INSTALLED_APPS.
|
||||
|
||||
Based on http://stackoverflow.com/questions/502916#1827272
|
||||
|
||||
"""
|
||||
apps = []
|
||||
|
||||
def _pre_setup(self):
|
||||
# Add the models to the db.
|
||||
self._original_installed_apps = list(settings.INSTALLED_APPS)
|
||||
for app in self.apps:
|
||||
settings.INSTALLED_APPS.append(app)
|
||||
loading.cache.loaded = False
|
||||
call_command('syncdb', interactive=False, verbosity=0)
|
||||
# Call the original method that does the fixtures etc.
|
||||
super(ModelsTestCase, self)._pre_setup()
|
||||
|
||||
def _post_teardown(self):
|
||||
# Call the original method.
|
||||
super(ModelsTestCase, self)._post_teardown()
|
||||
# Restore the settings.
|
||||
settings.INSTALLED_APPS = self._original_installed_apps
|
||||
loading.cache.loaded = False
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
from django.db import models
|
||||
|
||||
from notifications.models import NotificationsMixin
|
||||
|
||||
|
||||
# TODO: figure out why placing the mixin *after* models.Model fails
|
||||
# See also http://code.djangoproject.com/ticket/10249
|
||||
class MockModel(NotificationsMixin, models.Model):
|
||||
pass
|
|
@ -4,7 +4,8 @@ from django.contrib.contenttypes.models import ContentType
|
|||
|
||||
from notifications.events import Event
|
||||
from notifications.models import Watch
|
||||
from notifications.tests import watch, watch_filter
|
||||
from notifications.tests import watch, watch_filter, ModelsTestCase
|
||||
from notifications.tests.models import MockModel
|
||||
from sumo.tests import TestCase
|
||||
from users.tests import user
|
||||
|
||||
|
@ -140,3 +141,21 @@ class TestNotification(TestCase):
|
|||
FilteredContentTypeEvent.notify('hi@there.com', color=3, flavor=4)
|
||||
assert not FilteredContentTypeEvent.is_notifying('hi@there.com',
|
||||
color=3)
|
||||
|
||||
|
||||
class TestCascadeDelete(ModelsTestCase):
|
||||
"""Cascading deletes on object_id + content_type."""
|
||||
apps = ['notifications.tests']
|
||||
|
||||
def test_mock_model(self):
|
||||
"""Deleting an instance of MockModel should delete watches.
|
||||
|
||||
Create instance of MockModel from notifications.tests.models, then
|
||||
delete it and watch the cascade go.
|
||||
|
||||
"""
|
||||
mock_m = MockModel.objects.create()
|
||||
watch(event_type=TYPE, email='hi@there.com', content_object=mock_m,
|
||||
save=True)
|
||||
MockModel.objects.all().delete()
|
||||
assert not Watch.objects.count(), 'Cascade delete failed.'
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
CREATE TABLE `notifications_watch` (
|
||||
`id` integer NOT NULL AUTO_INCREMENT,
|
||||
`event_type` varchar(30) binary NOT NULL,
|
||||
`content_type_id` integer DEFAULT NULL,
|
||||
`object_id` integer unsigned DEFAULT NULL,
|
||||
`user_id` integer DEFAULT NULL,
|
||||
`email` varchar(75) DEFAULT NULL,
|
||||
`secret` varchar(10) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `notifications_watch_2be07fce` (`event_type`),
|
||||
KEY `notifications_watch_e4470c6e` (`content_type_id`),
|
||||
KEY `notifications_watch_829e37fd` (`object_id`),
|
||||
KEY `notifications_watch_fbfc09f1` (`user_id`),
|
||||
KEY `notifications_watch_3904588a` (`email`),
|
||||
CONSTRAINT `content_type_id_refs_id_23da5933` FOREIGN KEY (`content_type_id`) REFERENCES `django_content_type` (`id`),
|
||||
CONSTRAINT `user_id_refs_id_2dc6eef1` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
CREATE TABLE `notifications_watchfilter` (
|
||||
`id` integer NOT NULL AUTO_INCREMENT,
|
||||
`watch_id` integer NOT NULL,
|
||||
`name` binary(20) NOT NULL,
|
||||
`value` integer NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `notifications_watchfilter_6e1bd094` (`watch_id`),
|
||||
KEY `notifications_watchfilter_52094d6e` (`name`),
|
||||
CONSTRAINT `watch_id_refs_id_444d6e79` FOREIGN KEY (`watch_id`) REFERENCES `notifications_watch` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
Загрузка…
Ссылка в новой задаче