mailboxer 0.13.0 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +10 -13
  3. data/Appraisals +2 -10
  4. data/README.md +40 -41
  5. data/app/builders/mailboxer/message_builder.rb +0 -8
  6. data/app/mailers/mailboxer/notification_mailer.rb +1 -1
  7. data/app/models/mailboxer/conversation.rb +15 -8
  8. data/app/models/mailboxer/mailbox.rb +5 -0
  9. data/app/models/mailboxer/message.rb +10 -9
  10. data/app/models/mailboxer/notification.rb +12 -21
  11. data/app/models/mailboxer/receipt.rb +3 -14
  12. data/app/views/mailboxer/notification_mailer/new_notification_email.text.erb +1 -1
  13. data/db/migrate/20110511145103_create_mailboxer.rb +25 -26
  14. data/db/migrate/20151103080417_add_delivery_tracking_info_to_mailboxer_receipts.rb +7 -0
  15. data/gemfiles/{rails4.0.gemfile → rails5.0.gemfile} +2 -2
  16. data/lib/generators/mailboxer/install_generator.rb +4 -15
  17. data/lib/generators/mailboxer/templates/initializer.rb +1 -1
  18. data/lib/generators/mailboxer/templates/mailboxer_namespacing_compatibility.rb +0 -10
  19. data/lib/mailboxer.rb +2 -3
  20. data/lib/mailboxer/engine.rb +0 -2
  21. data/lib/mailboxer/mail_dispatcher.rb +20 -24
  22. data/lib/mailboxer/models/messageable.rb +1 -6
  23. data/lib/mailboxer/recipient_filter.rb +17 -0
  24. data/lib/mailboxer/version.rb +1 -1
  25. data/mailboxer.gemspec +2 -10
  26. data/spec/dummy/config/application.rb +0 -5
  27. data/spec/dummy/db/migrate/20151103202534_add_missing_indices.mailboxer_engine.rb +20 -0
  28. data/spec/dummy/db/migrate/20151103202535_add_delivery_tracking_info_to_mailboxer_receipts.mailboxer_engine.rb +8 -0
  29. data/spec/mailboxer/mail_dispatcher_spec.rb +15 -38
  30. data/spec/mailboxer/recipient_filter_spec.rb +26 -0
  31. data/spec/mailers/message_mailer_spec.rb +0 -30
  32. data/spec/models/conversation_spec.rb +12 -1
  33. data/spec/models/mailbox_spec.rb +6 -0
  34. data/spec/models/message_spec.rb +53 -17
  35. data/spec/models/notification_spec.rb +2 -3
  36. data/spec/spec_helper.rb +8 -0
  37. metadata +15 -26
  38. data/gemfiles/rails3.2.gemfile +0 -7
  39. data/gemfiles/rails4.1.gemfile +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 76560ca95f622b27cb610d4e333f5f07da0145f0
4
- data.tar.gz: 5865f0a7a71a57403bc459cae32aba44b2a3ca4e
3
+ metadata.gz: 20ef2352a667a4efe2b58ba03e9e0ec71be8c6f5
4
+ data.tar.gz: 62b56eef4d08c04fffea2050d547ea65331cd8d9
5
5
  SHA512:
6
- metadata.gz: 39519d696f2bc2240d62c3e79738d195148d817cf105cf47a75a74d717c70c58823787bd3c9e0fe6f16977ab731ee858524535b22a5f5755ad5b033d3ad53dd8
7
- data.tar.gz: 87c71b2d1e53a05dc3d27842b7dd25577610d28e1016dc3b61e2d190f653e0fcb5bd25cb613e83c6a71df92eb20a66a78759ecb89251db76378ed81d6620f187
6
+ metadata.gz: 1aa5bbfb3de37857cbccfee7e010f73d9bc92b03e6b221e5bbf4210af8e5fa599b9227bd4f922752d6f19342f846f328e5a3cb08b319bf818f07ba773b615ce8
7
+ data.tar.gz: 5d6dc14ece4e486dce7ff21afb63ee2d562092e29792cad1dc74fb91135f69c564853b8e939efb9702a305d5f49c168eb57e615830678bb173f45983bb86be74
@@ -3,22 +3,19 @@ cache: bundler
3
3
  sudo: false
4
4
 
5
5
  rvm:
6
- - 2.1.4
7
-
8
- matrix:
9
- include:
10
- - rvm: 1.9.3
11
- gemfile: gemfiles/rails4.1.gemfile
12
- - rvm: 2.0
13
- gemfile: gemfiles/rails4.1.gemfile
14
- - rvm: jruby-19mode
15
- gemfile: gemfiles/rails4.1.gemfile
6
+ - 2.1.10
7
+ - 2.2.5
8
+ - 2.3.1
16
9
 
17
10
  gemfile:
18
- - gemfiles/rails3.2.gemfile
19
- - gemfiles/rails4.0.gemfile
20
- - gemfiles/rails4.1.gemfile
21
11
  - gemfiles/rails4.2.gemfile
12
+ - gemfiles/rails5.0.gemfile
13
+
14
+ matrix:
15
+ exclude:
16
+ - rvm: 2.1.10
17
+ gemfile: gemfiles/rails5.0.gemfile
18
+
22
19
  env:
23
20
  global:
24
21
  - NOKOGIRI_USE_SYSTEM_LIBRARIES=true
data/Appraisals CHANGED
@@ -1,11 +1,3 @@
1
- appraise "rails3.2" do
2
- gem "rails", "~> 3.2.17"
3
- end
4
-
5
- appraise "rails4.0" do
6
- gem "rails", "~> 4.0.4"
7
- end
8
-
9
- appraise "rails4.1" do
10
- gem "rails", "~> 4.1.0"
1
+ appraise "rails4.2" do
2
+ gem "rails", "~> 4.2.6"
11
3
  end
data/README.md CHANGED
@@ -188,7 +188,29 @@ Version 0.8.0 sees `Messageable#read` and `Messageable#unread` renamed to `mark_
188
188
  alfa.send_message(beta, "Body", "subject")
189
189
  ```
190
190
 
191
- ### How can I reply a message?
191
+ ### How can I read the messages of a conversation?
192
+
193
+ As a messageable, what you receive are receipts, which are associated with the message itself. You should retrieve your receipts for the conversation and get the message associated with them.
194
+
195
+ This is done this way because receipts save the information about the relation between messageable and the messages: is it read?, is it trashed?, etc.
196
+
197
+ ```ruby
198
+ #alfa gets the last conversation (chronologically, the first in the inbox)
199
+ conversation = alfa.mailbox.inbox.first
200
+
201
+ #alfa gets it receipts chronologically ordered.
202
+ receipts = conversation.receipts_for alfa
203
+
204
+ #using the receipts (i.e. in the view)
205
+ receipts.each do |receipt|
206
+ ...
207
+ message = receipt.message
208
+ read = receipt.is_unread? #or message.is_unread?(alfa)
209
+ ...
210
+ end
211
+ ```
212
+
213
+ ### How can I reply to a message?
192
214
 
193
215
  ```ruby
194
216
  #alfa wants to reply to all in a conversation
@@ -205,22 +227,6 @@ alfa.reply_to_conversation(conversation, "Reply body")
205
227
  alfa.reply_to_sender(receipt, "Reply body")
206
228
  ```
207
229
 
208
- ### How can I retrieve my conversations?
209
-
210
- ```ruby
211
- #alfa wants to retrieve all his conversations
212
- alfa.mailbox.conversations
213
-
214
- #A wants to retrieve his inbox
215
- alfa.mailbox.inbox
216
-
217
- #A wants to retrieve his sent conversations
218
- alfa.mailbox.sentbox
219
-
220
- #alfa wants to retrieve his trashed conversations
221
- alfa.mailbox.trash
222
- ```
223
-
224
230
  ### How can I delete a message from trash?
225
231
 
226
232
  ```ruby
@@ -239,10 +245,25 @@ conversation.mark_as_deleted participant
239
245
  #* An array with any of them
240
246
  alfa.mark_as_deleted conversation
241
247
  ```
248
+ ### How can I retrieve my conversations?
249
+
250
+ ```ruby
251
+ #alfa wants to retrieve all his conversations
252
+ alfa.mailbox.conversations
253
+
254
+ #A wants to retrieve his inbox
255
+ alfa.mailbox.inbox
256
+
257
+ #A wants to retrieve his sent conversations
258
+ alfa.mailbox.sentbox
259
+
260
+ #alfa wants to retrieve his trashed conversations
261
+ alfa.mailbox.trash
262
+ ```
242
263
 
243
264
  ### How can I paginate conversations?
244
265
 
245
- You can use Kaminari to paginate the conversations as normal. Please, make sure you use the last version as mailboxer uses `select('DISTINCT conversations.*')` which was not respected before Kaminari 0.12.4 according to its changelog. Working corretly on Kaminari 0.13.0.
266
+ You can use Kaminari to paginate the conversations as normal. Please, make sure you use the last version as mailboxer uses `select('DISTINCT conversations.*')` which was not respected before Kaminari 0.12.4 according to its changelog. Working correctly on Kaminari 0.13.0.
246
267
 
247
268
  ```ruby
248
269
  #Paginating all conversations using :page parameter and 9 per page
@@ -258,28 +279,6 @@ conversations = alfa.mailbox.sentbox.page(params[:page]).per(9)
258
279
  conversations = alfa.mailbox.trash.page(params[:page]).per(9)
259
280
  ```
260
281
 
261
- ### How can I read the messages of a conversation?
262
-
263
- As a messageable, what you receive are receipts, which are associated with the message itself. You should retrieve your receipts for the conversation a get the message associated with them.
264
-
265
- This is done this way because receipts save the information about the relation between messageable and the messages: is it read?, is it trashed?, etc.
266
-
267
- ```ruby
268
- #alfa gets the last conversation (chronologically, the first in the inbox)
269
- conversation = alfa.mailbox.inbox.first
270
-
271
- #alfa gets it receipts chronologically ordered.
272
- receipts = conversation.receipts_for alfa
273
-
274
- #using the receipts (i.e. in the view)
275
- receipts.each do |receipt|
276
- ...
277
- message = receipt.message
278
- read = receipt.is_unread? #or message.is_unread?(alfa)
279
- ...
280
- end
281
- ```
282
-
283
282
  You can take a look at the full documentation for Mailboxer in [rubydoc.info](http://rubydoc.info/gems/mailboxer/frames).
284
283
 
285
284
  ## Do you want to test Mailboxer?
@@ -288,7 +287,7 @@ Thanks to [Roman Kushnir (@RKushnir)](https://github.com/RKushnir/) you can test
288
287
 
289
288
  ## I need a GUI!
290
289
 
291
- If you need a GUI you should take a look a these links:
290
+ If you need a GUI you should take a look at these links:
292
291
 
293
292
  * The [rails-messaging](https://github.com/frodefi/rails-messaging) project.
294
293
  * The wiki page [GUI Example on a real application](https://github.com/ging/mailboxer/wiki/GUI-Example-on-a-real-application).
@@ -5,12 +5,4 @@ class Mailboxer::MessageBuilder < Mailboxer::BaseBuilder
5
5
  def klass
6
6
  Mailboxer::Message
7
7
  end
8
-
9
- def subject
10
- params[:subject] || default_subject
11
- end
12
-
13
- def default_subject
14
- "#{params[:conversation].subject}"
15
- end
16
8
  end
@@ -1,5 +1,5 @@
1
1
  class Mailboxer::NotificationMailer < Mailboxer::BaseMailer
2
- #Sends and email for indicating a new notification to a receiver.
2
+ #Sends an email for indicating a new notification to a receiver.
3
3
  #It calls new_notification_email.
4
4
  def send_email(notification, receiver)
5
5
  new_notification_email(notification, receiver)
@@ -14,8 +14,8 @@ class Mailboxer::Conversation < ActiveRecord::Base
14
14
 
15
15
  scope :participant, lambda {|participant|
16
16
  where('mailboxer_notifications.type'=> Mailboxer::Message.name).
17
- order("mailboxer_conversations.updated_at DESC").
18
- joins(:receipts).merge(Mailboxer::Receipt.recipient(participant)).uniq
17
+ order(updated_at: :desc).
18
+ joins(:receipts).merge(Mailboxer::Receipt.recipient(participant)).distinct
19
19
  }
20
20
  scope :inbox, lambda {|participant|
21
21
  participant(participant).merge(Mailboxer::Receipt.inbox.not_trash.not_deleted)
@@ -32,6 +32,13 @@ class Mailboxer::Conversation < ActiveRecord::Base
32
32
  scope :not_trash, lambda {|participant|
33
33
  participant(participant).merge(Mailboxer::Receipt.not_trash)
34
34
  }
35
+ scope :between, lambda {|participant_one, participant_two|
36
+ joins("INNER JOIN (#{Mailboxer::Notification.recipient(participant_two).to_sql}) participant_two_notifications " \
37
+ "ON participant_two_notifications.conversation_id = #{table_name}.id AND participant_two_notifications.type IN ('Mailboxer::Message')").
38
+ joins("INNER JOIN mailboxer_receipts ON mailboxer_receipts.notification_id = participant_two_notifications.id").
39
+ merge(Mailboxer::Receipt.recipient(participant_one)).
40
+ order(updated_at: :desc).distinct
41
+ }
35
42
 
36
43
  #Mark the conversation as read for one of the participants
37
44
  def mark_as_read(participant)
@@ -115,17 +122,17 @@ class Mailboxer::Conversation < ActiveRecord::Base
115
122
  receipts_for(participant).any?
116
123
  end
117
124
 
118
- #Adds a new participant to the conversation
119
- def add_participant(participant)
120
- messages.each do |message|
125
+ #Adds a new participant to the conversation
126
+ def add_participant(participant)
127
+ messages.each do |message|
121
128
  Mailboxer::ReceiptBuilder.new({
122
129
  :notification => message,
123
130
  :receiver => participant,
124
131
  :updated_at => message.updated_at,
125
132
  :created_at => message.created_at
126
133
  }).build.save
127
- end
128
- end
134
+ end
135
+ end
129
136
 
130
137
  #Returns true if the participant has at least one trashed message of the conversation
131
138
  def is_trashed?(participant)
@@ -163,7 +170,7 @@ class Mailboxer::Conversation < ActiveRecord::Base
163
170
  end
164
171
 
165
172
  # Creates a opt out object
166
- # because by default all particpants are opt in
173
+ # because by default all participants are opt in
167
174
  def opt_out(participant)
168
175
  return unless has_subscriber?(participant)
169
176
  opt_outs.create(:unsubscriber => participant)
@@ -17,6 +17,11 @@ class Mailboxer::Mailbox
17
17
  notifs
18
18
  end
19
19
 
20
+ #Returns the conversations between messageable and other messageable
21
+ def conversations_with(other_messageable)
22
+ Mailboxer::Conversation.between(messageable, other_messageable)
23
+ end
24
+
20
25
  #Returns the conversations for the messageable
21
26
  #
22
27
  #Options
@@ -2,7 +2,7 @@ class Mailboxer::Message < Mailboxer::Notification
2
2
  attr_accessible :attachment if Mailboxer.protected_attributes?
3
3
  self.table_name = :mailboxer_notifications
4
4
 
5
- belongs_to :conversation, :class_name => "Mailboxer::Conversation", :validate => true, :autosave => true
5
+ belongs_to :conversation, :validate => true, :autosave => true
6
6
  validates_presence_of :sender
7
7
 
8
8
  class_attribute :on_deliver_callback
@@ -11,7 +11,7 @@ class Mailboxer::Message < Mailboxer::Notification
11
11
  where(:conversation_id => conversation.id)
12
12
  }
13
13
 
14
- mount_uploader :attachment, AttachmentUploader
14
+ mount_uploader :attachment, Mailboxer::AttachmentUploader
15
15
 
16
16
  class << self
17
17
  #Sets the on deliver callback method.
@@ -26,16 +26,17 @@ class Mailboxer::Message < Mailboxer::Notification
26
26
  self.clean if should_clean
27
27
 
28
28
  #Receiver receipts
29
- temp_receipts = recipients.map { |r| build_receipt(r, 'inbox') }
29
+ receiver_receipts = recipients.map do |r|
30
+ receipts.build(receiver: r, mailbox_type: 'inbox', is_read: false)
31
+ end
30
32
 
31
33
  #Sender receipt
32
- sender_receipt = build_receipt(sender, 'sentbox', true)
33
-
34
- temp_receipts << sender_receipt
34
+ sender_receipt =
35
+ receipts.build(receiver: sender, mailbox_type: 'sentbox', is_read: true)
35
36
 
36
- if temp_receipts.all?(&:valid?)
37
- temp_receipts.each(&:save!)
38
- Mailboxer::MailDispatcher.new(self, recipients).call
37
+ if valid?
38
+ save!
39
+ Mailboxer::MailDispatcher.new(self, receiver_receipts).call
39
40
 
40
41
  conversation.touch if reply
41
42
 
@@ -4,12 +4,11 @@ class Mailboxer::Notification < ActiveRecord::Base
4
4
  attr_accessor :recipients
5
5
  attr_accessible :body, :subject, :global, :expires if Mailboxer.protected_attributes?
6
6
 
7
- belongs_to :sender, :polymorphic => :true
8
- belongs_to :notified_object, :polymorphic => :true
7
+ belongs_to :sender, :polymorphic => :true, :required => false
8
+ belongs_to :notified_object, :polymorphic => :true, :required => false
9
9
  has_many :receipts, :dependent => :destroy, :class_name => "Mailboxer::Receipt"
10
10
 
11
- validates :subject, :presence => true,
12
- :length => { :maximum => Mailboxer.subject_max_length }
11
+ validates :subject, :length => { :maximum => Mailboxer.subject_max_length }
13
12
  validates :body, :presence => true,
14
13
  :length => { :maximum => Mailboxer.body_max_length }
15
14
 
@@ -81,11 +80,14 @@ class Mailboxer::Notification < ActiveRecord::Base
81
80
  #Use Mailboxer::Models::Message.notify and Notification.notify_all instead.
82
81
  def deliver(should_clean = true, send_mail = true)
83
82
  clean if should_clean
84
- temp_receipts = recipients.map { |r| build_receipt(r, nil, false) }
83
+ temp_receipts = recipients.map do |r|
84
+ receipts.build(receiver: r, mailbox_type: nil, is_read: false)
85
+ end
86
+
87
+ if valid?
88
+ Mailboxer::MailDispatcher.new(self, temp_receipts).call if send_mail
89
+ save!
85
90
 
86
- if temp_receipts.all?(&:valid?)
87
- temp_receipts.each(&:save!) #Save receipts
88
- Mailboxer::MailDispatcher.new(self, recipients).call if send_mail
89
91
  self.recipients = nil
90
92
  end
91
93
 
@@ -96,7 +98,8 @@ class Mailboxer::Notification < ActiveRecord::Base
96
98
  #Returns the recipients of the Notification
97
99
  def recipients
98
100
  return Array.wrap(@recipients) unless @recipients.blank?
99
- @recipients = receipts.map { |receipt| receipt.receiver }
101
+ recipients = receipts.includes(:receiver).map(&:receiver)
102
+ @recipients = Mailboxer::RecipientFilter.new(self, recipients).call
100
103
  end
101
104
 
102
105
  #Returns the receipt for the participant
@@ -176,16 +179,4 @@ class Mailboxer::Notification < ActiveRecord::Base
176
179
  def sanitize(text)
177
180
  ::Mailboxer::Cleaner.instance.sanitize(text)
178
181
  end
179
-
180
- private
181
-
182
- def build_receipt(receiver, mailbox_type, is_read = false)
183
- Mailboxer::ReceiptBuilder.new({
184
- :notification => self,
185
- :mailbox_type => mailbox_type,
186
- :receiver => receiver,
187
- :is_read => is_read
188
- }).build
189
- end
190
-
191
182
  end
@@ -2,9 +2,9 @@ class Mailboxer::Receipt < ActiveRecord::Base
2
2
  self.table_name = :mailboxer_receipts
3
3
  attr_accessible :trashed, :is_read, :deleted if Mailboxer.protected_attributes?
4
4
 
5
- belongs_to :notification, :class_name => "Mailboxer::Notification", :validate => true, :autosave => true
6
- belongs_to :receiver, :polymorphic => :true
7
- belongs_to :message, :class_name => "Mailboxer::Message", :foreign_key => "notification_id"
5
+ belongs_to :notification, :class_name => "Mailboxer::Notification"
6
+ belongs_to :receiver, :polymorphic => :true, :required => false
7
+ belongs_to :message, :class_name => "Mailboxer::Message", :foreign_key => "notification_id", :required => false
8
8
 
9
9
  validates_presence_of :receiver
10
10
 
@@ -30,7 +30,6 @@ class Mailboxer::Receipt < ActiveRecord::Base
30
30
  scope :is_read, lambda { where(:is_read => true) }
31
31
  scope :is_unread, lambda { where(:is_read => false) }
32
32
 
33
- after_validation :remove_duplicate_errors
34
33
  class << self
35
34
  #Marks all the receipts from the relation as read
36
35
  def mark_as_read(options={})
@@ -140,16 +139,6 @@ class Mailboxer::Receipt < ActiveRecord::Base
140
139
 
141
140
  protected
142
141
 
143
- #Removes the duplicate error about not present subject from Conversation if it has been already
144
- #raised by Message
145
- def remove_duplicate_errors
146
- if errors["mailboxer_notification.conversation.subject"].present? and errors["mailboxer_notification.subject"].present?
147
- errors["mailboxer_notification.conversation.subject"].each do |msg|
148
- errors["mailboxer_notification.conversation.subject"].delete(msg)
149
- end
150
- end
151
- end
152
-
153
142
  if Mailboxer.search_enabled
154
143
  searchable do
155
144
  text :subject, :boost => 5 do
@@ -1,6 +1,6 @@
1
1
  You have a new notification: <%= @notification.subject.html_safe? ? @notification.subject : strip_tags(@notification.subject) %>
2
2
  ===============================================
3
-
3
+
4
4
  You have received a new notification:
5
5
 
6
6
  -----------------------------------------------
@@ -1,13 +1,13 @@
1
1
  class CreateMailboxer < ActiveRecord::Migration
2
- def self.up
2
+ def self.up
3
3
  #Tables
4
- #Conversations
4
+ #Conversations
5
5
  create_table :mailboxer_conversations do |t|
6
6
  t.column :subject, :string, :default => ""
7
7
  t.column :created_at, :datetime, :null => false
8
8
  t.column :updated_at, :datetime, :null => false
9
- end
10
- #Receipts
9
+ end
10
+ #Receipts
11
11
  create_table :mailboxer_receipts do |t|
12
12
  t.references :receiver, :polymorphic => true
13
13
  t.column :notification_id, :integer, :null => false
@@ -17,8 +17,8 @@ class CreateMailboxer < ActiveRecord::Migration
17
17
  t.column :mailbox_type, :string, :limit => 25
18
18
  t.column :created_at, :datetime, :null => false
19
19
  t.column :updated_at, :datetime, :null => false
20
- end
21
- #Notifications and Messages
20
+ end
21
+ #Notifications and Messages
22
22
  create_table :mailboxer_notifications do |t|
23
23
  t.column :type, :string
24
24
  t.column :body, :text
@@ -33,30 +33,29 @@ class CreateMailboxer < ActiveRecord::Migration
33
33
  t.column :created_at, :datetime, :null => false
34
34
  t.boolean :global, default: false
35
35
  t.datetime :expires
36
- end
37
-
38
-
36
+ end
37
+
39
38
  #Indexes
40
- #Conversations
41
- #Receipts
42
- add_index "mailboxer_receipts","notification_id"
39
+ #Conversations
40
+ #Receipts
41
+ add_index "mailboxer_receipts","notification_id"
42
+
43
+ #Messages
44
+ add_index "mailboxer_notifications","conversation_id"
43
45
 
44
- #Messages
45
- add_index "mailboxer_notifications","conversation_id"
46
-
47
- #Foreign keys
48
- #Conversations
49
- #Receipts
50
- add_foreign_key "mailboxer_receipts", "mailboxer_notifications", :name => "receipts_on_notification_id", :column => "notification_id"
51
- #Messages
52
- add_foreign_key "mailboxer_notifications", "mailboxer_conversations", :name => "notifications_on_conversation_id", :column => "conversation_id"
46
+ #Foreign keys
47
+ #Conversations
48
+ #Receipts
49
+ add_foreign_key "mailboxer_receipts", "mailboxer_notifications", :name => "receipts_on_notification_id", :column => "notification_id"
50
+ #Messages
51
+ add_foreign_key "mailboxer_notifications", "mailboxer_conversations", :name => "notifications_on_conversation_id", :column => "conversation_id"
53
52
  end
54
-
53
+
55
54
  def self.down
56
- #Tables
57
- remove_foreign_key "mailboxer_receipts", :name => "receipts_on_notification_id"
58
- remove_foreign_key "mailboxer_notifications", :name => "notifications_on_conversation_id"
59
-
55
+ #Tables
56
+ remove_foreign_key "mailboxer_receipts", :name => "receipts_on_notification_id"
57
+ remove_foreign_key "mailboxer_notifications", :name => "notifications_on_conversation_id"
58
+
60
59
  #Indexes
61
60
  drop_table :mailboxer_receipts
62
61
  drop_table :mailboxer_conversations
@@ -0,0 +1,7 @@
1
+ class AddDeliveryTrackingInfoToMailboxerReceipts < ActiveRecord::Migration
2
+ def change
3
+ add_column :mailboxer_receipts, :is_delivered, :boolean, default: false
4
+ add_column :mailboxer_receipts, :delivery_method, :string
5
+ add_column :mailboxer_receipts, :message_id, :string
6
+ end
7
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 4.0.4"
5
+ gem "rails", "~> 5.0.0"
6
6
 
7
- gemspec :path => "../"
7
+ gemspec path: "../"
@@ -17,20 +17,9 @@ class Mailboxer::InstallGenerator < Rails::Generators::Base #:nodoc:
17
17
  end
18
18
 
19
19
  def copy_migrations
20
- if Rails.version < "3.1"
21
- migrations = [
22
- %w[20110511145103_create_mailboxer.rb create_mailboxer.rb],
23
- %w[20131206080416_add_conversation_optout.rb add_conversation_optout.rb],
24
- %w[20131206080417_add_missing_indices.rb add_missing_indices.rb]
25
- ],
26
- migrations.each do |migration|
27
- migration_template "../../../../db/migrate/" + migration[0], "db/migrate/" + migration[1]
28
- end
29
- else
30
- require 'rake'
31
- Rails.application.load_tasks
32
- Rake::Task['railties:install:migrations'].reenable
33
- Rake::Task['mailboxer_engine:install:migrations'].invoke
34
- end
20
+ require 'rake'
21
+ Rails.application.load_tasks
22
+ Rake::Task['railties:install:migrations'].reenable
23
+ Rake::Task['mailboxer_engine:install:migrations'].invoke
35
24
  end
36
25
  end
@@ -1,6 +1,6 @@
1
1
  Mailboxer.setup do |config|
2
2
 
3
- #Configures if you application uses or not email sending for Notifications and Messages
3
+ #Configures if your application uses or not email sending for Notifications and Messages
4
4
  config.uses_emails = true
5
5
 
6
6
  #Configures the default from for emails sent for Messages and Notifications
@@ -5,11 +5,6 @@ class MailboxerNamespacingCompatibility < ActiveRecord::Migration
5
5
  rename_table :notifications, :mailboxer_notifications
6
6
  rename_table :receipts, :mailboxer_receipts
7
7
 
8
- if Rails.version < '4'
9
- rename_index :mailboxer_notifications, :notifications_on_conversation_id, :mailboxer_notifications_on_conversation_id
10
- rename_index :mailboxer_receipts, :receipts_on_notification_id, :mailboxer_receipts_on_notification_id
11
- end
12
-
13
8
  Mailboxer::Notification.where(type: 'Message').update_all(type: 'Mailboxer::Message')
14
9
  end
15
10
 
@@ -18,11 +13,6 @@ class MailboxerNamespacingCompatibility < ActiveRecord::Migration
18
13
  rename_table :mailboxer_notifications, :notifications
19
14
  rename_table :mailboxer_receipts, :receipts
20
15
 
21
- if Rails.version < '4'
22
- rename_index :notifications, :mailboxer_notifications_on_conversation_id, :notifications_on_conversation_id
23
- rename_index :receipts, :mailboxer_receipts_on_notification_id, :receipts_on_notification_id
24
- end
25
-
26
16
  Mailboxer::Notification.where(type: 'Mailboxer::Message').update_all(type: 'Message')
27
17
  end
28
18
  end
@@ -7,8 +7,6 @@ module Mailboxer
7
7
  @@default_from = "no-reply@mailboxer.com"
8
8
  mattr_accessor :uses_emails
9
9
  @@uses_emails = true
10
- mattr_accessor :mailer_wants_array
11
- @@mailer_wants_array = false
12
10
  mattr_accessor :search_enabled
13
11
  @@search_enabled = false
14
12
  mattr_accessor :search_engine
@@ -31,7 +29,7 @@ module Mailboxer
31
29
  end
32
30
 
33
31
  def protected_attributes?
34
- Rails.version < '4' || defined?(ProtectedAttributes)
32
+ defined?(ProtectedAttributes)
35
33
  end
36
34
  end
37
35
 
@@ -41,3 +39,4 @@ end
41
39
  require 'mailboxer/engine'
42
40
  require 'mailboxer/cleaner'
43
41
  require 'mailboxer/mail_dispatcher'
42
+ require 'mailboxer/recipient_filter'
@@ -1,5 +1,3 @@
1
- # Database foreign keys
2
- require 'foreigner' if Rails.version < "4.2.0"
3
1
  require 'carrierwave'
4
2
  begin
5
3
  require 'sunspot_rails'
@@ -1,21 +1,17 @@
1
1
  module Mailboxer
2
2
  class MailDispatcher
3
+ attr_reader :mailable, :receipts
3
4
 
4
- attr_reader :mailable, :recipients
5
-
6
- def initialize(mailable, recipients)
7
- @mailable, @recipients = mailable, recipients
5
+ def initialize(mailable, receipts)
6
+ @mailable, @receipts = mailable, receipts
8
7
  end
9
8
 
10
9
  def call
11
10
  return false unless Mailboxer.uses_emails
12
- if Mailboxer.mailer_wants_array
13
- send_email(filtered_recipients)
14
- else
15
- filtered_recipients.each do |recipient|
16
- email_to = recipient.send(Mailboxer.email_method, mailable)
17
- send_email(recipient) if email_to.present?
18
- end
11
+
12
+ receipts.map do |receipt|
13
+ email_to = receipt.receiver.send(Mailboxer.email_method, mailable)
14
+ send_email(receipt) if email_to.present?
19
15
  end
20
16
  end
21
17
 
@@ -27,22 +23,22 @@ module Mailboxer
27
23
  Mailboxer.send(method) || "#{mailable.class}Mailer".constantize
28
24
  end
29
25
 
30
- # recipients can be filtered on a conversation basis
31
- def filtered_recipients
32
- return recipients unless mailable.respond_to?(:conversation)
33
-
34
- recipients.each_with_object([]) do |recipient, array|
35
- array << recipient if mailable.conversation.has_subscriber?(recipient)
36
- end
37
- end
38
-
39
- def send_email(recipient)
26
+ def send_email(receipt)
40
27
  if Mailboxer.custom_deliver_proc
41
- Mailboxer.custom_deliver_proc.call(mailer, mailable, recipient)
28
+ Mailboxer.custom_deliver_proc.call(mailer, mailable, receipt.receiver)
42
29
  else
43
- email = mailer.send_email(mailable, recipient)
44
- email.respond_to?(:deliver_now) ? email.deliver_now : email.deliver
30
+ default_send_email(receipt)
45
31
  end
46
32
  end
33
+
34
+ def default_send_email(receipt)
35
+ mail = mailer.send_email(mailable, receipt.receiver)
36
+ mail.respond_to?(:deliver_now) ? mail.deliver_now : mail.deliver
37
+ receipt.assign_attributes(
38
+ :delivery_method => :email,
39
+ :message_id => mail.message_id
40
+ )
41
+ mail
42
+ end
47
43
  end
48
44
  end
@@ -14,12 +14,7 @@ module Mailboxer
14
14
 
15
15
  included do
16
16
  has_many :messages, :class_name => "Mailboxer::Message", :as => :sender
17
- if Rails::VERSION::MAJOR == 4
18
- has_many :receipts, -> { order 'created_at DESC' }, :class_name => "Mailboxer::Receipt", dependent: :destroy, as: :receiver
19
- else
20
- # Rails 3 does it this way
21
- has_many :receipts, :order => 'created_at DESC', :class_name => "Mailboxer::Receipt", :dependent => :destroy, :as => :receiver
22
- end
17
+ has_many :receipts, -> { order 'created_at DESC' }, :class_name => "Mailboxer::Receipt", dependent: :destroy, as: :receiver
23
18
  end
24
19
 
25
20
  unless defined?(Mailboxer.name_method)
@@ -0,0 +1,17 @@
1
+ module Mailboxer
2
+ class RecipientFilter
3
+ attr_reader :mailable, :recipients
4
+ def initialize(mailable, recipients)
5
+ @mailable, @recipients = mailable, recipients
6
+ end
7
+
8
+ # recipients can be filtered on a conversation basis
9
+ def call
10
+ return recipients unless mailable.respond_to?(:conversation)
11
+
12
+ recipients.each_with_object([]) do |recipient, array|
13
+ array << recipient if mailable.conversation.has_subscriber?(recipient)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module Mailboxer
2
- VERSION = "0.13.0"
2
+ VERSION = "0.14.0"
3
3
  end
@@ -20,11 +20,9 @@ Gem::Specification.new do |s|
20
20
 
21
21
  # Gem dependencies
22
22
  #
23
- # SQL foreign keys
24
- s.add_runtime_dependency('foreigner', '>= 0.9.1')
25
23
 
26
24
  # Development Gem dependencies
27
- s.add_runtime_dependency('rails', '>= 3.2.0')
25
+ s.add_runtime_dependency('rails', '>= 4.2.0')
28
26
  s.add_runtime_dependency('carrierwave', '>= 0.5.8')
29
27
 
30
28
  if RUBY_ENGINE == "rbx" && RUBY_VERSION >= "2.1.0"
@@ -37,13 +35,7 @@ Gem::Specification.new do |s|
37
35
  s.add_development_dependency 'rspec-its', '~> 1.1'
38
36
  s.add_development_dependency 'rspec-collection_matchers', '~> 1.1'
39
37
  s.add_development_dependency('appraisal', '~> 1.0.0')
40
- s.add_development_dependency('shoulda-matchers')
41
- # Fixtures
42
- #if RUBY_VERSION >= '1.9.2'
43
- # s.add_development_dependency('factory_girl', '>= 3.0.0')
44
- #else
45
- #s.add_development_dependency('factory_girl', '~> 2.6.0')
46
- #end
38
+ s.add_development_dependency('shoulda-matchers', '~> 2')
47
39
  s.add_development_dependency('factory_girl', '~> 2.6.0')
48
40
  # Population
49
41
  s.add_development_dependency('forgery', '>= 0.3.6')
@@ -7,9 +7,6 @@ require "mailboxer"
7
7
 
8
8
  module Dummy
9
9
  class Application < Rails::Application
10
- def rails_more_than_4_2?
11
- Gem::Version.new(Rails.version) >= Gem::Version.new('4.2.0')
12
- end
13
10
  # Settings in config/environments/* take precedence over those specified here.
14
11
  # Application configuration should go into files in config/initializers
15
12
  # -- all .rb files in that directory are automatically loaded.
@@ -40,8 +37,6 @@ module Dummy
40
37
 
41
38
  # Configure sensitive parameters which will be filtered from the log file.
42
39
  config.filter_parameters += [:password]
43
- config.active_record.raise_in_transactional_callbacks = true if rails_more_than_4_2?
44
-
45
40
  end
46
41
  end
47
42
 
@@ -0,0 +1,20 @@
1
+ # This migration comes from mailboxer_engine (originally 20131206080417)
2
+ class AddMissingIndices < ActiveRecord::Migration
3
+ def change
4
+ # We'll explicitly specify its name, as the auto-generated name is too long and exceeds 63
5
+ # characters limitation.
6
+ add_index :mailboxer_conversation_opt_outs, [:unsubscriber_id, :unsubscriber_type],
7
+ name: 'index_mailboxer_conversation_opt_outs_on_unsubscriber_id_type'
8
+ add_index :mailboxer_conversation_opt_outs, :conversation_id
9
+
10
+ add_index :mailboxer_notifications, :type
11
+ add_index :mailboxer_notifications, [:sender_id, :sender_type]
12
+
13
+ # We'll explicitly specify its name, as the auto-generated name is too long and exceeds 63
14
+ # characters limitation.
15
+ add_index :mailboxer_notifications, [:notified_object_id, :notified_object_type],
16
+ name: 'index_mailboxer_notifications_on_notified_object_id_and_type'
17
+
18
+ add_index :mailboxer_receipts, [:receiver_id, :receiver_type]
19
+ end
20
+ end
@@ -0,0 +1,8 @@
1
+ # This migration comes from mailboxer_engine (originally 20151103080417)
2
+ class AddDeliveryTrackingInfoToMailboxerReceipts < ActiveRecord::Migration
3
+ def change
4
+ add_column :mailboxer_receipts, :is_delivered, :boolean, default: false
5
+ add_column :mailboxer_receipts, :delivery_method, :string
6
+ add_column :mailboxer_receipts, :message_id, :string
7
+ end
8
+ end
@@ -2,12 +2,15 @@ require 'spec_helper'
2
2
 
3
3
  describe Mailboxer::MailDispatcher do
4
4
 
5
- subject(:instance) { described_class.new(mailable, recipients) }
5
+ subject(:instance) { described_class.new(mailable, receipts) }
6
6
 
7
7
  let(:mailable) { Mailboxer::Notification.new }
8
- let(:recipient1) { double 'recipient1', mailboxer_email: '' }
9
- let(:recipient2) { double 'recipient2', mailboxer_email: 'foo@bar.com' }
10
- let(:recipients) { [ recipient1, recipient2 ] }
8
+ let(:recipient1) { double 'recipient1', id: 1, mailboxer_email: '' }
9
+ let(:recipient2) { double 'recipient2', id: 2, mailboxer_email: 'foo@bar.com'}
10
+ let(:receipt1) { double 'receipt1', id: 1, receiver: recipient1 }
11
+ let(:receipt2) { double 'receipt2', id: 2, receiver: recipient2 }
12
+
13
+ let(:receipts) { [ receipt1, receipt2 ] }
11
14
 
12
15
  describe "call" do
13
16
  context "no emails" do
@@ -16,19 +19,10 @@ describe Mailboxer::MailDispatcher do
16
19
  its(:call) { should be false }
17
20
  end
18
21
 
19
- context "mailer wants array" do
20
- before { Mailboxer.mailer_wants_array = true }
21
- after { Mailboxer.mailer_wants_array = false }
22
+ context "mailer doesn't want array" do
22
23
  it 'sends collection' do
23
- expect(subject).to receive(:send_email).with(recipients)
24
- subject.call
25
- end
26
- end
27
-
28
- context "mailer doesnt want array" do
29
- it 'sends collection' do
30
- expect(subject).not_to receive(:send_email).with(recipient1) #email is blank
31
- expect(subject).to receive(:send_email).with(recipient2)
24
+ expect(subject).not_to receive(:send_email).with(receipt1) #email is blank
25
+ expect(subject).to receive(:send_email).with(receipt2)
32
26
  subject.call
33
27
  end
34
28
  end
@@ -49,24 +43,25 @@ describe Mailboxer::MailDispatcher do
49
43
  after { Mailboxer.custom_deliver_proc = nil }
50
44
  it "triggers proc" do
51
45
  expect(my_proc).to receive(:call).with(mailer, mailable, recipient1)
52
- subject.send :send_email, recipient1
46
+ subject.send :send_email, receipt1
53
47
  end
54
48
  end
55
49
 
56
50
  context "without custom_deliver_proc" do
57
- let(:email) { double :email }
51
+ let(:email) { double :email, message_id: '123@local.com' }
58
52
 
59
53
  it "triggers standard deliver chain" do
60
54
  expect(mailer).to receive(:send_email).with(mailable, recipient1).and_return email
55
+ expect(receipt1).to receive(:assign_attributes).with({:delivery_method=>:email, :message_id=>"123@local.com"}).and_return email
61
56
  expect(email).to receive :deliver
62
57
 
63
- subject.send :send_email, recipient1
58
+ subject.send :send_email, receipt1
64
59
  end
65
60
  end
66
61
  end
67
62
 
68
63
  describe "mailer" do
69
- let(:recipients) { [] }
64
+ let(:receipts) { [] }
70
65
 
71
66
  context "mailable is a Message" do
72
67
  let(:mailable) { Mailboxer::Notification.new }
@@ -93,22 +88,4 @@ describe Mailboxer::MailDispatcher do
93
88
  end
94
89
  end
95
90
  end
96
-
97
- describe "filtered_recipients" do
98
- context "responds to conversation" do
99
- let(:conversation) { double 'conversation' }
100
- let(:mailable) { double 'mailable', :conversation => conversation }
101
- before(:each) do
102
- expect(conversation).to receive(:has_subscriber?).with(recipient1).and_return false
103
- expect(conversation).to receive(:has_subscriber?).with(recipient2).and_return true
104
- end
105
-
106
- its(:filtered_recipients){ should eq [recipient2] }
107
- end
108
-
109
- context 'doesnt respond to conversation' do
110
- let(:mailable) { double 'mailable' }
111
- its(:filtered_recipients){ should eq recipients }
112
- end
113
- end
114
91
  end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mailboxer::RecipientFilter do
4
+ subject(:instance) { described_class.new(mailable, recipients) }
5
+ let(:recipient1) { double 'recipient1', id: 1, mailboxer_email: '' }
6
+ let(:recipient2) { double 'recipient2', id: 2, mailboxer_email: 'foo@bar.com'}
7
+ let(:recipients) { [ recipient1, recipient2 ] }
8
+
9
+ describe "call" do
10
+ context "responds to conversation" do
11
+ let(:conversation) { double 'conversation' }
12
+ let(:mailable) { double 'mailable', :conversation => conversation }
13
+ before(:each) do
14
+ expect(conversation).to receive(:has_subscriber?).with(recipient1).and_return false
15
+ expect(conversation).to receive(:has_subscriber?).with(recipient2).and_return true
16
+ end
17
+
18
+ its(:call){ should eq [recipient2] }
19
+ end
20
+
21
+ context 'doesnt respond to conversation' do
22
+ let(:mailable) { double 'mailable' }
23
+ its(:call){ should eq recipients }
24
+ end
25
+ end
26
+ end
@@ -60,36 +60,6 @@ describe Mailboxer::MessageMailer do
60
60
  end
61
61
  end
62
62
  end
63
-
64
- context "when mailer_wants_array is false" do
65
- it_behaves_like 'message_mailer'
66
- end
67
-
68
- context "mailer_wants_array is true" do
69
- class ArrayMailer < Mailboxer::MessageMailer
70
- default template_path: 'mailboxer/message_mailer'
71
-
72
- def new_message_email(message, receivers)
73
- receivers.each { |receiver| super(message, receiver) if receiver.mailboxer_email(message).present? }
74
- end
75
-
76
- def reply_message_email(message, receivers)
77
- receivers.each { |receiver| super(message, receiver) if receiver.mailboxer_email(message).present? }
78
- end
79
- end
80
-
81
- before :all do
82
- Mailboxer.mailer_wants_array = true
83
- Mailboxer.message_mailer = ArrayMailer
84
- end
85
-
86
- after :all do
87
- Mailboxer.mailer_wants_array = false
88
- Mailboxer.message_mailer = Mailboxer::MessageMailer
89
- end
90
-
91
- it_behaves_like 'message_mailer'
92
- end
93
63
  end
94
64
 
95
65
  def print_emails
@@ -13,7 +13,7 @@ describe Mailboxer::Conversation do
13
13
  let!(:conversation) { message1.conversation }
14
14
 
15
15
  it { should validate_presence_of :subject }
16
- it { should ensure_length_of(:subject).is_at_most(Mailboxer.subject_max_length) }
16
+ it { should validate_length_of(:subject).is_at_most(Mailboxer.subject_max_length) }
17
17
 
18
18
  it "should have proper original message" do
19
19
  expect(conversation.original_message).to eq message1
@@ -118,6 +118,17 @@ describe Mailboxer::Conversation do
118
118
  expect(Mailboxer::Conversation.unread(participant)).to eq [unread_conversation]
119
119
  end
120
120
  end
121
+
122
+ describe ".between" do
123
+ it "finds conversations where two participants participate" do
124
+ expect(Mailboxer::Conversation.between(entity1, participant)).to eq [sentbox_conversation, inbox_conversation]
125
+ end
126
+
127
+ it "does not find conversations if the participants have not interacted yet" do
128
+ expect(Mailboxer::Conversation.between(participant, entity2)).to eq []
129
+ end
130
+
131
+ end
121
132
  end
122
133
 
123
134
  describe "#is_completely_trashed?" do
@@ -14,6 +14,12 @@ describe Mailboxer::Mailbox do
14
14
  @conversation = @message1.conversation
15
15
  end
16
16
 
17
+ it "should return conversations between two entities" do
18
+ assert @entity1.mailbox.conversations_with(@entity2)
19
+
20
+ expect(@entity1.mailbox.conversations_with(@entity2)).to eq [@conversation]
21
+ end
22
+
17
23
  it "should return all conversations" do
18
24
  @conv2 = @entity1.send_message(@entity2,"Body","Subject").conversation
19
25
  @conv3 = @entity2.send_message(@entity1,"Body","Subject").conversation
@@ -1,30 +1,66 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Mailboxer::Message do
4
-
5
4
  before do
5
+ ActionMailer::Base.deliveries.clear
6
6
  @entity1 = FactoryGirl.create(:user)
7
7
  @entity2 = FactoryGirl.create(:user)
8
- @receipt1 = @entity1.send_message(@entity2,"Body","Subject")
9
- @receipt2 = @entity2.reply_to_all(@receipt1,"Reply body 1")
10
- @receipt3 = @entity1.reply_to_all(@receipt2,"Reply body 2")
11
- @receipt4 = @entity2.reply_to_all(@receipt3,"Reply body 3")
12
- @message1 = @receipt1.notification
13
- @message4 = @receipt4.notification
14
- @conversation = @message1.conversation
15
8
  end
16
9
 
17
- it "should have right recipients" do
18
- expect(@receipt1.notification.recipients.count).to eq 2
19
- expect(@receipt2.notification.recipients.count).to eq 2
20
- expect(@receipt3.notification.recipients.count).to eq 2
21
- expect(@receipt4.notification.recipients.count).to eq 2
10
+ context "with errors" do
11
+ describe "empty subject" do
12
+ before do
13
+ @receipt1 = @entity1.send_message(@entity2,"Body","")
14
+ @message1 = @receipt1.notification
15
+ end
16
+
17
+ it "should add errors to the created notification" do
18
+ errors = @message1.errors['conversation.subject']
19
+
20
+ expect(errors).to eq(["can't be blank"])
21
+ end
22
+ end
22
23
  end
23
24
 
24
- it "should be able to be marked as deleted" do
25
- expect(@receipt1.deleted).to be false
26
- @message1.mark_as_deleted @entity1
27
- expect(@message1.is_deleted?(@entity1)).to be true
25
+ context "after send" do
26
+
27
+ before do
28
+ ActionMailer::Base.deliveries.clear
29
+ @entity1 = FactoryGirl.create(:user)
30
+ @entity2 = FactoryGirl.create(:user)
31
+ @receipt1 = @entity1.send_message(@entity2,"Body","Subject")
32
+ @message1 = @receipt1.notification
33
+ end
34
+
35
+ it "should be able to be marked as deleted" do
36
+ expect(@receipt1.deleted).to be false
37
+ @message1.mark_as_deleted @entity1
38
+ expect(@message1.is_deleted?(@entity1)).to be true
39
+ end
40
+
41
+ it "creates a conversation" do
42
+ expect(@message1.conversation).to eq(Mailboxer::Conversation.last)
43
+ end
44
+
45
+ it "should send email only to receivers" do
46
+ expect(ActionMailer::Base.deliveries.count).to eq 1
47
+ end
48
+
49
+ context "and multiple replies" do
50
+ before do
51
+ @receipt2 = @entity2.reply_to_all(@receipt1,"Reply body 1")
52
+ @receipt3 = @entity1.reply_to_all(@receipt2,"Reply body 2")
53
+ @receipt4 = @entity2.reply_to_all(@receipt3,"Reply body 3")
54
+ end
55
+
56
+ it "should have right recipients" do
57
+ expect(@receipt1.notification.recipients.count).to eq 2
58
+ expect(@receipt2.notification.recipients.count).to eq 2
59
+ expect(@receipt3.notification.recipients.count).to eq 2
60
+ expect(@receipt4.notification.recipients.count).to eq 2
61
+ end
62
+ end
63
+
28
64
  end
29
65
 
30
66
  end
@@ -8,11 +8,10 @@ describe Mailboxer::Notification do
8
8
  @entity3 = FactoryGirl.create(:user)
9
9
  end
10
10
 
11
- it { should validate_presence_of :subject }
12
11
  it { should validate_presence_of :body }
13
12
 
14
- it { should ensure_length_of(:subject).is_at_most(Mailboxer.subject_max_length) }
15
- it { should ensure_length_of(:body).is_at_most(Mailboxer.body_max_length) }
13
+ it { should validate_length_of(:subject).is_at_most(Mailboxer.subject_max_length) }
14
+ it { should validate_length_of(:body).is_at_most(Mailboxer.body_max_length) }
16
15
 
17
16
  it "should notify one user" do
18
17
  @entity1.notify("Subject", "Body")
@@ -30,6 +30,14 @@ Dir["#{File.dirname(__FILE__)}/factories/*.rb"].each {|f| require f}
30
30
 
31
31
  # Shoulda Matchers
32
32
  require 'shoulda/matchers'
33
+ if Shoulda::Matchers.respond_to?(:configure)
34
+ Shoulda::Matchers.configure do |config|
35
+ config.integrate do |with|
36
+ with.test_framework :rspec
37
+ with.library :rails
38
+ end
39
+ end
40
+ end
33
41
 
34
42
  RSpec.configure do |config|
35
43
  # Remove this line if you don't want RSpec's should and should_not
metadata CHANGED
@@ -1,43 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailboxer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eduardo Casanova Cuesta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-02 00:00:00.000000000 Z
11
+ date: 2016-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: foreigner
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: 0.9.1
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: 0.9.1
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: rails
29
15
  requirement: !ruby/object:Gem::Requirement
30
16
  requirements:
31
17
  - - ">="
32
18
  - !ruby/object:Gem::Version
33
- version: 3.2.0
19
+ version: 4.2.0
34
20
  type: :runtime
35
21
  prerelease: false
36
22
  version_requirements: !ruby/object:Gem::Requirement
37
23
  requirements:
38
24
  - - ">="
39
25
  - !ruby/object:Gem::Version
40
- version: 3.2.0
26
+ version: 4.2.0
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: carrierwave
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -112,16 +98,16 @@ dependencies:
112
98
  name: shoulda-matchers
113
99
  requirement: !ruby/object:Gem::Requirement
114
100
  requirements:
115
- - - ">="
101
+ - - "~>"
116
102
  - !ruby/object:Gem::Version
117
- version: '0'
103
+ version: '2'
118
104
  type: :development
119
105
  prerelease: false
120
106
  version_requirements: !ruby/object:Gem::Requirement
121
107
  requirements:
122
- - - ">="
108
+ - - "~>"
123
109
  - !ruby/object:Gem::Version
124
- version: '0'
110
+ version: '2'
125
111
  - !ruby/object:Gem::Dependency
126
112
  name: factory_girl
127
113
  requirement: !ruby/object:Gem::Requirement
@@ -223,10 +209,9 @@ files:
223
209
  - db/migrate/20110511145103_create_mailboxer.rb
224
210
  - db/migrate/20131206080416_add_conversation_optout.rb
225
211
  - db/migrate/20131206080417_add_missing_indices.rb
226
- - gemfiles/rails3.2.gemfile
227
- - gemfiles/rails4.0.gemfile
228
- - gemfiles/rails4.1.gemfile
212
+ - db/migrate/20151103080417_add_delivery_tracking_info_to_mailboxer_receipts.rb
229
213
  - gemfiles/rails4.2.gemfile
214
+ - gemfiles/rails5.0.gemfile
230
215
  - lib/generators/mailboxer/install_generator.rb
231
216
  - lib/generators/mailboxer/namespacing_compatibility_generator.rb
232
217
  - lib/generators/mailboxer/templates/initializer.rb
@@ -237,6 +222,7 @@ files:
237
222
  - lib/mailboxer/engine.rb
238
223
  - lib/mailboxer/mail_dispatcher.rb
239
224
  - lib/mailboxer/models/messageable.rb
225
+ - lib/mailboxer/recipient_filter.rb
240
226
  - lib/mailboxer/version.rb
241
227
  - mailboxer.gemspec
242
228
  - spec/dummy/.gitignore
@@ -274,6 +260,8 @@ files:
274
260
  - spec/dummy/db/migrate/20110306015107_create_cylons.rb
275
261
  - spec/dummy/db/migrate/20120305103200_create_mailboxer.rb
276
262
  - spec/dummy/db/migrate/20131206080416_add_conversation_optout.rb
263
+ - spec/dummy/db/migrate/20151103202534_add_missing_indices.mailboxer_engine.rb
264
+ - spec/dummy/db/migrate/20151103202535_add_delivery_tracking_info_to_mailboxer_receipts.mailboxer_engine.rb
277
265
  - spec/dummy/db/schema.rb
278
266
  - spec/dummy/public/404.html
279
267
  - spec/dummy/public/422.html
@@ -289,6 +277,7 @@ files:
289
277
  - spec/integration/message_and_receipt_spec.rb
290
278
  - spec/integration/navigation_spec.rb
291
279
  - spec/mailboxer/mail_dispatcher_spec.rb
280
+ - spec/mailboxer/recipient_filter_spec.rb
292
281
  - spec/mailboxer_spec.rb
293
282
  - spec/mailers/message_mailer_spec.rb
294
283
  - spec/mailers/notification_mailer_spec.rb
@@ -320,7 +309,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
320
309
  version: '0'
321
310
  requirements: []
322
311
  rubyforge_project:
323
- rubygems_version: 2.4.8
312
+ rubygems_version: 2.5.1
324
313
  signing_key:
325
314
  specification_version: 4
326
315
  summary: Messaging system for rails apps.
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "http://rubygems.org"
4
-
5
- gem "rails", "~> 3.2.17"
6
-
7
- gemspec :path => "../"
@@ -1,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "http://rubygems.org"
4
-
5
- gem "rails", "~> 4.1.0"
6
-
7
- gemspec :path => "../"