Browse Source

Move notifications into customer app

master
David Winterbottom 13 years ago
parent
commit
3b4af0add0

+ 0
- 1
oscar/__init__.py View File

36
     'oscar.apps.checkout',
36
     'oscar.apps.checkout',
37
     'oscar.apps.shipping',
37
     'oscar.apps.shipping',
38
     'oscar.apps.catalogue',
38
     'oscar.apps.catalogue',
39
-    'oscar.apps.notifications',
40
     'oscar.apps.catalogue.reviews',
39
     'oscar.apps.catalogue.reviews',
41
     'oscar.apps.basket',
40
     'oscar.apps.basket',
42
     'oscar.apps.payment',
41
     'oscar.apps.payment',

+ 41
- 0
oscar/apps/customer/abstract_models.py View File

116
 
116
 
117
     def is_user_related(self):
117
     def is_user_related(self):
118
         return self.category == self.USER_RELATED
118
         return self.category == self.USER_RELATED
119
+
120
+
121
+class AbstractNotification(models.Model):
122
+    recipient = models.ForeignKey('auth.User', related_name='notifications',
123
+                                  db_index=True)
124
+
125
+    # Not all notifications will have a sender.
126
+    sender = models.ForeignKey('auth.User', null=True)
127
+
128
+    # HTML is allowed in this field as it can contain links
129
+    subject = models.CharField(max_length=255)
130
+    body = models.TextField()
131
+
132
+    # Some projects may want to categorise their notifications.  You may want
133
+    # to use this field to show a different icons next to the notification.
134
+    category = models.CharField(max_length=255, null=True)
135
+
136
+    INBOX, ARCHIVE = 'Inbox', 'Archive'
137
+    choices = (
138
+        (INBOX, _(INBOX)),
139
+        (ARCHIVE, _(ARCHIVE)))
140
+    location = models.CharField(max_length=32, choices=choices,
141
+                                default=INBOX)
142
+
143
+    date_sent = models.DateTimeField(auto_now_add=True)
144
+    date_read = models.DateTimeField(null=True)
145
+
146
+    class Meta:
147
+        ordering = ('-date_sent',)
148
+        abstract = True
149
+
150
+    def __unicode__(self):
151
+        return self.subject
152
+
153
+    def archive(self):
154
+        self.location = self.ARCHIVE
155
+        self.save()
156
+
157
+    @property
158
+    def is_read(self):
159
+        return self.date_read is not None

+ 2
- 1
oscar/apps/customer/app.py View File

2
 from django.contrib.auth.decorators import login_required
2
 from django.contrib.auth.decorators import login_required
3
 from django.views import generic
3
 from django.views import generic
4
 
4
 
5
-from oscar.apps.customer import views, notification_views
5
+from oscar.apps.customer import views
6
+from oscar.apps.customer.notifications import views as notification_views
6
 from oscar.core.application import Application
7
 from oscar.core.application import Application
7
 
8
 
8
 
9
 

+ 6
- 1
oscar/apps/customer/models.py View File

1
-from oscar.apps.customer.abstract_models import AbstractEmail, AbstractCommunicationEventType
1
+from oscar.apps.customer.abstract_models import (
2
+    AbstractEmail, AbstractCommunicationEventType, AbstractNotification)
2
 
3
 
3
 
4
 
4
 class Email(AbstractEmail):
5
 class Email(AbstractEmail):
9
     pass
10
     pass
10
 
11
 
11
 
12
 
13
+class Notification(AbstractNotification):
14
+    pass
15
+
16
+
12
 from oscar.apps.customer.history_helpers import *
17
 from oscar.apps.customer.history_helpers import *

oscar/apps/notifications/__init__.py → oscar/apps/customer/notifications/__init__.py View File


oscar/apps/notifications/context_processors.py → oscar/apps/customer/notifications/context_processors.py View File

1
 from django.db.models import get_model
1
 from django.db.models import get_model
2
 
2
 
3
-Notification = get_model('notifications', 'Notification')
3
+Notification = get_model('customer', 'Notification')
4
 
4
 
5
 
5
 
6
 def notifications(request):
6
 def notifications(request):

oscar/apps/customer/services.py → oscar/apps/customer/notifications/services.py View File

1
 from django.db.models import get_model
1
 from django.db.models import get_model
2
 
2
 
3
-Notification = get_model('notifications', 'Notification')
3
+Notification = get_model('customer', 'Notification')
4
 
4
 
5
 
5
 
6
 def notify_user(user, msg, category=None):
6
 def notify_user(user, msg, category=None):

oscar/apps/customer/notification_views.py → oscar/apps/customer/notifications/views.py View File

9
 
9
 
10
 from oscar.views.generic import BulkEditMixin
10
 from oscar.views.generic import BulkEditMixin
11
 
11
 
12
-Notification = get_model('notifications', 'Notification')
12
+Notification = get_model('customer', 'Notification')
13
 
13
 
14
 
14
 
15
 class NotificationListView(generic.ListView):
15
 class NotificationListView(generic.ListView):

+ 0
- 43
oscar/apps/notifications/abstract_models.py View File

1
-from django.db import models
2
-from django.utils.translation import ugettext_lazy as _
3
-
4
-
5
-class AbstractNotification(models.Model):
6
-    recipient = models.ForeignKey('auth.User', related_name='notifications',
7
-                                  db_index=True)
8
-
9
-    # Not all notifications will have a sender.
10
-    sender = models.ForeignKey('auth.User', null=True)
11
-
12
-    # HTML is allowed in this field as it can contain links
13
-    subject = models.CharField(max_length=255)
14
-    body = models.TextField()
15
-
16
-    # Some projects may want to categorise their notifications.  You may want
17
-    # to use this field to show a different icons next to the notification.
18
-    category = models.CharField(max_length=255, null=True)
19
-
20
-    INBOX, ARCHIVE = 'Inbox', 'Archive'
21
-    choices = (
22
-        (INBOX, _(INBOX)),
23
-        (ARCHIVE, _(ARCHIVE)))
24
-    location = models.CharField(max_length=32, choices=choices,
25
-                                default=INBOX)
26
-
27
-    date_sent = models.DateTimeField(auto_now_add=True)
28
-    date_read = models.DateTimeField(null=True)
29
-
30
-    class Meta:
31
-        ordering = ('-date_sent',)
32
-        abstract = True
33
-
34
-    def __unicode__(self):
35
-        return self.subject
36
-
37
-    def archive(self):
38
-        self.location = self.ARCHIVE
39
-        self.save()
40
-
41
-    @property
42
-    def is_read(self):
43
-        return self.date_read is not None

+ 0
- 5
oscar/apps/notifications/models.py View File

1
-from oscar.apps.notifications import abstract_models
2
-
3
-
4
-class Notification(abstract_models.AbstractNotification):
5
-    pass

+ 0
- 41
oscar/apps/notifications/tmp.py View File

1
-from django.db import models
2
-from django.utils.translation import ugettext_lazy as _
3
-
4
-
5
-class Notification(models.Model):
6
-    sender = models.ForeignKey('auth.User', null=True)
7
-    recipient = models.ForeignKey('auth.User', related_name='notifications')
8
-
9
-    subject = models.CharField(max_length=255)
10
-    body = models.TextField()
11
-
12
-    # Some projects may want to categorise their notifications.  You may want
13
-    # to use this field to show a different icons next to the notification.
14
-    category = models.CharField(max_length=255, null=True)
15
-
16
-    INBOX, ARCHIVE = 'Inbox', 'Archive'
17
-    choices = (
18
-        (INBOX, _(INBOX)),
19
-        (ARCHIVE, _(ARCHIVE)))
20
-    location = models.CharField(max_length=32, choices=choices,
21
-                                default=INBOX)
22
-
23
-    date_sent = models.DateTimeField(auto_now_add=True)
24
-    date_read = models.DateTimeField(null=True)
25
-
26
-
27
-class StockReminder(models.Model):
28
-    user = models.ForeignKey('auth.User', related_name='stock_reminders')
29
-    # + other fields so anonymous users can get reminders too
30
-    product = models.ForeignKey('catalogue.Product')
31
-    UNCONFIRMED, ACTIVE, INACTIVE = ('unconfirmed', 'active', 'inactive')
32
-    STATUS_TYPES = (
33
-        (UNCONFIRMED, _('Not yet confirmed')),
34
-        (ACTIVE, _('Active')),
35
-        (INACTIVE, _('Inactive')),
36
-    )
37
-    status = models.CharField(max_length=20, choices=STATUS_TYPES,
38
-                              default=INACTIVE)
39
-
40
-    date_created = models.DateTimeField(auto_now_add=True)
41
-    date_notified = models.DateTimeField(null=True)

+ 1
- 1
sites/demo/settings.py View File

99
     'oscar.apps.search.context_processors.search_form',
99
     'oscar.apps.search.context_processors.search_form',
100
     'oscar.apps.promotions.context_processors.promotions',
100
     'oscar.apps.promotions.context_processors.promotions',
101
     'oscar.apps.checkout.context_processors.checkout',
101
     'oscar.apps.checkout.context_processors.checkout',
102
-    'oscar.apps.notifications.context_processors.notifications',
102
+    'oscar.apps.customer.notifications.context_processors.notifications',
103
     'oscar.core.context_processors.metadata',
103
     'oscar.core.context_processors.metadata',
104
 )
104
 )
105
 
105
 

+ 1
- 1
sites/sandbox/settings.py View File

108
     'oscar.apps.promotions.context_processors.promotions',
108
     'oscar.apps.promotions.context_processors.promotions',
109
     'oscar.apps.checkout.context_processors.checkout',
109
     'oscar.apps.checkout.context_processors.checkout',
110
     'oscar.core.context_processors.metadata',
110
     'oscar.core.context_processors.metadata',
111
-    'oscar.apps.notifications.context_processors.notifications',
111
+    'oscar.apps.customer.notifications.context_processors.notifications',
112
 )
112
 )
113
 
113
 
114
 MIDDLEWARE_CLASSES = (
114
 MIDDLEWARE_CLASSES = (

+ 1
- 0
tests/config.py View File

36
                 "django.core.context_processors.static",
36
                 "django.core.context_processors.static",
37
                 "django.contrib.messages.context_processors.messages",
37
                 "django.contrib.messages.context_processors.messages",
38
                 'oscar.apps.search.context_processors.search_form',
38
                 'oscar.apps.search.context_processors.search_form',
39
+                'oscar.apps.customer.notifications.context_processors.notifications',
39
                 'oscar.apps.promotions.context_processors.promotions',
40
                 'oscar.apps.promotions.context_processors.promotions',
40
                 'oscar.apps.checkout.context_processors.checkout',
41
                 'oscar.apps.checkout.context_processors.checkout',
41
                 ),
42
                 ),

+ 17
- 0
tests/functional/customer/notification_tests.py View File

1
+from django.contrib.auth.models import User
2
+from django_dynamic_fixture import G
3
+
4
+from oscar.test import WebTestCase
5
+from oscar.apps.customer.notifications import services
6
+
7
+
8
+class TestAUserWithUnreadNotifications(WebTestCase):
9
+
10
+    def setUp(self):
11
+        self.user = G(User)
12
+        services.notify_user(self.user, "Test message")
13
+
14
+    def test_can_see_them_in_page_header(self):
15
+        homepage = self.app.get('/', user=self.user)
16
+        self.assertTrue('num_unread_notifications' in homepage.context)
17
+        self.assertEqual(1, homepage.context['num_unread_notifications'])

+ 0
- 0
tests/unit/customer/__init__.py View File


tests/unit/customer_tests.py → tests/unit/customer/customer_tests.py View File


tests/unit/notification_tests.py → tests/unit/customer/notification_tests.py View File

2
 from django.contrib.auth.models import User
2
 from django.contrib.auth.models import User
3
 from django_dynamic_fixture import G
3
 from django_dynamic_fixture import G
4
 
4
 
5
-from oscar.apps.notifications.models import Notification
5
+from oscar.apps.customer.models import Notification
6
+from oscar.apps.customer.notifications import services
6
 
7
 
7
 
8
 
8
 class TestANewNotification(TestCase):
9
 class TestANewNotification(TestCase):
30
     def test_can_be_archived(self):
31
     def test_can_be_archived(self):
31
         self.notification.archive()
32
         self.notification.archive()
32
         self.assertEqual(Notification.ARCHIVE, self.notification.location)
33
         self.assertEqual(Notification.ARCHIVE, self.notification.location)
34
+
35
+
36
+class TestAServiceExistsTo(TestCase):
37
+
38
+    def test_notify_a_single_user(self):
39
+        user = G(User)
40
+        services.notify_user(user, "Hello you!")
41
+        self.assertEqual(1, Notification.objects.filter(
42
+            recipient=user).count())
43
+
44
+    def test_notify_a_set_of_users(self):
45
+        users = [G(User) for i in range(5)]
46
+        services.notify_users(User.objects.all(), "Hello everybody!")
47
+        for user in users:
48
+            self.assertEqual(1, Notification.objects.filter(
49
+                recipient=user).count())

Loading…
Cancel
Save