Parcourir la source

Move notifications into customer app

master
David Winterbottom il y a 13 ans
Parent
révision
3b4af0add0

+ 0
- 1
oscar/__init__.py Voir le fichier

@@ -36,7 +36,6 @@ OSCAR_CORE_APPS = [
36 36
     'oscar.apps.checkout',
37 37
     'oscar.apps.shipping',
38 38
     'oscar.apps.catalogue',
39
-    'oscar.apps.notifications',
40 39
     'oscar.apps.catalogue.reviews',
41 40
     'oscar.apps.basket',
42 41
     'oscar.apps.payment',

+ 41
- 0
oscar/apps/customer/abstract_models.py Voir le fichier

@@ -116,3 +116,44 @@ class AbstractCommunicationEventType(models.Model):
116 116
 
117 117
     def is_user_related(self):
118 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 Voir le fichier

@@ -2,7 +2,8 @@ from django.conf.urls import patterns, url
2 2
 from django.contrib.auth.decorators import login_required
3 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 7
 from oscar.core.application import Application
7 8
 
8 9
 

+ 6
- 1
oscar/apps/customer/models.py Voir le fichier

@@ -1,4 +1,5 @@
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 5
 class Email(AbstractEmail):
@@ -9,4 +10,8 @@ class CommunicationEventType(AbstractCommunicationEventType):
9 10
     pass
10 11
 
11 12
 
13
+class Notification(AbstractNotification):
14
+    pass
15
+
16
+
12 17
 from oscar.apps.customer.history_helpers import *

oscar/apps/notifications/__init__.py → oscar/apps/customer/notifications/__init__.py Voir le fichier


oscar/apps/notifications/context_processors.py → oscar/apps/customer/notifications/context_processors.py Voir le fichier

@@ -1,6 +1,6 @@
1 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 6
 def notifications(request):

oscar/apps/customer/services.py → oscar/apps/customer/notifications/services.py Voir le fichier

@@ -1,6 +1,6 @@
1 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 6
 def notify_user(user, msg, category=None):

oscar/apps/customer/notification_views.py → oscar/apps/customer/notifications/views.py Voir le fichier

@@ -9,7 +9,7 @@ from django.db.models import get_model
9 9
 
10 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 15
 class NotificationListView(generic.ListView):

+ 0
- 43
oscar/apps/notifications/abstract_models.py Voir le fichier

@@ -1,43 +0,0 @@
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 Voir le fichier

@@ -1,5 +0,0 @@
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 Voir le fichier

@@ -1,41 +0,0 @@
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 Voir le fichier

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

+ 1
- 1
sites/sandbox/settings.py Voir le fichier

@@ -108,7 +108,7 @@ TEMPLATE_CONTEXT_PROCESSORS = (
108 108
     'oscar.apps.promotions.context_processors.promotions',
109 109
     'oscar.apps.checkout.context_processors.checkout',
110 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 114
 MIDDLEWARE_CLASSES = (

+ 1
- 0
tests/config.py Voir le fichier

@@ -36,6 +36,7 @@ def configure(nose_args=None):
36 36
                 "django.core.context_processors.static",
37 37
                 "django.contrib.messages.context_processors.messages",
38 38
                 'oscar.apps.search.context_processors.search_form',
39
+                'oscar.apps.customer.notifications.context_processors.notifications',
39 40
                 'oscar.apps.promotions.context_processors.promotions',
40 41
                 'oscar.apps.checkout.context_processors.checkout',
41 42
                 ),

+ 17
- 0
tests/functional/customer/notification_tests.py Voir le fichier

@@ -0,0 +1,17 @@
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 Voir le fichier


tests/unit/customer_tests.py → tests/unit/customer/customer_tests.py Voir le fichier


tests/unit/notification_tests.py → tests/unit/customer/notification_tests.py Voir le fichier

@@ -2,7 +2,8 @@ from django.test import TestCase
2 2
 from django.contrib.auth.models import User
3 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 9
 class TestANewNotification(TestCase):
@@ -30,3 +31,19 @@ class TestANotification(TestCase):
30 31
     def test_can_be_archived(self):
31 32
         self.notification.archive()
32 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())

Chargement…
Annuler
Enregistrer