mailboxer 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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