diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/controllers/api_controller_spec.rb | 134 | ||||
-rw-r--r-- | spec/controllers/general_controller_spec.rb | 50 | ||||
-rw-r--r-- | spec/controllers/request_controller_spec.rb | 2 | ||||
-rw-r--r-- | spec/fixtures/files/dos-linebreaks.email | 31 | ||||
-rw-r--r-- | spec/fixtures/files/humberside-police-odd-mime-type.email | 25 | ||||
-rw-r--r-- | spec/fixtures/files/incoming-request-attachment-headers.email | 50 | ||||
-rw-r--r-- | spec/fixtures/files/incoming-request-attachment-unknown-extension.email | 5 | ||||
-rw-r--r-- | spec/fixtures/files/many-attachments-date-header.email | 451 | ||||
-rw-r--r-- | spec/fixtures/files/rfc822-attachment.email | 147 | ||||
-rw-r--r-- | spec/lib/i18n_interpolation.rb | 3 | ||||
-rw-r--r-- | spec/lib/mail_handler/mail_handler_spec.rb | 362 | ||||
-rw-r--r-- | spec/models/incoming_message_spec.rb | 108 | ||||
-rw-r--r-- | spec/models/info_request_spec.rb | 16 | ||||
-rw-r--r-- | spec/spec_helper.rb | 9 |
14 files changed, 1258 insertions, 135 deletions
diff --git a/spec/controllers/api_controller_spec.rb b/spec/controllers/api_controller_spec.rb index 8d8a39950..1c320f85c 100644 --- a/spec/controllers/api_controller_spec.rb +++ b/spec/controllers/api_controller_spec.rb @@ -2,7 +2,7 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') def normalise_whitespace(s) - s = s.gsub(/^\s+|\s+$/, "") + s = s.gsub(/\A\s+|\s+\Z/, "") s = s.gsub(/\s+/, " ") return s end @@ -14,23 +14,36 @@ Spec::Matchers.define :be_equal_modulo_whitespace_to do |expected| end describe ApiController, "when using the API" do - it "should check the API key" do - request_data = { + + describe 'checking API keys' do + before do + @number_of_requests = InfoRequest.count + @request_data = { "title" => "Tell me about your chickens", "body" => "Dear Sir,\n\nI should like to know about your chickens.\n\nYours in faith,\nBob\n", - + "external_url" => "http://www.example.gov.uk/foi/chickens_23", "external_user_name" => "Bob Smith", } - - number_of_requests = InfoRequest.count + end + + it 'should check that an API key is given as a param' do expect { - post :create_request, :k => "This is not really an API key", :request_json => request_data.to_json + post :create_request, :request_json => @request_data.to_json }.to raise_error ApplicationController::PermissionDenied - - InfoRequest.count.should == number_of_requests + InfoRequest.count.should == @number_of_requests + end + + it "should check the API key" do + expect { + post :create_request, + :k => "This is not really an API key", + :request_json => @request_data.to_json + }.to raise_error ApplicationController::PermissionDenied + InfoRequest.count.should == @number_of_requests + end end - + it "should create a new request from a POST" do number_of_requests = InfoRequest.count( :conditions => [ @@ -38,61 +51,61 @@ describe ApiController, "when using the API" do public_bodies(:geraldine_public_body).id ] ) - + request_data = { "title" => "Tell me about your chickens", "body" => "Dear Sir,\n\nI should like to know about your chickens.\n\nYours in faith,\nBob\n", - + "external_url" => "http://www.example.gov.uk/foi/chickens_23", "external_user_name" => "Bob Smith", } - + post :create_request, :k => public_bodies(:geraldine_public_body).api_key, :request_json => request_data.to_json response.should be_success response.content_type.should == "application/json" - + response_body = ActiveSupport::JSON.decode(response.body) response_body["errors"].should be_nil response_body["url"].should =~ /^http/ - + InfoRequest.count(:conditions => [ "public_body_id = ?", public_bodies(:geraldine_public_body).id] ).should == number_of_requests + 1 - + new_request = InfoRequest.find(response_body["id"]) new_request.user_id.should be_nil new_request.external_user_name.should == request_data["external_user_name"] new_request.external_url.should == request_data["external_url"] - + new_request.title.should == request_data["title"] new_request.last_event_forming_initial_request.outgoing_message.body.should == request_data["body"].strip - + new_request.public_body_id.should == public_bodies(:geraldine_public_body).id end - + def _create_request post :create_request, :k => public_bodies(:geraldine_public_body).api_key, :request_json => { "title" => "Tell me about your chickens", "body" => "Dear Sir,\n\nI should like to know about your chickens.\n\nYours in faith,\nBob\n", - + "external_url" => "http://www.example.gov.uk/foi/chickens_23", "external_user_name" => "Bob Smith", }.to_json response.content_type.should == "application/json" return ActiveSupport::JSON.decode(response.body)["id"] end - + it "should add a response to a request" do # First we need an external request request_id = info_requests(:external_request).id - + # Initially it has no incoming messages IncomingMessage.count(:conditions => ["info_request_id = ?", request_id]).should == 0 - + # Now add one sent_at = "2012-05-28T12:35:39+01:00" response_body = "Thank you for your request for information, which we are handling in accordance with the Freedom of Information Act 2000. You will receive a response within 20 working days or before the next full moon, whichever is sooner.\n\nYours sincerely,\nJohn Gandermulch,\nExample Council FOI Officer\n" @@ -104,13 +117,13 @@ describe ApiController, "when using the API" do "sent_at" => sent_at, "body" => response_body }.to_json - + # And make sure it worked response.should be_success incoming_messages = IncomingMessage.all(:conditions => ["info_request_id = ?", request_id]) incoming_messages.count.should == 1 incoming_message = incoming_messages[0] - + incoming_message.sent_at.should == Time.iso8601(sent_at) incoming_message.get_main_body_text_folded.should be_equal_modulo_whitespace_to(response_body) end @@ -118,10 +131,10 @@ describe ApiController, "when using the API" do it "should add a followup to a request" do # First we need an external request request_id = info_requests(:external_request).id - + # Initially it has one outgoing message OutgoingMessage.count(:conditions => ["info_request_id = ?", request_id]).should == 1 - + # Add another, as a followup sent_at = "2012-05-29T12:35:39+01:00" followup_body = "Pls answer ASAP.\nkthxbye\n" @@ -133,7 +146,7 @@ describe ApiController, "when using the API" do "sent_at" => sent_at, "body" => followup_body }.to_json - + # Make sure it worked response.should be_success followup_messages = OutgoingMessage.all( @@ -141,15 +154,15 @@ describe ApiController, "when using the API" do ) followup_messages.size.should == 1 followup_message = followup_messages[0] - + followup_message.last_sent_at.should == Time.iso8601(sent_at) followup_message.body.should == followup_body.strip end - + it "should not allow internal requests to be updated" do n_incoming_messages = IncomingMessage.count n_outgoing_messages = OutgoingMessage.count - + request_id = info_requests(:naughty_chicken_request).id post :add_correspondence, :k => public_bodies(:geraldine_public_body).api_key, @@ -159,20 +172,20 @@ describe ApiController, "when using the API" do "sent_at" => Time.now.iso8601, "body" => "xxx" }.to_json - + response.status.should == "500 Internal Server Error" ActiveSupport::JSON.decode(response.body)["errors"].should == [ "Request #{request_id} cannot be updated using the API"] - + IncomingMessage.count.should == n_incoming_messages OutgoingMessage.count.should == n_outgoing_messages end - + it "should not allow other people's requests to be updated" do request_id = _create_request n_incoming_messages = IncomingMessage.count n_outgoing_messages = OutgoingMessage.count - + post :add_correspondence, :k => public_bodies(:humpadink_public_body).api_key, :id => request_id, @@ -181,15 +194,15 @@ describe ApiController, "when using the API" do "sent_at" => Time.now.iso8601, "body" => "xxx" }.to_json - + response.status.should == "500 Internal Server Error" ActiveSupport::JSON.decode(response.body)["errors"].should == [ "You do not own request #{request_id}"] - + IncomingMessage.count.should == n_incoming_messages OutgoingMessage.count.should == n_outgoing_messages end - + it "should not allow files to be attached to a followup" do post :add_correspondence, :k => public_bodies(:geraldine_public_body).api_key, @@ -202,21 +215,21 @@ describe ApiController, "when using the API" do :attachments => [ fixture_file_upload("files/tfl.pdf") ] - - + + # Make sure it worked response.status.to_i.should == 500 errors = ActiveSupport::JSON.decode(response.body)["errors"] errors.should == ["You cannot attach files to messages in the 'request' direction"] end - + it "should allow files to be attached to a response" do # First we need an external request request_id = info_requests(:external_request).id - + # Initially it has no incoming messages IncomingMessage.count(:conditions => ["info_request_id = ?", request_id]).should == 0 - + # Now add one sent_at = "2012-05-28T12:35:39+01:00" response_body = "Thank you for your request for information, which we are handling in accordance with the Freedom of Information Act 2000. You will receive a response within 20 working days or before the next full moon, whichever is sooner.\n\nYours sincerely,\nJohn Gandermulch,\nExample Council FOI Officer\n" @@ -231,34 +244,33 @@ describe ApiController, "when using the API" do :attachments => [ fixture_file_upload("files/tfl.pdf") ] - + # And make sure it worked response.should be_success incoming_messages = IncomingMessage.all(:conditions => ["info_request_id = ?", request_id]) incoming_messages.count.should == 1 incoming_message = incoming_messages[0] - + incoming_message.sent_at.should == Time.iso8601(sent_at) incoming_message.get_main_body_text_folded.should be_equal_modulo_whitespace_to(response_body) - + # Get the attachment attachments = incoming_message.get_attachments_for_display attachments.size.should == 1 attachment = attachments[0] - attachment.filename.should == "tfl.pdf" - attachment.body.should == load_file_fixture("tfl.pdf") + attachment.body.should == load_file_fixture("tfl.pdf", as_binary=true) end - + it "should show information about a request" do info_request = info_requests(:naughty_chicken_request) get :show_request, :k => public_bodies(:geraldine_public_body).api_key, :id => info_request.id - + response.should be_success assigns[:request].id.should == info_request.id - + r = ActiveSupport::JSON.decode(response.body) r["title"].should == info_request.title # Let’s not test all the fields here, because it would @@ -266,13 +278,13 @@ describe ApiController, "when using the API" do # assigns them and changing assignment to an equality # check, which does not really test anything at all. end - + it "should show an Atom feed of new request events" do get :body_request_events, :id => public_bodies(:geraldine_public_body).id, :k => public_bodies(:geraldine_public_body).api_key, :feed_type => "atom" - + response.should be_success response.should render_template("api/request_events.atom") assigns[:events].size.should > 0 @@ -288,7 +300,7 @@ describe ApiController, "when using the API" do :id => public_bodies(:geraldine_public_body).id, :k => public_bodies(:geraldine_public_body).api_key, :feed_type => "json" - + response.should be_success assigns[:events].size.should > 0 assigns[:events].each do |event| @@ -296,13 +308,13 @@ describe ApiController, "when using the API" do event.outgoing_message.should_not be_nil event.event_type.should satisfy {|x| ['sent', 'followup_sent', 'resent', 'followup_resent'].include?(x)} end - + assigns[:event_data].size.should == assigns[:events].size assigns[:event_data].each do |event_record| event_record[:event_type].should satisfy {|x| ['sent', 'followup_sent', 'resent', 'followup_resent'].include?(x)} end end - + it "should honour the since_event_id parameter" do get :body_request_events, :id => public_bodies(:geraldine_public_body).id, @@ -311,7 +323,7 @@ describe ApiController, "when using the API" do response.should be_success first_event = assigns[:event_data][0] second_event_id = assigns[:event_data][1][:event_id] - + get :body_request_events, :id => public_bodies(:geraldine_public_body).id, :k => public_bodies(:geraldine_public_body).api_key, @@ -320,14 +332,14 @@ describe ApiController, "when using the API" do response.should be_success assigns[:event_data].should == [first_event] end - + it "should honour the since_date parameter for the Atom feed" do get :body_request_events, :id => public_bodies(:humpadink_public_body).id, :k => public_bodies(:humpadink_public_body).api_key, :since_date => "2010-01-01", :feed_type => "atom" - + response.should be_success response.should render_template("api/request_events.atom") assigns[:events].size.should > 0 @@ -335,7 +347,7 @@ describe ApiController, "when using the API" do event.created_at.should >= Date.new(2010, 1, 1) end end - + it "should return a JSON 404 error for non-existent requests" do request_id = 123459876 # Let's hope this doesn't exist! sent_at = "2012-05-28T12:35:39+01:00" @@ -351,7 +363,7 @@ describe ApiController, "when using the API" do response.status.should == "404 Not Found" ActiveSupport::JSON.decode(response.body)["errors"].should == ["Could not find request 123459876"] end - + it "should return a JSON 500 error if we try to add correspondence to a request we don't own" do request_id = info_requests(:naughty_chicken_request).id sent_at = "2012-05-28T12:35:39+01:00" diff --git a/spec/controllers/general_controller_spec.rb b/spec/controllers/general_controller_spec.rb index 830486493..642ed0e05 100644 --- a/spec/controllers/general_controller_spec.rb +++ b/spec/controllers/general_controller_spec.rb @@ -97,8 +97,57 @@ describe GeneralController, "when showing the frontpage" do response.should be_success end + describe 'when there is more than one locale' do + + describe 'when using the default locale' do + + before do + @default_lang_home_link = /href=".*\/en\// + @other_lang_home_link = /href=".*\/es\// + @old_include_default_locale_in_urls = Configuration::include_default_locale_in_urls + end + + def set_default_locale_in_urls(value) + Configuration.stub!(:include_default_locale_in_urls).and_return(value) + load Rails.root.join("config/initializers/fast_gettext.rb") + end + + describe 'when the config value INCLUDE_DEFAULT_LOCALE_IN_URLS is false' do + + before do + set_default_locale_in_urls(false) + end + + it 'should generate URLs without a locale prepended' do + get :frontpage + response.should_not have_text(@default_lang_home_link) + end + + it 'should render the front page in the default language when no locale param + is present and the session locale is not the default' do + get(:frontpage, {}, {:locale => 'es'}) + response.should_not have_text(@other_lang_home_link) + end + end + + it 'should generate URLs with a locale prepended when the config value + INCLUDE_DEFAULT_LOCALE_IN_URLS is true' do + set_default_locale_in_urls(true) + get :frontpage + response.should have_text(@default_lang_home_link) + end + + after do + set_default_locale_in_urls(@old_include_default_locale_in_urls) + end + + end + end + + describe "when using different locale settings" do home_link_regex = /href=".*\/en\// + it "should generate URLs with a locale prepended when there's more than one locale set" do get :frontpage response.should have_text(home_link_regex) @@ -137,6 +186,7 @@ describe GeneralController, "when showing the frontpage" do FastGettext.default_available_locales = old_fgt_available_locales I18n.available_locales = old_i18n_available_locales end + end end describe GeneralController, "when showing the front page with fixture data" do diff --git a/spec/controllers/request_controller_spec.rb b/spec/controllers/request_controller_spec.rb index e898fb91b..f40eecfff 100644 --- a/spec/controllers/request_controller_spec.rb +++ b/spec/controllers/request_controller_spec.rb @@ -757,7 +757,7 @@ describe RequestController, "when showing one request" do assigns[:url_path].should_not == old_path response.location.should have_text(/#{assigns[:url_path]}/) zipfile = Zip::ZipFile.open(File.join(File.dirname(__FILE__), "../../cache/zips", assigns[:url_path])) { |zipfile| - zipfile.count.should == 5 # the message, two hello.txt, the unknown attachment, and its empty message + zipfile.count.should == 4 # the message, two hello.txt plus the unknown attachment } end diff --git a/spec/fixtures/files/dos-linebreaks.email b/spec/fixtures/files/dos-linebreaks.email new file mode 100644 index 000000000..1f5f1473f --- /dev/null +++ b/spec/fixtures/files/dos-linebreaks.email @@ -0,0 +1,31 @@ +From email@example.com Wed Mar 12 14:58:26 2008 +Return-path: email@example.com> +Envelope-to: request-xxx-xxxxxx@whatdotheyknow.com +Delivery-date: Wed, 12 Mar 2008 14:58:26 +0000 +Received: from example.com ([0.0.0.0]:1368 helo=example.com) + by tea.ukcod.org.uk with esmtp (Exim 4.50) + id 1JZSPS-0002yK-Rq + for request-60-3548031c@whatdotheyknow.com; Wed, 12 Mar 2008 14:58:26 +0000 +X-MimeOLE: Produced By Microsoft Exchange V0.0.0.0 +Content-class: urn:content-classes:message +MIME-Version: 1.0 +Content-Type: text/plain; + charset="us-ascii" +Content-Transfer-Encoding: quoted-printable +Disposition-Notification-To: "A Person" email@example.com> +Subject: RE: Freedom of Information request - Plans for the East Oxford Community Centre +Date: Wed, 12 Mar 2008 14:59:04 -0000 +Message-ID: <3D8BEC617D49EF45A9E6D103A83FD30331BF84@local> +X-MS-Has-Attach: +X-MS-TNEF-Correlator: +Thread-Topic: Freedom of Information request +Thread-Index: AciDziuIcYirFQ7GT36VyP2ABE14qgAg1c0w +From: "A Person" email@example.com> +To: FOI Person <EMAIL_TO> +X-OriginalArrivalTime: 12 Mar 2008 14:59:04.0368 (UTC) FILETIME=[9D245300:01C88451] +X-SEF-7853D99-ADF1-478E-8894-213D316B8FFA: 1 +X-SEF-Processed: 6_0_1_111__2008_03_12_14_59_05 + +Thank you for your Freedom of Information request. I have forwarded it=0D=0A= +to the relevant department for their reply.=0D=0A=0D=0A + diff --git a/spec/fixtures/files/humberside-police-odd-mime-type.email b/spec/fixtures/files/humberside-police-odd-mime-type.email index 5514b29da..ae4ceeffe 100644 --- a/spec/fixtures/files/humberside-police-odd-mime-type.email +++ b/spec/fixtures/files/humberside-police-odd-mime-type.email @@ -3,19 +3,20 @@ Return-path: <> Envelope-to: request-5335-xxxxxxxx@whatdotheyknow.com Delivery-date: Thu, 01 Jan 2009 15:56:20 +0000 Received: from earth.karoo.kcom.com ([212.50.160.55]:62894) - by sandwich.ukcod.org.uk with esmtp (Exim 4.63) - id 1LIPuG-0004AJ-B3 - for request-5335-xxxxxxxx@whatdotheyknow.com; Thu, 01 Jan 2009 15:56:20 +0000 + by sandwich.ukcod.org.uk with esmtp (Exim 4.63) + id 1LIPuG-0004AJ-B3 + for request-5335-xxxxxxxx@whatdotheyknow.com; Thu, 01 Jan 2009 15:56:20 +0000 Received: from unknown (HELO smtp-in.karoo.kcom.com) ([10.102.8.11]) by earth.karoo.kcom.com with ESMTP; 01 Jan 2009 15:44:42 +0000 Received: from exim by smtp-in.karoo.kcom.comwith local (Exim 4.30) - id 1LIPu0-0004fg-G6 server-id smtp-in4 - for request-5335-xxxxxxxx@whatdotheyknow.com; Thu, 01 Jan 2009 15:56:04 +0000 + id 1LIPu0-0004fg-G6 server-id smtp-in4 + for request-5335-xxxxxxxx@whatdotheyknow.com; Thu, 01 Jan 2009 15:56:04 +0000 X-Failed-Recipients: clerk@humberside-pa.karoo.co.uk Reply-To: Postmaster <postmaster@karoo.kcom.com> Auto-Submitted: auto-generated From: Mail Delivery System <Mailer-Daemon@karoo.co.uk> To: request-5335-xxxxxxxx@whatdotheyknow.com +Cc: request-5335-xxxxxxxx@whatdotheyknow.com Subject: Mail delivery failed : returning message to sender X-Mailer: Karoo Mailcore [version 2.0-IB] MIME-Version: 1.0 @@ -52,19 +53,19 @@ Content-Transfer-Encoding: 8bit Return-path: <request-5335-xxxxxxxx@whatdotheyknow.com> Received: from [212.50.160.60] (helo=venus.karoo.kcom.com) - by smtp-in.karoo.kcom.comwith esmtp (Exim 4.30) - id 1LIPu0-0004fc-FM server-id smtp-in4 - for clerk@humberside-pa.karoo.co.uk; Thu, 01 Jan 2009 15:56:04 +0000 + by smtp-in.karoo.kcom.comwith esmtp (Exim 4.30) + id 1LIPu0-0004fc-FM server-id smtp-in4 + for clerk@humberside-pa.karoo.co.uk; Thu, 01 Jan 2009 15:56:04 +0000 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AnECAF9nXElSb+bUmWdsb2JhbACMZQGHFQEBAQEBCAsKBxG2eIVy -X-IronPort-AV: E=Sophos;i="4.36,313,1228089600"; +X-IronPort-AV: E=Sophos;i="4.36,313,1228089600"; d="scan'208";a="465483300" Received: from sandwich.ukcod.org.uk ([82.111.230.212]) by venus.karoo.kcom.com with ESMTP; 01 Jan 2009 15:46:44 +0000 Received: from foi by sandwich.ukcod.org.uk with local (Exim 4.63) - (envelope-from <request-5335-xxxxxxxx@whatdotheyknow.com>) - id 1LIPtz-0004AG-OC - for clerk@humberside-pa.karoo.co.uk; Thu, 01 Jan 2009 15:56:03 +0000 + (envelope-from <request-5335-xxxxxxxx@whatdotheyknow.com>) + id 1LIPtz-0004AG-OC + for clerk@humberside-pa.karoo.co.uk; Thu, 01 Jan 2009 15:56:03 +0000 From: John Jarman <request-5335-xxxxxxxx@whatdotheyknow.com> To: FOI requests at Humberside Police Authority <clerk@humberside-pa.karoo.co.uk> Subject: Freedom of Information request - Police Injury Award Pensions diff --git a/spec/fixtures/files/incoming-request-attachment-headers.email b/spec/fixtures/files/incoming-request-attachment-headers.email new file mode 100644 index 000000000..80e71556d --- /dev/null +++ b/spec/fixtures/files/incoming-request-attachment-headers.email @@ -0,0 +1,50 @@ +From foi@example.com Mon Oct 06 13:45:38 2008 +Return-path: <foi@example.com> +Envelope-to: foi@sandwich.ukcod.org.uk +Delivery-date: Mon, 06 Oct 2008 13:45:38 +0100 +Message-Id: <s8ea1156.098@example.com> +X-Mailer: Novell GroupWise Internet Agent 6.5.4 +Date: Mon, 06 Oct 2008 13:23:00 +0100 +From: "Steve Knight" <foi@example.com> +To: <request-xxxx-xxxxx@whatdotheyknow.com> +Subject: FOI request +Mime-Version: 1.0 +Content-Type: multipart/mixed; boundary="=__PartFDD45234.0__=" +X-Proofpoint-Virus-Version: vendor=nai engine=5.2.00 definitions=5398 signatures=473327 +X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 classifier= adjust=0 reason=limit engine=3.1.0-0805090000 definitions=main-0810060054 + +This is a MIME message. If you are reading this text, you may want to +consider changing to a mail reader or gateway that understands how to +properly handle MIME multipart messages. +--=__PartFDD45234.0__= +Content-Type: text/plain; charset=US-ASCII +Content-Transfer-Encoding: quoted-printable +Content-Disposition: inline + +Dear Mr Requester, + +Here is some information. + +--=__PartFDD45234.0__= +Content-Type: message/rfc822 + +Date: Fri, 23 May 2008 17:02:11 +0100 +From: "David Bishop" <foi2@example.com> +To: "foi" <foi3@example.com> +Subject: Foi request +Mime-Version: 1.0 +Content-Type: text/plain; charset=US-ASCII +Content-Transfer-Encoding: quoted-printable +Content-Disposition: inline + +Extra info. + +--=__PartFDD45234.0__= +Content-Type: image/jpeg; name="info.jpg" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="info.jpg" + +xxxx + +--=__PartFDD45234.0__=-- + diff --git a/spec/fixtures/files/incoming-request-attachment-unknown-extension.email b/spec/fixtures/files/incoming-request-attachment-unknown-extension.email index b3485ec2d..aecd9a52c 100644 --- a/spec/fixtures/files/incoming-request-attachment-unknown-extension.email +++ b/spec/fixtures/files/incoming-request-attachment-unknown-extension.email @@ -4,17 +4,16 @@ Subject: Same attachment twice Content-Type: multipart/mixed; boundary="Q68bSM7Ycu6FN28Q" Content-Disposition: inline - --Q68bSM7Ycu6FN28Q Content-Type: text/plain; charset=utf-8 Content-Disposition: inline - --Q68bSM7Ycu6FN28Q Content-Type: application/x-nonsense Content-Disposition: attachment; filename="hello.qwglhm" This is an unusual sort of file. ---Q68bSM7Ycu6FN28Q +--Q68bSM7Ycu6FN28Q-- + diff --git a/spec/fixtures/files/many-attachments-date-header.email b/spec/fixtures/files/many-attachments-date-header.email new file mode 100644 index 000000000..a241e2456 --- /dev/null +++ b/spec/fixtures/files/many-attachments-date-header.email @@ -0,0 +1,451 @@ +From email@example.com Wed Apr 14 11:23:08 2010 +Return-path: <email@example.com> +Envelope-to: email@example.com +Delivery-date: Wed, 14 Apr 2010 11:23:08 +0100 +X-TM-IMSS-Message-ID:<email@example.com> +Received: from example.com ([0.0.0.0]) by example.com ([0.0.0.0]) with ESMTP (TREND IMSS SMTP Service 7.0) id 1ec0f7ac0002a77f ; Wed, 14 Apr 2010 11:22:52 +0100 +Received: from GWGATE-MTA by example.com + with Novell_GroupWise; Wed, 14 Apr 2010 11:22:53 +0100 +Message-Id: <email@example.com> +X-Mailer: Novell GroupWise Internet Agent 8.0.1 +Date: Wed, 14 Apr 2010 11:22:47 +0100 +From: "A Person" <email@example.com> +To: <email@example.com> +Cc: "FOI FOI" <email@example.com>, + "A Person" <email@example.com> +Subject: Fwd: Re: Freedom of Information request +References: <email@example.com> + <email@example.com> +Mime-Version: 1.0 +Content-Type: multipart/mixed; boundary="=__Part163C9567.0__=" + +This is a MIME message. If you are reading this text, you may want to +consider changing to a mail reader or gateway that understands how to +properly handle MIME multipart messages. + +--=__Part163C9567.0__= +Content-Type: text/plain; charset=US-ASCII +Content-Transfer-Encoding: quoted-printable +Content-Disposition: inline + +Some information + + +--=__Part163C9567.0__= +Content-Type: message/rfc822 + +Date: Wed, 10 Mar 2010 14:17:52 +0000 +From: "A Person" <email@example.com> +To: "A Person" <email@example.com> +Subject: Re: xxx +Mime-Version: 1.0 +Content-Type: text/plain; charset=US-ASCII +Content-Transfer-Encoding: quoted-printable +Content-Disposition: inline + +2 + +--=__Part163C9567.0__= +Content-Type: message/rfc822 + +Return-path: <email@example.com> +Received: from example.com ([0.0.0.0]) + by example.com with ESMTP; Tue, 24 Nov 2009 10:45:58 +0000 +X-TM-IMSS-Message-ID:<email@example.com> +Received: from example.com ([0.0.0.0]) by example.com ([0.0.0.0]) with SMTP (TREND IMSS SMTP Service 7.0) id 00660acd00000f42 ; Tue, 24 Nov 2009 10:45:55 +0000 +Received: from source ([0.0.0.0]) (using TLSv1) by eu1sys200aob115.postini.com ([0.0.0.0]) with SMTP + ID email@example.com Tue, 24 Nov 2009 10:45:56 UTC +Received: from example.com ([::1]) by + example.com ([::1]) with mapi; Tue, 24 Nov 2009 + 10:45:53 +0000 +From: A Person <email@example.com> +To: email@example.com <email@example.com> +Date: Tue, 24 Nov 2009 10:45:52 +0000 +Subject: example +Thread-Topic: example +Thread-Index: AcpnbI2i+XAmfHFVTFy0eGDpVJhXoQFhVeZw +Message-ID: <email@example.com> +Accept-Language: en-US, en-GB +Content-Language: en-US +X-MS-Has-Attach: yes +X-MS-TNEF-Correlator: +acceptlanguage: en-US, en-GB +Content-Type: multipart/mixed; + boundary="_006_B3BDF1D06801114FA040D0F1BEE7CF9C48FD3549evs02ukcommonpu_" +MIME-Version: 1.0 +X-TM-AS-Product-Ver: IMSS-0.0.0.0-0.0.0.0-17028.005 +X-TM-AS-Result: No--19.329-5.0-31-1 +X-imss-scan-details: No--19.329-5.0-31-1 +X-TM-AS-User-Approved-Sender: No +X-TM-AS-User-Blocked-Sender: No + + +--_006_B3BDF1D06801114FA040D0F1BEE7CF9C48FD3549evs02ukcommonpu_ +Content-Type: multipart/related; + boundary="_005_B3BDF1D06801114FA040D0F1BEE7CF9C48FD3549evs02ukcommonpu_"; + type="multipart/alternative" + +--_005_B3BDF1D06801114FA040D0F1BEE7CF9C48FD3549evs02ukcommonpu_ +Content-Type: multipart/alternative; + boundary="_000_B3BDF1D06801114FA040D0F1BEE7CF9C48FD3549evs02ukcommonpu_" + +--_000_B3BDF1D06801114FA040D0F1BEE7CF9C48FD3549evs02ukcommonpu_ +Content-Type: text/plain; charset="iso-8859-1" +Content-Transfer-Encoding: quoted-printable + + +3 + +--_000_B3BDF1D06801114FA040D0F1BEE7CF9C48FD3549evs02ukcommonpu_ +Content-Type: text/html; charset="iso-8859-1" +Content-Transfer-Encoding: quoted-printable + +4 + +--_000_B3BDF1D06801114FA040D0F1BEE7CF9C48FD3549evs02ukcommonpu_-- + +--_005_B3BDF1D06801114FA040D0F1BEE7CF9C48FD3549evs02ukcommonpu_ +Content-Type: image/gif; name="image001.gif" +Content-Description: image001.gif +Content-Disposition: inline; filename="image001.gif"; size=5445; + creation-date="Tue, 17 Nov 2009 09:58:46 GMT"; + modification-date="Tue, 17 Nov 2009 09:58:46 GMT" +Content-ID: <email@example.com> +Content-Transfer-Encoding: base64 + +5 +--_005_B3BDF1D06801114FA040D0F1BEE7CF9C48FD3549evs02ukcommonpu_-- + +--_006_B3BDF1D06801114FA040D0F1BEE7CF9C48FD3549evs02ukcommonpu_ +Content-Type: application/vnd.ms-excel; + name="particpant list.xls" +Content-Description: particpant list.xls +Content-Disposition: attachment; + filename="particpant list.xls"; size=21504; + creation-date="Mon, 02 Nov 2009 09:42:37 GMT"; + modification-date="Tue, 24 Nov 2009 10:45:52 GMT" +Content-Transfer-Encoding: base64 + +6 + +--_006_B3BDF1D06801114FA040D0F1BEE7CF9C48FD3549evs02ukcommonpu_-- +--=__Part163C9567.0__= +Content-Type: message/rfc822 + +Return-path: <email@example.com> +Received: from example.com ([0.0.0.0]) + by example.com with ESMTP; Thu, 03 Dec 2009 09:29:07 +0000 +X-TM-IMSS-Message-ID:<email@example.com> +Received: from eu1sys200aog116.obsmtp.com ([0.0.0.0]) by example.com ([0.0.0.0]) with SMTP (TREND IMSS SMTP Service 7.0) id 0ac1bf1b0001116e ; Thu, 3 Dec 2009 09:29:04 +0000 +Received: from source ([0.0.0.0]) (using TLSv1) by eu1sys200aob116.postini.com ([0.0.0.0]) with SMTP + ID email@example.com Thu, 03 Dec 2009 09:29:06 UTC +Received: from example.com ([::1]) by + example.com ([::1]) with mapi; Thu, 3 Dec 2009 09:29:03 + +0000 +From: A Person <email@example.com> +To: 'A Person' <email@example.com> +Date: Thu, 3 Dec 2009 09:29:03 +0000 +Subject: RE: example +Thread-Topic: example +Thread-Index: AcpuoEyRvzM8fXw+THuj/617pjnvCgFWqZdQ +Message-ID: <email@example.com> +References: <email@example.com> + <email@example.com> +In-Reply-To: <email@example.com> +Accept-Language: en-US, en-GB +Content-Language: en-US +X-MS-Has-Attach: +X-MS-TNEF-Correlator: +acceptlanguage: en-US, en-GB +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: base64 +MIME-Version: 1.0 +X-TM-AS-Product-Ver: IMSS-0.0.0.0-0.0.0.0-17046.004 +X-TM-AS-Result: No--16.791-5.0-31-1 +X-imss-scan-details: No--16.791-5.0-31-1 +X-TM-AS-User-Approved-Sender: No +X-TM-AS-User-Blocked-Sender: No + + +7 +--=__Part163C9567.0__= +Content-Type: message/rfc822 + +Return-path: <email@example.com> +Received: from example.com ([0.0.0.0]) + by example.com with ESMTP; Wed, 25 Nov 2009 22:26:23 +0000 +X-TM-IMSS-Message-ID:<email@example.com> +Received: from eu1sys200aog105.obsmtp.com ([0.0.0.0]) by example.com ([0.0.0.0]) with SMTP (TREND IMSS SMTP Service 7.0) id 034354c900007016 ; Wed, 25 Nov 2009 22:26:19 +0000 +Received: from source ([0.0.0.0]) (using TLSv1) by eu1sys200aob105.postini.com ([0.0.0.0]) with SMTP + ID email@example.com Wed, 25 Nov 2009 22:26:21 UTC +Received: from example.com ([::1]) by + example.com ([::1]) with mapi; Wed, 25 Nov 2009 + 22:26:15 +0000 +From: A Person <email@example.com> +To: email@example.com <email@example.com> +CC: A Person <email@example.com> +Date: Wed, 25 Nov 2009 22:26:12 +0000 +Subject: As promised - Masterclass info (example) +Thread-Topic: As promised - Masterclass info (example) +Thread-Index: AcpuHcJ4yrR8PBHZTVCU/RLGzwqsDAAACGwQ +Message-ID: <email@example.com> +Accept-Language: en-US, en-GB +Content-Language: en-US +X-MS-Has-Attach: yes +X-MS-TNEF-Correlator: +acceptlanguage: en-US, en-GB +Content-Type: multipart/mixed; + boundary="_007_B3BDF1D06801114FA040D0F1BEE7CF9C48DC6D82evs02ukcommonpu_" +MIME-Version: 1.0 +X-TM-AS-Product-Ver: IMSS-0.0.0.0-0.0.0.0-17032.000 +X-TM-AS-Result: No--26.167-5.0-31-1 +X-imss-scan-details: No--26.167-5.0-31-1 +X-TM-AS-User-Approved-Sender: No +X-TM-AS-User-Blocked-Sender: No + + +--_007_B3BDF1D06801114FA040D0F1BEE7CF9C48DC6D82evs02ukcommonpu_ +Content-Type: multipart/related; + boundary="_006_B3BDF1D06801114FA040D0F1BEE7CF9C48DC6D82evs02ukcommonpu_"; + type="multipart/alternative" + +--_006_B3BDF1D06801114FA040D0F1BEE7CF9C48DC6D82evs02ukcommonpu_ +Content-Type: multipart/alternative; + boundary="_000_B3BDF1D06801114FA040D0F1BEE7CF9C48DC6D82evs02ukcommonpu_" + +--_000_B3BDF1D06801114FA040D0F1BEE7CF9C48DC6D82evs02ukcommonpu_ +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: base64 + +8 +--_000_B3BDF1D06801114FA040D0F1BEE7CF9C48DC6D82evs02ukcommonpu_ +Content-Type: text/html; charset="utf-8" +Content-Transfer-Encoding: base64 + +9 +--_000_B3BDF1D06801114FA040D0F1BEE7CF9C48DC6D82evs02ukcommonpu_-- + +--_006_B3BDF1D06801114FA040D0F1BEE7CF9C48DC6D82evs02ukcommonpu_ +Content-Type: image/gif; name="image001.gif" +Content-Description: image001.gif +Content-Disposition: inline; filename="image001.gif"; size=5445; + creation-date="Wed, 25 Nov 2009 22:26:14 GMT"; + modification-date="Wed, 25 Nov 2009 22:26:14 GMT" +Content-ID: <email@example.com> +Content-Transfer-Encoding: base64 + + +10 + +--_006_B3BDF1D06801114FA040D0F1BEE7CF9C48DC6D82evs02ukcommonpu_-- + +--_007_B3BDF1D06801114FA040D0F1BEE7CF9C48DC6D82evs02ukcommonpu_ +Content-Type: application/msword; + name= "Participant List.doc" +Content-Description: Participant List.doc +Content-Disposition: attachment; + filename="Participant List.doc"; size=112640; + creation-date="Wed, 25 Nov 2009 22:17:24 GMT"; + modification-date="Wed, 25 Nov 2009 11:43:48 GMT" +Content-Transfer-Encoding: base64 + +11 +--_007_B3BDF1D06801114FA040D0F1BEE7CF9C48DC6D82evs02ukcommonpu_ +Content-Type: application/msword; name="Information & Booking Form.doc" +Content-Description: Information & Booking Form.doc +Content-Disposition: attachment; filename="Information & Booking Form.doc"; size=84480; + creation-date="Wed, 25 Nov 2009 22:17:40 GMT"; + modification-date="Wed, 04 Nov 2009 14:42:54 GMT" +Content-Transfer-Encoding: base64 + +12 + +--_007_B3BDF1D06801114FA040D0F1BEE7CF9C48DC6D82evs02ukcommonpu_-- +--=__Part163C9567.0__= +Content-Type: message/rfc822 + +Return-path: <email@example.com> +Received: from example.com ([0.0.0.0]) + by example.com with ESMTP; Fri, 04 Dec 2009 10:00:05 +0000 +X-TM-IMSS-Message-ID:<email@example.com> +Received: from eu1sys200aog109.obsmtp.com ([0.0.0.0]) by example.com ([0.0.0.0]) with SMTP (TREND IMSS SMTP Service 7.0) id 100473260001a476 ; Fri, 4 Dec 2009 10:00:01 +0000 +Received: from source ([0.0.0.0]) (using TLSv1) by eu1sys200aob109.postini.com ([0.0.0.0]) with SMTP + ID email@example.com Fri, 04 Dec 2009 10:00:04 UTC +Received: from example.com ([::1]) by + example.com ([::1]) with mapi; Fri, 4 Dec 2009 10:00:01 + +0000 +From: A Person <email@example.com> +To: email@example.com <email@example.com> +Date: Fri, 4 Dec 2009 10:00:01 +0000 +Subject: Re: As promised - info (example) +Thread-Topic: As promised - info (example) +Thread-Index: AcpzhLeBjBId8eZATYudOfBgN6CPXQBQ9Pok +Message-ID: <email@example.com> +Accept-Language: en-US, en-GB +Content-Language: en-US +X-MS-Has-Attach: +X-MS-TNEF-Correlator: +acceptlanguage: en-US, en-GB +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: base64 +MIME-Version: 1.0 +X-TM-AS-Product-Ver: IMSS-0.0.0.0-0.0.0.0-17048.005 +X-TM-AS-Result: No--24.171-5.0-31-1 +X-imss-scan-details: No--24.171-5.0-31-1 +X-TM-AS-User-Approved-Sender: No +X-TM-AS-User-Blocked-Sender: No + +13 +--=__Part163C9567.0__= +Content-Type: message/rfc822 + +Return-path: <email@example.com> +Received: from example.com ([0.0.0.0]) + by example.com with ESMTP; Sun, 21 Mar 2010 21:53:38 +0000 +X-TM-IMSS-Message-ID:<email@example.com> +Received: from eu1sys200aog117.obsmtp.com ([0.0.0.0]) by example.com ([0.0.0.0]) with SMTP (TREND IMSS SMTP Service 7.0) id 1e3611c1000d37df ; Sun, 21 Mar 2010 21:53:32 +0000 +Received: from source ([0.0.0.0]) (using TLSv1) by eu1sys200aob117.postini.com ([0.0.0.0]) with SMTP + ID email@example.com Sun, 21 Mar 2010 21:53:37 UTC +Received: from example.com ([::1]) by exchhub01 + ([0.0.0.0]) with mapi; Sun, 21 Mar 2010 21:53:34 +0000 +From: A Person <email@example.com> +To: email@example.com <email@example.com> +CC: A Person <email@example.com> +Date: Sun, 21 Mar 2010 21:53:32 +0000 +Subject: Thank you from example +Thread-Topic: Thank you from example +Thread-Index: AcrJQPL4xb9zjXMHRJGTjAxo3X/kfA== +Message-ID: <email@example.com> +Accept-Language: en-US, en-GB +Content-Language: en-US +X-MS-Has-Attach: yes +X-MS-TNEF-Correlator: +acceptlanguage: en-US, en-GB +Content-Type: multipart/related; + boundary="_004_B3BDF1D06801114FA040D0F1BEE7CF9C5E14635Bevs02ukcommonpu_"; + type="multipart/alternative" +MIME-Version: 1.0 +X-TM-AS-Product-Ver: IMSS-0.0.0.0-0.0.0.0-17266.002 +X-TM-AS-Result: No--26.373-5.0-31-1 +X-imss-scan-details: No--26.373-5.0-31-1 +X-TM-AS-User-Approved-Sender: No +X-TM-AS-User-Blocked-Sender: No + + +--_004_B3BDF1D06801114FA040D0F1BEE7CF9C5E14635Bevs02ukcommonpu_ +Content-Type: multipart/alternative; + boundary="_000_B3BDF1D06801114FA040D0F1BEE7CF9C5E14635Bevs02ukcommonpu_" + +--_000_B3BDF1D06801114FA040D0F1BEE7CF9C5E14635Bevs02ukcommonpu_ +Content-Type: text/plain; charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +14 + +--_000_B3BDF1D06801114FA040D0F1BEE7CF9C5E14635Bevs02ukcommonpu_ +Content-Type: text/html; charset="us-ascii" +Content-Transfer-Encoding: quoted-printable + +15 + +--_000_B3BDF1D06801114FA040D0F1BEE7CF9C5E14635Bevs02ukcommonpu_-- + +--_004_B3BDF1D06801114FA040D0F1BEE7CF9C5E14635Bevs02ukcommonpu_ +Content-Type: image/gif; name="image001.gif" +Content-Description: image001.gif +Content-Disposition: inline; filename="image001.gif"; size=5445; + creation-date="Sun, 21 Mar 2010 21:53:33 GMT"; + modification-date="Sun, 21 Mar 2010 21:53:33 GMT" +Content-ID: <email@example.com> +Content-Transfer-Encoding: base64 + +16 +--_004_B3BDF1D06801114FA040D0F1BEE7CF9C5E14635Bevs02ukcommonpu_-- +--=__Part163C9567.0__= +Content-Type: message/rfc822 + +Return-path: <email@example.com> +Received: from example.com ([0.0.0.0]) + by example.com with ESMTP; Tue, 23 Feb 2010 15:33:48 +0000 +X-TM-IMSS-Message-ID:<email@example.com> +Received: from eu1sys200aog112.obsmtp.com ([0.0.0.0]) by example.com ([0.0.0.0]) with SMTP (TREND IMSS SMTP Service 7.0) id 96f54043000f2e72 ; Tue, 23 Feb 2010 15:33:48 +0000 +Received: from source ([0.0.0.0]) by eu1sys200aob112.postini.com ([0.0.0.0]) with SMTP + ID email@example.com Tue, 23 Feb 2010 15:33:47 UTC +Received: from gla-002561-lap ([0.0.0.0]) by example.com with Microsoft SMTPSVC(0.0.0.0); + Tue, 23 Feb 2010 15:33:46 +0000 +Reply-To: email@example.com +From: email@example.com +To: email@example.com +Subject: example - Meeting - Tuesday 2nd March +Date: 23 February 2010 15:33 +X-Mailer: Internet Professional v1.15 +Return-Path: email@example.com +Message-ID: <email@example.com> +X-OriginalArrivalTime: 23 Feb 2010 15:33:46.0648 (UTC) FILETIME=[96CEC980:01CAB49D] +X-TM-AS-Product-Ver: IMSS-0.0.0.0-0.0.0.0-17212.000 +X-TM-AS-Result: No--16.146-5.0-31-1 +X-imss-scan-details: No--16.146-5.0-31-1 +X-TM-AS-User-Approved-Sender: No +X-TM-AS-User-Blocked-Sender: No + +17 + +--=__Part163C9567.0__= +Content-Type: message/rfc822 + +Return-path: <email@example.com> +Received: from example.com ([0.0.0.0]) + by example.com with ESMTP; Mon, 08 Mar 2010 09:21:42 +0000 +X-TM-IMSS-Message-ID:<email@example.com> +Received: from eu1sys200aog117.obsmtp.com ([0.0.0.0]) by example.com ([0.0.0.0]) with SMTP (TREND IMSS SMTP Service 7.0) id d8931aff001580d6 ; Mon, 8 Mar 2010 09:21:40 +0000 +Received: from source ([0.0.0.0]) by eu1sys200aob117.postini.com ([0.0.0.0]) with SMTP + ID email@example.com Mon, 08 Mar 2010 09:21:39 UTC +Received: from gla-002561-lap ([0.0.0.0]) by example.com with Microsoft SMTPSVC(0.0.0.0); + Mon, 8 Mar 2010 09:21:36 +0000 +Reply-To: email@example.com +From: email@example.com +To: email@example.com +Subject: example - Help needed +Date: 08 March 2010 09:21 +X-Mailer: Internet Professional v1.15 +MIME-Version: 1.0 +Content-Type: multipart/mixed;boundary="_NextPart_00009D35-00000F3C-00271781-26DF" +Return-Path: email@example.com +Message-ID: <email@example.com> +X-OriginalArrivalTime: 08 Mar 2010 09:21:36.0283 (UTC) FILETIME=[C03E3EB0:01CABEA0] +X-TM-AS-Product-Ver: IMSS-0.0.0.0-0.0.0.0-17236.006 +X-TM-AS-Result: No--32.111-5.0-31-1 +X-imss-scan-details: No--32.111-5.0-31-1 +X-TM-AS-User-Approved-Sender: No +X-TM-AS-User-Blocked-Sender: No + +This message is in MIME format. Since your mail reader does not +understand this format, some or all of this message may not be legible. +--_NextPart_00009D35-00000F3C-00271781-26DF +Content-Type: text/plain +Content-Transfer-Encoding: 7bit + +18 + +--_NextPart_00009D35-00000F3C-00271781-26DF +Content-Type: application/octet-stream;name="Information Pack.pdf" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment;filename="Information Pack.pdf";size=106688 + +19 +--_NextPart_00009D35-00000F3C-00271781-26DF-- +--=__Part163C9567.0__= +Content-Type: message/rfc822 + +Date: Wed, 02 Dec 2009 19:21:27 +0000 +From: "A Person" <email@example.com> +To: "A Person" <email@example.com> +Subject: Re: As promised - info (example) +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Content-Disposition: inline + +20 +--=__Part163C9567.0__=-- + diff --git a/spec/fixtures/files/rfc822-attachment.email b/spec/fixtures/files/rfc822-attachment.email new file mode 100644 index 000000000..ae58a06af --- /dev/null +++ b/spec/fixtures/files/rfc822-attachment.email @@ -0,0 +1,147 @@ +From foi.officer@example.com Fri Mar 14 08:39:57 2008 +Return-path: <foi.officer@example.com> +Envelope-to: request-bounce-xx-xxxxx@whatdotheyknow.com +Delivery-date: Fri, 14 Mar 2008 08:39:57 +0000 +Received: from service27.mimecast.com ([213.235.63.79]:55305) + by tea.ukcod.org.uk with smtp (Exim 4.50) + id 1Ja5SH-0005iP-Jm + for xxx@whatdotheyknow.com; Fri, 14 Mar 2008 08:39:57 +0000 +Received: from mailscan.ad.example.com (mailgate.example.com [194.70.143.2]) + by service27.mimecast.com; + Fri, 14 Mar 2008 08:38:47 +0000 +Received: from exch2serv.ad.example.com ([201.234.62.4]) by mailscan.ad.example.com with InterScan Message Security Suite; Fri, 14 Mar 2008 08:38:47 -0000 +X-MIMEOLE: Produced By Microsoft Exchange V6.0.6603.0 +content-class: urn:content-classes:message +MIME-Version: 1.0 +Subject: +Date: Fri, 14 Mar 2008 08:38:46 -0000 +Message-ID: <0F3951EA9DCFB246827E1F6513F6C79D096DDADB@exch2serv.ad.example.com> +X-MS-Has-Attach: yes +X-MS-TNEF-Correlator: +Thread-Index: AciFrtIeS9pyMOhuQdyxkm5305zs9g== +From: "An FOI Officer" <foi.officer@example.com> +To: "On" <request-bounce-xx-xxxxx@whatdotheyknow.com> +X-MC-Unique: 108031408384702301 +Content-Type: multipart/mixed; + boundary="----_=_NextPart_001_01C885AE.D1BF23AC" + +This is a multi-part message in MIME format. + +------_=_NextPart_001_01C885AE.D1BF23AC +Content-Type: multipart/alternative; + boundary="MCBoundary=_108031408384800401" + +--MCBoundary=_108031408384800401 +Content-Type: text/plain; charset=WINDOWS-1252 +Content-Transfer-Encoding: quoted-printable + + + <<Freedom of Information request >>=20 + + +e-mail: foi.officer@example.com=20 + + + + +***************************************************************************= +******** +The information in this Email and any attachments is personal to the +sender and the views of the author may not necessarily reflect those +of Borough Council. The information is strictly confidential +and is intended only for the named person or organisation to whom it is +addressed as it may contain privileged and confidential information. If +you are not the intended recipient do not copy, distribute or use this +Email, and please notify the sender. Please note that we cannot +guarantee that this message or any attachment is virus free or has not +been intercepted and amended. +***************************************************************************= +******** + +Disclaimer=20 +---------------------------------------------------------------------------= +---------------- +This email message has been scanned for viruses by Mimecast. +Mimecast delivers a complete managed email solution from a single web based= + platform. +For more information please visit www.mimecast.com +---------------------------------------------------------------------------= +---------------- +--MCBoundary=_108031408384800401 +Content-Type: text/html; charset=WINDOWS-1252 +Content-Transfer-Encoding: quoted-printable + +<HTML><BODY> =20 + <BR> + <<Freedom of Information request >> <BR> +<BR> +e-mail: <a href=3D"mailto:foi.officer@example.com">foi.officer@example.com</a> <BR> +<BR> +<BR> +<BR> +<BR> +***************************************************************************= +********<BR> +The information in this Email and any attachments is personal to the<B= +R> +sender and the views of the author may not necessarily reflect those<BR= +> +of Borough Council. The information is strictly confidential<B= +R> +and is intended only for the named person or organisation to whom it is<BR> +addressed as it may contain privileged and confidential information. If<B= +R> +you are not the intended recipient do not copy, distribute or use this= +<BR> +Email, and please notify the sender. Please note that we cannot<B= +R> +guarantee that this message or any attachment is virus free or has not<BR> +been intercepted and amended.<BR> +***************************************************************************= +********<BR> + + <BR> + <BR> + <span style=3D"font-family:Arial; Font-size:10.0pt"> + Disclaimer <p> + <hr width=3D"100%"> + This email message has been scanned for viruses by Mimecast.<BR> + Mimecast delivers a complete managed email solution from a single we= +b based platform.<BR> + For more information please visit <a href=3D"http://www.mimecast.com= +">http://www.mimecast.com</a> + <hr width=3D"100%"> + </span> + </BODY></HTML> + + +--MCBoundary=_108031408384800401-- +------_=_NextPart_001_01C885AE.D1BF23AC +Content-Type: message/rfc822 +Content-Transfer-Encoding: 7bit + +X-MIMEOLE: Produced By Microsoft Exchange V6.0.6603.0 +content-class: urn:content-classes:message +MIME-Version: 1.0 +Subject: Freedom of Information request +Date: Thu, 13 Mar 2008 16:57:33 -0000 +Message-ID: <0F3951EA9DCFB246827E1F6513F6C79D098AC8C5@exch2serv.ad.example.com> +X-MS-Has-Attach: +X-MS-TNEF-Correlator: +Thread-Topic: Freedom of Information request +Thread-Index: AciE9w0L7QnQlahDQS+Zjrz40mr8KAAD5KuQAADg+1AABjC9wAAAXtJgAAEHJvAAAHTxwA== +X-Priority: 1 +Priority: Urgent +Importance: high +From: "An FOI Officer" <foi.officer@example.com> +To: <request-bounce-xx-xxxxx@whatdotheyno.com> +Content-Type: text/plain; + charset="utf-8" +Content-Transfer-Encoding: base64 + +c29tZSBleGFtcGxlIHRleHQ= + +------_=_NextPart_001_01C885AE.D1BF23AC-- + + + diff --git a/spec/lib/i18n_interpolation.rb b/spec/lib/i18n_interpolation.rb index 8c86413ad..6b745059c 100644 --- a/spec/lib/i18n_interpolation.rb +++ b/spec/lib/i18n_interpolation.rb @@ -1,6 +1,3 @@ -# This is a test of the set_content_type monkey patch in -# lib/tmail_extensions.rb - require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe "when using i18n" do diff --git a/spec/lib/mail_handler/mail_handler_spec.rb b/spec/lib/mail_handler/mail_handler_spec.rb index a3fba0698..ae65210f2 100644 --- a/spec/lib/mail_handler/mail_handler_spec.rb +++ b/spec/lib/mail_handler/mail_handler_spec.rb @@ -1,6 +1,12 @@ # coding: utf-8 require File.expand_path(File.dirname(__FILE__) + '../../../spec_helper') +def create_message_from(from_field) + mail_data = load_file_fixture('incoming-request-plain.email') + mail_data.gsub!('EMAIL_FROM', from_field) + mail = MailHandler.mail_from_raw_email(mail_data) +end + describe 'when creating a mail object from raw data' do it 'should correctly parse a multipart email with a linebreak in the boundary' do @@ -17,7 +23,361 @@ describe 'when creating a mail object from raw data' do it 'should convert an iso8859 email to utf8' do mail = get_fixture_mail('iso8859_2_raw_email.email') mail.subject.should have_text(/gjatë/u) - mail.body.is_utf8?.should == true + MailHandler.get_part_body(mail).is_utf8?.should == true + end + +end + +describe 'when asked for the from name' do + + it 'should return nil if there is a blank "From" field' do + mail = create_message_from('') + MailHandler.get_from_name(mail).should == nil + end + + it 'should correctly return an encoded name from the from field' do + mail = get_fixture_mail('quoted-subject-iso8859-1.email') + MailHandler.get_from_name(mail).should == 'Coordenação de Relacionamento, Pesquisa e Informação/CEDI' + end + + it 'should get a name from a "From" field with a name and address' do + mail = get_fixture_mail('incoming-request-oft-attachments.email') + MailHandler.get_from_name(mail).should == 'Public Authority' + end + + it 'should return nil from a "From" field that is just a name'do + mail = get_fixture_mail('track-response-webshield-bounce.email') + MailHandler.get_from_name(mail).should == nil + end + +end + +describe 'when asked for the from address' do + + it 'should return nil if there is a blank "From" field' do + mail = create_message_from('') + MailHandler.get_from_address(mail).should == nil + end + + it 'should correctly return an address from a mail that has an encoded name in the from field' do + mail = get_fixture_mail('quoted-subject-iso8859-1.email') + MailHandler.get_from_address(mail).should == 'geraldinequango@localhost' + end + + it 'should return nil if there is no address in the "From" field' do + mail = get_fixture_mail('track-response-webshield-bounce.email') + MailHandler.get_from_address(mail).should == nil + end + + it 'should return the "From" email address if there is one' do + mail = get_fixture_mail('track-response-abcmail-oof.email') + MailHandler.get_from_address(mail).should == 'Name.Removed@example.gov.uk' + end + + it 'should get an address from a "From" field with a name and address' do + mail = get_fixture_mail('incoming-request-oft-attachments.email') + MailHandler.get_from_address(mail).should == 'public@authority.gov.uk' + end +end + +describe 'when asked for all the addresses a mail has been sent to' do + + it 'should return an array containing the envelope-to address and the to address, and the cc address if there is one' do + mail_data = load_file_fixture('humberside-police-odd-mime-type.email') + mail_data.gsub!('Envelope-to: request-5335-xxxxxxxx@whatdotheyknow.com', + 'Envelope-to: request-5555-xxxxxxxx@whatdotheyknow.com') + mail_data.gsub!('Cc: request-5335-xxxxxxxx@whatdotheyknow.com', + 'Cc: request-3333-xxxxxxxx@whatdotheyknow.com') + mail = MailHandler.mail_from_raw_email(mail_data) + MailHandler.get_all_addresses(mail).should == ['request-5335-xxxxxxxx@whatdotheyknow.com', + 'request-3333-xxxxxxxx@whatdotheyknow.com', + 'request-5555-xxxxxxxx@whatdotheyknow.com'] + end + + it 'should only return unique values' do + # envelope-to and to fields are the same + mail = get_fixture_mail('humberside-police-odd-mime-type.email') + MailHandler.get_all_addresses(mail).should == ['request-5335-xxxxxxxx@whatdotheyknow.com'] + end + + it 'should handle the absence of an envelope-to or cc field' do + mail_data = load_file_fixture('autoresponse-header.email') + mail_data.gsub!('To: FOI Person <EMAIL_TO>', + 'To: FOI Person <request-5555-xxxxxxxx@whatdotheyknow.com>') + mail = MailHandler.mail_from_raw_email(mail_data) + MailHandler.get_all_addresses(mail).should == ["request-5555-xxxxxxxx@whatdotheyknow.com"] + end +end + +describe 'when asked for auto_submitted' do + + it 'should return a string value for an email with an auto-submitted header' do + mail = get_fixture_mail('autoresponse-header.email') + MailHandler.get_auto_submitted(mail).should == 'auto-replied' + end + + it 'should return a nil value for an email with no auto-submitted header' do + mail = get_fixture_mail('incoming-request-plain.email') + MailHandler.get_auto_submitted(mail).should == nil + end + +end + +describe 'when asked if there is an empty return path' do + + it 'should return true if there is an empty return-path specified' do + mail = get_fixture_mail('empty-return-path.email') + MailHandler.empty_return_path?(mail).should == true + end + + it 'should return false if there is no return-path header' do + mail = get_fixture_mail('incoming-request-attach-attachments.email') + MailHandler.empty_return_path?(mail).should == false + end + + it 'should return false if there is a return path address' do + mail = get_fixture_mail('autoresponse-header.email') + MailHandler.empty_return_path?(mail).should == false + end +end + +describe 'when deriving a name, email and formatted address from a message from a line' do + + def should_render_from_address(from_line, expected_result) + mail = create_message_from(from_line) + name = MailHandler.get_from_name(mail) + email = MailHandler.get_from_address(mail) + address = MailHandler.address_from_name_and_email(name, email).to_s + [name, email, address].should == expected_result + end + + it 'should correctly render a name with quoted commas' do + should_render_from_address('"Clare College, Cambridge" <test@test.test>', + ['Clare College, Cambridge', + 'test@test.test', + '"Clare College, Cambridge" <test@test.test>']) end + it 'should correctly reproduce a simple name and email that does not need quotes' do + should_render_from_address('"FOI Person" <foiperson@localhost>', + ['FOI Person', + 'foiperson@localhost', + 'FOI Person <foiperson@localhost>']) + end + + it 'should render an address with no name' do + should_render_from_address("foiperson@localhost", + [nil, + "foiperson@localhost", + "foiperson@localhost"]) + end + + it 'should quote a name with a square bracked in it' do + should_render_from_address('"FOI [ Person" <foiperson@localhost>', + ['FOI [ Person', + 'foiperson@localhost', + '"FOI [ Person" <foiperson@localhost>']) + end + + it 'should quote a name with an @ in it' do + should_render_from_address('"FOI @ Person" <foiperson@localhost>', + ['FOI @ Person', + 'foiperson@localhost', + '"FOI @ Person" <foiperson@localhost>']) + end + + + it 'should quote a name with quotes in it' do + should_render_from_address('"FOI \" Person" <foiperson@localhost>', + ['FOI " Person', + 'foiperson@localhost', + '"FOI \" Person" <foiperson@localhost>']) + end + +end + +describe 'when getting the content type of a mail part' do + + def expect_content_type(fixture_file, content_type) + mail = get_fixture_mail(fixture_file) + MailHandler.get_content_type(mail).should == content_type + end + + it 'should correctly return a type of "multipart/report"' do + expect_content_type('track-response-multipart-report.email', 'multipart/report') + end + + it 'should correctly return a type of "text/plain"' do + expect_content_type('track-response-abcmail-oof.email', 'text/plain') + end + + it 'should correctly return a type of "multipart/mixed"' do + expect_content_type('track-response-messageclass-oof.email', 'multipart/mixed') + end + + it 'should correctly return the types in an example bounce report' do + mail = get_fixture_mail('track-response-ms-bounce.email') + report = mail.parts.detect{ |part| MailHandler.get_content_type(part) == 'multipart/report'} + MailHandler.get_content_type(report.parts[0]).should == 'text/plain' + MailHandler.get_content_type(report.parts[1]).should == 'message/delivery-status' + MailHandler.get_content_type(report.parts[2]).should == 'message/rfc822' + end + +end + +describe 'when getting header strings' do + + def expect_header_string(fixture_file, header, header_string) + mail = get_fixture_mail(fixture_file) + MailHandler.get_header_string(header, mail).should == header_string + end + + it 'should return the contents of a "Subject" header' do + expect_header_string('track-response-ms-bounce.email', + 'Subject', + 'Delivery Status Notification (Delay)') + end + + it 'should return the contents of an "X-Failed-Recipients" header' do + expect_header_string('autoresponse-header.email', + 'X-Failed-Recipients', + 'enquiries@cheese.com') + end + + it 'should return the contents of an example "" header' do + expect_header_string('track-response-messageclass-oof.email', + 'X-POST-MessageClass', + '9; Autoresponder') + end + +end + +describe "when parsing HTML mail" do + it "should display UTF-8 characters in the plain text version correctly" do + html = "<html><b>foo</b> është" + plain_text = MailHandler.get_attachment_text_one_file('text/html', html) + plain_text.should match(/është/) + end + +end + +describe "when getting the attachment text" do + it "should not raise an error if the expansion of a zip file raises an error" do + mock_entry = mock('ZipFile entry', :file? => true) + mock_entries = [mock_entry] + mock_entries.stub!(:close) + mock_entry.stub!(:get_input_stream).and_raise("invalid distance too far back") + Zip::ZipFile.stub!(:open).and_return(mock_entries) + MailHandler.get_attachment_text_one_file('application/zip', "some string") + end + +end + +describe 'when getting attachment attributes' do + + it 'should get two attachment parts from a multipart mail with text and html alternatives + and an image' do + mail = get_fixture_mail('quoted-subject-iso8859-1.email') + attributes = MailHandler.get_attachment_attributes(mail) + attributes.size.should == 2 + end + + it 'should expand a mail attached as text' do + mail = get_fixture_mail('rfc822-attachment.email') + attributes = MailHandler.get_attachment_attributes(mail) + attributes.size.should == 2 + rfc_attachment = attributes[1] + rfc_attachment[:within_rfc822_subject].should == 'Freedom of Information request' + headers = ['Date: Thu, 13 Mar 2008 16:57:33 +0000', + 'Subject: Freedom of Information request', + 'From: An FOI Officer <foi.officer@example.com>', + 'To: request-bounce-xx-xxxxx@whatdotheyno.com'] + rfc_attachment[:body].should == "#{headers.join("\n")}\n\nsome example text" + end + + it 'should handle a mail which causes Tmail to generate a blank header value' do + mail = get_fixture_mail('many-attachments-date-header.email') + attributes = MailHandler.get_attachment_attributes(mail) + end + + it 'should produce a consistent set of url_part_numbers, content_types, within_rfc822_subjects + and filenames from an example mail with lots of attachments' do + mail = get_fixture_mail('many-attachments-date-header.email') + attributes = MailHandler.get_attachment_attributes(mail) + + expected_attributes = [ { :content_type=>"text/plain", + :url_part_number=>1, + :within_rfc822_subject=>nil, + :filename=>nil}, + { :content_type=>"text/plain", + :url_part_number=>2, + :within_rfc822_subject=>"Re: xxx", + :filename=>nil}, + { :content_type=>"text/html", + :url_part_number=>4, + :within_rfc822_subject=>"example", + :filename=>nil}, + { :content_type=>"image/gif", :url_part_number=>5, + :within_rfc822_subject=>"example", + :filename=>"image001.gif"}, + { :content_type=>"application/vnd.ms-excel", + :url_part_number=>6, + :within_rfc822_subject=>"example", + :filename=>"particpant list.xls"}, + { :content_type=>"text/plain", + :url_part_number=>7, + :within_rfc822_subject=>"RE: example", + :filename=>nil}, + { :content_type=>"text/html", + :url_part_number=>9, + :within_rfc822_subject=>"As promised - Masterclass info (example)", + :filename=>nil}, + { :content_type=>"image/gif", + :url_part_number=>10, + :within_rfc822_subject=>"As promised - Masterclass info (example)", + :filename=>"image001.gif"}, + { :content_type=>"application/vnd.ms-word", + :url_part_number=>11, + :within_rfc822_subject=>"As promised - Masterclass info (example)", + :filename=>"Participant List.doc"}, + { :content_type=>"application/vnd.ms-word", + :url_part_number=>12, + :within_rfc822_subject=>"As promised - Masterclass info (example)", + :filename=>"Information & Booking Form.doc"}, + { :content_type=>"text/plain", + :url_part_number=>13, + :within_rfc822_subject=>"Re: As promised - info (example)", + :filename=>nil}, + { :content_type=>"text/html", + :url_part_number=>15, + :within_rfc822_subject=>"Thank you from example", + :filename=>nil}, + { :content_type=>"image/gif", + :url_part_number=>16, + :within_rfc822_subject=>"Thank you from example", + :filename=>"image001.gif"}, + { :content_type=>"text/plain", + :url_part_number=>17, + :within_rfc822_subject=>"example - Meeting - Tuesday 2nd March", + :filename=>nil}, + { :content_type=>"text/plain", + :url_part_number=>18, + :within_rfc822_subject=>"example - Help needed", + :filename=>nil}, + { :content_type=>"application/pdf", + :url_part_number=>19, + :within_rfc822_subject=>"example - Help needed", + :filename=>"Information Pack.pdf"}, + { :content_type=>"text/plain", + :url_part_number=>20, + :within_rfc822_subject=>"Re: As promised - info (example)", + :filename=>nil} ] + + attributes.each_with_index do |attr, index| + attr.delete(:charset) + attr.delete(:body) + attr.delete(:hexdigest) + attr.should == expected_attributes[index] + end + end end diff --git a/spec/models/incoming_message_spec.rb b/spec/models/incoming_message_spec.rb index fdbcd1e23..70b323e9f 100644 --- a/spec/models/incoming_message_spec.rb +++ b/spec/models/incoming_message_spec.rb @@ -26,11 +26,6 @@ describe IncomingMessage, " when dealing with incoming mail" do @im.sent_at.should == @im.mail.date end - it "should be able to parse emails with quoted commas in" do - em = "\"Clare College, Cambridge\" <test@test.test>" - TMail::Address.parse(em) - end - it "should correctly fold various types of footer" do Dir.glob(File.join(Spec::Runner.configuration.fixture_path, "files", "email-folding-example-*.txt")).each do |file| message = File.read(file) @@ -73,6 +68,14 @@ describe IncomingMessage, " when dealing with incoming mail" do message.get_main_body_text_internal.should include("The above text was badly encoded") end + it 'should convert DOS-style linebreaks to Unix style' do + ir = info_requests(:fancy_dog_request) + receive_incoming_mail('dos-linebreaks.email', ir.incoming_email) + message = ir.incoming_messages[1] + message.parse_raw_email! + message.get_main_body_text_internal.should_not match(/\r\n/) + end + it "should fold multiline sections" do { "foo\n--------\nconfidential" => "foo\nFOLDED_QUOTED_SECTION\n", # basic test @@ -107,27 +110,6 @@ describe IncomingMessage, " when dealing with incoming mail" do end -describe IncomingMessage, "when parsing HTML mail" do - it "should display UTF-8 characters in the plain text version correctly" do - html = "<html><b>foo</b> është" - plain_text = IncomingMessage._get_attachment_text_internal_one_file('text/html', html) - plain_text.should match(/është/) - end - -end - -describe IncomingMessage, "when getting the attachment text" do - - it "should not raise an error if the expansion of a zip file raises an error" do - mock_entry = mock('ZipFile entry', :file? => true) - mock_entry.stub!(:get_input_stream).and_raise("invalid distance too far back") - Zip::ZipFile.stub!(:open).and_return([mock_entry]) - IncomingMessage._get_attachment_text_internal_one_file('application/zip', "some string") - end - -end - - describe IncomingMessage, " display attachments" do it "should not show slashes in filenames" do @@ -143,7 +125,7 @@ describe IncomingMessage, " display attachments" do # http://www.whatdotheyknow.com/request/post_commercial_manager_librarie#incoming-17233 foi_attachment.within_rfc822_subject = "FOI/09/066 RESPONSE TO FOI REQUEST RECEIVED 21st JANUARY 2009" foi_attachment.content_type = 'text/plain' - foi_attachment.ensure_filename! + foi_attachment.ensure_filename! expected_display_filename = foi_attachment.within_rfc822_subject.gsub(/\//, " ") + ".txt" foi_attachment.display_filename.should == expected_display_filename end @@ -194,59 +176,50 @@ describe IncomingMessage, " folding quoted parts of emails" do end describe IncomingMessage, " checking validity to reply to" do - def test_email(result, email, return_path, autosubmitted = nil) - @address = mock(TMail::Address) - @address.stub!(:spec).and_return(email) - - @return_path = mock(TMail::ReturnPathHeader) - @return_path.stub!(:addr).and_return(return_path) - if !autosubmitted.nil? - @autosubmitted = TMail::UnstructuredHeader.new("auto-submitted", autosubmitted) - end - @mail = mock(TMail::Mail) - @mail.stub!(:from_addrs).and_return( [ @address ] ) - @mail.stub!(:[]).with("return-path").and_return(@return_path) - @mail.stub!(:[]).with("auto-submitted").and_return(@autosubmitted) - + def test_email(result, email, empty_return_path, autosubmitted = nil) + @mail = mock('mail') + MailHandler.stub!(:get_from_address).and_return(email) + MailHandler.stub!(:empty_return_path?).with(@mail).and_return(empty_return_path) + MailHandler.stub!(:get_auto_submitted).with(@mail).and_return(autosubmitted) @incoming_message = IncomingMessage.new() @incoming_message.stub!(:mail).and_return(@mail) @incoming_message._calculate_valid_to_reply_to.should == result end it "says a valid email is fine" do - test_email(true, "team@mysociety.org", nil) + test_email(true, "team@mysociety.org", false) end it "says postmaster email is bad" do - test_email(false, "postmaster@mysociety.org", nil) + test_email(false, "postmaster@mysociety.org", false) end it "says Mailer-Daemon email is bad" do - test_email(false, "Mailer-Daemon@mysociety.org", nil) + test_email(false, "Mailer-Daemon@mysociety.org", false) end it "says case mangled MaIler-DaemOn email is bad" do - test_email(false, "MaIler-DaemOn@mysociety.org", nil) + test_email(false, "MaIler-DaemOn@mysociety.org", false) end it "says Auto_Reply email is bad" do - test_email(false, "Auto_Reply@mysociety.org", nil) + test_email(false, "Auto_Reply@mysociety.org", false) end it "says DoNotReply email is bad" do - test_email(false, "DoNotReply@tube.tfl.gov.uk", nil) + test_email(false, "DoNotReply@tube.tfl.gov.uk", false) end it "says a filled-out return-path is fine" do - test_email(true, "team@mysociety.org", "Return-path: <foo@baz.com>") + test_email(true, "team@mysociety.org", false) end it "says an empty return-path is bad" do - test_email(false, "team@mysociety.org", "<>") + test_email(false, "team@mysociety.org", true) end it "says an auto-submitted keyword is bad" do - test_email(false, "team@mysociety.org", nil, "auto-replied") + test_email(false, "team@mysociety.org", false, "auto-replied") end end @@ -340,12 +313,12 @@ describe IncomingMessage, " when censoring data" do orig_pdf = load_file_fixture('tfl.pdf') pdf = orig_pdf.dup - orig_text = IncomingMessage._get_attachment_text_internal_one_file('application/pdf', pdf) + orig_text = MailHandler.get_attachment_text_one_file('application/pdf', pdf) orig_text.should match(/foi@tfl.gov.uk/) @im.binary_mask_stuff!(pdf, "application/pdf") - masked_text = IncomingMessage._get_attachment_text_internal_one_file('application/pdf', pdf) + masked_text = MailHandler.get_attachment_text_one_file('application/pdf', pdf) masked_text.should_not match(/foi@tfl.gov.uk/) masked_text.should match(/xxx@xxx.xxx.xx/) config['USE_GHOSTSCRIPT_COMPRESSION'] = previous @@ -455,6 +428,24 @@ end describe IncomingMessage, "when messages are attached to messages" do + it 'should expand an RFC822 attachment' do + mail_body = load_file_fixture('rfc822-attachment.email') + mail = MailHandler.mail_from_raw_email(mail_body) + + im = incoming_messages(:useless_incoming_message) + im.stub!(:mail).and_return(mail) + + attachments = im.get_attachments_for_display + attachments.size.should == 1 + attachment = attachments.first + + attachment.content_type.should == 'text/plain' + attachment.filename.should == "Freedom of Information request.txt" + attachment.charset.should == "utf-8" + attachment.within_rfc822_subject.should == "Freedom of Information request" + attachment.hexdigest.should == 'f10fe56e4f2287685a58b71329f09639' + end + it "should flatten all the attachments out" do mail = get_fixture_mail('incoming-request-attach-attachments.email') @@ -470,6 +461,19 @@ describe IncomingMessage, "when messages are attached to messages" do 'hello.txt', ] end + + it 'should add headers to attached plain text message bodies' do + mail_body = load_file_fixture('incoming-request-attachment-headers.email') + mail = MailHandler.mail_from_raw_email(mail_body) + + im = incoming_messages(:useless_incoming_message) + im.stub!(:mail).and_return(mail) + + attachments = im.get_attachments_for_display + attachments.size.should == 2 + attachments[0].body.should match('Date: Fri, 23 May 2008') + end + end describe IncomingMessage, "when Outlook messages are attached to messages" do diff --git a/spec/models/info_request_spec.rb b/spec/models/info_request_spec.rb index 2aeac2fec..544852f91 100644 --- a/spec/models/info_request_spec.rb +++ b/spec/models/info_request_spec.rb @@ -2,6 +2,22 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe InfoRequest do + describe 'when generating a user name slug' do + + before do + @public_body = mock_model(PublicBody, :url_name => 'example_body', + :eir_only? => false) + @info_request = InfoRequest.new(:external_url => 'http://www.example.com', + :external_user_name => 'Example User', + :public_body => @public_body) + end + + it 'should generate a slug for an example user name' do + @info_request.user_name_slug.should == 'example_body_example_user' + end + + end + describe "guessing a request from an email" do before(:each) do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d4dad591d..9621211f5 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -93,9 +93,14 @@ def file_fixture_name(file_name) return File.join(Spec::Runner.configuration.fixture_path, "files", file_name) end -def load_file_fixture(file_name) +def load_file_fixture(file_name, as_binary=false) file_name = file_fixture_name(file_name) - content = File.read(file_name) + content = File.open(file_name, 'r') do |file| + if as_binary + file.set_encoding(Encoding::BINARY) if file.respond_to?(:set_encoding) + end + file.read + end return content end |