diff options
Diffstat (limited to 'spec/controllers/request_controller_spec.rb')
-rw-r--r-- | spec/controllers/request_controller_spec.rb | 1409 |
1 files changed, 880 insertions, 529 deletions
diff --git a/spec/controllers/request_controller_spec.rb b/spec/controllers/request_controller_spec.rb index 6f25b605a..1e7df4536 100644 --- a/spec/controllers/request_controller_spec.rb +++ b/spec/controllers/request_controller_spec.rb @@ -2,7 +2,6 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe RequestController, "when listing recent requests" do - before(:each) do load_raw_emails_data get_fixtures_xapian_index @@ -18,92 +17,8 @@ describe RequestController, "when listing recent requests" do response.should render_template('list') end - it "should filter requests" do - get :list, :view => 'all' - assigns[:list_results].map(&:info_request).should =~ InfoRequest.all - - # default sort order is the request with the most recently created event first - assigns[:list_results].map(&:info_request).should == InfoRequest.all( - :order => "(select max(info_request_events.created_at) from info_request_events where info_request_events.info_request_id = info_requests.id) DESC") - - get :list, :view => 'successful' - assigns[:list_results].map(&:info_request).should =~ InfoRequest.all( - :conditions => "id in ( - select info_request_id - from info_request_events - where not exists ( - select * - from info_request_events later_events - where later_events.created_at > info_request_events.created_at - and later_events.info_request_id = info_request_events.info_request_id - and later_events.described_state is not null - ) - and info_request_events.described_state in ('successful', 'partially_successful') - )") - end - - it "should filter requests by date" do - # The semantics of the search are that it finds any InfoRequest - # that has any InfoRequestEvent created in the specified range - - get :list, :view => 'all', :request_date_before => '13/10/2007' - assigns[:list_results].map(&:info_request).should =~ InfoRequest.all( - :conditions => "id in (select info_request_id from info_request_events where created_at < '2007-10-13'::date)") - - get :list, :view => 'all', :request_date_after => '13/10/2007' - assigns[:list_results].map(&:info_request).should =~ InfoRequest.all( - :conditions => "id in (select info_request_id from info_request_events where created_at > '2007-10-13'::date)") - - get :list, :view => 'all', :request_date_after => '13/10/2007', :request_date_before => '01/11/2007' - assigns[:list_results].map(&:info_request).should =~ InfoRequest.all( - :conditions => "id in (select info_request_id from info_request_events where created_at between '2007-10-13'::date and '2007-11-01'::date)") - end - - it "should list internal_review requests as unresolved ones" do - get :list, :view => 'awaiting' - - # This doesn’t precisely duplicate the logic of the actual - # query, but it is close enough to give the same result with - # the current set of test data. - assigns[:list_results].should =~ InfoRequestEvent.all( - :conditions => "described_state in ( - 'waiting_response', 'waiting_clarification', - 'internal_review', 'gone_postal', 'error_message', 'requires_admin' - ) and not exists ( - select * - from info_request_events later_events - where later_events.created_at > info_request_events.created_at - and later_events.info_request_id = info_request_events.info_request_id - )") - - - get :list, :view => 'awaiting' - assigns[:list_results].map(&:info_request).include?(info_requests(:fancy_dog_request)).should == false - - event = info_request_events(:useless_incoming_message_event) - event.described_state = event.calculated_state = "internal_review" - event.save! - rebuild_xapian_index - - get :list, :view => 'awaiting' - assigns[:list_results].map(&:info_request).include?(info_requests(:fancy_dog_request)).should == true - end - - it "should assign the first page of results" do - xap_results = mock_model(ActsAsXapian::Search, - :results => (1..25).to_a.map { |m| { :model => m } }, - :matches_estimated => 1000000) - - InfoRequest.should_receive(:full_search). - with([InfoRequestEvent]," (variety:sent OR variety:followup_sent OR variety:response OR variety:comment)", "created_at", anything, anything, anything, anything). - and_return(xap_results) - get :list, :view => 'all' - assigns[:list_results].size.should == 25 - assigns[:show_no_more_than].should == RequestController::MAX_RESULTS - end - it "should return 404 for pages we don't want to serve up" do - xap_results = mock_model(ActsAsXapian::Search, + xap_results = mock(ActsAsXapian::Search, :results => (1..25).to_a.map { |m| { :model => m } }, :matches_estimated => 1000000) lambda { @@ -120,8 +35,7 @@ describe RequestController, "when listing recent requests" do end describe RequestController, "when changing things that appear on the request page" do - - integrate_views + render_views it "should purge the downstream cache when mail is received" do ir = info_requests(:fancy_dog_request) @@ -136,7 +50,7 @@ describe RequestController, "when changing things that appear on the request pag it "should purge the downstream cache when a followup is made" do session[:user_id] = users(:bob_smith_user).id ir = info_requests(:fancy_dog_request) - post :show_response, :outgoing_message => { :body => "What a useless response! You suck.", :what_doing => 'normal_sort' }, :id => ir.id, :incoming_message_id => incoming_messages(:useless_incoming_message), :submitted_followup => 1 + post :show_response, :outgoing_message => { :body => "What a useless response! You suck.", :what_doing => 'normal_sort' }, :id => ir.id, :submitted_followup => 1 PurgeRequest.all().first.model_id.should == ir.id end it "should purge the downstream cache when the request is categorised" do @@ -174,7 +88,7 @@ describe RequestController, "when changing things that appear on the request pag ir.save! PurgeRequest.all().first.model_id.should == ir.id end - it "should not create more than one entry for any given resourcce" do + it "should not create more than one entry for any given resource" do ir = info_requests(:fancy_dog_request) ir.prominence = 'hidden' ir.save! @@ -187,11 +101,10 @@ describe RequestController, "when changing things that appear on the request pag end describe RequestController, "when showing one request" do - integrate_views + render_views before(:each) do load_raw_emails_data - FileUtils.rm_rf File.join(File.dirname(__FILE__), "../../cache/zips") end it "should be successful" do @@ -216,20 +129,20 @@ describe RequestController, "when showing one request" do end it "should redirect from a numeric URL to pretty one" do - get :show, :url_title => info_requests(:naughty_chicken_request).id + get :show, :url_title => info_requests(:naughty_chicken_request).id.to_s response.should redirect_to(:action => 'show', :url_title => info_requests(:naughty_chicken_request).url_title) end it 'should show actions the request owner can take' do get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' - response.should have_tag('div#owner_actions') + response.should have_selector('div#owner_actions') end describe 'when the request does allow comments' do it 'should have a comment link' do get :show, { :url_title => 'why_do_you_have_such_a_fancy_dog' }, { :user_id => users(:admin_user).id } - response.should have_tag('#anyone_actions', /Add an annotation/) + response.should have_selector('#anyone_actions', :content => "Add an annotation") end end @@ -237,10 +150,40 @@ describe RequestController, "when showing one request" do it 'should not have a comment link' do get :show, { :url_title => 'spam_1' }, { :user_id => users(:admin_user).id } - response.should_not have_tag('#anyone_actions', /Add an annotation/) + response.should_not have_selector('#anyone_actions', :content => "Add an annotation") end end + context "when the request has not yet been reported" do + it "should allow the user to report" do + title = info_requests(:badger_request).url_title + get :show, :url_title => title + response.should_not contain("This request has been reported") + response.should contain("Offensive?") + end + end + + context "when the request has been reported for admin attention" do + before :each do + info_requests(:fancy_dog_request).report!("", "", nil) + end + it "should inform the user" do + get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' + response.should contain("This request has been reported") + response.should_not contain("Offensive?") + end + + context "and then deemed okay and left to complete" do + before :each do + info_requests(:fancy_dog_request).set_described_state("successful") + end + it "should let the user know that the administrators have not hidden this request" do + get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' + response.body.should =~ (/the site administrators.*have not hidden it/) + end + end + end + describe 'when the request is being viewed by an admin' do describe 'if the request is awaiting description' do @@ -254,13 +197,13 @@ describe RequestController, "when showing one request" do it 'should show the describe state form' do get :show, { :url_title => 'why_do_you_have_such_a_fancy_dog' }, { :user_id => users(:admin_user).id } - response.should have_tag('div.describe_state_form') + response.should have_selector('div.describe_state_form') end it 'should ask the user to use the describe state from' do get :show, { :url_title => 'why_do_you_have_such_a_fancy_dog' }, { :user_id => users(:admin_user).id } - response.should have_tag('p#request_status', :text => /answer the question above/) + response.should have_selector('p#request_status', :content => "answer the question above") end end @@ -278,7 +221,7 @@ describe RequestController, "when showing one request" do it 'should give a link to requesting an internal review' do get :show, { :url_title => 'why_do_you_have_such_a_fancy_dog' }, { :user_id => users(:admin_user).id } - response.should have_tag('p#request_status', :text =>/requesting an internal review/) + response.should have_selector('p#request_status', :content => "requesting an internal review") end end @@ -296,7 +239,7 @@ describe RequestController, "when showing one request" do it 'should give a link to make a followup' do get :show, { :url_title => 'why_do_you_have_such_a_fancy_dog' }, { :user_id => users(:admin_user).id } - response.should have_tag('p#request_status a', :text =>/send a follow up message/) + response.should have_selector('p#request_status a', :content => "send a follow up message") end end @@ -313,7 +256,7 @@ describe RequestController, "when showing one request" do it 'should not display actions the request owner can take' do get :show, :url_title => 'balalas' - response.should_not have_tag('div#owner_actions') + response.should_not have_selector('div#owner_actions') end end @@ -339,12 +282,12 @@ describe RequestController, "when showing one request" do it 'should not show the describe state form' do make_request - response.should_not have_tag('div.describe_state_form') + response.should_not have_selector('div.describe_state_form') end it 'should not ask the user to use the describe state form' do make_request - response.should_not have_tag('p#request_status', :text => /answer the question above/) + response.should_not have_selector('p#request_status', :content => "answer the question above") end end @@ -361,7 +304,7 @@ describe RequestController, "when showing one request" do it 'should not give a link to requesting an internal review' do make_request - response.should_not have_tag('p#request_status', :text =>/requesting an internal review/) + response.should_not have_selector('p#request_status', :content => "requesting an internal review") end end @@ -377,12 +320,12 @@ describe RequestController, "when showing one request" do it 'should not give a link to make a followup' do make_request - response.should_not have_tag('p#request_status a', :text =>/send a follow up message/) + response.should_not have_selector('p#request_status a', :content => "send a follow up message") end it 'should not give a link to sign in (in the request status paragraph)' do make_request - response.should_not have_tag('p#request_status a', :text => /sign in/) + response.should_not have_selector('p#request_status a', :content => "sign in") end end @@ -445,7 +388,7 @@ describe RequestController, "when showing one request" do describe 'when handling incoming mail' do - integrate_views + render_views it "should receive incoming messages, send email to creator, and show them" do ir = info_requests(:fancy_dog_request) @@ -479,13 +422,13 @@ describe RequestController, "when showing one request" do (assigns[:info_request_events].size - size_before).should == 1 ir.reload - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1 + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello world.txt', :skip_cache => 1 response.content_type.should == "text/plain" - response.should have_text(/Second hello/) + response.should contain "Second hello" - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 3, :file_name => ['hello.txt'], :skip_cache => 1 + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 3, :file_name => 'hello world.txt', :skip_cache => 1 response.content_type.should == "text/plain" - response.should have_text(/First hello/) + response.should contain "First hello" end it 'should cache an attachment on a request with normal prominence' do @@ -496,24 +439,23 @@ describe RequestController, "when showing one request" do get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, - :file_name => ['hello.txt'] - + :file_name => 'hello world.txt' end it "should convert message body to UTF8" do ir = info_requests(:fancy_dog_request) receive_incoming_mail('iso8859_2_raw_email.email', ir.incoming_email) get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' - response.should have_text(/tënde/u) + response.should contain "tënde" end it "should generate valid HTML verson of plain text attachments" do ir = info_requests(:fancy_dog_request) receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) ir.reload - get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1 + get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello world.txt.html', :skip_cache => 1 response.content_type.should == "text/html" - response.should have_text(/Second hello/) + response.should contain "Second hello" end # This is a regression test for a bug where URLs of this form were causing 500 errors @@ -532,11 +474,11 @@ describe RequestController, "when showing one request" do ir.reload ugly_id = "55195" lambda { - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1 + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => 'hello world.txt.html', :skip_cache => 1 }.should raise_error(ActiveRecord::RecordNotFound) lambda { - get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1 + get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => 'hello world.txt', :skip_cache => 1 }.should raise_error(ActiveRecord::RecordNotFound) end it "should return 404 when incoming message and request ids don't match" do @@ -545,7 +487,7 @@ describe RequestController, "when showing one request" do receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) ir.reload lambda { - get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => wrong_id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1 + get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => wrong_id, :part => 2, :file_name => 'hello world.txt.html', :skip_cache => 1 }.should raise_error(ActiveRecord::RecordNotFound) end it "should return 404 for ugly URLs contain a request id that isn't an integer, even if the integer prefix refers to an actual request" do @@ -555,11 +497,11 @@ describe RequestController, "when showing one request" do ugly_id = "%d95" % [info_requests(:naughty_chicken_request).id] lambda { - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1 + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => 'hello world.txt.html', :skip_cache => 1 }.should raise_error(ActiveRecord::RecordNotFound) lambda { - get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1 + get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ugly_id, :part => 2, :file_name => 'hello world.txt', :skip_cache => 1 }.should raise_error(ActiveRecord::RecordNotFound) end it "should return 404 when incoming message and request ids don't match" do @@ -568,7 +510,7 @@ describe RequestController, "when showing one request" do receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) ir.reload lambda { - get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => wrong_id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1 + get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => wrong_id, :part => 2, :file_name => 'hello world.txt.html', :skip_cache => 1 }.should raise_error(ActiveRecord::RecordNotFound) end @@ -576,41 +518,64 @@ describe RequestController, "when showing one request" do ir = info_requests(:fancy_dog_request) receive_incoming_mail('incoming-request-pdf-attachment.email', ir.incoming_email) ir.reload - get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['fs_50379341.pdf.html'], :skip_cache => 1 + get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'fs 50379341.pdf.html', :skip_cache => 1 response.content_type.should == "text/html" - response.should have_text(/Walberswick Parish Council/) + response.should contain "Walberswick Parish Council" end - it "should not cause a reparsing of the raw email, even when the result would be a 404" do + it "should not cause a reparsing of the raw email, even when the attachment can't be found" do ir = info_requests(:fancy_dog_request) receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) ir.reload - attachment = IncomingMessage.get_attachment_by_url_part_number(ir.incoming_messages[1].get_attachments_for_display, 2) - attachment.body.should have_text(/Second hello/) + attachment = IncomingMessage.get_attachment_by_url_part_number_and_filename(ir.incoming_messages[1].get_attachments_for_display, 2, 'hello world.txt') + attachment.body.should contain "Second hello" # change the raw_email associated with the message; this only be reparsed when explicitly asked for ir.incoming_messages[1].raw_email.data = ir.incoming_messages[1].raw_email.data.sub("Second", "Third") - # asking for an attachment by the wrong filename results - # in a 404 for browsing users. This shouldn't cause a - # re-parse... - lambda { - get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt.baz.html'], :skip_cache => 1 - }.should raise_error(ActiveRecord::RecordNotFound) + # asking for an attachment by the wrong filename should result in redirecting + # back to the incoming message, but shouldn't cause a reparse: + get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello world.txt.baz.html', :skip_cache => 1 + response.status.should == 303 - attachment = IncomingMessage.get_attachment_by_url_part_number(ir.incoming_messages[1].get_attachments_for_display, 2) - attachment.body.should have_text(/Second hello/) + attachment = IncomingMessage.get_attachment_by_url_part_number_and_filename(ir.incoming_messages[1].get_attachments_for_display, 2, 'hello world.txt') + attachment.body.should contain "Second hello" # ...nor should asking for it by its correct filename... - get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1 - response.should_not have_text(/Third hello/) + get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello world.txt.html', :skip_cache => 1 + response.should_not contain "Third hello" # ...but if we explicitly ask for attachments to be extracted, then they should be force = true ir.incoming_messages[1].parse_raw_email!(force) - attachment = IncomingMessage.get_attachment_by_url_part_number(ir.incoming_messages[1].get_attachments_for_display, 2) - attachment.body.should have_text(/Second hello/) - get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt.html'], :skip_cache => 1 - response.should have_text(/Third hello/) + ir.reload + attachment = IncomingMessage.get_attachment_by_url_part_number_and_filename(ir.incoming_messages[1].get_attachments_for_display, 2, 'hello world.txt') + attachment.body.should contain "Third hello" + get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello world.txt.html', :skip_cache => 1 + response.should contain "Third hello" + end + + it "should redirect to the incoming message if there's a wrong part number and an ambiguous filename" do + ir = info_requests(:fancy_dog_request) + receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) + ir.reload + + im = ir.incoming_messages[1] + + attachment = IncomingMessage.get_attachment_by_url_part_number_and_filename(im.get_attachments_for_display, 5, 'hello world.txt') + attachment.should be_nil + + get :get_attachment_as_html, :incoming_message_id => im.id, :id => ir.id, :part => 5, :file_name => 'hello world.txt', :skip_cache => 1 + response.status.should == 303 + new_location = response.header['Location'] + new_location.should match(/request\/#{ir.url_title}#incoming-#{im.id}/) + end + + it "should find a uniquely named filename even if the URL part number was wrong" do + ir = info_requests(:fancy_dog_request) + receive_incoming_mail('incoming-request-pdf-attachment.email', ir.incoming_email) + ir.reload + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 5, :file_name => 'fs 50379341.pdf', :skip_cache => 1 + response.content_type.should == "application/pdf" end it "should treat attachments with unknown extensions as binary" do @@ -618,19 +583,17 @@ describe RequestController, "when showing one request" do receive_incoming_mail('incoming-request-attachment-unknown-extension.email', ir.incoming_email) ir.reload - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.qwglhm'], :skip_cache => 1 + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello.qwglhm', :skip_cache => 1 response.content_type.should == "application/octet-stream" - response.should have_text(/an unusual sort of file/) + response.should contain "an unusual sort of file" end it "should not download attachments with wrong file name" do ir = info_requests(:fancy_dog_request) receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) - lambda { - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, - :file_name => ['http://trying.to.hack'] - }.should raise_error(ActiveRecord::RecordNotFound) + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'http://trying.to.hack' + response.status.should == 303 end it "should censor attachments downloaded as binary" do @@ -646,9 +609,9 @@ describe RequestController, "when showing one request" do begin receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1 + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello world.txt', :skip_cache => 1 response.content_type.should == "text/plain" - response.should have_text(/xxxxxx hello/) + response.should contain "xxxxxx hello" ensure ir.censor_rules.clear end @@ -668,9 +631,9 @@ describe RequestController, "when showing one request" do receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) ir.reload - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => ['hello.txt'], :skip_cache => 1 + get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, :id => ir.id, :part => 2, :file_name => 'hello world.txt', :skip_cache => 1 response.content_type.should == "text/plain" - response.should have_text(/xxxxxx hello/) + response.should contain "xxxxxx hello" ensure ir.user.censor_rules.clear end @@ -692,205 +655,247 @@ describe RequestController, "when showing one request" do get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' assert assigns[:info_request].info_request_events[3].incoming_message.get_attachments_for_display.count == 2 # the issue is that the info_request_events have got cached on them the old info_requests. - # where i'm at: trying to replace those fields that got re-read from the raw email. however tests are failing in very strange ways. currently I don't appear to be getting any attachments parsed in at all when in the template (see "*****" in _correspondence.rhtml) but do when I'm in the code. + # where i'm at: trying to replace those fields that got re-read from the raw email. however tests are failing in very strange ways. currently I don't appear to be getting any attachments parsed in at all when in the template (see "*****" in _correspondence.html.erb) but do when I'm in the code. # so at this point, assigns[:info_request].incoming_messages[1].get_attachments_for_display is returning stuff, but the equivalent thing in the template isn't. # but something odd is that the above is return a whole load of attachments which aren't there in the controller - response.body.should have_tag("p.attachment strong", /hello.txt/m) + response.body.should have_selector("p.attachment strong") do |s| + s.should contain /hello world.txt/m + end censor_rule = CensorRule.new() - censor_rule.text = "hello.txt" + # Note that the censor rule applies to the original filename, + # not the display_filename: + censor_rule.text = "hello-world.txt" censor_rule.replacement = "goodbye.txt" censor_rule.last_edit_editor = "unknown" censor_rule.last_edit_comment = "none" ir.censor_rules << censor_rule begin get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' - response.body.should have_tag("p.attachment strong", /goodbye.txt/m) + response.body.should have_selector("p.attachment strong") do |s| + s.should contain /goodbye.txt/m + end ensure ir.censor_rules.clear 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 have_text(/#{title}.zip$/) - old_path = assigns[:url_path] - response.location.should have_text(/#{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 have_text(/#{title}.zip$/) - old_path = assigns[:url_path] - response.location.should have_text(/#{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.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 have_text(/#{title}.zip$/) - assigns[:url_path].should_not == old_path - response.location.should have_text(/#{assigns[:url_path]}/) - zipfile = Zip::ZipFile.open(File.join(File.dirname(__FILE__), "../../cache/zips", assigns[:url_path])) { |zipfile| - zipfile.count.should == 4 # the message, two hello.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 have_text(/#{assigns[:url_path]}$/) - end - end end end -describe RequestController, "when changing prominence of a request" do +describe RequestController, "when handling prominence" do - before(:each) do - load_raw_emails_data + 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 show hidden requests if logged in as super user" 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] = users(:admin_user) - get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' - response.should render_template('show') - 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 not show requester_only requests if you're not logged in" do - ir = info_requests(:fancy_dog_request) - ir.prominence = 'requester_only' - 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 - get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' - response.should render_template('hidden') 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! + context 'when the request is requester_only' do - 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') + before(:each) do + @info_request = FactoryGirl.create(:info_request_with_incoming_attachments, + :prominence => 'requester_only') + 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('show') + 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(:admin_user).id - get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' - response.should render_template('show') - end + 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') - 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' + session[:user_id] = @info_request.user.id + get :show, :url_title => @info_request.url_title + response.should render_template('show') + + 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 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' 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 have_text(/Second hello/) - response.should render_template('request/hidden') - get :get_attachment, :incoming_message_id => ir.incoming_messages[1].id, - :id => ir.id, - :part => 3, - :skip_cache => 1 - response.content_type.should == "text/html" - response.should_not have_text(/First hello/) - response.should render_template('request/hidden') - response.code.should == '410' end - it 'should not generate an HTML version of an attachment whose prominence is hidden/requester - only even for the requester or an admin but should return a 404' do - ir = info_requests(:fancy_dog_request) - ir.prominence = 'hidden' - ir.save! - receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) - session[:user_id] = users(:admin_user).id - lambda do - get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, - :id => ir.id, - :part => 2, - :file_name => ['hello.txt'] - end.should raise_error(ActiveRecord::RecordNotFound) - end - - it 'should not generate an HTML version of an attachment whose prominence is hidden/requester - only even for the requester or an admin but should return a 404' do - ir = info_requests(:fancy_dog_request) - ir.prominence = 'hidden' - ir.save! - receive_incoming_mail('incoming-request-two-same-name.email', ir.incoming_email) - session[:user_id] = users(:admin_user).id - lambda do - get :get_attachment_as_html, :incoming_message_id => ir.incoming_messages[1].id, - :id => ir.id, - :part => 2, - :file_name => ['hello.txt'] - end.should raise_error(ActiveRecord::RecordNotFound) + 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' 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 @@ -902,11 +907,11 @@ end # end describe RequestController, "when searching for an authority" do - # Whether or not sign-in is required for this step is configurable, # so we make sure we're logged in, just in case before do @user = users(:bob_smith_user) + get_fixtures_xapian_index end it "should return nothing for the empty query string" do @@ -918,6 +923,7 @@ describe RequestController, "when searching for an authority" do end it "should return matching bodies" do + session[:user_id] = @user.id get :select_authority, :query => "Quango" @@ -942,7 +948,7 @@ describe RequestController, "when searching for an authority" do end describe RequestController, "when creating a new request" do - integrate_views + render_views before do @user = users(:bob_smith_user) @@ -973,6 +979,14 @@ describe RequestController, "when creating a new request" do response.should render_template('new') end + it 'should display one meaningful error message when no message body is added' do + post :new, :info_request => { :public_body_id => @body.id }, + :outgoing_message => { :body => "" }, + :submitted_new_request => 1, :preview => 1 + assigns[:info_request].errors.full_messages.should_not include('Outgoing messages is invalid') + assigns[:outgoing_message].errors.full_messages.should include('Body Please enter your letter requesting information') + end + it "should give an error and render 'new' template when a summary isn't given" do post :new, :info_request => { :public_body_id => @body.id }, :outgoing_message => { :body => "This is a silly letter. It is too short to be interesting." }, @@ -1034,7 +1048,7 @@ describe RequestController, "when creating a new request" do response.should redirect_to show_new_request_url(:url_title => ir.url_title) # This test uses an explicit path because it's relied in # Google Analytics goals: - response.redirected_to.should =~ /request\/why_is_your_quango_called_gerald\/new$/ + response.redirect_url.should =~ /request\/why_is_your_quango_called_gerald\/new$/ end it "should give an error if the same request is submitted twice" do @@ -1178,7 +1192,7 @@ describe RequestController, "when making a new request" do end describe RequestController, "when viewing an individual response for reply/followup" do - integrate_views + render_views before(:each) do load_raw_emails_data @@ -1199,7 +1213,7 @@ describe RequestController, "when viewing an individual response for reply/follo it "should offer the opportunity to reply to the main address" do session[:user_id] = users(:bob_smith_user).id get :show_response, :id => info_requests(:fancy_dog_request).id, :incoming_message_id => incoming_messages(:useless_incoming_message) - response.body.should have_tag("div#other_recipients ul li", /the main FOI contact address for/) + response.body.should have_selector("div#other_recipients ul li", :content => "the main FOI contact address for") end it "should offer an opportunity to reply to another address" do @@ -1209,17 +1223,32 @@ describe RequestController, "when viewing an individual response for reply/follo ir.save! receive_incoming_mail('incoming-request-plain.email', ir.incoming_email, "Frob <frob@bonce.com>") get :show_response, :id => ir.id, :incoming_message_id => incoming_messages(:useless_incoming_message) - response.body.should have_tag("div#other_recipients ul li", /Frob/) + response.body.should have_selector("div#other_recipients ul li", :content => "Frob") end - it "should not show individual responses if request hidden, even if request owner" do - ir = info_requests(:fancy_dog_request) - ir.prominence = 'hidden' - ir.save! + context 'when a request is hidden' do + + before do + ir = info_requests(:fancy_dog_request) + ir.prominence = 'hidden' + ir.save! + + session[:user_id] = users(:bob_smith_user).id + end + + it "should not show individual responses, even if request owner" do + get :show_response, :id => info_requests(:fancy_dog_request).id, :incoming_message_id => incoming_messages(:useless_incoming_message) + response.should render_template('request/hidden') + end + + 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 == '403' + end - session[:user_id] = users(:bob_smith_user).id - get :show_response, :id => info_requests(:fancy_dog_request).id, :incoming_message_id => incoming_messages(:useless_incoming_message) - response.should render_template('request/hidden') end describe 'when viewing a response for an external request' do @@ -1248,8 +1277,7 @@ describe RequestController, "when classifying an information request" do end it 'should redirect to the request page' do - post :describe_state, :id => @external_request.id, - :submitted_describe_state => 1 + post :describe_state, :id => @external_request.id response.should redirect_to(:action => 'show', :controller => 'request', :url_title => @external_request.url_title) @@ -1269,8 +1297,7 @@ describe RequestController, "when classifying an information request" do def post_status(status) post :describe_state, :incoming_message => { :described_state => status }, :id => @dog_request.id, - :last_info_request_event_id => @dog_request.last_event_id_needing_description, - :submitted_describe_state => 1 + :last_info_request_event_id => @dog_request.last_event_id_needing_description end it "should require login" do @@ -1280,6 +1307,7 @@ describe RequestController, "when classifying an information request" do end it 'should ask whether the request is old and unclassified' do + session[:user_id] = users(:silly_name_user).id @dog_request.should_receive(:is_old_unclassified?) post_status('rejected') end @@ -1294,7 +1322,9 @@ describe RequestController, "when classifying an information request" do before do @dog_request.stub!(:is_old_unclassified?).and_return(true) - RequestMailer.stub!(:deliver_old_unclassified_updated) + mail_mock = mock("mail") + mail_mock.stub(:deliver) + RequestMailer.stub!(:old_unclassified_updated).and_return(mail_mock) end describe 'when the user is not logged in' do @@ -1317,7 +1347,7 @@ describe RequestController, "when classifying an information request" do it 'should classify the request' do @dog_request.stub!(:calculate_status).and_return('rejected') - @dog_request.should_receive(:set_described_state).with('rejected') + @dog_request.should_receive(:set_described_state).with('rejected', users(:silly_name_user), nil) post_status('rejected') end @@ -1331,7 +1361,7 @@ describe RequestController, "when classifying an information request" do end it 'should send an email to the requester letting them know someone has updated the status of their request' do - RequestMailer.should_receive(:deliver_old_unclassified_updated) + RequestMailer.should_receive(:old_unclassified_updated) post_status('rejected') end @@ -1345,6 +1375,26 @@ describe RequestController, "when classifying an information request" do flash[:notice].should == 'Thank you for updating this request!' end + context "playing the classification game" do + before :each do + session[:request_game] = true + end + + it "should continue the game after classifying a request" do + post_status("rejected") + flash[:notice].should =~ /There are some more requests below for you to classify/ + response.should redirect_to categorise_play_url + end + end + + it "should send a mail from the user who changed the state to requires_admin" do + post :describe_state, :incoming_message => { :described_state => "requires_admin", :message => "a message" }, :id => @dog_request.id, :incoming_message_id => incoming_messages(:useless_incoming_message), :last_info_request_event_id => @dog_request.last_event_id_needing_description + + deliveries = ActionMailer::Base.deliveries + deliveries.size.should == 1 + mail = deliveries[0] + mail.from_addrs.first.to_s.should == users(:silly_name_user).email + end end end @@ -1360,7 +1410,7 @@ describe RequestController, "when classifying an information request" do it 'should update the status of the request' do @dog_request.stub!(:calculate_status).and_return('rejected') - @dog_request.should_receive(:set_described_state).with('rejected') + @dog_request.should_receive(:set_described_state).with('rejected', @admin_user, nil) post_status('rejected') end @@ -1382,7 +1432,9 @@ describe RequestController, "when classifying an information request" do end it 'should send an email to the requester letting them know someone has updated the status of their request' do - RequestMailer.should_receive(:deliver_old_unclassified_updated) + mail_mock = mock("mail") + mail_mock.stub :deliver + RequestMailer.should_receive(:old_unclassified_updated).and_return(mail_mock) post_status('rejected') end @@ -1411,17 +1463,17 @@ describe RequestController, "when classifying an information request" do it 'should update the status of the request' do @dog_request.stub!(:calculate_status).and_return('rejected') - @dog_request.should_receive(:set_described_state).with('rejected') + @dog_request.should_receive(:set_described_state).with('rejected', @admin_user, nil) post_status('rejected') end - it 'should not log a status update event' do - @dog_request.should_not_receive(:log_event) + it 'should log a status update event' do + @dog_request.should_receive(:log_event) post_status('rejected') end it 'should not send an email to the requester letting them know someone has updated the status of their request' do - RequestMailer.should_not_receive(:deliver_old_unclassified_updated) + RequestMailer.should_not_receive(:old_unclassified_updated) post_status('rejected') end @@ -1446,42 +1498,71 @@ describe RequestController, "when classifying an information request" do @dog_request.stub!(:each).and_return([@dog_request]) end + it "should let you know when you forget to select a status" do + post :describe_state, :id => @dog_request.id, + :last_info_request_event_id => @dog_request.last_event_id_needing_description + response.should redirect_to show_request_url(:url_title => @dog_request.url_title) + flash[:error].should == _("Please choose whether or not you got some of the information that you wanted.") + end + + it "should not change the status if the request has changed while viewing it" do + @dog_request.stub!(:last_event_id_needing_description).and_return(2) + + post :describe_state, :incoming_message => { :described_state => "rejected" }, + :id => @dog_request.id, :last_info_request_event_id => 1 + response.should redirect_to show_request_url(:url_title => @dog_request.url_title) + flash[:error].should =~ /The request has been updated since you originally loaded this page/ + end + it "should successfully classify response if logged in as user controlling request" do post_status('rejected') response.should redirect_to(:controller => 'help', :action => 'unhappy', :url_title => @dog_request.url_title) @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_response_event.calculated_state.should == 'rejected' + @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 - it 'should not log a status update event' do - @dog_request.should_not_receive(:log_event) + it 'should log a status update event' do + @dog_request.should_receive(:log_event) post_status('rejected') end it 'should not send an email to the requester letting them know someone has updated the status of their request' do - RequestMailer.should_not_receive(:deliver_old_unclassified_updated) + RequestMailer.should_not_receive(:old_unclassified_updated) post_status('rejected') end - it "should send email when classified as requires_admin" do - post :describe_state, :incoming_message => { :described_state => "requires_admin" }, :id => @dog_request.id, :incoming_message_id => incoming_messages(:useless_incoming_message), :last_info_request_event_id => @dog_request.last_event_id_needing_description, :submitted_describe_state => 1 - response.should redirect_to(:controller => 'help', :action => 'contact') + it "should go to the page asking for more information when classified as requires_admin" do + post :describe_state, :incoming_message => { :described_state => "requires_admin" }, :id => @dog_request.id, :incoming_message_id => incoming_messages(:useless_incoming_message), :last_info_request_event_id => @dog_request.last_event_id_needing_description + response.should redirect_to describe_state_message_url(:url_title => @dog_request.url_title, :described_state => "requires_admin") @dog_request.reload - @dog_request.awaiting_description.should == false - @dog_request.described_state.should == 'requires_admin' - @dog_request.get_last_response_event.calculated_state.should == 'requires_admin' + @dog_request.described_state.should_not == 'requires_admin' - deliveries = ActionMailer::Base.deliveries - deliveries.size.should == 1 - mail = deliveries[0] - mail.body.should =~ /as needing admin/ - mail.from_addrs.first.to_s.should == @request_owner.name_and_email + ActionMailer::Base.deliveries.should be_empty end + context "message is included when classifying as requires_admin" do + it "should send an email including the message" do + post :describe_state, + :incoming_message => { + :described_state => "requires_admin", + :message => "Something weird happened" }, + :id => @dog_request.id, + :last_info_request_event_id => @dog_request.last_event_id_needing_description + + deliveries = ActionMailer::Base.deliveries + deliveries.size.should == 1 + mail = deliveries[0] + mail.body.should =~ /as needing admin/ + mail.body.should =~ /Something weird happened/ + end + end + + it 'should say it is showing advice as to what to do next' do post_status('rejected') flash[:notice].should match(/Here is what to do now/) @@ -1505,7 +1586,7 @@ describe RequestController, "when classifying an information request" do end end - describe 'when redirecting after a successful status update by the request owner' do + describe 'after a successful status update by the request owner' do before do @request_owner = users(:bob_smith_user) @@ -1513,11 +1594,6 @@ describe RequestController, "when classifying an information request" do @dog_request = info_requests(:fancy_dog_request) @dog_request.stub!(:each).and_return([@dog_request]) InfoRequest.stub!(:find).and_return(@dog_request) - @old_filters = ActionController::Routing::Routes.filters - ActionController::Routing::Routes.filters = RoutingFilter::Chain.new - end - after do - ActionController::Routing::Routes.filters = @old_filters end def request_url @@ -1533,77 +1609,161 @@ describe RequestController, "when classifying an information request" do response.should redirect_to("http://test.host/#{redirect_path}") end - it 'should redirect to the "request url" with a message in the right tense when status is updated to "waiting response" and the response is not overdue' do - @dog_request.stub!(:date_response_required_by).and_return(Time.now.to_date+1) - @dog_request.stub!(:date_very_overdue_after).and_return(Time.now.to_date+40) + context 'when status is updated to "waiting_response"' do - expect_redirect("waiting_response", "request/#{@dog_request.url_title}") - flash[:notice].should match(/should get a response/) - end + it 'should redirect to the "request url" with a message in the right tense when + the response is not overdue' do + @dog_request.stub!(:date_response_required_by).and_return(Time.now.to_date+1) + @dog_request.stub!(:date_very_overdue_after).and_return(Time.now.to_date+40) - it 'should redirect to the "request url" with a message in the right tense when status is updated to "waiting response" and the response is overdue' do - @dog_request.stub!(:date_response_required_by).and_return(Time.now.to_date-1) - @dog_request.stub!(:date_very_overdue_after).and_return(Time.now.to_date+40) - expect_redirect('waiting_response', request_url) - flash[:notice].should match(/should have got a response/) - end + expect_redirect("waiting_response", "request/#{@dog_request.url_title}") + flash[:notice].should match(/should get a response/) + end - it 'should redirect to the "request url" with a message in the right tense when status is updated to "waiting response" and the response is overdue' do - @dog_request.stub!(:date_response_required_by).and_return(Time.now.to_date-2) - @dog_request.stub!(:date_very_overdue_after).and_return(Time.now.to_date-1) - expect_redirect('waiting_response', unhappy_url) - flash[:notice].should match(/is long overdue/) - flash[:notice].should match(/by more than 40 working days/) - flash[:notice].should match(/within 20 working days/) - end + it 'should redirect to the "request url" with a message in the right tense when + the response is overdue' do + @dog_request.stub!(:date_response_required_by).and_return(Time.now.to_date-1) + @dog_request.stub!(:date_very_overdue_after).and_return(Time.now.to_date+40) + expect_redirect('waiting_response', request_url) + flash[:notice].should match(/should have got a response/) + end - it 'should redirect to the "request url" when status is updated to "not held"' do - expect_redirect('not_held', request_url) + it 'should redirect to the "request url" with a message in the right tense when + the response is overdue' do + @dog_request.stub!(:date_response_required_by).and_return(Time.now.to_date-2) + @dog_request.stub!(:date_very_overdue_after).and_return(Time.now.to_date-1) + expect_redirect('waiting_response', unhappy_url) + flash[:notice].should match(/is long overdue/) + flash[:notice].should match(/by more than 40 working days/) + flash[:notice].should match(/within 20 working days/) + end end - it 'should redirect to the "request url" when status is updated to "successful"' do - expect_redirect('successful', request_url) - end + context 'when status is updated to "not held"' do + + it 'should redirect to the "request url"' do + expect_redirect('not_held', request_url) + end - it 'should redirect to the "unhappy url" when status is updated to "rejected"' do - expect_redirect('rejected', "help/unhappy/#{@dog_request.url_title}") end - it 'should redirect to the "unhappy url" when status is updated to "partially successful"' do - expect_redirect('partially_successful', "help/unhappy/#{@dog_request.url_title}") + context 'when status is updated to "successful"' do + + it 'should redirect to the "request url"' do + expect_redirect('successful', request_url) + end + + it 'should show a message including the donation url if there is one' do + AlaveteliConfiguration.stub!(:donation_url).and_return('http://donations.example.com') + post_status('successful') + flash[:notice].should match('make a donation') + flash[:notice].should match('http://donations.example.com') + end + + it 'should show a message without reference to donations if there is no + donation url' do + AlaveteliConfiguration.stub!(:donation_url).and_return('') + post_status('successful') + flash[:notice].should_not match('make a donation') + end + end - it 'should redirect to the "response url" when status is updated to "waiting clarification" and there is a last response' do - incoming_message = mock_model(IncomingMessage) - @dog_request.stub!(:get_last_response).and_return(incoming_message) - expect_redirect('waiting_clarification', "request/#{@dog_request.id}/response/#{incoming_message.id}") + context 'when status is updated to "waiting clarification"' 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_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_public_response).and_return(nil) + expect_redirect('waiting_clarification', "request/#{@dog_request.id}/response") + end + end - it 'should redirect to the "response no followup url" when status is updated to "waiting clarification" and there are no events needing description' do - @dog_request.stub!(:get_last_response).and_return(nil) - expect_redirect('waiting_clarification', "request/#{@dog_request.id}/response") + context 'when status is updated to "rejected"' do + + it 'should redirect to the "unhappy url"' do + expect_redirect('rejected', "help/unhappy/#{@dog_request.url_title}") + end + end - it 'should redirect to the "respond to last url" when status is updated to "gone postal"' do - expect_redirect('gone_postal', "request/#{@dog_request.id}/response/#{@dog_request.get_last_response.id}?gone_postal=1") + context 'when status is updated to "partially successful"' do + + it 'should redirect to the "unhappy url"' do + expect_redirect('partially_successful', "help/unhappy/#{@dog_request.url_title}") + end + + it 'should show a message including the donation url if there is one' do + AlaveteliConfiguration.stub!(:donation_url).and_return('http://donations.example.com') + post_status('successful') + flash[:notice].should match('make a donation') + flash[:notice].should match('http://donations.example.com') + end + + it 'should show a message without reference to donations if there is no + donation url' do + AlaveteliConfiguration.stub!(:donation_url).and_return('') + post_status('successful') + flash[:notice].should_not match('make a donation') + end + end - it 'should redirect to the "request url" when status is updated to "internal review"' do - expect_redirect('internal_review', request_url) + 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_public_response.id}?gone_postal=1") + end + end - it 'should redirect to the "help general url" when status is updated to "requires admin"' do - expect_redirect('requires_admin', "help/contact") + context 'when status updated to "internal review"' do + + it 'should redirect to the "request url"' do + expect_redirect('internal_review', request_url) + end + end - it 'should redirect to the "help general url" when status is updated to "error message"' do - expect_redirect('error_message', "help/contact") + context 'when status is updated to "requires admin"' do + + it 'should redirect to the "request url"' do + post :describe_state, :incoming_message => { + :described_state => 'requires_admin', + :message => "A message" }, + :id => @dog_request.id, + :last_info_request_event_id => @dog_request.last_event_id_needing_description + response.should redirect_to show_request_url(:url_title => @dog_request.url_title) + end + end - it 'should redirect to the "respond to last url url" when status is updated to "user_withdrawn"' do - expect_redirect('user_withdrawn', "request/#{@dog_request.id}/response/#{@dog_request.get_last_response.id}") + context 'when status is updated to "error message"' do + + it 'should redirect to the "request url"' do + post :describe_state, :incoming_message => { + :described_state => 'error_message', + :message => "A message" }, + :id => @dog_request.id, + :last_info_request_event_id => @dog_request.last_event_id_needing_description + response.should redirect_to show_request_url(:url_title => @dog_request.url_title) + end + end + 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_public_response.id}") + end + + end end end @@ -1611,7 +1771,7 @@ describe RequestController, "when classifying an information request" do end describe RequestController, "when sending a followup message" do - integrate_views + render_views before(:each) do load_raw_emails_data @@ -1653,7 +1813,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 @@ -1664,14 +1824,14 @@ describe RequestController, "when sending a followup message" do deliveries.size.should == 1 mail = deliveries[0] mail.body.should =~ /What a useless response! You suck./ - mail.to_addrs.first.to_s.should == "FOI Person <foiperson@localhost>" + mail.to_addrs.first.to_s.should == "foiperson@localhost" response.should redirect_to(:action => 'show', :url_title => info_requests(:fancy_dog_request).url_title) # 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 @@ -1693,7 +1853,7 @@ end # it can't check the URLs in the emails I don't think, ugh. describe RequestController, "sending overdue request alerts" do - integrate_views + render_views before(:each) do load_raw_emails_data @@ -1711,9 +1871,9 @@ describe RequestController, "sending overdue request alerts" do mail = chicken_mails[0] mail.body.should =~ /promptly, as normally/ - mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.name_and_email + mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.email - mail.body =~ /(http:\/\/.*\/c\/(.*))/ + mail.body.to_s =~ /(http:\/\/.*\/c\/(.*))/ mail_url = $1 mail_token = $2 @@ -1740,7 +1900,7 @@ describe RequestController, "sending overdue request alerts" do mail = chicken_mails[0] mail.body.should =~ /promptly, as normally/ - mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.name_and_email + mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.email end it "should send not actually send the overdue alert if the user is banned but should @@ -1768,9 +1928,9 @@ describe RequestController, "sending overdue request alerts" do mail = chicken_mails[0] mail.body.should =~ /required by law/ - mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.name_and_email + mail.to_addrs.first.to_s.should == info_requests(:naughty_chicken_request).user.email - mail.body =~ /(http:\/\/.*\/c\/(.*))/ + mail.body.to_s =~ /(http:\/\/.*\/c\/(.*))/ mail_url = $1 mail_token = $2 @@ -1838,7 +1998,7 @@ describe RequestController, "sending overdue request alerts" do end describe RequestController, "sending unclassified new response reminder alerts" do - integrate_views + render_views before(:each) do load_raw_emails_data @@ -1851,8 +2011,8 @@ describe RequestController, "sending unclassified new response reminder alerts" deliveries.size.should == 3 # sufficiently late it sends reminders too mail = deliveries[0] mail.body.should =~ /To let everyone know/ - mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.name_and_email - mail.body =~ /(http:\/\/.*\/c\/(.*))/ + mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.email + mail.body.to_s =~ /(http:\/\/.*\/c\/(.*))/ mail_url = $1 mail_token = $2 @@ -1868,7 +2028,7 @@ describe RequestController, "sending unclassified new response reminder alerts" end describe RequestController, "clarification required alerts" do - integrate_views + render_views before(:each) do load_raw_emails_data end @@ -1887,8 +2047,8 @@ describe RequestController, "clarification required alerts" do deliveries.size.should == 1 mail = deliveries[0] mail.body.should =~ /asked you to explain/ - mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.name_and_email - mail.body =~ /(http:\/\/.*\/c\/(.*))/ + mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.email + mail.body.to_s =~ /(http:\/\/.*\/c\/(.*))/ mail_url = $1 mail_token = $2 @@ -1921,7 +2081,7 @@ describe RequestController, "clarification required alerts" do end describe RequestController, "comment alerts" do - integrate_views + render_views before(:each) do load_raw_emails_data end @@ -1940,8 +2100,8 @@ describe RequestController, "comment alerts" do deliveries = ActionMailer::Base.deliveries mail = deliveries[0] mail.body.should =~ /has annotated your/ - mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.name_and_email - mail.body =~ /(http:\/\/.*)/ + mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.email + mail.body.to_s =~ /(http:\/\/.*)/ mail_url = $1 mail_url.should match("/request/why_do_you_have_such_a_fancy_dog#comment-#{new_comment.id}") @@ -1990,8 +2150,8 @@ describe RequestController, "comment alerts" do deliveries.size.should == 1 mail = deliveries[0] mail.body.should =~ /There are 2 new annotations/ - mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.name_and_email - mail.body =~ /(http:\/\/.*)/ + mail.to_addrs.first.to_s.should == info_requests(:fancy_dog_request).user.email + mail.body.to_s =~ /(http:\/\/.*)/ mail_url = $1 mail_url.should match("/request/why_do_you_have_such_a_fancy_dog#comment-#{comments(:silly_comment).id}") @@ -2000,7 +2160,7 @@ describe RequestController, "comment alerts" do end describe RequestController, "when viewing comments" do - integrate_views + render_views before(:each) do load_raw_emails_data end @@ -2008,22 +2168,26 @@ describe RequestController, "when viewing comments" do it "should link to the user who submitted it" do session[:user_id] = users(:bob_smith_user).id get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' - response.body.should have_tag("div#comment-1 h2", /Silly.*left an annotation/m) - response.body.should_not have_tag("div#comment-1 h2", /You.*left an annotation/m) + response.body.should have_selector("div#comment-1 h2") do |s| + s.should contain /Silly.*left an annotation/m + s.should_not contain /You.*left an annotation/m + end end it "should link to the user who submitted to it, even if it is you" do session[:user_id] = users(:silly_name_user).id get :show, :url_title => 'why_do_you_have_such_a_fancy_dog' - response.body.should have_tag("div#comment-1 h2", /Silly.*left an annotation/m) - response.body.should_not have_tag("div#comment-1 h2", /You.*left an annotation/m) + response.body.should have_selector("div#comment-1 h2") do |s| + s.should contain /Silly.*left an annotation/m + s.should_not contain /You.*left an annotation/m + end end end describe RequestController, "authority uploads a response from the web interface" do - integrate_views + render_views before(:each) do # domain after the @ is used for authentication of FOI officers, so to test it @@ -2061,7 +2225,7 @@ describe RequestController, "authority uploads a response from the web interface session[:user_id] = @normal_user.id # post up a photo of the parrot - parrot_upload = fixture_file_upload('files/parrot.png','image/png') + parrot_upload = fixture_file_upload('/files/parrot.png','image/png') post :upload_response, :url_title => 'why_do_you_have_such_a_fancy_dog', :body => "Find attached a picture of a parrot", :file_1 => parrot_upload, @@ -2089,7 +2253,7 @@ describe RequestController, "authority uploads a response from the web interface session[:user_id] = @foi_officer_user.id # post up a photo of the parrot - parrot_upload = fixture_file_upload('files/parrot.png','image/png') + parrot_upload = fixture_file_upload('/files/parrot.png','image/png') post :upload_response, :url_title => 'why_do_you_have_such_a_fancy_dog', :body => "Find attached a picture of a parrot", :file_1 => parrot_upload, @@ -2113,7 +2277,6 @@ describe RequestController, "authority uploads a response from the web interface end describe RequestController, "when showing JSON version for API" do - before(:each) do load_raw_emails_data end @@ -2132,25 +2295,28 @@ describe RequestController, "when showing JSON version for API" do end describe RequestController, "when doing type ahead searches" do + render_views - integrate_views + before :each do + get_fixtures_xapian_index + end it "should return nothing for the empty query string" do get :search_typeahead, :q => "" - response.should render_template('request/_search_ahead.rhtml') + response.should render_template('request/_search_ahead') assigns[:xapian_requests].should be_nil end it "should return a request matching the given keyword, but not users with a matching description" do get :search_typeahead, :q => "chicken" - response.should render_template('request/_search_ahead.rhtml') + response.should render_template('request/_search_ahead') assigns[:xapian_requests].results.size.should == 1 assigns[:xapian_requests].results[0][:model].title.should == info_requests(:naughty_chicken_request).title end it "should return all requests matching any of the given keywords" do get :search_typeahead, :q => "money dog" - response.should render_template('request/_search_ahead.rhtml') + response.should render_template('request/_search_ahead') assigns[:xapian_requests].results.map{|x|x[:model].info_request}.should =~ [ info_requests(:fancy_dog_request), info_requests(:naughty_chicken_request), @@ -2160,13 +2326,13 @@ describe RequestController, "when doing type ahead searches" do it "should not return matches for short words" do get :search_typeahead, :q => "a" - response.should render_template('request/_search_ahead.rhtml') + response.should render_template('request/_search_ahead') assigns[:xapian_requests].should be_nil end it "should do partial matches for longer words" do get :search_typeahead, :q => "chick" - response.should render_template('request/_search_ahead.rhtml') + response.should render_template('request/_search_ahead') assigns[:xapian_requests].results.size.should ==1 end @@ -2191,7 +2357,12 @@ describe RequestController, "when doing type ahead searches" do end describe RequestController, "when showing similar requests" do - integrate_views + render_views + + before do + get_fixtures_xapian_index + load_raw_emails_data + end it "should work" do get :similar, :url_title => info_requests(:badger_request).url_title @@ -2223,93 +2394,7 @@ describe RequestController, "when showing similar requests" do end - -describe RequestController, "when reporting a request when not logged in" do - it "should only allow logged-in users to report requests" do - get :report_request, :url_title => info_requests(:badger_request).url_title - post_redirect = PostRedirect.get_last_post_redirect - response.should redirect_to(:controller => 'user', :action => 'signin', :token => post_redirect.token) - end -end - -describe RequestController, "when reporting a request (logged in)" do - integrate_views - - before do - @user = users(:robin_user) - session[:user_id] = @user.id - end - - it "should 404 for non-existent requests" do - lambda { - post :report_request, :url_title => "hjksfdhjk_louytu_qqxxx" - }.should raise_error(ActiveRecord::RecordNotFound) - end - - it "should mark a request as having been reported" do - ir = info_requests(:badger_request) - title = ir.url_title - get :show, :url_title => title - assigns[:info_request].attention_requested.should == false - - post :report_request, :url_title => title - response.should redirect_to(:action => :show, :url_title => title) - - get :show, :url_title => title - response.should be_success - assigns[:info_request].attention_requested.should == true - assigns[:info_request].described_state.should == "attention_requested" - end - - it "should not allow a request to be reported twice" do - title = info_requests(:badger_request).url_title - - post :report_request, :url_title => title - response.should redirect_to(:action => :show, :url_title => title) - get :show, :url_title => title - response.should be_success - response.body.should include("has been reported") - - post :report_request, :url_title => title - response.should redirect_to(:action => :show, :url_title => title) - get :show, :url_title => title - response.should be_success - response.body.should include("has already been reported") - end - - it "should let users know a request has been reported" do - title = info_requests(:badger_request).url_title - get :show, :url_title => title - response.body.should include("Offensive?") - - post :report_request, :url_title => title - response.should redirect_to(:action => :show, :url_title => title) - - get :show, :url_title => title - response.body.should_not include("Offensive?") - response.body.should include("This request has been reported") - - info_requests(:badger_request).set_described_state("successful") - get :show, :url_title => title - response.body.should_not include("This request has been reported") - response.body.should =~ (/the site administrators.*have not hidden it/) - end - - it "should send an email from the reporter to admins" do - ir = info_requests(:badger_request) - title = ir.url_title - post :report_request, :url_title => title - deliveries = ActionMailer::Base.deliveries - deliveries.size.should == 1 - mail = deliveries[0] - mail.subject.should =~ /attention_requested/ - mail.from.should include(@user.email) - mail.body.should include(@user.name) - end -end - describe RequestController, "when caching fragments" do - it "should not fail with long filenames" do long_name = "blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah.txt" info_request = mock(InfoRequest, :user_can_view? => true, @@ -2319,13 +2404,15 @@ 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) - IncomingMessage.stub!(:get_attachment_by_url_part_number).and_return(attachment) + IncomingMessage.stub!(:get_attachment_by_url_part_number_and_filename).and_return(attachment) InfoRequest.stub!(:find).with("132").and_return(info_request) - params = { :file_name => [long_name], + params = { :file_name => long_name, :controller => "request", :action => "get_attachment_as_html", :id => "132", @@ -2336,4 +2423,268 @@ describe RequestController, "when caching fragments" do end +describe RequestController, "#new_batch" do + + context "when batch requests is enabled" do + + before do + AlaveteliConfiguration.stub!(:allow_batch_requests).and_return(true) + end + + context "when the current user can make batch requests" do + + before do + @user = FactoryGirl.create(:user, :can_make_batch_requests => true) + @public_body = FactoryGirl.create(:public_body) + @other_public_body = FactoryGirl.create(:public_body) + @public_body_ids = [@public_body.id, @other_public_body.id] + @default_post_params = { :info_request => { :title => "What does it all mean?", + :tag_string => "" }, + :public_body_ids => @public_body_ids, + :outgoing_message => { :body => "This is a silly letter." }, + :submitted_new_request => 1, + :preview => 1 } + end + + it 'should be successful' do + get :new_batch, {:public_body_ids => @public_body_ids}, {:user_id => @user.id} + response.should be_success + end + + it 'should render the "new" template' do + get :new_batch, {:public_body_ids => @public_body_ids}, {:user_id => @user.id} + response.should render_template('request/new') + end + + it 'should redirect to "select_authorities" if no public_body_ids param is passed' do + get :new_batch, {}, {:user_id => @user.id} + response.should redirect_to select_authorities_path + end + + it "should render 'preview' when given a good title and body" do + post :new_batch, @default_post_params, { :user_id => @user.id } + response.should render_template('preview') + end + + it "should give an error and render 'new' template when a summary isn't given" do + @default_post_params[:info_request].delete(:title) + post :new_batch, @default_post_params, { :user_id => @user.id } + assigns[:info_request].errors[:title].should == ['Please enter a summary of your request'] + response.should render_template('new') + end + + it "should allow re-editing of a request" do + params = @default_post_params.merge(:preview => 0, :reedit => 1) + post :new_batch, params, { :user_id => @user.id } + response.should render_template('new') + end + + context "on success" do + + def make_request + @params = @default_post_params.merge(:preview => 0) + post :new_batch, @params, { :user_id => @user.id } + end + + it 'should create an info request batch and redirect to the new batch on success' do + make_request + new_info_request_batch = assigns[:info_request_batch] + new_info_request_batch.should_not be_nil + response.should redirect_to(info_request_batch_path(new_info_request_batch)) + end + + it 'should prevent double submission of a batch request' do + make_request + post :new_batch, @params, { :user_id => @user.id } + response.should render_template('new') + assigns[:existing_batch].should_not be_nil + end + + it 'should display a success notice' do + make_request + notice_text = "<p>Your Freedom of Information requests will be <strong>sent</strong> shortly!" + flash[:notice].should match notice_text + end + + end + + context "when the user is banned" do + + before do + @user.ban_text = "bad behaviour" + @user.save! + end + + it 'should show the "banned" template' do + post :new_batch, @default_post_params, { :user_id => @user.id } + response.should render_template('user/banned') + assigns[:details].should == 'bad behaviour' + end + + end + + end + + context "when the current user can't make batch requests" do + + render_views + + before do + @user = FactoryGirl.create(:user) + end + + it 'should return a 403 with an appropriate message' do + get :new_batch, {}, {:user_id => @user.id} + response.code.should == '403' + response.body.should match("Users cannot usually make batch requests to multiple authorities at once") + end + + end + + context 'when there is no logged-in user' do + + it 'should return a redirect to the login page' do + get :new_batch + post_redirect = PostRedirect.get_last_post_redirect + response.should redirect_to(:controller => 'user', :action => 'signin', :token => post_redirect.token) + end + end + + + end + + context "when batch requests is not enabled" do + + it 'should return a 404' do + Rails.application.config.stub!(:consider_all_requests_local).and_return(false) + get :new_batch + response.code.should == '404' + end + + end + +end + +describe RequestController, "#select_authorities" do + + context "when batch requests is enabled" do + + before do + get_fixtures_xapian_index + load_raw_emails_data + AlaveteliConfiguration.stub!(:allow_batch_requests).and_return(true) + end + + context "when the current user can make batch requests" do + + before do + @user = FactoryGirl.create(:user, :can_make_batch_requests => true) + end + + context 'when asked for HTML' do + + it 'should be successful' do + get :select_authorities, {}, {:user_id => @user.id} + response.should be_success + end + + it 'should render the "select_authorities" template' do + get :select_authorities, {}, {:user_id => @user.id} + response.should render_template('request/select_authorities') + end + + it 'should assign a list of search results to the view if passed a query' do + get :select_authorities, {:public_body_query => "Quango"}, {:user_id => @user.id} + assigns[:search_bodies].results.size.should == 1 + assigns[:search_bodies].results[0][:model].name.should == public_bodies(:geraldine_public_body).name + end + + it 'should assign a list of public bodies to the view if passed a list of ids' do + get :select_authorities, {:public_body_ids => [public_bodies(:humpadink_public_body).id]}, + {:user_id => @user.id} + assigns[:public_bodies].size.should == 1 + assigns[:public_bodies][0].name.should == public_bodies(:humpadink_public_body).name + end + + it 'should subtract a list of public bodies to remove from the list of bodies assigned to + the view' do + get :select_authorities, {:public_body_ids => [public_bodies(:humpadink_public_body).id, + public_bodies(:geraldine_public_body).id], + :remove_public_body_ids => [public_bodies(:geraldine_public_body).id]}, + {:user_id => @user.id} + assigns[:public_bodies].size.should == 1 + assigns[:public_bodies][0].name.should == public_bodies(:humpadink_public_body).name + end + + end + + context 'when asked for JSON', :focus => true do + + it 'should be successful' do + get :select_authorities, {:public_body_query => "Quan", :format => 'json'}, {:user_id => @user.id} + response.should be_success + end + + it 'should return a list of public body names and ids' do + get :select_authorities, {:public_body_query => "Quan", :format => 'json'}, + {:user_id => @user.id} + + JSON(response.body).should == [{ 'id' => public_bodies(:geraldine_public_body).id, + 'name' => public_bodies(:geraldine_public_body).name }] + end + + it 'should return an empty list if no search is passed' do + get :select_authorities, {:format => 'json' },{:user_id => @user.id} + JSON(response.body).should == [] + end + + it 'should return an empty list if there are no bodies' do + get :select_authorities, {:public_body_query => 'fknkskalnr', :format => 'json' }, + {:user_id => @user.id} + JSON(response.body).should == [] + end + + end + + end + + context "when the current user can't make batch requests" do + + render_views + + before do + @user = FactoryGirl.create(:user) + end + + it 'should return a 403 with an appropriate message' do + get :select_authorities, {}, {:user_id => @user.id} + response.code.should == '403' + response.body.should match("Users cannot usually make batch requests to multiple authorities at once") + end + + end + + context 'when there is no logged-in user' do + + it 'should return a redirect to the login page' do + get :select_authorities + post_redirect = PostRedirect.get_last_post_redirect + response.should redirect_to(:controller => 'user', :action => 'signin', :token => post_redirect.token) + end + end + + + end + + context "when batch requests is not enabled" do + + it 'should return a 404' do + Rails.application.config.stub!(:consider_all_requests_local).and_return(false) + get :select_authorities + response.code.should == '404' + end + + end + +end |