pluginaweek-has_messages 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,16 @@
1
+ class CreateMessages < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :messages do |t|
4
+ t.references :sender, :polymorphic => true, :null => false
5
+ t.text :subject, :body
6
+ t.string :state, :null => false
7
+ t.datetime :hidden_at
8
+ t.string :type
9
+ t.timestamps
10
+ end
11
+ end
12
+
13
+ def self.down
14
+ drop_table :messages
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ class CreateMessageRecipients < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :message_recipients do |t|
4
+ t.references :message, :null => false
5
+ t.references :receiver, :polymorphic => true, :null => false
6
+ t.string :kind, :null => false
7
+ t.integer :position
8
+ t.string :state, :null => false
9
+ t.datetime :hidden_at
10
+ end
11
+ add_index :message_recipients, [:message_id, :kind, :position], :unique => true
12
+ end
13
+
14
+ def self.down
15
+ drop_table :message_recipients
16
+ end
17
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'has_messages'
@@ -0,0 +1,72 @@
1
+ require 'state_machine'
2
+
3
+ # Adds a generic implementation for sending messages between users
4
+ module HasMessages
5
+ module MacroMethods
6
+ # Creates the following message associations:
7
+ # * +messages+ - Messages that were composed and are visible to the owner.
8
+ # Mesages may have been sent or unsent.
9
+ # * +received_messages - Messages that have been received from others and
10
+ # are visible. Messages may have been read or unread.
11
+ #
12
+ # == Creating new messages
13
+ #
14
+ # To create a new message, the +messages+ association should be used,
15
+ # for example:
16
+ #
17
+ # user = User.find(123)
18
+ # message = user.messages.build
19
+ # message.subject = 'Hello'
20
+ # message.body = 'How are you?'
21
+ # message.to User.find(456)
22
+ # message.save
23
+ # message.deliver
24
+ #
25
+ # == Drafts
26
+ #
27
+ # You can get the drafts for a particular user by using the +unsent_messages+
28
+ # helper method. This will find all messages in the "unsent" state. For example,
29
+ #
30
+ # user = User.find(123)
31
+ # user.unsent_messages
32
+ #
33
+ # You can also get at the messages that *have* been sent, using the +sent_messages+
34
+ # helper method. For example,
35
+ #
36
+ # user = User.find(123)
37
+ # user.sent_messages
38
+ def has_messages
39
+ has_many :messages,
40
+ :as => :sender,
41
+ :class_name => 'Message',
42
+ :conditions => {:hidden_at => nil},
43
+ :order => 'messages.created_at ASC'
44
+ has_many :received_messages,
45
+ :as => :receiver,
46
+ :class_name => 'MessageRecipient',
47
+ :include => :message,
48
+ :conditions => ['message_recipients.hidden_at IS NULL AND messages.state = ?', 'sent'],
49
+ :order => 'messages.created_at ASC'
50
+
51
+ include HasMessages::InstanceMethods
52
+ end
53
+ end
54
+
55
+ module InstanceMethods
56
+ # Composed messages that have not yet been sent. These consists of all
57
+ # messages that are currently in the "unsent" state.
58
+ def unsent_messages
59
+ messages.with_state(:unsent)
60
+ end
61
+
62
+ # Composed messages that have already been sent. These consists of all
63
+ # messages that are currently in the "queued" or "sent" states.
64
+ def sent_messages
65
+ messages.with_states(:queued, :sent)
66
+ end
67
+ end
68
+ end
69
+
70
+ ActiveRecord::Base.class_eval do
71
+ extend HasMessages::MacroMethods
72
+ end
@@ -0,0 +1,3 @@
1
+ class User < ActiveRecord::Base
2
+ has_messages
3
+ end
@@ -0,0 +1,9 @@
1
+ require 'config/boot'
2
+
3
+ Rails::Initializer.run do |config|
4
+ config.plugin_paths << '..'
5
+ config.plugins = %w(state_machine has_messages)
6
+ config.cache_classes = false
7
+ config.whiny_nils = true
8
+ config.action_controller.session = {:key => 'rails_session', :secret => 'd229e4d22437432705ab3985d4d246'}
9
+ end
@@ -0,0 +1,11 @@
1
+ class CreateUsers < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :users do |t|
4
+ t.string :login, :null => false
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ drop_table :users
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ class MigrateHasMessagesToVersion2 < ActiveRecord::Migration
2
+ def self.up
3
+ ActiveRecord::Migrator.new(:up, "#{Rails.root}/../../db/migrate", 0).migrations.each do |migration|
4
+ migration.migrate(:up)
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ ActiveRecord::Migrator.new(:up, "#{Rails.root}/../../db/migrate", 0).migrations.each do |migration|
10
+ migration.migrate(:down)
11
+ end
12
+ end
13
+ end
data/test/factory.rb ADDED
@@ -0,0 +1,57 @@
1
+ module Factory
2
+ # Build actions for the model
3
+ def self.build(model, &block)
4
+ name = model.to_s.underscore
5
+
6
+ define_method("#{name}_attributes", block)
7
+ define_method("valid_#{name}_attributes") {|*args| valid_attributes_for(model, *args)}
8
+ define_method("new_#{name}") {|*args| new_record(model, *args)}
9
+ define_method("create_#{name}") {|*args| create_record(model, *args)}
10
+ end
11
+
12
+ # Get valid attributes for the model
13
+ def valid_attributes_for(model, attributes = {})
14
+ name = model.to_s.underscore
15
+ send("#{name}_attributes", attributes)
16
+ attributes.stringify_keys!
17
+ attributes
18
+ end
19
+
20
+ # Build an unsaved record
21
+ def new_record(model, *args)
22
+ attributes = valid_attributes_for(model, *args)
23
+ record = model.new(attributes)
24
+ attributes.each {|attr, value| record.send("#{attr}=", value) if model.accessible_attributes && !model.accessible_attributes.include?(attr) || model.protected_attributes && model.protected_attributes.include?(attr)}
25
+ record
26
+ end
27
+
28
+ # Build and save/reload a record
29
+ def create_record(model, *args)
30
+ record = new_record(model, *args)
31
+ record.save!
32
+ record.reload
33
+ record
34
+ end
35
+
36
+ build Message do |attributes|
37
+ attributes[:sender] = create_user unless attributes.include?(:sender)
38
+ attributes.reverse_merge!(
39
+ :subject => 'New features',
40
+ :body => 'Lots of new things to talk about... come to the meeting tonight to find out!'
41
+ )
42
+ end
43
+
44
+ build MessageRecipient do |attributes|
45
+ attributes[:message] = create_message unless attributes.include?(:message)
46
+ attributes[:receiver] = create_user(:login => 'me') unless attributes.include?(:receiver)
47
+ attributes.reverse_merge!(
48
+ :kind => 'to'
49
+ )
50
+ end
51
+
52
+ build User do |attributes|
53
+ attributes.reverse_merge!(
54
+ :login => 'admin'
55
+ )
56
+ end
57
+ end
@@ -0,0 +1,139 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class UserByDefaultTest < ActiveSupport::TestCase
4
+ def setup
5
+ @user = create_user
6
+ end
7
+
8
+ def test_should_not_have_any_messages
9
+ assert @user.messages.empty?
10
+ end
11
+
12
+ def test_should_not_have_any_unsent_messages
13
+ assert @user.unsent_messages.empty?
14
+ end
15
+
16
+ def test_should_not_have_any_sent_messages
17
+ assert @user.sent_messages.empty?
18
+ end
19
+
20
+ def test_should_not_have_any_received_messages
21
+ assert @user.received_messages.empty?
22
+ end
23
+ end
24
+
25
+ class UserTest < ActiveSupport::TestCase
26
+ def setup
27
+ @user = create_user
28
+ end
29
+
30
+ def test_should_be_able_to_create_new_messages
31
+ message = @user.messages.build
32
+ assert_instance_of Message, message
33
+ assert_equal @user, message.sender
34
+ end
35
+
36
+ def test_should_be_able_to_send_new_messages
37
+ message = @user.messages.build
38
+ message.to create_user(:login => 'John')
39
+ assert message.deliver
40
+ end
41
+ end
42
+
43
+ class UserWithUnsentMessages < ActiveSupport::TestCase
44
+ def setup
45
+ @user = create_user
46
+ @sent_message = create_message(:sender => @user, :to => create_user(:login => 'you'))
47
+ @sent_message.deliver
48
+ @first_draft = create_message(:sender => @user)
49
+ @second_draft = create_message(:sender => @user)
50
+ end
51
+
52
+ def test_should_have_unsent_messages
53
+ assert_equal [@first_draft, @second_draft], @user.unsent_messages
54
+ end
55
+
56
+ def test_should_include_unsent_messages_in_messages
57
+ assert_equal [@sent_message, @first_draft, @second_draft], @user.messages
58
+ end
59
+ end
60
+
61
+ class UserWithSentMessages < ActiveSupport::TestCase
62
+ def setup
63
+ @user = create_user
64
+ @to = create_user(:login => 'you')
65
+ @draft = create_message(:sender => @user)
66
+
67
+ @first_sent_message = create_message(:sender => @user, :to => @to)
68
+ @first_sent_message.deliver
69
+
70
+ @second_sent_message = create_message(:sender => @user, :to => @to)
71
+ @second_sent_message.deliver
72
+ end
73
+
74
+ def test_should_have_sent_messages
75
+ assert_equal [@first_sent_message, @second_sent_message], @user.sent_messages
76
+ end
77
+
78
+ def test_should_include_sent_messages_in_messages
79
+ assert_equal [@draft, @first_sent_message, @second_sent_message], @user.messages
80
+ end
81
+ end
82
+
83
+ class UserWithReceivedMessages < ActiveSupport::TestCase
84
+ def setup
85
+ @sender = create_user
86
+ @user = create_user(:login => 'me')
87
+
88
+ @unsent_message = create_message(:sender => @sender, :to => @user)
89
+
90
+ @first_sent_message = create_message(:sender => @sender, :to => @user)
91
+ @first_sent_message.deliver
92
+
93
+ @second_sent_message = create_message(:sender => @sender, :to => @user)
94
+ @second_sent_message.deliver
95
+ end
96
+
97
+ def test_should_have_received_messages
98
+ assert_equal [@first_sent_message, @second_sent_message], @user.received_messages.map(&:message)
99
+ end
100
+ end
101
+
102
+ class UserWithHiddenMessagesTest < ActiveSupport::TestCase
103
+ def setup
104
+ @user = create_user
105
+ @friend = create_user(:login => 'you')
106
+
107
+ hidden_unsent_message = create_message(:sender => @user)
108
+ hidden_unsent_message.hide
109
+ @unsent_message = create_message(:sender => @user)
110
+
111
+ hidden_sent_message = create_message(:sender => @user, :to => @friend)
112
+ hidden_sent_message.deliver
113
+ hidden_sent_message.hide
114
+ @sent_message = create_message(:sender => @user, :to => @friend)
115
+ @sent_message.deliver
116
+
117
+ hidden_received_message = create_message(:sender => @friend, :to => @user)
118
+ hidden_received_message.deliver
119
+ hidden_received_message.recipients.first.hide
120
+ @received_message = create_message(:sender => @friend, :to => @user)
121
+ @received_message.deliver
122
+ end
123
+
124
+ def test_should_not_include_hidden_messages_in_messages
125
+ assert_equal [@unsent_message, @sent_message], @user.messages
126
+ end
127
+
128
+ def test_should_not_include_hidden_messages_in_unsent_messages
129
+ assert_equal [@unsent_message], @user.unsent_messages
130
+ end
131
+
132
+ def test_should_not_include_hidden_messages_in_sent_messages
133
+ assert_equal [@sent_message], @user.sent_messages
134
+ end
135
+
136
+ def test_should_not_include_hidden_messages_in_received_messages
137
+ assert_equal [@received_message], @user.received_messages.map(&:message)
138
+ end
139
+ end
@@ -0,0 +1,13 @@
1
+ # Load the plugin testing framework
2
+ $:.unshift("#{File.dirname(__FILE__)}/../../plugin_test_helper/lib")
3
+ require 'rubygems'
4
+ require 'plugin_test_helper'
5
+
6
+ # Run the migrations
7
+ ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate")
8
+
9
+ # Mixin the factory helper
10
+ require File.expand_path("#{File.dirname(__FILE__)}/factory")
11
+ Test::Unit::TestCase.class_eval do
12
+ include Factory
13
+ end
@@ -0,0 +1,449 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+
3
+ class MessageRecipientByDefaultTest < ActiveSupport::TestCase
4
+ def setup
5
+ @recipient = MessageRecipient.new
6
+ end
7
+
8
+ def test_should_not_have_a_message
9
+ assert_nil @recipient.message_id
10
+ end
11
+
12
+ def test_should_not_have_a_receiver_id
13
+ assert_nil @recipient.receiver_id
14
+ end
15
+
16
+ def test_should_not_have_a_receiver_type
17
+ assert @recipient.receiver_type.blank?
18
+ end
19
+
20
+ def test_should_not_have_a_kind
21
+ assert @recipient.kind.blank?
22
+ end
23
+
24
+ def test_should_not_have_a_position
25
+ assert_nil @recipient.position
26
+ end
27
+
28
+ def test_should_be_in_the_unread_state
29
+ assert_equal 'unread', @recipient.state
30
+ end
31
+
32
+ def test_should_not_be_hidden
33
+ assert_nil @recipient.hidden_at
34
+ assert !@recipient.hidden?
35
+ end
36
+ end
37
+
38
+ class MesageRecipientTest < ActiveSupport::TestCase
39
+ def test_should_be_valid_with_a_set_of_valid_attributes
40
+ recipient = new_message_recipient
41
+ assert recipient.valid?
42
+ end
43
+
44
+ def test_should_require_a_message
45
+ recipient = new_message_recipient(:message => nil)
46
+ assert !recipient.valid?
47
+ assert recipient.errors.invalid?(:message_id)
48
+ end
49
+
50
+ def test_should_require_a_kind
51
+ recipient = new_message_recipient(:kind => nil)
52
+ assert !recipient.valid?
53
+ assert recipient.errors.invalid?(:kind)
54
+ end
55
+
56
+ def test_should_require_a_state
57
+ recipient = new_message_recipient(:state => nil)
58
+ assert !recipient.valid?
59
+ assert recipient.errors.invalid?(:state)
60
+ end
61
+
62
+ def test_should_require_a_receiver_id
63
+ recipient = new_message_recipient(:receiver => nil)
64
+ assert !recipient.valid?
65
+ assert recipient.errors.invalid?(:receiver_id)
66
+ end
67
+
68
+ def test_should_require_a_receiver_type
69
+ recipient = new_message_recipient(:receiver => nil)
70
+ assert !recipient.valid?
71
+ assert recipient.errors.invalid?(:receiver_type)
72
+ end
73
+
74
+ def test_should_not_require_a_position
75
+ recipient = new_message_recipient(:position => nil)
76
+ assert recipient.valid?
77
+ end
78
+
79
+ def test_should_protect_attributes_from_mass_assignment
80
+ recipient = MessageRecipient.new(
81
+ :id => 1,
82
+ :message_id => 1,
83
+ :receiver_id => 1,
84
+ :receiver_type => 'User',
85
+ :kind => 'bcc',
86
+ :position => 10,
87
+ :state => 'read',
88
+ :hidden_at => Time.now
89
+ )
90
+
91
+ assert_nil recipient.id
92
+ assert_equal 1, recipient.message_id
93
+ assert_equal 1, recipient.receiver_id
94
+ assert_equal 'User', recipient.receiver_type
95
+ assert_equal 'bcc', recipient.kind
96
+ assert_nil recipient.position
97
+ assert_equal 'unread', recipient.state
98
+ assert_nil recipient.hidden_at
99
+ end
100
+ end
101
+
102
+ class MessageRecipientAfterBeingCreatedTest < ActiveSupport::TestCase
103
+ def setup
104
+ @admin = create_user(:login => 'admin')
105
+ @erich = create_user(:login => 'Erich')
106
+ @richard = create_user(:login => 'Richard')
107
+ @ralph = create_user(:login => 'Ralph')
108
+
109
+ message = create_message(
110
+ :subject => 'Hello',
111
+ :body => 'How are you?',
112
+ :sender => @admin,
113
+ :cc => @richard,
114
+ :bcc => @ralph
115
+ )
116
+ @recipient = create_message_recipient(
117
+ :message => message,
118
+ :receiver => @erich,
119
+ :kind => 'to'
120
+ )
121
+ end
122
+
123
+ def test_should_not_be_hidden
124
+ assert !@recipient.hidden?
125
+ end
126
+
127
+ def test_should_delegate_sender_to_message
128
+ assert_equal @admin, @recipient.sender
129
+ end
130
+
131
+ def test_should_delegate_subject_to_message
132
+ assert_equal 'Hello', @recipient.subject
133
+ end
134
+
135
+ def test_should_delegate_body_to_message
136
+ assert_equal 'How are you?', @recipient.body
137
+ end
138
+
139
+ def test_should_delegate_recipients_to_message
140
+ assert_equal [@erich, @richard, @ralph], @recipient.recipients.map(&:receiver)
141
+ end
142
+
143
+ def test_should_delegate_to_receivers_to_message
144
+ assert_equal [@erich], @recipient.to
145
+ end
146
+
147
+ def test_should_delegate_cc_receivers_to_message
148
+ assert_equal [@richard], @recipient.cc
149
+ end
150
+
151
+ def test_should_delegate_bcc_receivers_to_message
152
+ assert_equal [@ralph], @recipient.bcc
153
+ end
154
+
155
+ def test_should_delegate_created_at_to_message
156
+ assert_not_nil @recipient.created_at
157
+ end
158
+ end
159
+
160
+ class MessageRecipientOfMultipleTest < ActiveSupport::TestCase
161
+ def setup
162
+ @erich = create_user(:login => 'Erich')
163
+ @richard = create_user(:login => 'Richard')
164
+ @ralph = create_user(:login => 'Ralph')
165
+
166
+ message = create_message(:to => [@erich, @richard])
167
+ @recipient = create_message_recipient(
168
+ :message => message,
169
+ :receiver => @ralph,
170
+ :kind => 'to'
171
+ )
172
+ end
173
+
174
+ def test_should_use_position_based_on_position_of_last_recipient
175
+ assert_equal 3, @recipient.position
176
+ end
177
+ end
178
+
179
+ class MessageRecipientUnreadWithUnsentMessageTest < ActiveSupport::TestCase
180
+ def setup
181
+ @recipient = create_message_recipient
182
+ end
183
+
184
+ def test_should_be_in_the_unread_state
185
+ assert_equal 'unread', @recipient.state
186
+ end
187
+
188
+ def test_should_not_be_able_to_view
189
+ assert !@recipient.view
190
+ end
191
+ end
192
+
193
+ class MessageRecipientUnreadWithSentMessageTest < ActiveSupport::TestCase
194
+ def setup
195
+ @recipient = create_message_recipient
196
+ @recipient.message.deliver
197
+ end
198
+
199
+ def test_should_be_in_the_unread_state
200
+ assert_equal 'unread', @recipient.state
201
+ end
202
+
203
+ def test_should_be_able_to_view
204
+ assert @recipient.view
205
+ end
206
+ end
207
+
208
+ class MessageRecipientReadTest < ActiveSupport::TestCase
209
+ def setup
210
+ @recipient = create_message_recipient
211
+ @recipient.message.deliver
212
+ @recipient.view
213
+ end
214
+
215
+ def test_should_be_in_the_read_state
216
+ assert_equal 'read', @recipient.state
217
+ end
218
+
219
+ def test_should_not_be_able_to_view
220
+ assert !@recipient.view
221
+ end
222
+ end
223
+
224
+ class MessageRecipientHiddenTest < ActiveSupport::TestCase
225
+ def setup
226
+ @recipient = create_message_recipient
227
+ @recipient.hide
228
+ end
229
+
230
+ def test_should_record_when_it_was_hidden
231
+ assert_not_nil @recipient.hidden_at
232
+ end
233
+
234
+ def test_should_be_hidden
235
+ assert @recipient.hidden?
236
+ end
237
+
238
+ def test_should_not_be_visible
239
+ assert !@recipient.visible?
240
+ end
241
+ end
242
+
243
+ class MessageRecipientUnhiddenTest < ActiveSupport::TestCase
244
+ def setup
245
+ @recipient = create_message_recipient
246
+ @recipient.hide
247
+ @recipient.unhide
248
+ end
249
+
250
+ def test_should_not_have_the_recorded_value_when_it_was_hidden
251
+ assert_nil @recipient.hidden_at
252
+ end
253
+
254
+ def test_should_not_be_hidden
255
+ assert !@recipient.hidden?
256
+ end
257
+
258
+ def test_should_be_visible
259
+ assert @recipient.visible?
260
+ end
261
+ end
262
+
263
+ class MessageRecipientForwardedTest < ActiveSupport::TestCase
264
+ def setup
265
+ @erich = create_user(:login => 'Erich')
266
+ original_message = create_message(
267
+ :subject => 'Hello',
268
+ :body => 'How are you?',
269
+ :cc => create_user(:login => 'Richard'),
270
+ :bcc => create_user(:login => 'Ralph')
271
+ )
272
+ @recipient = create_message_recipient(
273
+ :message => original_message,
274
+ :receiver => @erich
275
+ )
276
+ @message = @recipient.forward
277
+ end
278
+
279
+ def test_should_be_in_unsent_state
280
+ assert_equal 'unsent', @message.state
281
+ end
282
+
283
+ def test_should_not_be_hidden
284
+ assert !@message.hidden?
285
+ end
286
+
287
+ def test_should_have_original_subject
288
+ assert_equal 'Hello', @message.subject
289
+ end
290
+
291
+ def test_should_have_original_body
292
+ assert_equal 'How are you?', @message.body
293
+ end
294
+
295
+ def test_should_use_receiver_as_the_sender
296
+ assert_equal @erich, @message.sender
297
+ end
298
+
299
+ def test_should_not_include_to_recipients
300
+ assert @message.to.empty?
301
+ end
302
+
303
+ def test_should_not_include_cc_recipients
304
+ assert @message.cc.empty?
305
+ end
306
+
307
+ def test_should_not_include_bcc_recipients
308
+ assert @message.bcc.empty?
309
+ end
310
+ end
311
+
312
+ class MessageRecipientRepliedTest < ActiveSupport::TestCase
313
+ def setup
314
+ @erich = create_user(:login => 'Erich')
315
+ @john = create_user(:login => 'John')
316
+ original_message = create_message(
317
+ :subject => 'Hello',
318
+ :body => 'How are you?',
319
+ :to => @john,
320
+ :cc => create_user(:login => 'Richard'),
321
+ :bcc => create_user(:login => 'Ralph')
322
+ )
323
+ @recipient = create_message_recipient(
324
+ :message => original_message,
325
+ :receiver => @erich
326
+ )
327
+ @message = @recipient.reply
328
+ end
329
+
330
+ def test_should_be_in_unsent_state
331
+ assert_equal 'unsent', @message.state
332
+ end
333
+
334
+ def test_should_not_be_hidden
335
+ assert !@message.hidden?
336
+ end
337
+
338
+ def test_should_have_original_subject
339
+ assert_equal 'Hello', @message.subject
340
+ end
341
+
342
+ def test_should_have_original_body
343
+ assert_equal 'How are you?', @message.body
344
+ end
345
+
346
+ def test_should_use_receiver_as_the_sender
347
+ assert_equal @erich, @message.sender
348
+ end
349
+
350
+ def test_should_include_to_recipients
351
+ assert [@erich, @john], @message.to
352
+ end
353
+
354
+ def test_should_not_include_cc_recipients
355
+ assert @message.cc.empty?
356
+ end
357
+
358
+ def test_should_not_include_bcc_recipients
359
+ assert @message.bcc.empty?
360
+ end
361
+ end
362
+
363
+ class MessageRecipientRepliedToAllTest < ActiveSupport::TestCase
364
+ def setup
365
+ @erich = create_user(:login => 'Erich')
366
+ @john = create_user(:login => 'John')
367
+ @richard = create_user(:login => 'Richard')
368
+ @ralph = create_user(:login => 'Ralph')
369
+ original_message = create_message(
370
+ :subject => 'Hello',
371
+ :body => 'How are you?',
372
+ :to => @john,
373
+ :cc => @richard,
374
+ :bcc => @ralph
375
+ )
376
+ @recipient = create_message_recipient(
377
+ :message => original_message,
378
+ :receiver => @erich
379
+ )
380
+ @message = @recipient.reply_to_all
381
+ end
382
+
383
+ def test_should_be_in_unsent_state
384
+ assert_equal 'unsent', @message.state
385
+ end
386
+
387
+ def test_should_not_be_hidden
388
+ assert !@message.hidden?
389
+ end
390
+
391
+ def test_should_have_original_subject
392
+ assert_equal 'Hello', @message.subject
393
+ end
394
+
395
+ def test_should_have_original_body
396
+ assert_equal 'How are you?', @message.body
397
+ end
398
+
399
+ def test_should_use_receiver_as_the_sender
400
+ assert_equal @erich, @message.sender
401
+ end
402
+
403
+ def test_should_include_to_recipients
404
+ assert [@erich, @john], @message.to
405
+ end
406
+
407
+ def test_should_include_cc_recipients
408
+ assert_equal [@richard], @message.cc
409
+ end
410
+
411
+ def test_should_include_bcc_recipients
412
+ assert_equal [@ralph], @message.bcc
413
+ end
414
+ end
415
+
416
+ class MessageRecipientAfterBeingDestroyedTest < ActiveSupport::TestCase
417
+ def setup
418
+ message = create_message
419
+ @first_recipient = create_message_recipient(
420
+ :message => message,
421
+ :receiver => create_user(:login => 'Erich'),
422
+ :kind => 'to'
423
+ )
424
+ @last_recipient = create_message_recipient(
425
+ :message => message,
426
+ :receiver => create_user(:login => 'Richard'),
427
+ :kind => 'to'
428
+ )
429
+
430
+ assert @first_recipient.destroy
431
+ @last_recipient.reload
432
+ end
433
+
434
+ def test_should_reorder_positions_of_all_other_recipients
435
+ assert_equal 1, @last_recipient.position
436
+ end
437
+ end
438
+
439
+ class MessageRecipientAsAClassTest < ActiveSupport::TestCase
440
+ def setup
441
+ message = create_message
442
+ @hidden_recipient = create_message_recipient(:message => message, :receiver => create_user(:login => 'erich'), :hidden_at => Time.now)
443
+ @visible_recipient = create_message_recipient(:message => message, :receiver => create_user(:login => 'richard'))
444
+ end
445
+
446
+ def test_should_include_only_visible_messages_in_visible_scope
447
+ assert_equal [@visible_recipient], MessageRecipient.visible
448
+ end
449
+ end