mailboxer 0.13.0 → 0.14.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.
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 => "../"