diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/controllers/admin_public_body_controller_spec.rb | 116 | ||||
-rw-r--r-- | spec/controllers/api_controller_spec.rb | 54 | ||||
-rw-r--r-- | spec/controllers/services_controller_spec.rb | 14 | ||||
-rw-r--r-- | spec/models/censor_rule_spec.rb | 206 | ||||
-rw-r--r-- | spec/models/incoming_message_spec.rb | 33 | ||||
-rw-r--r-- | spec/models/info_request_spec.rb | 281 | ||||
-rw-r--r-- | spec/spec_helper.rb | 13 | ||||
-rw-r--r-- | spec/views/request/_after_actions.rhtml_spec.rb | 2 | ||||
-rw-r--r-- | spec/views/request/_describe_state.rhtml_spec.rb | 7 | ||||
-rw-r--r-- | spec/views/request/show.rhtml_spec.rb | 2 |
10 files changed, 578 insertions, 150 deletions
diff --git a/spec/controllers/admin_public_body_controller_spec.rb b/spec/controllers/admin_public_body_controller_spec.rb index 55a6649b2..be33802c5 100644 --- a/spec/controllers/admin_public_body_controller_spec.rb +++ b/spec/controllers/admin_public_body_controller_spec.rb @@ -50,7 +50,7 @@ describe AdminPublicBodyController, "when administering public bodies" do response.should redirect_to(:controller=>'admin_public_body', :action=>'show', :id => id) PublicBody.count.should == n end - + it "destroys a public body" do n = PublicBody.count post :destroy, { :id => public_bodies(:forlorn_public_body).id } @@ -70,6 +70,86 @@ describe AdminPublicBodyController, "when administering public bodies" do response.should redirect_to(:action=>'list') PublicBody.find_by_tag("department").count.should == n end + + describe 'import_csv' do + + describe 'when handling a GET request' do + + it 'should get the page successfully' do + get :import_csv + response.should be_success + end + + end + + describe 'when handling a POST request' do + + before do + PublicBody.stub!(:import_csv).and_return([[],[]]) + @file_object = mock("a file upload", :read => 'some contents', + :original_filename => 'contents.txt') + end + + it 'should handle a nil csv file param' do + post :import_csv, { :commit => 'Dry run' } + response.should be_success + end + + describe 'if there is a csv file param' do + + it 'should try to get the contents and original name of a csv file param' do + @file_object.should_receive(:read).and_return('some contents') + post :import_csv, { :csv_file => @file_object, + :commit => 'Dry run'} + end + + it 'should assign the original filename to the view' do + post :import_csv, { :csv_file => @file_object, + :commit => 'Dry run'} + assigns[:original_csv_file].should == 'contents.txt' + end + + end + + describe 'if there is no csv file param, but there are temporary_csv_file and + original_csv_file params' do + + it 'should try and get the file contents from a temporary file whose name + is passed as a param' do + @controller.should_receive(:retrieve_csv_data).with('csv_upload-2046-12-31-394') + post :import_csv, { :temporary_csv_file => 'csv_upload-2046-12-31-394', + :original_csv_file => 'original_contents.txt', + :commit => 'Dry run'} + end + + it 'should raise an error on an invalid temp file name' do + params = { :temporary_csv_file => 'bad_name', + :original_csv_file => 'original_contents.txt', + :commit => 'Dry run'} + expected_error = "Invalid filename in upload_csv: bad_name" + lambda{ post :import_csv, params }.should raise_error(expected_error) + end + + it 'should raise an error if the temp file does not exist' do + temp_name = "csv_upload-20461231-394" + params = { :temporary_csv_file => temp_name, + :original_csv_file => 'original_contents.txt', + :commit => 'Dry run'} + expected_error = "Missing file in upload_csv: csv_upload-20461231-394" + lambda{ post :import_csv, params }.should raise_error(expected_error) + end + + it 'should assign the temporary filename to the view' do + post :import_csv, { :csv_file => @file_object, + :commit => 'Dry run'} + temporary_filename = assigns[:temporary_csv_file] + temporary_filename.should match(/csv_upload-#{Time.now.strftime("%Y%m%d")}-\d{1,5}/) + end + + end + + end + end end describe AdminPublicBodyController, "when administering public bodies and paying attention to authentication" do @@ -79,7 +159,7 @@ describe AdminPublicBodyController, "when administering public bodies and paying before do config = MySociety::Config.load_default() config['SKIP_ADMIN_AUTH'] = false - basic_auth_login @request + basic_auth_login @request end after do config = MySociety::Config.load_default() @@ -106,7 +186,7 @@ describe AdminPublicBodyController, "when administering public bodies and paying PublicBody.count.should == n - 1 session[:using_admin].should == 1 end - + it "doesn't let people with bad credentials log in" do config = MySociety::Config.load_default() config['SKIP_ADMIN_AUTH'] = false @@ -159,7 +239,7 @@ end describe AdminPublicBodyController, "when administering public bodies with i18n" do integrate_views - + it "shows the index page" do get :index end @@ -175,7 +255,7 @@ describe AdminPublicBodyController, "when administering public bodies with i18n" it "edits a public body" do get :edit, {:id => 3, :locale => :en} - + # When editing a body, the controller returns all available translations assigns[:public_body].translation("es").name.should == 'El Department for Humpadinking' assigns[:public_body].name.should == 'Department for Humpadinking' @@ -186,20 +266,20 @@ describe AdminPublicBodyController, "when administering public bodies with i18n" PublicBody.with_locale(:es) do pb = PublicBody.find(id=3) pb.name.should == "El Department for Humpadinking" - post :update, { - :id => 3, - :public_body => { - :name => "Department for Humpadinking", - :short_name => "", - :tag_string => "some tags", - :request_email => 'edited@localhost', + post :update, { + :id => 3, + :public_body => { + :name => "Department for Humpadinking", + :short_name => "", + :tag_string => "some tags", + :request_email => 'edited@localhost', :last_edit_comment => 'From test code', :translated_versions => { 3 => {:locale => "es", :name => "Renamed",:short_name => "", :request_email => 'edited@localhost'} } } } - response.flash[:notice].should include('successful') + response.flash[:notice].should include('successful') end pb = PublicBody.find(public_bodies(:humpadink_public_body).id) @@ -221,7 +301,7 @@ end describe AdminPublicBodyController, "when creating public bodies with i18n" do integrate_views - + before do @old_filters = ActionController::Routing::Routes.filters ActionController::Routing::Routes.filters = RoutingFilter::Chain.new @@ -242,14 +322,14 @@ describe AdminPublicBodyController, "when creating public bodies with i18n" do it "creates a new public body with multiple locales" do n = PublicBody.count - post :create, { - :public_body => { + post :create, { + :public_body => { :name => "New Quango", :short_name => "", :tag_string => "blah", :request_email => 'newquango@localhost', :last_edit_comment => 'From test code', :translated_versions => [{ :locale => "es", :name => "Mi Nuevo Quango", :short_name => "", :request_email => 'newquango@localhost' }] } } PublicBody.count.should == n + 1 - + body = PublicBody.find_by_name("New Quango") body.translations.map {|t| t.locale.to_s}.sort.should == ["en", "es"] PublicBody.with_locale(:en) do @@ -262,7 +342,7 @@ describe AdminPublicBodyController, "when creating public bodies with i18n" do body.url_name.should == "mi_nuevo_quango" body.first_letter.should == "M" end - + response.should redirect_to(:controller=>'admin_public_body', :action=>'show', :id=>body.id) end end diff --git a/spec/controllers/api_controller_spec.rb b/spec/controllers/api_controller_spec.rb index 1f65576b6..98751a93a 100644 --- a/spec/controllers/api_controller_spec.rb +++ b/spec/controllers/api_controller_spec.rb @@ -260,4 +260,58 @@ describe ApiController, "when using the API" do # assigns them and changing assignment to an equality # check, which does not really test anything at all. end + + it "should show an Atom feed of new request events" do + get :body_request_events, + :id => public_bodies(:geraldine_public_body).id, + :k => public_bodies(:geraldine_public_body).api_key, + :feed_type => "atom" + + response.should be_success + response.should render_template("api/request_events.atom") + assigns[:events].size.should > 0 + assigns[:events].each do |event| + event.info_request.public_body.should == public_bodies(:geraldine_public_body) + event.outgoing_message.should_not be_nil + event.event_type.should satisfy {|x| ['sent', 'followup_sent', 'resent', 'followup_resent'].include?(x)} + end + end + + it "should show a JSON feed of new request events" do + get :body_request_events, + :id => public_bodies(:geraldine_public_body).id, + :k => public_bodies(:geraldine_public_body).api_key, + :feed_type => "json" + + response.should be_success + assigns[:events].size.should > 0 + assigns[:events].each do |event| + event.info_request.public_body.should == public_bodies(:geraldine_public_body) + event.outgoing_message.should_not be_nil + event.event_type.should satisfy {|x| ['sent', 'followup_sent', 'resent', 'followup_resent'].include?(x)} + end + + assigns[:event_data].size.should == assigns[:events].size + assigns[:event_data].each do |event_record| + event_record[:event_type].should satisfy {|x| ['sent', 'followup_sent', 'resent', 'followup_resent'].include?(x)} + end + end + + it "should honour the since_event_id parameter" do + get :body_request_events, + :id => public_bodies(:geraldine_public_body).id, + :k => public_bodies(:geraldine_public_body).api_key, + :feed_type => "json" + response.should be_success + first_event = assigns[:event_data][0] + second_event_id = assigns[:event_data][1][:event_id] + + get :body_request_events, + :id => public_bodies(:geraldine_public_body).id, + :k => public_bodies(:geraldine_public_body).api_key, + :feed_type => "json", + :since_event_id => second_event_id + response.should be_success + assigns[:event_data].should == [first_event] + end end diff --git a/spec/controllers/services_controller_spec.rb b/spec/controllers/services_controller_spec.rb index 2be382258..a701ae247 100644 --- a/spec/controllers/services_controller_spec.rb +++ b/spec/controllers/services_controller_spec.rb @@ -2,8 +2,15 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe ServicesController, "when using web services" do + integrate_views - + + # store and restore the locale in the context of the test suite to isolate + # changes made in these tests + before do + @old_locale = FastGettext.locale() + end + it "should show no alaveteli message when in the deployed country" do config = MySociety::Config.load_default() config['ISO_COUNTRY_CODE'] = "DE" @@ -29,5 +36,8 @@ describe ServicesController, "when using web services" do response.body.should match(/Puede hacer solicitudes de información en España/) end + after do + FastGettext.set_locale(@old_locale) + end -end +end
\ No newline at end of file diff --git a/spec/models/censor_rule_spec.rb b/spec/models/censor_rule_spec.rb index 44087c5a6..c11b05a03 100644 --- a/spec/models/censor_rule_spec.rb +++ b/spec/models/censor_rule_spec.rb @@ -1,25 +1,197 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') -describe CensorRule, "substituting things" do - before do - @censor_rule = CensorRule.new - @censor_rule.text = "goodbye" - @censor_rule.replacement = "hello" +describe CensorRule, "substituting things" do + + describe 'when using a text rule' do + + before do + @censor_rule = CensorRule.new + @censor_rule.text = "goodbye" + @censor_rule.replacement = "hello" + end + + it 'should do basic text substitution' do + body = "I don't know why you say goodbye" + @censor_rule.apply_to_text!(body) + body.should == "I don't know why you say hello" + end + + it 'should keep size same for binary substitution' do + body = "I don't know why you say goodbye" + orig_body = body.dup + @censor_rule.apply_to_binary!(body) + body.size.should == orig_body.size + body.should == "I don't know why you say xxxxxxx" + body.should_not == orig_body # be sure duplicated as expected + end + end - it 'should do basic text substitution' do - body = "I don't know why you say goodbye" - @censor_rule.apply_to_text!(body) - body.should == "I don't know why you say hello" + describe "when using a regular expression rule" do + + before do + @censor_rule = CensorRule.new(:last_edit_editor => 1, + :last_edit_comment => 'comment') + @censor_rule.text = "--PRIVATE.*--PRIVATE" + @censor_rule.replacement = "--REMOVED\nHidden private info\n--REMOVED" + @censor_rule.regexp = true + @body = +<<BODY +Some public information +--PRIVATE +Some private information +--PRIVATE +BODY + end + + it "replaces the regexp with the replacement text when applied to text" do + @censor_rule.apply_to_text!(@body) + @body.should == +<<BODY +Some public information +--REMOVED +Hidden private info +--REMOVED +BODY + end + + it "replaces the regexp with the same number of 'x' characters as the text replaced + when applied to binary" do + @censor_rule.apply_to_binary!(@body) + @body.should == +<<BODY +Some public information +xxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxx +BODY + end + + end + +end + +describe 'when validating rules' do + + describe 'should be invalid without text' do + censor_rule = CensorRule.new + censor_rule.valid?.should == false + censor_rule.errors.on(:text).should == "can't be blank" end - it 'should keep size same for binary substitution' do - body = "I don't know why you say goodbye" - orig_body = body.dup - @censor_rule.apply_to_binary!(body) - body.size.should == orig_body.size - body.should == "I don't know why you say xxxxxxx" - body.should_not == orig_body # be sure duplicated as expected + describe 'when validating a regexp rule' do + + before do + @censor_rule = CensorRule.new(:regexp => true, + :text => '*') + end + + it 'should try to create a regexp from the text' do + Regexp.should_receive(:new).with('*', Regexp::MULTILINE) + @censor_rule.valid? + end + + describe 'if a regexp error is produced' do + + it 'should add an error message to the text field with the regexp error message' do + Regexp.stub!(:new).and_raise(RegexpError.new("very bad regexp")) + @censor_rule.valid?.should == false + @censor_rule.errors.on(:text).should == "very bad regexp" + end + + end + + describe 'if no regexp error is produced' do + + it 'should not add any error message to the text field' do + Regexp.stub!(:new) + @censor_rule.valid? + @censor_rule.errors.on(:text).should == nil + end + + end + end + + describe 'when the allow_global flag has been set' do + + before do + @censor_rule = CensorRule.new(:text => 'some text') + @censor_rule.allow_global = true + end + + it 'should allow a global censor rule (without user_id, request_id or public_body_id)' do + @censor_rule.valid?.should == true + end + + end + + describe 'when the allow_global flag has not been set' do + + before do + @censor_rule = CensorRule.new(:text => '/./') + end + + it 'should not allow a global text censor rule (without user_id, request_id or public_body_id)' do + @censor_rule.valid?.should == false + @expected_error = 'Censor must apply to an info request a user or a body; is invalid' + @censor_rule.errors.full_messages.should == [@expected_error] + end + + it 'should not allow a global regex censor rule (without user_id, request_id or public_body_id)' do + @censor_rule.regexp = true + @censor_rule.valid?.should == false + @expected_error = 'Censor must apply to an info request a user or a body; is invalid' + @censor_rule.errors.full_messages.should == [@expected_error] + end + + end + end - + +describe 'when handling global rules' do + + describe 'an instance without user_id, request_id or public_body_id' do + + before do + @global_rule = CensorRule.new + end + + it 'should return a value of true from is_global?' do + @global_rule.is_global?.should == true + end + + end + + describe 'the scope CensorRule.global.all' do + + before do + @global_rule = CensorRule.create!(:allow_global => true, + :text => 'hide me', + :replacement => 'nothing to see here', + :last_edit_editor => 1, + :last_edit_comment => 'comment') + @user_rule = CensorRule.create!(:user_id => 1, + :text => 'hide me', + :replacement => 'nothing to see here', + :last_edit_editor => 1, + :last_edit_comment => 'comment') + end + + it 'should include an instance without user_id, request_id or public_body_id' do + CensorRule.global.all.include?(@global_rule).should == true + end + + it 'should not include a request with user_id' do + CensorRule.global.all.include?(@user_rule).should == false + end + + after do + @global_rule.destroy if @global_rule + @user_rule.destroy if @user_rule + end + end + +end + + diff --git a/spec/models/incoming_message_spec.rb b/spec/models/incoming_message_spec.rb index c6658905c..bc73ef071 100644 --- a/spec/models/incoming_message_spec.rb +++ b/spec/models/incoming_message_spec.rb @@ -71,7 +71,7 @@ describe IncomingMessage, " when dealing with incoming mail" do end -describe IncomingMessage, "when parsing HTML mail" do +describe IncomingMessage, "when parsing HTML mail" do it "should display UTF-8 characters in the plain text version correctly" do html = "<html><b>foo</b> është" plain_text = IncomingMessage._get_attachment_text_internal_one_file('text/html', html) @@ -79,15 +79,15 @@ describe IncomingMessage, "when parsing HTML mail" do end end -describe IncomingMessage, "when getting the attachment text" do +describe IncomingMessage, "when getting the attachment text" do - it "should not raise an error if the expansion of a zip file raises an error" do + it "should not raise an error if the expansion of a zip file raises an error" do mock_entry = mock('ZipFile entry', :file? => true) mock_entry.stub!(:get_input_stream).and_raise("invalid distance too far back") Zip::ZipFile.stub!(:open).and_return([mock_entry]) IncomingMessage._get_attachment_text_internal_one_file('application/zip', "some string") end - + end @@ -196,17 +196,17 @@ describe IncomingMessage, " checking validity to reply to with real emails" do ActionMailer::Base.deliveries.clear end it "should allow a reply to plain emails" do - ir = info_requests(:fancy_dog_request) + ir = info_requests(:fancy_dog_request) receive_incoming_mail('incoming-request-plain.email', ir.incoming_email) ir.incoming_messages[1].valid_to_reply_to?.should == true end it "should not allow a reply to emails with empty return-paths" do - ir = info_requests(:fancy_dog_request) + ir = info_requests(:fancy_dog_request) receive_incoming_mail('empty-return-path.email', ir.incoming_email) ir.incoming_messages[1].valid_to_reply_to?.should == false end it "should not allow a reply to emails with autoresponse headers" do - ir = info_requests(:fancy_dog_request) + ir = info_requests(:fancy_dog_request) receive_incoming_mail('autoresponse-header.email', ir.incoming_email) ir.incoming_messages[1].valid_to_reply_to?.should == false end @@ -234,6 +234,13 @@ describe IncomingMessage, " when censoring data" do @censor_rule_2.last_edit_comment = "none" @im.info_request.censor_rules << @censor_rule_2 + @regex_censor_rule = CensorRule.new() + @regex_censor_rule.text = 'm[a-z][a-z][a-z]e' + @regex_censor_rule.regexp = true + @regex_censor_rule.replacement = 'cat' + @regex_censor_rule.last_edit_editor = 'unknown' + @regex_censor_rule.last_edit_comment = 'none' + @im.info_request.censor_rules << @regex_censor_rule load_raw_emails_data end @@ -246,7 +253,7 @@ describe IncomingMessage, " when censoring data" do it "should replace censor text in Word documents" do data = @test_data.dup @im.binary_mask_stuff!(data, "application/vnd.ms-word") - data.should == "There was a mouse called xxxxxxx, he wished that he was xxxx." + data.should == "There was a xxxxx called xxxxxxx, he wished that he was xxxx." end it "should replace ASCII email addresses in Word documents" do @@ -301,7 +308,7 @@ describe IncomingMessage, " when censoring data" do it "should apply censor rules to HTML files" do data = @test_data.dup @im.html_mask_stuff!(data) - data.should == "There was a mouse called Jarlsberg, he wished that he was yellow." + data.should == "There was a cat called Jarlsberg, he wished that he was yellow." end it "should apply hard-coded privacy rules to HTML files" do @@ -312,8 +319,8 @@ describe IncomingMessage, " when censoring data" do end it "should apply censor rules to From: addresses" do - @im.stub!(:mail_from).and_return("Stilton Mouse") - @im.stub!(:last_parsed).and_return(Time.now) + @im.stub!(:mail_from).and_return("Stilton Mouse") + @im.stub!(:last_parsed).and_return(Time.now) safe_mail_from = @im.safe_mail_from safe_mail_from.should == "Jarlsberg Mouse" end @@ -363,7 +370,7 @@ describe IncomingMessage, " when uudecoding bad messages" do im = incoming_messages(:useless_incoming_message) im.stub!(:mail).and_return(mail) im.extract_attachments! - + attachments = im.foi_attachments attachments.size.should == 2 attachments[1].filename.should == 'moo.txt' @@ -407,7 +414,7 @@ describe IncomingMessage, "when messages are attached to messages" do im = incoming_messages(:useless_incoming_message) im.stub!(:mail).and_return(mail) - + im.extract_attachments! attachments = im.get_attachments_for_display diff --git a/spec/models/info_request_spec.rb b/spec/models/info_request_spec.rb index a18a4bd1d..2a738fa4c 100644 --- a/spec/models/info_request_spec.rb +++ b/spec/models/info_request_spec.rb @@ -1,8 +1,8 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') -describe InfoRequest do +describe InfoRequest do - describe "guessing a request from an email" do + describe "guessing a request from an email" do before(:each) do @im = incoming_messages(:useless_incoming_message) @@ -17,7 +17,7 @@ describe InfoRequest do @info_request.idhash.should_not == nil end - it 'should find a request based on an email with an intact id and a broken hash' do + it 'should find a request based on an email with an intact id and a broken hash' do ir = info_requests(:fancy_dog_request) id = ir.id @im.mail.to = "request-#{id}-asdfg@example.com" @@ -35,42 +35,42 @@ describe InfoRequest do end - describe "making up the URL title" do + describe "making up the URL title" do before do @info_request = InfoRequest.new end - it 'should remove spaces, and make lower case' do + it 'should remove spaces, and make lower case' do @info_request.title = 'Something True' @info_request.url_title.should == 'something_true' end - it 'should not allow a numeric title' do + it 'should not allow a numeric title' do @info_request.title = '1234' @info_request.url_title.should == 'request' end end - - describe "when asked for the last event id that needs description" do - + + describe "when asked for the last event id that needs description" do + before do @info_request = InfoRequest.new end - - it 'should return the last undescribed event id if there is one' do + + it 'should return the last undescribed event id if there is one' do last_mock_event = mock_model(InfoRequestEvent) other_mock_event = mock_model(InfoRequestEvent) @info_request.stub!(:events_needing_description).and_return([other_mock_event, last_mock_event]) @info_request.last_event_id_needing_description.should == last_mock_event.id - end - + end + it 'should return zero if there are no undescribed events' do @info_request.stub!(:events_needing_description).and_return([]) @info_request.last_event_id_needing_description.should == 0 end - + end - + describe " when emailing" do before do @@ -116,7 +116,7 @@ describe InfoRequest do hash_part = ir.incoming_email.match(/-[0-9a-f]+@/)[0] break if hash_part.match(/1/) end - + # Make email with a 1 in the hash part changed to l test_email = ir.incoming_email new_hash_part = hash_part.gsub(/1/, "l") @@ -134,7 +134,7 @@ describe InfoRequest do end it "should return nil when receiving email for a deleted request" do - deleted_request_address = InfoRequest.magic_email_for_id("request-", 98765) + deleted_request_address = InfoRequest.magic_email_for_id("request-", 98765) found_info_request = InfoRequest.find_by_incoming_email(deleted_request_address) found_info_request.should be_nil end @@ -148,7 +148,7 @@ describe InfoRequest do update_xapian_index end - end + end describe "when calculating the status" do @@ -169,22 +169,22 @@ describe InfoRequest do end it "isn't overdue on due date (20 working days after request sent)" do - Time.stub!(:now).and_return(Time.utc(2007, 11, 9, 23, 59)) + Time.stub!(:now).and_return(Time.utc(2007, 11, 9, 23, 59)) @ir.calculate_status.should == 'waiting_response' end it "is overdue a day after due date (20 working days after request sent)" do - Time.stub!(:now).and_return(Time.utc(2007, 11, 10, 00, 01)) + Time.stub!(:now).and_return(Time.utc(2007, 11, 10, 00, 01)) @ir.calculate_status.should == 'waiting_response_overdue' end it "is still overdue 40 working days after request sent" do - Time.stub!(:now).and_return(Time.utc(2007, 12, 10, 23, 59)) + Time.stub!(:now).and_return(Time.utc(2007, 12, 10, 23, 59)) @ir.calculate_status.should == 'waiting_response_overdue' end it "is very overdue the day after 40 working days after request sent" do - Time.stub!(:now).and_return(Time.utc(2007, 12, 11, 00, 01)) + Time.stub!(:now).and_return(Time.utc(2007, 12, 11, 00, 01)) @ir.calculate_status.should == 'waiting_response_very_overdue' end end @@ -209,18 +209,18 @@ describe InfoRequest do it "accepts extended states" do # this time would normally be "overdue" - Time.stub!(:now).and_return(Time.utc(2007, 11, 10, 00, 01)) + Time.stub!(:now).and_return(Time.utc(2007, 11, 10, 00, 01)) @ir.set_described_state("deadline_extended") @ir.display_status.should == 'Deadline extended.' @ir.date_deadline_extended end - + it "is not overdue if it's had the deadline extended" do when_overdue = Time.utc(2007, 11, 10, 00, 01) + 16.days - Time.stub!(:now).and_return(when_overdue) + Time.stub!(:now).and_return(when_overdue) @ir.calculate_status.should == 'waiting_response_overdue' end - + end @@ -245,160 +245,243 @@ describe InfoRequest do end it "isn't overdue on due date (20 working days after request sent)" do - Time.stub!(:now).and_return(Time.utc(2007, 11, 9, 23, 59)) + Time.stub!(:now).and_return(Time.utc(2007, 11, 9, 23, 59)) @ir.calculate_status.should == 'waiting_response' end it "is overdue a day after due date (20 working days after request sent)" do - Time.stub!(:now).and_return(Time.utc(2007, 11, 10, 00, 01)) + Time.stub!(:now).and_return(Time.utc(2007, 11, 10, 00, 01)) @ir.calculate_status.should == 'waiting_response_overdue' end it "is still overdue 40 working days after request sent" do - Time.stub!(:now).and_return(Time.utc(2007, 12, 10, 23, 59)) + Time.stub!(:now).and_return(Time.utc(2007, 12, 10, 23, 59)) @ir.calculate_status.should == 'waiting_response_overdue' end it "is still overdue the day after 40 working days after request sent" do - Time.stub!(:now).and_return(Time.utc(2007, 12, 11, 00, 01)) + Time.stub!(:now).and_return(Time.utc(2007, 12, 11, 00, 01)) @ir.calculate_status.should == 'waiting_response_overdue' end it "is still overdue 60 working days after request sent" do - Time.stub!(:now).and_return(Time.utc(2008, 01, 11, 23, 59)) + Time.stub!(:now).and_return(Time.utc(2008, 01, 11, 23, 59)) @ir.calculate_status.should == 'waiting_response_overdue' end it "is very overdue the day after 60 working days after request sent" do - Time.stub!(:now).and_return(Time.utc(2008, 01, 12, 00, 01)) + Time.stub!(:now).and_return(Time.utc(2008, 01, 12, 00, 01)) @ir.calculate_status.should == 'waiting_response_very_overdue' end end - - describe 'when asked if a user is the owning user for this request' do - - before do + + describe 'when asked if a user is the owning user for this request' do + + before do @mock_user = mock_model(User) @info_request = InfoRequest.new(:user => @mock_user) @other_mock_user = mock_model(User) end - - it 'should return false if a nil object is passed to it' do + + it 'should return false if a nil object is passed to it' do @info_request.is_owning_user?(nil).should be_false end - - it 'should return true if the user is the request\'s owner' do + + it 'should return true if the user is the request\'s owner' do @info_request.is_owning_user?(@mock_user).should be_true end - - it 'should return false for a user that is not the owner and does not own every request' do + + it 'should return false for a user that is not the owner and does not own every request' do @other_mock_user.stub!(:owns_every_request?).and_return(false) @info_request.is_owning_user?(@other_mock_user).should be_false end - + it 'should return true if the user is not the owner but owns every request' do @other_mock_user.stub!(:owns_every_request?).and_return(true) @info_request.is_owning_user?(@other_mock_user).should be_true end - + end - - describe 'when asked if it requires admin' do - - before do + + describe 'when asked if it requires admin' do + + before do @info_request = InfoRequest.new end - - it 'should return true if its described state is error_message' do + + it 'should return true if its described state is error_message' do @info_request.described_state = 'error_message' @info_request.requires_admin?.should be_true end - - it 'should return true if its described state is requires_admin' do + + it 'should return true if its described state is requires_admin' do @info_request.described_state = 'requires_admin' @info_request.requires_admin?.should be_true end - - it 'should return false if its described state is waiting_response' do + + it 'should return false if its described state is waiting_response' do @info_request.described_state = 'waiting_response' @info_request.requires_admin?.should be_false end - + end - - describe 'when asked for old unclassified requests' do - - before do + + describe 'when asked for old unclassified requests' do + + before do Time.stub!(:now).and_return(Time.utc(2007, 11, 9, 23, 59)) end - - it 'should ask for requests using any limit param supplied' do - InfoRequest.should_receive(:find).with(:all, {:select => anything, - :order => anything, - :conditions=> anything, + + it 'should ask for requests using any limit param supplied' do + InfoRequest.should_receive(:find).with(:all, {:select => anything, + :order => anything, + :conditions=> anything, :limit => 5}) InfoRequest.find_old_unclassified(:limit => 5) end - - it 'should not limit the number of requests returned by default' do - InfoRequest.should_not_receive(:find).with(:all, {:select => anything, - :order => anything, - :conditions=> anything, + + it 'should not limit the number of requests returned by default' do + InfoRequest.should_not_receive(:find).with(:all, {:select => anything, + :order => anything, + :conditions=> anything, :limit => anything}) InfoRequest.find_old_unclassified - end - - it 'should add extra conditions if supplied' do - InfoRequest.should_receive(:find).with(:all, - {:select=> anything, - :order=> anything, - :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' order by created_at desc limit 1) < ? and url_title != 'holding_pen' and prominence != 'backpage'", + end + + it 'should add extra conditions if supplied' do + InfoRequest.should_receive(:find).with(:all, + {:select=> anything, + :order=> anything, + :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' order by created_at desc limit 1) < ? and url_title != 'holding_pen' and prominence != 'backpage'", true, Time.now - 21.days]}) InfoRequest.find_old_unclassified({:conditions => ["prominence != 'backpage'"]}) end - - it 'should ask the database for requests that are awaiting description, have a last response older than 21 days old, are not the holding pen and are not backpaged' do - InfoRequest.should_receive(:find).with(:all, - {:select=>"*, (select created_at from info_request_events where info_request_events.info_request_id = info_requests.id and info_request_events.event_type = 'response' order by created_at desc limit 1) as last_response_time", - :order=>"last_response_time", - :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' order by created_at desc limit 1) < ? and url_title != 'holding_pen'", + + it 'should ask the database for requests that are awaiting description, have a last response older than 21 days old, are not the holding pen and are not backpaged' do + InfoRequest.should_receive(:find).with(:all, + {:select=>"*, (select created_at from info_request_events where info_request_events.info_request_id = info_requests.id and info_request_events.event_type = 'response' order by created_at desc limit 1) as last_response_time", + :order=>"last_response_time", + :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' order by created_at desc limit 1) < ? and url_title != 'holding_pen'", true, Time.now - 21.days]}) InfoRequest.find_old_unclassified end - + end - - describe 'when an instance is asked if it is old and unclassified' do - - before do + + describe 'when an instance is asked if it is old and unclassified' do + + before do Time.stub!(:now).and_return(Time.utc(2007, 11, 9, 23, 59)) @mock_comment_event = safe_mock_model(InfoRequestEvent, :created_at => Time.now - 23.days, :event_type => 'comment') @mock_response_event = safe_mock_model(InfoRequestEvent, :created_at => Time.now - 22.days, :event_type => 'response') - @info_request = InfoRequest.new(:prominence => 'normal', - :awaiting_description => true, + @info_request = InfoRequest.new(:prominence => 'normal', + :awaiting_description => true, :info_request_events => [@mock_response_event, @mock_comment_event]) end - - it 'should return false if it is the holding pen' do + + it 'should return false if it is the holding pen' do @info_request.stub!(:url_title).and_return('holding_pen') @info_request.is_old_unclassified?.should be_false end - - it 'should return false if it is not awaiting description' do + + it 'should return false if it is not awaiting description' do @info_request.stub!(:awaiting_description).and_return(false) @info_request.is_old_unclassified?.should be_false end - - it 'should return false if its last response event occurred less than 21 days ago' do + + it 'should return false if its last response event occurred less than 21 days ago' do @mock_response_event.stub!(:created_at).and_return(Time.now - 20.days) @info_request.is_old_unclassified?.should be_false end - - it 'should return true if it is awaiting description, isn\'t the holding pen and hasn\'t had an event in 21 days' do + + it 'should return true if it is awaiting description, isn\'t the holding pen and hasn\'t had an event in 21 days' do @info_request.is_old_unclassified?.should be_true end - + end - + + describe 'when applying censor rules' do + + before do + @global_rule = mock_model(CensorRule, :apply_to_text! => nil, + :apply_to_binary! => nil) + @user_rule = mock_model(CensorRule, :apply_to_text! => nil, + :apply_to_binary! => nil) + @request_rule = mock_model(CensorRule, :apply_to_text! => nil, + :apply_to_binary! => nil) + @body_rule = mock_model(CensorRule, :apply_to_text! => nil, + :apply_to_binary! => nil) + @user = mock_model(User, :censor_rules => [@user_rule]) + @body = mock_model(PublicBody, :censor_rules => [@body_rule]) + @info_request = InfoRequest.new(:prominence => 'normal', + :awaiting_description => true, + :title => 'title') + @info_request.stub!(:user).and_return(@user) + @info_request.stub!(:censor_rules).and_return([@request_rule]) + @info_request.stub!(:public_body).and_return(@body) + @text = 'some text' + CensorRule.stub!(:global).and_return(mock('global context', :all => [@global_rule])) + end + + context "when applying censor rules to text" do + + it "should apply a global censor rule" do + @global_rule.should_receive(:apply_to_text!).with(@text) + @info_request.apply_censor_rules_to_text!(@text) + end + + it 'should apply a user rule' do + @user_rule.should_receive(:apply_to_text!).with(@text) + @info_request.apply_censor_rules_to_text!(@text) + end + + it 'should not raise an error if there is no user' do + @info_request.user_id = nil + lambda{ @info_request.apply_censor_rules_to_text!(@text) }.should_not raise_error + end + + it 'should apply a rule from the body associated with the request' do + @body_rule.should_receive(:apply_to_text!).with(@text) + @info_request.apply_censor_rules_to_text!(@text) + end + + it 'should apply a request rule' do + @request_rule.should_receive(:apply_to_text!).with(@text) + @info_request.apply_censor_rules_to_text!(@text) + end + + end + + context 'when applying censor rules to binary files' do + + it "should apply a global censor rule" do + @global_rule.should_receive(:apply_to_binary!).with(@text) + @info_request.apply_censor_rules_to_binary!(@text) + end + + it 'should apply a user rule' do + @user_rule.should_receive(:apply_to_binary!).with(@text) + @info_request.apply_censor_rules_to_binary!(@text) + end + + it 'should not raise an error if there is no user' do + @info_request.user_id = nil + lambda{ @info_request.apply_censor_rules_to_binary!(@text) }.should_not raise_error + end + + it 'should apply a rule from the body associated with the request' do + @body_rule.should_receive(:apply_to_binary!).with(@text) + @info_request.apply_censor_rules_to_binary!(@text) + end + + it 'should apply a request rule' do + @request_rule.should_receive(:apply_to_binary!).with(@text) + @info_request.apply_censor_rules_to_binary!(@text) + end + + end + + end + end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a7f3020c1..c11c7c5bc 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -206,3 +206,16 @@ def load_test_categories "Miscellaneous", [ "other", "Miscellaneous", "miscellaneous" ],]) end + + +# Monkeypatch applicationcontroller because the `render_to_string` +# method in the original breaks all the rspec test assertions such as +# `should render_template('foo')`. Same problem as +# http://stackoverflow.com/questions/8174415/is-it-possible-to-assert-template-or-render-template-against-the-same-partial-wi +# - a bug in either Rails or Rspec I don't have the time to fix :( + +class ApplicationController < ActionController::Base + def set_popup_banner + @popup_banner = nil + end +end diff --git a/spec/views/request/_after_actions.rhtml_spec.rb b/spec/views/request/_after_actions.rhtml_spec.rb index 6a56e7a71..d04db3fc2 100644 --- a/spec/views/request/_after_actions.rhtml_spec.rb +++ b/spec/views/request/_after_actions.rhtml_spec.rb @@ -9,6 +9,8 @@ describe 'when displaying actions that can be taken with regard to a request' do :url_name => 'test_user') @mock_request = mock_model(InfoRequest, :title => 'test request', :user => @mock_user, + :user_name => @mock_user.name, + :is_external? => false, :public_body => @mock_body, :url_title => 'test_request') assigns[:info_request] = @mock_request diff --git a/spec/views/request/_describe_state.rhtml_spec.rb b/spec/views/request/_describe_state.rhtml_spec.rb index ccf653b1b..18778d5d2 100644 --- a/spec/views/request/_describe_state.rhtml_spec.rb +++ b/spec/views/request/_describe_state.rhtml_spec.rb @@ -18,7 +18,12 @@ describe 'when showing the form for describing the state of a request' do before do @mock_user = mock_model(User, :name => 'test user', :url_name => 'test_user') - @mock_request = mock_model(InfoRequest, :described_state => '', :user => @mock_user) + @mock_request = mock_model(InfoRequest, + :described_state => '', + :user => @mock_user, + :user_name => @mock_user.name, + :is_external? => false + ) assigns[:info_request] = @mock_request end diff --git a/spec/views/request/show.rhtml_spec.rb b/spec/views/request/show.rhtml_spec.rb index ef7d1a47c..4429e9e58 100644 --- a/spec/views/request/show.rhtml_spec.rb +++ b/spec/views/request/show.rhtml_spec.rb @@ -15,6 +15,8 @@ describe 'when viewing an information request' do :law_used_full => 'Freedom of Information', :public_body => @mock_body, :user => @mock_user, + :user_name => @mock_user.name, + :is_external? => false, :calculate_status => 'waiting_response', :date_response_required_by => Date.today, :prominence => 'normal') |