mailboxer 0.6.5 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -5,4 +5,6 @@ rvm:
5
5
  - 1.9.3
6
6
  - ree
7
7
  - rbx-18mode
8
+ - rbx-19mode
8
9
  - jruby-18mode
10
+ - jruby-19mode
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 Eduardo Casanova Cuesta
1
+ Copyright (c) 2012 Universidad Politécnica de Madrid
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Mailboxer 0.6.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.7.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
@@ -72,6 +72,16 @@ Mailboxer.setup do |config|
72
72
  end
73
73
  ````
74
74
 
75
+ You can change the way in which emails are delivered by specifying a custom implementation for notification and message mailer
76
+
77
+ ````ruby
78
+ Mailboxer.setup do |config|
79
+ config.notification_mailer = CustomNotificationMailer
80
+ config.message_mailer = CustomMessageMailer
81
+ ...
82
+ end
83
+ ````
84
+
75
85
  ### User identities
76
86
 
77
87
  Users must have an identity defined by a `name` and an `email`. We must assure that Messageable models have some specific methods. These methods are:
@@ -219,6 +229,10 @@ This is done this way because receipts save the information about the relation b
219
229
 
220
230
  You can take a look at the full documentation of Mailboxer in [rubydoc.info](http://rubydoc.info/gems/mailboxer/frames).
221
231
 
232
+ ## Do you want to test Mailboxer?
233
+
234
+ Thanks to [Roman Kushnir (@RKushnir)](https://github.com/RKushnir/) you can test Mailboxer with this [sample app](https://github.com/RKushnir/mailboxer-app).
235
+
222
236
  ## I need a GUI!
223
237
 
224
238
  If you need a GUI you should take a look a this links:
@@ -229,16 +243,9 @@ If you need a GUI you should take a look a this links:
229
243
  ## Contributors
230
244
  * [Roendal](https://github.com/ging/mailboxer/commits/master?author=Roendal) (Eduardo Casanova)
231
245
  * [dickeyxxx](https://github.com/ging/mailboxer/commits/master?author=dickeyxxx) (Jeff Dickey)
246
+ * [RKushnir](https://github.com/ging/mailboxer/commits/master?author=RKushnir) (Roman Kushnir)
247
+ * [amaierhofer](https://github.com/ging/mailboxer/commits/master?author=amaierhofer) (Andreas Maierhofer)
232
248
  * [tonydewan](https://github.com/ging/mailboxer/commits/master?author=tonydewan) (Tony Dewan)
233
249
  * [plentz](https://github.com/ging/mailboxer/commits/master?author=plentz) (Diego Plentz)
234
250
  * [laserlemon](https://github.com/ging/mailboxer/commits/master?author=laserlemon) (Steve Richert)
235
-
236
- ## License
237
-
238
- Copyright © 2012 Eduardo Casanova Cuesta
239
-
240
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
241
-
242
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
243
-
244
- THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
251
+ * [daveworth](https://github.com/ging/mailboxer/commits/master?author=daveworth) (Dave Worth)
@@ -1,4 +1,6 @@
1
1
  class Conversation < ActiveRecord::Base
2
+ attr_accessible :subject
3
+
2
4
  has_many :messages, :dependent => :destroy
3
5
  has_many :receipts, :through => :messages
4
6
 
@@ -6,20 +8,23 @@ class Conversation < ActiveRecord::Base
6
8
 
7
9
  before_validation :clean
8
10
 
9
- scope :participant, lambda {|participant|
10
- joins(:receipts).select('DISTINCT conversations.*').where('notifications.type'=> Message.to_s,'receipts.receiver_id' => participant.id,'receipts.receiver_type' => participant.class.to_s).order("conversations.updated_at DESC")
11
+ scope :participant, lambda {|participant|
12
+ select('DISTINCT conversations.*').
13
+ where('notifications.type'=> Message.name).
14
+ order("conversations.updated_at DESC").
15
+ joins(:receipts).merge(Receipt.recipient(participant))
11
16
  }
12
- scope :inbox, lambda {|participant|
13
- joins(:receipts).select('DISTINCT conversations.*').where('notifications.type'=> Message.to_s,'receipts.receiver_id' => participant.id,'receipts.receiver_type' => participant.class.to_s, 'receipts.mailbox_type' => 'inbox','receipts.trashed' => false).order("conversations.updated_at DESC")
17
+ scope :inbox, lambda {|participant|
18
+ participant(participant).merge(Receipt.inbox.not_trash)
14
19
  }
15
- scope :sentbox, lambda {|participant|
16
- joins(:receipts).select('DISTINCT conversations.*').where('notifications.type'=> Message.to_s,'receipts.receiver_id' => participant.id,'receipts.receiver_type' => participant.class.to_s, 'receipts.mailbox_type' => 'sentbox','receipts.trashed' => false).order("conversations.updated_at DESC")
20
+ scope :sentbox, lambda {|participant|
21
+ participant(participant).merge(Receipt.sentbox.not_trash)
17
22
  }
18
- scope :trash, lambda {|participant|
19
- joins(:receipts).select('DISTINCT conversations.*').where('notifications.type'=> Message.to_s,'receipts.receiver_id' => participant.id,'receipts.receiver_type' => participant.class.to_s,'receipts.trashed' => true).order("conversations.updated_at DESC")
23
+ scope :trash, lambda {|participant|
24
+ participant(participant).merge(Receipt.trash)
20
25
  }
21
- scope :unread, lambda {|participant|
22
- joins(:receipts).select('DISTINCT conversations.*').where('notifications.type'=> Message.to_s,'receipts.receiver_id' => participant.id,'receipts.receiver_type' => participant.class.to_s,'receipts.read' => false).order("conversations.updated_at DESC")
26
+ scope :unread, lambda {|participant|
27
+ participant(participant).merge(Receipt.unread)
23
28
  }
24
29
 
25
30
  #Mark the conversation as read for one of the participants
@@ -55,7 +60,7 @@ class Conversation < ActiveRecord::Base
55
60
  end
56
61
  return []
57
62
  end
58
-
63
+
59
64
  #Returns an array of participants
60
65
  def participants
61
66
  return recipients
@@ -110,13 +115,17 @@ class Conversation < ActiveRecord::Base
110
115
  #Returns true if the participant has trashed all the messages of the conversation
111
116
  def is_completely_trashed?(participant)
112
117
  return false if participant.nil?
113
- return self.receipts_for(participant).trash.count==self.receipts(participant).count
118
+ return self.receipts_for(participant).trash.count == self.receipts_for(participant).count
119
+ end
120
+
121
+ def is_read?(participant)
122
+ !self.is_unread?(participant)
114
123
  end
115
124
 
116
125
  #Returns true if the participant has at least one unread message of the conversation
117
126
  def is_unread?(participant)
118
127
  return false if participant.nil?
119
- return self.receipts_for(participant).unread.count!=0
128
+ return self.receipts_for(participant).not_trash.unread.count!=0
120
129
  end
121
130
 
122
131
  protected
@@ -42,7 +42,7 @@ class Mailbox
42
42
  end
43
43
  end
44
44
 
45
- if (options[:read].present? and options[:read]==false) or (options[:unread].present? and options[:unread]==true)
45
+ if (options.has_key?(:read) && options[:read]==false) || (options.has_key?(:unread) && options[:unread]==true)
46
46
  conv = conv.unread(@messageable)
47
47
  end
48
48
 
@@ -1,5 +1,6 @@
1
1
  class Message < Notification
2
- #
2
+ attr_accessible :attachment
3
+
3
4
  belongs_to :conversation, :validate => true, :autosave => true
4
5
  validates_presence_of :sender
5
6
 
@@ -10,6 +11,8 @@ class Message < Notification
10
11
  }
11
12
 
12
13
  mount_uploader :attachment, AttachmentUploader
14
+
15
+ include Concerns::ConfigurableMailer
13
16
 
14
17
  class << self
15
18
  #Sets the on deliver callback method.
@@ -45,15 +48,15 @@ class Message < Notification
45
48
  temp_receipts.each(&:save!) #Save receipts
46
49
  self.recipients.each do |r|
47
50
  #Should send an email?
48
- if Mailboxer.uses_emails
51
+ if Mailboxer.uses_emails
49
52
  email_to = r.send(Mailboxer.email_method,self)
50
53
  unless email_to.blank?
51
- MessageMailer.send_email(self,r).deliver
54
+ get_mailer.send_email(self,r).deliver
52
55
  end
53
56
  end
54
57
  end
55
58
  if reply
56
- self.conversation.update_attribute(:updated_at, Time.now)
59
+ self.conversation.touch
57
60
  end
58
61
  self.recipients=nil
59
62
  self.on_deliver_callback.call(self) unless self.on_deliver_callback.nil?
@@ -1,24 +1,27 @@
1
1
  class Notification < ActiveRecord::Base
2
-
3
2
  attr_accessor :recipients
3
+ attr_accessible :body, :subject
4
+
4
5
  belongs_to :sender, :polymorphic => :true
5
6
  belongs_to :notified_object, :polymorphic => :true
6
7
  validates_presence_of :subject, :body
7
8
  has_many :receipts, :dependent => :destroy
8
-
9
+
9
10
  scope :recipient, lambda { |recipient|
10
11
  joins(:receipts).where('receipts.receiver_id' => recipient.id,'receipts.receiver_type' => recipient.class.to_s)
11
12
  }
12
13
  scope :with_object, lambda { |obj|
13
14
  where('notified_object_id' => obj.id,'notified_object_type' => obj.class.to_s)
14
- }
15
+ }
15
16
  scope :not_trashed, lambda {
16
17
  joins(:receipts).where('receipts.trashed' => false)
17
18
  }
18
19
  scope :unread, lambda {
19
20
  joins(:receipts).where('receipts.read' => false)
20
21
  }
21
-
22
+
23
+ include Concerns::ConfigurableMailer
24
+
22
25
  class << self
23
26
  #Sends a Notification to all the recipients
24
27
  def notify_all(recipients,subject,body,obj = nil,sanitize_text = true,notification_code=nil)
@@ -29,7 +32,7 @@ class Notification < ActiveRecord::Base
29
32
  notification.notification_code = notification_code if notification_code.present?
30
33
  return notification.deliver sanitize_text
31
34
  end
32
-
35
+
33
36
  #Takes a +Receipt+ or an +Array+ of them and returns +true+ if the delivery was
34
37
  #successful or +false+ if some error raised
35
38
  def successful_delivery? receipts
@@ -42,7 +45,7 @@ class Notification < ActiveRecord::Base
42
45
  return receipts.all? { |t| t.errors.empty? }
43
46
  else
44
47
  return false
45
- end
48
+ end
46
49
  end
47
50
  end
48
51
 
@@ -57,17 +60,17 @@ class Notification < ActiveRecord::Base
57
60
  msg_receipt.notification = self
58
61
  msg_receipt.read = false
59
62
  msg_receipt.receiver = r
60
- temp_receipts << msg_receipt
63
+ temp_receipts << msg_receipt
61
64
  end
62
65
  temp_receipts.each(&:valid?)
63
66
  if temp_receipts.all? { |t| t.errors.empty? }
64
67
  temp_receipts.each(&:save!) #Save receipts
65
68
  self.recipients.each do |r|
66
69
  #Should send an email?
67
- if Mailboxer.uses_emails
70
+ if Mailboxer.uses_emails
68
71
  email_to = r.send(Mailboxer.email_method,self)
69
72
  unless email_to.blank?
70
- NotificationMailer.send_email(self,r).deliver
73
+ get_mailer.send_email(self,r).deliver
71
74
  end
72
75
  end
73
76
  end
@@ -76,7 +79,7 @@ class Notification < ActiveRecord::Base
76
79
  return temp_receipts if temp_receipts.size > 1
77
80
  return temp_receipts.first
78
81
  end
79
-
82
+
80
83
  #Returns the recipients of the Notification
81
84
  def recipients
82
85
  if @recipients.blank?
@@ -93,7 +96,7 @@ class Notification < ActiveRecord::Base
93
96
  def receipt_for(participant)
94
97
  return Receipt.notification(self).recipient(participant)
95
98
  end
96
-
99
+
97
100
  #Returns the receipt for the participant. Alias for receipt_for(participant)
98
101
  def receipts_for(participant)
99
102
  return receipt_for(participant)
@@ -105,11 +108,15 @@ class Notification < ActiveRecord::Base
105
108
  return !self.receipt_for(participant).first.read
106
109
  end
107
110
 
111
+ def is_read?(participant)
112
+ !self.is_unread?(participant)
113
+ end
114
+
108
115
  #Returns if the participant have trashed the Notification
109
116
  def is_trashed?(participant)
110
117
  return false if participant.nil?
111
118
  return self.receipt_for(participant).first.trashed
112
- end
119
+ end
113
120
 
114
121
  #Mark the notification as read
115
122
  def mark_as_read(participant)
@@ -129,7 +136,7 @@ class Notification < ActiveRecord::Base
129
136
  return self.receipt_for(participant).move_to_trash
130
137
  end
131
138
 
132
- #Takes the notification out of the trash
139
+ #Takes the notification out of the trash
133
140
  def untrash(participant)
134
141
  return if participant.nil?
135
142
  return self.receipt_for(participant).untrash
@@ -145,7 +152,7 @@ class Notification < ActiveRecord::Base
145
152
  end
146
153
  self.body = sanitize self.body
147
154
  end
148
-
155
+
149
156
  #Returns notified_object. DEPRECATED
150
157
  def object
151
158
  warn "DEPRECATION WARNING: use 'notify_object' instead of 'object' to get the object associated with the Notification"
@@ -59,13 +59,13 @@ class Receipt < ActiveRecord::Base
59
59
 
60
60
  #This methods helps to do a update_all with table joins, not currently supported by rails.
61
61
  #Acording to the github ticket https://github.com/rails/rails/issues/522 it should be
62
- #supported with 3.2.
62
+ #supported with 3.2.
63
63
  def update_receipts(updates,options={})
64
64
  ids = Array.new
65
65
  where(options).each do |rcp|
66
66
  ids << rcp.id
67
67
  end
68
- return if ids.empty?
68
+ return if ids.empty?
69
69
  conditions = [""].concat(ids)
70
70
  condition = "id = ? "
71
71
  ids.drop(1).each do
@@ -120,9 +120,9 @@ class Receipt < ActiveRecord::Base
120
120
  #Returns if the participant have trashed the Notification
121
121
  def is_trashed?
122
122
  return self.trashed
123
- end
123
+ end
124
+
124
125
 
125
-
126
126
  protected
127
127
 
128
128
  #Removes the duplicate error about not present subject from Conversation if it has been already
data/lib/mailboxer.rb CHANGED
@@ -15,7 +15,9 @@ module Mailboxer
15
15
  @@email_method = :mailboxer_email
16
16
  mattr_accessor :name_method
17
17
  @@name_method = :name
18
-
18
+ mattr_accessor :notification_mailer
19
+ mattr_accessor :message_mailer
20
+
19
21
  class << self
20
22
  def setup
21
23
  yield self
@@ -26,3 +28,4 @@ end
26
28
  # reopen ActiveRecord and include all the above to make
27
29
  # them available to all our models if they want it
28
30
  require 'mailboxer/engine'
31
+ require 'mailboxer/concerns/configurable_mailer'
@@ -0,0 +1,13 @@
1
+ require 'active_support/inflections'
2
+
3
+ module Concerns
4
+ module ConfigurableMailer
5
+
6
+ def get_mailer
7
+ return @mailer if @mailer
8
+ method = "#{self.class.to_s.downcase}_mailer".to_sym
9
+ @mailer = Mailboxer.send(method) || "#{self.class}Mailer".constantize
10
+ end
11
+
12
+ end
13
+ end
@@ -3,7 +3,6 @@ require 'foreigner'
3
3
  require 'carrierwave'
4
4
  begin
5
5
  require 'sunspot_rails'
6
- Logger.new(STDOUT).debug 'The sunspot_rails gem is present. Loading it into mailboxer. You can know use Solr search engine.'
7
6
  rescue LoadError
8
7
  end
9
8
 
@@ -16,7 +16,7 @@ module Mailboxer
16
16
  end
17
17
  end
18
18
 
19
- module InstanceMethods
19
+ module InstanceMethods
20
20
  eval <<-EOM
21
21
  #Returning any kind of identification you want for the model
22
22
  def #{Mailboxer.name_method}
@@ -26,7 +26,7 @@ module Mailboxer
26
26
  end
27
27
 
28
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.
29
+ #If no mail has to be sent, return nil.
30
30
  def #{Mailboxer.email_method}(object)
31
31
  super
32
32
  rescue NameError
@@ -49,7 +49,8 @@ module Mailboxer
49
49
  #as originator
50
50
  def send_message(recipients, msg_body, subject, sanitize_text=true, attachment=nil)
51
51
  convo = Conversation.new({:subject => subject})
52
- message = Message.new({:sender => self, :conversation => convo, :body => msg_body, :subject => subject, :attachment => attachment})
52
+ message = messages.new({:body => msg_body, :subject => subject, :attachment => attachment})
53
+ message.conversation = convo
53
54
  message.recipients = recipients.is_a?(Array) ? recipients : [recipients]
54
55
  message.recipients = message.recipients.uniq
55
56
  return message.deliver false,sanitize_text
@@ -59,7 +60,8 @@ module Mailboxer
59
60
  #Use reply_to_sender, reply_to_all and reply_to_conversation instead.
60
61
  def reply(conversation, recipients, reply_body, subject=nil, sanitize_text=true, attachment=nil)
61
62
  subject = subject || "RE: #{conversation.subject}"
62
- response = Message.new({:sender => self, :conversation => conversation, :body => reply_body, :subject => subject, :attachment => attachment})
63
+ response = messages.new({:body => reply_body, :subject => subject, :attachment => attachment})
64
+ response.conversation = conversation
63
65
  response.recipients = recipients.is_a?(Array) ? recipients : [recipients]
64
66
  response.recipients = response.recipients.uniq
65
67
  response.recipients.delete(self)
data/mailboxer.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "mailboxer"
3
- s.version = "0.6.5"
3
+ s.version = "0.7.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 " +
@@ -27,7 +27,11 @@ Gem::Specification.new do |s|
27
27
  # Specs
28
28
  s.add_development_dependency('rspec-rails', '>= 2.6.1')
29
29
  # Fixtures
30
- s.add_development_dependency('factory_girl', '>= 2.6.0')
30
+ if RUBY_VERSION >= '1.9.2'
31
+ s.add_development_dependency('factory_girl', '>= 3.0.0')
32
+ else
33
+ s.add_development_dependency('factory_girl', '~> 2.6.0')
34
+ end
31
35
  # Population
32
36
  s.add_development_dependency('forgery', '>= 0.3.6')
33
37
  # Integration testing
@@ -4,8 +4,8 @@ describe "Messages And Receipts" do
4
4
 
5
5
  describe "two equal entities" do
6
6
  before do
7
- @entity1 = Factory(:user)
8
- @entity2 = Factory(:user)
7
+ @entity1 = FactoryGirl.create(:user)
8
+ @entity2 = FactoryGirl.create(:user)
9
9
  end
10
10
 
11
11
  describe "message sending" do
@@ -190,8 +190,8 @@ describe "Messages And Receipts" do
190
190
 
191
191
  describe "two different entities" do
192
192
  before do
193
- @entity1 = Factory(:user)
194
- @entity2 = Factory(:duck)
193
+ @entity1 = FactoryGirl.create(:user)
194
+ @entity2 = FactoryGirl.create(:duck)
195
195
  end
196
196
 
197
197
  describe "message sending" do
@@ -352,9 +352,9 @@ describe "Messages And Receipts" do
352
352
 
353
353
  describe "three equal entities" do
354
354
  before do
355
- @entity1 = Factory(:user)
356
- @entity2 = Factory(:user)
357
- @entity3 = Factory(:user)
355
+ @entity1 = FactoryGirl.create(:user)
356
+ @entity2 = FactoryGirl.create(:user)
357
+ @entity3 = FactoryGirl.create(:user)
358
358
  @recipients = Array.new
359
359
  @recipients << @entity2
360
360
  @recipients << @entity3
@@ -534,9 +534,9 @@ describe "Messages And Receipts" do
534
534
 
535
535
  describe "three different entities" do
536
536
  before do
537
- @entity1 = Factory(:user)
538
- @entity2 = Factory(:duck)
539
- @entity3 = Factory(:cylon)
537
+ @entity1 = FactoryGirl.create(:user)
538
+ @entity2 = FactoryGirl.create(:duck)
539
+ @entity3 = FactoryGirl.create(:cylon)
540
540
  @recipients = Array.new
541
541
  @recipients << @entity2
542
542
  @recipients << @entity3
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+ describe Concerns::ConfigurableMailer do
3
+
4
+ describe "Notification instance#get_mailer" do
5
+ before { @obj = Notification.new }
6
+ it "returns default_mailer" do
7
+ @obj.get_mailer.should eq NotificationMailer
8
+ end
9
+ it "returns 'foo' from Mailerbox.notification_mailer" do
10
+ Mailboxer.notification_mailer = 'foo'
11
+ @obj.get_mailer.should eq 'foo'
12
+ end
13
+ after { Mailboxer.notification_mailer = nil }
14
+ end
15
+
16
+ describe "Message instance#get_mailer" do
17
+ before { @obj = Message.new }
18
+ it "returns default_mailer" do
19
+ @obj.get_mailer.should eq MessageMailer
20
+ end
21
+ it "returns 'foo' from Mailerbox.message_mailer" do
22
+ Mailboxer.message_mailer = 'foo'
23
+ @obj.get_mailer.should eq 'foo'
24
+ end
25
+ after { Mailboxer.message_mailer = nil }
26
+ end
27
+ end
@@ -4,4 +4,4 @@ describe Mailboxer do
4
4
  it "should be valid" do
5
5
  Mailboxer.should be_a(Module)
6
6
  end
7
- end
7
+ end
@@ -3,10 +3,10 @@ require 'spec_helper'
3
3
  describe MessageMailer do
4
4
  describe "when sending new message" do
5
5
  before do
6
- @sender = Factory(:user)
7
- @entity1 = Factory(:user)
8
- @entity2 = Factory(:duck)
9
- @entity3 = Factory(:cylon)
6
+ @sender = FactoryGirl.create(:user)
7
+ @entity1 = FactoryGirl.create(:user)
8
+ @entity2 = FactoryGirl.create(:duck)
9
+ @entity3 = FactoryGirl.create(:cylon)
10
10
  @receipt1 = @sender.send_message([@entity1,@entity2,@entity3], "Body Body Body Body Body Body Body Body Body Body Body Body","Subject")
11
11
  end
12
12
 
@@ -48,10 +48,10 @@ describe MessageMailer do
48
48
 
49
49
  describe "when replying" do
50
50
  before do
51
- @sender = Factory(:user)
52
- @entity1 = Factory(:user)
53
- @entity2 = Factory(:duck)
54
- @entity3 = Factory(:cylon)
51
+ @sender = FactoryGirl.create(:user)
52
+ @entity1 = FactoryGirl.create(:user)
53
+ @entity2 = FactoryGirl.create(:duck)
54
+ @entity3 = FactoryGirl.create(:cylon)
55
55
  @receipt1 = @sender.send_message([@entity1,@entity2,@entity3], "Body","Subject")
56
56
  @receipt2 = @sender.reply_to_all(@receipt1, "Body")
57
57
  end
@@ -2,9 +2,9 @@ require 'spec_helper'
2
2
 
3
3
  describe NotificationMailer do
4
4
  before do
5
- @entity1 = Factory(:user)
6
- @entity2 = Factory(:duck)
7
- @entity3 = Factory(:cylon)
5
+ @entity1 = FactoryGirl.create(:user)
6
+ @entity2 = FactoryGirl.create(:duck)
7
+ @entity3 = FactoryGirl.create(:cylon)
8
8
  @receipt1 = Notification.notify_all([@entity1,@entity2,@entity3],"Subject", "Body Body Body Body Body Body Body Body Body Body Body Body")
9
9
  end
10
10
 
@@ -1,10 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Conversation do
4
-
4
+
5
5
  before do
6
- @entity1 = Factory(:user)
7
- @entity2 = Factory(:user)
6
+ @entity1 = FactoryGirl.create(:user)
7
+ @entity2 = FactoryGirl.create(:user)
8
8
  @receipt1 = @entity1.send_message(@entity2,"Body","Subject")
9
9
  @receipt2 = @entity2.reply_to_all(@receipt1,"Reply body 1")
10
10
  @receipt3 = @entity1.reply_to_all(@receipt2,"Reply body 2")
@@ -13,37 +13,89 @@ describe Conversation do
13
13
  @message4 = @receipt4.notification
14
14
  @conversation = @message1.conversation
15
15
  end
16
-
16
+
17
17
  it "should have proper original message" do
18
18
  @conversation.original_message.should==@message1
19
19
  end
20
-
20
+
21
21
  it "should have proper originator (first sender)" do
22
22
  @conversation.originator.should==@entity1
23
23
  end
24
-
24
+
25
25
  it "should have proper last message" do
26
26
  @conversation.last_message.should==@message4
27
27
  end
28
-
28
+
29
29
  it "should have proper last sender" do
30
30
  @conversation.last_sender.should==@entity2
31
31
  end
32
-
33
- it "should have all conversation users" do
32
+
33
+ it "should have all conversation users" do
34
34
  @conversation.recipients.count.should==2
35
35
  @conversation.recipients.count.should==2
36
36
  @conversation.recipients.count(@entity1).should==1
37
37
  @conversation.recipients.count(@entity2).should==1
38
38
  end
39
-
40
- it "should be able to be marked as read" do
41
- @conversation.move_to_trash(@entity1)
39
+
40
+ it "should be able to be marked as read" do
41
+ #@conversation.move_to_trash(@entity1)
42
+ @conversation.mark_as_read(@entity1)
43
+ @conversation.should be_is_read(@entity)
42
44
  end
43
-
45
+
44
46
  it "should be able to be marked as unread" do
45
- @conversation.move_to_trash(@entity1)
46
- @conversation.untrash(@entity1)
47
+ @conversation.mark_as_read(@entity1)
48
+ @conversation.mark_as_unread(@entity1)
49
+ @conversation.should be_is_unread(@entity1)
50
+ end
51
+
52
+ describe "scopes" do
53
+ let(:participant) { FactoryGirl.create(:user) }
54
+ let!(:inbox_conversation) { @entity1.send_message(participant, "Body", "Subject").notification.conversation }
55
+ let!(:sentbox_conversation) { participant.send_message(@entity1, "Body", "Subject").notification.conversation }
56
+
57
+
58
+ describe ".participant" do
59
+ it "finds conversations with receipts for participant" do
60
+ Conversation.participant(participant).should == [sentbox_conversation, inbox_conversation]
61
+ end
62
+ end
63
+
64
+ describe ".inbox" do
65
+ it "finds inbox conversations with receipts for participant" do
66
+ Conversation.inbox(participant).should == [inbox_conversation]
67
+ end
68
+ end
69
+
70
+ describe ".sentbox" do
71
+ it "finds sentbox conversations with receipts for participant" do
72
+ Conversation.sentbox(participant).should == [sentbox_conversation]
73
+ end
74
+ end
75
+
76
+ describe ".trash" do
77
+ it "finds trash conversations with receipts for participant" do
78
+ trashed_conversation = @entity1.send_message(participant, "Body", "Subject").notification.conversation
79
+ trashed_conversation.move_to_trash(participant)
80
+
81
+ Conversation.trash(participant).should == [trashed_conversation]
82
+ end
83
+ end
84
+
85
+ describe ".unread" do
86
+ it "finds unread conversations with receipts for participant" do
87
+ [sentbox_conversation, inbox_conversation].each {|c| c.mark_as_read(participant) }
88
+ unread_conversation = @entity1.send_message(participant, "Body", "Subject").notification.conversation
89
+
90
+ Conversation.unread(participant).should == [unread_conversation]
91
+ end
92
+ end
93
+ end
94
+
95
+ describe "#is_completely_trashed?" do
96
+ it "returns true if all receipts in conversation are trashed for participant" do
97
+ @conversation.move_to_trash(@entity1)
98
+ @conversation.is_completely_trashed?(@entity1).should be_true
99
+ end
47
100
  end
48
-
49
101
  end
@@ -3,8 +3,8 @@ require 'spec_helper'
3
3
  describe Mailbox do
4
4
 
5
5
  before do
6
- @entity1 = Factory(:user)
7
- @entity2 = Factory(:user)
6
+ @entity1 = FactoryGirl.create(:user)
7
+ @entity2 = FactoryGirl.create(:user)
8
8
  @receipt1 = @entity1.send_message(@entity2,"Body","Subject")
9
9
  @receipt2 = @entity2.reply_to_all(@receipt1,"Reply body 1")
10
10
  @receipt3 = @entity1.reply_to_all(@receipt2,"Reply body 2")
@@ -67,6 +67,12 @@ describe Mailbox do
67
67
  @entity2.mailbox.receipts.inbox[0].should==Receipt.recipient(@entity2).inbox.conversation(@conversation)[0]
68
68
  @entity2.mailbox.receipts.inbox[1].should==Receipt.recipient(@entity2).inbox.conversation(@conversation)[1]
69
69
  end
70
+
71
+ it "should understand the read option" do
72
+ @entity1.mailbox.inbox({:read => false}).count.should_not == 0
73
+ @conversation.mark_as_read(@entity1)
74
+ @entity1.mailbox.inbox({:read => false}).count.should == 0
75
+ end
70
76
 
71
77
  it "should return trashed mails" do
72
78
  @entity1.mailbox.receipts.move_to_trash
@@ -3,8 +3,8 @@ require 'spec_helper'
3
3
  describe "Mailboxer::Models::Messageable through User" do
4
4
 
5
5
  before do
6
- @entity1 = Factory(:user)
7
- @entity2 = Factory(:user)
6
+ @entity1 = FactoryGirl.create(:user)
7
+ @entity2 = FactoryGirl.create(:user)
8
8
  end
9
9
 
10
10
  it "should have a mailbox" do
@@ -3,8 +3,8 @@ require 'spec_helper'
3
3
  describe Message do
4
4
 
5
5
  before do
6
- @entity1 = Factory(:user)
7
- @entity2 = Factory(:user)
6
+ @entity1 = FactoryGirl.create(:user)
7
+ @entity2 = FactoryGirl.create(:user)
8
8
  @receipt1 = @entity1.send_message(@entity2,"Body","Subject")
9
9
  @receipt2 = @entity2.reply_to_all(@receipt1,"Reply body 1")
10
10
  @receipt3 = @entity1.reply_to_all(@receipt2,"Reply body 2")
@@ -3,9 +3,9 @@ require 'spec_helper'
3
3
  describe Message do
4
4
 
5
5
  before do
6
- @entity1 = Factory(:user)
7
- @entity2 = Factory(:user)
8
- @entity3 = Factory(:user)
6
+ @entity1 = FactoryGirl.create(:user)
7
+ @entity2 = FactoryGirl.create(:user)
8
+ @entity3 = FactoryGirl.create(:user)
9
9
  end
10
10
 
11
11
  it "should notify one user" do
@@ -24,6 +24,21 @@ describe Message do
24
24
  notification.subject.should=="Subject"
25
25
  notification.body.should=="Body"
26
26
  end
27
+
28
+ it "should be unread by default" do
29
+ @entity1.notify("Subject", "Body")
30
+ @entity1.mailbox.receipts.size.should==1
31
+ notification = @entity1.mailbox.receipts.first.notification
32
+ notification.should be_is_unread(@entity1)
33
+ end
34
+
35
+ it "should be able to marked as read" do
36
+ @entity1.notify("Subject", "Body")
37
+ @entity1.mailbox.receipts.size.should==1
38
+ notification = @entity1.mailbox.receipts.first.notification
39
+ notification.mark_as_read(@entity1)
40
+ notification.should be_is_read(@entity1)
41
+ end
27
42
 
28
43
  it "should notify several users" do
29
44
  Notification.notify_all([@entity1,@entity2,@entity3],"Subject","Body")
@@ -60,5 +75,5 @@ describe Message do
60
75
  notification.body.should=="Body"
61
76
 
62
77
  end
63
-
78
+
64
79
  end
@@ -3,8 +3,8 @@ require 'spec_helper'
3
3
  describe Receipt do
4
4
 
5
5
  before do
6
- @entity1 = Factory(:user)
7
- @entity2 = Factory(:user)
6
+ @entity1 = FactoryGirl.create(:user)
7
+ @entity2 = FactoryGirl.create(:user)
8
8
  @mail1 = @entity1.send_message(@entity2,"Body","Subject")
9
9
  end
10
10
 
metadata CHANGED
@@ -1,115 +1,173 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: mailboxer
3
- version: !ruby/object:Gem::Version
4
- version: 0.6.5
3
+ version: !ruby/object:Gem::Version
4
+ hash: 3
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 7
9
+ - 0
10
+ version: 0.7.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Eduardo Casanova Cuesta
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-03-22 00:00:00.000000000Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2012-06-18 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: foreigner
16
- requirement: &74888040 !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
17
24
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 57
29
+ segments:
30
+ - 0
31
+ - 9
32
+ - 1
21
33
  version: 0.9.1
22
34
  type: :runtime
23
- prerelease: false
24
- version_requirements: *74888040
25
- - !ruby/object:Gem::Dependency
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
26
37
  name: rails
27
- requirement: &74877970 !ruby/object:Gem::Requirement
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
28
40
  none: false
29
- requirements:
30
- - - ! '>'
31
- - !ruby/object:Gem::Version
41
+ requirements:
42
+ - - ">"
43
+ - !ruby/object:Gem::Version
44
+ hash: 7
45
+ segments:
46
+ - 3
47
+ - 0
48
+ - 0
32
49
  version: 3.0.0
33
50
  type: :runtime
34
- prerelease: false
35
- version_requirements: *74877970
36
- - !ruby/object:Gem::Dependency
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
37
53
  name: carrierwave
38
- requirement: &74876920 !ruby/object:Gem::Requirement
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
39
56
  none: false
40
- requirements:
41
- - - ! '>='
42
- - !ruby/object:Gem::Version
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 27
61
+ segments:
62
+ - 0
63
+ - 5
64
+ - 8
43
65
  version: 0.5.8
44
66
  type: :runtime
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ name: ruby-debug
45
70
  prerelease: false
46
- version_requirements: *74876920
47
- - !ruby/object:Gem::Dependency
71
+ requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 49
77
+ segments:
78
+ - 0
79
+ - 10
80
+ - 3
81
+ version: 0.10.3
82
+ type: :development
83
+ version_requirements: *id004
84
+ - !ruby/object:Gem::Dependency
48
85
  name: rspec-rails
49
- requirement: &74875050 !ruby/object:Gem::Requirement
86
+ prerelease: false
87
+ requirement: &id005 !ruby/object:Gem::Requirement
50
88
  none: false
51
- requirements:
52
- - - ! '>='
53
- - !ruby/object:Gem::Version
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 21
93
+ segments:
94
+ - 2
95
+ - 6
96
+ - 1
54
97
  version: 2.6.1
55
98
  type: :development
56
- prerelease: false
57
- version_requirements: *74875050
58
- - !ruby/object:Gem::Dependency
99
+ version_requirements: *id005
100
+ - !ruby/object:Gem::Dependency
59
101
  name: factory_girl
60
- requirement: &74862190 !ruby/object:Gem::Requirement
102
+ prerelease: false
103
+ requirement: &id006 !ruby/object:Gem::Requirement
61
104
  none: false
62
- requirements:
63
- - - ! '>='
64
- - !ruby/object:Gem::Version
105
+ requirements:
106
+ - - ~>
107
+ - !ruby/object:Gem::Version
108
+ hash: 23
109
+ segments:
110
+ - 2
111
+ - 6
112
+ - 0
65
113
  version: 2.6.0
66
114
  type: :development
67
- prerelease: false
68
- version_requirements: *74862190
69
- - !ruby/object:Gem::Dependency
115
+ version_requirements: *id006
116
+ - !ruby/object:Gem::Dependency
70
117
  name: forgery
71
- requirement: &74857660 !ruby/object:Gem::Requirement
118
+ prerelease: false
119
+ requirement: &id007 !ruby/object:Gem::Requirement
72
120
  none: false
73
- requirements:
74
- - - ! '>='
75
- - !ruby/object:Gem::Version
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ hash: 31
125
+ segments:
126
+ - 0
127
+ - 3
128
+ - 6
76
129
  version: 0.3.6
77
130
  type: :development
78
- prerelease: false
79
- version_requirements: *74857660
80
- - !ruby/object:Gem::Dependency
131
+ version_requirements: *id007
132
+ - !ruby/object:Gem::Dependency
81
133
  name: capybara
82
- requirement: &74856860 !ruby/object:Gem::Requirement
134
+ prerelease: false
135
+ requirement: &id008 !ruby/object:Gem::Requirement
83
136
  none: false
84
- requirements:
85
- - - ! '>='
86
- - !ruby/object:Gem::Version
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ hash: 1
141
+ segments:
142
+ - 0
143
+ - 3
144
+ - 9
87
145
  version: 0.3.9
88
146
  type: :development
89
- prerelease: false
90
- version_requirements: *74856860
91
- - !ruby/object:Gem::Dependency
147
+ version_requirements: *id008
148
+ - !ruby/object:Gem::Dependency
92
149
  name: sqlite3-ruby
93
- requirement: &74849270 !ruby/object:Gem::Requirement
150
+ prerelease: false
151
+ requirement: &id009 !ruby/object:Gem::Requirement
94
152
  none: false
95
- requirements:
96
- - - ! '>='
97
- - !ruby/object:Gem::Version
98
- version: '0'
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ hash: 3
157
+ segments:
158
+ - 0
159
+ version: "0"
99
160
  type: :development
100
- prerelease: false
101
- version_requirements: *74849270
102
- description: A Rails engine that allows any model to act as messageable, adding the
103
- ability to exchange messages with any other messageable model, even different ones.
104
- It supports the use of conversations with two or more recipients to organize the
105
- messages. You have a complete use of a mailbox object for each messageable model
106
- that manages an inbox, sentbox and trash for conversations. It also supports sending
107
- notifications to messageable models, intended to be used as system notifications.
161
+ version_requirements: *id009
162
+ description: A Rails engine that allows any model to act as messageable, adding the ability to exchange messages with any other messageable model, even different ones. It supports the use of conversations with two or more recipients to organize the messages. You have a complete use of a mailbox object for each messageable model that manages an inbox, sentbox and trash for conversations. It also supports sending notifications to messageable models, intended to be used as system notifications.
108
163
  email: ecasanovac@gmail.com
109
164
  executables: []
165
+
110
166
  extensions: []
167
+
111
168
  extra_rdoc_files: []
112
- files:
169
+
170
+ files:
113
171
  - .gitignore
114
172
  - .rspec
115
173
  - .travis.yml
@@ -141,6 +199,7 @@ files:
141
199
  - lib/generators/mailboxer/templates/initializer.rb
142
200
  - lib/generators/mailboxer/views_generator.rb
143
201
  - lib/mailboxer.rb
202
+ - lib/mailboxer/concerns/configurable_mailer.rb
144
203
  - lib/mailboxer/engine.rb
145
204
  - lib/mailboxer/models/messageable.rb
146
205
  - mailboxer.gemspec
@@ -195,6 +254,7 @@ files:
195
254
  - spec/factories/user.rb
196
255
  - spec/integration/message_and_receipt_spec.rb
197
256
  - spec/integration/navigation_spec.rb
257
+ - spec/mailboxer/concerns/configurable_mailer_spec.rb
198
258
  - spec/mailboxer_spec.rb
199
259
  - spec/mailers/message_mailer_spec.rb
200
260
  - spec/mailers/notification_mailer_spec.rb
@@ -208,27 +268,36 @@ files:
208
268
  - spec/testfile.txt
209
269
  homepage: https://github.com/ging/mailboxer
210
270
  licenses: []
271
+
211
272
  post_install_message:
212
273
  rdoc_options: []
213
- require_paths:
274
+
275
+ require_paths:
214
276
  - lib
215
- required_ruby_version: !ruby/object:Gem::Requirement
277
+ required_ruby_version: !ruby/object:Gem::Requirement
216
278
  none: false
217
- requirements:
218
- - - ! '>='
219
- - !ruby/object:Gem::Version
220
- version: '0'
221
- required_rubygems_version: !ruby/object:Gem::Requirement
279
+ requirements:
280
+ - - ">="
281
+ - !ruby/object:Gem::Version
282
+ hash: 3
283
+ segments:
284
+ - 0
285
+ version: "0"
286
+ required_rubygems_version: !ruby/object:Gem::Requirement
222
287
  none: false
223
- requirements:
224
- - - ! '>='
225
- - !ruby/object:Gem::Version
226
- version: '0'
288
+ requirements:
289
+ - - ">="
290
+ - !ruby/object:Gem::Version
291
+ hash: 3
292
+ segments:
293
+ - 0
294
+ version: "0"
227
295
  requirements: []
296
+
228
297
  rubyforge_project:
229
- rubygems_version: 1.8.12
298
+ rubygems_version: 1.8.10
230
299
  signing_key:
231
300
  specification_version: 3
232
301
  summary: Messaging system for rails apps.
233
302
  test_files: []
234
- has_rdoc:
303
+