mailfactory-acd 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bd5c22dcb9829217553cb8cfc66edb342495913f
4
+ data.tar.gz: 487f01301096879b20b0f7090075d27aeec88f2c
5
+ SHA512:
6
+ metadata.gz: c8cc09ec8c971cc04ddc2a4a3675c13b17fe8bcaeb172f32221f6e1a04df7b353f733867c39ec03acd5336b22e047af4cef5fa9cd4a13535d2621b71f51740b9
7
+ data.tar.gz: 4df58e799a254ee4a809e20abe0917c7688f164ba794d50a7c8085987b550ab8c29423d0c9db119e44c142a90495814e8e067c4750a3eba85ed0f7f26e7b8508
@@ -0,0 +1,465 @@
1
+ # = Overview:
2
+ # A simple to use module for generating RFC compliant MIME mail
3
+ # ---
4
+ # = License:
5
+ # Author:: David Powers
6
+ # Copyright:: May, 2005
7
+ # License:: Ruby License
8
+ # ---
9
+ # = Usage:
10
+ # require 'net/smtp'
11
+ # require 'rubygems'
12
+ # require 'mailfactory'
13
+ #
14
+ #
15
+ # mail = MailFactory.new()
16
+ # mail.to = "test@test.com"
17
+ # mail.from = "sender@sender.com"
18
+ # mail.subject = "Here are some files for you!"
19
+ # mail.text = "This is what people with plain text mail readers will see"
20
+ # mail.html = "A little something <b>special</b> for people with HTML readers"
21
+ # mail.attach("/etc/fstab")
22
+ # mail.attach("/some/other/file")
23
+ #
24
+ # Net::SMTP.start('smtp1.testmailer.com', 25, 'mail.from.domain', fromaddress, password, :cram_md5) { |smtp|
25
+ # mail.to = toaddress
26
+ # smtp.send_message(mail.to_s(), fromaddress, toaddress)
27
+ # }
28
+
29
+ require 'pathname'
30
+
31
+ # try to bring in the mime/types module, make a dummy module if it can't be found
32
+ begin
33
+ begin
34
+ require 'rubygems'
35
+ rescue LoadError
36
+ end
37
+ require 'mime/types'
38
+ rescue LoadError
39
+ module MIME
40
+ class Types
41
+ def Types::type_for(filename)
42
+ return('')
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ # An easy class for creating a mail message
49
+ class MailFactory
50
+
51
+ VERSION = '1.4.0'
52
+
53
+ def initialize()
54
+ @headers = Array.new()
55
+ @attachments = Array.new()
56
+ @attachmentboundary = generate_boundary()
57
+ @bodyboundary = generate_boundary()
58
+ @html = nil
59
+ @text = nil
60
+ @charset = 'utf-8'
61
+ end
62
+
63
+
64
+ # adds a header to the bottom of the headers
65
+ def add_header(header, value)
66
+ value = quoted_printable_with_instruction(value, @charset) if header == 'subject'
67
+ value = quote_address_if_necessary(value, @charset) if %w[from to cc bcc reply-to].include?(header.downcase)
68
+ @headers << "#{header}: #{value}"
69
+ end
70
+
71
+
72
+ # removes the named header - case insensitive
73
+ def remove_header(header)
74
+ @headers.each_index() { |i|
75
+ if(@headers[i] =~ /^#{Regexp.escape(header)}:/i)
76
+ @headers.delete_at(i)
77
+ end
78
+ }
79
+ end
80
+
81
+
82
+ # sets a header (removing any other versions of that header)
83
+ def set_header(header, value)
84
+ remove_header(header)
85
+ add_header(header, value)
86
+ end
87
+
88
+
89
+ def replyto=(newreplyto)
90
+ remove_header("Reply-To")
91
+ add_header("Reply-To", newreplyto)
92
+ end
93
+
94
+
95
+ def replyto()
96
+ return(get_header("Reply-To")[0])
97
+ end
98
+
99
+
100
+ # sets the plain text body of the message
101
+ def text=(newtext)
102
+ @text = newtext
103
+ end
104
+
105
+
106
+ # sets the HTML body of the message. Only the body of the
107
+ # html should be provided
108
+ def html=(newhtml)
109
+ @html = "<html>\n<head>\n<meta content=\"text/html;charset=#{@charset}\" http-equiv=\"Content-Type\">\n</head>\n<body bgcolor=\"#ffffff\" text=\"#000000\">\n#{newhtml}\n</body>\n</html>"
110
+ end
111
+
112
+
113
+ # sets the HTML body of the message. The entire HTML section should be provided
114
+ def rawhtml=(newhtml)
115
+ @html = newhtml
116
+ end
117
+
118
+
119
+ # implement method missing to provide helper methods for setting and getting headers.
120
+ # Headers with '-' characters may be set/gotten as 'x_mailer' or 'XMailer' (splitting
121
+ # will occur between capital letters or on '_' chracters)
122
+ def method_missing(methId, *args)
123
+ name = methId.id2name()
124
+
125
+ # mangle the name if we have to
126
+ if(name =~ /_/)
127
+ name = name.gsub(/_/, '-')
128
+ elsif(name =~ /[A-Z]/)
129
+ name = name.gsub(/([a-zA-Z])([A-Z])/, '\1-\2')
130
+ end
131
+
132
+ # determine if it sets or gets, and do the right thing
133
+ if(name =~ /=$/)
134
+ if(args.length != 1)
135
+ super(methId, args)
136
+ end
137
+ set_header(name[/^(.*)=$/, 1], args[0])
138
+ else
139
+ if(args.length != 0)
140
+ super(methId, args)
141
+ end
142
+ headers = get_header(name)
143
+ return(get_header(name))
144
+ end
145
+ end
146
+
147
+
148
+ # returns the value (or values) of the named header in an array
149
+ def get_header(header)
150
+ headers = Array.new()
151
+ headerregex = /^#{Regexp.escape(header)}:/i
152
+ @headers.each() { |h|
153
+ if(headerregex.match(h))
154
+ headers << h[/^[^:]+:(.*)/i, 1].strip()
155
+ end
156
+ }
157
+
158
+ return(headers)
159
+ end
160
+
161
+
162
+ # returns true if the email is multipart
163
+ def multipart?()
164
+ if(@attachments.length > 0 or @html != nil)
165
+ return(true)
166
+ else
167
+ return(false)
168
+ end
169
+ end
170
+
171
+
172
+ # builds an email and returns it as a string. Takes the following options:
173
+ # <tt>:messageid</tt>:: Adds a message id to the message based on the from header (defaults to false)
174
+ # <tt>:date</tt>:: Adds a date to the message if one is not present (defaults to true)
175
+ def construct(options = Hash.new)
176
+ if(options[:date] == nil)
177
+ options[:date] = true
178
+ end
179
+
180
+ if(options[:messageid])
181
+ # add a unique message-id
182
+ remove_header("Message-ID")
183
+ sendingdomain = get_header('from')[0].to_s()[/@([-a-zA-Z0-9._]+)/,1].to_s()
184
+ add_header("Message-ID", "<#{Time.now.to_f()}.#{Process.euid()}.#{String.new.object_id()}@#{sendingdomain}>")
185
+ end
186
+
187
+ if(options[:date])
188
+ if(get_header("Date").length == 0)
189
+ add_header("Date", Time.now.strftime("%a, %d %b %Y %H:%M:%S %z"))
190
+ end
191
+ end
192
+
193
+ # Add a mime header if we don't already have one and we have multiple parts
194
+ if(multipart?())
195
+ if(get_header("MIME-Version").length == 0)
196
+ add_header("MIME-Version", "1.0")
197
+ end
198
+
199
+ if(get_header("Content-Type").length == 0)
200
+ if(@attachments.length == 0)
201
+ add_header("Content-Type", "multipart/alternative;boundary=\"#{@bodyboundary}\"")
202
+ else
203
+ add_header("Content-Type", "multipart/mixed; boundary=\"#{@attachmentboundary}\"")
204
+ end
205
+ end
206
+ end
207
+
208
+ return("#{headers_to_s()}#{body_to_s()}")
209
+ end
210
+
211
+
212
+ # returns a formatted email - equivalent to construct(:messageid => true)
213
+ def to_s()
214
+ return(construct(:messageid => true))
215
+ end
216
+
217
+
218
+ # generates a unique boundary string
219
+ def generate_boundary()
220
+ randomstring = Array.new()
221
+ 1.upto(25) {
222
+ whichglyph = rand(100)
223
+ if(whichglyph < 40)
224
+ randomstring << (rand(25) + 65).chr()
225
+ elsif(whichglyph < 70)
226
+ randomstring << (rand(25) + 97).chr()
227
+ elsif(whichglyph < 90)
228
+ randomstring << (rand(10) + 48).chr()
229
+ elsif(whichglyph < 95)
230
+ randomstring << '.'
231
+ else
232
+ randomstring << '_'
233
+ end
234
+ }
235
+ return("----=_NextPart_#{randomstring.join()}")
236
+ end
237
+
238
+
239
+ # adds an attachment to the mail. Type may be given as a mime type. If it
240
+ # is left off and the MIME::Types module is available it will be determined automagically.
241
+ # If the optional attachemntheaders is given, then they will be added to the attachment
242
+ # boundary in the email, which can be used to produce Content-ID markers. attachmentheaders
243
+ # can be given as an Array or a String.
244
+ def add_attachment(filename, type=nil, attachmentheaders = nil)
245
+ attachment = Hash.new()
246
+ attachment['filename'] = Pathname.new(filename).basename
247
+ if(type == nil)
248
+ attachment['mimetype'] = MIME::Types.type_for(filename).to_s
249
+ else
250
+ attachment['mimetype'] = type
251
+ end
252
+
253
+ # Open in rb mode to handle Windows, which mangles binary files opened in a text mode
254
+ File.open(filename, "rb") { |fp|
255
+ attachment['attachment'] = file_encode(fp.read())
256
+ }
257
+
258
+ if(attachmentheaders != nil)
259
+ if(!attachmentheaders.kind_of?(Array))
260
+ attachmentheaders = attachmentheaders.split(/\r?\n/)
261
+ end
262
+ attachment['headers'] = attachmentheaders
263
+ end
264
+
265
+ @attachments << attachment
266
+ end
267
+
268
+
269
+ # adds an attachment to the mail as emailfilename. Type may be given as a mime type. If it
270
+ # is left off and the MIME::Types module is available it will be determined automagically.
271
+ # file may be given as an IO stream (which will be read until the end) or as a filename.
272
+ # If the optional attachemntheaders is given, then they will be added to the attachment
273
+ # boundary in the email, which can be used to produce Content-ID markers. attachmentheaders
274
+ # can be given as an Array of a String.
275
+ def add_attachment_as(file, emailfilename, type=nil, attachmentheaders = nil)
276
+ attachment = Hash.new()
277
+ attachment['filename'] = emailfilename
278
+
279
+ if(type != nil)
280
+ attachment['mimetype'] = type.to_s()
281
+ elsif(file.kind_of?(String) or file.kind_of?(Pathname))
282
+ attachment['mimetype'] = MIME::Types.type_for(file.to_s()).to_s
283
+ else
284
+ attachment['mimetype'] = ''
285
+ end
286
+
287
+ if(file.kind_of?(String) or file.kind_of?(Pathname))
288
+ # Open in rb mode to handle Windows, which mangles binary files opened in a text mode
289
+ File.open(file.to_s(), "rb") { |fp|
290
+ attachment['attachment'] = file_encode(fp.read())
291
+ }
292
+ elsif(file.respond_to?(:read))
293
+ attachment['attachment'] = file_encode(file.read())
294
+ else
295
+ raise(Exception, "file is not a supported type (must be a String, Pathnamem, or support read method)")
296
+ end
297
+
298
+ if(attachmentheaders != nil)
299
+ if(!attachmentheaders.kind_of?(Array))
300
+ attachmentheaders = attachmentheaders.split(/\r?\n/)
301
+ end
302
+ attachment['headers'] = attachmentheaders
303
+ end
304
+
305
+ @attachments << attachment
306
+ end
307
+
308
+
309
+ alias attach add_attachment
310
+ alias attach_as add_attachment_as
311
+
312
+ protected
313
+
314
+ # returns the @headers as a properly formatted string
315
+ def headers_to_s()
316
+ return("#{@headers.join("\r\n")}\r\n\r\n")
317
+ end
318
+
319
+
320
+ # returns the body as a properly formatted string
321
+ def body_to_s()
322
+ body = Array.new()
323
+
324
+ # simple message with one part
325
+ if(!multipart?())
326
+ return(@text)
327
+ else
328
+ body << "This is a multi-part message in MIME format.\r\n\r\n--#{@attachmentboundary}\r\nContent-Type: multipart/alternative; boundary=\"#{@bodyboundary}\""
329
+
330
+ if(@attachments.length > 0)
331
+ # text part
332
+ body << "#{buildbodyboundary("text/plain; charset=#{@charset}; format=flowed", 'quoted-printable')}\r\n\r\n#{quote_if_necessary(@text, @charset)}"
333
+
334
+ # html part if one is provided
335
+ if @html
336
+ body << "#{buildbodyboundary("text/html; charset=#{@charset}", 'quoted-printable')}\r\n\r\n#{quote_if_necessary(@html, @charset)}"
337
+ end
338
+
339
+ body << "--#{@bodyboundary}--"
340
+
341
+ # and, the attachments
342
+ if(@attachments.length > 0)
343
+ @attachments.each() { |attachment|
344
+ body << "#{buildattachmentboundary(attachment)}\r\n\r\n#{attachment['attachment']}"
345
+ }
346
+ body << "\r\n--#{@attachmentboundary}--"
347
+ end
348
+ else
349
+ # text part
350
+ body << "#{buildbodyboundary("text/plain; charset=#{@charset}; format=flowed", 'quoted-printable')}\r\n\r\n#{quote_if_necessary(@text, @charset)}"
351
+
352
+ # html part
353
+ body << "#{buildbodyboundary("text/html; charset=#{@charset}", 'quoted-printable')}\r\n\r\n#{quote_if_necessary(@html, @charset)}"
354
+
355
+ body << "--#{@bodyboundary}--"
356
+ end
357
+
358
+ return(body.join("\r\n\r\n"))
359
+ end
360
+ end
361
+
362
+
363
+ # builds a boundary string for including attachments in the body, expects an attachment hash as built by
364
+ # add_attachment and add_attachment_as
365
+ def buildattachmentboundary(attachment)
366
+ disposition = "Content-Disposition: inline; filename=\"#{attachment['filename']}\""
367
+ boundary = "--#{@attachmentboundary}\r\nContent-Type: #{attachment['mimetype']}; name=\"#{attachment['filename']}\"\r\nContent-Transfer-Encoding: base64\r\n#{disposition}"
368
+ if(attachment['headers'])
369
+ boundary = boundary + "\r\n#{attachment['headers'].join("\r\n")}"
370
+ end
371
+
372
+ return(boundary)
373
+ end
374
+
375
+
376
+ # builds a boundary string for inclusion in the body of a message
377
+ def buildbodyboundary(type, encoding)
378
+ return("--#{@bodyboundary}\r\nContent-Type: #{type}\r\nContent-Transfer-Encoding: #{encoding}")
379
+ end
380
+
381
+
382
+ # returns a base64 encoded version of the contents of str
383
+ def file_encode(str)
384
+ collection = Array.new()
385
+ enc = [str].pack('m')
386
+ # while(enc.length > 60)
387
+ # collection << enc.slice!(0..59)
388
+ # end
389
+ # collection << enc
390
+ # return(collection.join("\n"))
391
+ return(enc)
392
+ end
393
+
394
+
395
+ # Convert the given text into quoted printable format, with an instruction
396
+ # that the text be eventually interpreted in the given charset.
397
+
398
+ def quoted_printable_with_instruction(text, charset)
399
+ text = quoted_printable_encode_header(text)
400
+ "=?#{charset}?Q?#{text}?="
401
+ end
402
+
403
+ # rfc2045 compatible. use rfc2047 for headers (such as the Subject line) instead
404
+ def quoted_printable_encode(text)
405
+ [text].pack('M').gsub(/\n/, "\r\n").chomp.gsub(/=$/, '')
406
+ end
407
+
408
+ # Convert the given character to quoted printable format
409
+ # see http://tools.ietf.org/html/rfc2047
410
+
411
+ require 'enumerator' unless ''.respond_to? :enum_for
412
+
413
+ def quoted_printable_encode_header(text)
414
+ text.enum_for(:each_byte).map do |ord|
415
+ if ord < 128 and ord != 61 # 61 is ascii '='
416
+ ord.chr
417
+ else
418
+ '=%X' % ord
419
+ end
420
+ end.join('').
421
+ chomp.
422
+ gsub(/=$/,'').
423
+ gsub('?', '=3F').
424
+ gsub('_', '=5F').
425
+ gsub(/ /, '_')
426
+ end
427
+
428
+
429
+ # A quick-and-dirty regexp for determining whether a string contains any
430
+ # characters that need escaping.
431
+ #--
432
+ # Jun18-08: deprecated, since all multipart blocks are marked quoted-printable, quoting is required
433
+
434
+ # if !defined?(CHARS_NEEDING_QUOTING)
435
+ # CHARS_NEEDING_QUOTING = /[\000-\011\013\014\016-\037\177-\377]/
436
+ # end
437
+
438
+
439
+ # Quote the given text if it contains any "illegal" characters
440
+ def quote_if_necessary(text, charset, instruction = false)
441
+ return unless text
442
+ text = text.dup.force_encoding(Encoding::ASCII_8BIT) if text.respond_to?(:force_encoding)
443
+ #(text =~ CHARS_NEEDING_QUOTING) ? (instruction ? quoted_printable_with_instruction(text, charset) : quoted_printable_encode(text)) : text
444
+ instruction ? quoted_printable_with_instruction(text, charset) : quoted_printable_encode(text)
445
+ end
446
+
447
+
448
+ # Quote the given address if it needs to be. The address may be a
449
+ # regular email address, or it can be a phrase followed by an address in
450
+ # brackets. The phrase is the only part that will be quoted, and only if
451
+ # it needs to be. This allows extended characters to be used in the
452
+ # "to", "from", "cc", and "bcc" headers.
453
+ def quote_address_if_necessary(address, charset)
454
+ if Array === address
455
+ address.map { |a| quote_address_if_necessary(a, charset) }
456
+ elsif address =~ /^(\S.*)\s+(<.*>)$/
457
+ address = $2
458
+ phrase = quote_if_necessary($1.gsub(/^['"](.*)['"]$/, '\1'), charset, true)
459
+ "\"#{phrase}\" #{address}"
460
+ else
461
+ address
462
+ end
463
+ end
464
+
465
+ end
@@ -0,0 +1,225 @@
1
+ #!/usr/bin/env ruby
2
+ # coding:utf-8
3
+
4
+ require 'test/unit/ui/console/testrunner'
5
+ require File.dirname(__FILE__) + '/../lib/mailfactory.rb'
6
+
7
+
8
+ def get_options()
9
+ options = Hash.new()
10
+
11
+ opts = OptionParser.new() { |opts|
12
+ opts.on_tail("-h", "--help", "Print this message") {
13
+ print(opts)
14
+ exit()
15
+ }
16
+
17
+ opts.on("-s", "--smtpserver SERVER", "SMTP server to use for remote tests") { |server|
18
+ options['smtpserver'] = server
19
+ }
20
+
21
+ opts.on("-f", "--from ADDRESS", "address to send the mail from") { |address|
22
+ options['from'] = address
23
+ }
24
+
25
+ opts.on("-t", "--to ADDRESS", "address to send the mail to") { |address|
26
+ options['to'] = address
27
+ }
28
+
29
+ opts.on("-u", "--username USERNAME", "username for smtp auth (required)") { |username|
30
+ options['username'] = username
31
+ }
32
+
33
+ opts.on("-p", "--password PASSWORD", "password for smtp auth (required)") { |password|
34
+ options['password'] = password
35
+ }
36
+
37
+ }
38
+
39
+ opts.parse(ARGV)
40
+
41
+ return(options)
42
+ end
43
+
44
+
45
+
46
+ class TC_MailFactory < Test::Unit::TestCase
47
+
48
+ def setup()
49
+ @mail = MailFactory.new
50
+ end
51
+
52
+
53
+ def test_set_to
54
+ assert_nothing_raised("exception raised while setting to=") {
55
+ @mail.to = "test@test.com"
56
+ }
57
+
58
+ assert_equal(@mail.to, ["test@test.com"], "to does not equal what it was set to")
59
+
60
+ assert_nothing_raised("exception raised while setting to=") {
61
+ @mail.to = "test@test2.com"
62
+ }
63
+
64
+ # count to headers in the final message to make sure we have only one
65
+ count = 0
66
+ @mail.to_s().each_line() { |line|
67
+ if(line =~ /^To:/i)
68
+ count = count + 1
69
+ end
70
+ }
71
+ assert_equal(1, count, "Count of To: headers expected to be 1, but was #{count}")
72
+ end
73
+
74
+
75
+ def test_set_from
76
+ assert_nothing_raised("exception raised while setting from=") {
77
+ @mail.from = "test@test.com"
78
+ }
79
+
80
+ assert_equal(@mail.from, ["test@test.com"], "from does not equal what it was set to")
81
+
82
+ assert_nothing_raised("exception raised while setting from=") {
83
+ @mail.from = "test@test2.com"
84
+ }
85
+
86
+ # count to headers in the final message to make sure we have only one
87
+ count = 0
88
+ @mail.to_s().each_line() { |line|
89
+ if(line =~ /^From:/i)
90
+ count = count + 1
91
+ end
92
+ }
93
+ assert_equal(1, count, "Count of From: headers expected to be 1, but was #{count}")
94
+ end
95
+
96
+
97
+ def test_set_subject
98
+ assert_nothing_raised("exception raised while setting subject=") {
99
+ @mail.subject = "Test Subject"
100
+ }
101
+
102
+ assert_equal(["=?utf-8?Q?Test_Subject?="], @mail.subject, "subject does not equal what it was set to")
103
+
104
+ assert_nothing_raised("exception raised while setting subject=") {
105
+ @mail.subject = "A Different Subject"
106
+ }
107
+
108
+ # count to headers in the final message to make sure we have only one
109
+ count = 0
110
+ @mail.to_s().each_line() { |line|
111
+ if(line =~ /^Subject:/i)
112
+ count = count + 1
113
+ end
114
+ }
115
+ assert_equal(1, count, "Count of Subject: headers expected to be 1, but was #{count}")
116
+ end
117
+
118
+
119
+ def test_set_header
120
+ assert_nothing_raised("exception raised while setting arbitrary header") {
121
+ @mail.set_header("arbitrary", "some value")
122
+ }
123
+
124
+ assert_equal("some value", @mail.get_header("arbitrary")[0], "arbitrary header does not equal \"some value\"")
125
+
126
+ assert_nothing_raised("exception raised while setting arbitrary header with _") {
127
+ @mail.arbitrary_header = "some _ value"
128
+ }
129
+
130
+ assert_equal(["some _ value"], @mail.get_header("arbitrary-header"), "arbitrary header does not equal \"some _ value\"")
131
+ assert_equal(["some _ value"], @mail.arbitrary_header, "arbitrary header does not equal \"some _ value\"")
132
+
133
+
134
+ assert_nothing_raised("exception raised while setting arbitraryHeader") {
135
+ @mail.arbitraryHeader = "someValue"
136
+ }
137
+
138
+ assert_equal(["someValue"], @mail.get_header("arbitrary-header"), "arbitrary header does not equal \"someValue\"")
139
+ assert_equal(["someValue"], @mail.arbitraryHeader, "arbitrary header does not equal \"someValue\"")
140
+ end
141
+
142
+
143
+ def test_boundary_generator
144
+ 1.upto(50) {
145
+ assert_match(/^----=_NextPart_[a-zA-Z0-9\._]{25}$/, @mail.generate_boundary(), "illegal message boundary generated")
146
+ }
147
+ end
148
+
149
+
150
+ def test_email
151
+ @mail.to="test@test.com"
152
+ @mail.from="test@othertest.com"
153
+ @mail.subject="This is a test"
154
+ @mail.text = "This is a test message with\na few\n\nlines."
155
+
156
+ @mail.attach(File.dirname(__FILE__) + '/testfile.txt')
157
+ @mail.attach(File.dirname(__FILE__) + '/testsheet.xls')
158
+
159
+ if($options['smtpserver'] != nil and $options['to'] != nil and $options['from'] != nil)
160
+ assert_nothing_raised() {
161
+ require('net/smtp')
162
+ Net::SMTP.start($options['smtpserver'], 25, 'mail.from.domain', $options['username'], $options['password'], :cram_md5) { |smtp|
163
+ smtp.send_message(@mail.to_s(), $options['from'], $options['to'])
164
+ }
165
+ }
166
+ end
167
+ end
168
+
169
+
170
+ def test_attach_as
171
+ @mail.to="test@test.com"
172
+ @mail.from="test@othertest.com"
173
+ @mail.subject="This is a test"
174
+ @mail.text = "This is a test message with\na few\n\nlines."
175
+
176
+ @mail.add_attachment_as(File.dirname(__FILE__) + '/testfile.txt', 'newname.txt')
177
+ @mail.add_attachment_as(File.open(File.dirname(__FILE__) + '/testsheet.xls', 'rb'), 'newname.xls', 'application/vnd.ms-excel')
178
+
179
+ if($options['smtpserver'] != nil and $options['to'] != nil and $options['from'] != nil)
180
+ assert_nothing_raised() {
181
+ require('net/smtp')
182
+ Net::SMTP.start($options['smtpserver'], 25, 'mail.from.domain', $options['username'], $options['password'], :cram_md5) { |smtp|
183
+ smtp.send_message(@mail.to_s(), $options['from'], $options['to'])
184
+ }
185
+ }
186
+ end
187
+ end
188
+
189
+ def test_quoted_printable_with_instruction
190
+ @mail.to="test@test.com"
191
+ @mail.from="test@othertest.com"
192
+ @mail.subject="My email subject has a ? in it and also an = and a _ too... Also some non-quoted junk ()!@\#\{\$\%\}"
193
+ @mail.text = "This is a test message with\na few\n\nlines."
194
+ assert_equal(["=?utf-8?Q?My_email_subject_has_a_=3F_in_it_and_also_an_=3D_and_a_=5F_too..._Also_some_non-quoted_junk_()!@\#\{\$\%\}?="], @mail.subject)
195
+ end
196
+
197
+ def test_scandinavian_subject_quoting
198
+ @mail.to="test@test.com"
199
+ @mail.from="test@othertest.com"
200
+ # Three a with dots and three o with dots.
201
+ @mail.subject="\303\244\303\244\303\244\303\266\303\266\303\266"
202
+ @mail.text = "This is a test message with\na few\n\nlines."
203
+ assert_equal(["=?utf-8?Q?=C3=A4=C3=A4=C3=A4=C3=B6=C3=B6=C3=B6?="], @mail.subject)
204
+ end
205
+
206
+ def test_utf8_quoted_printable_with_instruction
207
+ @mail.to="test@test.com"
208
+ @mail.from="test@othertest.com"
209
+ @mail.subject="My email subject has a à which is utf8."
210
+ @mail.text = "This is a test message with\na few\n\nlines."
211
+ assert_equal(["=?utf-8?Q?My_email_subject_has_a_=C3=83_which_is_utf8.?="], @mail.subject)
212
+ end
213
+
214
+ def test_quoted_printable_html
215
+ @mail.to="test@test.com"
216
+ @mail.from="test@othertest.com"
217
+ @mail.subject="some html"
218
+ @mail.html="<a href=\"http://google.com\">click here</a>"
219
+ assert_match('<a href=3D"http://google.com">click here</a>', @mail.to_s)
220
+ end
221
+
222
+ end
223
+
224
+ $options = get_options()
225
+ Test::Unit::UI::Console::TestRunner.run(TC_MailFactory)
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mailfactory-acd
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.4.0
5
+ platform: ruby
6
+ authors:
7
+ - David Powers
8
+ - CJ Lazell
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-11-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mime-types
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: 1.13.1
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: 1.13.1
28
+ description: MailFactory is s simple module for producing RFC compliant mail that
29
+ can include multiple attachments, multiple body parts, and arbitrary headers
30
+ email:
31
+ - david@grayskies.net
32
+ - cjlazell@gmail.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - lib/mailfactory.rb
38
+ - tests/test_mailfactory.rb
39
+ homepage: https://github.com/acdcorp/mailfactory
40
+ licenses:
41
+ - MIT
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.2.2
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: MailFactory is a pure-ruby MIME mail generator
63
+ test_files: []