Mercurial > hg > soundsoftware-site
comparison test/unit/mail_handler_test.rb @ 1526:404aa68d4227
Merge from live branch
author | Chris Cannam |
---|---|
date | Thu, 11 Sep 2014 12:46:20 +0100 |
parents | dffacf8a6908 |
children |
comparison
equal
deleted
inserted
replaced
1493:a5f2bdf3b486 | 1526:404aa68d4227 |
---|---|
1 # encoding: utf-8 | 1 # encoding: utf-8 |
2 # | 2 # |
3 # Redmine - project management software | 3 # Redmine - project management software |
4 # Copyright (C) 2006-2012 Jean-Philippe Lang | 4 # Copyright (C) 2006-2014 Jean-Philippe Lang |
5 # | 5 # |
6 # This program is free software; you can redistribute it and/or | 6 # This program is free software; you can redistribute it and/or |
7 # modify it under the terms of the GNU General Public License | 7 # modify it under the terms of the GNU General Public License |
8 # as published by the Free Software Foundation; either version 2 | 8 # as published by the Free Software Foundation; either version 2 |
9 # of the License, or (at your option) any later version. | 9 # of the License, or (at your option) any later version. |
39 Setting.clear_cache | 39 Setting.clear_cache |
40 end | 40 end |
41 | 41 |
42 def test_add_issue | 42 def test_add_issue |
43 ActionMailer::Base.deliveries.clear | 43 ActionMailer::Base.deliveries.clear |
44 lft1 = new_issue_lft | |
44 # This email contains: 'Project: onlinestore' | 45 # This email contains: 'Project: onlinestore' |
45 issue = submit_email('ticket_on_given_project.eml') | 46 issue = submit_email('ticket_on_given_project.eml') |
46 assert issue.is_a?(Issue) | 47 assert issue.is_a?(Issue) |
47 assert !issue.new_record? | 48 assert !issue.new_record? |
48 issue.reload | 49 issue.reload |
56 assert_equal '2010-12-31', issue.due_date.to_s | 57 assert_equal '2010-12-31', issue.due_date.to_s |
57 assert_equal User.find_by_login('jsmith'), issue.assigned_to | 58 assert_equal User.find_by_login('jsmith'), issue.assigned_to |
58 assert_equal Version.find_by_name('Alpha'), issue.fixed_version | 59 assert_equal Version.find_by_name('Alpha'), issue.fixed_version |
59 assert_equal 2.5, issue.estimated_hours | 60 assert_equal 2.5, issue.estimated_hours |
60 assert_equal 30, issue.done_ratio | 61 assert_equal 30, issue.done_ratio |
61 assert_equal [issue.id, 1, 2], [issue.root_id, issue.lft, issue.rgt] | 62 assert_equal [issue.id, lft1, lft1 + 1], [issue.root_id, issue.lft, issue.rgt] |
62 # keywords should be removed from the email body | 63 # keywords should be removed from the email body |
63 assert !issue.description.match(/^Project:/i) | 64 assert !issue.description.match(/^Project:/i) |
64 assert !issue.description.match(/^Status:/i) | 65 assert !issue.description.match(/^Status:/i) |
65 assert !issue.description.match(/^Start Date:/i) | 66 assert !issue.description.match(/^Start Date:/i) |
66 # Email notification should be sent | 67 # Email notification should be sent |
200 issue = submit_email('ticket_on_given_project.eml') do |email| | 201 issue = submit_email('ticket_on_given_project.eml') do |email| |
201 email.sub!(/^Assigned to.*$/, 'Assigned to: Foo Bar Foo baz') | 202 email.sub!(/^Assigned to.*$/, 'Assigned to: Foo Bar Foo baz') |
202 end | 203 end |
203 assert issue.is_a?(Issue) | 204 assert issue.is_a?(Issue) |
204 assert_equal user, issue.assigned_to | 205 assert_equal user, issue.assigned_to |
206 end | |
207 | |
208 def test_add_issue_should_set_default_start_date | |
209 with_settings :default_issue_start_date_to_creation_date => '1' do | |
210 issue = submit_email('ticket_with_cc.eml', :issue => {:project => 'ecookbook'}) | |
211 assert issue.is_a?(Issue) | |
212 assert_equal Date.today, issue.start_date | |
213 end | |
205 end | 214 end |
206 | 215 |
207 def test_add_issue_with_cc | 216 def test_add_issue_with_cc |
208 issue = submit_email('ticket_with_cc.eml', :issue => {:project => 'ecookbook'}) | 217 issue = submit_email('ticket_with_cc.eml', :issue => {:project => 'ecookbook'}) |
209 assert issue.is_a?(Issue) | 218 assert issue.is_a?(Issue) |
262 end | 271 end |
263 end | 272 end |
264 end | 273 end |
265 | 274 |
266 def test_add_issue_by_anonymous_user_on_private_project_without_permission_check | 275 def test_add_issue_by_anonymous_user_on_private_project_without_permission_check |
276 lft1 = new_issue_lft | |
267 assert_no_difference 'User.count' do | 277 assert_no_difference 'User.count' do |
268 assert_difference 'Issue.count' do | 278 assert_difference 'Issue.count' do |
269 issue = submit_email( | 279 issue = submit_email( |
270 'ticket_by_unknown_user.eml', | 280 'ticket_by_unknown_user.eml', |
271 :issue => {:project => 'onlinestore'}, | 281 :issue => {:project => 'onlinestore'}, |
273 :unknown_user => 'accept' | 283 :unknown_user => 'accept' |
274 ) | 284 ) |
275 assert issue.is_a?(Issue) | 285 assert issue.is_a?(Issue) |
276 assert issue.author.anonymous? | 286 assert issue.author.anonymous? |
277 assert !issue.project.is_public? | 287 assert !issue.project.is_public? |
278 assert_equal [issue.id, 1, 2], [issue.root_id, issue.lft, issue.rgt] | 288 assert_equal [issue.id, lft1, lft1 + 1], [issue.root_id, issue.lft, issue.rgt] |
279 end | 289 end |
280 end | 290 end |
281 end | 291 end |
282 | 292 |
283 def test_add_issue_by_created_user | 293 def test_add_issue_by_created_user |
302 password = mail_body(email).match(/\* Password: (.*)$/)[1].strip | 312 password = mail_body(email).match(/\* Password: (.*)$/)[1].strip |
303 assert_equal issue.author, User.try_to_login(login, password) | 313 assert_equal issue.author, User.try_to_login(login, password) |
304 end | 314 end |
305 end | 315 end |
306 | 316 |
317 def test_created_user_should_be_added_to_groups | |
318 group1 = Group.generate! | |
319 group2 = Group.generate! | |
320 | |
321 assert_difference 'User.count' do | |
322 submit_email( | |
323 'ticket_by_unknown_user.eml', | |
324 :issue => {:project => 'ecookbook'}, | |
325 :unknown_user => 'create', | |
326 :default_group => "#{group1.name},#{group2.name}" | |
327 ) | |
328 end | |
329 user = User.order('id DESC').first | |
330 assert_same_elements [group1, group2], user.groups | |
331 end | |
332 | |
333 def test_created_user_should_not_receive_account_information_with_no_account_info_option | |
334 assert_difference 'User.count' do | |
335 submit_email( | |
336 'ticket_by_unknown_user.eml', | |
337 :issue => {:project => 'ecookbook'}, | |
338 :unknown_user => 'create', | |
339 :no_account_notice => '1' | |
340 ) | |
341 end | |
342 | |
343 # only 1 email for the new issue notification | |
344 assert_equal 1, ActionMailer::Base.deliveries.size | |
345 email = ActionMailer::Base.deliveries.first | |
346 assert_include 'Ticket by unknown user', email.subject | |
347 end | |
348 | |
349 def test_created_user_should_have_mail_notification_to_none_with_no_notification_option | |
350 assert_difference 'User.count' do | |
351 submit_email( | |
352 'ticket_by_unknown_user.eml', | |
353 :issue => {:project => 'ecookbook'}, | |
354 :unknown_user => 'create', | |
355 :no_notification => '1' | |
356 ) | |
357 end | |
358 user = User.order('id DESC').first | |
359 assert_equal 'none', user.mail_notification | |
360 end | |
361 | |
307 def test_add_issue_without_from_header | 362 def test_add_issue_without_from_header |
308 Role.anonymous.add_permission!(:add_issues) | 363 Role.anonymous.add_permission!(:add_issues) |
309 assert_equal false, submit_email('ticket_without_from_header.eml') | 364 assert_equal false, submit_email('ticket_without_from_header.eml') |
310 end | 365 end |
311 | 366 |
312 def test_add_issue_with_invalid_attributes | 367 def test_add_issue_with_invalid_attributes |
313 issue = submit_email( | 368 with_settings :default_issue_start_date_to_creation_date => '0' do |
314 'ticket_with_invalid_attributes.eml', | 369 issue = submit_email( |
315 :allow_override => 'tracker,category,priority' | 370 'ticket_with_invalid_attributes.eml', |
316 ) | 371 :allow_override => 'tracker,category,priority' |
317 assert issue.is_a?(Issue) | 372 ) |
318 assert !issue.new_record? | 373 assert issue.is_a?(Issue) |
319 issue.reload | 374 assert !issue.new_record? |
320 assert_nil issue.assigned_to | 375 issue.reload |
321 assert_nil issue.start_date | 376 assert_nil issue.assigned_to |
322 assert_nil issue.due_date | 377 assert_nil issue.start_date |
323 assert_equal 0, issue.done_ratio | 378 assert_nil issue.due_date |
324 assert_equal 'Normal', issue.priority.to_s | 379 assert_equal 0, issue.done_ratio |
325 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.') | 380 assert_equal 'Normal', issue.priority.to_s |
381 assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.') | |
382 end | |
383 end | |
384 | |
385 def test_add_issue_with_invalid_project_should_be_assigned_to_default_project | |
386 issue = submit_email('ticket_on_given_project.eml', :issue => {:project => 'ecookbook'}, :allow_override => 'project') do |email| | |
387 email.gsub!(/^Project:.+$/, 'Project: invalid') | |
388 end | |
389 assert issue.is_a?(Issue) | |
390 assert !issue.new_record? | |
391 assert_equal 'ecookbook', issue.project.identifier | |
326 end | 392 end |
327 | 393 |
328 def test_add_issue_with_localized_attributes | 394 def test_add_issue_with_localized_attributes |
329 User.find_by_mail('jsmith@somenet.foo').update_attribute 'language', 'fr' | 395 User.find_by_mail('jsmith@somenet.foo').update_attribute 'language', 'fr' |
330 issue = submit_email( | 396 issue = submit_email( |
445 assert File.exist?(attachment.diskfile) | 511 assert File.exist?(attachment.diskfile) |
446 assert_equal 5, File.size(attachment.diskfile) | 512 assert_equal 5, File.size(attachment.diskfile) |
447 assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest | 513 assert_equal 'd8e8fca2dc0f896fd7cb4cb0031ba249', attachment.digest |
448 end | 514 end |
449 | 515 |
516 def test_multiple_inline_text_parts_should_be_appended_to_issue_description | |
517 issue = submit_email('multiple_text_parts.eml', :issue => {:project => 'ecookbook'}) | |
518 assert_include 'first', issue.description | |
519 assert_include 'second', issue.description | |
520 assert_include 'third', issue.description | |
521 end | |
522 | |
523 def test_attachment_text_part_should_be_added_as_issue_attachment | |
524 issue = submit_email('multiple_text_parts.eml', :issue => {:project => 'ecookbook'}) | |
525 assert_not_include 'Plain text attachment', issue.description | |
526 attachment = issue.attachments.detect {|a| a.filename == 'textfile.txt'} | |
527 assert_not_nil attachment | |
528 assert_include 'Plain text attachment', File.read(attachment.diskfile) | |
529 end | |
530 | |
450 def test_add_issue_with_iso_8859_1_subject | 531 def test_add_issue_with_iso_8859_1_subject |
451 issue = submit_email( | 532 issue = submit_email( |
452 'subject_as_iso-8859-1.eml', | 533 'subject_as_iso-8859-1.eml', |
453 :issue => {:project => 'ecookbook'} | 534 :issue => {:project => 'ecookbook'} |
454 ) | 535 ) |
465 ) | 546 ) |
466 assert_kind_of Issue, issue | 547 assert_kind_of Issue, issue |
467 ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88" | 548 ja = "\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88" |
468 ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding) | 549 ja.force_encoding('UTF-8') if ja.respond_to?(:force_encoding) |
469 assert_equal ja, issue.subject | 550 assert_equal ja, issue.subject |
551 end | |
552 | |
553 def test_add_issue_with_korean_body | |
554 # Make sure mail bodies with a charset unknown to Ruby | |
555 # but known to the Mail gem 2.5.4 are handled correctly | |
556 kr = "\xEA\xB3\xA0\xEB\xA7\x99\xEC\x8A\xB5\xEB\x8B\x88\xEB\x8B\xA4." | |
557 if !kr.respond_to?(:force_encoding) | |
558 puts "\nOn Ruby 1.8, skip Korean encoding mail body test" | |
559 else | |
560 kr.force_encoding('UTF-8') | |
561 issue = submit_email( | |
562 'body_ks_c_5601-1987.eml', | |
563 :issue => {:project => 'ecookbook'} | |
564 ) | |
565 assert_kind_of Issue, issue | |
566 assert_equal kr, issue.description | |
567 end | |
470 end | 568 end |
471 | 569 |
472 def test_add_issue_with_no_subject_header | 570 def test_add_issue_with_no_subject_header |
473 issue = submit_email( | 571 issue = submit_email( |
474 'no_subject_header.eml', | 572 'no_subject_header.eml', |
575 end | 673 end |
576 end | 674 end |
577 end | 675 end |
578 end | 676 end |
579 end | 677 end |
580 journal = Journal.first(:order => 'id DESC') | 678 journal = Journal.order('id DESC').first |
581 assert_equal Issue.find(2), journal.journalized | 679 assert_equal Issue.find(2), journal.journalized |
582 assert_equal 1, journal.details.size | 680 assert_equal 1, journal.details.size |
583 | 681 |
584 detail = journal.details.first | 682 detail = journal.details.first |
585 assert_equal 'attachment', detail.property | 683 assert_equal 'attachment', detail.property |
644 issue.reload | 742 issue.reload |
645 assert_equal 'HTML email', issue.subject | 743 assert_equal 'HTML email', issue.subject |
646 assert_equal 'This is a html-only email.', issue.description | 744 assert_equal 'This is a html-only email.', issue.description |
647 end | 745 end |
648 | 746 |
649 context "truncate emails based on the Setting" do | 747 test "truncate emails with no setting should add the entire email into the issue" do |
650 context "with no setting" do | 748 with_settings :mail_handler_body_delimiters => '' do |
651 setup do | 749 issue = submit_email('ticket_on_given_project.eml') |
652 Setting.mail_handler_body_delimiters = '' | 750 assert_issue_created(issue) |
653 end | 751 assert issue.description.include?('---') |
654 | 752 assert issue.description.include?('This paragraph is after the delimiter') |
655 should "add the entire email into the issue" do | 753 end |
656 issue = submit_email('ticket_on_given_project.eml') | 754 end |
657 assert_issue_created(issue) | 755 |
658 assert issue.description.include?('---') | 756 test "truncate emails with a single string should truncate the email at the delimiter for the issue" do |
659 assert issue.description.include?('This paragraph is after the delimiter') | 757 with_settings :mail_handler_body_delimiters => '---' do |
660 end | 758 issue = submit_email('ticket_on_given_project.eml') |
661 end | 759 assert_issue_created(issue) |
662 | 760 assert issue.description.include?('This paragraph is before delimiters') |
663 context "with a single string" do | 761 assert issue.description.include?('--- This line starts with a delimiter') |
664 setup do | 762 assert !issue.description.match(/^---$/) |
665 Setting.mail_handler_body_delimiters = '---' | 763 assert !issue.description.include?('This paragraph is after the delimiter') |
666 end | 764 end |
667 should "truncate the email at the delimiter for the issue" do | 765 end |
668 issue = submit_email('ticket_on_given_project.eml') | 766 |
669 assert_issue_created(issue) | 767 test "truncate emails with a single quoted reply should truncate the email at the delimiter with the quoted reply symbols (>)" do |
670 assert issue.description.include?('This paragraph is before delimiters') | 768 with_settings :mail_handler_body_delimiters => '--- Reply above. Do not remove this line. ---' do |
671 assert issue.description.include?('--- This line starts with a delimiter') | 769 journal = submit_email('issue_update_with_quoted_reply_above.eml') |
672 assert !issue.description.match(/^---$/) | 770 assert journal.is_a?(Journal) |
673 assert !issue.description.include?('This paragraph is after the delimiter') | 771 assert journal.notes.include?('An update to the issue by the sender.') |
674 end | 772 assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---")) |
675 end | 773 assert !journal.notes.include?('Looks like the JSON api for projects was missed.') |
676 | 774 end |
677 context "with a single quoted reply (e.g. reply to a Redmine email notification)" do | 775 end |
678 setup do | 776 |
679 Setting.mail_handler_body_delimiters = '--- Reply above. Do not remove this line. ---' | 777 test "truncate emails with multiple quoted replies should truncate the email at the delimiter with the quoted reply symbols (>)" do |
680 end | 778 with_settings :mail_handler_body_delimiters => '--- Reply above. Do not remove this line. ---' do |
681 should "truncate the email at the delimiter with the quoted reply symbols (>)" do | 779 journal = submit_email('issue_update_with_multiple_quoted_reply_above.eml') |
682 journal = submit_email('issue_update_with_quoted_reply_above.eml') | 780 assert journal.is_a?(Journal) |
683 assert journal.is_a?(Journal) | 781 assert journal.notes.include?('An update to the issue by the sender.') |
684 assert journal.notes.include?('An update to the issue by the sender.') | 782 assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---")) |
685 assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---")) | 783 assert !journal.notes.include?('Looks like the JSON api for projects was missed.') |
686 assert !journal.notes.include?('Looks like the JSON api for projects was missed.') | 784 end |
687 end | 785 end |
688 end | 786 |
689 | 787 test "truncate emails with multiple strings should truncate the email at the first delimiter found (BREAK)" do |
690 context "with multiple quoted replies (e.g. reply to a reply of a Redmine email notification)" do | 788 with_settings :mail_handler_body_delimiters => "---\nBREAK" do |
691 setup do | 789 issue = submit_email('ticket_on_given_project.eml') |
692 Setting.mail_handler_body_delimiters = '--- Reply above. Do not remove this line. ---' | 790 assert_issue_created(issue) |
693 end | 791 assert issue.description.include?('This paragraph is before delimiters') |
694 should "truncate the email at the delimiter with the quoted reply symbols (>)" do | 792 assert !issue.description.include?('BREAK') |
695 journal = submit_email('issue_update_with_multiple_quoted_reply_above.eml') | 793 assert !issue.description.include?('This paragraph is between delimiters') |
696 assert journal.is_a?(Journal) | 794 assert !issue.description.match(/^---$/) |
697 assert journal.notes.include?('An update to the issue by the sender.') | 795 assert !issue.description.include?('This paragraph is after the delimiter') |
698 assert !journal.notes.match(Regexp.escape("--- Reply above. Do not remove this line. ---")) | 796 end |
699 assert !journal.notes.include?('Looks like the JSON api for projects was missed.') | 797 end |
700 end | 798 |
701 end | 799 def test_attachments_that_match_mail_handler_excluded_filenames_should_be_ignored |
702 | 800 with_settings :mail_handler_excluded_filenames => '*.vcf, *.jpg' do |
703 context "with multiple strings" do | 801 issue = submit_email('ticket_with_attachment.eml', :issue => {:project => 'onlinestore'}) |
704 setup do | 802 assert issue.is_a?(Issue) |
705 Setting.mail_handler_body_delimiters = "---\nBREAK" | 803 assert !issue.new_record? |
706 end | 804 assert_equal 0, issue.reload.attachments.size |
707 should "truncate the email at the first delimiter found (BREAK)" do | 805 end |
708 issue = submit_email('ticket_on_given_project.eml') | 806 end |
709 assert_issue_created(issue) | 807 |
710 assert issue.description.include?('This paragraph is before delimiters') | 808 def test_attachments_that_do_not_match_mail_handler_excluded_filenames_should_be_attached |
711 assert !issue.description.include?('BREAK') | 809 with_settings :mail_handler_excluded_filenames => '*.vcf, *.gif' do |
712 assert !issue.description.include?('This paragraph is between delimiters') | 810 issue = submit_email('ticket_with_attachment.eml', :issue => {:project => 'onlinestore'}) |
713 assert !issue.description.match(/^---$/) | 811 assert issue.is_a?(Issue) |
714 assert !issue.description.include?('This paragraph is after the delimiter') | 812 assert !issue.new_record? |
715 end | 813 assert_equal 1, issue.reload.attachments.size |
716 end | 814 end |
717 end | 815 end |
718 | 816 |
719 def test_email_with_long_subject_line | 817 def test_email_with_long_subject_line |
720 issue = submit_email('ticket_with_long_subject.eml') | 818 issue = submit_email('ticket_with_long_subject.eml') |
739 assert user.valid?, user.errors.full_messages.to_s | 837 assert user.valid?, user.errors.full_messages.to_s |
740 assert_equal attrs.first, user.mail | 838 assert_equal attrs.first, user.mail |
741 assert_equal expected[0], user.login | 839 assert_equal expected[0], user.login |
742 assert_equal expected[1], user.firstname | 840 assert_equal expected[1], user.firstname |
743 assert_equal expected[2], user.lastname | 841 assert_equal expected[2], user.lastname |
744 end | 842 assert_equal 'only_my_events', user.mail_notification |
745 end | |
746 | |
747 def test_new_user_from_attributes_should_respect_minimum_password_length | |
748 with_settings :password_min_length => 15 do | |
749 user = MailHandler.new_user_from_attributes('jsmith@example.net') | |
750 assert user.valid? | |
751 assert user.password.length >= 15 | |
752 end | 843 end |
753 end | 844 end |
754 | 845 |
755 def test_new_user_from_attributes_should_use_default_login_if_invalid | 846 def test_new_user_from_attributes_should_use_default_login_if_invalid |
756 user = MailHandler.new_user_from_attributes('foo+bar@example.net') | 847 user = MailHandler.new_user_from_attributes('foo+bar@example.net') |
765 'fullname_of_sender_as_utf8_encoded.eml', | 856 'fullname_of_sender_as_utf8_encoded.eml', |
766 :issue => {:project => 'ecookbook'}, | 857 :issue => {:project => 'ecookbook'}, |
767 :unknown_user => 'create' | 858 :unknown_user => 'create' |
768 ) | 859 ) |
769 end | 860 end |
770 | 861 user = User.order('id DESC').first |
771 user = User.first(:order => 'id DESC') | |
772 assert_equal "foo@example.org", user.mail | 862 assert_equal "foo@example.org", user.mail |
773 str1 = "\xc3\x84\xc3\xa4" | 863 str1 = "\xc3\x84\xc3\xa4" |
774 str2 = "\xc3\x96\xc3\xb6" | 864 str2 = "\xc3\x96\xc3\xb6" |
775 str1.force_encoding('UTF-8') if str1.respond_to?(:force_encoding) | 865 str1.force_encoding('UTF-8') if str1.respond_to?(:force_encoding) |
776 str2.force_encoding('UTF-8') if str2.respond_to?(:force_encoding) | 866 str2.force_encoding('UTF-8') if str2.respond_to?(:force_encoding) |
777 assert_equal str1, user.firstname | 867 assert_equal str1, user.firstname |
778 assert_equal str2, user.lastname | 868 assert_equal str2, user.lastname |
779 end | 869 end |
780 | 870 |
871 def test_extract_options_from_env_should_return_options | |
872 options = MailHandler.extract_options_from_env({ | |
873 'tracker' => 'defect', | |
874 'project' => 'foo', | |
875 'unknown_user' => 'create' | |
876 }) | |
877 | |
878 assert_equal({ | |
879 :issue => {:tracker => 'defect', :project => 'foo'}, | |
880 :unknown_user => 'create' | |
881 }, options) | |
882 end | |
883 | |
781 private | 884 private |
782 | 885 |
783 def submit_email(filename, options={}) | 886 def submit_email(filename, options={}) |
784 raw = IO.read(File.join(FIXTURES_PATH, filename)) | 887 raw = IO.read(File.join(FIXTURES_PATH, filename)) |
785 yield raw if block_given? | 888 yield raw if block_given? |