aboutsummaryrefslogtreecommitdiffstats
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/admin_incoming_message_controller_spec.rb144
-rw-r--r--spec/controllers/admin_outgoing_message_controller_spec.rb105
-rw-r--r--spec/controllers/admin_request_controller_spec.rb91
-rw-r--r--spec/controllers/request_controller_spec.rb374
-rw-r--r--spec/factories.rb140
-rw-r--r--spec/fixtures/comments.yml15
-rw-r--r--spec/fixtures/files/interesting.pdfbin0 -> 6280 bytes
-rw-r--r--spec/fixtures/holidays.yml9
-rw-r--r--spec/fixtures/incoming_messages.yml22
-rw-r--r--spec/fixtures/info_request_events.yml17
-rw-r--r--spec/fixtures/info_requests.yml24
-rw-r--r--spec/fixtures/locale/en/app.po4
-rw-r--r--spec/fixtures/locale/en_GB/app.po4
-rw-r--r--spec/fixtures/locale/es/app.po4
-rw-r--r--spec/fixtures/outgoing_messages.yml16
-rw-r--r--spec/fixtures/public_bodies.yml23
-rw-r--r--spec/fixtures/raw_emails.yml7
-rw-r--r--spec/fixtures/track_things.yml16
-rw-r--r--spec/fixtures/users.yml26
-rw-r--r--spec/integration/admin_spec.rb79
-rw-r--r--spec/integration/alaveteli_dsl.rb68
-rw-r--r--spec/integration/create_request_spec.rb45
-rw-r--r--spec/integration/download_request_spec.rb324
-rw-r--r--spec/integration/request_controller_spec.rb17
-rw-r--r--spec/integration/view_request_spec.rb164
-rw-r--r--spec/mailers/request_mailer_spec.rb20
-rw-r--r--spec/models/censor_rule_spec.rb17
-rw-r--r--spec/models/foi_attachment_spec.rb15
-rw-r--r--spec/models/holiday_spec.rb9
-rw-r--r--spec/models/incoming_message_spec.rb134
-rw-r--r--spec/models/info_request_event_spec.rb75
-rw-r--r--spec/models/info_request_spec.rb144
-rw-r--r--spec/models/mail_server_log_spec.rb13
-rw-r--r--spec/models/outgoing_message_spec.rb93
-rw-r--r--spec/models/post_redirect_spec.rb16
-rw-r--r--spec/models/profile_photo_spec.rb10
-rw-r--r--spec/models/public_body_spec.rb23
-rw-r--r--spec/models/purge_request_spec.rb11
-rw-r--r--spec/models/raw_email_spec.rb7
-rw-r--r--spec/models/track_thing_spec.rb16
-rw-r--r--spec/models/track_things_sent_email_spec.rb13
-rw-r--r--spec/models/user_info_request_sent_alert_spec.rb11
-rw-r--r--spec/models/user_spec.rb26
-rw-r--r--spec/spec_helper.rb2
-rw-r--r--spec/views/request/_after_actions.html.erb_spec.rb21
-rw-r--r--spec/views/request/show.html.erb_spec.rb88
46 files changed, 2086 insertions, 416 deletions
diff --git a/spec/controllers/admin_incoming_message_controller_spec.rb b/spec/controllers/admin_incoming_message_controller_spec.rb
new file mode 100644
index 000000000..b969a8a3f
--- /dev/null
+++ b/spec/controllers/admin_incoming_message_controller_spec.rb
@@ -0,0 +1,144 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe AdminIncomingMessageController, "when administering incoming messages" do
+
+ describe 'when destroying an incoming message' do
+
+ before(:each) do
+ basic_auth_login @request
+ load_raw_emails_data
+ end
+
+ before do
+ @im = incoming_messages(:useless_incoming_message)
+ @controller.stub!(:expire_for_request)
+ end
+
+ it "destroys the raw email file" do
+ raw_email = @im.raw_email.filepath
+ assert_equal File.exists?(raw_email), true
+ post :destroy, :incoming_message_id => @im.id
+ assert_equal File.exists?(raw_email), false
+ end
+
+ it 'asks the incoming message to fully destroy itself' do
+ IncomingMessage.stub!(:find).and_return(@im)
+ @im.should_receive(:fully_destroy)
+ post :destroy, :incoming_message_id => @im.id
+ end
+
+ it 'expires the file cache for the associated info_request' do
+ @controller.should_receive(:expire_for_request).with(@im.info_request)
+ post :destroy, :incoming_message_id => @im.id
+ end
+
+ end
+
+ describe 'when redelivering an incoming message' do
+
+ before(:each) do
+ basic_auth_login @request
+ load_raw_emails_data
+ end
+
+ it 'expires the file cache for the previous request' do
+ current_info_request = info_requests(:fancy_dog_request)
+ destination_info_request = info_requests(:naughty_chicken_request)
+ incoming_message = incoming_messages(:useless_incoming_message)
+ @controller.should_receive(:expire_for_request).with(current_info_request)
+ post :redeliver, :redeliver_incoming_message_id => incoming_message.id,
+ :url_title => destination_info_request.url_title
+ end
+
+
+ end
+
+ describe 'when editing an incoming message' do
+
+ before do
+ @incoming = FactoryGirl.create(:incoming_message)
+ end
+
+ it 'should be successful' do
+ get :edit, :id => @incoming.id
+ response.should be_success
+ end
+
+ it 'should assign the incoming message to the view' do
+ get :edit, :id => @incoming.id
+ assigns[:incoming_message].should == @incoming
+ end
+
+ end
+
+ describe 'when updating an incoming message' do
+
+ before do
+ @incoming = FactoryGirl.create(:incoming_message, :prominence => 'normal')
+ @default_params = {:id => @incoming.id,
+ :incoming_message => {:prominence => 'hidden',
+ :prominence_reason => 'dull'} }
+ end
+
+ def make_request(params=@default_params)
+ post :update, params
+ end
+
+ it 'should save the prominence of the message' do
+ make_request
+ @incoming.reload
+ @incoming.prominence.should == 'hidden'
+ end
+
+ it 'should save a prominence reason for the message' do
+ make_request
+ @incoming.reload
+ @incoming.prominence_reason.should == 'dull'
+ end
+
+ it 'should log an "edit_incoming" event on the info_request' do
+ @controller.stub!(:admin_current_user).and_return("Admin user")
+ make_request
+ @incoming.reload
+ last_event = @incoming.info_request_events.last
+ last_event.event_type.should == 'edit_incoming'
+ last_event.params.should == { :incoming_message_id => @incoming.id,
+ :editor => "Admin user",
+ :old_prominence => "normal",
+ :prominence => "hidden",
+ :old_prominence_reason => nil,
+ :prominence_reason => "dull" }
+ end
+
+ it 'should expire the file cache for the info request' do
+ @controller.should_receive(:expire_for_request).with(@incoming.info_request)
+ make_request
+ end
+
+ context 'if the incoming message saves correctly' do
+
+ it 'should redirect to the admin info request view' do
+ make_request
+ response.should redirect_to admin_request_show_url(@incoming.info_request)
+ end
+
+ it 'should show a message that the incoming message has been updated' do
+ make_request
+ flash[:notice].should == 'Incoming message successfully updated.'
+ end
+
+ end
+
+ context 'if the incoming message is not valid' do
+
+ it 'should render the edit template' do
+ make_request({:id => @incoming.id,
+ :incoming_message => {:prominence => 'fantastic',
+ :prominence_reason => 'dull'}})
+ response.should render_template("edit")
+ end
+
+ end
+ end
+
+end
diff --git a/spec/controllers/admin_outgoing_message_controller_spec.rb b/spec/controllers/admin_outgoing_message_controller_spec.rb
new file mode 100644
index 000000000..0dde53b86
--- /dev/null
+++ b/spec/controllers/admin_outgoing_message_controller_spec.rb
@@ -0,0 +1,105 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe AdminOutgoingMessageController do
+
+ describe 'when editing an outgoing message' do
+
+ before do
+ @info_request = FactoryGirl.create(:info_request)
+ @outgoing = @info_request.outgoing_messages.first
+ end
+
+ it 'should be successful' do
+ get :edit, :id => @outgoing.id
+ response.should be_success
+ end
+
+ it 'should assign the incoming message to the view' do
+ get :edit, :id => @outgoing.id
+ assigns[:outgoing_message].should == @outgoing
+ end
+
+ end
+
+ describe 'when updating an outgoing message' do
+
+ before do
+ @info_request = FactoryGirl.create(:info_request)
+ @outgoing = @info_request.outgoing_messages.first
+ @default_params = {:id => @outgoing.id,
+ :outgoing_message => {:prominence => 'hidden',
+ :prominence_reason => 'dull',
+ :body => 'changed body'} }
+ end
+
+ def make_request(params=@default_params)
+ post :update, params
+ end
+
+ it 'should save a change to the body of the message' do
+ make_request
+ @outgoing.reload
+ @outgoing.body.should == 'changed body'
+ end
+
+ it 'should save the prominence of the message' do
+ make_request
+ @outgoing.reload
+ @outgoing.prominence.should == 'hidden'
+ end
+
+ it 'should save a prominence reason for the message' do
+ make_request
+ @outgoing.reload
+ @outgoing.prominence_reason.should == 'dull'
+ end
+
+ it 'should log an "edit_outgoing" event on the info_request' do
+ @controller.stub!(:admin_current_user).and_return("Admin user")
+ make_request
+ @info_request.reload
+ last_event = @info_request.info_request_events.last
+ last_event.event_type.should == 'edit_outgoing'
+ last_event.params.should == { :outgoing_message_id => @outgoing.id,
+ :editor => "Admin user",
+ :old_prominence => "normal",
+ :prominence => "hidden",
+ :old_prominence_reason => nil,
+ :old_body => 'Some information please',
+ :body => 'changed body',
+ :prominence_reason => "dull" }
+ end
+
+ it 'should expire the file cache for the info request' do
+ @controller.should_receive(:expire_for_request).with(@info_request)
+ make_request
+ end
+
+ context 'if the outgoing message saves correctly' do
+
+ it 'should redirect to the admin info request view' do
+ make_request
+ response.should redirect_to admin_request_show_url(@info_request)
+ end
+
+ it 'should show a message that the incoming message has been updated' do
+ make_request
+ flash[:notice].should == 'Outgoing message successfully updated.'
+ end
+
+ end
+
+ context 'if the incoming message is not valid' do
+
+ it 'should render the edit template' do
+ make_request({:id => @outgoing.id,
+ :outgoing_message => {:prominence => 'fantastic',
+ :prominence_reason => 'dull',
+ :body => 'Some information please'}})
+ response.should render_template("edit")
+ end
+
+ end
+ end
+
+end
diff --git a/spec/controllers/admin_request_controller_spec.rb b/spec/controllers/admin_request_controller_spec.rb
index b7b726507..c374ff90d 100644
--- a/spec/controllers/admin_request_controller_spec.rb
+++ b/spec/controllers/admin_request_controller_spec.rb
@@ -52,18 +52,6 @@ describe AdminRequestController, "when administering requests" do
end
- it "edits an outgoing message" do
- get :edit_outgoing, :id => outgoing_messages(:useless_outgoing_message)
- end
-
- it "saves edits to an outgoing_message" do
- outgoing_messages(:useless_outgoing_message).body.should include("fancy dog")
- post :update_outgoing, { :id => outgoing_messages(:useless_outgoing_message), :outgoing_message => { :body => "Why do you have such a delicious cat?" } }
- request.flash[:notice].should include('successful')
- ir = OutgoingMessage.find(outgoing_messages(:useless_outgoing_message).id)
- ir.body.should include("delicious cat")
- end
-
describe 'when fully destroying a request' do
it 'expires the file cache for that request' do
@@ -89,59 +77,10 @@ describe AdminRequestController, "when administering the holding pen" do
ir.handle_rejected_responses = 'holding_pen'
ir.save!
receive_incoming_mail('incoming-request-plain.email', ir.incoming_email, "frob@nowhere.com")
- get :show_raw_email, :id => InfoRequest.holding_pen_request.get_last_response.raw_email.id
+ get :show_raw_email, :id => InfoRequest.holding_pen_request.get_last_public_response.raw_email.id
response.should contain "Only the authority can reply to this request"
end
- it "allows redelivery even to a closed request" do
- ir = info_requests(:fancy_dog_request)
- ir.allow_new_responses_from = 'nobody'
- ir.handle_rejected_responses = 'holding_pen'
- ir.save!
- InfoRequest.holding_pen_request.incoming_messages.length.should == 0
- ir.incoming_messages.length.should == 1
- receive_incoming_mail('incoming-request-plain.email', ir.incoming_email, "frob@nowhere.com")
- InfoRequest.holding_pen_request.incoming_messages.length.should == 1
- new_im = InfoRequest.holding_pen_request.incoming_messages[0]
- ir.incoming_messages.length.should == 1
- post :redeliver_incoming, :redeliver_incoming_message_id => new_im.id, :url_title => ir.url_title
- ir = InfoRequest.find_by_url_title(ir.url_title)
- ir.incoming_messages.length.should == 2
- response.should redirect_to(:controller=>'admin_request', :action=>'show', :id=>101)
- InfoRequest.holding_pen_request.incoming_messages.length.should == 0
- end
-
- it "allows redelivery to more than one request" do
- ir1 = info_requests(:fancy_dog_request)
- ir1.allow_new_responses_from = 'nobody'
- ir1.handle_rejected_responses = 'holding_pen'
- ir1.save!
- ir1.incoming_messages.length.should == 1
- ir2 = info_requests(:another_boring_request)
- ir2.incoming_messages.length.should == 1
-
- receive_incoming_mail('incoming-request-plain.email', ir1.incoming_email, "frob@nowhere.com")
- InfoRequest.holding_pen_request.incoming_messages.length.should == 1
-
- new_im = InfoRequest.holding_pen_request.incoming_messages[0]
- post :redeliver_incoming, :redeliver_incoming_message_id => new_im.id, :url_title => "#{ir1.url_title},#{ir2.url_title}"
- ir1.reload
- ir1.incoming_messages.length.should == 2
- ir2.reload
- ir2.incoming_messages.length.should == 2
- response.should redirect_to(:controller=>'admin_request', :action=>'show', :id=>ir2.id)
- InfoRequest.holding_pen_request.incoming_messages.length.should == 0
- end
-
- it 'expires the file cache for the previous request' do
- current_info_request = info_requests(:fancy_dog_request)
- destination_info_request = info_requests(:naughty_chicken_request)
- incoming_message = incoming_messages(:useless_incoming_message)
- @controller.should_receive(:expire_for_request).with(current_info_request)
- post :redeliver_incoming, :redeliver_incoming_message_id => incoming_message.id,
- :url_title => destination_info_request.url_title
- end
-
it "guesses a misdirected request" do
ir = info_requests(:fancy_dog_request)
ir.handle_rejected_responses = 'holding_pen'
@@ -149,7 +88,8 @@ describe AdminRequestController, "when administering the holding pen" do
ir.save!
mail_to = "request-#{ir.id}-asdfg@example.com"
receive_incoming_mail('incoming-request-plain.email', mail_to)
- interesting_email = InfoRequest.holding_pen_request.get_last_response.raw_email.id
+ interesting_email = InfoRequest.holding_pen_request.get_last_public_response
+.raw_email.id
# now we add another message to the queue, which we're not interested in
receive_incoming_mail('incoming-request-plain.email', ir.incoming_email, "")
InfoRequest.holding_pen_request.incoming_messages.length.should == 2
@@ -158,32 +98,7 @@ describe AdminRequestController, "when administering the holding pen" do
assigns[:info_requests][0].should == ir
end
- describe 'when destroying an incoming message' do
-
- before do
- @im = incoming_messages(:useless_incoming_message)
- @controller.stub!(:expire_for_request)
- end
-
- it "destroys the raw email file" do
- raw_email = @im.raw_email.filepath
- assert_equal File.exists?(raw_email), true
- post :destroy_incoming, :incoming_message_id => @im.id
- assert_equal File.exists?(raw_email), false
- end
-
- it 'asks the incoming message to fully destroy itself' do
- IncomingMessage.stub!(:find).and_return(@im)
- @im.should_receive(:fully_destroy)
- post :destroy_incoming, :incoming_message_id => @im.id
- end
- it 'expires the file cache for the associated info_request' do
- @controller.should_receive(:expire_for_request).with(@im.info_request)
- post :destroy_incoming, :incoming_message_id => @im.id
- end
-
- end
it "shows a suitable default 'your email has been hidden' message" do
ir = info_requests(:fancy_dog_request)
diff --git a/spec/controllers/request_controller_spec.rb b/spec/controllers/request_controller_spec.rb
index 9c4e16c67..d190b0db7 100644
--- a/spec/controllers/request_controller_spec.rb
+++ b/spec/controllers/request_controller_spec.rb
@@ -191,7 +191,6 @@ describe RequestController, "when showing one request" do
before(:each) do
load_raw_emails_data
- FileUtils.rm_rf File.join(File.dirname(__FILE__), "../../cache/zips")
end
it "should be successful" do
@@ -768,194 +767,221 @@ describe RequestController, "when showing one request" do
end
end
- describe 'when making a zipfile available' do
- it 'should return a 410 for a request that is hidden' do
- title = 'why_do_you_have_such_a_fancy_dog'
- ir = info_requests(:fancy_dog_request)
- ir.prominence = 'hidden'
- ir.save!
- get :download_entire_request, {:url_title => title}, { :user_id => ir.user.id }
- response.should render_template('request/hidden')
- response.code.should == '410'
- end
-
- it "should have a different zipfile URL when the request changes" do
- title = 'why_do_you_have_such_a_fancy_dog'
- ir = info_requests(:fancy_dog_request)
- session[:user_id] = ir.user.id # bob_smith_user
- get :download_entire_request, :url_title => title
- assigns[:url_path].should contain /#{title}.zip$/
- old_path = assigns[:url_path]
- response.location.should contain /#{assigns[:url_path]}$/
- zipfile = Zip::ZipFile.open(File.join(File.dirname(__FILE__), "../../cache/zips", old_path)) { |zipfile|
- zipfile.count.should == 1 # just the message
- }
- receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email)
- get :download_entire_request, :url_title => title
- assigns[:url_path].should contain /#{title}.zip$/
- old_path = assigns[:url_path]
- response.location.should contain /#{assigns[:url_path]}$/
- zipfile = Zip::ZipFile.open(File.join(File.dirname(__FILE__), "../../cache/zips", old_path)) { |zipfile|
- zipfile.count.should == 3 # the message plus two "hello-world.txt" files
- }
-
- # The path of the zip file is based on the hash of the timestamp of the last request
- # in the thread, so we wait for a second to make sure this one will have a different
- # timestamp than the previous.
- sleep 1
- receive_incoming_mail('incoming-request-attachment-unknown-extension.email', ir.incoming_email)
- get :download_entire_request, :url_title => title
- assigns[:url_path].should contain /#{title}.zip$/
- assigns[:url_path].should_not == old_path
- response.location.should contain assigns[:url_path]
- zipfile = Zip::ZipFile.open(File.join(File.dirname(__FILE__), "../../cache/zips", assigns[:url_path])) { |zipfile|
- zipfile.count.should == 4 # the message, two hello-world.txt plus the unknown attachment
- }
- end
-
- it 'should successfully make a zipfile for an external request' do
- info_request = info_requests(:external_request)
- get :download_entire_request, { :url_title => info_request.url_title },
- { :user_id => users(:bob_smith_user) }
- response.location.should contain /#{assigns[:url_path]}$/
- end
- end
end
end
-describe RequestController, "when changing prominence of a request" do
- before(:each) do
- load_raw_emails_data
+describe RequestController, "when handling prominence" do
+
+ def expect_hidden(hidden_template)
+ response.content_type.should == "text/html"
+ response.should render_template(hidden_template)
+ response.code.should == '403'
end
- it "should not show hidden requests" do
- ir = info_requests(:fancy_dog_request)
- ir.prominence = 'hidden'
- ir.save!
+ context 'when the request is hidden' do
- get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.should render_template('hidden')
- end
+ before(:each) do
+ @info_request = FactoryGirl.create(:info_request_with_incoming_attachments,
+ :prominence => 'hidden')
+ end
- it "should not show hidden requests even if logged in as their owner" do
- ir = info_requests(:fancy_dog_request)
- ir.prominence = 'hidden'
- ir.save!
+ it "should not show request if you're not logged in" do
+ get :show, :url_title => @info_request.url_title
+ expect_hidden('hidden')
+ end
- session[:user_id] = ir.user.id # bob_smith_user
- get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.should render_template('hidden')
- end
+ it "should not show request even if logged in as their owner" do
+ session[:user_id] = @info_request.user.id
+ get :show, :url_title => @info_request.url_title
+ expect_hidden('hidden')
+ end
- it 'should not show hidden requests if requested using json' do
- ir = info_requests(:fancy_dog_request)
- ir.prominence = 'hidden'
- ir.save!
+ it 'should not show request if requested using json' do
+ session[:user_id] = @info_request.user.id
+ get :show, :url_title => @info_request.url_title, :format => 'json'
+ response.code.should == '403'
+ end
- session[:user_id] = ir.user.id # bob_smith_user
- get :show, :url_title => 'why_do_you_have_such_a_fancy_dog', :format => 'json'
- response.code.should == '410'
- end
+ it "should show request if logged in as super user" do
+ session[:user_id] = FactoryGirl.create(:admin_user)
+ get :show, :url_title => @info_request.url_title
+ response.should render_template('show')
+ end
- it "should show hidden requests if logged in as super user" do
- ir = info_requests(:fancy_dog_request)
- ir.prominence = 'hidden'
- ir.save!
+ it "should not download attachments" do
+ incoming_message = @info_request.incoming_messages.first
+ get :get_attachment, :incoming_message_id => incoming_message.id,
+ :id => @info_request.id,
+ :part => 2,
+ :file_name => 'interesting.pdf',
+ :skip_cache => 1
+ expect_hidden('request/hidden')
+ end
+
+ it 'should not generate an HTML version of an attachment for a request whose prominence
+ is hidden even for an admin but should return a 404' do
+ session[:user_id] = FactoryGirl.create(:admin_user)
+ incoming_message = @info_request.incoming_messages.first
+ lambda do
+ get :get_attachment_as_html, :incoming_message_id => incoming_message.id,
+ :id => @info_request.id,
+ :part => 2,
+ :file_name => 'interesting.pdf'
+ end.should raise_error(ActiveRecord::RecordNotFound)
+ end
- session[:user_id] = users(:admin_user)
- get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.should render_template('show')
end
- it "should not show requester_only requests if you're not logged in" do
- ir = info_requests(:fancy_dog_request)
- ir.prominence = 'requester_only'
- ir.save!
+ context 'when the request is requester_only' do
- get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.should render_template('hidden')
- end
+ before(:each) do
+ @info_request = FactoryGirl.create(:info_request_with_incoming_attachments,
+ :prominence => 'requester_only')
+ end
- it "should show requester_only requests to requester and admin if logged in" do
- ir = info_requests(:fancy_dog_request)
- ir.prominence = 'requester_only'
- ir.save!
+ it "should not show request if you're not logged in" do
+ get :show, :url_title => @info_request.url_title
+ expect_hidden('hidden')
+ end
- session[:user_id] = users(:silly_name_user).id
- get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.should render_template('hidden')
+ it "should show request to requester and admin if logged in" do
+ session[:user_id] = FactoryGirl.create(:user).id
+ get :show, :url_title => @info_request.url_title
+ expect_hidden('hidden')
- session[:user_id] = ir.user.id # bob_smith_user
- get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.should render_template('show')
+ session[:user_id] = @info_request.user.id
+ get :show, :url_title => @info_request.url_title
+ response.should render_template('show')
- session[:user_id] = users(:admin_user).id
- get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
- response.should render_template('show')
- end
+ session[:user_id] = FactoryGirl.create(:admin_user).id
+ get :show, :url_title => @info_request.url_title
+ response.should render_template('show')
+ end
- it 'should not cache an attachment on a request whose prominence is requester_only when showing
- the request to the requester or admin' do
- ir = info_requests(:fancy_dog_request)
- ir.prominence = 'requester_only'
- ir.save!
- session[:user_id] = ir.user.id # bob_smith_user
- @controller.should_not_receive(:foi_fragment_cache_write)
- get :show, :url_title => 'why_do_you_have_such_a_fancy_dog'
+ it 'should not cache an attachment when showing an attachment to the requester or admin' do
+ session[:user_id] = @info_request.user.id
+ incoming_message = @info_request.incoming_messages.first
+ @controller.should_not_receive(:foi_fragment_cache_write)
+ get :get_attachment, :incoming_message_id => incoming_message.id,
+ :id => @info_request.id,
+ :part => 2,
+ :file_name => 'interesting.pdf'
+ end
end
- it "should not download attachments if hidden" do
- ir = info_requests(:fancy_dog_request)
- ir.prominence = 'hidden'
- ir.save!
- receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email)
+ context 'when the incoming message has prominence hidden' do
+
+ before(:each) do
+ @incoming_message = FactoryGirl.create(:incoming_message_with_attachments,
+ :prominence => 'hidden')
+ @info_request = @incoming_message.info_request
+ end
+
+ it "should not download attachments for a non-logged in user" do
+ get :get_attachment, :incoming_message_id => @incoming_message.id,
+ :id => @info_request.id,
+ :part => 2,
+ :file_name => 'interesting.pdf',
+ :skip_cache => 1
+ expect_hidden('request/hidden_correspondence')
+ end
+
+ it 'should not download attachments for the request owner' do
+ session[:user_id] = @info_request.user.id
+ get :get_attachment, :incoming_message_id => @incoming_message.id,
+ :id => @info_request.id,
+ :part => 2,
+ :file_name => 'interesting.pdf',
+ :skip_cache => 1
+ expect_hidden('request/hidden_correspondence')
+ end
+
+ it 'should download attachments for an admin user', :focus => true do
+ session[:user_id] = FactoryGirl.create(:admin_user).id
+ get :get_attachment, :incoming_message_id => @incoming_message.id,
+ :id => @info_request.id,
+ :part => 2,
+ :file_name => 'interesting.pdf',
+ :skip_cache => 1
+ response.content_type.should == 'application/pdf'
+ response.should be_success
+ end
+
+ it 'should not generate an HTML version of an attachment for a request whose prominence
+ is hidden even for an admin but should return a 404' do
+ session[:user_id] = FactoryGirl.create(:admin_user).id
+ lambda do
+ get :get_attachment_as_html, :incoming_message_id => @incoming_message.id,
+ :id => @info_request.id,
+ :part => 2,
+ :file_name => 'interesting.pdf',
+ :skip_cache => 1
+ end.should raise_error(ActiveRecord::RecordNotFound)
+ end
+
+ it 'should not cache an attachment when showing an attachment to the requester or admin' do
+ session[:user_id] = @info_request.user.id
+ @controller.should_not_receive(:foi_fragment_cache_write)
+ get :get_attachment, :incoming_message_id => @incoming_message.id,
+ :id => @info_request.id,
+ :part => 2,
+ :file_name => 'interesting.pdf'
+ end
- 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 contain "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
- response.content_type.should == "text/html"
- response.should_not contain "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 world.txt'
- end.should raise_error(ActiveRecord::RecordNotFound)
- 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 world.txt'
- end.should raise_error(ActiveRecord::RecordNotFound)
+ context 'when the incoming message has prominence requester_only' do
+
+ before(:each) do
+ @incoming_message = FactoryGirl.create(:incoming_message_with_attachments,
+ :prominence => 'requester_only')
+ @info_request = @incoming_message.info_request
+ end
+
+ it "should not download attachments for a non-logged in user" do
+ get :get_attachment, :incoming_message_id => @incoming_message.id,
+ :id => @info_request.id,
+ :part => 2,
+ :file_name => 'interesting.pdf',
+ :skip_cache => 1
+ expect_hidden('request/hidden_correspondence')
+ end
+
+ it 'should download attachments for the request owner' do
+ session[:user_id] = @info_request.user.id
+ get :get_attachment, :incoming_message_id => @incoming_message.id,
+ :id => @info_request.id,
+ :part => 2,
+ :file_name => 'interesting.pdf',
+ :skip_cache => 1
+ response.content_type.should == 'application/pdf'
+ response.should be_success
+ end
+
+ it 'should download attachments for an admin user', :focus => true do
+ session[:user_id] = FactoryGirl.create(:admin_user).id
+ get :get_attachment, :incoming_message_id => @incoming_message.id,
+ :id => @info_request.id,
+ :part => 2,
+ :file_name => 'interesting.pdf',
+ :skip_cache => 1
+ response.content_type.should == 'application/pdf'
+ response.should be_success
+ end
+
+ it 'should not generate an HTML version of an attachment for a request whose prominence
+ is hidden even for an admin but should return a 404' do
+ session[:user_id] = FactoryGirl.create(:admin_user)
+ lambda do
+ get :get_attachment_as_html, :incoming_message_id => @incoming_message.id,
+ :id => @info_request.id,
+ :part => 2,
+ :file_name => 'interesting.pdf',
+ :skip_cache => 1
+ end.should raise_error(ActiveRecord::RecordNotFound)
+ end
+
end
end
@@ -1293,12 +1319,12 @@ describe RequestController, "when viewing an individual response for reply/follo
response.should render_template('request/hidden')
end
- it 'should respond to a json request for a hidden request with a 410 code and no body' do
+ it 'should respond to a json request for a hidden request with a 403 code and no body' do
get :show_response, :id => info_requests(:fancy_dog_request).id,
:incoming_message_id => incoming_messages(:useless_incoming_message),
:format => 'json'
- response.code.should == '410'
+ response.code.should == '403'
end
end
@@ -1572,7 +1598,7 @@ describe RequestController, "when classifying an information request" do
@dog_request.reload
@dog_request.awaiting_description.should == false
@dog_request.described_state.should == 'rejected'
- @dog_request.get_last_response_event.should == info_request_events(:useless_incoming_message_event)
+ @dog_request.get_last_public_response_event.should == info_request_events(:useless_incoming_message_event)
@dog_request.info_request_events.last.event_type.should == "status_update"
@dog_request.info_request_events.last.calculated_state.should == 'rejected'
end
@@ -1725,13 +1751,13 @@ describe RequestController, "when classifying an information request" do
it 'should redirect to the "response url" when there is a last response' do
incoming_message = mock_model(IncomingMessage)
- @dog_request.stub!(:get_last_response).and_return(incoming_message)
+ @dog_request.stub!(:get_last_public_response).and_return(incoming_message)
expect_redirect('waiting_clarification', "request/#{@dog_request.id}/response/#{incoming_message.id}")
end
it 'should redirect to the "response no followup url" when there are no events
needing description' do
- @dog_request.stub!(:get_last_response).and_return(nil)
+ @dog_request.stub!(:get_last_public_response).and_return(nil)
expect_redirect('waiting_clarification', "request/#{@dog_request.id}/response")
end
@@ -1770,7 +1796,7 @@ describe RequestController, "when classifying an information request" do
context 'when status is updated to "gone postal"' do
it 'should redirect to the "respond to last url"' do
- expect_redirect('gone_postal', "request/#{@dog_request.id}/response/#{@dog_request.get_last_response.id}?gone_postal=1")
+ expect_redirect('gone_postal', "request/#{@dog_request.id}/response/#{@dog_request.get_last_public_response.id}?gone_postal=1")
end
end
@@ -1812,7 +1838,7 @@ describe RequestController, "when classifying an information request" do
context 'when status is updated to "user_withdrawn"' do
it 'should redirect to the "respond to last url url" ' do
- expect_redirect('user_withdrawn', "request/#{@dog_request.id}/response/#{@dog_request.get_last_response.id}")
+ expect_redirect('user_withdrawn', "request/#{@dog_request.id}/response/#{@dog_request.get_last_public_response.id}")
end
end
@@ -1865,7 +1891,7 @@ describe RequestController, "when sending a followup message" do
# fake that this is a clarification
info_requests(:fancy_dog_request).set_described_state('waiting_clarification')
info_requests(:fancy_dog_request).described_state.should == 'waiting_clarification'
- info_requests(:fancy_dog_request).get_last_response_event.calculated_state.should == 'waiting_clarification'
+ info_requests(:fancy_dog_request).get_last_public_response_event.calculated_state.should == 'waiting_clarification'
# make the followup
session[:user_id] = users(:bob_smith_user).id
@@ -1883,7 +1909,7 @@ describe RequestController, "when sending a followup message" do
# and that the status changed
info_requests(:fancy_dog_request).reload
info_requests(:fancy_dog_request).described_state.should == 'waiting_response'
- info_requests(:fancy_dog_request).get_last_response_event.calculated_state.should == 'waiting_clarification'
+ info_requests(:fancy_dog_request).get_last_public_response_event.calculated_state.should == 'waiting_clarification'
end
it "should give an error if the same followup is submitted twice" do
@@ -2456,7 +2482,9 @@ describe RequestController, "when caching fragments" do
:info_request_id => 132,
:id => 44,
:get_attachments_for_display => nil,
- :html_mask_stuff! => nil)
+ :html_mask_stuff! => nil,
+ :user_can_view? => true,
+ :all_can_view? => true)
attachment = mock(FoiAttachment, :display_filename => long_name,
:body_as_html => ['some text', 'wrapper'])
IncomingMessage.stub!(:find).with("44").and_return(incoming_message)
diff --git a/spec/factories.rb b/spec/factories.rb
new file mode 100644
index 000000000..653525920
--- /dev/null
+++ b/spec/factories.rb
@@ -0,0 +1,140 @@
+FactoryGirl.define do
+
+ sequence(:email) { |n| "person#{n}@example.com" }
+ sequence(:name) { |n| "Example Public Body #{n}" }
+ sequence(:short_name) { |n| "Example Body #{n}" }
+
+ factory :foi_attachment do
+ factory :body_text do
+ content_type 'text/plain'
+ body { 'hereisthetext' }
+ end
+ factory :pdf_attachment do
+ content_type 'application/pdf'
+ filename 'interesting.pdf'
+ body { load_file_fixture('interesting.pdf') }
+ end
+ end
+
+ factory :incoming_message do
+ info_request
+ raw_email
+ last_parsed { 1.week.ago }
+ sent_at { 1.week.ago }
+
+ after_create do |incoming_message, evaluator|
+ FactoryGirl.create(:body_text,
+ :incoming_message => incoming_message,
+ :url_part_number => 1)
+ end
+
+ factory :plain_incoming_message do
+ last_parsed { nil }
+ sent_at { nil }
+ after_create do |incoming_message, evaluator|
+ data = load_file_fixture('incoming-request-plain.email')
+ data.gsub!('EMAIL_FROM', 'Bob Responder <bob@example.com>')
+ incoming_message.raw_email.data = data
+ incoming_message.raw_email.save!
+ end
+ end
+
+ factory :incoming_message_with_attachments do
+ # foi_attachments_count is declared as an ignored attribute and available in
+ # attributes on the factory, as well as the callback via the evaluator
+ ignore do
+ foi_attachments_count 2
+ end
+
+ # the after(:create) yields two values; the incoming_message instance itself and the
+ # evaluator, which stores all values from the factory, including ignored
+ # attributes;
+ after_create do |incoming_message, evaluator|
+ evaluator.foi_attachments_count.times do |count|
+ FactoryGirl.create(:pdf_attachment,
+ :incoming_message => incoming_message,
+ :url_part_number => count+2)
+ end
+ end
+ end
+ end
+
+ factory :raw_email
+
+ factory :outgoing_message do
+ factory :initial_request do
+ ignore do
+ status 'ready'
+ message_type 'initial_request'
+ body 'Some information please'
+ what_doing 'normal_sort'
+ end
+ initialize_with { OutgoingMessage.new({ :status => status,
+ :message_type => message_type,
+ :body => body,
+ :what_doing => what_doing }) }
+ after_create do |outgoing_message|
+ outgoing_message.send_message
+ end
+ end
+ end
+
+ factory :info_request do
+ title "Example Title"
+ public_body
+ user
+
+ after_create do |info_request, evaluator|
+ FactoryGirl.create(:initial_request, :info_request => info_request)
+ end
+
+ factory :info_request_with_incoming do
+ after_create do |info_request, evaluator|
+ incoming_message = FactoryGirl.create(:incoming_message, :info_request => info_request)
+ info_request.log_event("response", {:incoming_message_id => incoming_message.id})
+ end
+ end
+
+ factory :info_request_with_plain_incoming do
+ after_create do |info_request, evaluator|
+ incoming_message = FactoryGirl.create(:plain_incoming_message, :info_request => info_request)
+ info_request.log_event("response", {:incoming_message_id => incoming_message.id})
+ end
+ end
+
+ factory :info_request_with_incoming_attachments do
+ after_create do |info_request, evaluator|
+ incoming_message = FactoryGirl.create(:incoming_message_with_attachments, :info_request => info_request)
+ info_request.log_event("response", {:incoming_message_id => incoming_message.id})
+ end
+ end
+
+ factory :external_request do
+ user nil
+ external_user_name 'External User'
+ external_url 'http://www.example.org/request/external'
+ end
+
+ end
+
+ factory :user do
+ name 'Example User'
+ email
+ salt "-6116981980.392287733335677"
+ hashed_password '6b7cd45a5f35fd83febc0452a799530398bfb6e8' # jonespassword
+ email_confirmed true
+ factory :admin_user do
+ name 'Admin User'
+ admin_level 'super'
+ end
+ end
+
+ factory :public_body do
+ name
+ short_name
+ request_email 'request@example.com'
+ last_edit_editor "admin user"
+ last_edit_comment "Making an edit"
+ end
+
+end
diff --git a/spec/fixtures/comments.yml b/spec/fixtures/comments.yml
index b73385a55..44db44d54 100644
--- a/spec/fixtures/comments.yml
+++ b/spec/fixtures/comments.yml
@@ -1,3 +1,18 @@
+# == Schema Information
+#
+# Table name: comments
+#
+# id :integer not null, primary key
+# user_id :integer not null
+# comment_type :string(255) default("internal_error"), not null
+# info_request_id :integer
+# body :text not null
+# visible :boolean default(TRUE), not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# locale :text default(""), not null
+#
+
silly_comment:
visible: t
updated_at: 2008-08-13 01:25:17.486939
diff --git a/spec/fixtures/files/interesting.pdf b/spec/fixtures/files/interesting.pdf
new file mode 100644
index 000000000..17f543455
--- /dev/null
+++ b/spec/fixtures/files/interesting.pdf
Binary files differ
diff --git a/spec/fixtures/holidays.yml b/spec/fixtures/holidays.yml
index 5a3d018bc..e6b8889c3 100644
--- a/spec/fixtures/holidays.yml
+++ b/spec/fixtures/holidays.yml
@@ -1,3 +1,12 @@
+# == Schema Information
+#
+# Table name: holidays
+#
+# id :integer not null, primary key
+# day :date
+# description :text
+#
+
date20071130:
id: '1'
day: '2007-11-30'
diff --git a/spec/fixtures/incoming_messages.yml b/spec/fixtures/incoming_messages.yml
index fca5c716c..0bf392be1 100644
--- a/spec/fixtures/incoming_messages.yml
+++ b/spec/fixtures/incoming_messages.yml
@@ -1,3 +1,25 @@
+# == Schema Information
+#
+# Table name: incoming_messages
+#
+# id :integer not null, primary key
+# info_request_id :integer not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# raw_email_id :integer not null
+# cached_attachment_text_clipped :text
+# cached_main_body_text_folded :text
+# cached_main_body_text_unfolded :text
+# subject :text
+# mail_from_domain :text
+# valid_to_reply_to :boolean
+# last_parsed :datetime
+# mail_from :text
+# sent_at :datetime
+# prominence :string(255) default("normal"), not null
+# prominence_reason :text
+#
+
useless_incoming_message:
id: 1
info_request_id: 101
diff --git a/spec/fixtures/info_request_events.yml b/spec/fixtures/info_request_events.yml
index 3907703d8..b2f40cc37 100644
--- a/spec/fixtures/info_request_events.yml
+++ b/spec/fixtures/info_request_events.yml
@@ -1,3 +1,20 @@
+# == Schema Information
+#
+# Table name: info_request_events
+#
+# id :integer not null, primary key
+# info_request_id :integer not null
+# event_type :text not null
+# params_yaml :text not null
+# created_at :datetime not null
+# described_state :string(255)
+# calculated_state :string(255)
+# last_described_at :datetime
+# incoming_message_id :integer
+# outgoing_message_id :integer
+# comment_id :integer
+#
+
useless_outgoing_message_event:
id: 900
params_yaml: "--- \n\
diff --git a/spec/fixtures/info_requests.yml b/spec/fixtures/info_requests.yml
index 97effd036..d64807a49 100644
--- a/spec/fixtures/info_requests.yml
+++ b/spec/fixtures/info_requests.yml
@@ -1,3 +1,27 @@
+# == Schema Information
+#
+# Table name: info_requests
+#
+# id :integer not null, primary key
+# title :text not null
+# user_id :integer
+# public_body_id :integer not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# described_state :string(255) not null
+# awaiting_description :boolean default(FALSE), not null
+# prominence :string(255) default("normal"), not null
+# url_title :text not null
+# law_used :string(255) default("foi"), not null
+# allow_new_responses_from :string(255) default("anybody"), not null
+# handle_rejected_responses :string(255) default("bounce"), not null
+# idhash :string(255) not null
+# external_user_name :string(255)
+# external_url :string(255)
+# attention_requested :boolean default(FALSE)
+# comments_allowed :boolean default(TRUE), not null
+#
+
fancy_dog_request:
id: 101
title: Why do you have & such a fancy dog?
diff --git a/spec/fixtures/locale/en/app.po b/spec/fixtures/locale/en/app.po
index ee5c8d9c8..6d5bca1f9 100644
--- a/spec/fixtures/locale/en/app.po
+++ b/spec/fixtures/locale/en/app.po
@@ -1417,10 +1417,6 @@ msgstr ""
msgid "InfoRequestEvent|Params yaml"
msgstr ""
-#: locale/model_attributes.rb:41
-msgid "InfoRequestEvent|Prominence"
-msgstr ""
-
#: locale/model_attributes.rb:102
msgid "InfoRequest|Allow new responses from"
msgstr ""
diff --git a/spec/fixtures/locale/en_GB/app.po b/spec/fixtures/locale/en_GB/app.po
index 84997a319..f106273a0 100644
--- a/spec/fixtures/locale/en_GB/app.po
+++ b/spec/fixtures/locale/en_GB/app.po
@@ -1417,10 +1417,6 @@ msgstr ""
msgid "InfoRequestEvent|Params yaml"
msgstr ""
-#: locale/model_attributes.rb:41
-msgid "InfoRequestEvent|Prominence"
-msgstr ""
-
#: locale/model_attributes.rb:102
msgid "InfoRequest|Allow new responses from"
msgstr ""
diff --git a/spec/fixtures/locale/es/app.po b/spec/fixtures/locale/es/app.po
index d45d9b3b1..2e0f4302a 100644
--- a/spec/fixtures/locale/es/app.po
+++ b/spec/fixtures/locale/es/app.po
@@ -1553,10 +1553,6 @@ msgstr "InfoRequestEvent|Last described at"
msgid "InfoRequestEvent|Params yaml"
msgstr "InfoRequestEvent|Params yaml"
-#: locale/model_attributes.rb:41
-msgid "InfoRequestEvent|Prominence"
-msgstr "InfoRequestEvent|Prominence"
-
#: locale/model_attributes.rb:102
msgid "InfoRequest|Allow new responses from"
msgstr "InfoRequest|Allow new responses from"
diff --git a/spec/fixtures/outgoing_messages.yml b/spec/fixtures/outgoing_messages.yml
index c71ee08bf..971ce0cc5 100644
--- a/spec/fixtures/outgoing_messages.yml
+++ b/spec/fixtures/outgoing_messages.yml
@@ -1,3 +1,19 @@
+# == Schema Information
+#
+# Table name: outgoing_messages
+#
+# id :integer not null, primary key
+# info_request_id :integer not null
+# body :text not null
+# status :string(255) not null
+# message_type :string(255) not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# last_sent_at :datetime
+# incoming_message_followup_id :integer
+# what_doing :string(255) not null
+#
+
useless_outgoing_message:
id: 1
info_request_id: 101
diff --git a/spec/fixtures/public_bodies.yml b/spec/fixtures/public_bodies.yml
index 6eae53db8..1fa016d3a 100644
--- a/spec/fixtures/public_bodies.yml
+++ b/spec/fixtures/public_bodies.yml
@@ -1,3 +1,26 @@
+# == Schema Information
+#
+# Table name: public_bodies
+#
+# id :integer not null, primary key
+# name :text not null
+# short_name :text not null
+# request_email :text not null
+# version :integer not null
+# last_edit_editor :string(255) not null
+# last_edit_comment :text not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# url_name :text not null
+# home_page :text default(""), not null
+# notes :text default(""), not null
+# first_letter :string(255) not null
+# publication_scheme :text default(""), not null
+# api_key :string(255) not null
+# info_requests_count :integer default(0), not null
+# disclosure_log :text default(""), not null
+#
+
geraldine_public_body:
name: The Geraldine Quango
first_letter: T
diff --git a/spec/fixtures/raw_emails.yml b/spec/fixtures/raw_emails.yml
index ad2bc0a63..efdadde7b 100644
--- a/spec/fixtures/raw_emails.yml
+++ b/spec/fixtures/raw_emails.yml
@@ -1,3 +1,10 @@
+# == Schema Information
+#
+# Table name: raw_emails
+#
+# id :integer not null, primary key
+#
+
# The actual email messages are in fixtures/files/raw_emails
#
# Note that the words "money" and "bob" are used in some tests
diff --git a/spec/fixtures/track_things.yml b/spec/fixtures/track_things.yml
index 1c4b323fd..61f1ed532 100644
--- a/spec/fixtures/track_things.yml
+++ b/spec/fixtures/track_things.yml
@@ -1,3 +1,19 @@
+# == Schema Information
+#
+# Table name: track_things
+#
+# id :integer not null, primary key
+# tracking_user_id :integer not null
+# track_query :string(255) not null
+# info_request_id :integer
+# tracked_user_id :integer
+# public_body_id :integer
+# track_medium :string(255) not null
+# track_type :string(255) default("internal_error"), not null
+# created_at :datetime
+# updated_at :datetime
+#
+
track_fancy_dog_request:
id: "10"
track_query: request:why_do_you_have_such_a_fancy_dog
diff --git a/spec/fixtures/users.yml b/spec/fixtures/users.yml
index c9730d855..d996fd31e 100644
--- a/spec/fixtures/users.yml
+++ b/spec/fixtures/users.yml
@@ -1,3 +1,29 @@
+# == Schema Information
+#
+# Table name: users
+#
+# id :integer not null, primary key
+# email :string(255) not null
+# name :string(255) not null
+# hashed_password :string(255) not null
+# salt :string(255) not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# email_confirmed :boolean default(FALSE), not null
+# url_name :text not null
+# last_daily_track_email :datetime default(2000-01-01 00:00:00 UTC)
+# admin_level :string(255) default("none"), not null
+# ban_text :text default(""), not null
+# about_me :text default(""), not null
+# locale :string(255)
+# email_bounced_at :datetime
+# email_bounce_message :text default(""), not null
+# no_limit :boolean default(FALSE), not null
+# receive_email_alerts :boolean default(TRUE), not null
+# address :string(255)
+# dob :date
+#
+
bob_smith_user:
id: "1"
name: Bob Smith
diff --git a/spec/integration/admin_spec.rb b/spec/integration/admin_spec.rb
index 8a5e59ba2..8e6351d2c 100644
--- a/spec/integration/admin_spec.rb
+++ b/spec/integration/admin_spec.rb
@@ -1,21 +1,74 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
-
-require "base64"
+require File.expand_path(File.dirname(__FILE__) + '/alaveteli_dsl')
describe "When administering the site" do
+
+ before do
+ AlaveteliConfiguration.stub!(:skip_admin_auth).and_return(false)
+ end
+
it "allows an admin to log in as another user" do
# First log in as Joe Admin
- admin_user = users(:admin_user)
- admin_user.email_confirmed = true
- admin_user.save!
- post_via_redirect "/profile/sign_in", :user_signin => {:email => admin_user.email, :password => "jonespassword"}
- response.should be_success
-
+ confirm(:admin_user)
+ admin = login(:admin_user)
+
# Now fetch the "log in as" link to log in as Bob
- get_via_redirect "/admin/user/login_as/#{users(:bob_smith_user).id}", nil, {
- "Authorization" => "Basic " + Base64.encode64("#{AlaveteliConfiguration::admin_username}:#{AlaveteliConfiguration::admin_password}").strip
- }
- response.should be_success
- session[:user_id].should == users(:bob_smith_user).id
+ admin.get_via_redirect "/en/admin/user/login_as/#{users(:bob_smith_user).id}"
+ admin.response.should be_success
+ admin.session[:user_id].should == users(:bob_smith_user).id
+ end
+
+ it 'does not allow a non-admin user to login as another user' do
+ robin = login(:robin_user)
+ robin.get_via_redirect "/en/admin/user/login_as/#{users(:bob_smith_user).id}"
+ robin.response.should be_success
+ robin.session[:user_id].should_not == users(:bob_smith_user).id
+ end
+
+ it "allows redelivery of an incoming message to a closed request" do
+ confirm(:admin_user)
+ admin = login(:admin_user)
+ ir = info_requests(:fancy_dog_request)
+ close_request(ir)
+ InfoRequest.holding_pen_request.incoming_messages.length.should == 0
+ ir.incoming_messages.length.should == 1
+ receive_incoming_mail('incoming-request-plain.email', ir.incoming_email, "frob@nowhere.com")
+ InfoRequest.holding_pen_request.incoming_messages.length.should == 1
+ new_im = InfoRequest.holding_pen_request.incoming_messages[0]
+ ir.incoming_messages.length.should == 1
+ post_params = {'redeliver_incoming_message_id' => new_im.id,
+ 'url_title' => ir.url_title}
+ admin.post '/en/admin/incoming/redeliver', post_params
+ admin.response.location.should == 'http://www.example.com/en/admin/request/show/101'
+ ir = InfoRequest.find_by_url_title(ir.url_title)
+ ir.incoming_messages.length.should == 2
+
+ InfoRequest.holding_pen_request.incoming_messages.length.should == 0
+ end
+
+ it "allows redelivery of an incoming message to more than one request" do
+ confirm(:admin_user)
+ admin = login(:admin_user)
+
+ ir1 = info_requests(:fancy_dog_request)
+ close_request(ir1)
+ ir1.incoming_messages.length.should == 1
+ ir2 = info_requests(:another_boring_request)
+ ir2.incoming_messages.length.should == 1
+
+ receive_incoming_mail('incoming-request-plain.email', ir1.incoming_email, "frob@nowhere.com")
+ InfoRequest.holding_pen_request.incoming_messages.length.should == 1
+
+ new_im = InfoRequest.holding_pen_request.incoming_messages[0]
+ post_params = {'redeliver_incoming_message_id' => new_im.id,
+ 'url_title' => "#{ir1.url_title},#{ir2.url_title}"}
+ admin.post '/en/admin/incoming/redeliver', post_params
+ ir1.reload
+ ir1.incoming_messages.length.should == 2
+ ir2.reload
+ ir2.incoming_messages.length.should == 2
+ admin.response.location.should == 'http://www.example.com/en/admin/request/show/106'
+ InfoRequest.holding_pen_request.incoming_messages.length.should == 0
end
+
end
diff --git a/spec/integration/alaveteli_dsl.rb b/spec/integration/alaveteli_dsl.rb
new file mode 100644
index 000000000..119bb05a0
--- /dev/null
+++ b/spec/integration/alaveteli_dsl.rb
@@ -0,0 +1,68 @@
+module AlaveteliDsl
+
+ def browses_request(url_title)
+ get "/request/#{url_title}"
+ assert_response :success
+ end
+
+ def creates_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")
+ response.body.should match(/To send your FOI request, please sign in or make a new account./)
+ end
+
+end
+
+def login(user)
+ open_session do |sess|
+ # Make sure we get a fresh empty session - there seems to be some
+ # problem with session leakage otherwise
+ sess.reset!
+ sess.extend(AlaveteliDsl)
+
+ if user.is_a? User
+ u = user
+ else
+ u = users(user)
+ end
+ sess.visit signin_path
+ sess.fill_in "Your e-mail:", :with => u.email
+ sess.fill_in "Password:", :with => "jonespassword"
+ sess.click_button "Sign in"
+ assert sess.session[:user_id] == u.id
+ end
+end
+
+def without_login
+ open_session do |sess|
+ sess.extend(AlaveteliDsl)
+ end
+end
+
+def confirm(user)
+ u = users(user)
+ u.email_confirmed = true
+ u.save!
+end
+
+def close_request(request)
+ request.allow_new_responses_from = 'nobody'
+ request.handle_rejected_responses = 'holding_pen'
+ request.save!
+end
+
+
+
diff --git a/spec/integration/create_request_spec.rb b/spec/integration/create_request_spec.rb
index 4efbf94ee..84fad12f9 100644
--- a/spec/integration/create_request_spec.rb
+++ b/spec/integration/create_request_spec.rb
@@ -1,51 +1,36 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+require File.expand_path(File.dirname(__FILE__) + '/alaveteli_dsl')
describe "When creating requests" do
- 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")
- 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
+
+ unregistered = without_login
# This is a test for https://github.com/mysociety/alaveteli/issues/446
- create_request_unregistered
+ unregistered.creates_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
+ unregistered.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.
- response.should render_template("user/confirm")
+ unregistered.response.body.should match('Now check your email!')
post_redirect = PostRedirect.get_last_post_redirect
+
# Now log in as an admin user, then follow the confirmation link in the email that was sent to the unconfirmed user
- admin_user = users(:admin_user)
- admin_user.email_confirmed = true
- admin_user.save!
- post_via_redirect "/profile/sign_in", :user_signin => {:email => admin_user.email, :password => "jonespassword"}
- response.should be_success
- get "/c/" + post_redirect.email_token
- follow_redirect!
- response.location.should =~ %r(/request/(.+)/new)
- response.location =~ %r(/request/(.+)/new)
+ confirm(:admin_user)
+ admin = login(:admin_user)
+ admin.get "/c/" + post_redirect.email_token
+ admin.follow_redirect!
+ admin.response.location.should =~ %r(/request/(.+)/new)
+ admin.response.location =~ %r(/request/(.+)/new)
url_title = $1
info_request = InfoRequest.find_by_url_title(url_title)
info_request.should_not be_nil
# Make sure the request is still owned by the user who made it, not the admin who confirmed it
info_request.user_id.should == users(:unconfirmed_user).id
+
end
end
diff --git a/spec/integration/download_request_spec.rb b/spec/integration/download_request_spec.rb
new file mode 100644
index 000000000..638198cde
--- /dev/null
+++ b/spec/integration/download_request_spec.rb
@@ -0,0 +1,324 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+require File.expand_path(File.dirname(__FILE__) + '/alaveteli_dsl')
+
+describe 'when making a zipfile available' do
+
+ after do
+ FileUtils.rm_rf(InfoRequest.download_zip_dir)
+ end
+
+ def inspect_zip_download(session, info_request)
+ session.get_via_redirect "request/#{info_request.url_title}/download"
+ session.response.should be_success
+ Tempfile.open('download') do |f|
+ f.binmode
+ f.write(session.response.body)
+ f.flush
+ Zip::ZipFile::open(f.path) do |zip|
+ yield zip
+ end
+ end
+ end
+
+ def sleep_and_receive_mail(name, info_request)
+ # The path of the zip file is based on the hash of the timestamp of the last request
+ # in the thread, so we wait for a second to make sure this one will have a different
+ # timestamp than the previous.
+ sleep 1
+ receive_incoming_mail(name, info_request.incoming_email)
+ end
+
+ context 'when an html to pdf converter is supplied' do
+
+ before do
+ # We want to test the contents of the pdf, and we don't know whether a particular
+ # instance will have a working html_to_pdf tool, so just copy the HTML rendered
+ # to the PDF file for the purposes of checking it doesn't contain anything that
+ # shouldn't be there.
+ AlaveteliConfiguration.stub!(:html_to_pdf_command).and_return('/bin/cp')
+ end
+
+ context 'when an incoming message is made "requester_only"' do
+
+ it 'should not include the incoming message or attachments in a download of the entire request
+ by a non-request owner but should retain them for owner and admin' do
+
+ # Non-owner can download zip with incoming and attachments
+ non_owner = login(FactoryGirl.create(:user))
+ info_request = FactoryGirl.create(:info_request_with_incoming_attachments)
+
+ inspect_zip_download(non_owner, info_request) do |zip|
+ zip.count.should == 3
+ zip.read('correspondence.pdf').should match('hereisthetext')
+ end
+
+ # Admin makes the incoming message requester only
+ admin = login(FactoryGirl.create(:admin_user))
+ post_data = {:incoming_message => {:prominence => 'requester_only',
+ :prominence_reason => 'boring'}}
+ admin.post_via_redirect "/en/admin/incoming/update/#{info_request.incoming_messages.first.id}", post_data
+ admin.response.should be_success
+
+ # Admin retains the requester only things
+ inspect_zip_download(admin, info_request) do |zip|
+ zip.count.should == 3
+ zip.read('correspondence.pdf').should match('hereisthetext')
+ end
+
+ # Zip for non owner is now without requester_only things
+ inspect_zip_download(non_owner, info_request) do |zip|
+ zip.count.should == 1
+ correspondence_text = zip.read('correspondence.pdf')
+ correspondence_text.should_not match('hereisthetext')
+ expected_text = "This message has been hidden.\n boring"
+ correspondence_text.should match(expected_text)
+ end
+
+ # Requester retains the requester only things
+ owner = login(info_request.user)
+ inspect_zip_download(owner, info_request) do |zip|
+ zip.count.should == 3
+ zip.read('correspondence.pdf').should match('hereisthetext')
+ end
+
+ end
+
+ end
+
+ context 'when an outgoing message is made "requester_only"' do
+
+ it 'should not include the outgoing message in a download of the entire request
+ by a non-request owner but should retain them for owner and admin' do
+
+ # Non-owner can download zip with outgoing
+ non_owner = login(FactoryGirl.create(:user))
+ info_request = FactoryGirl.create(:info_request)
+
+ inspect_zip_download(non_owner, info_request) do |zip|
+ zip.count.should == 1
+ zip.read('correspondence.pdf').should match('Some information please')
+ end
+
+ # Admin makes the incoming message requester only
+ admin = login(FactoryGirl.create(:admin_user))
+ post_data = {:outgoing_message => {:prominence => 'requester_only',
+ :prominence_reason => 'boring',
+ :body => 'Some information please'}}
+ admin.post_via_redirect "/en/admin/outgoing/update/#{info_request.outgoing_messages.first.id}", post_data
+ admin.response.should be_success
+
+ # Admin retains the requester only things
+ inspect_zip_download(admin, info_request) do |zip|
+ zip.count.should == 1
+ zip.read('correspondence.pdf').should match('Some information please')
+ end
+
+ # Zip for non owner is now without requester_only things
+ inspect_zip_download(non_owner, info_request) do |zip|
+ zip.count.should == 1
+ correspondence_text = zip.read('correspondence.pdf')
+ correspondence_text.should_not match('Some information please')
+ expected_text = "This message has been hidden.\n boring"
+ correspondence_text.should match(expected_text)
+ end
+
+ # Requester retains the requester only things
+ owner = login(info_request.user)
+ inspect_zip_download(owner, info_request) do |zip|
+ zip.count.should == 1
+ zip.read('correspondence.pdf').should match('Some information please')
+ end
+
+ end
+
+ end
+
+ end
+
+ context 'when no html to pdf converter is supplied' do
+
+ before do
+ AlaveteliConfiguration.stub!(:html_to_pdf_command).and_return('')
+ end
+
+ it "should update the contents of the zipfile when the request changes" do
+
+ info_request = FactoryGirl.create(:info_request_with_incoming)
+ request_owner = login(info_request.user)
+ inspect_zip_download(request_owner, info_request) do |zip|
+ zip.count.should == 1 # just the message
+ expected = 'This is a plain-text version of the Freedom of Information request "Example Title"'
+ zip.read('correspondence.txt').should match expected
+ end
+
+ sleep_and_receive_mail('incoming-request-two-same-name.email', info_request)
+
+ inspect_zip_download(request_owner, info_request) do |zip|
+ zip.count.should == 3 # the message plus two "hello-world.txt" files
+ zip.read('2_2_hello world.txt').should match('Second hello')
+ zip.read('2_3_hello world.txt').should match('First hello')
+ end
+
+ sleep_and_receive_mail('incoming-request-attachment-unknown-extension.email', info_request)
+
+ inspect_zip_download(request_owner, info_request) do |zip|
+ zip.count.should == 4 # the message plus two "hello-world.txt" files, and the new attachment
+ zip.read('3_2_hello.qwglhm').should match('This is an unusual')
+ end
+ end
+
+ context 'when a request is "requester_only"' do
+
+ before do
+ @non_owner = login(FactoryGirl.create(:user))
+ @info_request = FactoryGirl.create(:info_request_with_incoming,
+ :prominence => 'requester_only')
+ @request_owner = login(@info_request.user)
+ @admin = login(FactoryGirl.create(:admin_user))
+ end
+
+
+ it 'should allow a download of the request by the request owner and admin only' do
+ # Requester can access the zip
+ inspect_zip_download(@request_owner, @info_request) do |zip|
+ zip.count.should == 1
+ zip.read('correspondence.txt').should match('hereisthetext')
+ end
+ # Non-owner can't
+ @non_owner.get_via_redirect "request/#{@info_request.url_title}/download"
+ @non_owner.response.code.should == '403'
+ # Admin can
+ inspect_zip_download(@admin, @info_request) do |zip|
+ zip.count.should == 1
+ zip.read('correspondence.txt').should match('hereisthetext')
+ end
+ end
+ end
+
+ context 'when a request is "hidden"' do
+
+ it 'should not allow a download of the request by an admin only' do
+ @non_owner = login(FactoryGirl.create(:user))
+ @info_request = FactoryGirl.create(:info_request_with_incoming,
+ :prominence => 'hidden')
+ @request_owner = login(@info_request.user)
+ @admin = login(FactoryGirl.create(:admin_user))
+
+ # Requester can't access the zip
+ @request_owner.get_via_redirect "request/#{@info_request.url_title}/download"
+ @request_owner.response.code.should == '403'
+ # Non-owner can't
+ @non_owner.get_via_redirect "request/#{@info_request.url_title}/download"
+ @non_owner.response.code.should == '403'
+ # Admin can
+ inspect_zip_download(@admin, @info_request) do |zip|
+ zip.count.should == 1
+ zip.read('correspondence.txt').should match('hereisthetext')
+ end
+ end
+
+ end
+
+ context 'when an incoming message is made "requester_only"' do
+
+ it 'should not include the incoming message or attachments in a download of the entire request
+ by a non-request owner but should retain them for owner and admin' do
+
+ # Non-owner can download zip with outgoing
+ non_owner = login(FactoryGirl.create(:user))
+ info_request = FactoryGirl.create(:info_request_with_incoming_attachments)
+
+ inspect_zip_download(non_owner, info_request) do |zip|
+ zip.count.should == 3
+ zip.read('correspondence.txt').should match('hereisthetext')
+ end
+
+ # Admin makes the incoming message requester only
+ admin = login(FactoryGirl.create(:admin_user))
+ post_data = {:incoming_message => {:prominence => 'requester_only',
+ :prominence_reason => 'boring'}}
+ admin.post_via_redirect "/en/admin/incoming/update/#{info_request.incoming_messages.first.id}", post_data
+ admin.response.should be_success
+
+ # Admin retains the requester only things
+ inspect_zip_download(admin, info_request) do |zip|
+ zip.count.should == 3
+ zip.read('correspondence.txt').should match('hereisthetext')
+ end
+
+ # Zip for non owner is now without requester_only things
+ inspect_zip_download(non_owner, info_request) do |zip|
+ zip.count.should == 1
+ correspondence_text = zip.read('correspondence.txt')
+ correspondence_text.should_not match('hereisthetext')
+ expected_text = 'This message has been hidden. boring'
+ correspondence_text.should match(expected_text)
+ end
+
+ # Requester retains the requester only things
+ owner = login(info_request.user)
+ inspect_zip_download(owner, info_request) do |zip|
+ zip.count.should == 3
+ zip.read('correspondence.txt').should match('hereisthetext')
+ end
+
+ end
+
+ end
+
+ context 'when an outgoing message is made "requester_only"' do
+
+ it 'should not include the outgoing message in a download of the entire request
+ by a non-request owner but should retain them for owner and admin' do
+
+ # Non-owner can download zip with incoming and attachments
+ non_owner = login(FactoryGirl.create(:user))
+ info_request = FactoryGirl.create(:info_request)
+
+ inspect_zip_download(non_owner, info_request) do |zip|
+ zip.count.should == 1
+ zip.read('correspondence.txt').should match('Some information please')
+ end
+
+ # Admin makes the incoming message requester only
+ admin = login(FactoryGirl.create(:admin_user))
+ post_data = {:outgoing_message => {:prominence => 'requester_only',
+ :prominence_reason => 'boring',
+ :body => 'Some information please'}}
+ admin.post_via_redirect "/en/admin/outgoing/update/#{info_request.outgoing_messages.first.id}", post_data
+ admin.response.should be_success
+
+ # Admin retains the requester only things
+ inspect_zip_download(admin, info_request) do |zip|
+ zip.count.should == 1
+ zip.read('correspondence.txt').should match('Some information please')
+ end
+
+ # Zip for non owner is now without requester_only things
+ inspect_zip_download(non_owner, info_request) do |zip|
+ zip.count.should == 1
+ correspondence_text = zip.read('correspondence.txt')
+ correspondence_text.should_not match('Some information please')
+ expected_text = 'This message has been hidden. boring'
+ correspondence_text.should match(expected_text)
+ end
+
+ # Requester retains the requester only things
+ owner = login(info_request.user)
+ inspect_zip_download(owner, info_request) do |zip|
+ zip.count.should == 1
+ zip.read('correspondence.txt').should match('Some information please')
+ end
+
+ end
+
+ end
+
+ it 'should successfully make a zipfile for an external request' do
+ external_request = FactoryGirl.create(:external_request)
+ user = login(FactoryGirl.create(:user))
+ inspect_zip_download(user, external_request){ |zip| zip.count.should == 1 }
+ end
+ end
+
+end
diff --git a/spec/integration/request_controller_spec.rb b/spec/integration/request_controller_spec.rb
index 9e585448b..f5de692b8 100644
--- a/spec/integration/request_controller_spec.rb
+++ b/spec/integration/request_controller_spec.rb
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+require File.expand_path(File.dirname(__FILE__) + '/alaveteli_dsl')
describe RequestController, "when classifying an information request" do
@@ -16,26 +17,22 @@ describe RequestController, "when classifying an information request" do
describe 'when logged in as the requestor' do
before :each do
- @request_owner = @dog_request.user
- visit signin_path
- fill_in "Your e-mail:", :with => @request_owner.email
- fill_in "Password:", :with => "jonespassword"
- click_button "Sign in"
+ @bob = login(:bob_smith_user)
end
it "should send an email including the message" do
- visit describe_state_message_path(:url_title => @dog_request.url_title,
+ @bob.visit describe_state_message_path(:url_title => @dog_request.url_title,
:described_state => "requires_admin")
- fill_in "Please tell us more:", :with => "Okay. I don't quite understand."
- click_button "Submit status and send message"
+ @bob.fill_in "Please tell us more:", :with => "Okay. I don't quite understand."
+ @bob.click_button "Submit status and send message"
- response.should contain "Thank you! We'll look into what happened and try and fix it up."
+ @bob.response.should contain "Thank you! We'll look into what happened and try and fix it up."
deliveries = ActionMailer::Base.deliveries
deliveries.size.should == 1
mail = deliveries[0]
mail.body.should =~ /as needing admin/
- mail.body.should =~ /Okay. I don't quite understand./
+ mail.body.should =~ /Okay. I don't quite understand./
end
end
end
diff --git a/spec/integration/view_request_spec.rb b/spec/integration/view_request_spec.rb
index 3d646cfe7..814e20fb3 100644
--- a/spec/integration/view_request_spec.rb
+++ b/spec/integration/view_request_spec.rb
@@ -1,23 +1,169 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+require File.expand_path(File.dirname(__FILE__) + '/alaveteli_dsl')
describe "When viewing requests" do
- before(:each) do
- load_raw_emails_data
+ before do
+ @info_request = FactoryGirl.create(:info_request)
+ @unregistered = without_login
end
it "should not make endlessly recursive JSON <link>s" do
- @dog_request = info_requests(:fancy_dog_request)
- get "request/#{@dog_request.url_title}?unfold=1"
- response.body.should_not include("dog?unfold=1.json")
- response.body.should include("dog.json?unfold=1")
+ @unregistered.browses_request("#{@info_request.url_title}?unfold=1")
+ @unregistered.response.body.should_not include("#{@info_request.url_title}?unfold=1.json")
+ @unregistered.response.body.should include("#{@info_request.url_title}.json?unfold=1")
end
it 'should not raise a routing error when making a json link for a request with an
"action" querystring param' do
- @dog_request = info_requests(:fancy_dog_request)
- get "request/#{@dog_request.url_title}?action=add"
- response.should be_success
+ @unregistered.browses_request("#{@info_request.url_title}?action=add")
+ end
+
+ context 'when a response has prominence "normal"' do
+
+ before do
+ @info_request = FactoryGirl.create(:info_request_with_incoming)
+ end
+
+ it 'should show the message itself to any user' do
+
+ # unregistered
+ unregistered = without_login
+ unregistered.browses_request(@info_request.url_title)
+ unregistered.response.body.should include("hereisthetext")
+ unregistered.response.body.should_not include("This message has been hidden.")
+ unregistered.response.body.should_not include("sign in</a> to view the message.")
+
+ # requester
+ owner = login(@info_request.user)
+ owner.browses_request(@info_request.url_title)
+ owner.response.body.should include("hereisthetext")
+ owner.response.body.should_not include("This message has been hidden.")
+
+ # admin
+ admin_user = login(FactoryGirl.create(:admin_user))
+ admin_user.browses_request(@info_request.url_title)
+ admin_user.response.body.should include("hereisthetext")
+ admin_user.response.body.should_not include("This message has prominence \'hidden\'.")
+
+ end
+
+ end
+
+ context 'when a response has prominence "hidden"' do
+
+ before do
+ @info_request = FactoryGirl.create(:info_request_with_incoming)
+ message = @info_request.incoming_messages.first
+ message.prominence = 'hidden'
+ message.prominence_reason = 'It is too irritating.'
+ message.save!
+ end
+
+ it 'should show a hidden notice, not the message, to an unregistered user or the requester and
+ the message itself to an admin ' do
+
+ # unregistered
+ unregistered = without_login
+ unregistered.browses_request(@info_request.url_title)
+ unregistered.response.body.should include("This message has been hidden.")
+ unregistered.response.body.should include("It is too irritating.")
+ unregistered.response.body.should_not include("sign in</a> to view the message.")
+ unregistered.response.body.should_not include("hereisthetext")
+
+ # requester
+ owner = login(@info_request.user)
+ owner.browses_request(@info_request.url_title)
+ owner.response.body.should include("This message has been hidden.")
+ owner.response.body.should include("It is too irritating")
+ owner.response.body.should_not include("hereisthetext")
+
+ # admin
+ admin_user = login(FactoryGirl.create(:admin_user))
+ admin_user.browses_request(@info_request.url_title)
+ admin_user.response.body.should include('hereisthetext')
+ admin_user.response.body.should include("This message has prominence \'hidden\'.")
+ admin_user.response.body.should include("It is too irritating.")
+ admin_user.response.body.should include("You can only see it because you are logged in as a super user.")
+
+ end
+
+ end
+
+ context 'when a response has prominence "requester_only"' do
+
+ before do
+ @info_request = FactoryGirl.create(:info_request_with_incoming)
+ message = @info_request.incoming_messages.first
+ message.prominence = 'requester_only'
+ message.prominence_reason = 'It is too irritating.'
+ message.save!
+ end
+
+ it 'should show a hidden notice with login link to an unregistered user, and the message itself
+ with a hidden note to the requester or an admin' do
+
+ # unregistered
+ unregistered = without_login
+ unregistered.browses_request(@info_request.url_title)
+ unregistered.response.body.should include("This message has been hidden.")
+ unregistered.response.body.should include("It is too irritating")
+ unregistered.response.body.should include("sign in</a> to view the message.")
+ unregistered.response.body.should_not include("hereisthetext")
+
+ # requester
+ owner = login(@info_request.user)
+ owner.browses_request(@info_request.url_title)
+ owner.response.body.should include("hereisthetext")
+ owner.response.body.should include("This message is hidden, so that only you, the requester, can see it.")
+ owner.response.body.should include("It is too irritating.")
+
+ # admin
+ admin_user = login(FactoryGirl.create(:admin_user))
+ admin_user.browses_request(@info_request.url_title)
+ admin_user.response.body.should include('hereisthetext')
+ admin_user.response.body.should_not include("This message has been hidden.")
+ admin_user.response.body.should include("This message is hidden, so that only you, the requester, can see it.")
+ end
+
+ end
+
+ context 'when an outgoing message has prominence "requester_only"' do
+
+ before do
+ @info_request = FactoryGirl.create(:info_request)
+ message = @info_request.outgoing_messages.first
+ message.prominence = 'requester_only'
+ message.prominence_reason = 'It is too irritating.'
+ message.save!
+ end
+
+ it 'should show a hidden notice with login link to an unregistered user, and the message itself
+ with a hidden note to the requester or an admin' do
+
+ # unregistered
+ unregistered = without_login
+ unregistered.browses_request(@info_request.url_title)
+ unregistered.response.body.should include("This message has been hidden.")
+ unregistered.response.body.should include("It is too irritating")
+ unregistered.response.body.should include("sign in</a> to view the message.")
+ unregistered.response.body.should_not include("Some information please")
+
+ # requester
+ owner = login(@info_request.user)
+ owner.browses_request(@info_request.url_title)
+ owner.response.body.should include("Some information please")
+ owner.response.body.should include("This message is hidden, so that only you, the requester, can see it.")
+ owner.response.body.should include("It is too irritating.")
+
+ # admin
+ admin_user = login(FactoryGirl.create(:admin_user))
+ admin_user.browses_request(@info_request.url_title)
+ admin_user.response.body.should include('Some information please')
+ admin_user.response.body.should_not include("This message has been hidden.")
+ admin_user.response.body.should include("This message is hidden, so that only you, the requester, can see it.")
+ end
+
end
end
diff --git a/spec/mailers/request_mailer_spec.rb b/spec/mailers/request_mailer_spec.rb
index 23806b35b..4e0765921 100644
--- a/spec/mailers/request_mailer_spec.rb
+++ b/spec/mailers/request_mailer_spec.rb
@@ -204,10 +204,10 @@ describe RequestMailer, "when sending reminders to requesters to classify a resp
before do
Time.stub!(:now).and_return(Time.utc(2007, 11, 12, 23, 59))
@mock_event = mock_model(InfoRequestEvent)
- @mock_response = mock_model(IncomingMessage)
+ @mock_response = mock_model(IncomingMessage, :user_can_view? => true)
@mock_user = mock_model(User)
- @mock_request = mock_model(InfoRequest, :get_last_response_event_id => @mock_event.id,
- :get_last_response => @mock_response,
+ @mock_request = mock_model(InfoRequest, :get_last_public_response_event_id => @mock_event.id,
+ :get_last_public_response => @mock_response,
:user_id => 2,
:url_title => 'test_title',
:user => @mock_user)
@@ -230,10 +230,12 @@ describe RequestMailer, "when sending reminders to requesters to classify a resp
it 'should ask for all requests that are awaiting description and whose latest response is older
than the number of days given and that are not the holding pen' do
expected_conditions = [ "awaiting_description = ?
- AND (SELECT created_at
- FROM info_request_events
- WHERE info_request_events.info_request_id = info_requests.id
- AND info_request_events.event_type = 'response'
+ AND (SELECT info_request_events.created_at
+ FROM info_request_events, incoming_messages
+ WHERE info_request_events.info_request_id = info_requests.id
+ AND info_request_events.event_type = 'response'
+ AND incoming_messages.id = info_request_events.incoming_message_id
+ AND incoming_messages.prominence = 'normal'
ORDER BY created_at desc LIMIT 1) < ?
AND url_title != 'holding_pen'
AND user_id IS NOT NULL".split(' ').join(' '),
@@ -252,7 +254,7 @@ describe RequestMailer, "when sending reminders to requesters to classify a resp
end
it 'should raise an error if a request does not have a last response event id' do
- @mock_request.stub!(:get_last_response_event_id).and_return(nil)
+ @mock_request.stub!(:get_last_public_response_event_id).and_return(nil)
expected_message = "internal error, no last response while making alert new response reminder, request id #{@mock_request.id}"
lambda{ send_alerts }.should raise_error(expected_message)
end
@@ -289,7 +291,7 @@ describe RequestMailer, "when sending reminders to requesters to classify a resp
mock_sent_alert.should_receive(:info_request=).with(@mock_request)
mock_sent_alert.should_receive(:user=).with(@mock_user)
mock_sent_alert.should_receive(:alert_type=).with('new_response_reminder_1')
- mock_sent_alert.should_receive(:info_request_event_id=).with(@mock_request.get_last_response_event_id)
+ mock_sent_alert.should_receive(:info_request_event_id=).with(@mock_request.get_last_public_response_event_id)
mock_sent_alert.should_receive(:save!)
send_alerts
end
diff --git a/spec/models/censor_rule_spec.rb b/spec/models/censor_rule_spec.rb
index 3782cc630..5b41cc0d4 100644
--- a/spec/models/censor_rule_spec.rb
+++ b/spec/models/censor_rule_spec.rb
@@ -1,3 +1,20 @@
+# == Schema Information
+#
+# Table name: censor_rules
+#
+# id :integer not null, primary key
+# info_request_id :integer
+# user_id :integer
+# public_body_id :integer
+# text :text not null
+# replacement :text not null
+# last_edit_editor :string(255) not null
+# last_edit_comment :text not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# regexp :boolean
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe CensorRule, "substituting things" do
diff --git a/spec/models/foi_attachment_spec.rb b/spec/models/foi_attachment_spec.rb
index 9b0115c44..882723d1e 100644
--- a/spec/models/foi_attachment_spec.rb
+++ b/spec/models/foi_attachment_spec.rb
@@ -1,3 +1,18 @@
+# == Schema Information
+#
+# Table name: foi_attachments
+#
+# id :integer not null, primary key
+# content_type :text
+# filename :text
+# charset :text
+# display_size :text
+# url_part_number :integer
+# within_rfc822_subject :text
+# incoming_message_id :integer
+# hexdigest :string(32)
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe FoiAttachment do
diff --git a/spec/models/holiday_spec.rb b/spec/models/holiday_spec.rb
index 5d3f76d24..89849abb7 100644
--- a/spec/models/holiday_spec.rb
+++ b/spec/models/holiday_spec.rb
@@ -1,3 +1,12 @@
+# == Schema Information
+#
+# Table name: holidays
+#
+# id :integer not null, primary key
+# day :date
+# description :text
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe Holiday, " when calculating due date" do
diff --git a/spec/models/incoming_message_spec.rb b/spec/models/incoming_message_spec.rb
index ff6a8e34e..c0a7e5340 100644
--- a/spec/models/incoming_message_spec.rb
+++ b/spec/models/incoming_message_spec.rb
@@ -1,6 +1,140 @@
# coding: utf-8
+# == Schema Information
+#
+# Table name: incoming_messages
+#
+# id :integer not null, primary key
+# info_request_id :integer not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# raw_email_id :integer not null
+# cached_attachment_text_clipped :text
+# cached_main_body_text_folded :text
+# cached_main_body_text_unfolded :text
+# subject :text
+# mail_from_domain :text
+# valid_to_reply_to :boolean
+# last_parsed :datetime
+# mail_from :text
+# sent_at :datetime
+# prominence :string(255) default("normal"), not null
+# prominence_reason :text
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+describe IncomingMessage, 'when validating' do
+
+ it 'should be valid with valid prominence values' do
+ ['hidden', 'requester_only', 'normal'].each do |prominence|
+ incoming_message = IncomingMessage.new(:raw_email => RawEmail.new,
+ :info_request => InfoRequest.new,
+ :prominence => prominence)
+ incoming_message.valid?.should be_true
+ end
+ end
+
+ it 'should not be valid with an invalid prominence value' do
+ incoming_message = IncomingMessage.new(:raw_email => RawEmail.new,
+ :info_request => InfoRequest.new,
+ :prominence => 'norman')
+ incoming_message.valid?.should be_false
+ end
+
+end
+
+describe IncomingMessage, 'when getting a response event' do
+
+ it 'should return an event with event_type "response"' do
+ incoming_message = IncomingMessage.new
+ ['comment', 'response'].each do |event_type|
+ incoming_message.info_request_events << InfoRequestEvent.new(:event_type => event_type)
+ end
+ incoming_message.response_event.event_type.should == 'response'
+ end
+
+end
+
+describe IncomingMessage, 'when asked if a user can view it' do
+
+ before do
+ @user = mock_model(User)
+ @info_request = mock_model(InfoRequest)
+ @incoming_message = IncomingMessage.new(:info_request => @info_request)
+ end
+
+ context 'if the prominence is hidden' do
+
+ before do
+ @incoming_message.prominence = 'hidden'
+ end
+
+ it 'should return true if the user can view hidden things' do
+ User.stub!(:view_hidden?).with(@user).and_return(true)
+ @incoming_message.user_can_view?(@user).should be_true
+ end
+
+ it 'should return false if the user cannot view hidden things' do
+ User.stub!(:view_hidden?).with(@user).and_return(false)
+ @incoming_message.user_can_view?(@user).should be_false
+ end
+
+ end
+
+ context 'if the prominence is requester_only' do
+
+ before do
+ @incoming_message.prominence = 'requester_only'
+ end
+
+ it 'should return true if the user owns the associated request' do
+ @info_request.stub!(:is_owning_user?).with(@user).and_return(true)
+ @incoming_message.user_can_view?(@user).should be_true
+ end
+
+ it 'should return false if the user does not own the associated request' do
+ @info_request.stub!(:is_owning_user?).with(@user).and_return(false)
+ @incoming_message.user_can_view?(@user).should be_false
+ end
+ end
+
+ context 'if the prominence is normal' do
+
+ before do
+ @incoming_message.prominence = 'normal'
+ end
+
+ it 'should return true' do
+ @incoming_message.user_can_view?(@user).should be_true
+ end
+
+ end
+
+end
+
+describe 'when asked if it is indexed by search' do
+
+ before do
+ @incoming_message = IncomingMessage.new
+ end
+
+ it 'should return false if it has prominence "hidden"' do
+ @incoming_message.prominence = 'hidden'
+ @incoming_message.indexed_by_search?.should be_false
+ end
+
+ it 'should return false if it has prominence "requester_only"' do
+ @incoming_message.prominence = 'requester_only'
+ @incoming_message.indexed_by_search?.should be_false
+ end
+
+ it 'should return true if it has prominence "normal"' do
+ @incoming_message.prominence = 'normal'
+ @incoming_message.indexed_by_search?.should be_true
+ end
+
+end
+
describe IncomingMessage, " when dealing with incoming mail" do
before(:each) do
diff --git a/spec/models/info_request_event_spec.rb b/spec/models/info_request_event_spec.rb
index eb0de8c86..53c83bd46 100644
--- a/spec/models/info_request_event_spec.rb
+++ b/spec/models/info_request_event_spec.rb
@@ -1,4 +1,21 @@
# coding: utf-8
+# == Schema Information
+#
+# Table name: info_request_events
+#
+# id :integer not null, primary key
+# info_request_id :integer not null
+# event_type :text not null
+# params_yaml :text not null
+# created_at :datetime not null
+# described_state :string(255)
+# calculated_state :string(255)
+# last_described_at :datetime
+# incoming_message_id :integer
+# outgoing_message_id :integer
+# comment_id :integer
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe InfoRequestEvent do
@@ -15,6 +32,64 @@ describe InfoRequestEvent do
end
+ describe 'when deciding if it is indexed by search' do
+
+ before do
+ @comment = mock_model(Comment)
+ @incoming_message = mock_model(IncomingMessage)
+ @outgoing_message = mock_model(OutgoingMessage)
+ @info_request = mock_model(InfoRequest, :indexed_by_search? => true)
+ end
+
+ it 'should return false for a comment that is not visible' do
+ @comment.stub!(:visible).and_return(false)
+ @info_request_event = InfoRequestEvent.new(:event_type => 'comment',
+ :comment => @comment,
+ :info_request => @info_request)
+ @info_request_event.indexed_by_search?.should be_false
+ end
+
+ it 'should return true for a comment that is visible' do
+ @comment.stub!(:visible).and_return(true)
+ @info_request_event = InfoRequestEvent.new(:event_type => 'comment',
+ :comment => @comment,
+ :info_request => @info_request)
+ @info_request_event.indexed_by_search?.should be_true
+ end
+
+ it 'should return false for an incoming message that is not indexed by search' do
+ @incoming_message.stub!(:indexed_by_search?).and_return false
+ @info_request_event = InfoRequestEvent.new(:event_type => 'response',
+ :incoming_message => @incoming_message,
+ :info_request => @info_request)
+ @info_request_event.indexed_by_search?.should be_false
+ end
+
+ it 'should return true for an incoming message that is indexed by search' do
+ @incoming_message.stub!(:indexed_by_search?).and_return true
+ @info_request_event = InfoRequestEvent.new(:event_type => 'response',
+ :incoming_message => @incoming_message,
+ :info_request => @info_request)
+ @info_request_event.indexed_by_search?.should be_true
+ end
+
+ it 'should return false for an outgoing message that is not indexed by search' do
+ @outgoing_message.stub!(:indexed_by_search?).and_return false
+ @info_request_event = InfoRequestEvent.new(:event_type => 'followup_sent',
+ :outgoing_message => @outgoing_message,
+ :info_request => @info_request)
+ @info_request_event.indexed_by_search?.should be_false
+ end
+
+ it 'should return true for an outgoing message that is indexed by search' do
+ @outgoing_message.stub!(:indexed_by_search?).and_return true
+ @info_request_event = InfoRequestEvent.new(:event_type => 'followup_sent',
+ :outgoing_message => @outgoing_message,
+ :info_request => @info_request)
+ @info_request_event.indexed_by_search?.should be_true
+ end
+ end
+
describe 'after saving' do
it 'should mark the model for reindexing in xapian if there is no no_xapian_reindex flag on the object' do
diff --git a/spec/models/info_request_spec.rb b/spec/models/info_request_spec.rb
index 6d026e286..fac89109c 100644
--- a/spec/models/info_request_spec.rb
+++ b/spec/models/info_request_spec.rb
@@ -1,4 +1,28 @@
# encoding: utf-8
+# == Schema Information
+#
+# Table name: info_requests
+#
+# id :integer not null, primary key
+# title :text not null
+# user_id :integer
+# public_body_id :integer not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# described_state :string(255) not null
+# awaiting_description :boolean default(FALSE), not null
+# prominence :string(255) default("normal"), not null
+# url_title :text not null
+# law_used :string(255) default("foi"), not null
+# allow_new_responses_from :string(255) default("anybody"), not null
+# handle_rejected_responses :string(255) default("bounce"), not null
+# idhash :string(255) not null
+# external_user_name :string(255)
+# external_url :string(255)
+# attention_requested :boolean default(FALSE)
+# comments_allowed :boolean default(TRUE), not null
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe InfoRequest do
@@ -398,10 +422,12 @@ describe InfoRequest do
it 'should add extra conditions if supplied' do
expected_conditions = ["awaiting_description = ?
- AND (SELECT created_at
- FROM info_request_events
+ AND (SELECT info_request_events.created_at
+ FROM info_request_events, incoming_messages
WHERE info_request_events.info_request_id = info_requests.id
AND info_request_events.event_type = 'response'
+ AND incoming_messages.id = info_request_events.incoming_message_id
+ AND incoming_messages.prominence = 'normal'
ORDER BY created_at desc LIMIT 1) < ?
AND url_title != 'holding_pen'
AND user_id IS NOT NULL
@@ -416,21 +442,25 @@ describe InfoRequest do
InfoRequest.find_old_unclassified({:conditions => ["prominence != 'backpage'"]})
end
- it 'should ask the database for requests that are awaiting description, have a last response older
+ it 'should ask the database for requests that are awaiting description, have a last public response older
than 21 days old, have a user, are not the holding pen and are not backpaged' do
expected_conditions = ["awaiting_description = ?
- AND (SELECT created_at
- FROM info_request_events
+ AND (SELECT info_request_events.created_at
+ FROM info_request_events, incoming_messages
WHERE info_request_events.info_request_id = info_requests.id
AND info_request_events.event_type = 'response'
+ AND incoming_messages.id = info_request_events.incoming_message_id
+ AND incoming_messages.prominence = 'normal'
ORDER BY created_at desc LIMIT 1) < ?
AND url_title != 'holding_pen'
AND user_id IS NOT NULL".split(' ').join(' '),
true, Time.now - 21.days]
- expected_select = "*, (SELECT created_at
- FROM info_request_events
+ expected_select = "*, (SELECT info_request_events.created_at
+ FROM info_request_events, incoming_messages
WHERE info_request_events.info_request_id = info_requests.id
AND info_request_events.event_type = 'response'
+ AND incoming_messages.id = info_request_events.incoming_message_id
+ AND incoming_messages.prominence = 'normal'
ORDER BY created_at desc LIMIT 1)
AS last_response_time".split(' ').join(' ')
InfoRequest.should_receive(:find) do |all, query_params|
@@ -449,8 +479,14 @@ describe InfoRequest do
before do
Time.stub!(:now).and_return(Time.utc(2007, 11, 9, 23, 59))
- @mock_comment_event = mock_model(InfoRequestEvent, :created_at => Time.now - 23.days, :event_type => 'comment', :response? => false)
- @mock_response_event = mock_model(InfoRequestEvent, :created_at => Time.now - 22.days, :event_type => 'response', :response? => true)
+ @mock_comment_event = mock_model(InfoRequestEvent, :created_at => Time.now - 23.days,
+ :event_type => 'comment',
+ :response? => false)
+ mock_incoming_message = mock_model(IncomingMessage, :all_can_view? => true)
+ @mock_response_event = mock_model(InfoRequestEvent, :created_at => Time.now - 22.days,
+ :event_type => 'response',
+ :response? => true,
+ :incoming_message => mock_incoming_message)
@info_request = InfoRequest.new(:prominence => 'normal',
:awaiting_description => true,
:info_request_events => [@mock_response_event, @mock_comment_event])
@@ -587,6 +623,96 @@ describe InfoRequest do
end
end
+ describe 'when asked for the last public response event' do
+
+ before do
+ @info_request = FactoryGirl.create(:info_request_with_incoming)
+ @incoming_message = @info_request.incoming_messages.first
+ end
+
+ it 'should not return an event with a hidden prominence message' do
+ @incoming_message.prominence = 'hidden'
+ @incoming_message.save!
+ @info_request.get_last_public_response_event.should == nil
+ end
+
+ it 'should not return an event with a requester_only prominence message' do
+ @incoming_message.prominence = 'requester_only'
+ @incoming_message.save!
+ @info_request.get_last_public_response_event.should == nil
+ end
+
+ it 'should return an event with a normal prominence message' do
+ @incoming_message.prominence = 'normal'
+ @incoming_message.save!
+ @info_request.get_last_public_response_event.should == @incoming_message.response_event
+ end
+ end
+
+ describe 'when asked for the last public outgoing event' do
+
+ before do
+ @info_request = FactoryGirl.create(:info_request)
+ @outgoing_message = @info_request.outgoing_messages.first
+ end
+
+ it 'should not return an event with a hidden prominence message' do
+ @outgoing_message.prominence = 'hidden'
+ @outgoing_message.save!
+ @info_request.get_last_public_outgoing_event.should == nil
+ end
+
+ it 'should not return an event with a requester_only prominence message' do
+ @outgoing_message.prominence = 'requester_only'
+ @outgoing_message.save!
+ @info_request.get_last_public_outgoing_event.should == nil
+ end
+
+ it 'should return an event with a normal prominence message' do
+ @outgoing_message.prominence = 'normal'
+ @outgoing_message.save!
+ @info_request.get_last_public_outgoing_event.should == @outgoing_message.info_request_events.first
+ end
+
+ end
+
+ describe 'when asked who can be sent a followup' do
+
+ before do
+ @info_request = FactoryGirl.create(:info_request_with_plain_incoming)
+ @incoming_message = @info_request.incoming_messages.first
+ @public_body = @info_request.public_body
+ end
+
+ it 'should not include details from a hidden prominence response' do
+ @incoming_message.prominence = 'hidden'
+ @incoming_message.save!
+ @info_request.who_can_followup_to.should == [[@public_body.name,
+ @public_body.request_email,
+ nil]]
+ end
+
+ it 'should not include details from a requester_only prominence response' do
+ @incoming_message.prominence = 'requester_only'
+ @incoming_message.save!
+ @info_request.who_can_followup_to.should == [[@public_body.name,
+ @public_body.request_email,
+ nil]]
+ end
+
+ it 'should include details from a normal prominence response' do
+ @incoming_message.prominence = 'normal'
+ @incoming_message.save!
+ @info_request.who_can_followup_to.should == [[@public_body.name,
+ @public_body.request_email,
+ nil],
+ ['Bob Responder',
+ "bob@example.com",
+ @incoming_message.id]]
+ end
+
+ end
+
describe 'when generating json for the api' do
before do
diff --git a/spec/models/mail_server_log_spec.rb b/spec/models/mail_server_log_spec.rb
index 2b44a4559..67709b130 100644
--- a/spec/models/mail_server_log_spec.rb
+++ b/spec/models/mail_server_log_spec.rb
@@ -1,3 +1,16 @@
+# == Schema Information
+#
+# Table name: mail_server_logs
+#
+# id :integer not null, primary key
+# mail_server_log_done_id :integer
+# info_request_id :integer
+# order :integer not null
+# line :text not null
+# created_at :datetime not null
+# updated_at :datetime not null
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe MailServerLog do
diff --git a/spec/models/outgoing_message_spec.rb b/spec/models/outgoing_message_spec.rb
index 60164fb31..1e05e09f1 100644
--- a/spec/models/outgoing_message_spec.rb
+++ b/spec/models/outgoing_message_spec.rb
@@ -1,3 +1,19 @@
+# == Schema Information
+#
+# Table name: outgoing_messages
+#
+# id :integer not null, primary key
+# info_request_id :integer not null
+# body :text not null
+# status :string(255) not null
+# message_type :string(255) not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# last_sent_at :datetime
+# incoming_message_followup_id :integer
+# what_doing :string(255) not null
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe OutgoingMessage, " when making an outgoing message" do
@@ -50,6 +66,81 @@ describe OutgoingMessage, " when making an outgoing message" do
outgoing_message.body.should include(expected_text)
end
+ describe 'when asked if a user can view it' do
+
+ before do
+ @info_request = FactoryGirl.create(:info_request)
+ @outgoing_message = @info_request.outgoing_messages.first
+ end
+
+ context 'if the prominence is hidden' do
+
+ before do
+ @outgoing_message.prominence = 'hidden'
+ end
+
+ it 'should return true for an admin user' do
+ @outgoing_message.user_can_view?(FactoryGirl.create(:admin_user)).should be_true
+ end
+
+ it 'should return false for a non-admin user' do
+ @outgoing_message.user_can_view?(FactoryGirl.create(:user)).should be_false
+ end
+
+ end
+
+ context 'if the prominence is requester_only' do
+
+ before do
+ @outgoing_message.prominence = 'requester_only'
+ end
+
+ it 'should return true if the user owns the associated request' do
+ @outgoing_message.user_can_view?(@info_request.user).should be_true
+ end
+
+ it 'should return false if the user does not own the associated request' do
+ @outgoing_message.user_can_view?(FactoryGirl.create(:user)).should be_false
+ end
+ end
+
+ context 'if the prominence is normal' do
+
+ before do
+ @outgoing_message.prominence = 'normal'
+ end
+
+ it 'should return true for a non-admin user' do
+ @outgoing_message.user_can_view?(FactoryGirl.create(:user)).should be_true
+ end
+
+ end
+
+ end
+
+ describe 'when asked if it is indexed by search' do
+
+ before do
+ @info_request = FactoryGirl.create(:info_request)
+ @outgoing_message = @info_request.outgoing_messages.first
+ end
+
+ it 'should return false if it has prominence "hidden"' do
+ @outgoing_message.prominence = 'hidden'
+ @outgoing_message.indexed_by_search?.should be_false
+ end
+
+ it 'should return false if it has prominence "requester_only"' do
+ @outgoing_message.prominence = 'requester_only'
+ @outgoing_message.indexed_by_search?.should be_false
+ end
+
+ it 'should return true if it has prominence "normal"' do
+ @outgoing_message.prominence = 'normal'
+ @outgoing_message.indexed_by_search?.should be_true
+ end
+
+ end
end
@@ -72,5 +163,3 @@ describe IncomingMessage, " when censoring data" do
@om.body.should match(/fancy cat/)
end
end
-
-
diff --git a/spec/models/post_redirect_spec.rb b/spec/models/post_redirect_spec.rb
index 5f51b6de5..73740e914 100644
--- a/spec/models/post_redirect_spec.rb
+++ b/spec/models/post_redirect_spec.rb
@@ -1,3 +1,19 @@
+# == Schema Information
+#
+# Table name: post_redirects
+#
+# id :integer not null, primary key
+# token :text not null
+# uri :text not null
+# post_params_yaml :text
+# created_at :datetime not null
+# updated_at :datetime not null
+# email_token :text not null
+# reason_params_yaml :text
+# user_id :integer
+# circumstance :text default("normal"), not null
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe PostRedirect, " when constructing" do
diff --git a/spec/models/profile_photo_spec.rb b/spec/models/profile_photo_spec.rb
index 892cccd08..0e157e2c5 100644
--- a/spec/models/profile_photo_spec.rb
+++ b/spec/models/profile_photo_spec.rb
@@ -1,3 +1,13 @@
+# == Schema Information
+#
+# Table name: profile_photos
+#
+# id :integer not null, primary key
+# data :binary not null
+# user_id :integer
+# draft :boolean default(FALSE), not null
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe ProfilePhoto, "when constructing a new photo" do
diff --git a/spec/models/public_body_spec.rb b/spec/models/public_body_spec.rb
index 3578c0e9c..582f1430e 100644
--- a/spec/models/public_body_spec.rb
+++ b/spec/models/public_body_spec.rb
@@ -1,4 +1,27 @@
# encoding: UTF-8
+# == Schema Information
+#
+# Table name: public_bodies
+#
+# id :integer not null, primary key
+# name :text not null
+# short_name :text not null
+# request_email :text not null
+# version :integer not null
+# last_edit_editor :string(255) not null
+# last_edit_comment :text not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# url_name :text not null
+# home_page :text default(""), not null
+# notes :text default(""), not null
+# first_letter :string(255) not null
+# publication_scheme :text default(""), not null
+# api_key :string(255) not null
+# info_requests_count :integer default(0), not null
+# disclosure_log :text default(""), not null
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe PublicBody, " using tags" do
diff --git a/spec/models/purge_request_spec.rb b/spec/models/purge_request_spec.rb
index 7b67fca52..02b3d685d 100644
--- a/spec/models/purge_request_spec.rb
+++ b/spec/models/purge_request_spec.rb
@@ -1,3 +1,14 @@
+# == Schema Information
+#
+# Table name: purge_requests
+#
+# id :integer not null, primary key
+# url :string(255)
+# created_at :datetime not null
+# model :string(255) not null
+# model_id :integer not null
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
require 'fakeweb'
diff --git a/spec/models/raw_email_spec.rb b/spec/models/raw_email_spec.rb
index ff2830a62..f86b35e99 100644
--- a/spec/models/raw_email_spec.rb
+++ b/spec/models/raw_email_spec.rb
@@ -1,3 +1,10 @@
+# == Schema Information
+#
+# Table name: raw_emails
+#
+# id :integer not null, primary key
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe User, "manipulating a raw email" do
diff --git a/spec/models/track_thing_spec.rb b/spec/models/track_thing_spec.rb
index c42eb5e8b..86d3c0cda 100644
--- a/spec/models/track_thing_spec.rb
+++ b/spec/models/track_thing_spec.rb
@@ -1,3 +1,19 @@
+# == Schema Information
+#
+# Table name: track_things
+#
+# id :integer not null, primary key
+# tracking_user_id :integer not null
+# track_query :string(255) not null
+# info_request_id :integer
+# tracked_user_id :integer
+# public_body_id :integer
+# track_medium :string(255) not null
+# track_type :string(255) default("internal_error"), not null
+# created_at :datetime
+# updated_at :datetime
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe TrackThing, "when tracking changes" do
diff --git a/spec/models/track_things_sent_email_spec.rb b/spec/models/track_things_sent_email_spec.rb
index 6166f42ab..4675d0847 100644
--- a/spec/models/track_things_sent_email_spec.rb
+++ b/spec/models/track_things_sent_email_spec.rb
@@ -1,3 +1,16 @@
+# == Schema Information
+#
+# Table name: track_things_sent_emails
+#
+# id :integer not null, primary key
+# track_thing_id :integer not null
+# info_request_event_id :integer
+# user_id :integer
+# public_body_id :integer
+# created_at :datetime
+# updated_at :datetime
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe TrackThingsSentEmail, "when tracking things sent email" do
diff --git a/spec/models/user_info_request_sent_alert_spec.rb b/spec/models/user_info_request_sent_alert_spec.rb
index 971c5b8c1..69be1092b 100644
--- a/spec/models/user_info_request_sent_alert_spec.rb
+++ b/spec/models/user_info_request_sent_alert_spec.rb
@@ -1,3 +1,14 @@
+# == Schema Information
+#
+# Table name: user_info_request_sent_alerts
+#
+# id :integer not null, primary key
+# user_id :integer not null
+# info_request_id :integer not null
+# alert_type :string(255) not null
+# info_request_event_id :integer
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe UserInfoRequestSentAlert, " when blah" do
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 96c169604..f380f6f13 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1,3 +1,29 @@
+# == Schema Information
+#
+# Table name: users
+#
+# id :integer not null, primary key
+# email :string(255) not null
+# name :string(255) not null
+# hashed_password :string(255) not null
+# salt :string(255) not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# email_confirmed :boolean default(FALSE), not null
+# url_name :text not null
+# last_daily_track_email :datetime default(2000-01-01 00:00:00 UTC)
+# admin_level :string(255) default("none"), not null
+# ban_text :text default(""), not null
+# about_me :text default(""), not null
+# locale :string(255)
+# email_bounced_at :datetime
+# email_bounce_message :text default(""), not null
+# no_limit :boolean default(FALSE), not null
+# receive_email_alerts :boolean default(TRUE), not null
+# address :string(255)
+# dob :date
+#
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
describe User, "making up the URL name" do
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 86ca5150a..0d8f8fac5 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -155,5 +155,7 @@ Spork.prefork do
end
Spork.each_run do
+ FactoryGirl.definition_file_paths = [ Rails.root.join('spec', 'factories') ]
+ FactoryGirl.reload
# This code will be run each time you run your specs.
end
diff --git a/spec/views/request/_after_actions.html.erb_spec.rb b/spec/views/request/_after_actions.html.erb_spec.rb
index ae398f4ce..833323d68 100644
--- a/spec/views/request/_after_actions.html.erb_spec.rb
+++ b/spec/views/request/_after_actions.html.erb_spec.rb
@@ -69,24 +69,11 @@ describe 'when displaying actions that can be taken with regard to a request' do
end
end
- describe 'if the request is viewable by all' do
- it 'should display the link to download the entire request' do
- render :partial => 'request/after_actions'
- response.should have_selector('div#anyone_actions') do |div|
- div.should have_selector('a', :content => 'Download a zip file of all correspondence')
- end
- end
- end
-
- describe 'if the request is not viewable by all' do
-
- it 'should not display the link to download the entire request' do
- @mock_request.stub!(:all_can_view?).and_return(false)
- render :partial => 'request/after_actions'
- response.should have_selector('div#anyone_actions') do |div|
- div.should_not have_selector('a', :content => 'Download a zip file of all correspondence')
- end
+ it 'should display the link to download the entire request' do
+ render :partial => 'request/after_actions'
+ response.should have_selector('div#anyone_actions') do |div|
+ div.should have_selector('a', :content => 'Download a zip file of all correspondence')
end
end
diff --git a/spec/views/request/show.html.erb_spec.rb b/spec/views/request/show.html.erb_spec.rb
index 4578268b2..6e63b9b43 100644
--- a/spec/views/request/show.html.erb_spec.rb
+++ b/spec/views/request/show.html.erb_spec.rb
@@ -1,8 +1,8 @@
require File.expand_path(File.join('..', '..', '..', 'spec_helper'), __FILE__)
describe 'request/show' do
-
- before do
+
+ before do
@mock_body = mock_model(PublicBody, :name => 'test body',
:url_name => 'test_body',
:is_school? => false)
@@ -10,101 +10,101 @@ describe 'request/show' do
:url_name => 'test_user',
:profile_photo => nil)
@mock_request = mock_model(InfoRequest, :title => 'test request',
- :awaiting_description => false,
+ :awaiting_description => false,
:law_used_with_a => 'A Freedom of Information request',
:law_used_full => 'Freedom of Information',
:public_body => @mock_body,
- :user => @mock_user,
- :user_name => @mock_user.name,
+ :user => @mock_user,
+ :user_name => @mock_user.name,
:is_external? => false,
- :calculate_status => 'waiting_response',
+ :calculate_status => 'waiting_response',
:date_response_required_by => Date.today,
:prominence => 'normal',
:comments_allowed? => true,
:all_can_view? => true,
:url_title => 'test_request')
end
-
+
def request_page
assign :info_request, @mock_request
assign :info_request_events, []
assign :status, @mock_request.calculate_status
render
end
-
- describe 'when a status update has been requested' do
-
- before do
+
+ describe 'when a status update has been requested' do
+
+ before do
assign :update_status, true
end
-
+
it 'should show the first form for describing the state of the request' do
request_page
response.should have_selector("div.describe_state_form#describe_state_form_1")
- end
-
+ end
+
end
-
- describe 'when it is awaiting a description' do
-
- before do
+
+ describe 'when it is awaiting a description' do
+
+ before do
@mock_request.stub!(:awaiting_description).and_return(true)
end
-
+
it 'should show the first form for describing the state of the request' do
request_page
response.should have_selector("div.describe_state_form#describe_state_form_1")
end
-
- it 'should show the second form for describing the state of the request' do
+
+ it 'should show the second form for describing the state of the request' do
request_page
response.should have_selector("div.describe_state_form#describe_state_form_2")
end
-
+
end
-
- describe 'when the user is the request owner' do
-
- before do
+
+ describe 'when the user is the request owner' do
+
+ before do
assign :is_owning_user, true
end
-
- describe 'when the request status is "waiting clarification"' do
-
- before do
+
+ describe 'when the request status is "waiting clarification"' do
+
+ before do
@mock_request.stub!(:calculate_status).and_return('waiting_clarification')
end
-
- describe 'when there is a last response' do
-
+
+ describe 'when there is a last response' do
+
before do
@mock_response = mock_model(IncomingMessage)
- @mock_request.stub!(:get_last_response).and_return(@mock_response)
+ @mock_request.stub!(:get_last_public_response).and_return(@mock_response)
end
-
- it 'should show a link to follow up the last response with clarification' do
+
+ it 'should show a link to follow up the last response with clarification' do
request_page
expected_url = "/en/request/#{@mock_request.id}/response/#{@mock_response.id}#followup"
response.should have_selector("a", :href => expected_url, :content => 'send a follow up message')
end
-
+
end
-
+
describe 'when there is no last response' do
-
- before do
- @mock_request.stub!(:get_last_response).and_return(nil)
+
+ before do
+ @mock_request.stub!(:get_last_public_response).and_return(nil)
end
-
- it 'should show a link to follow up the request without reference to a specific response' do
+
+ it 'should show a link to follow up the request without reference to a specific response' do
request_page
expected_url = "/en/request/#{@mock_request.id}/response#followup"
response.should have_selector("a", :href => expected_url, :content => 'send a follow up message')
end
end
end
-
+
end
end