multi_mail 0.1.0 → 0.1.1
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.
- checksums.yaml +7 -0
- data/README.md +57 -34
- data/bin/multi_mail_post +71 -0
- data/lib/mail_ext/message.rb +11 -0
- data/lib/multi_mail.rb +25 -8
- data/lib/multi_mail/cloudmailin/receiver.rb +24 -3
- data/lib/multi_mail/mailgun/message.rb +6 -1
- data/lib/multi_mail/mailgun/sender.rb +4 -4
- data/lib/multi_mail/mandrill/message.rb +4 -3
- data/lib/multi_mail/mandrill/sender.rb +9 -2
- data/lib/multi_mail/message/base.rb +14 -0
- data/lib/multi_mail/postmark/message.rb +74 -0
- data/lib/multi_mail/postmark/receiver.rb +2 -1
- data/lib/multi_mail/postmark/sender.rb +54 -24
- data/lib/multi_mail/sendgrid/message.rb +4 -4
- data/lib/multi_mail/sendgrid/sender.rb +2 -2
- data/lib/multi_mail/simple/receiver.rb +31 -1
- data/lib/multi_mail/version.rb +1 -1
- data/multi_mail.gemspec +2 -1
- data/spec/cloudmailin/receiver_spec.rb +89 -84
- data/spec/fixtures/cloudmailin/json/attachment_store.txt +65 -0
- data/spec/fixtures/cloudmailin/multipart/attachment_store.txt +174 -0
- data/spec/fixtures/cloudmailin/raw/attachment_store.txt +162 -0
- data/spec/fixtures/mailgun/parsed/valid.txt +107 -101
- data/spec/fixtures/simple/invalid.txt +4 -0
- data/spec/fixtures/simple/missing.txt +4 -0
- data/spec/fixtures/simple/valid.txt +1 -1
- data/spec/mail_ext/message_spec.rb +45 -0
- data/spec/mailgun/message_spec.rb +38 -8
- data/spec/mailgun/receiver_spec.rb +104 -110
- data/spec/mailgun/sender_spec.rb +13 -7
- data/spec/mandrill/message_spec.rb +25 -1
- data/spec/mandrill/receiver_spec.rb +81 -83
- data/spec/mandrill/sender_spec.rb +13 -6
- data/spec/message/base_spec.rb +33 -1
- data/spec/postmark/message_spec.rb +292 -0
- data/spec/postmark/receiver_spec.rb +46 -48
- data/spec/postmark/sender_spec.rb +10 -10
- data/spec/sendgrid/message_spec.rb +6 -1
- data/spec/sendgrid/receiver_spec.rb +56 -58
- data/spec/sendgrid/sender_spec.rb +9 -7
- data/spec/service_spec.rb +1 -1
- data/spec/simple/receiver_spec.rb +38 -25
- data/spec/spec_helper.rb +6 -8
- metadata +185 -203
@@ -2,59 +2,57 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
require 'multi_mail/postmark/receiver'
|
3
3
|
|
4
4
|
describe MultiMail::Receiver::Postmark do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
5
|
+
let :service do
|
6
|
+
MultiMail::Receiver.new(:provider => :postmark)
|
7
|
+
end
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
def params(fixture)
|
10
|
+
MultiMail::Receiver::Postmark.parse(response('postmark', fixture))
|
11
|
+
end
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
13
|
+
describe '#transform' do
|
14
|
+
it 'should return a mail message' do
|
15
|
+
messages = service.transform(params('valid'))
|
16
|
+
messages.size.should == 1
|
17
|
+
message = messages[0]
|
18
|
+
|
19
|
+
# Headers
|
20
|
+
message.date.should == DateTime.parse('Mon, 15 Apr 2013 20:20:12 -0400')
|
21
|
+
message.from.should == ['james@opennorth.ca']
|
22
|
+
message.to.should == ['4354473e2e6ab001fa836f627a54004e+bar@inbound.postmarkapp.com']
|
23
|
+
message.subject.should == 'Test'
|
24
|
+
|
25
|
+
# Body
|
26
|
+
message.multipart?.should == true
|
27
|
+
message.parts.size.should == 4
|
28
|
+
message.parts[0].content_type.should == 'text/plain'
|
29
|
+
message.parts[1].content_type.should == 'text/html; charset=UTF-8'
|
30
|
+
message.parts[0].body.decoded.should == "bold text\n\n\n\nsome more bold text\n\n\n\nsome italic text\n\n> multiline\n> quoted\n> text\n\n\n--\nSignature block"
|
31
|
+
# @note Due to a Postmark bug, the HTML part is missing content.
|
32
|
+
message.parts[1].body.decoded.should == %(<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><b>bold text</b><div><br></div><div></div></body></html>)
|
33
|
+
|
34
|
+
# Attachments
|
35
|
+
attachment0 = message.attachments.find{|attachment| attachment.filename == 'foo.txt'}
|
36
|
+
attachment1 = message.attachments.find{|attachment| attachment.filename == 'bar.txt'}
|
37
|
+
attachment0.read.should == "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"
|
38
|
+
attachment1.read.should == "Nam accumsan euismod eros et rhoncus.\n"
|
39
|
+
|
40
|
+
# Extra Postmark parameters
|
41
|
+
message['MailboxHash'].value.should == 'bar'
|
42
|
+
message['MessageID'].value.should == 'e27500eb-142e-4ca0-8529-e32ffd9931d6'
|
43
|
+
message['Tag'].should be_nil
|
46
44
|
end
|
45
|
+
end
|
47
46
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
47
|
+
describe '#spam?' do
|
48
|
+
it 'should return true if the response is spam' do
|
49
|
+
message = service.transform(params('spam'))[0]
|
50
|
+
service.spam?(message).should == true
|
51
|
+
end
|
53
52
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
53
|
+
it 'should return false if the response is ham' do
|
54
|
+
message = service.transform(params('valid'))[0]
|
55
|
+
service.spam?(message).should == false
|
58
56
|
end
|
59
57
|
end
|
60
58
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
require 'multi_mail/postmark/sender'
|
3
2
|
|
4
3
|
# @see https://github.com/wildbit/postmark-gem/blob/master/spec/unit/postmark/handlers/mail_spec.rb
|
5
4
|
# @see https://github.com/wildbit/postmark-gem/blob/master/spec/integration/mail_delivery_method_spec.rb
|
@@ -53,14 +52,12 @@ describe MultiMail::Sender::Postmark do
|
|
53
52
|
it 'should raise an error if :api_key is missing' do
|
54
53
|
expect{
|
55
54
|
message.delivery_method MultiMail::Sender::Postmark
|
56
|
-
message.deliver
|
57
55
|
}.to raise_error(ArgumentError, "Missing required arguments: api_key")
|
58
56
|
end
|
59
57
|
|
60
58
|
it 'should raise an error if :api_key is nil' do
|
61
59
|
expect{
|
62
60
|
message.delivery_method MultiMail::Sender::Postmark, :api_key => nil
|
63
|
-
message.deliver
|
64
61
|
}.to raise_error(ArgumentError, "Missing required arguments: api_key")
|
65
62
|
end
|
66
63
|
|
@@ -81,7 +78,6 @@ describe MultiMail::Sender::Postmark do
|
|
81
78
|
|
82
79
|
it 'should send a message' do
|
83
80
|
message.deliver.should == message
|
84
|
-
message['Message-ID'].should_not be_nil # postmark gem
|
85
81
|
end
|
86
82
|
end
|
87
83
|
|
@@ -94,13 +90,13 @@ describe MultiMail::Sender::Postmark do
|
|
94
90
|
|
95
91
|
it 'should send a message' do
|
96
92
|
result = message.deliver!
|
97
|
-
result.size.should ==
|
93
|
+
result.size.should == 5
|
98
94
|
|
99
|
-
Time.parse(result[
|
100
|
-
result[
|
101
|
-
result[
|
102
|
-
result[
|
103
|
-
result[
|
95
|
+
Time.parse(result['SubmittedAt']).should be_within(2).of(Time.now)
|
96
|
+
result['To'].should == "bar@example.com"
|
97
|
+
result['MessageID'].should match(/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/)
|
98
|
+
result['ErrorCode'].should == 0
|
99
|
+
result['Message'].should == 'Test job accepted'
|
104
100
|
end
|
105
101
|
|
106
102
|
it 'should not send a message without a From header' do
|
@@ -111,6 +107,10 @@ describe MultiMail::Sender::Postmark do
|
|
111
107
|
expect{message_without_to.deliver!}.to raise_error(MultiMail::MissingRecipients, 'Zero recipients specified')
|
112
108
|
end
|
113
109
|
|
110
|
+
it 'should send a message without a subject' do
|
111
|
+
expect{message_without_subject.deliver!}.to_not raise_error
|
112
|
+
end
|
113
|
+
|
114
114
|
it 'should not send a message without a body' do
|
115
115
|
expect{message_without_body.deliver!}.to raise_error(MultiMail::MissingBody, 'Provide either email TextBody or HtmlBody or both.')
|
116
116
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
require 'multi_mail/sendgrid/message'
|
3
2
|
|
4
3
|
describe MultiMail::Message::SendGrid do
|
5
4
|
let :message do
|
@@ -239,6 +238,12 @@ describe MultiMail::Message::SendGrid do
|
|
239
238
|
hash.size.should == 13
|
240
239
|
end
|
241
240
|
|
241
|
+
it 'should return the recipients without names' do
|
242
|
+
hash = message_without_names.to_sendgrid_hash
|
243
|
+
hash[:from].should == 'foo@example.com'
|
244
|
+
hash[:to].should == ['bar@example.com', 'baz@example.com']
|
245
|
+
end
|
246
|
+
|
242
247
|
it 'should convert the message without a text body' do
|
243
248
|
message_without_text_body.to_sendgrid_hash.should == {
|
244
249
|
:to => ['bar@example.com'],
|
@@ -3,75 +3,73 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
3
3
|
require 'multi_mail/sendgrid/receiver'
|
4
4
|
|
5
5
|
describe MultiMail::Receiver::SendGrid do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
6
|
+
let :service do
|
7
|
+
MultiMail::Receiver.new(:provider => :sendgrid)
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
def params(fixture, encoding = 'UTF-8')
|
11
|
+
MultiMail::Receiver::SendGrid.parse(response('sendgrid', fixture, false, encoding))
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
describe '#transform' do
|
15
|
+
it 'should return a mail message' do
|
16
|
+
messages = service.transform(params('valid'))
|
17
|
+
messages.size.should == 1
|
18
|
+
message = messages[0]
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
# Headers
|
21
|
+
message.date.should == DateTime.parse('Mon, 15 Apr 2013 20:20:12 -0400')
|
22
|
+
message.from.should == ['james@opennorth.ca']
|
23
|
+
message.to.should == ['foo+bar@parolecitoyenne.com']
|
24
|
+
message.subject.should == 'Test'
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
26
|
+
# Body
|
27
|
+
message.multipart?.should == true
|
28
|
+
# @note SendGrid adds additional HTML parts as attachments, which is
|
29
|
+
# sensible, but it does not match the behavior of other email APIs.
|
30
|
+
message.parts.size.should == 6
|
31
|
+
message.parts[0].content_type.should == 'text/plain'
|
32
|
+
message.parts[1].content_type.should == 'text/html; charset=UTF-8'
|
33
|
+
message.parts[0].body.decoded.should == "bold text\n\n\n\nsome more bold text\n\n\n\nsome italic text\n\n> multiline\n> quoted\n> text\n\n\n--\nSignature block"
|
34
|
+
# @note Due to a SendGrid bug, the HTML part is missing content.
|
35
|
+
message.parts[1].body.decoded.should == %(<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><b>bold text</b><div><br></div><div></div></body></html>)
|
37
36
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
37
|
+
# HTML attachments
|
38
|
+
message.parts[3].content_type.should == 'text/html; filename=msg-12415-313.html'
|
39
|
+
message.parts[5].content_type.should == 'text/html; filename=msg-12415-314.html'
|
40
|
+
message.parts[3].body.decoded.should == %(<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><head></head><br><div></div><div><br></div><div><b>some more bold text</b></div><div><b><br></b></div><div><b></b></div></body></html>)
|
41
|
+
message.parts[5].body.decoded.should == %(<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><b></b></div><div><b><span class="Apple-style-span" style="font-weight: normal; "><br></span></b></div><div><b><span class="Apple-style-span" style="font-weight: normal; "><i>some italic text</i></span></b></div><div><b><span class="Apple-style-span" style="font-weight: normal; "><br></span></b></div><div><blockquote type="cite">multiline</blockquote><blockquote type="cite">quoted</blockquote><blockquote type="cite">text</blockquote></div><div><br></div><div>--</div><div>Signature block</div></body></html>)
|
43
42
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
43
|
+
# Attachments
|
44
|
+
attachment0 = message.attachments.find{|attachment| attachment.filename == 'foo.txt'}
|
45
|
+
attachment1 = message.attachments.find{|attachment| attachment.filename == 'bar.txt'}
|
46
|
+
attachment0.read.should == "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"
|
47
|
+
attachment1.read.should == "Nam accumsan euismod eros et rhoncus.\n"
|
49
48
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
49
|
+
# Extra SendGrid parameters
|
50
|
+
message['dkim'].value.should == 'none'
|
51
|
+
message['SPF'].value.should == 'pass'
|
52
|
+
message['spam_report'].value.should == "Spam detection software, running on the system \"mx3.sendgrid.net\", has\r\nidentified this incoming email as possible spam. The original message\r\nhas been attached to this so you can view it (if it isn't spam) or label\r\nsimilar future email. If you have any questions, see\r\nthe administrator of that system for details.\r\n\r\nContent preview: bold text some more bold text some italic text [...] \r\n\r\nContent analysis details: (-2.6 points, 5.0 required)\r\n\r\n pts rule name description\r\n---- ---------------------- --------------------------------------------------\r\n-0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low\r\n trust\r\n [209.85.223.172 listed in list.dnswl.org]\r\n-1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1%\r\n [score: 0.0000]\r\n 0.0 HTML_MESSAGE BODY: HTML included in message\r\n\r\n"
|
53
|
+
message['spam_score'].value.should == '-2.599'
|
54
|
+
end
|
56
55
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
56
|
+
# No postbin is capable of handling mixed encodings, and most fail to even
|
57
|
+
# display the request. http://postbin.hackyon.com/ works best, but we
|
58
|
+
# still need to hand-edit the response.
|
59
|
+
it 'should respect encodings' do
|
60
|
+
service.transform(params('encoding', 'WINDOWS-1252'))[0].text_part.decoded.should == 'World €'
|
63
61
|
end
|
62
|
+
end
|
64
63
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
64
|
+
describe '#spam?' do
|
65
|
+
it 'should return true if the response is spam' do
|
66
|
+
message = service.transform(params('spam'))[0]
|
67
|
+
service.spam?(message).should == true
|
68
|
+
end
|
70
69
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
70
|
+
it 'should return false if the response is ham' do
|
71
|
+
message = service.transform(params('valid'))[0]
|
72
|
+
service.spam?(message).should == false
|
75
73
|
end
|
76
74
|
end
|
77
75
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
require 'multi_mail/sendgrid/sender'
|
3
2
|
|
4
3
|
describe MultiMail::Sender::SendGrid do
|
5
4
|
let :message do
|
@@ -52,34 +51,37 @@ describe MultiMail::Sender::SendGrid do
|
|
52
51
|
it 'should raise an error if :api_user is missing' do
|
53
52
|
expect{
|
54
53
|
message.delivery_method MultiMail::Sender::SendGrid, :api_key => 'xxx'
|
55
|
-
message.deliver # request not sent
|
56
54
|
}.to raise_error(ArgumentError, "Missing required arguments: api_user")
|
57
55
|
end
|
58
56
|
|
59
57
|
it 'should raise an error if :api_key is missing' do
|
60
58
|
expect{
|
61
59
|
message.delivery_method MultiMail::Sender::SendGrid, :api_user => 'xxx'
|
62
|
-
message.deliver # request not sent
|
63
60
|
}.to raise_error(ArgumentError, "Missing required arguments: api_key")
|
64
61
|
end
|
65
62
|
|
66
63
|
it 'should raise an error if :api_user is nil' do
|
67
64
|
expect{
|
68
65
|
message.delivery_method MultiMail::Sender::SendGrid, :api_user => nil, :api_key => 'xxx'
|
69
|
-
message.deliver # request not sent
|
70
66
|
}.to raise_error(ArgumentError, "Missing required arguments: api_user")
|
71
67
|
end
|
72
68
|
|
73
69
|
it 'should raise an error if :api_key is nil' do
|
74
70
|
expect{
|
75
71
|
message.delivery_method MultiMail::Sender::SendGrid, :api_user => 'xxx', :api_key => nil
|
76
|
-
message.deliver # request not sent
|
77
72
|
}.to raise_error(ArgumentError, "Missing required arguments: api_key")
|
78
73
|
end
|
79
74
|
|
80
|
-
it 'should raise an error if :api_user
|
75
|
+
it 'should raise an error if :api_user is invalid' do
|
81
76
|
expect{
|
82
|
-
message.delivery_method MultiMail::Sender::SendGrid, :api_user => 'xxx', :api_key => '
|
77
|
+
message.delivery_method MultiMail::Sender::SendGrid, :api_user => 'xxx', :api_key => ENV['SENDGRID_API_KEY']
|
78
|
+
message.deliver
|
79
|
+
}.to raise_error(MultiMail::InvalidAPIKey, 'Bad username / password')
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should raise an error if :api_key is invalid' do
|
83
|
+
expect{
|
84
|
+
message.delivery_method MultiMail::Sender::SendGrid, :api_user => ENV['SENDGRID_API_USER'], :api_key => 'xxx'
|
83
85
|
message.deliver
|
84
86
|
}.to raise_error(MultiMail::InvalidAPIKey, 'Bad username / password')
|
85
87
|
end
|
data/spec/service_spec.rb
CHANGED
@@ -2,35 +2,48 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
2
|
require 'multi_mail/simple/receiver'
|
3
3
|
|
4
4
|
describe MultiMail::Receiver::Simple do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
let :service do
|
6
|
+
MultiMail::Receiver.new({
|
7
|
+
:provider => :simple,
|
8
|
+
:secret => 'foo',
|
9
|
+
})
|
10
|
+
end
|
11
|
+
|
12
|
+
def params(fixture)
|
13
|
+
MultiMail::Receiver::Simple.parse(response('simple', fixture))
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#valid?' do
|
17
|
+
it 'should return true if the response is valid' do
|
18
|
+
service.valid?(params('valid')).should == true
|
10
19
|
end
|
11
20
|
|
12
|
-
|
13
|
-
|
21
|
+
it 'should return false if the response is invalid' do
|
22
|
+
service.valid?(params('invalid')).should == false
|
14
23
|
end
|
15
24
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
25
|
+
it 'should raise an error if parameters are missing' do
|
26
|
+
expect{ service.valid?(params('missing')) }.to raise_error(IndexError)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#transform' do
|
31
|
+
it 'should return a mail message' do
|
32
|
+
message = service.transform(params('valid')['message'])[0]
|
33
|
+
|
34
|
+
# Headers
|
35
|
+
message.date.should == DateTime.parse('Thu, 27 Dec 2012 15:25:37 -0500')
|
36
|
+
message.from.should == ['james@opennorth.ca']
|
37
|
+
message.to.should == ['foo+bar@govkit.org']
|
38
|
+
message.subject.should == 'Test'
|
39
|
+
|
40
|
+
# Body
|
41
|
+
message.multipart?.should == true
|
42
|
+
message.parts.size.should == 2
|
43
|
+
message.parts[0].content_type.should == 'text/plain; charset=us-ascii'
|
44
|
+
message.parts[0].body.should == "bold text\n\n\n> multiline\n> quoted\n> text\n\n--\nSignature block"
|
45
|
+
message.parts[1].content_type.should == 'text/html; charset=us-ascii'
|
46
|
+
message.parts[1].body.should == %(<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><b>bold text</b></div><div><br></div><div><blockquote type="cite"></blockquote></div><div><blockquote type="cite">multiline</blockquote></div><blockquote type="cite"><div>quoted</div><div>text</div></blockquote><br><div>--</div><div>Signature block</div></body></html>)
|
34
47
|
end
|
35
48
|
end
|
36
49
|
end
|