mime 0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
metadata CHANGED
@@ -1,46 +1,45 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: mime
3
- version: !ruby/object:Gem::Version
4
- version: "0.1"
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
5
6
  platform: ruby
6
- authors:
7
+ authors:
7
8
  - Clint Pachl
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
-
12
- date: 2008-11-05 00:00:00 -07:00
13
- default_executable:
12
+ date: 2013-12-18 00:00:00.000000000 Z
14
13
  dependencies: []
14
+ description: ! 'A library for building RFC compliant Multipurpose Internet Mail Extensions
15
+
16
+ (MIME) messages. It can be used to construct standardized MIME messages for use
17
+
18
+ in client/server communications, such as Internet mail or HTTP
15
19
 
16
- description:
20
+ multipart/form-data transactions.
21
+
22
+ '
17
23
  email: pachl@ecentryx.com
18
24
  executables: []
19
-
20
25
  extensions: []
21
-
22
26
  extra_rdoc_files: []
23
-
24
- files:
25
- - README
27
+ files:
28
+ - README.rdoc
26
29
  - Rakefile
30
+ - mime.gemspec
27
31
  - lib/mime/headers/mime.rb
28
32
  - lib/mime/headers/internet.rb
33
+ - lib/mime/discrete_media_factory.rb
34
+ - lib/mime/error.rb
35
+ - lib/mime/header_container.rb
36
+ - lib/mime/parser.rb
29
37
  - lib/mime/content_types.rb
30
38
  - lib/mime/media_type.rb
31
39
  - lib/mime/composite_media_type.rb
32
40
  - lib/mime/discrete_media_type.rb
33
41
  - lib/mime/message.rb
34
- - lib/mime/discrete_media_factory.rb
35
- - lib/mime/error.rb
36
- - lib/mime/header_container.rb
37
- - lib/mime/parser.rb
38
42
  - lib/mime.rb
39
- - test/scaffold
40
- - test/scaffold/multipart_form_data_file.msg
41
- - test/scaffold/multipart_mixed_inline_and_attachment.msg
42
- - test/scaffold/multipart_form_data_text.msg
43
- - test/scaffold/audio.msg
44
43
  - test/scaffold/application.msg
45
44
  - test/scaffold/unknown.yyy
46
45
  - test/scaffold/video.msg
@@ -48,45 +47,48 @@ files:
48
47
  - test/scaffold/image.jpg
49
48
  - test/scaffold/book.pdf
50
49
  - test/scaffold/plain_text_email.msg
51
- - test/scaffold/multipart_alternative_related.msg
52
- - test/scaffold/multipart_alternative.msg
53
- - test/scaffold/ruby.png
54
50
  - test/scaffold/song.mp3
51
+ - test/scaffold/ruby.png
52
+ - test/scaffold/multipart_alternative.msg
53
+ - test/scaffold/multipart_alternative_related.msg
55
54
  - test/scaffold/multipart_related.msg
56
55
  - test/scaffold/multipart_mixed_inline_and_attachment2.msg
57
- - test/scaffold/multipart_form_data_file_and_text.msg
58
56
  - test/scaffold/image.msg
59
- - test/scaffold/multipart_form_data_mixed.msg
57
+ - test/scaffold/multipart_form_data_file_and_text.msg
60
58
  - test/scaffold/data.xml
59
+ - test/scaffold/multipart_form_data_mixed.msg
61
60
  - test/scaffold/text.msg
62
- - test/scaffold/index.html
63
61
  - test/scaffold/main.css
64
- - test/mime_test.rb
65
- has_rdoc: true
66
- homepage: mime.rubyforge.org
62
+ - test/scaffold/multipart_mixed_inline_and_attachment.msg
63
+ - test/scaffold/multipart_form_data_text.msg
64
+ - test/scaffold/audio.msg
65
+ - test/scaffold/data.htm
66
+ - test/test_mime.rb-try
67
+ - test/test_mime.rb
68
+ homepage: http://ecentryx.com/gems/mime
69
+ licenses:
70
+ - ISC
67
71
  post_install_message:
68
72
  rdoc_options: []
69
-
70
- require_paths:
73
+ require_paths:
71
74
  - lib
72
- required_ruby_version: !ruby/object:Gem::Requirement
73
- requirements:
74
- - - ">="
75
- - !ruby/object:Gem::Version
76
- version: "0"
77
- version:
78
- required_rubygems_version: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: "0"
83
- version:
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
84
87
  requirements: []
85
-
86
- rubyforge_project: mime
87
- rubygems_version: 1.3.0
88
+ rubyforge_project:
89
+ rubygems_version: 1.8.23
88
90
  signing_key:
89
- specification_version: 2
91
+ specification_version: 3
90
92
  summary: Multipurpose Internet Mail Extensions (MIME) Library
91
- test_files:
92
- - test/mime_test.rb
93
+ test_files:
94
+ - test/test_mime.rb
data/README DELETED
@@ -1,256 +0,0 @@
1
- == Multipurpose Internet Mail Extensions (MIME)
2
-
3
- A library for building RFC compliant Multipurpose Internet Mail Extensions
4
- (MIME) messages. It can be used to construct standardized MIME messages for use
5
- in client/server communications, such as Internet mail or HTTP
6
- multipart/form-data transactions.
7
-
8
-
9
- == See
10
-
11
- * MIME for RFCs used to implement the library (other RFCs scattered throughout)
12
- * MIME::CompositeMediaType for a description of composite media types
13
- * MIME::DiscreteMediaType for a description of discrete media types
14
- * MIME::DiscreteMediaFactory for easy programming of discrete media types
15
-
16
-
17
- == Media Type Inheritance Heirarchy
18
-
19
- MediaType*
20
- ^
21
- |
22
- |--DiscreteMediaType*
23
- | ^
24
- | |
25
- | |--ApplicationMedia
26
- | |--AudioMedia
27
- | |--ImageMedia
28
- | |--TextMedia
29
- | +--VideoMedia
30
- |
31
- +--CompositeMediaType*
32
- ^
33
- |
34
- |--MessageMedia**
35
- | ^
36
- | |
37
- | |--ExternalBody**
38
- | |--Partial**
39
- | +--RFC822**
40
- |
41
- +--MultipartMedia*
42
- ^
43
- |
44
- |--Alternative
45
- |--Digest**
46
- |--Encrypted**
47
- |--FormData
48
- |--Mixed
49
- |--Parallel**
50
- |--Related
51
- |--Report**
52
- +--Signed**
53
-
54
- * Abstract Class
55
- ** Not implemented
56
-
57
-
58
- == MIME Message Structure
59
-
60
-
61
- ---------------------+
62
- +----------------+ |
63
- | RFC822 & MIME | |
64
- | Message Headers| |
65
- +----------------+ |
66
- ---+ |
67
- +----------------+ | |
68
- | MIME Headers | | |
69
- +----------------+ |---MIME Entity |
70
- +----------------+ | (N) |
71
- | Body | | |---RFC822 Message
72
- +----------------+ | |
73
- ---+ |
74
- ---+ |
75
- +----------------+ | |
76
- | MIME Headers | | |
77
- +----------------+ |---MIME Entity |
78
- +----------------+ | (N+1) |
79
- | Body | | |
80
- +----------------+ | |
81
- ---+ |
82
- ---------------------+
83
-
84
- Each <em>MIME Entity</em> must be a discrete (MIME::DiscreteMediaType) or
85
- composite (MIME::CompositeMediaType) media type. Because MIME is recursive,
86
- composite entity bodies may contain other composite or discrete entites and so
87
- on. However, discrete entities are non-recursive and contain only non-MIME
88
- bodies.
89
-
90
-
91
- == Examples
92
-
93
- <em>The following examples imply that the MIME module is included.</em>
94
-
95
-
96
- === Two ways to instantiate a DiscreteMediaType object using a file path
97
-
98
- fpath = '/tmp/data.xml'
99
- text_media = open(fpath) {|f| TextMedia.new(f.read, 'text/xml')}
100
- text_media = DiscreteMediaFactory.create(fpath)
101
-
102
-
103
- === Simple text/plain RFC822 email
104
-
105
- msg = Message.new # creates a blank message with date and message ID headers
106
- msg.date = (Time.now - 3600).rfc2822 # specify a different date
107
- msg.subject = 'This is important'
108
- msg.headers.add('X-Priority', 'high') # custom header
109
-
110
- msg.body = TextMedia.new('hello, it is me!')
111
- #
112
- # The following snippets are equivalent to the previous line.
113
- #
114
- # msg.body = "\r\nhello, it is me!"
115
- # msg.header.add('Content-Type', 'text/plain; charset=us-ascii')
116
- #
117
- # --OR--
118
- #
119
- # msg.body = "Content-Type: text/plain; charset=us-ascii\r\n\r\nhello, it is me!"
120
-
121
- msg.to = {
122
- 's13xj@x.com' => nil, # no name display
123
- 'james@x.com' => 'James',
124
- 'clint@x.com' => 'Clint',
125
- }
126
- msg.from = {
127
- 'theboss@x.com' => 'Boss Man'
128
- }
129
-
130
- msg.to_s # ready to be sent via SMTP
131
-
132
-
133
- === Plain text multipart/mixed message with a file attachment
134
-
135
- The multipart/mixed content type can be used to aggregate multiple unrelated
136
- entities.
137
-
138
- text = DiscreteMediaFactory.create('/tmp/data.txt')
139
- image = DiscreteMediaFactory.create('/tmp/ruby.png')
140
-
141
- mixed_msg = MultipartMedia::Mixed.new
142
- mixed_msg.attach_entity(image)
143
- mixed_msg.add_entity(text)
144
- mixed_msg.to_s
145
-
146
-
147
- === Plain text and HTML multipart/alternative MIME message
148
-
149
- The multipart/alternative content type allows for multiple alternatively
150
- formatted versions of the same content. Clients are then responsible for
151
- choosing the most suitable version for display.
152
-
153
- text_msg = TextMedia.new(<<-text_data, 'text/plain')
154
- *Headline*
155
- Ruby is cool!
156
- text_data
157
-
158
- html_msg = TextMedia.new(<<-html_data, 'text/html')
159
- <html>
160
- <body>
161
- <h1>Headline</h1>
162
- <p>Ruby is cool!</p>
163
- </body>
164
- </html>
165
- html_data
166
-
167
- msg = MultipartMedia::Alternative.new
168
- msg.add_entity(html_msg) # most complex representation must be added first
169
- msg.add_entity(text_msg)
170
- msg.to_s
171
-
172
-
173
- === HTML multipart/related MIME email with embedded image
174
-
175
- Sometimes it is desirable to send a document that is made up of many separate
176
- parts. For example, an HTML page with embedded images. The multipart/related
177
- content type aggregates all the parts and creates the means for the root entity
178
- to reference the other entities.
179
-
180
- image = DiscreteMediaFactory.create('/tmp/ruby.png')
181
- image.content_transfer_encoding = 'binary'
182
-
183
- html_msg = TextMedia.new(<<-html_data, 'text/html; charset=iso-8859-1')
184
- <html>
185
- <body>
186
- <h1>Ruby Image</h1>
187
- <p>Check out this cool pic.</p>
188
- <img alt="cool ruby" src="cid:#{image.content_id}"/>
189
- <p>Wasn't it cool?</p>
190
- </body>
191
- </html>
192
- html_data
193
- html_msg.content_transfer_encoding = '7bit'
194
-
195
- related_msg = MultipartMedia::Related.new
196
- related_msg.inline_entity(image)
197
- related_msg.add_entity(html_msg)
198
-
199
- email_msg = Message.new(related_msg)
200
- email_msg.to = {'joe@domain.com' => 'Joe Schmo'}
201
- email_msg.from = {'john@domain.com' => 'John Doe'}
202
- email_msg.subject = 'Ruby is cool'
203
- email_msg.to_s
204
-
205
-
206
- === HTML form with file upload using multipart/form-data encoding
207
-
208
- This example builds a representation of an HTML form that can be POSTed to an
209
- HTTP server. It contains a single text input and a file input.
210
-
211
- name_field = TextMedia.new('Joe Blow')
212
-
213
- portrait_filename = '/tmp/joe_portrait.jpg'
214
- portrait_field = open(portrait_filename) do |f|
215
- ImageMedia.new(f.read, 'image/jpeg') # explicit content type
216
- end
217
- portrait_field.content_transfer_encoding = 'binary'
218
-
219
- form_data = MultipartMedia::FormData.new
220
- form_data.add_entity(name_field, 'name')
221
- form_data.add_entity(portrait_field, 'portrait', portrait_filename) # explicity filename
222
- form_data.to_s
223
-
224
-
225
- === HTML form with file upload using multipart/form-data encoding (DiscreteMediaFactory)
226
-
227
- The outcome of this example is identical to the previous example. The only
228
- semantic difference is that the MIME::DiscreteMediaFactory class is used to
229
- automatically instantiate the MIME::MediaType object.
230
-
231
- name_field = TextMedia.new('Joe Blow')
232
-
233
- portrait_field = DiscreteMediaFactory.create('/tmp/joe_portrait.jpg') # no explicit content type
234
- portrait_field.content_transfer_encoding = 'binary'
235
-
236
- form_data = MultipartMedia::FormData.new
237
- form_data.add_entity(name_field, 'name')
238
- form_data.add_entity(portrait_field, 'portrait') # no explicit filename
239
- form_data.to_s
240
-
241
-
242
- == More Examples
243
-
244
- For many more examples, check the test class MIMETest.
245
-
246
-
247
- == Contact
248
-
249
- Please email inquiries to pachl at ecentryx dot com.
250
-
251
- [Home Page] http://mime.rubyforge.org/
252
- [RubyForge] http://rubyforge.org/projects/mime/
253
-
254
- == License
255
-
256
- The entire MIME library is free to use under the terms of the Ruby license.
@@ -1,386 +0,0 @@
1
- require 'mime'
2
- require 'test/unit'
3
-
4
- class MIMETest < Test::Unit::TestCase
5
-
6
- include MIME
7
-
8
- def test_make_top_level_rfc2822_message
9
- data = "\r\nmessage body"
10
- rfc2822_msg = Message.new
11
- rfc2822_msg.body = data
12
- expected_msg =
13
- "Message-ID: <993708956@989739608>\r\n"\
14
- "Date: Wed, 24 Oct 2008 15:45:31 -0700\r\n"\
15
- "MIME-Version: 1.0 (Ruby MIME v0.1)\r\n"\
16
- "\r\nmessage body\r\n"
17
-
18
- assert_equal_mime_message expected_msg, rfc2822_msg.to_s
19
- end
20
-
21
- def test_make_audio_message
22
- audio = '0110000101110101011001000110100101101111'
23
- audio_media = AudioMedia.new(audio, 'audio/midi')
24
- audio_media.content_transfer_encoding = 'binary'
25
-
26
- mime_msg = Message.new(audio_media).to_s
27
- expected_mime_msg = IO.read(sd('/audio.msg'))
28
-
29
- assert_equal_mime_message expected_mime_msg, mime_msg
30
- end
31
-
32
- def test_make_application_message
33
- application = '011000100110100101101110011000010111001001111001'
34
- application_media = ApplicationMedia.new(application)
35
- application_media.content_transfer_encoding = 'binary'
36
-
37
- mime_msg = Message.new(application_media).to_s
38
- expected_mime_msg = IO.read(sd('/application.msg'))
39
-
40
- assert_equal_mime_message expected_mime_msg, mime_msg
41
- end
42
-
43
- def test_make_image_message
44
- image = IO.read(sd('/image.jpg'))
45
- image_media = ImageMedia.new(image)
46
- image_media.content_type = 'image/jpeg'
47
- image_media.content_transfer_encoding = 'binary'
48
-
49
- mime_msg = Message.new(image_media).to_s
50
- expected_mime_msg = IO.read(sd('/image.msg'))
51
-
52
- assert_equal_mime_message expected_mime_msg, mime_msg
53
- end
54
-
55
- def test_make_text_message
56
- text = 'a plain text message'
57
- mime_msg = Message.new(TextMedia.new(text)).to_s
58
- expected_mime_msg = IO.read(sd('/text.msg'))
59
-
60
- assert_equal_mime_message expected_mime_msg, mime_msg
61
- end
62
-
63
- def test_make_video_message
64
- video = '0111011001101001011001000110010101101111'
65
- video_media = VideoMedia.new(video)
66
- video_media.content_type = 'video/mpeg'
67
- video_media.content_transfer_encoding = 'binary'
68
-
69
- mime_msg = Message.new(video_media).to_s
70
- expected_mime_msg = IO.read(sd('/video.msg'))
71
-
72
- assert_equal_mime_message expected_mime_msg, mime_msg
73
- end
74
-
75
- def test_no_instantiation_of_abstract_classes
76
- e = AbstractClassError
77
- assert_raise(e) {MediaType.new(nil, nil)}
78
- assert_raise(e) {DiscreteMediaType.new(nil)}
79
- assert_raise(e) {CompositeMediaType.new(nil)}
80
- assert_raise(e) {MultipartMedia.new(nil)}
81
- end
82
-
83
- def test_multipart_form_data_with_text_entities
84
- t1 = TextMedia.new('this is t1')
85
- t2 = TextMedia.new('this is t2', 'text/enhanced')
86
- t3 = open(sd('/index.html')) {|f| TextMedia.new(f.read, 'text/html')}
87
- t4 = open(sd('/data.xml')) {|f| TextMedia.new(f.read, 'text/xml')}
88
-
89
- form_data = MultipartMedia::FormData.new
90
- form_data.add_entity t1, 'txt1'
91
- form_data.add_entity t2, 'txt2'
92
- form_data.add_entity t3, 'txt3'
93
- form_data.add_entity t3, 'txt3'
94
-
95
- expected = IO.read(sd('/multipart_form_data_text.msg'))
96
-
97
- assert_equal_mime_message expected, form_data.to_s
98
- end
99
-
100
- def test_multipart_form_data_with_file_entities
101
- img1 = sd('/image.jpg')
102
- img2 = sd('/ruby.png')
103
- f1 = open(img1) {|f| ImageMedia.new(f.read, 'image/jpeg')}
104
- f2 = open(img2) {|f| ImageMedia.new(f.read, 'image/png')}
105
-
106
- f1.content_transfer_encoding = 'binary'
107
- f2.content_transfer_encoding = 'binary'
108
-
109
- form_data = MultipartMedia::FormData.new
110
- form_data.add_entity f1, 'file1', img1
111
- form_data.add_entity f2, 'file2', img2
112
-
113
- expected = IO.read(sd('/multipart_form_data_file.msg'))
114
-
115
- assert_equal_mime_message expected, form_data.to_s
116
- end
117
-
118
- def test_multipart_form_data_with_file_and_text_entities
119
- t1 = TextMedia.new('this is t1')
120
- t2 = TextMedia.new('this is t2', 'text/enhanced')
121
-
122
- img1 = sd('/image.jpg')
123
- f1 = open(img1) {|f| ImageMedia.new(f.read, 'image/jpeg')}
124
- f1.content_transfer_encoding = 'binary'
125
-
126
- form_data = MultipartMedia::FormData.new
127
- form_data.add_entity t1, 'txt1'
128
- form_data.add_entity t2, 'txt2'
129
- form_data.add_entity f1, 'img1', img1
130
-
131
- expected = IO.read(sd('/multipart_form_data_file_and_text.msg'))
132
-
133
- assert_equal_mime_message expected, form_data.to_s
134
- end
135
-
136
- def test_construction_of_plain_text_email_message
137
- email_msg = Message.new
138
- email_msg.to = {
139
- 'person1@domain.com' => 'Harry',
140
- 'person2@domain.com' => nil,
141
- 'person3@domain.com' => 'Mary'
142
- }
143
- email_msg.cc = {'Head Honcho' => 'bossman@domain.com'}
144
- email_msg.from = 'person4@domain.com'
145
- email_msg.subject = 'This is an important email'
146
- #TODO - what do we do about this body thing???????? raw_body= and body=
147
- email_msg.body = "\r\nThis is the all important email body"
148
- #email_msg.body = TextMedia.new("This is the all important email body")
149
-
150
- expected = IO.read(sd('/plain_text_email.msg'))
151
-
152
- assert_equal_mime_message expected, email_msg.to_s
153
- end
154
-
155
- def test_content_type_detection
156
- (o = Object.new).extend(ContentTypes)
157
-
158
- # test using file path
159
- assert_equal 'application/pdf', o.file_type('book.pdf')
160
- assert_equal 'audio/mpeg', o.file_type('/tmp/song.mp3')
161
- assert_equal 'text/css', o.file_type('/tmp/main.css')
162
- assert_equal 'video/quicktime', o.file_type('mini.mov')
163
- assert_equal 'application/octet-stream', o.file_type('dsk.iso')
164
- assert_equal nil, o.file_type('file.yyy')
165
-
166
- # test using file object
167
- img_file = sd('/ruby.png')
168
- img_type = open(img_file) {|f| o.file_type(f)}
169
- assert_equal 'image/png', img_type
170
- assert_not_equal 'image/jpeg', img_type
171
- end
172
-
173
- def test_object_instantiation_using_discrete_media_factory
174
- application_file = sd('/book.pdf')
175
- audio_file = sd('/song.mp3')
176
- text_file = sd('/data.xml')
177
- video_file = sd('/mini.mov')
178
- image_file = sd('/image.jpg')
179
- unknown_file = sd('/unknown.yyy')
180
-
181
- dmf = DiscreteMediaFactory
182
-
183
- # test using file path
184
- assert_kind_of ApplicationMedia, dmf.create(application_file)
185
- assert_kind_of AudioMedia, dmf.create(audio_file)
186
- assert_kind_of TextMedia, dmf.create(text_file)
187
- assert_kind_of VideoMedia, dmf.create(video_file)
188
-
189
- # test using file object
190
- open(image_file) do |image_file_obj|
191
- assert_kind_of ImageMedia, dmf.create(image_file_obj)
192
- end
193
- open(text_file) do |text_file_obj|
194
- assert_kind_of TextMedia, dmf.create(text_file_obj)
195
- end
196
-
197
- # raise for unknown file path and File object
198
- assert_raises(UnknownContentError) {dmf.create(unknown_file)}
199
- open(unknown_file) do |unknown_file_obj|
200
- assert_raises(UnknownContentError) {dmf.create(unknown_file_obj)}
201
- end
202
- end
203
-
204
- def test_discrete_media_factory_creates_path_singleton_method
205
- pdf_file_path = sd('/book.pdf')
206
-
207
- media_obj = DiscreteMediaFactory.create(pdf_file_path)
208
- assert_equal pdf_file_path, media_obj.path
209
-
210
- open(pdf_file_path) do |pdf_file_obj|
211
- media_obj = DiscreteMediaFactory.create(pdf_file_obj)
212
- end
213
- assert_equal pdf_file_path, media_obj.path
214
- end
215
-
216
- def test_multipart_alternative_message_construction
217
- txt_data = "*Header*\nmessage\n"
218
- htm_data = "<html><body><h1>Header</h1><p>message</p></body></html>\n"
219
- txt_msg = TextMedia.new(txt_data)
220
- htm_msg = TextMedia.new(htm_data)
221
-
222
- txt_msg.content_type = 'text/plain; charset=us-ascii'
223
- htm_msg.content_type = 'text/html; charset=iso-8859-1'
224
-
225
- alt_msg = MultipartMedia::Alternative.new
226
- alt_msg.add_entity htm_msg
227
- alt_msg.add_entity txt_msg
228
-
229
- expected = IO.read(sd('/multipart_alternative.msg'))
230
-
231
- assert_equal_mime_message expected, alt_msg.to_s
232
- end
233
-
234
- def test_multipart_mixed_with_inline_and_attachment
235
- mixed_msg = MultipartMedia::Mixed.new
236
-
237
- open(sd('/image.jpg')) do |img_file|
238
- img_msg = ImageMedia.new(img_file.read, 'image/jpeg')
239
- mixed_msg.attach_entity(img_msg, 'filename' => img_file.path)
240
- end
241
- mixed_msg.inline_entity(TextMedia.new('This is plain text'))
242
-
243
- expected = IO.read(sd('/multipart_mixed_inline_and_attachment.msg'))
244
-
245
- assert_equal_mime_message expected, mixed_msg.to_s
246
- end
247
-
248
- def test_multipart_mixed_message_construction_using_media_factory
249
- img1 = sd('/image.jpg')
250
- img2 = sd('/ruby.png')
251
- txt = sd('/index.html')
252
- bot_img = DiscreteMediaFactory.create(img1)
253
- top_img = DiscreteMediaFactory.create(img2)
254
- top_txt = DiscreteMediaFactory.create(txt)
255
-
256
- mixed_msg = MultipartMedia::Mixed.new
257
- mixed_msg.attach_entity(bot_img)
258
- mixed_msg.attach_entity(top_img)
259
- mixed_msg.inline_entity(top_txt)
260
-
261
- expected = IO.read(sd('/multipart_mixed_inline_and_attachment2.msg'))
262
-
263
- assert_equal_mime_message expected, mixed_msg.to_s
264
- end
265
-
266
- def test_multipart_form_data_with_mixed_entity
267
- txt = TextMedia.new('Joe Blow')
268
- img1 = DiscreteMediaFactory.create(sd('/image.jpg'))
269
- img2 = DiscreteMediaFactory.create(sd('/ruby.png'))
270
-
271
- mixed_msg = MultipartMedia::Mixed.new
272
- mixed_msg.attach_entity(img2)
273
- mixed_msg.attach_entity(img1)
274
-
275
- form = MultipartMedia::FormData.new
276
- form.add_entity(mixed_msg, 'pics')
277
- form.add_entity(txt, 'field1')
278
-
279
- # similar to example 6 in RFC1867
280
- expected = IO.read(sd('/multipart_form_data_mixed.msg'))
281
-
282
- assert_equal_mime_message expected, form.to_s
283
- end
284
-
285
- def test_multipart_related_html_message_with_embedded_image
286
- img = DiscreteMediaFactory.create(sd('/ruby.png'))
287
- img.content_transfer_encoding = 'binary'
288
-
289
- html_msg = TextMedia.new(<<-html, 'text/html; charset=iso-8859-1')
290
- <html>
291
- <body>
292
- <h1>HTML multipart/related message</h1>
293
- <p>txt before pix</p>
294
- <img alt="cool ruby" src="cid:#{img.content_id}"/>
295
- <p>txt after pix</p>
296
- </body>
297
- </html>
298
- html
299
- html_msg.content_transfer_encoding = '7bit'
300
-
301
- related_msg = MultipartMedia::Related.new
302
- related_msg.inline_entity(img)
303
- related_msg.add_entity(html_msg)
304
-
305
- expected = IO.read(sd('/multipart_related.msg'))
306
-
307
- assert_equal_mime_message expected, related_msg.to_s
308
- end
309
-
310
- def test_multipart_alternative_with_related_html_entity
311
- img = DiscreteMediaFactory.create(sd('/ruby.png'))
312
- img.content_transfer_encoding = 'binary'
313
-
314
- html_msg = TextMedia.new(<<-html, 'text/html; charset=iso-8859-1')
315
- <html>
316
- <body>
317
- <h1>HTML multipart/alternative message</h1>
318
- <p>txt before pix</p>
319
- <img alt="cool ruby" src="cid:#{img.content_id}"/>
320
- <p>txt after pix</p>
321
- </body>
322
- </html>
323
- html
324
- html_msg.content_transfer_encoding = '7bit'
325
-
326
- text_msg = TextMedia.new(<<-text)
327
- *HTML multipart/alternative message*
328
- txt before pix
329
- <cool ruby image>
330
- txt after pix
331
- text
332
- text_msg.content_transfer_encoding = '7bit'
333
-
334
- related_msg = MultipartMedia::Related.new
335
- related_msg.inline_entity(img)
336
- related_msg.add_entity(html_msg)
337
-
338
- alt_msg = MultipartMedia::Alternative.new
339
- alt_msg.add_entity(related_msg)
340
- alt_msg.add_entity(text_msg)
341
-
342
- expected = IO.read(sd('/multipart_alternative_related.msg'))
343
-
344
- assert_equal_mime_message expected, alt_msg.to_s
345
- end
346
-
347
-
348
- private
349
-
350
- #
351
- # Test the equality of the normalized +expected+ and +actual+ MIME messages.
352
- #
353
- def assert_equal_mime_message expected, actual
354
- assert_equal normalize_message(expected), normalize_message(actual)
355
- end
356
-
357
- #
358
- # Make messages comparable by removing *-ID header values, library version
359
- # comment in MIME-Version header, Date header value, multipart/related
360
- # content IDs, and boundaries.
361
- #
362
- def normalize_message message
363
- # these are very delicate REs that are inter-dependent, be careful
364
- match_id_headers = /-ID: <[^>]+>\r\n/
365
- match_boundaries = /Boundary_\d+\.\d+/
366
- match_lib_version = / \(Ruby MIME v\d\.\d\)/
367
- match_date_header = /^Date: .*\d{4}\r\n/
368
- match_related_cid = /cid:\d+\.\d+/
369
-
370
- message.
371
- gsub(match_related_cid, "cid").
372
- gsub(match_id_headers, "-ID:\r\n").
373
- gsub(match_boundaries, "Boundary_").
374
- sub(match_date_header, "Date:\r\n").
375
- sub(match_lib_version, " (Ruby MIME v0.0)")
376
- end
377
-
378
- #
379
- # Return the absolute path of +file+ under the test/scaffold directory.
380
- #
381
- def sd file
382
- @scaffold_dir ||= File.join(File.dirname(__FILE__), 'scaffold')
383
- @scaffold_dir + file
384
- end
385
-
386
- end