aboutsummaryrefslogtreecommitdiffstats
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/api_controller_spec.rb134
-rw-r--r--spec/controllers/application_controller_spec.rb9
-rw-r--r--spec/controllers/general_controller_spec.rb56
-rw-r--r--spec/controllers/public_body_controller_spec.rb18
-rw-r--r--spec/controllers/request_controller_spec.rb30
-rw-r--r--spec/controllers/track_controller_spec.rb14
-rw-r--r--spec/controllers/user_controller_spec.rb70
-rw-r--r--spec/fixtures/files/dos-linebreaks.email31
-rw-r--r--spec/fixtures/files/humberside-police-odd-mime-type.email25
-rw-r--r--spec/fixtures/files/incoming-request-attachment-headers.email50
-rw-r--r--spec/fixtures/files/incoming-request-attachment-unknown-extension.email5
-rw-r--r--spec/fixtures/files/many-attachments-date-header.email451
-rw-r--r--spec/fixtures/files/rfc822-attachment.email147
-rw-r--r--spec/helpers/link_to_helper_spec.rb12
-rw-r--r--spec/integration/create_request_spec.rb35
-rw-r--r--spec/integration/search_request_spec.rb2
-rw-r--r--spec/lib/i18n_interpolation.rb3
-rw-r--r--spec/lib/mail_handler/mail_handler_spec.rb387
-rw-r--r--spec/lib/timezone_fixes_spec.rb16
-rw-r--r--spec/lib/tmail_extensions_spec.rb45
-rw-r--r--spec/models/application_mailer_spec.rb6
-rw-r--r--spec/models/incoming_message_spec.rb158
-rw-r--r--spec/models/info_request_event_spec.rb47
-rw-r--r--spec/models/info_request_spec.rb16
-rw-r--r--spec/models/request_mailer_spec.rb2
-rw-r--r--spec/models/track_mailer_spec.rb2
-rw-r--r--spec/models/xapian_spec.rb22
-rw-r--r--spec/script/handle-mail-replies_spec.rb10
-rw-r--r--spec/spec_helper.rb94
29 files changed, 1563 insertions, 334 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/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index 08e68d85e..18341ae6f 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -39,7 +39,14 @@ describe ApplicationController, "when caching fragments" do
it "should not fail with long filenames" do
long_name = "blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah.txt"
- path = self.controller.send(:foi_fragment_cache_path, long_name)
+ params = { :only_path => true,
+ :file_name => [long_name],
+ :controller => "request",
+ :action => "get_attachment_as_html",
+ :id => "132",
+ :incoming_message_id => "44",
+ :part => "2" }
+ path = self.controller.send(:foi_fragment_cache_path, params)
self.controller.send(:foi_fragment_cache_write, path, "whassap")
end
diff --git a/spec/controllers/general_controller_spec.rb b/spec/controllers/general_controller_spec.rb
index 935f8eab6..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
@@ -144,7 +194,7 @@ describe GeneralController, "when showing the front page with fixture data" do
describe 'when constructing the list of recent requests' do
before(:each) do
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
describe 'when there are fewer than five successful requests' do
@@ -189,8 +239,8 @@ describe GeneralController, 'when using xapian search' do
# rebuild xapian index after fixtures loaded
before(:each) do
- load_raw_emails_data
- rebuild_xapian_index
+ load_raw_emails_data
+ get_fixtures_xapian_index
end
it "should redirect from search query URL to pretty URL" do
diff --git a/spec/controllers/public_body_controller_spec.rb b/spec/controllers/public_body_controller_spec.rb
index d12818a1c..29ece18cb 100644
--- a/spec/controllers/public_body_controller_spec.rb
+++ b/spec/controllers/public_body_controller_spec.rb
@@ -6,7 +6,7 @@ describe PublicBodyController, "when showing a body" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
it "should be successful" do
@@ -29,14 +29,14 @@ describe PublicBodyController, "when showing a body" do
assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ InfoRequest.all(
:conditions => ["public_body_id = ?", public_bodies(:geraldine_public_body).id])
end
-
+
it "should assign the requests (2)" do
get :show, :url_name => "tgq", :view => 'successful'
assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ InfoRequest.all(
:conditions => ["described_state = ? and public_body_id = ?",
"successful", public_bodies(:geraldine_public_body).id])
end
-
+
it "should assign the requests (3)" do
get :show, :url_name => "dfh", :view => 'all'
assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ InfoRequest.all(
@@ -66,7 +66,7 @@ describe PublicBodyController, "when showing a body" do
ActionController::Routing::Routes.filters = old_filters
end
-
+
it "should redirect to newest name if you use historic name of public body in URL" do
get :show, :url_name => "hdink", :view => 'all'
response.should redirect_to(:controller => 'public_body', :action => 'show', :url_name => "dfh")
@@ -148,7 +148,7 @@ describe PublicBodyController, "when listing bodies" do
get :list, :tag => "other"
response.should render_template('list')
assigns[:public_bodies].should =~ PublicBody.all(:conditions => "id not in (#{public_bodies(:humpadink_public_body).id}, #{PublicBody.internal_admin_body.id})")
-
+
get :list
response.should render_template('list')
assigns[:public_bodies].should =~ PublicBody.all(:conditions => "id <> #{PublicBody.internal_admin_body.id}")
@@ -194,10 +194,10 @@ end
describe PublicBodyController, "when doing type ahead searches" do
integrate_views
-
+
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
it "should return nothing for the empty query string" do
@@ -205,7 +205,7 @@ describe PublicBodyController, "when doing type ahead searches" do
response.should render_template('public_body/_search_ahead')
assigns[:xapian_requests].should be_nil
end
-
+
it "should return a body matching the given keyword, but not users with a matching description" do
get :search_typeahead, :query => "Geraldine"
response.should render_template('public_body/_search_ahead')
@@ -230,7 +230,7 @@ describe PublicBodyController, "when doing type ahead searches" do
end
it "should not return matches for short words" do
- get :search_typeahead, :query => "b"
+ get :search_typeahead, :query => "b"
response.should render_template('public_body/_search_ahead')
assigns[:xapian_requests].should be_nil
end
diff --git a/spec/controllers/request_controller_spec.rb b/spec/controllers/request_controller_spec.rb
index 625bf17e7..521ad7b5a 100644
--- a/spec/controllers/request_controller_spec.rb
+++ b/spec/controllers/request_controller_spec.rb
@@ -5,7 +5,7 @@ describe RequestController, "when listing recent requests" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
it "should be successful" do
@@ -767,7 +767,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
@@ -859,14 +859,36 @@ describe RequestController, "when changing prominence of a request" do
ir.save!
receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email)
- get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :skip_cache => 1
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id,
+ :id => ir.id,
+ :part => 2,
+ :skip_cache => 1
response.content_type.should == "text/html"
response.should_not have_text(/Second hello/)
response.should render_template('request/hidden')
- get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 3, :skip_cache => 1
+ get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id,
+ :id => ir.id,
+ :part => 3,
+ :skip_cache => 1
response.content_type.should == "text/html"
response.should_not have_text(/First hello/)
response.should render_template('request/hidden')
+ response.code.should == '410'
+ end
+
+ it 'should not generate an HTML version of an attachment whose prominence is hidden/requester
+ only even for the requester or an admin but should return a 404' do
+ ir = info_requests(:fancy_dog_request)
+ ir.prominence = 'hidden'
+ ir.save!
+ receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email)
+ session[:user_id] = users(:admin_user).id
+ lambda do
+ get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id,
+ :id => ir.id,
+ :part => 2,
+ :file_name => ['hello.txt']
+ end.should raise_error(ActiveRecord::RecordNotFound)
end
it 'should not generate an HTML version of an attachment whose prominence is hidden/requester
diff --git a/spec/controllers/track_controller_spec.rb b/spec/controllers/track_controller_spec.rb
index 7daa23769..c785960b5 100644
--- a/spec/controllers/track_controller_spec.rb
+++ b/spec/controllers/track_controller_spec.rb
@@ -38,7 +38,7 @@ describe TrackController, "when making a new track on a request" do
get :track_request, :url_title => @ir.url_title, :feed => 'track'
response.should redirect_to(:controller => 'request', :action => 'show', :url_title => @ir.url_title)
end
-
+
it "should 404 for non-existent requests" do
session[:user_id] = @user.id
lambda {
@@ -61,9 +61,9 @@ describe TrackController, "when sending alerts for a track" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
-
+
it "should send alerts" do
# Don't do clever locale-insertion-unto-URL stuff
old_filters = ActionController::Routing::Routes.filters
@@ -138,7 +138,7 @@ describe TrackController, "when viewing RSS feed for a track" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
it "should get the RSS feed" do
@@ -168,7 +168,7 @@ describe TrackController, "when viewing JSON version of a track feed" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
it "should get the feed" do
@@ -210,9 +210,9 @@ describe TrackController, "when tracking a public body" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
-
+
it "should work" do
geraldine = public_bodies(:geraldine_public_body)
get :track_public_body, :feed => 'feed', :url_name => geraldine.url_name
diff --git a/spec/controllers/user_controller_spec.rb b/spec/controllers/user_controller_spec.rb
index 386d1b04b..23006803b 100644
--- a/spec/controllers/user_controller_spec.rb
+++ b/spec/controllers/user_controller_spec.rb
@@ -8,9 +8,9 @@ describe UserController, "when showing a user" do
integrate_views
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
-
+
it "should be successful" do
get :show, :url_name => "bob_smith"
response.should be_success
@@ -45,7 +45,7 @@ describe UserController, "when showing a user" do
get :show, :url_name => "bob_smith"
assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ InfoRequest.all(
:conditions => "user_id = #{users(:bob_smith_user).id}")
-
+
get :show, :url_name => "bob_smith", :user_query => "money"
assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ [
info_requests(:naughty_chicken_request),
@@ -218,7 +218,7 @@ describe UserController, "when signing in" do
# Get the confirmation URL, and check we’re still Joe
get :confirm, :email_token => post_redirect.email_token
session[:user_id].should == users(:admin_user).id
-
+
# And the redirect should still work, of course
response.should redirect_to(:controller => 'request', :action => 'list', :post_redirect => 1)
@@ -232,21 +232,21 @@ describe UserController, "when signing up" do
it "should be an error if you type the password differently each time" do
post :signup, { :user_signup => { :email => 'new@localhost', :name => 'New Person',
- :password => 'sillypassword', :password_confirmation => 'sillypasswordtwo' }
+ :password => 'sillypassword', :password_confirmation => 'sillypasswordtwo' }
}
assigns[:user_signup].errors[:password].should == 'Please enter the same password twice'
end
it "should be an error to sign up with a misformatted email" do
post :signup, { :user_signup => { :email => 'malformed-email', :name => 'Mr Malformed',
- :password => 'sillypassword', :password_confirmation => 'sillypassword' }
+ :password => 'sillypassword', :password_confirmation => 'sillypassword' }
}
assigns[:user_signup].errors[:email].should_not be_nil
end
it "should send confirmation mail if you fill in the form right" do
post :signup, { :user_signup => { :email => 'new@localhost', :name => 'New Person',
- :password => 'sillypassword', :password_confirmation => 'sillypassword' }
+ :password => 'sillypassword', :password_confirmation => 'sillypassword' }
}
response.should render_template('confirm')
@@ -270,13 +270,13 @@ describe UserController, "when signing up" do
it "should send special 'already signed up' mail if you fill the form in with existing registered email" do
post :signup, { :user_signup => { :email => 'silly@localhost', :name => 'New Person',
- :password => 'sillypassword', :password_confirmation => 'sillypassword' }
+ :password => 'sillypassword', :password_confirmation => 'sillypassword' }
}
response.should render_template('confirm')
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
-
+
# This text may span a line break, depending on the length of the SITE_NAME
deliveries[0].body.should match(/when\s+you\s+already\s+have\s+an/)
end
@@ -377,7 +377,7 @@ describe UserController, "when changing password" do
get :signchangepassword
response.should render_template('signchangepassword')
end
-
+
it "should change the password, if you have right to do so" do
session[:user_id] = users(:bob_smith_user).id
session[:user_circumstance] = "change_password"
@@ -437,8 +437,8 @@ describe UserController, "when changing email address" do
it "should be an error if the password is wrong, everything else right" do
@user = users(:bob_smith_user)
session[:user_id] = @user.id
-
- post :signchangeemail, { :signchangeemail => { :old_email => 'bob@localhost',
+
+ post :signchangeemail, { :signchangeemail => { :old_email => 'bob@localhost',
:password => 'donotknowpassword', :new_email => 'newbob@localhost' },
:submitted_signchangeemail_do => 1
}
@@ -455,8 +455,8 @@ describe UserController, "when changing email address" do
it "should be an error if old email is wrong, everything else right" do
@user = users(:bob_smith_user)
session[:user_id] = @user.id
-
- post :signchangeemail, { :signchangeemail => { :old_email => 'bob@moo',
+
+ post :signchangeemail, { :signchangeemail => { :old_email => 'bob@moo',
:password => 'jonespassword', :new_email => 'newbob@localhost' },
:submitted_signchangeemail_do => 1
}
@@ -473,8 +473,8 @@ describe UserController, "when changing email address" do
it "should work even if the old email had a case difference" do
@user = users(:bob_smith_user)
session[:user_id] = @user.id
-
- post :signchangeemail, { :signchangeemail => { :old_email => 'BOB@localhost',
+
+ post :signchangeemail, { :signchangeemail => { :old_email => 'BOB@localhost',
:password => 'jonespassword', :new_email => 'newbob@localhost' },
:submitted_signchangeemail_do => 1
}
@@ -485,8 +485,8 @@ describe UserController, "when changing email address" do
it "should send confirmation email if you get all the details right" do
@user = users(:bob_smith_user)
session[:user_id] = @user.id
-
- post :signchangeemail, { :signchangeemail => { :old_email => 'bob@localhost',
+
+ post :signchangeemail, { :signchangeemail => { :old_email => 'bob@localhost',
:password => 'jonespassword', :new_email => 'newbob@localhost' },
:submitted_signchangeemail_do => 1
}
@@ -521,16 +521,16 @@ describe UserController, "when changing email address" do
post_redirect = PostRedirect.find_by_email_token(mail_token)
post_redirect.circumstance.should == 'change_email'
post_redirect.user.should == users(:bob_smith_user)
- post_redirect.post_params.should == {"submitted_signchangeemail_do"=>"1",
- "action"=>"signchangeemail",
+ post_redirect.post_params.should == {"submitted_signchangeemail_do"=>"1",
+ "action"=>"signchangeemail",
"signchangeemail"=>{
- "old_email"=>"bob@localhost",
- "new_email"=>"newbob@localhost"},
+ "old_email"=>"bob@localhost",
+ "new_email"=>"newbob@localhost"},
"controller"=>"user"}
post :signchangeemail, post_redirect.post_params
response.should redirect_to(:controller => 'user', :action => 'show', :url_name => 'bob_smith')
- flash[:notice].should match(/You have now changed your email address/)
+ flash[:notice].should match(/You have now changed your email address/)
@user.reload
@user.email.should == 'newbob@localhost'
@user.email_confirmed.should == true
@@ -539,8 +539,8 @@ describe UserController, "when changing email address" do
it "should send special 'already signed up' mail if you try to change your email to one already used" do
@user = users(:bob_smith_user)
session[:user_id] = @user.id
-
- post :signchangeemail, { :signchangeemail => { :old_email => 'bob@localhost',
+
+ post :signchangeemail, { :signchangeemail => { :old_email => 'bob@localhost',
:password => 'jonespassword', :new_email => 'silly@localhost' },
:submitted_signchangeemail_do => 1
}
@@ -572,9 +572,9 @@ describe UserController, "when using profile photos" do
@uploadedfile_2 = File.open(file_fixture_name("parrot.jpg"))
@uploadedfile_2.stub!(:original_filename).and_return('parrot.jpg')
end
-
+
it "should not let you change profile photo if you're not logged in as the user" do
- post :set_profile_photo, { :id => @user.id, :file => @uploadedfile, :submitted_draft_profile_photo => 1, :automatically_crop => 1 }
+ post :set_profile_photo, { :id => @user.id, :file => @uploadedfile, :submitted_draft_profile_photo => 1, :automatically_crop => 1 }
end
it "should return a 404 not a 500 when a profile photo has not been set" do
@@ -588,10 +588,10 @@ describe UserController, "when using profile photos" do
@user.profile_photo.should be_nil
session[:user_id] = @user.id
- post :set_profile_photo, { :id => @user.id, :file => @uploadedfile, :submitted_draft_profile_photo => 1, :automatically_crop => 1 }
+ post :set_profile_photo, { :id => @user.id, :file => @uploadedfile, :submitted_draft_profile_photo => 1, :automatically_crop => 1 }
response.should redirect_to(:controller => 'user', :action => 'show', :url_name => "bob_smith")
- flash[:notice].should match(/Thank you for updating your profile photo/)
+ flash[:notice].should match(/Thank you for updating your profile photo/)
@user.reload
@user.profile_photo.should_not be_nil
@@ -601,13 +601,13 @@ describe UserController, "when using profile photos" do
@user.profile_photo.should be_nil
session[:user_id] = @user.id
- post :set_profile_photo, { :id => @user.id, :file => @uploadedfile, :submitted_draft_profile_photo => 1, :automatically_crop => 1 }
+ post :set_profile_photo, { :id => @user.id, :file => @uploadedfile, :submitted_draft_profile_photo => 1, :automatically_crop => 1 }
response.should redirect_to(:controller => 'user', :action => 'show', :url_name => "bob_smith")
- flash[:notice].should match(/Thank you for updating your profile photo/)
+ flash[:notice].should match(/Thank you for updating your profile photo/)
- post :set_profile_photo, { :id => @user.id, :file => @uploadedfile_2, :submitted_draft_profile_photo => 1, :automatically_crop => 1 }
+ post :set_profile_photo, { :id => @user.id, :file => @uploadedfile_2, :submitted_draft_profile_photo => 1, :automatically_crop => 1 }
response.should redirect_to(:controller => 'user', :action => 'show', :url_name => "bob_smith")
- flash[:notice].should match(/Thank you for updating your profile photo/)
+ flash[:notice].should match(/Thank you for updating your profile photo/)
@user.reload
@user.profile_photo.should_not be_nil
@@ -617,7 +617,7 @@ describe UserController, "when using profile photos" do
end
describe UserController, "when showing JSON version for API" do
-
+
it "should be successful" do
get :show, :url_name => "bob_smith", :format => "json"
@@ -634,7 +634,7 @@ describe UserController, "when viewing the wall" do
integrate_views
before(:each) do
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
it "should show users stuff on their wall, most recent first" do
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>
+ &lt;&lt;Freedom of Information request &gt;&gt; <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/helpers/link_to_helper_spec.rb b/spec/helpers/link_to_helper_spec.rb
index ef89e8bf9..030fd612d 100644
--- a/spec/helpers/link_to_helper_spec.rb
+++ b/spec/helpers/link_to_helper_spec.rb
@@ -73,4 +73,16 @@ describe LinkToHelper do
end
end
end
+
+ describe 'simple_date' do
+ it 'should respect time zones' do
+ Time.use_zone('Australia/Sydney') do
+ simple_date(Time.utc(2012, 11, 07, 21, 30, 26)).should == 'November 08, 2012'
+ end
+ end
+
+ it 'should handle Date objects' do
+ simple_date(Date.new(2012, 11, 21)).should == 'November 21, 2012'
+ end
+ end
end
diff --git a/spec/integration/create_request_spec.rb b/spec/integration/create_request_spec.rb
index 56757c7e0..4efbf94ee 100644
--- a/spec/integration/create_request_spec.rb
+++ b/spec/integration/create_request_spec.rb
@@ -1,23 +1,30 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe "When creating requests" do
- it "should associate the request with the requestor, even if it is approved by an admin" do
- # This is a test for https://github.com/mysociety/alaveteli/issues/446
- params = { :info_request => { :public_body_id => public_bodies(:geraldine_public_body).id,
- :title => "Why is your quango called Geraldine?", :tag_string => "" },
- :outgoing_message => { :body => "This is a silly letter. It is too short to be interesting." },
- :submitted_new_request => 1, :preview => 0
- }
+ def create_request_unregistered
+ params = { :info_request => { :public_body_id => public_bodies(:geraldine_public_body).id,
+ :title => "Why is your quango called Geraldine?",
+ :tag_string => "" },
+ :outgoing_message => { :body => "This is a silly letter. It is too short to be interesting." },
+ :submitted_new_request => 1,
+ :preview => 0
+ }
- # Initially we are not logged in. Try to create a new request.
- post "/new", params
- # We expect to be redirected to the login page
- post_redirect = PostRedirect.get_last_post_redirect
- response.should redirect_to(:controller => 'user', :action => 'signin', :token => post_redirect.token)
- follow_redirect!
- response.should render_template("user/sign")
+ # Initially we are not logged in. Try to create a new request.
+ post "/new", params
+ # We expect to be redirected to the login page
+ post_redirect = PostRedirect.get_last_post_redirect
+ response.should redirect_to(:controller => 'user', :action => 'signin', :token => post_redirect.token)
+ follow_redirect!
+ response.should render_template("user/sign")
+ response.body.should match(/To send your FOI request, please sign in or make a new account./)
+ end
+ it "should associate the request with the requestor, even if it is approved by an admin" do
+ # This is a test for https://github.com/mysociety/alaveteli/issues/446
+ create_request_unregistered
+ post_redirect = PostRedirect.get_last_post_redirect
# Now log in as an unconfirmed user.
post "/profile/sign_in", :user_signin => {:email => users(:unconfirmed_user).email, :password => "jonespassword"}, :token => post_redirect.token
# This will trigger a confirmation mail. Get the PostRedirect for later.
diff --git a/spec/integration/search_request_spec.rb b/spec/integration/search_request_spec.rb
index 17a7b4aaa..c564032a6 100644
--- a/spec/integration/search_request_spec.rb
+++ b/spec/integration/search_request_spec.rb
@@ -4,7 +4,7 @@ describe "When searching" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
it "should not strip quotes from quoted query" do
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
new file mode 100644
index 000000000..48c32e2bc
--- /dev/null
+++ b/spec/lib/mail_handler/mail_handler_spec.rb
@@ -0,0 +1,387 @@
+# 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
+ mail = get_fixture_mail('space-boundary.email')
+ mail.parts.size.should == 2
+ mail.multipart?.should == true
+ end
+
+ it 'should parse multiple to addresses with unqoted display names' do
+ mail = get_fixture_mail('multiple-unquoted-display-names.email')
+ mail.to.should == ["request-66666-caa77777@whatdotheyknow.com", "foi@example.com"]
+ end
+
+ 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)
+ 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
+ # Note that this spec will only pass using Tmail in the timezone set as datetime headers
+ # are rendered out in the local time - using the Mail gem this is not necessary
+ with_env_tz('London') 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
+ 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/lib/timezone_fixes_spec.rb b/spec/lib/timezone_fixes_spec.rb
index a2bea5f64..525bd7561 100644
--- a/spec/lib/timezone_fixes_spec.rb
+++ b/spec/lib/timezone_fixes_spec.rb
@@ -92,22 +92,6 @@ describe "when doing things with timezones" do
end
end
-
- protected
-
- def with_env_tz(new_tz = 'US/Eastern')
- old_tz, ENV['TZ'] = ENV['TZ'], new_tz
- yield
- ensure
- old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
- end
-
- def with_active_record_default_timezone(zone)
- old_zone, ActiveRecord::Base.default_timezone = ActiveRecord::Base.default_timezone, zone
- yield
- ensure
- ActiveRecord::Base.default_timezone = old_zone
- end
end
diff --git a/spec/lib/tmail_extensions_spec.rb b/spec/lib/tmail_extensions_spec.rb
deleted file mode 100644
index bd89e6a84..000000000
--- a/spec/lib/tmail_extensions_spec.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# coding: utf-8
-# 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 TMail" do
-
- before(:each) do
- ActionMailer::Base.deliveries.clear
- end
-
- it "should load an email with funny MIME settings" do
- # just send it to the holding pen
- InfoRequest.holding_pen_request.incoming_messages.size.should == 0
- receive_incoming_mail("humberside-police-odd-mime-type.email", 'dummy')
- InfoRequest.holding_pen_request.incoming_messages.size.should == 1
-
- # clear the notification of new message in holding pen
- deliveries = ActionMailer::Base.deliveries
- deliveries.size.should == 1
- deliveries.clear
-
- incoming_message = InfoRequest.holding_pen_request.incoming_messages[0]
-
- # This will raise an error if the bug in TMail hasn't been fixed
- incoming_message.get_body_for_html_display()
- end
-
- it 'should parse multiple to addresses with unqoted display names' do
- mail = TMail::Mail.parse(load_file_fixture('multiple-unquoted-display-names.email'))
- mail.to.should == ["request-66666-caa77777@whatdotheyknow.com", "foi@example.com"]
- end
-
- it 'should convert to utf8' do
- # NB this isn't actually a TMail extension, but is core TMail;
- # this was just a convenient place to assert the UTF8
- # conversion is working
- mail = TMail::Mail.parse(load_file_fixture('iso8859_2_raw_email.email'))
- mail.subject.should have_text(/gjatë/u)
- mail.body.is_utf8?.should == true
- end
-
-end
-
diff --git a/spec/models/application_mailer_spec.rb b/spec/models/application_mailer_spec.rb
index a90f79c01..acf5f43bc 100644
--- a/spec/models/application_mailer_spec.rb
+++ b/spec/models/application_mailer_spec.rb
@@ -80,7 +80,8 @@ describe ApplicationMailer do
it 'should raise an error if the template is in neither core nor theme' do
prepend_theme_views('theme_one')
- lambda{ ApplicationMailer.create_neither() }.should raise_error('Missing template application_mailer/neither.erb in view path spec/fixtures/theme_views/theme_one:spec/fixtures/theme_views/core')
+ expected_error = 'Missing template application_mailer/neither.erb in view path'
+ lambda{ ApplicationMailer.create_neither() }.should raise_error(/#{expected_error}/)
end
it 'should render a multipart email using a theme template' do
@@ -125,7 +126,8 @@ describe ApplicationMailer do
it 'should raise an error if the template is in neither core nor theme' do
append_theme_views('theme_one')
- lambda{ ApplicationMailer.create_neither() }.should raise_error('Missing template application_mailer/neither.erb in view path spec/fixtures/theme_views/core:spec/fixtures/theme_views/theme_one')
+ expected_error = 'Missing template application_mailer/neither.erb in view path'
+ lambda{ ApplicationMailer.create_neither() }.should raise_error(/#{expected_error}/)
end
it 'should render a multipart email using a core template' do
diff --git a/spec/models/incoming_message_spec.rb b/spec/models/incoming_message_spec.rb
index b038c43d9..6fc0ff3cc 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
@@ -85,28 +88,27 @@ describe IncomingMessage, " when dealing with incoming mail" do
end
end
-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
+ it "should load an email with funny MIME settings" do
+ ActionMailer::Base.deliveries.clear
+ # just send it to the holding pen
+ InfoRequest.holding_pen_request.incoming_messages.size.should == 0
+ receive_incoming_mail("humberside-police-odd-mime-type.email", 'dummy')
+ InfoRequest.holding_pen_request.incoming_messages.size.should == 1
-end
+ # clear the notification of new message in holding pen
+ deliveries = ActionMailer::Base.deliveries
+ deliveries.size.should == 1
+ deliveries.clear
-describe IncomingMessage, "when getting the attachment text" do
+ incoming_message = InfoRequest.holding_pen_request.incoming_messages[0]
- 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
+ # This will raise an error if the bug in TMail hasn't been fixed
+ incoming_message.get_body_for_html_display()
+ end
-end
+end
describe IncomingMessage, " display attachments" do
@@ -123,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
@@ -174,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
@@ -320,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
@@ -399,14 +392,8 @@ end
describe IncomingMessage, " when uudecoding bad messages" do
- before(:each) do
- load_raw_emails_data
- end
-
it "should be able to do it at all" do
- mail_body = load_file_fixture('incoming-request-bad-uuencoding.email')
- mail = TMail::Mail.parse(mail_body)
- mail.base64_decode
+ mail = get_fixture_mail('incoming-request-bad-uuencoding.email')
im = incoming_messages(:useless_incoming_message)
im.stub!(:mail).and_return(mail)
im.extract_attachments!
@@ -418,9 +405,7 @@ describe IncomingMessage, " when uudecoding bad messages" do
end
it "should apply censor rules" do
- mail_body = load_file_fixture('incoming-request-bad-uuencoding.email')
- mail = TMail::Mail.parse(mail_body)
- mail.base64_decode
+ mail = get_fixture_mail('incoming-request-bad-uuencoding.email')
im = incoming_messages(:useless_incoming_message)
im.stub!(:mail).and_return(mail)
@@ -443,14 +428,30 @@ end
describe IncomingMessage, "when messages are attached to messages" do
- before(:each) do
- load_raw_emails_data
+ it 'should expand an RFC822 attachment' do
+ # Note that this spec will only pass using Tmail in the timezone set as datetime headers
+ # are rendered out in the local time - using the Mail gem this is not necessary
+ with_env_tz('London') 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
end
it "should flatten all the attachments out" do
- mail_body = load_file_fixture('incoming-request-attach-attachments.email')
- mail = TMail::Mail.parse(mail_body)
- mail.base64_decode
+ mail = get_fixture_mail('incoming-request-attach-attachments.email')
im = incoming_messages(:useless_incoming_message)
im.stub!(:mail).and_return(mail)
@@ -464,18 +465,29 @@ describe IncomingMessage, "when messages are attached to messages" do
'hello.txt',
]
end
-end
-describe IncomingMessage, "when Outlook messages are attached to messages" do
+ it 'should add headers to attached plain text message bodies' do
+ # Note that this spec will only pass using Tmail in the timezone set as datetime headers
+ # are rendered out in the local time - using the Mail gem this is not necessary
+ with_env_tz('London') do
+ mail_body = load_file_fixture('incoming-request-attachment-headers.email')
+ mail = MailHandler.mail_from_raw_email(mail_body)
- before(:each) do
- load_raw_emails_data
+ 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
+end
+
+describe IncomingMessage, "when Outlook messages are attached to messages" do
+
it "should flatten all the attachments out" do
- mail_body = load_file_fixture('incoming-request-oft-attachments.email')
- mail = TMail::Mail.parse(mail_body)
- mail.base64_decode
+ mail = get_fixture_mail('incoming-request-oft-attachments.email')
im = incoming_messages(:useless_incoming_message)
im.stub!(:mail).and_return(mail)
@@ -490,14 +502,8 @@ end
describe IncomingMessage, "when TNEF attachments are attached to messages" do
- before(:each) do
- load_raw_emails_data
- end
-
it "should flatten all the attachments out" do
- mail_body = load_file_fixture('incoming-request-tnef-attachments.email')
- mail = TMail::Mail.parse(mail_body)
- mail.base64_decode
+ mail = get_fixture_mail('incoming-request-tnef-attachments.email')
im = incoming_messages(:useless_incoming_message)
im.stub!(:mail).and_return(mail)
diff --git a/spec/models/info_request_event_spec.rb b/spec/models/info_request_event_spec.rb
index 7352f3be0..796f8b840 100644
--- a/spec/models/info_request_event_spec.rb
+++ b/spec/models/info_request_event_spec.rb
@@ -54,36 +54,71 @@ describe InfoRequestEvent do
end
- describe "doing search/index stuff" do
+ describe "doing search/index stuff" do
before(:each) do
load_raw_emails_data
parse_all_incoming_messages
end
- it 'should get search text for outgoing messages' do
+ it 'should get search text for outgoing messages' do
event = info_request_events(:useless_outgoing_message_event)
message = outgoing_messages(:useless_outgoing_message).body
event.search_text_main.should == message + "\n\n"
end
- it 'should get search text for incoming messages' do
+ it 'should get search text for incoming messages' do
event = info_request_events(:useless_incoming_message_event)
event.search_text_main.strip.should == "No way! I'm not going to tell you that in a month of Thursdays.\n\nThe Geraldine Quango"
end
- it 'should get clipped text for incoming messages, and cache it too' do
+ it 'should get clipped text for incoming messages, and cache it too' do
event = info_request_events(:useless_incoming_message_event)
-
+
event.incoming_message_selective_columns("cached_main_body_text_folded").cached_main_body_text_folded = nil
event.search_text_main(true).strip.should == "No way! I'm not going to tell you that in a month of Thursdays.\n\nThe Geraldine Quango"
event.incoming_message_selective_columns("cached_main_body_text_folded").cached_main_body_text_folded.should_not == nil
end
-
end
+ describe 'when asked if it has the same email as a previous send' do
+
+ before do
+ @info_request_event = InfoRequestEvent.new
+ end
+
+ it 'should return true if the email in its params and the previous email the request was sent to are both nil' do
+ @info_request_event.stub!(:params).and_return({})
+ @info_request_event.stub_chain(:info_request, :get_previous_email_sent_to).and_return(nil)
+ @info_request_event.same_email_as_previous_send?.should be_true
+ end
+
+ it 'should return false if one email address exists and the other does not' do
+ @info_request_event.stub!(:params).and_return(:email => 'test@example.com')
+ @info_request_event.stub_chain(:info_request, :get_previous_email_sent_to).and_return(nil)
+ @info_request_event.same_email_as_previous_send?.should be_false
+ end
+ it 'should return true if the addresses are identical' do
+ @info_request_event.stub!(:params).and_return(:email => 'test@example.com')
+ @info_request_event.stub_chain(:info_request, :get_previous_email_sent_to).and_return('test@example.com')
+ @info_request_event.same_email_as_previous_send?.should be_true
+ end
+
+ it 'should return false if the addresses are different' do
+ @info_request_event.stub!(:params).and_return(:email => 'test@example.com')
+ @info_request_event.stub_chain(:info_request, :get_previous_email_sent_to).and_return('different@example.com')
+ @info_request_event.same_email_as_previous_send?.should be_false
+ end
+
+ it 'should return true if the addresses have different formats' do
+ @info_request_event.stub!(:params).and_return(:email => 'A Test <test@example.com>')
+ @info_request_event.stub_chain(:info_request, :get_previous_email_sent_to).and_return('test@example.com')
+ @info_request_event.same_email_as_previous_send?.should be_true
+ end
+
+ end
end
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/models/request_mailer_spec.rb b/spec/models/request_mailer_spec.rb
index 906756784..0f09e6926 100644
--- a/spec/models/request_mailer_spec.rb
+++ b/spec/models/request_mailer_spec.rb
@@ -98,7 +98,7 @@ describe RequestMailer, " when receiving incoming mail" do
mail.multipart?.should == true
mail.parts.size.should == 2
message_part = mail.parts[0].to_s
- bounced_mail = TMail::Mail.parse(mail.parts[1].body)
+ bounced_mail = MailHandler.mail_from_raw_email(mail.parts[1].body, decode=false)
bounced_mail.to.should == [ ir.incoming_email ]
bounced_mail.from.should == [ 'geraldinequango@localhost' ]
bounced_mail.body.include?("That's so totally a rubbish question").should be_true
diff --git a/spec/models/track_mailer_spec.rb b/spec/models/track_mailer_spec.rb
index 1bf77dab5..9bf03c3d0 100644
--- a/spec/models/track_mailer_spec.rb
+++ b/spec/models/track_mailer_spec.rb
@@ -169,7 +169,7 @@ describe TrackMailer do
it 'should deliver one email, with right headers' do
@user = mock_model(User,
- :name_and_email => TMail::Address.address_from_name_and_email('Tippy Test', 'tippy@localhost'),
+ :name_and_email => MailHandler.address_from_name_and_email('Tippy Test', 'tippy@localhost'),
:url_name => 'tippy_test'
)
diff --git a/spec/models/xapian_spec.rb b/spec/models/xapian_spec.rb
index 195b39eee..8c99d550f 100644
--- a/spec/models/xapian_spec.rb
+++ b/spec/models/xapian_spec.rb
@@ -4,9 +4,9 @@ describe User, " when indexing users with Xapian" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
-
+
it "should search by name" do
# def InfoRequest.full_search(models, query, order, ascending, collapse, per_page, page)
xapian_object = InfoRequest.full_search([User], "Silly", 'created_at', true, nil, 100, 1)
@@ -21,7 +21,7 @@ describe User, " when indexing users with Xapian" do
xapian_object = InfoRequest.full_search([User], "stuff", 'created_at', true, nil, 100, 1)
xapian_object.results.size.should == 1
xapian_object.results[0][:model].should == user
-
+
user.about_me = "I am really an aardvark, true story."
user.save!
update_xapian_index
@@ -38,7 +38,7 @@ end
describe PublicBody, " when indexing public bodies with Xapian" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
it "should search index the main name field" do
@@ -71,7 +71,7 @@ describe PublicBody, " when indexing requests by body they are to" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
it "should find requests to the body" do
@@ -126,7 +126,7 @@ end
describe User, " when indexing requests by user they are from" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
it "should find requests from the user" do
@@ -204,7 +204,7 @@ end
describe User, " when indexing comments by user they are by" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
it "should find requests from the user" do
@@ -239,7 +239,7 @@ end
describe InfoRequest, " when indexing requests by their title" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
it "should find events for the request" do
@@ -268,7 +268,7 @@ end
describe InfoRequest, " when indexing requests by tag" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
it "should find request by tag, even when changes" do
@@ -289,7 +289,7 @@ end
describe PublicBody, " when indexing authorities by tag" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
it "should find request by tag, even when changes" do
@@ -313,7 +313,7 @@ end
describe PublicBody, " when only indexing selected things on a rebuild" do
before(:each) do
load_raw_emails_data
- rebuild_xapian_index
+ get_fixtures_xapian_index
end
it "should only index what we ask it to" do
diff --git a/spec/script/handle-mail-replies_spec.rb b/spec/script/handle-mail-replies_spec.rb
index 406af9ee3..90a8de27c 100644
--- a/spec/script/handle-mail-replies_spec.rb
+++ b/spec/script/handle-mail-replies_spec.rb
@@ -5,7 +5,7 @@ def mail_reply_test(email_filename)
Dir.chdir Rails.root do
xc = ExternalCommand.new("script/handle-mail-replies", "--test")
xc.run(load_file_fixture(email_filename))
-
+
xc.err.should == ""
return xc
end
@@ -14,7 +14,7 @@ end
describe "When filtering" do
it "should not fail when not in test mode" do
xc = ExternalCommand.new("script/handle-mail-replies")
- xc.run(load_file_fixture("track-response-exim-bounce.email"))
+ xc.run(load_file_fixture("track-response-exim-bounce.email"))
xc.err.should == ""
end
@@ -23,19 +23,19 @@ describe "When filtering" do
r.status.should == 1
r.out.should == "user@example.com\n"
end
-
+
it "should detect a WebShield delivery error message" do
r = mail_reply_test("track-response-webshield-bounce.email")
r.status.should == 1
r.out.should == "failed.user@example.co.uk\n"
end
-
+
it "should detect a MS Exchange non-permanent delivery error message" do
r = mail_reply_test("track-response-ms-bounce.email")
r.status.should == 1
r.out.should == ""
end
-
+
it "should pass on a non-bounce message" do
r = mail_reply_test("incoming-request-bad-uuencoding.email")
r.status.should == 0
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 248dff70e..561a75da6 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -23,7 +23,6 @@ FakeWeb.register_uri(:purge, %r|varnish.localdomain|, :body => "OK")
# Use test-specific translations
FastGettext.add_text_domain 'app', :path => File.join(File.dirname(__FILE__), 'fixtures', 'locale'), :type => :po
FastGettext.default_text_domain = 'app'
-
Spec::Runner.configure do |config|
# If you're not using ActiveRecord you should remove these
# lines, delete config/database.yml and disable :active_record
@@ -47,6 +46,21 @@ Spec::Runner.configure do |config|
:holidays,
:track_things_sent_emails
+ # This section makes the garbage collector run less often to speed up tests
+ last_gc_run = Time.now
+
+ config.before(:each) do
+ GC.disable
+ end
+
+ config.after(:each) do
+ if Time.now - last_gc_run > 4
+ GC.enable
+ GC.start
+ last_gc_run = Time.now
+ end
+ end
+
# == Fixtures
#
# You can declare fixtures for each example_group like this:
@@ -93,12 +107,30 @@ 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
+def parse_all_incoming_messages
+ IncomingMessage.find(:all).each{ |x| x.parse_raw_email! }
+end
+
+def load_raw_emails_data
+ raw_emails_yml = File.join(Spec::Runner.configuration.fixture_path, "raw_emails.yml")
+ for raw_email_id in YAML::load_file(raw_emails_yml).map{|k,v| v["id"]} do
+ raw_email = RawEmail.find(raw_email_id)
+ raw_email.data = load_file_fixture("raw_emails/%d.email" % [raw_email_id])
+ end
+end
+
+# Rebuild the current xapian index
def rebuild_xapian_index(terms = true, values = true, texts = true, dropfirst = true)
if dropfirst
begin
@@ -110,16 +142,35 @@ def rebuild_xapian_index(terms = true, values = true, texts = true, dropfirst =
ActsAsXapian.writable_db.close
end
parse_all_incoming_messages
- verbose = false
# safe_rebuild=true, which involves forking to avoid memory leaks, doesn't work well with rspec.
# unsafe is significantly faster, and we can afford possible memory leaks while testing.
- safe_rebuild = false
- ActsAsXapian.rebuild_index(["PublicBody", "User", "InfoRequestEvent"].map{|m| m.constantize}, verbose, terms, values, texts, safe_rebuild)
+ models = [PublicBody, User, InfoRequestEvent]
+ ActsAsXapian.rebuild_index(models, verbose=false, terms, values, texts, safe_rebuild=false)
+end
+
+# Create a clean xapian index based on the fixture files and the raw_email data.
+def create_fixtures_xapian_index
+ load_raw_emails_data
+ rebuild_xapian_index
end
def update_xapian_index
- verbose = false
- ActsAsXapian.update_index(flush_to_disk=false, verbose)
+ ActsAsXapian.update_index(flush_to_disk=false, verbose=false)
+end
+
+# Copy the xapian index created in create_fixtures_xapian_index to a temporary
+# copy at the same level and point xapian at the copy
+def get_fixtures_xapian_index()
+ # Create a base index for the fixtures if not already created
+ $existing_xapian_db ||= create_fixtures_xapian_index
+ # Store whatever the xapian db path is originally
+ $original_xapian_path ||= ActsAsXapian.db_path
+ path_array = $original_xapian_path.split(File::Separator)
+ path_array.pop
+ temp_path = File.join(path_array, 'test.temp')
+ FileUtils.remove_entry_secure(temp_path, force=true)
+ FileUtils.cp_r($original_xapian_path, temp_path)
+ ActsAsXapian.db_path = temp_path
end
# Validate an entire HTML page
@@ -200,16 +251,8 @@ def safe_mock_model(model, args = {})
mock
end
-def load_raw_emails_data
- raw_emails_yml = File.join(Spec::Runner.configuration.fixture_path, "raw_emails.yml")
- for raw_email_id in YAML::load_file(raw_emails_yml).map{|k,v| v["id"]} do
- raw_email = RawEmail.find(raw_email_id)
- raw_email.data = load_file_fixture("raw_emails/%d.email" % [raw_email_id])
- end
-end
-
-def parse_all_incoming_messages
- IncomingMessage.find(:all).each{|x| x.parse_raw_email!}
+def get_fixture_mail(filename)
+ MailHandler.mail_from_raw_email(load_file_fixture(filename))
end
def load_test_categories
@@ -232,3 +275,18 @@ class ApplicationController < ActionController::Base
@popup_banner = nil
end
end
+
+
+def with_env_tz(new_tz = 'US/Eastern')
+ old_tz, ENV['TZ'] = ENV['TZ'], new_tz
+ yield
+ensure
+ old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
+end
+
+def with_active_record_default_timezone(zone)
+ old_zone, ActiveRecord::Base.default_timezone = ActiveRecord::Base.default_timezone, zone
+ yield
+ensure
+ ActiveRecord::Base.default_timezone = old_zone
+end