Repository: django-oscar/django-oscar

Issue:
Hurry mode for customer alerts is never True
[The code](https://github.com/django-oscar/django-oscar/blob/62014cf6e36f5e1e612adc47dcbd7f859db3be4b/src/oscar/apps/customer/alerts/utils.py#L68-L77) to determine if hurry mode is set for a customer alert is checking that the number of active alerts are _less_ than the total number of items in stock for a product. 

```
if num_stockrecords == 1:
    num_in_stock = stockrecords[0].num_in_stock
    # hurry_mode is false if num_in_stock is None
    hurry_mode = num_in_stock is not None and num_alerts < num_in_stock
else:
    result = stockrecords.aggregate(max_in_stock=Max('num_in_stock'))
    hurry_mode = result['max_in_stock'] is not None and \
        num_alerts < result['max_in_stock']
```

I think it should be the reverse - check if the number of active alerts for a product are _greater_ than the number in stock. I'll submit a pull request to fix this.



Discussion:

Resolving patch:
diff --git a/src/oscar/apps/customer/alerts/utils.py b/src/oscar/apps/customer/alerts/utils.py
--- a/src/oscar/apps/customer/alerts/utils.py
+++ b/src/oscar/apps/customer/alerts/utils.py
@@ -66,15 +66,14 @@ def send_product_alerts(product):
     )
 
     # Determine 'hurry mode'
-    num_alerts = alerts.count()
     if num_stockrecords == 1:
         num_in_stock = stockrecords[0].num_in_stock
-        # hurry_mode is false if num_in_stock is None
-        hurry_mode = num_in_stock is not None and num_alerts < num_in_stock
     else:
         result = stockrecords.aggregate(max_in_stock=Max('num_in_stock'))
-        hurry_mode = result['max_in_stock'] is not None and \
-            num_alerts < result['max_in_stock']
+        num_in_stock = result['max_in_stock']
+
+    # hurry_mode is false if num_in_stock is None
+    hurry_mode = num_in_stock is not None and alerts.count() > num_in_stock
 
     # Load templates
     message_tpl = loader.get_template('customer/alerts/message.html')


Test patch:
diff --git a/tests/functional/customer/test_alert.py b/tests/functional/customer/test_alert.py
--- a/tests/functional/customer/test_alert.py
+++ b/tests/functional/customer/test_alert.py
@@ -1,7 +1,9 @@
 from django_webtest import WebTest
 from django.core.urlresolvers import reverse
 from django.core import mail
+from django.test import TestCase
 
+from oscar.apps.customer.alerts.utils import send_product_alerts
 from oscar.apps.customer.models import ProductAlert
 from oscar.test.factories import create_product, create_stockrecord
 from oscar.test.factories import UserFactory
@@ -78,3 +80,56 @@ def test_can_create_a_stock_alert(self):
         alert = alerts[0]
         self.assertEqual(ProductAlert.UNCONFIRMED, alert.status)
         self.assertEqual(alert.product, product)
+
+
+class TestHurryMode(TestCase):
+
+    def setUp(self):
+        self.user = UserFactory()
+        self.product = create_product()
+
+    def test_hurry_mode_not_set_when_stock_high(self):
+        # One alert, 5 items in stock. No need to hurry.
+        create_stockrecord(self.product, num_in_stock=5)
+        ProductAlert.objects.create(user=self.user, product=self.product)
+
+        send_product_alerts(self.product)
+
+        self.assertEqual(1, len(mail.outbox))
+        self.assertNotIn('Beware that the amount of items in stock is limited',
+            mail.outbox[0].body)
+
+    def test_hurry_mode_set_when_stock_low(self):
+        # Two alerts, 1 item in stock. Hurry mode should be set.
+        create_stockrecord(self.product, num_in_stock=1)
+        ProductAlert.objects.create(user=self.user, product=self.product)
+        ProductAlert.objects.create(user=UserFactory(), product=self.product)
+
+        send_product_alerts(self.product)
+
+        self.assertEqual(2, len(mail.outbox))
+        self.assertIn('Beware that the amount of items in stock is limited',
+            mail.outbox[0].body)
+
+    def test_hurry_mode_not_set_multiple_stockrecords(self):
+        # Two stockrecords, 5 items in stock for one. No need to hurry.
+        create_stockrecord(self.product, num_in_stock=1)
+        create_stockrecord(self.product, num_in_stock=5)
+        ProductAlert.objects.create(user=self.user, product=self.product)
+
+        send_product_alerts(self.product)
+
+        self.assertNotIn('Beware that the amount of items in stock is limited',
+            mail.outbox[0].body)
+
+    def test_hurry_mode_set_multiple_stockrecords(self):
+        # Two stockrecords, low stock on both. Hurry mode should be set.
+        create_stockrecord(self.product, num_in_stock=1)
+        create_stockrecord(self.product, num_in_stock=1)
+        ProductAlert.objects.create(user=self.user, product=self.product)
+        ProductAlert.objects.create(user=UserFactory(), product=self.product)
+
+        send_product_alerts(self.product)
+
+        self.assertIn('Beware that the amount of items in stock is limited',
+            mail.outbox[0].body)