Permalink
Browse files

Feature: Added concept of threads and parent threads

  • Loading branch information...
Theo Cushion
Theo Cushion committed Mar 19, 2012
1 parent 9379535 commit 1139109b6231d94fb5c153daef05571dbfa6d4c2
@@ -29,15 +29,15 @@ describe("Message", function() {
var s = parseStanza("<message to='bob@bar.com' from='alice@bar.com'><body>hello there</body><thread>123</thread></message>");
var m = Frabjous.Store.find(klass, s.id());
- expect(m.get('thread')).toEqual('123');
+ expect(m.get('thread_id')).toEqual('123');
});
it("should record parent thread information", function(){
var s = parseStanza("<message to='bob@bar.com' from='alice@bar.com'><body>hello there</body><thread parent='ABC'>123</thread></message>");
var m = Frabjous.Store.find(klass, s.id());
- expect(m.get('thread')).toEqual('123');
- expect(m.get('parent_thread')).toEqual('ABC');
+ expect(m.get('thread_id')).toEqual('123');
+ expect(m.get('parent_thread_id')).toEqual('ABC');
});
it("should link to a contact", function(){
@@ -0,0 +1,49 @@
+describe("XEP-0201",function(){
+
+ var klass = Frabjous.Thread;
+
+ beforeEach(function(){
+ Frabjous.Store.init();
+ });
+
+ describe("when a message is received", function(){
+ it("should link to a thread if present", function(){
+ var s = parseStanza("<message from='juliet@example.com/balcony' to='romeo@example.net' type='chat'><body>Of that tongue's utterance, yet I know the sound:</body><thread>sadfasdf</thread></message>");
+ var m = Frabjous.Store.find(Frabjous.Message, s.id());
+
+ var t = Frabjous.Store.find(klass, 'sadfasdf');
+ expect(m.get('thread')).toEqualModel(t);
+ expect(t.get('messages')).toEqualModelArray([m]);
+ });
+
+ it("should link to a parent_thread if present", function(){
+ var s = parseStanza("<message to='romeo@example.net/orchard' from='juliet@example.com/balcony' id='asiwe8289ljfdalk' type='chat'><body>Art thou not Romeo, and a Montague?</body><thread parent='7edac73ab41e45c4aafa7b2d7b749080'>e0ffe42b28561960c6b12b944a092794b9683a38</thread></message>");
+ var m = Frabjous.Store.find(Frabjous.Message, s.id());
+
+ var t = Frabjous.Store.find(klass, 'e0ffe42b28561960c6b12b944a092794b9683a38');
+ var p = Frabjous.Store.find(klass, '7edac73ab41e45c4aafa7b2d7b749080');
+ expect(m.get('thread')).toEqualModel(t);
+ expect(m.get('parent_thread')).toEqualModel(p);
+
+ expect(t.get('messages')).toEqualModelArray([m]);
+
+ expect(p.get('messages')).toEqualModelArray([]);
+ expect(p.get('child_threads')).toEqualModelArray([t]);
+ });
+ });
+
+ describe("when multiple messages are received", function(){
+ it("messages should return them in the correct order" ,function(){
+ var s1 = parseStanza("<message from='juliet@example.com/balcony' to='romeo@example.net' type='chat'><body>Art thou not Romeo and a Montague?</body><thread>drawgyavOg</thread></message>");
+ var m1 = Frabjous.Store.find(Frabjous.Message,s1.id());
+
+ var s2 = parseStanza("<message from='romeo@example.net' to='juliet@example.com/balcony' type='chat'><body>Neither, fair saint, if either thee dislike</body><thread>drawgyavOg</thread></message>");
+ var m2 = Frabjous.Store.find(Frabjous.Message,s2.id());
+
+ var t = Frabjous.Store.find(klass, 'drawgyavOg');
+
+ expect(t.get('messages')).toEqualModelArray([m1,m2]);
+ });
+ });
+
+});
@@ -74,6 +74,18 @@ describe("XEP-0203", function() {
expect(c.get('messages')).toEqualModelArray([m2,m1]); // opposite order they were recieved in
});
+
+ it("when received out of order, the messages for a thread should be in the correct order", function(){
+ var s1 = parseStanza("<message from='romeo@montague.net/orchard' to='juliet@capulet.com'><body>And what love can do that dares love attempt; Therefore thy kinsmen are no let to me.</body><thread>1345345</thread></message>");
+ var m1 = Frabjous.Store.find(type, s1.id());
+
+ var s2 = parseStanza("<message from='romeo@montague.net/orchard' to='juliet@im.example.com'><body>With love's light wings did I o'er-perch these walls;For stony limits cannot hold love out,</body><thread>1345345</thread><delay xmlns='urn:xmpp:delay' from='capulet.com' stamp='2002-09-10T23:08:25Z'>Offline Storage</delay></message>");
+ var m2 = Frabjous.Store.find(type, s2.id());
+
+ var t = Frabjous.Store.find(Frabjous.Thread,'1345345');
+
+ expect(t.get('messages')).toEqualModelArray([m2,m1]); // opposite order they were recieved in
+ });
});
describe("when presence", function(){
View
@@ -3,31 +3,34 @@
//= require ./contact
Frabjous.Message = DS.Model.extend({
- from: DS.attr('jidString'),
- to: DS.attr('jidString'),
- type: DS.attr('string'),
- body: DS.attr('string'),
- subject: DS.attr('string'),
- thread: DS.attr('string'),
- parent_thread: DS.attr('string'),
- contact: DS.belongsTo('Frabjous.Contact'),
- didLoad: function(){
+ from: DS.attr('jidString'),
+ to: DS.attr('jidString'),
+ type: DS.attr('string'),
+ body: DS.attr('string'),
+ subject: DS.attr('string'),
+ thread_id: DS.attr('string'),
+ parent_thread_id: DS.attr('string'),
+ contact: DS.belongsTo('Frabjous.Contact'),
+ _load_contact: function(){
var contact;
- var type = Frabjous.Contact;
- var contact_id = this.get('from').toString();
- var contact_client_id = Frabjous.Store.clientIdForId(type, contact_id);
+ var type = Frabjous.Contact;
+ var id = this.get('from').toString();
+ var client_id = Frabjous.Store.clientIdForId(type, id);
- if( Ember.none(contact_client_id) ){
+ if( Ember.none(client_id) ){
// No contact exists, so create one
- Frabjous.Store.load(type,{jid: this.get('from'), _messages_sent:[this.get('id')]});
- contact = Frabjous.Store.find(type,contact_id);
+ Frabjous.Store.load(type,{jid: id, _messages_sent:[this.get('id')]});
+ contact = Frabjous.Store.find(type,id);
}else{
// Update contact
- contact = Frabjous.Store.find(type,contact_id);
+ contact = Frabjous.Store.find(type,id);
contact.get('_messages_sent').addObject(this);
}
this.set('contact',contact);
+ },
+ didLoad: function(){
+ this._load_contact();
}
});
@@ -48,8 +51,8 @@ Frabjous.Parser.register("Message", function(stanza){
parsed.subject = stanza.root().find('subject').text();
parsed.body = stanza.root().find('body').text();
- parsed.thread = stanza.root().find('thread').text();
- parsed.parent_thread = stanza.root().find('thread').attr('parent');
+ parsed.thread_id = stanza.root().find('thread').text();
+ parsed.parent_thread_id = stanza.root().find('thread').attr('parent');
parsed.frabjous_type = Frabjous.Message;
View
@@ -0,0 +1,55 @@
+//= require ./message
+
+Frabjous.Thread = DS.Model.extend({
+ child_threads: DS.hasMany('Frabjous.Thread'),
+ _messages: DS.hasMany('Frabjous.Message'),
+ messages: function(){ return this.get('_messages'); }.property('_messages'),
+});
+
+Frabjous.Message.reopen({
+ thread: DS.belongsTo('Frabjous.Thread'),
+ parent_thread: DS.belongsTo('Frabjous.Thread'),
+ _load_thread: function(){
+ var thread;
+ var type = Frabjous.Thread;
+ var id = this.get('thread_id');
+ var client_id = Frabjous.Store.clientIdForId(type,id);
+
+ if( Ember.none(client_id) ){
+ // Create
+ Frabjous.Store.load(type,{id: id, _messages:[this.get('id')]});
+ thread = Frabjous.Store.find(type,id);
+ }else{
+ // Update
+ thread = Frabjous.Store.find(type,id);
+ thread.get('_messages').addObject(this);
+ }
+ this.set('thread', thread);
+ },
+ _load_parent_thread: function(){
+ var thread;
+ var type = Frabjous.Thread;
+ var id = this.get('parent_thread_id');
+ var client_id = Frabjous.Store.clientIdForId(type, id);
+
+ if( Ember.none(client_id) ){
+ // Create
+ Frabjous.Store.load(type,{id: id, child_threads: [this.get('thread').get('id')]});
+ thread = Frabjous.Store.find(type,id);
+ }else{
+ // Update
+ thread = Frabjous.Store.find(type,id);
+ thread.get('child_threads').addObject(this.get('thread'));
+ }
+ this.set('parent_thread', thread);
+ },
+ didLoad: function(){
+ this._super();
+ if(!Ember.empty(this.get('thread_id'))){
+ this._load_thread();
+ if(!Ember.empty(this.get('parent_thread_id'))){
+ this._load_parent_thread();
+ }
+ }
+ }
+});
View
@@ -4,6 +4,7 @@
//= require ./message
//= require ./presence
//= require ./xep-0082
+//= require ./xep-0201
Frabjous.Delay = DS.Model.extend({
stamp: DS.attr('Xep0082dateString'),
@@ -43,6 +44,12 @@ Frabjous.Contact.reopen({
}.property('_messages_sent')
});
+Frabjous.Thread.reopen({
+ messages: function(){
+ return this.get('_messages').slice().sort(Frabjous.Delay.sort);
+ }.property('messages')
+});
+
Frabjous.Parser.register("XEP-0203", function(stanza){
if( stanza.is_message() || stanza.is_presence() ){
// At least have a message or presence, so add a created_at

0 comments on commit 1139109

Please sign in to comment.