mailboxer 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Mailboxer 0.8.x [![](https://secure.travis-ci.org/ging/mailboxer.png)](http://travis-ci.org/ging/mailboxer) [![](https://gemnasium.com/ging/mailboxer.png)](https://gemnasium.com/ging/mailboxer)
1
+ # Mailboxer 0.9.x [![](https://secure.travis-ci.org/ging/mailboxer.png)](http://travis-ci.org/ging/mailboxer) [![](https://gemnasium.com/ging/mailboxer.png)](https://gemnasium.com/ging/mailboxer)
2
2
 
3
3
  This project is based on the need of a private message system for [ging
4
4
  / social\_stream](https://github.com/ging/social_stream). Instead of creating our core message system heavily
@@ -6,7 +6,7 @@ class Receipt < ActiveRecord::Base
6
6
  validates_presence_of :receiver
7
7
 
8
8
  scope :recipient, lambda { |recipient|
9
- where(:receiver_id => recipient.id,:receiver_type => recipient.class.to_s)
9
+ where(:receiver_id => recipient.id,:receiver_type => recipient.class.base_class.to_s)
10
10
  }
11
11
  #Notifications Scope checks type to be nil, not Notification because of STI behaviour
12
12
  #with the primary class (no type is saved)
@@ -2,8 +2,8 @@ class AddAttachments < ActiveRecord::Migration
2
2
  def self.up
3
3
  add_column :notifications, :attachment, :string
4
4
  end
5
-
5
+
6
6
  def self.down
7
- remove_column :notifications, :attachment, :string
7
+ remove_column :notifications, :attachment
8
8
  end
9
9
  end
@@ -12,182 +12,186 @@ module Mailboxer
12
12
  has_many :messages, :as => :sender
13
13
  has_many :receipts, :order => 'created_at DESC', :dependent => :destroy, :as => :receiver
14
14
 
15
- include Mailboxer::Models::Messageable::InstanceMethods
16
15
  end
17
16
  end
18
17
 
19
- module InstanceMethods
20
- eval <<-EOM
21
- #Returning any kind of identification you want for the model
22
- def #{Mailboxer.name_method}
23
- super
24
- rescue NameError
25
- return "You should add method :#{Mailboxer.name_method} in your Messageable model"
26
- end
27
-
28
- #Returning the email address of the model if an email should be sent for this object (Message or Notification).
29
- #If no mail has to be sent, return nil.
30
- def #{Mailboxer.email_method}(object)
31
- super
32
- rescue NameError
33
- return "You should add method :#{Mailboxer.email_method} in your Messageable model"
34
- end
35
- EOM
36
- #Gets the mailbox of the messageable
37
- def mailbox
38
- @mailbox = Mailbox.new(self) if @mailbox.nil?
39
- @mailbox.type = :all
40
- return @mailbox
18
+ unless defined?(Mailboxer.name_method)
19
+ # Returning any kind of identification you want for the model
20
+ define_method Mailboxer.name_method do
21
+ begin
22
+ super
23
+ rescue NameError
24
+ return "You should add method :#{Mailboxer.name_method} in your Messageable model"
25
+ end
41
26
  end
27
+ end
42
28
 
43
- #Sends a notification to the messageable
44
- def notify(subject,body,obj = nil,sanitize_text=true,notification_code=nil)
45
- return Notification.notify_all([self],subject,body,obj,sanitize_text,notification_code)
29
+ unless defined?(Mailboxer.email_method)
30
+ #Returning the email address of the model if an email should be sent for this object (Message or Notification).
31
+ #If no mail has to be sent, return nil.
32
+ define_method Mailboxer.email_method do |object|
33
+ begin
34
+ super
35
+ rescue NameError
36
+ return "You should add method :#{Mailboxer.email_method} in your Messageable model"
37
+ end
46
38
  end
39
+ end
47
40
 
48
- #Sends a messages, starting a new conversation, with the messageable
49
- #as originator
50
- def send_message(recipients, msg_body, subject, sanitize_text=true, attachment=nil)
51
- convo = Conversation.new({:subject => subject})
52
- message = messages.new({:body => msg_body, :subject => subject, :attachment => attachment})
53
- message.conversation = convo
54
- message.recipients = recipients.is_a?(Array) ? recipients : [recipients]
55
- message.recipients = message.recipients.uniq
56
- return message.deliver false,sanitize_text
57
- end
41
+ #Gets the mailbox of the messageable
42
+ def mailbox
43
+ @mailbox = Mailbox.new(self) if @mailbox.nil?
44
+ @mailbox.type = :all
45
+ return @mailbox
46
+ end
58
47
 
59
- #Basic reply method. USE NOT RECOMENDED.
60
- #Use reply_to_sender, reply_to_all and reply_to_conversation instead.
61
- def reply(conversation, recipients, reply_body, subject=nil, sanitize_text=true, attachment=nil)
62
- subject = subject || "RE: #{conversation.subject}"
63
- response = messages.new({:body => reply_body, :subject => subject, :attachment => attachment})
64
- response.conversation = conversation
65
- response.recipients = recipients.is_a?(Array) ? recipients : [recipients]
66
- response.recipients = response.recipients.uniq
67
- response.recipients.delete(self)
68
- return response.deliver true, sanitize_text
69
- end
48
+ #Sends a notification to the messageable
49
+ def notify(subject,body,obj = nil,sanitize_text=true,notification_code=nil)
50
+ return Notification.notify_all([self],subject,body,obj,sanitize_text,notification_code)
51
+ end
70
52
 
71
- #Replies to the sender of the message in the conversation
72
- def reply_to_sender(receipt, reply_body, subject=nil, sanitize_text=true, attachment=nil)
73
- return reply(receipt.conversation, receipt.message.sender, reply_body, subject, sanitize_text, attachment)
74
- end
53
+ #Sends a messages, starting a new conversation, with the messageable
54
+ #as originator
55
+ def send_message(recipients, msg_body, subject, sanitize_text=true, attachment=nil)
56
+ convo = Conversation.new({:subject => subject})
57
+ message = messages.new({:body => msg_body, :subject => subject, :attachment => attachment})
58
+ message.conversation = convo
59
+ message.recipients = recipients.is_a?(Array) ? recipients : [recipients]
60
+ message.recipients = message.recipients.uniq
61
+ return message.deliver false,sanitize_text
62
+ end
75
63
 
76
- #Replies to all the recipients of the message in the conversation
77
- def reply_to_all(receipt, reply_body, subject=nil, sanitize_text=true, attachment=nil)
78
- return reply(receipt.conversation, receipt.message.recipients, reply_body, subject, sanitize_text, attachment)
79
- end
64
+ #Basic reply method. USE NOT RECOMENDED.
65
+ #Use reply_to_sender, reply_to_all and reply_to_conversation instead.
66
+ def reply(conversation, recipients, reply_body, subject=nil, sanitize_text=true, attachment=nil)
67
+ subject = subject || "RE: #{conversation.subject}"
68
+ response = messages.new({:body => reply_body, :subject => subject, :attachment => attachment})
69
+ response.conversation = conversation
70
+ response.recipients = recipients.is_a?(Array) ? recipients : [recipients]
71
+ response.recipients = response.recipients.uniq
72
+ response.recipients.delete(self)
73
+ return response.deliver true, sanitize_text
74
+ end
80
75
 
81
- #Replies to all the recipients of the last message in the conversation and untrash any trashed message by messageable
82
- #if should_untrash is set to true (this is so by default)
83
- def reply_to_conversation(conversation, reply_body, subject=nil, should_untrash=true, sanitize_text=true, attachment=nil)
84
- #move conversation to inbox if it is currently in the trash and should_untrash parameter is true.
85
- if should_untrash && mailbox.is_trashed?(conversation)
86
- mailbox.receipts_for(conversation).untrash
87
- end
88
- return reply(conversation, conversation.last_message.recipients, reply_body, subject, sanitize_text, attachment)
89
- end
76
+ #Replies to the sender of the message in the conversation
77
+ def reply_to_sender(receipt, reply_body, subject=nil, sanitize_text=true, attachment=nil)
78
+ return reply(receipt.conversation, receipt.message.sender, reply_body, subject, sanitize_text, attachment)
79
+ end
90
80
 
91
- #Mark the object as read for messageable.
92
- #
93
- #Object can be:
94
- #* A Receipt
95
- #* A Message
96
- #* A Notification
97
- #* A Conversation
98
- #* An array with any of them
99
- def mark_as_read(obj)
100
- case obj
101
- when Receipt
102
- return obj.mark_as_read if obj.receiver == self
103
- when Message, Notification
104
- obj.mark_as_read(self)
105
- when Conversation
106
- obj.mark_as_read(self)
107
- when Array
108
- obj.map{ |sub_obj| mark_as_read(sub_obj) }
109
- else
110
- return nil
111
- end
81
+ #Replies to all the recipients of the message in the conversation
82
+ def reply_to_all(receipt, reply_body, subject=nil, sanitize_text=true, attachment=nil)
83
+ return reply(receipt.conversation, receipt.message.recipients, reply_body, subject, sanitize_text, attachment)
84
+ end
85
+
86
+ #Replies to all the recipients of the last message in the conversation and untrash any trashed message by messageable
87
+ #if should_untrash is set to true (this is so by default)
88
+ def reply_to_conversation(conversation, reply_body, subject=nil, should_untrash=true, sanitize_text=true, attachment=nil)
89
+ #move conversation to inbox if it is currently in the trash and should_untrash parameter is true.
90
+ if should_untrash && mailbox.is_trashed?(conversation)
91
+ mailbox.receipts_for(conversation).untrash
112
92
  end
93
+ return reply(conversation, conversation.last_message.recipients, reply_body, subject, sanitize_text, attachment)
94
+ end
113
95
 
114
- #Mark the object as unread for messageable.
115
- #
116
- #Object can be:
117
- #* A Receipt
118
- #* A Message
119
- #* A Notification
120
- #* A Conversation
121
- #* An array with any of them
122
- def mark_as_unread(obj)
123
- case obj
124
- when Receipt
125
- return obj.mark_as_unread if obj.receiver == self
126
- when Message, Notification
127
- obj.mark_as_unread(self)
128
- when Conversation
129
- obj.mark_as_unread(self)
130
- when Array
131
- obj.map{ |sub_obj| mark_as_unread(sub_obj) }
132
- else
96
+ #Mark the object as read for messageable.
97
+ #
98
+ #Object can be:
99
+ #* A Receipt
100
+ #* A Message
101
+ #* A Notification
102
+ #* A Conversation
103
+ #* An array with any of them
104
+ def mark_as_read(obj)
105
+ case obj
106
+ when Receipt
107
+ return obj.mark_as_read if obj.receiver == self
108
+ when Message, Notification
109
+ obj.mark_as_read(self)
110
+ when Conversation
111
+ obj.mark_as_read(self)
112
+ when Array
113
+ obj.map{ |sub_obj| mark_as_read(sub_obj) }
114
+ else
133
115
  return nil
134
- end
135
116
  end
117
+ end
136
118
 
137
- #Mark the object as trashed for messageable.
138
- #
139
- #Object can be:
140
- #* A Receipt
141
- #* A Message
142
- #* A Notification
143
- #* A Conversation
144
- #* An array with any of them
145
- def trash(obj)
146
- case obj
147
- when Receipt
148
- return obj.move_to_trash if obj.receiver == self
149
- when Message, Notification
150
- obj.move_to_trash(self)
151
- when Conversation
152
- obj.move_to_trash(self)
153
- when Array
154
- obj.map{ |sub_obj| trash(sub_obj) }
155
- else
156
- return nil
157
- end
119
+ #Mark the object as unread for messageable.
120
+ #
121
+ #Object can be:
122
+ #* A Receipt
123
+ #* A Message
124
+ #* A Notification
125
+ #* A Conversation
126
+ #* An array with any of them
127
+ def mark_as_unread(obj)
128
+ case obj
129
+ when Receipt
130
+ return obj.mark_as_unread if obj.receiver == self
131
+ when Message, Notification
132
+ obj.mark_as_unread(self)
133
+ when Conversation
134
+ obj.mark_as_unread(self)
135
+ when Array
136
+ obj.map{ |sub_obj| mark_as_unread(sub_obj) }
137
+ else
138
+ return nil
158
139
  end
140
+ end
159
141
 
160
- #Mark the object as not trashed for messageable.
161
- #
162
- #Object can be:
163
- #* A Receipt
164
- #* A Message
165
- #* A Notification
166
- #* A Conversation
167
- #* An array with any of them
168
- def untrash(obj)
169
- case obj
170
- when Receipt
171
- return obj.untrash if obj.receiver == self
172
- when Message, Notification
173
- obj.untrash(self)
174
- when Conversation
175
- obj.untrash(self)
176
- when Array
177
- obj.map{ |sub_obj| untrash(sub_obj) }
178
- else
179
- return nil
180
- end
142
+ #Mark the object as trashed for messageable.
143
+ #
144
+ #Object can be:
145
+ #* A Receipt
146
+ #* A Message
147
+ #* A Notification
148
+ #* A Conversation
149
+ #* An array with any of them
150
+ def trash(obj)
151
+ case obj
152
+ when Receipt
153
+ return obj.move_to_trash if obj.receiver == self
154
+ when Message, Notification
155
+ obj.move_to_trash(self)
156
+ when Conversation
157
+ obj.move_to_trash(self)
158
+ when Array
159
+ obj.map{ |sub_obj| trash(sub_obj) }
160
+ else
161
+ return nil
181
162
  end
163
+ end
182
164
 
183
- def search_messages(query)
184
- @search = Receipt.search do
185
- fulltext query
186
- with :receiver_id, self.id
187
- end
165
+ #Mark the object as not trashed for messageable.
166
+ #
167
+ #Object can be:
168
+ #* A Receipt
169
+ #* A Message
170
+ #* A Notification
171
+ #* A Conversation
172
+ #* An array with any of them
173
+ def untrash(obj)
174
+ case obj
175
+ when Receipt
176
+ return obj.untrash if obj.receiver == self
177
+ when Message, Notification
178
+ obj.untrash(self)
179
+ when Conversation
180
+ obj.untrash(self)
181
+ when Array
182
+ obj.map{ |sub_obj| untrash(sub_obj) }
183
+ else
184
+ return nil
185
+ end
186
+ end
188
187
 
189
- @search.results.map { |r| r.conversation }.uniq
188
+ def search_messages(query)
189
+ @search = Receipt.search do
190
+ fulltext query
191
+ with :receiver_id, self.id
190
192
  end
193
+
194
+ @search.results.map { |r| r.conversation }.uniq
191
195
  end
192
196
  end
193
197
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "mailboxer"
3
- s.version = "0.8.0"
3
+ s.version = "0.9.0"
4
4
  s.authors = ["Eduardo Casanova Cuesta"]
5
5
  s.summary = "Messaging system for rails apps."
6
6
  s.description = "A Rails engine that allows any model to act as messageable, adding the ability to exchange messages " +
@@ -714,4 +714,190 @@ describe "Messages And Receipts" do
714
714
  end
715
715
  end
716
716
  end
717
+
718
+ describe "two STI entities" do
719
+ before do
720
+ @entity1 = FactoryGirl.create(:commander)
721
+ @entity2 = FactoryGirl.create(:commander)
722
+ end
723
+
724
+ describe "message sending" do
725
+
726
+ before do
727
+ @receipt1 = @entity1.send_message(@entity2,"Body","Subject")
728
+ @message1 = @receipt1.notification
729
+ end
730
+
731
+ it "should create proper message" do
732
+ @message1.sender.id.should == @entity1.id
733
+ @message1.sender.class.should == @entity1.class
734
+ assert @message1.body.eql?"Body"
735
+ assert @message1.subject.eql?"Subject"
736
+ end
737
+
738
+ it "should create proper mails" do
739
+ #Sender Mail
740
+ mail = Receipt.recipient(@entity1).notification(@message1).first
741
+ assert mail
742
+ if mail
743
+ mail.is_read.should==true
744
+ mail.trashed.should==false
745
+ mail.mailbox_type.should=="sentbox"
746
+ end
747
+ #Receiver Mail
748
+ mail = Receipt.recipient(@entity2).notification(@message1).first
749
+ assert mail
750
+ if mail
751
+ mail.is_read.should==false
752
+ mail.trashed.should==false
753
+ mail.mailbox_type.should=="inbox"
754
+ end
755
+ end
756
+
757
+ it "should have the correct recipients" do
758
+ recipients = @message1.recipients
759
+ recipients.count.should==2
760
+ recipients.count(@entity1).should==1
761
+ recipients.count(@entity2).should==1
762
+ end
763
+
764
+ end
765
+
766
+ describe "message replying to sender" do
767
+ before do
768
+ @receipt1 = @entity1.send_message(@entity2,"Body","Subject")
769
+ @receipt2 = @entity2.reply_to_sender(@receipt1,"Reply body")
770
+ @message1 = @receipt1.notification
771
+ @message2 = @receipt2.notification
772
+ end
773
+
774
+ it "should create proper message" do
775
+ @message2.sender.id.should == @entity2.id
776
+ @message2.sender.class.should == @entity2.class
777
+ assert @message2.body.eql?"Reply body"
778
+ assert @message2.subject.eql?"RE: Subject"
779
+ end
780
+
781
+ it "should create proper mails" do
782
+ #Sender Mail
783
+ mail = Receipt.recipient(@entity2).notification(@message2).first
784
+ assert mail
785
+ if mail
786
+ mail.is_read.should==true
787
+ mail.trashed.should==false
788
+ mail.mailbox_type.should=="sentbox"
789
+ end
790
+ #Receiver Mail
791
+ mail = Receipt.recipient(@entity1).notification(@message2).first
792
+ assert mail
793
+ if mail
794
+ mail.is_read.should==false
795
+ mail.trashed.should==false
796
+ mail.mailbox_type.should=="inbox"
797
+ end
798
+ end
799
+
800
+ it "should have the correct recipients" do
801
+ recipients = @message2.recipients
802
+ recipients.count.should==2
803
+ recipients.count(@entity1).should==1
804
+ recipients.count(@entity2).should==1
805
+ end
806
+
807
+ it "should be associated to the same conversation" do
808
+ @message1.conversation.id.should==@message2.conversation.id
809
+ end
810
+ end
811
+
812
+ describe "message replying to all" do
813
+ before do
814
+ @receipt1 = @entity1.send_message(@entity2,"Body","Subject")
815
+ @receipt2 = @entity2.reply_to_all(@receipt1,"Reply body")
816
+ @message1 = @receipt1.notification
817
+ @message2 = @receipt2.notification
818
+ end
819
+
820
+ it "should create proper message" do
821
+ @message2.sender.id.should == @entity2.id
822
+ @message2.sender.class.should == @entity2.class
823
+ assert @message2.body.eql?"Reply body"
824
+ assert @message2.subject.eql?"RE: Subject"
825
+ end
826
+
827
+ it "should create proper mails" do
828
+ #Sender Mail
829
+ mail = Receipt.recipient(@entity2).notification(@message2).first
830
+ assert mail
831
+ if mail
832
+ mail.is_read.should==true
833
+ mail.trashed.should==false
834
+ mail.mailbox_type.should=="sentbox"
835
+ end
836
+ #Receiver Mail
837
+ mail = Receipt.recipient(@entity1).notification(@message2).first
838
+ assert mail
839
+ if mail
840
+ mail.is_read.should==false
841
+ mail.trashed.should==false
842
+ mail.mailbox_type.should=="inbox"
843
+ end
844
+ end
845
+
846
+ it "should have the correct recipients" do
847
+ recipients = @message2.recipients
848
+ recipients.count.should==2
849
+ recipients.count(@entity1).should==1
850
+ recipients.count(@entity2).should==1
851
+ end
852
+
853
+ it "should be associated to the same conversation" do
854
+ @message1.conversation.id.should==@message2.conversation.id
855
+ end
856
+ end
857
+ describe "message replying to conversation" do
858
+ before do
859
+ @receipt1 = @entity1.send_message(@entity2,"Body","Subject")
860
+ @receipt2 = @entity2.reply_to_conversation(@receipt1.conversation,"Reply body")
861
+ @message1 = @receipt1.notification
862
+ @message2 = @receipt2.notification
863
+ end
864
+
865
+ it "should create proper message" do
866
+ @message2.sender.id.should == @entity2.id
867
+ @message2.sender.class.should == @entity2.class
868
+ assert @message2.body.eql?"Reply body"
869
+ assert @message2.subject.eql?"RE: Subject"
870
+ end
871
+
872
+ it "should create proper mails" do
873
+ #Sender Mail
874
+ mail = Receipt.recipient(@entity2).notification(@message2).first
875
+ assert mail
876
+ if mail
877
+ mail.is_read.should==true
878
+ mail.trashed.should==false
879
+ mail.mailbox_type.should=="sentbox"
880
+ end
881
+ #Receiver Mail
882
+ mail = Receipt.recipient(@entity1).notification(@message2).first
883
+ assert mail
884
+ if mail
885
+ mail.is_read.should==false
886
+ mail.trashed.should==false
887
+ mail.mailbox_type.should=="inbox"
888
+ end
889
+ end
890
+
891
+ it "should have the correct recipients" do
892
+ recipients = @message2.recipients
893
+ recipients.count.should==2
894
+ recipients.count(@entity1).should==1
895
+ recipients.count(@entity2).should==1
896
+ end
897
+
898
+ it "should be associated to the same conversation" do
899
+ @message1.conversation.id.should==@message2.conversation.id
900
+ end
901
+ end
902
+ end
717
903
  end
@@ -102,6 +102,23 @@ describe Mailbox do
102
102
  assert @entity2.mailbox.receipts.trash
103
103
  @entity2.mailbox.receipts.trash.count.should==0
104
104
  end
105
-
105
+
106
+ context "STI models" do
107
+ before do
108
+ @sti_entity1 = FactoryGirl.create(:commander)
109
+ @sti_entity2 = FactoryGirl.create(:commander)
110
+ @sti_mail = @sti_entity1.send_message(@sti_entity2, "Body", "Subject")
111
+ end
112
+
113
+ it "should add one to senders sentbox" do
114
+ @sti_entity1.mailbox.sentbox.count.should==1
115
+ @sti_entity1.mailbox.sentbox.should include(@sti_mail.conversation)
116
+ end
117
+
118
+ it "should add one to recievers inbox" do
119
+ @sti_entity2.mailbox.inbox.count.should == 1
120
+ @sti_entity2.mailbox.inbox.should include(@sti_mail.conversation)
121
+ end
122
+ end
106
123
 
107
124
  end
@@ -29,5 +29,16 @@ describe Receipt do
29
29
  @mail1.is_read.should==true
30
30
  end
31
31
 
32
+ context "STI models" do
33
+ before do
34
+ @entity3 = FactoryGirl.create(:commander)
35
+ @entity4 = FactoryGirl.create(:commander)
36
+ @mail2 = @entity3.send_message(@entity4, "Body", "Subject")
37
+ end
38
+
39
+ it "should refer to the correct base class" do
40
+ @mail2.receiver_type.should == @entity3.class.base_class.to_s
41
+ end
42
+ end
32
43
 
33
44
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailboxer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-15 00:00:00.000000000 Z
12
+ date: 2012-12-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: foreigner
@@ -264,7 +264,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
264
264
  version: '0'
265
265
  segments:
266
266
  - 0
267
- hash: 2240527445875672830
267
+ hash: 1911356081747184373
268
268
  required_rubygems_version: !ruby/object:Gem::Requirement
269
269
  none: false
270
270
  requirements:
@@ -273,7 +273,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
273
273
  version: '0'
274
274
  segments:
275
275
  - 0
276
- hash: 2240527445875672830
276
+ hash: 1911356081747184373
277
277
  requirements: []
278
278
  rubyforge_project:
279
279
  rubygems_version: 1.8.23