has_emails 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +23 -0
- data/MIT-LICENSE +20 -0
- data/README +130 -0
- data/Rakefile +81 -0
- data/app/mailers/application_mailer.rb +85 -0
- data/app/models/email.rb +84 -0
- data/app/models/email_address.rb +123 -0
- data/app/models/email_recipient.rb +78 -0
- data/app/models/email_recipient_build_extension.rb +7 -0
- data/db/bootstrap/events.yml +4 -0
- data/db/bootstrap/states.yml +9 -0
- data/db/migrate/001_create_email_addresses.rb +23 -0
- data/db/migrate/002_add_email_specs.rb +18 -0
- data/db/migrate/003_add_email_recipient_specs.rb +18 -0
- data/init.rb +1 -0
- data/lib/has_emails.rb +92 -0
- data/test/app_root/app/models/department.rb +2 -0
- data/test/app_root/app/models/user.rb +3 -0
- data/test/app_root/config/environment.rb +33 -0
- data/test/app_root/db/migrate/001_create_users.rb +11 -0
- data/test/app_root/db/migrate/002_create_departments.rb +12 -0
- data/test/fixtures/departments.yml +9 -0
- data/test/fixtures/email_addresses.yml +32 -0
- data/test/fixtures/message_recipients.yml +85 -0
- data/test/fixtures/messages.yml +52 -0
- data/test/fixtures/state_changes.yml +128 -0
- data/test/fixtures/users.yml +11 -0
- data/test/test_helper.rb +76 -0
- data/test/unit/application_mailer_test.rb +69 -0
- data/test/unit/email_address_test.rb +200 -0
- data/test/unit/email_recipient_test.rb +79 -0
- data/test/unit/email_test.rb +89 -0
- data/test/unit/has_emails_test.rb +36 -0
- data/test/unit/recipient_extension_test.rb +99 -0
- metadata +113 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
class AddEmailRecipientSpecs < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
# Workaround change_column not allowing change to :null => true
|
4
|
+
remove_column :message_recipients, :receiver_id
|
5
|
+
remove_column :message_recipients, :receiver_type
|
6
|
+
|
7
|
+
add_column :message_recipients, :receiver_id, :integer, :null => true, :default => nil, :references => nil
|
8
|
+
add_column :message_recipients, :receiver_type, :string, :null => true, :default => nil
|
9
|
+
add_column :message_recipients, :receiver_spec, :string, :limit => 320
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.down
|
13
|
+
remove_column :message_recipients, :receiver_spec
|
14
|
+
|
15
|
+
change_column :message_recipients, :receiver_id, :integer, :null => false, :references => nil
|
16
|
+
change_column :message_recipients, :receiver_type, :string, :null => false
|
17
|
+
end
|
18
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'has_emails'
|
data/lib/has_emails.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'has_messages'
|
2
|
+
require 'validates_as_email_address'
|
3
|
+
require 'acts_as_tokenized'
|
4
|
+
require 'nested_has_many_through'
|
5
|
+
|
6
|
+
module PluginAWeek #:nodoc:
|
7
|
+
module Has #:nodoc:
|
8
|
+
# Adds support for sending emails to models
|
9
|
+
module Emails
|
10
|
+
def self.included(base) #:nodoc:
|
11
|
+
base.extend(MacroMethods)
|
12
|
+
end
|
13
|
+
|
14
|
+
module MacroMethods
|
15
|
+
# Adds support for emailing instances of this model through multiple
|
16
|
+
# email addresses.
|
17
|
+
#
|
18
|
+
# == Generated associations
|
19
|
+
#
|
20
|
+
# The following +has_many+ associations are created for models that support
|
21
|
+
# emailing:
|
22
|
+
# * +email_addresses+ - The email addresses of this model
|
23
|
+
# * +emails+ - A collection of Emails of which this model was the sender
|
24
|
+
# * +email_recipients+ - A collection of EmailRecipients in which this record is a receiver
|
25
|
+
def has_email_addresses
|
26
|
+
has_many :email_addresses,
|
27
|
+
:class_name => 'EmailAddress',
|
28
|
+
:as => :emailable,
|
29
|
+
:dependent => :destroy
|
30
|
+
|
31
|
+
# Add associations for all emails the model has sent and received
|
32
|
+
has_many :emails,
|
33
|
+
:through => :email_addresses
|
34
|
+
has_many :email_recipients,
|
35
|
+
:through => :email_addresses
|
36
|
+
|
37
|
+
include PluginAWeek::Has::Emails::InstanceMethods
|
38
|
+
end
|
39
|
+
|
40
|
+
# Adds support for emailing instances of this model through a single
|
41
|
+
# email address.
|
42
|
+
#
|
43
|
+
# == Generated associations
|
44
|
+
#
|
45
|
+
# The following associations are created for models that support emailing:
|
46
|
+
# * +email_address+ - The email address of this model
|
47
|
+
# * +emails+ - A collection of Emails of which this model was the sender
|
48
|
+
# * +email_recipients+ - A collection of EmailRecipients in which this record is a receiver
|
49
|
+
def has_email_address
|
50
|
+
has_one :email_address,
|
51
|
+
:class_name => 'EmailAddress',
|
52
|
+
:as => :emailable,
|
53
|
+
:dependent => :destroy
|
54
|
+
|
55
|
+
delegate :emails,
|
56
|
+
:email_recipients,
|
57
|
+
:to => :email_address
|
58
|
+
|
59
|
+
include PluginAWeek::Has::Emails::InstanceMethods
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
module InstanceMethods
|
64
|
+
# All emails this model has received
|
65
|
+
def received_emails
|
66
|
+
email_recipients.active.find_in_states(:all, :unread, :read, :include => :message, :conditions => ['messages.state_id = ?', Message.states.find_by_name('sent').id]).collect do |recipient|
|
67
|
+
ReceivedMessage.new(recipient)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# All emails that have not yet been sent by this model (excluding any that have been deleted)
|
72
|
+
def unsent_emails(*args)
|
73
|
+
emails.active.unsent(*args)
|
74
|
+
end
|
75
|
+
|
76
|
+
# All emails that have been sent by this model (excluding any that have been deleted)
|
77
|
+
def sent_emails(*args)
|
78
|
+
emails.active.find_in_states(:all, :queued, :sent, *args)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Contains all of the emails that have been sent and received
|
82
|
+
def email_box
|
83
|
+
@email_box ||= MessageBox.new(received_emails, unsent_emails, sent_emails)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
ActiveRecord::Base.class_eval do
|
91
|
+
include PluginAWeek::Has::Emails
|
92
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'config/boot'
|
2
|
+
|
3
|
+
$:.unshift("#{RAILS_ROOT}/../../../../../rails/plugin_dependencies/lib")
|
4
|
+
begin
|
5
|
+
require 'plugin_dependencies'
|
6
|
+
rescue Exception => e
|
7
|
+
end
|
8
|
+
|
9
|
+
Rails::Initializer.run do |config|
|
10
|
+
config.plugin_paths.concat([
|
11
|
+
"#{RAILS_ROOT}/../../..",
|
12
|
+
"#{RAILS_ROOT}/../../../../migrations",
|
13
|
+
"#{RAILS_ROOT}/../../../../../rails",
|
14
|
+
"#{RAILS_ROOT}/../../../../../test",
|
15
|
+
"#{RAILS_ROOT}/../../../../../third_party"
|
16
|
+
])
|
17
|
+
config.plugins = [
|
18
|
+
'loaded_plugins',
|
19
|
+
'appable_plugins',
|
20
|
+
'plugin_migrations',
|
21
|
+
'has_states',
|
22
|
+
'has_finder',
|
23
|
+
'has_messages',
|
24
|
+
'acts_as_tokenized',
|
25
|
+
'nested_has_many_through',
|
26
|
+
File.basename(File.expand_path("#{RAILS_ROOT}/../..")),
|
27
|
+
'dry_validity_assertions'
|
28
|
+
]
|
29
|
+
config.cache_classes = false
|
30
|
+
config.whiny_nils = true
|
31
|
+
end
|
32
|
+
|
33
|
+
Plugin.mix_code_from(:mailers => /.+_mailer/)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateDepartments < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :departments do |t|
|
4
|
+
t.column :name, :string, :null => false
|
5
|
+
t.column :email_address, :string, :null => false
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.down
|
10
|
+
drop_table :departments
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
bob:
|
2
|
+
id: 1
|
3
|
+
emailable_id: 1
|
4
|
+
emailable_type: User
|
5
|
+
spec: bob@bob.com
|
6
|
+
verification_code: c2e4f499bf610fa95b8ee3a4e8013dbe
|
7
|
+
code_expiry: <%= Time.now.to_s(:db) %>
|
8
|
+
created_at: <%= Time.now.to_s(:db) %>
|
9
|
+
updated_at: <%= Time.now.to_s(:db) %>
|
10
|
+
state_id: 601
|
11
|
+
|
12
|
+
john:
|
13
|
+
id: 2
|
14
|
+
emailable_id: 2
|
15
|
+
emailable_type: User
|
16
|
+
spec: john@john.com
|
17
|
+
verification_code: 1d3955ee0d05ce5bb847f29d56b990cc
|
18
|
+
code_expiry: <%= Time.now.to_s(:db) %>
|
19
|
+
created_at: <%= Time.now.to_s(:db) %>
|
20
|
+
updated_at: <%= Time.now.to_s(:db) %>
|
21
|
+
state_id: 602
|
22
|
+
|
23
|
+
mary:
|
24
|
+
id: 3
|
25
|
+
emailable_id: 3
|
26
|
+
emailable_type: User
|
27
|
+
spec: mary@mary.com
|
28
|
+
verification_code: 8323145e816cb063d405f5e365d14807
|
29
|
+
code_expiry: <%= Time.now.to_s(:db) %>
|
30
|
+
created_at: <%= Time.now.to_s(:db) %>
|
31
|
+
updated_at: <%= Time.now.to_s(:db) %>
|
32
|
+
state_id: 602
|
@@ -0,0 +1,85 @@
|
|
1
|
+
bob_to_john:
|
2
|
+
id: 1
|
3
|
+
message_id: 1
|
4
|
+
receiver_id: 2
|
5
|
+
receiver_type: EmailAddress
|
6
|
+
receiver_spec: john@john.com
|
7
|
+
kind: to
|
8
|
+
position: 1
|
9
|
+
state_id: 511
|
10
|
+
type: EmailRecipient
|
11
|
+
|
12
|
+
bob_to_mary:
|
13
|
+
id: 2
|
14
|
+
message_id: 1
|
15
|
+
receiver_id: 3
|
16
|
+
receiver_type: EmailAddress
|
17
|
+
receiver_spec: mary@mary.com
|
18
|
+
kind: cc
|
19
|
+
position: 1
|
20
|
+
state_id: 510
|
21
|
+
type: EmailRecipient
|
22
|
+
|
23
|
+
bob_to_random:
|
24
|
+
id: 3
|
25
|
+
message_id: 1
|
26
|
+
receiver_spec: random@random.com
|
27
|
+
kind: cc
|
28
|
+
position: 2
|
29
|
+
state_id: 510
|
30
|
+
type: EmailRecipient
|
31
|
+
|
32
|
+
bob_to_marketing:
|
33
|
+
id: 4
|
34
|
+
message_id: 1
|
35
|
+
receiver_id: 1
|
36
|
+
receiver_type: Department
|
37
|
+
receiver_spec: marketing@companyxyz.com
|
38
|
+
kind: cc
|
39
|
+
position: 3
|
40
|
+
state_id: 510
|
41
|
+
type: EmailRecipient
|
42
|
+
|
43
|
+
mary_to_john:
|
44
|
+
id: 5
|
45
|
+
message_id: 2
|
46
|
+
receiver_id: 2
|
47
|
+
receiver_type: EmailAddress
|
48
|
+
receiver_spec: john@john.com
|
49
|
+
kind: bcc
|
50
|
+
position: 1
|
51
|
+
state_id: 510
|
52
|
+
type: EmailRecipient
|
53
|
+
|
54
|
+
unsent_bob_to_john:
|
55
|
+
id: 6
|
56
|
+
message_id: 3
|
57
|
+
receiver_id: 2
|
58
|
+
receiver_type: EmailAddress
|
59
|
+
receiver_spec: john@john.com
|
60
|
+
kind: to
|
61
|
+
position: 1
|
62
|
+
state_id: 510
|
63
|
+
type: EmailRecipient
|
64
|
+
|
65
|
+
unsent_bob_to_mary:
|
66
|
+
id: 7
|
67
|
+
message_id: 3
|
68
|
+
receiver_id: 3
|
69
|
+
receiver_type: EmailAddress
|
70
|
+
receiver_spec: mary@mary.com
|
71
|
+
kind: cc
|
72
|
+
position: 1
|
73
|
+
state_id: 510
|
74
|
+
type: EmailRecipient
|
75
|
+
|
76
|
+
queued_bob_to_john:
|
77
|
+
id: 8
|
78
|
+
message_id: 4
|
79
|
+
receiver_id: 2
|
80
|
+
receiver_type: User
|
81
|
+
receiver_spec: john@john.com
|
82
|
+
kind: to
|
83
|
+
position: 1
|
84
|
+
state_id: 510
|
85
|
+
type: EmailRecipient
|
@@ -0,0 +1,52 @@
|
|
1
|
+
sent_from_bob:
|
2
|
+
id: 1
|
3
|
+
sender_id: 1
|
4
|
+
sender_type: EmailAddress
|
5
|
+
sender_spec: bob@bob.com
|
6
|
+
subject: "Funny joke"
|
7
|
+
body: "Why can't dinosaurs talk? ...Because they're dead!"
|
8
|
+
created_at: <%= Time.now.to_s(:db) %>
|
9
|
+
state_id: 502
|
10
|
+
type: Email
|
11
|
+
|
12
|
+
sent_from_mary:
|
13
|
+
id: 2
|
14
|
+
sender_id: 3
|
15
|
+
sender_type: EmailAddress
|
16
|
+
sender_spec: mary@mary.com
|
17
|
+
subject: "FW: Funny joke"
|
18
|
+
body: "> Why can't dinosaurs talk? ...Because they're dead!"
|
19
|
+
created_at: <%= Time.now.to_s(:db) %>
|
20
|
+
state_id: 502
|
21
|
+
type: Email
|
22
|
+
|
23
|
+
unsent_from_bob:
|
24
|
+
id: 3
|
25
|
+
sender_id: 1
|
26
|
+
sender_type: EmailAddress
|
27
|
+
sender_spec: bob@bob.com
|
28
|
+
subject: "Another funny joke"
|
29
|
+
body: "Where do cows go on a date? ...To the moovies!"
|
30
|
+
created_at: <%= Time.now.to_s(:db) %>
|
31
|
+
state_id: 500
|
32
|
+
type: Email
|
33
|
+
|
34
|
+
queued_from_bob:
|
35
|
+
id: 4
|
36
|
+
sender_id: 1
|
37
|
+
sender_type: EmailAddress
|
38
|
+
sender_spec: bob@bob.com
|
39
|
+
subject: ""
|
40
|
+
body: ""
|
41
|
+
created_at: <%= Time.now.to_s(:db) %>
|
42
|
+
state_id: 501
|
43
|
+
type: Email
|
44
|
+
|
45
|
+
unsent_from_stranger:
|
46
|
+
id: 5
|
47
|
+
sender_spec: stranger@somewhere.com
|
48
|
+
subject: "Do you know where I am?"
|
49
|
+
body: "Just wondering..."
|
50
|
+
created_at: <%= Time.now.to_s(:db) %>
|
51
|
+
state_id: 500
|
52
|
+
type: Email
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# Emails
|
2
|
+
sent_from_bob_unsent:
|
3
|
+
id: 1
|
4
|
+
stateful_id: 1
|
5
|
+
stateful_type: Email
|
6
|
+
to_state_id: 500
|
7
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
8
|
+
|
9
|
+
sent_from_bob_sent:
|
10
|
+
id: 2
|
11
|
+
stateful_id: 1
|
12
|
+
stateful_type: Email
|
13
|
+
from_state_id: 500
|
14
|
+
to_state_id: 502
|
15
|
+
event_id: 500
|
16
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
17
|
+
|
18
|
+
sent_from_mary_unsent:
|
19
|
+
id: 3
|
20
|
+
stateful_id: 2
|
21
|
+
stateful_type: Email
|
22
|
+
to_state_id: 500
|
23
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
24
|
+
|
25
|
+
sent_from_mary_sent:
|
26
|
+
id: 4
|
27
|
+
stateful_id: 2
|
28
|
+
stateful_type: Email
|
29
|
+
from_state_id: 500
|
30
|
+
to_state_id: 502
|
31
|
+
event_id: 500
|
32
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
33
|
+
|
34
|
+
unsent_from_bob_unsent:
|
35
|
+
id: 5
|
36
|
+
stateful_id: 3
|
37
|
+
stateful_type: Email
|
38
|
+
to_state_id: 500
|
39
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
40
|
+
|
41
|
+
queued_from_bob_unsent:
|
42
|
+
id: 6
|
43
|
+
stateful_id: 4
|
44
|
+
stateful_type: Email
|
45
|
+
to_state_id: 500
|
46
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
47
|
+
|
48
|
+
queued_from_bob_queued:
|
49
|
+
id: 7
|
50
|
+
stateful_id: 4
|
51
|
+
stateful_type: Email
|
52
|
+
from_state_id: 500
|
53
|
+
to_state_id: 501
|
54
|
+
event_id: 501
|
55
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
56
|
+
|
57
|
+
unsent_from_stranger_unsent:
|
58
|
+
id: 8
|
59
|
+
stateful_id: 5
|
60
|
+
stateful_type: Email
|
61
|
+
to_state_id: 500
|
62
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
63
|
+
|
64
|
+
# EmailRecipients
|
65
|
+
bob_to_john_unread:
|
66
|
+
id: 9
|
67
|
+
stateful_id: 1
|
68
|
+
stateful_type: EmailRecipient
|
69
|
+
to_state_id: 510
|
70
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
71
|
+
|
72
|
+
bob_to_john_read:
|
73
|
+
id: 10
|
74
|
+
stateful_id: 1
|
75
|
+
stateful_type: EmailRecipient
|
76
|
+
from_state_id: 510
|
77
|
+
to_state_id: 511
|
78
|
+
event_id: 510
|
79
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
80
|
+
|
81
|
+
bob_to_mary_unread:
|
82
|
+
id: 11
|
83
|
+
stateful_id: 2
|
84
|
+
stateful_type: EmailRecipient
|
85
|
+
to_state_id: 510
|
86
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
87
|
+
|
88
|
+
bob_to_random_unread:
|
89
|
+
id: 12
|
90
|
+
stateful_id: 3
|
91
|
+
stateful_type: EmailRecipient
|
92
|
+
to_state_id: 510
|
93
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
94
|
+
|
95
|
+
bob_to_marketing_unread:
|
96
|
+
id: 13
|
97
|
+
stateful_id: 4
|
98
|
+
stateful_type: EmailRecipient
|
99
|
+
to_state_id: 510
|
100
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
101
|
+
|
102
|
+
mary_to_john_unread:
|
103
|
+
id: 14
|
104
|
+
stateful_id: 5
|
105
|
+
stateful_type: EmailRecipient
|
106
|
+
to_state_id: 510
|
107
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
108
|
+
|
109
|
+
unsent_bob_to_john_unread:
|
110
|
+
id: 15
|
111
|
+
stateful_id: 6
|
112
|
+
stateful_type: EmailRecipient
|
113
|
+
to_state_id: 510
|
114
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
115
|
+
|
116
|
+
unsent_bob_to_mary_unread:
|
117
|
+
id: 16
|
118
|
+
stateful_id: 7
|
119
|
+
stateful_type: EmailRecipient
|
120
|
+
to_state_id: 510
|
121
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
122
|
+
|
123
|
+
queued_bob_to_john_unread:
|
124
|
+
id: 17
|
125
|
+
stateful_id: 8
|
126
|
+
stateful_type: EmailRecipient
|
127
|
+
to_state_id: 510
|
128
|
+
occurred_at: <%= Time.now.to_s(:db) %>
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# Load local repository plugin paths
|
2
|
+
$:.unshift("#{File.dirname(__FILE__)}/../../../associations/class_associations/lib")
|
3
|
+
$:.unshift("#{File.dirname(__FILE__)}/../../../has/has_messages/lib")
|
4
|
+
$:.unshift("#{File.dirname(__FILE__)}/../../../has/has_states/lib")
|
5
|
+
$:.unshift("#{File.dirname(__FILE__)}/../../../miscellaneous/custom_callbacks/lib")
|
6
|
+
$:.unshift("#{File.dirname(__FILE__)}/../../../miscellaneous/dry_transaction_rollbacks/lib")
|
7
|
+
$:.unshift("#{File.dirname(__FILE__)}/../../../validations/validates_as_email_address/lib")
|
8
|
+
$:.unshift("#{File.dirname(__FILE__)}/../../../../ruby/object/eval_call/lib")
|
9
|
+
$:.unshift("#{File.dirname(__FILE__)}/../../../../third_party/acts_as_tokenized/lib")
|
10
|
+
$:.unshift("#{File.dirname(__FILE__)}/../../../../third_party/nested_has_many_through/lib")
|
11
|
+
|
12
|
+
# Load the plugin testing framework
|
13
|
+
$:.unshift("#{File.dirname(__FILE__)}/../../../../test/plugin_test_helper/lib")
|
14
|
+
require 'rubygems'
|
15
|
+
require 'plugin_test_helper'
|
16
|
+
|
17
|
+
# Run the plugin migrations
|
18
|
+
%w(has_states has_messages has_emails).each do |plugin|
|
19
|
+
Rails.plugins[plugin].migrate
|
20
|
+
end
|
21
|
+
|
22
|
+
# Run the test app migrations
|
23
|
+
ActiveRecord::Migrator.migrate("#{RAILS_ROOT}/db/migrate")
|
24
|
+
|
25
|
+
# Bootstrap the database
|
26
|
+
%w(has_messages has_emails).each do |plugin|
|
27
|
+
plugin = Rails.plugins[plugin]
|
28
|
+
bootstrap_path = "#{plugin.migration_path}/../bootstrap"
|
29
|
+
|
30
|
+
Dir.glob("#{bootstrap_path}/*.{yml,csv}").each do |fixture_file|
|
31
|
+
table_name = File.basename(fixture_file, '.*')
|
32
|
+
Fixtures.new(ActiveRecord::Base.connection, table_name, nil, File.join(bootstrap_path, table_name)).insert_fixtures
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Test::Unit::TestCase #:nodoc:
|
37
|
+
def self.require_fixture_classes(table_names=nil)
|
38
|
+
# Don't allow fixture classes to be required because classes like Message are
|
39
|
+
# going to throw an error since the states and events have not yet been
|
40
|
+
# loaded
|
41
|
+
end
|
42
|
+
|
43
|
+
# Freezes time for running email tests
|
44
|
+
def freeze_time(frozen_time = 946702800)
|
45
|
+
Time.instance_eval do
|
46
|
+
frozen_now = (frozen_time)
|
47
|
+
alias :original_now :now
|
48
|
+
alias :now :frozen_now
|
49
|
+
end
|
50
|
+
|
51
|
+
if block_given?
|
52
|
+
begin
|
53
|
+
yield
|
54
|
+
ensure
|
55
|
+
unfreeze_time
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Restores the original method for time
|
61
|
+
def unfreeze_time
|
62
|
+
Time.instance_eval do
|
63
|
+
alias :now :original_now
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Time
|
69
|
+
def self.frozen_now=(val)
|
70
|
+
@frozen_now = val
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.frozen_now
|
74
|
+
Time.at(@frozen_now || 946702800)
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class ApplicationMailerTest < Test::Unit::TestCase
|
4
|
+
fixtures :users, :email_addresses, :messages, :message_recipients, :state_changes
|
5
|
+
|
6
|
+
class TestMailer < ApplicationMailer
|
7
|
+
def signed_up(recipient)
|
8
|
+
recipients recipient
|
9
|
+
subject 'Thanks for signing up'
|
10
|
+
from 'welcome@mywebapp.com'
|
11
|
+
cc 'nobody@mywebapp.com'
|
12
|
+
bcc 'root@mywebapp.com'
|
13
|
+
body 'Congratulations!'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def setup
|
18
|
+
ActionMailer::Base.delivery_method = :test
|
19
|
+
ActionMailer::Base.perform_deliveries = true
|
20
|
+
ActionMailer::Base.raise_delivery_errors = true
|
21
|
+
ActionMailer::Base.deliveries = []
|
22
|
+
|
23
|
+
@original_logger = TestMailer.logger
|
24
|
+
@recipient = email_addresses(:bob)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_should_use_camelized_application_name_for_default_subject_prefix
|
28
|
+
assert_equal '[AppRoot] ', ApplicationMailer.default_subject_prefix
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_should_queue_email
|
32
|
+
assert_nothing_raised { TestMailer.queue_signed_up(@recipient) }
|
33
|
+
assert_equal 6, Email.count
|
34
|
+
|
35
|
+
email = Email.find(6)
|
36
|
+
assert_equal '[AppRoot] Thanks for signing up', email.subject
|
37
|
+
assert_equal 'Congratulations!', email.body
|
38
|
+
assert_equal [@recipient], email.to.map(&:receiver)
|
39
|
+
assert_equal 'welcome@mywebapp.com', email.sender
|
40
|
+
assert_equal ['nobody@mywebapp.com'], email.cc.map(&:receiver)
|
41
|
+
assert_equal ['root@mywebapp.com'], email.bcc.map(&:receiver)
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_should_deliver_email
|
45
|
+
freeze_time do
|
46
|
+
expected = new_mail
|
47
|
+
expected.to = 'john@john.com'
|
48
|
+
expected.cc = 'mary@mary.com'
|
49
|
+
expected.subject = 'Another funny joke'
|
50
|
+
expected.body = 'Where do cows go on a date? ...To the moovies!'
|
51
|
+
expected.from = 'bob@bob.com'
|
52
|
+
expected.date = Time.now
|
53
|
+
|
54
|
+
assert_nothing_raised { ApplicationMailer.deliver_email(messages(:unsent_from_bob)) }
|
55
|
+
assert_not_nil ActionMailer::Base.deliveries.first
|
56
|
+
assert_equal expected.encoded, ActionMailer::Base.deliveries.first.encoded
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def new_mail( charset="utf-8" )
|
62
|
+
mail = TMail::Mail.new
|
63
|
+
mail.mime_version = "1.0"
|
64
|
+
if charset
|
65
|
+
mail.set_content_type "text", "plain", { "charset" => charset }
|
66
|
+
end
|
67
|
+
mail
|
68
|
+
end
|
69
|
+
end
|