]> git.parisson.com Git - django-jqchat.git/commitdiff
Fix design error: the time when message were received was stored as an integer, so...
authorrichardbarran <richardbarran@8369a704-5b4a-11de-992f-fdd7e25b9163>
Mon, 17 May 2010 09:18:12 +0000 (09:18 +0000)
committerrichardbarran <richardbarran@8369a704-5b4a-11de-992f-fdd7e25b9163>
Mon, 17 May 2010 09:18:12 +0000 (09:18 +0000)
git-svn-id: http://django-jqchat.googlecode.com/svn/trunk@16 8369a704-5b4a-11de-992f-fdd7e25b9163

jqchat/models.py
jqchat/tests.py
jqchat/views.py

index 6ff4b676f9130b2feb8624c9aa9f2ffbe3d7f9a9..bc020cae022a5ba3e65b410c6997826477afb135 100644 (file)
@@ -57,10 +57,10 @@ class Room(models.Model):
     def save(self, **kw):
         # If description modified, update the timestamp field.
         if self._init_description != self.description:
-            self.description_modified = int(time.time())
+            self.description_modified = time.time()
         # if last_activity is null (i.e. we are creating the room) set it to now.
         if not self.last_activity:
-            self.last_activity = int(time.time())
+            self.last_activity = time.time()
         if not self.created:
             self.created = datetime.datetime.now()
         super(Room, self).save(**kw)
@@ -131,7 +131,7 @@ class Message(models.Model):
     - a unix timestamp.
     - a datetime timestamp.
     The reason: the unix timestamp is higher performance when sending data to the browser (easier
-    and faster to handle INTs instead of datetimes. The 'created' is used for displaying the date
+    and faster to handle numbers instead of datetimes. The 'created' is used for displaying the date
     of messages; I could calculate it from the unix timestamp, but I'm guessing that I will get
     higher performance by storing it in the database.
 
@@ -141,7 +141,7 @@ class Message(models.Model):
     room = models.ForeignKey(Room, help_text='This message was posted in a given chat room.')
     event = models.IntegerField(null=True, blank=True, choices=EVENT_CHOICES, help_text='An action performed in the room, either by a user or by the system (e.g. XYZ leaves room.')
     text = models.TextField(null=True, blank=True, help_text='A message, either typed in by a user or generated by the system.')
-    unix_timestamp = models.IntegerField(editable=False, help_text='Unix timestamp when this message was inserted into the database.')
+    unix_timestamp = models.FloatField(editable=False, help_text='Unix timestamp when this message was inserted into the database.')
     created = models.DateTimeField(editable=False)
 
     def __unicode__(self):
@@ -149,7 +149,7 @@ class Message(models.Model):
 
     def save(self, **kw):
         if not self.unix_timestamp:
-            self.unix_timestamp = int(time.time())
+            self.unix_timestamp = time.time()
             self.created = datetime.datetime.fromtimestamp(self.unix_timestamp)
         super(Message, self).save(**kw)
         self.room.last_activity = int(time.time())
index 479c8a36a330b9779209ab4c24707b965f90695a..1d54fe67bbf9d1e5fdcfba1800b4a7862c7ad187 100644 (file)
@@ -71,12 +71,12 @@ class AJAXGetTest(TestCase):
         # Should have a status of 1 (there are new messages).
         self.assert_(payload['status'] == 1, payload)
 
-        # The server returns the Unix time, this will be an integer > 0.
+        # The server returns the Unix time, this will be a number > 0.
         t = payload['time']
         try:
-            t = int(t)
+            t = float(t)
         except:
-            self.assert_(False, 'Time (%s) should be an integer.' % t)
+            self.assert_(False, 'Time (%s) should be a number.' % t)
 
         messages = payload['messages']
 
@@ -227,6 +227,74 @@ class AJAXPostTest(TestCase):
         self.assert_('&lt;script&gt;' in messages[-1]['text'])
         self.assert_('<script>' not in messages[-1]['text'])
 
+class BehaviourTest(TestCase):
+    """Check out how the chat window behaves in different scenarios."""
+
+    fixtures = ['test_jqchat.json']
+
+    def setUp(self):
+        self.client = Client()
+        self.client.login(username='mickey', password='test')
+
+        self.client2 = Client()
+        self.client2.login(username='donald', password='test')
+
+    def test_simultaneous_messages(self):
+        """Ensure that messages sent by different users at (virtually) the same time are picked up."""
+
+        response = self.client.post('/jqchat/room/1/ajax/', {'time': 0,
+                                                         'action': 'postmsg',
+                                                         'message': 'rhubarb'})
+        self.assert_(response.status_code == 200, response.status_code)
+
+        payload = simplejson.loads(response.content)
+        # Should have a status of 1 (there are new messages).
+        self.assert_(payload['status'] == 1, payload)
+
+        mickey_time = payload['time']
+        messages = payload['messages']
+
+        self.assert_(len(messages) == 5)
+        self.assert_('mickey' in messages[-1]['text'])
+        self.assert_('rhubarb' in messages[-1]['text'])
+
+        # Donald also sends a message, at virtually the same time.
+        response = self.client2.post('/jqchat/room/1/ajax/', {'time': 0,
+                                                         'action': 'postmsg',
+                                                         'message': 'crumble'})
+        self.assert_(response.status_code == 200, response.status_code)
+
+        payload = simplejson.loads(response.content)
+        # Should have a status of 1 (there are new messages).
+        self.assert_(payload['status'] == 1, payload)
+
+        messages = payload['messages']
+
+        # Will pick up the message by Mickey, as well as the one just posted by Donald.
+        self.assert_(len(messages) == 6, messages)
+        self.assert_('donald' in messages[-1]['text'])
+        self.assert_('crumble' in messages[-1]['text'])
+
+        # And the next to last message is the one by Mickey.
+        self.assert_('mickey' in messages[-2]['text'])
+        self.assert_('rhubarb' in messages[-2]['text'])
+
+        # Mickey immediately requests the latest messages (it could happen...).
+        # Note how the time is no longer 0 - it's whatever time was returned from the 
+        # last AJAX query.
+        response = self.client.get('/jqchat/room/1/ajax/', {'time': mickey_time})
+        self.assert_(response.status_code == 200, response.status_code)
+
+        payload = simplejson.loads(response.content)
+        # Should have a status of 1 (there are new messages).
+        self.assert_(payload['status'] == 1, payload)
+
+        messages = payload['messages']
+
+        # Since Mickey last checked, there has been one message posted by Donald.
+        self.assert_(len(messages) == 1, messages)
+        self.assert_('donald' in messages[-1]['text'])
+        self.assert_('crumble' in messages[-1]['text'])
 
 class EventTest(TestCase):
     """Create new events in the room."""
index 873297a076ac4663fdb248639d55655924873316..0f8a0bda57c6b2bf3c3147df8603ff5fbbefd291 100644 (file)
@@ -82,7 +82,7 @@ class Ajax(object):
         StatusCode = 0 # Default status code is 0 i.e. no new data.
         self.request = request
         try:
-            self.request_time = int(self.request.REQUEST['time'])
+            self.request_time = float(self.request.REQUEST['time'])
         except:
             return HttpResponseBadRequest("What's the time?")
         self.ThisRoom = Room.objects.get(id=id)
@@ -123,9 +123,9 @@ class Ajax(object):
         l = len(NewMessages)
         if l > JQCHAT_DISPLAY_COUNT:
             NewMessages = NewMessages[l-JQCHAT_DISPLAY_COUNT:]
-    
+            
         response =  render_to_response('jqchat/chat_payload.json',
-                                  {'current_unix_timestamp': int(time.time()),
+                                  {'current_unix_timestamp': time.time(),
                                    'NewMessages': NewMessages,
                                    'StatusCode': StatusCode,
                                    'NewDescription': NewDescription,