Make sure new events can be added *without* a URL.
We need to be able to add events (so that we can start collecting data) before we have a date (which means we won't yet have a URL or slug). Check that this works, and if it doesn't, fix it.

diff --git a/workshops/models.py b/workshops/models.py
index 2a293076..8aaf5892 100644
--- a/workshops/models.py
+++ b/workshops/models.py
@@ -295,6 +295,11 @@ class Event(models.Model):
 
         raise ObjectDoesNotExist(ident)
 
+    def save(self, *args, **kwargs):
+        self.url = self.url or None
+        super(Event, self).save(*args, **kwargs)
+
+
 #------------------------------------------------------------
 
 class Role(models.Model):
diff --git a/workshops/test/test_event.py b/workshops/test/test_event.py
index ad839958..c0377221 100644
--- a/workshops/test/test_event.py
+++ b/workshops/test/test_event.py
@@ -3,7 +3,7 @@ import sys
 
 from django.test import TestCase
 from django.core.urlresolvers import reverse
-from ..models import Event, Site
+from ..models import Event, Site, Tag
 from .base import TestBase
 
 
@@ -115,6 +115,9 @@ class TestEventViews(TestBase):
         test_site = Site.objects.create(domain='example.com',
                                         fullname='Test Site')
 
+        # Create a test tag
+        test_tag = Tag.objects.create(name='Test Tag', details='For testing')
+
         # Create fifty new events
         for i in range(50):
             event_start = datetime.now()
@@ -190,6 +193,52 @@ class TestEventViews(TestBase):
         # This should be the first page
         assert view_events.number == 5
 
+    def test_add_minimal_event(self):
+        site = Site.objects.get(fullname='Test Site')
+        tag = Tag.objects.get(name='Test Tag')
+        response = self.client.post(
+            reverse('event_add'),
+            {
+                'published': False,
+                'site': site.id,
+                'tags': [tag.id],
+            })
+        if response.status_code == 302:
+            url = response['location']
+            event_id = int(url.rsplit('/', 1)[1])
+            event = Event.objects.get(id=event_id)
+            assert event.published is False, (
+                'New event has wrong published status: {} != {}'.format(
+                    event.published, False))
+            assert event.site == site, (
+                'New event has wrong site: {} != {}'.format(event.site, site))
+            tags = list(event.tags.all())
+            assert tags == [tag], (
+                'New event has wrong tags: {} != {}'.format(tags, [tag]))
+        else:
+            self._check_status_code_and_parse(response, 200)
+            assert False, 'expected 302 redirect after post'
+
+    def test_add_two_minimal_events(self):
+        site = Site.objects.get(fullname='Test Site')
+        tag = Tag.objects.get(name='Test Tag')
+        url = reverse('event_add')
+        data = {
+                'published': False,
+                'site': site.id,
+                'tags': [tag.id],
+            }
+        response = self.client.post(url, data)
+        assert response.status_code == 302, (
+            'expected 302 redirect after first post, got {}'.format(
+            response.status_code))
+        response = self.client.post(url, data)
+        if response.status_code != 302:
+            self._check_status_code_and_parse(response, 200)
+            assert response.status_code == 302, (
+                'expected 302 redirect after second post, got {}'.format(
+                    response.status_code))
+
 
 class TestEventNotes(TestBase):
     """Make sure notes once written are saved forever!"""
['workshops/models.py', 'workshops/test/test_event.py']