diff options
Diffstat (limited to 'spec/models')
-rw-r--r-- | spec/models/about_me_validator_spec.rb | 53 | ||||
-rw-r--r-- | spec/models/holiday_import_spec.rb | 157 | ||||
-rw-r--r-- | spec/models/holiday_spec.rb | 133 | ||||
-rw-r--r-- | spec/models/incoming_message_spec.rb | 179 | ||||
-rw-r--r-- | spec/models/info_request_spec.rb | 2 | ||||
-rw-r--r-- | spec/models/public_body_category_link_spec.rb | 9 | ||||
-rw-r--r-- | spec/models/public_body_category_spec.rb | 177 | ||||
-rw-r--r-- | spec/models/public_body_heading_spec.rb | 132 | ||||
-rw-r--r-- | spec/models/public_body_spec.rb | 603 | ||||
-rw-r--r-- | spec/models/user_spec.rb | 18 |
10 files changed, 1116 insertions, 347 deletions
diff --git a/spec/models/about_me_validator_spec.rb b/spec/models/about_me_validator_spec.rb new file mode 100644 index 000000000..5610cead8 --- /dev/null +++ b/spec/models/about_me_validator_spec.rb @@ -0,0 +1,53 @@ +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') + +describe AboutMeValidator do + + describe :new do + + it 'sets each supported attribute on the instance' do + params = { :about_me => 'My description' } + validator = AboutMeValidator.new(params) + expect(validator.about_me).to eq('My description') + end + + end + + describe :valid? do + + it 'is valid if about_me is =< 500' do + params = { :about_me => 'a'*500 } + validator = AboutMeValidator.new(params) + expect(validator).to be_valid + end + + it 'is valid if about_me is blank' do + params = { :about_me => '' } + validator = AboutMeValidator.new(params) + expect(validator).to be_valid + end + + it 'is valid if about_me is nil' do + params = { :about_me => nil } + validator = AboutMeValidator.new(params) + expect(validator).to be_valid + end + + it 'is invalid if about_me is > 500' do + params = { :about_me => 'a'*501 } + validator = AboutMeValidator.new(params) + expect(validator).to have(1).error_on(:about_me) + end + + end + + describe :about_me do + + it 'has an attribute accessor' do + params = { :about_me => 'My description' } + validator = AboutMeValidator.new(params) + expect(validator.about_me).to eq('My description') + end + + end + +end diff --git a/spec/models/holiday_import_spec.rb b/spec/models/holiday_import_spec.rb new file mode 100644 index 000000000..21061f63f --- /dev/null +++ b/spec/models/holiday_import_spec.rb @@ -0,0 +1,157 @@ +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') + +describe HolidayImport do + + it 'validates the presence of a feed if the source is a feed' do + holiday_import = HolidayImport.new(:source => 'feed') + holiday_import.valid?.should be_false + holiday_import.errors[:ical_feed_url].should == ["can't be blank"] + end + + it 'does not validate the presence of a feed if the source is suggestions' do + holiday_import = HolidayImport.new(:source => 'suggestions') + holiday_import.valid?.should be_true + end + + it 'validates that the source is either "feed" or "suggestions"' do + holiday_import = HolidayImport.new(:source => 'something') + holiday_import.valid?.should be_false + holiday_import.errors[:source].should == ["is not included in the list"] + end + + it 'validates that all holidays create from attributes are valid' do + holiday_import = HolidayImport.new(:source => 'suggestions', + :holidays_attributes => {"0" => {:description => '', + "day(1i)"=>"", + "day(2i)"=>"", + "day(3i)"=>""}}) + holiday_import.valid?.should be_false + holiday_import.errors[:base].should == ["These holidays could not be imported"] + end + + it 'validates that all holidays to import are valid' do + holiday_import = HolidayImport.new + holiday_import.holidays = [ Holiday.new ] + holiday_import.valid?.should be_false + holiday_import.errors[:base].should == ['These holidays could not be imported'] + end + + it 'defaults to importing holidays for the current year' do + holiday_import = HolidayImport.new + holiday_import.start_year.should == Time.now.year + holiday_import.end_year.should == Time.now.year + end + + it 'allows the start and end year to be set' do + holiday_import = HolidayImport.new(:start_year => 2011, :end_year => 2012) + holiday_import.start_year.should == 2011 + holiday_import.end_year.should == 2012 + end + + it 'sets the start and end dates to the beginning and end of the year' do + holiday_import = HolidayImport.new(:start_year => 2011, :end_year => 2012) + holiday_import.start_date.should == Date.new(2011, 1, 1) + holiday_import.end_date.should == Date.new(2012, 12, 31) + end + + it 'sets a default source of suggestions' do + holiday_import = HolidayImport.new + holiday_import.source.should == 'suggestions' + end + + it 'allows the source to be set' do + holiday_import = HolidayImport.new(:source => 'feed') + holiday_import.source.should == 'feed' + end + + it 'allows an iCal feed URL to be set' do + holiday_import = HolidayImport.new(:ical_feed_url => 'http://www.example.com') + holiday_import.ical_feed_url.should == 'http://www.example.com' + end + + it 'sets a default populated flag to false' do + holiday_import = HolidayImport.new + holiday_import.populated.should == false + end + + it 'returns a readable description of the period for multiple years' do + HolidayImport.new(:start_year => 2011, :end_year => 2012).period.should == '2011-2012' + end + + it 'returns a readable description of the period for a single year' do + HolidayImport.new(:start_year => 2011, :end_year => 2011).period.should == '2011' + end + + it 'returns the country name for which suggestions are generated' do + HolidayImport.new.suggestions_country_name.should == 'Germany' + end + + describe 'when populating a set of holidays to import from suggestions' do + + before do + holidays = [ { :date => Date.new(2014, 1, 1), :name => "New Year's Day", :regions => [:gb] } ] + Holidays.stub!(:between).and_return(holidays) + @holiday_import = HolidayImport.new(:source => 'suggestions') + @holiday_import.populate + end + + it 'should populate holidays from the suggestions' do + @holiday_import.holidays.size.should == 1 + holiday = @holiday_import.holidays.first + holiday.description.should == "New Year's Day" + holiday.day.should == Date.new(2014, 1, 1) + end + + it 'should return a flag that it has been populated' do + @holiday_import.populated.should == true + end + + end + + describe 'when populating a set of holidays to import from a feed' do + + before do + @holiday_import = HolidayImport.new(:source => 'feed', + :ical_feed_url => 'http://www.example.com', + :start_year => 2014, + :end_year => 2014) + end + + it 'should populate holidays from the feed that are between the dates' do + @holiday_import.stub!(:open).and_return(load_file_fixture('ical-holidays.ics')) + @holiday_import.populate + @holiday_import.holidays.size.should == 1 + holiday = @holiday_import.holidays.first + holiday.description.should == "New Year's Day" + holiday.day.should == Date.new(2014, 1, 1) + end + + it 'should add an error if the calendar cannot be parsed' do + @holiday_import.stub!(:open).and_return('some invalid data') + @holiday_import.populate + expected = ["Sorry, there's a problem with the format of that feed."] + @holiday_import.errors[:ical_feed_url].should == expected + end + + it 'should add an error if the calendar cannot be found' do + @holiday_import.stub!(:open).and_raise Errno::ENOENT.new('No such file or directory') + @holiday_import.populate + expected = ["Sorry we couldn't find that feed."] + @holiday_import.errors[:ical_feed_url].should == expected + end + + end + + describe 'when saving' do + + it 'saves all holidays' do + holiday = Holiday.new + holiday_import = HolidayImport.new + holiday_import.holidays = [ holiday ] + holiday.should_receive(:save) + holiday_import.save + end + + end + +end diff --git a/spec/models/holiday_spec.rb b/spec/models/holiday_spec.rb index 89849abb7..2f8eeabd9 100644 --- a/spec/models/holiday_spec.rb +++ b/spec/models/holiday_spec.rb @@ -9,87 +9,98 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') -describe Holiday, " when calculating due date" do +describe Holiday do - def due_date(ymd) - return Holiday.due_date_from_working_days(Date.strptime(ymd), 20).strftime("%F") - end + describe :new do - context "in working days" do - it "handles no holidays" do - due_date('2008-10-01').should == '2008-10-29' + it 'should require a day' do + holiday = Holiday.new + holiday.valid?.should be_false + holiday.errors[:day].should == ["can't be blank"] end + end - it "handles non leap years" do - due_date('2007-02-01').should == '2007-03-01' - end + describe " when calculating due date" do - it "handles leap years" do - due_date('2008-02-01').should == '2008-02-29' + def due_date(ymd) + return Holiday.due_date_from_working_days(Date.strptime(ymd), 20).strftime("%F") end - it "handles Thursday start" do - due_date('2009-03-12').should == '2009-04-14' - end + context "in working days" do + it "handles no holidays" do + due_date('2008-10-01').should == '2008-10-29' + end - it "handles Friday start" do - due_date('2009-03-13').should == '2009-04-15' - end + it "handles non leap years" do + due_date('2007-02-01').should == '2007-03-01' + end - # Delivery at the weekend ends up the same due day as if it had arrived on - # the Friday before. This is because the next working day (Monday) counts - # as day 1. - # See http://www.whatdotheyknow.com/help/officers#days - it "handles Saturday start" do - due_date('2009-03-14').should == '2009-04-15' - end - it "handles Sunday start" do - due_date('2009-03-15').should == '2009-04-15' - end + it "handles leap years" do + due_date('2008-02-01').should == '2008-02-29' + end - it "handles Monday start" do - due_date('2009-03-16').should == '2009-04-16' - end + it "handles Thursday start" do + due_date('2009-03-12').should == '2009-04-14' + end - it "handles Time objects" do - Holiday.due_date_from_working_days(Time.utc(2009, 03, 16, 12, 0, 0), 20).strftime('%F').should == '2009-04-16' - end - end + it "handles Friday start" do + due_date('2009-03-13').should == '2009-04-15' + end - context "in calendar days" do - it "handles no holidays" do - Holiday.due_date_from_calendar_days(Date.new(2008, 10, 1), 20).should == Date.new(2008, 10, 21) - end + # Delivery at the weekend ends up the same due day as if it had arrived on + # the Friday before. This is because the next working day (Monday) counts + # as day 1. + # See http://www.whatdotheyknow.com/help/officers#days + it "handles Saturday start" do + due_date('2009-03-14').should == '2009-04-15' + end + it "handles Sunday start" do + due_date('2009-03-15').should == '2009-04-15' + end - it "handles the due date falling on a Friday" do - Holiday.due_date_from_calendar_days(Date.new(2008, 10, 4), 20).should == Date.new(2008, 10, 24) - end + it "handles Monday start" do + due_date('2009-03-16').should == '2009-04-16' + end - # If the due date would fall on a Saturday it should in fact fall on the next day that isn't a weekend - # or a holiday - it "handles the due date falling on a Saturday" do - Holiday.due_date_from_calendar_days(Date.new(2008, 10, 5), 20).should == Date.new(2008, 10, 27) + it "handles Time objects" do + Holiday.due_date_from_working_days(Time.utc(2009, 03, 16, 12, 0, 0), 20).strftime('%F').should == '2009-04-16' + end end - it "handles the due date falling on a Sunday" do - Holiday.due_date_from_calendar_days(Date.new(2008, 10, 6), 20).should == Date.new(2008, 10, 27) - end + context "in calendar days" do + it "handles no holidays" do + Holiday.due_date_from_calendar_days(Date.new(2008, 10, 1), 20).should == Date.new(2008, 10, 21) + end - it "handles the due date falling on a Monday" do - Holiday.due_date_from_calendar_days(Date.new(2008, 10, 7), 20).should == Date.new(2008, 10, 27) - end + it "handles the due date falling on a Friday" do + Holiday.due_date_from_calendar_days(Date.new(2008, 10, 4), 20).should == Date.new(2008, 10, 24) + end - it "handles the due date falling on a day before a Holiday" do - Holiday.due_date_from_calendar_days(Date.new(2008, 12, 4), 20).should == Date.new(2008, 12, 24) - end + # If the due date would fall on a Saturday it should in fact fall on the next day that isn't a weekend + # or a holiday + it "handles the due date falling on a Saturday" do + Holiday.due_date_from_calendar_days(Date.new(2008, 10, 5), 20).should == Date.new(2008, 10, 27) + end - it "handles the due date falling on a Holiday" do - Holiday.due_date_from_calendar_days(Date.new(2008, 12, 5), 20).should == Date.new(2008, 12, 29) - end + it "handles the due date falling on a Sunday" do + Holiday.due_date_from_calendar_days(Date.new(2008, 10, 6), 20).should == Date.new(2008, 10, 27) + end + + it "handles the due date falling on a Monday" do + Holiday.due_date_from_calendar_days(Date.new(2008, 10, 7), 20).should == Date.new(2008, 10, 27) + end + + it "handles the due date falling on a day before a Holiday" do + Holiday.due_date_from_calendar_days(Date.new(2008, 12, 4), 20).should == Date.new(2008, 12, 24) + end - it "handles Time objects" do - Holiday.due_date_from_calendar_days(Time.utc(2009, 03, 17, 12, 0, 0), 20).should == Date.new(2009, 4, 6) + it "handles the due date falling on a Holiday" do + Holiday.due_date_from_calendar_days(Date.new(2008, 12, 5), 20).should == Date.new(2008, 12, 29) + end + + it "handles Time objects" do + Holiday.due_date_from_calendar_days(Time.utc(2009, 03, 17, 12, 0, 0), 20).should == Date.new(2009, 4, 6) + end end end end - diff --git a/spec/models/incoming_message_spec.rb b/spec/models/incoming_message_spec.rb index 3b6887f76..f6e524de3 100644 --- a/spec/models/incoming_message_spec.rb +++ b/spec/models/incoming_message_spec.rb @@ -423,127 +423,50 @@ describe IncomingMessage, " checking validity to reply to with real emails" do end -describe IncomingMessage, " when censoring data" do - - before(:each) do - @test_data = "There was a mouse called Stilton, he wished that he was blue." - - @im = incoming_messages(:useless_incoming_message) - - @censor_rule_1 = CensorRule.new() - @censor_rule_1.text = "Stilton" - @censor_rule_1.replacement = "Jarlsberg" - @censor_rule_1.last_edit_editor = "unknown" - @censor_rule_1.last_edit_comment = "none" - @im.info_request.censor_rules << @censor_rule_1 - - @censor_rule_2 = CensorRule.new() - @censor_rule_2.text = "blue" - @censor_rule_2.replacement = "yellow" - @censor_rule_2.last_edit_editor = "unknown" - @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 - - it "should do nothing to a JPEG" do - data = @test_data.dup - @im.binary_mask_stuff!(data, "image/jpeg") - data.should == @test_data - end - - 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 xxxxx called xxxxxxx, he wished that he was xxxx." - end - - it "should replace ASCII email addresses in Word documents" do - orig_data = "His email was foo@bar.com" - data = orig_data.dup - @im.binary_mask_stuff!(data, "application/vnd.ms-word") - data.should == "His email was xxx@xxx.xxx" - end - - it "should replace UCS-2 addresses in Word documents" do - orig_data = "His email was f\000o\000o\000@\000b\000a\000r\000.\000c\000o\000m\000, indeed" - data = orig_data.dup - @im.binary_mask_stuff!(data, "application/vnd.ms-word") - data.should == "His email was x\000x\000x\000@\000x\000x\000x\000.\000x\000x\000x\000, indeed" - end - - it 'should handle multibyte characters correctly' do - orig_data = 'á' - data = orig_data.dup - @regex_censor_rule = CensorRule.new() - @regex_censor_rule.text = 'á' - @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 - lambda{ @im.binary_mask_stuff!(data, "text/plain") }.should_not raise_error - end - def pdf_replacement_test(use_ghostscript_compression) - config = MySociety::Config.load_default() - previous = config['USE_GHOSTSCRIPT_COMPRESSION'] - config['USE_GHOSTSCRIPT_COMPRESSION'] = use_ghostscript_compression - orig_pdf = load_file_fixture('tfl.pdf') - pdf = orig_pdf.dup - - orig_text = MailHandler.get_attachment_text_one_file('application/pdf', pdf) - orig_text.should match(/foi@tfl.gov.uk/) - - @im.binary_mask_stuff!(pdf, "application/pdf") - - masked_text = MailHandler.get_attachment_text_one_file('application/pdf', pdf) - masked_text.should_not match(/foi@tfl.gov.uk/) - masked_text.should match(/xxx@xxx.xxx.xx/) - config['USE_GHOSTSCRIPT_COMPRESSION'] = previous - end - - it "should replace everything in PDF files using pdftk" do - pdf_replacement_test(false) - end - - it "should replace everything in PDF files using ghostscript" do - pdf_replacement_test(true) - end - - it "should not produce zero length output if pdftk silently fails" do - orig_pdf = load_file_fixture('psni.pdf') - pdf = orig_pdf.dup - @im.binary_mask_stuff!(pdf, "application/pdf") - pdf.should_not == "" - end - - it "should apply censor rules to HTML files" do - data = @test_data.dup - @im.html_mask_stuff!(data) - 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 - data = "http://#{AlaveteliConfiguration::domain}/c/cheese" - @im.html_mask_stuff!(data) - data.should == "[WDTK login link]" - end +describe IncomingMessage, " when censoring data" do - 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) - safe_mail_from = @im.safe_mail_from - safe_mail_from.should == "Jarlsberg Mouse" - end + before(:each) do + @test_data = "There was a mouse called Stilton, he wished that he was blue." + + @im = incoming_messages(:useless_incoming_message) + + @censor_rule_1 = CensorRule.new() + @censor_rule_1.text = "Stilton" + @censor_rule_1.replacement = "Jarlsberg" + @censor_rule_1.last_edit_editor = "unknown" + @censor_rule_1.last_edit_comment = "none" + @im.info_request.censor_rules << @censor_rule_1 + + @censor_rule_2 = CensorRule.new() + @censor_rule_2.text = "blue" + @censor_rule_2.replacement = "yellow" + @censor_rule_2.last_edit_editor = "unknown" + @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 + + it "should replace censor text" do + data = "There was a mouse called Stilton, he wished that he was blue." + @im.apply_masks!(data, "application/vnd.ms-word") + data.should == "There was a xxxxx called xxxxxxx, he wished that he was xxxx." + 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) + safe_mail_from = @im.safe_mail_from + safe_mail_from.should == "Jarlsberg Mouse" + end end @@ -565,15 +488,16 @@ describe IncomingMessage, " when censoring whole users" do it "should apply censor rules to HTML files" do data = @test_data.dup - @im.html_mask_stuff!(data) + @im.apply_masks!(data, 'text/html') data.should == "There was a mouse called Gorgonzola, he wished that he was blue." end it "should replace censor text to Word documents" do data = @test_data.dup - @im.binary_mask_stuff!(data, "application/vnd.ms-word") + @im.apply_masks!(data, "application/vnd.ms-word") data.should == "There was a mouse called xxxxxxx, he wished that he was blue." end + end @@ -770,3 +694,16 @@ describe IncomingMessage, "when extracting attachments" do end end + +describe IncomingMessage, 'when getting the body of a message for html display' do + + it 'should replace any masked email addresses with a link to the help page' do + incoming_message = IncomingMessage.new + body_text = 'there was an [email address] here' + incoming_message.stub!(:get_main_body_text_folded).and_return(body_text) + incoming_message.stub!(:get_main_body_text_unfolded).and_return(body_text) + expected = 'there was an [<a href="/help/officers#mobiles">email address</a>] here' + incoming_message.get_body_for_html_display.should == expected + end + +end diff --git a/spec/models/info_request_spec.rb b/spec/models/info_request_spec.rb index 9ad616ea5..70947584b 100644 --- a/spec/models/info_request_spec.rb +++ b/spec/models/info_request_spec.rb @@ -824,7 +824,7 @@ describe InfoRequest do im = mock_model(IncomingMessage, :subject => nil, :valid_to_reply_to? => true) - subject = ir.email_subject_followup im + subject = ir.email_subject_followup(:incoming_message => im, :html => false) subject.should match(/^Re: Freedom of Information request.*fancy dog/) end diff --git a/spec/models/public_body_category_link_spec.rb b/spec/models/public_body_category_link_spec.rb index 8d91f02d5..fd5608480 100644 --- a/spec/models/public_body_category_link_spec.rb +++ b/spec/models/public_body_category_link_spec.rb @@ -1,10 +1,11 @@ # == Schema Information # -# Table name: public_body_category_link +# Table name: public_body_category_links # -# public_body_category_id :integer not null -# public_body_heading_id :integer not null -# category_display_order :integer +# public_body_category_id :integer not null +# public_body_heading_id :integer not null +# category_display_order :integer +# id :integer not null, primary key # require 'spec_helper' diff --git a/spec/models/public_body_category_spec.rb b/spec/models/public_body_category_spec.rb index c185a3169..297bd096a 100644 --- a/spec/models/public_body_category_spec.rb +++ b/spec/models/public_body_category_spec.rb @@ -2,46 +2,13 @@ # # Table name: public_body_categories # -# id :integer not null, primary key -# locale :string -# title :text not null -# category_tag :text not null -# description :text not null -# display_order :integer +# id :integer not null, primary key +# category_tag :text not null # require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe PublicBodyCategory do - describe 'when loading the data' do - it 'should use the display_order field to preserve the original data order' do - PublicBodyCategory.add(:en, [ - "Local and regional", - [ "local_council", "Local councils", "a local council" ], - "Miscellaneous", - [ "other", "Miscellaneous", "miscellaneous" ], - [ "aardvark", "Aardvark", "daft test"],]) - - headings = PublicBodyHeading.all - cat_group1 = headings[0].public_body_categories - cat_group1.count.should eq 1 - cat_group1[0].title.should eq "Local councils" - - cat_group2 = headings[1].public_body_categories - cat_group2.count.should eq 2 - cat_group2[0].title.should eq "Miscellaneous" - cat_group2[0].public_body_category_links.where( - :public_body_heading_id => headings[1].id). - first. - category_display_order.should eq 0 - - cat_group2[1].title.should eq "Aardvark" - cat_group2[1].public_body_category_links.where( - :public_body_heading_id => headings[1].id). - first. - category_display_order.should eq 1 - end - end context 'when validating' do @@ -67,5 +34,145 @@ describe PublicBodyCategory do category.should_not be_valid category.errors[:description].should == ["Description can't be blank"] end + + it 'validates the translations' do + category = FactoryGirl.build(:public_body_category) + translation = category.translations.build + expect(category).to_not be_valid + end + + it 'uses the base model validation for the default locale' do + category = PublicBodyCategory.new + translation = category.translations.build(:locale => 'en', + :description => 'No title') + category.valid? + translation.valid? + + expect(category).to have(1).error_on(:title) + expect(translation).to have(0).errors_on(:title) + end + + end + + describe :save do + + it 'saves translations' do + category = FactoryGirl.build(:public_body_category) + category.translations_attributes = { :es => { :locale => 'es', + :title => 'El Category', + :description => 'Spanish description' } } + + category.save + expect(PublicBodyCategory.find(category.id).translations.size).to eq(2) + end + end + + describe :translations_attributes= do + + context 'translation_attrs is a Hash' do + + it 'does not persist translations' do + category = FactoryGirl.create(:public_body_category) + category.translations_attributes = { :es => { :locale => 'es', + :title => 'El Category', + :description => 'Spanish description' } } + + expect(PublicBodyCategory.find(category.id).translations.size).to eq(1) + end + + it 'creates a new translation' do + category = FactoryGirl.create(:public_body_category) + category.translations_attributes = { :es => { :locale => 'es', + :title => 'El Category', + :description => 'Spanish description' } } + category.save + category.reload + expect(category.title(:es)).to eq('El Category') + end + + it 'updates an existing translation' do + category = FactoryGirl.create(:public_body_category) + category.translations_attributes = { 'es' => { :locale => 'es', + :title => 'Name', + :description => 'Desc' } } + category.save + + category.translations_attributes = { 'es' => { :id => category.translation_for(:es).id, + :locale => 'es', + :title => 'Renamed', + :description => 'Desc' } } + category.save + expect(category.title(:es)).to eq('Renamed') + end + + it 'updates an existing translation and creates a new translation' do + category = FactoryGirl.create(:public_body_category) + category.translations.create(:locale => 'es', + :title => 'Los Category', + :description => 'ES Description') + + expect(category.translations.size).to eq(2) + + category.translations_attributes = { + 'es' => { :id => category.translation_for(:es).id, + :locale => 'es', + :title => 'Renamed' }, + 'fr' => { :locale => 'fr', + :title => 'Le Category' } + } + + expect(category.translations.size).to eq(3) + I18n.with_locale(:es) { expect(category.title).to eq('Renamed') } + I18n.with_locale(:fr) { expect(category.title).to eq('Le Category') } + end + + it 'skips empty translations' do + category = FactoryGirl.create(:public_body_category) + category.translations.create(:locale => 'es', + :title => 'Los Category', + :description => 'ES Description') + + expect(category.translations.size).to eq(2) + + category.translations_attributes = { + 'es' => { :id => category.translation_for(:es).id, + :locale => 'es', + :title => 'Renamed' }, + 'fr' => { :locale => 'fr' } + } + + expect(category.translations.size).to eq(2) + end + + end + end + +end + +describe PublicBodyCategory::Translation do + + it 'requires a locale' do + translation = PublicBodyCategory::Translation.new + translation.valid? + expect(translation.errors[:locale]).to eq(["can't be blank"]) + end + + it 'is valid if no required attributes are assigned' do + translation = PublicBodyCategory::Translation.new(:locale => I18n.default_locale) + expect(translation).to be_valid + end + + it 'requires a title if another required attribute is assigned' do + translation = PublicBodyCategory::Translation.new(:description => 'spec') + translation.valid? + expect(translation.errors[:title]).to eq(["Title can't be blank"]) + end + + it 'requires a description if another required attribute is assigned' do + translation = PublicBodyCategory::Translation.new(:title => 'spec') + translation.valid? + expect(translation.errors[:description]).to eq(["Description can't be blank"]) + end + end diff --git a/spec/models/public_body_heading_spec.rb b/spec/models/public_body_heading_spec.rb index add2cac60..be3e7c7d2 100644 --- a/spec/models/public_body_heading_spec.rb +++ b/spec/models/public_body_heading_spec.rb @@ -2,9 +2,7 @@ # # Table name: public_body_headings # -# id :integer not null, primary key -# locale :string -# name :text not null +# id :integer not null, primary key # display_order :integer # @@ -12,26 +10,6 @@ require 'spec_helper' describe PublicBodyHeading do - context 'when loading the data' do - - before do - PublicBodyCategory.add(:en, [ - "Local and regional", - [ "local_council", "Local councils", "a local council" ], - "Miscellaneous", - [ "other", "Miscellaneous", "miscellaneous" ],]) - end - - it 'should use the display_order field to preserve the original data order' do - headings = PublicBodyHeading.all - headings[0].name.should eq 'Local and regional' - headings[0].display_order.should eq 0 - headings[1].name.should eq 'Miscellaneous' - headings[1].display_order.should eq 1 - end - - end - context 'when validating' do it 'should require a name' do @@ -52,6 +30,13 @@ describe PublicBodyHeading do heading.valid? heading.display_order.should == PublicBodyHeading.next_display_order end + + it 'validates the translations' do + heading = FactoryGirl.build(:public_body_heading) + translation = heading.translations.build + expect(heading).to_not be_valid + end + end context 'when setting a display order' do @@ -65,4 +50,105 @@ describe PublicBodyHeading do PublicBodyHeading.next_display_order.should == 1 end end + + describe :save do + + it 'saves translations' do + heading = FactoryGirl.build(:public_body_heading) + heading.translations_attributes = { :es => { :locale => 'es', + :name => 'El Heading' } } + + heading.save + expect(PublicBodyHeading.find(heading.id).translations.size).to eq(2) + end + + end + + describe :translations_attributes= do + + context 'translation_attrs is a Hash' do + + it 'does not persist translations' do + heading = FactoryGirl.create(:public_body_heading) + heading.translations_attributes = { :es => { :locale => 'es', + :name => 'El Heading' } } + + expect(PublicBodyHeading.find(heading.id).translations.size).to eq(1) + end + + it 'creates a new translation' do + heading = FactoryGirl.create(:public_body_heading) + heading.translations_attributes = { :es => { :locale => 'es', + :name => 'El Heading' } } + heading.save + heading.reload + expect(heading.name(:es)).to eq('El Heading') + end + + it 'updates an existing translation' do + heading = FactoryGirl.create(:public_body_heading) + heading.translations_attributes = { 'es' => { :locale => 'es', + :name => 'Name' } } + heading.save + + heading.translations_attributes = { 'es' => { :id => heading.translation_for(:es).id, + :locale => 'es', + :name => 'Renamed' } } + heading.save + expect(heading.name(:es)).to eq('Renamed') + end + + it 'updates an existing translation and creates a new translation' do + heading = FactoryGirl.create(:public_body_heading) + heading.translations.create(:locale => 'es', + :name => 'Los Heading') + + expect(heading.translations.size).to eq(2) + + heading.translations_attributes = { + 'es' => { :id => heading.translation_for(:es).id, + :locale => 'es', + :name => 'Renamed' }, + 'fr' => { :locale => 'fr', + :name => 'Le Heading' } + } + + expect(heading.translations.size).to eq(3) + I18n.with_locale(:es) { expect(heading.name).to eq('Renamed') } + I18n.with_locale(:fr) { expect(heading.name).to eq('Le Heading') } + end + + it 'skips empty translations' do + heading = FactoryGirl.create(:public_body_heading) + heading.translations.create(:locale => 'es', + :name => 'Los Heading') + + expect(heading.translations.size).to eq(2) + + heading.translations_attributes = { + 'es' => { :id => heading.translation_for(:es).id, + :locale => 'es', + :name => 'Renamed' }, + 'fr' => { :locale => 'fr' } + } + + expect(heading.translations.size).to eq(2) + end + end + end +end + +describe PublicBodyHeading::Translation do + + it 'requires a locale' do + translation = PublicBodyHeading::Translation.new + translation.valid? + expect(translation.errors[:locale]).to eq(["can't be blank"]) + end + + it 'is valid if all required attributes are assigned' do + translation = PublicBodyHeading::Translation.new(:locale => I18n.default_locale) + expect(translation).to be_valid + end + end diff --git a/spec/models/public_body_spec.rb b/spec/models/public_body_spec.rb index f12582f21..7b55efda1 100644 --- a/spec/models/public_body_spec.rb +++ b/spec/models/public_body_spec.rb @@ -30,106 +30,81 @@ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') describe PublicBody do - describe :translations_attributes= do - - context 'translation_attrs is a Hash' do - - it 'takes the correct code path for a Hash' do - attrs = {} - attrs.should_receive(:each_value) - PublicBody.new().translations_attributes = attrs - end - - it 'updates an existing translation' do - body = public_bodies(:geraldine_public_body) - translation = body.translation_for(:es) - params = { 'es' => { :locale => 'es', - :name => 'Renamed' } } - - body.translations_attributes = params - I18n.with_locale(:es) { expect(body.name).to eq('Renamed') } - end - - it 'updates an existing translation and creates a new translation' do - body = public_bodies(:geraldine_public_body) - translation = body.translation_for(:es) - - expect(body.translations.size).to eq(2) - - body.translations_attributes = { - 'es' => { :locale => 'es', - :name => 'Renamed' }, - 'fr' => { :locale => 'fr', - :name => 'Le Geraldine Quango' } - } - - expect(body.translations.size).to eq(3) - I18n.with_locale(:es) { expect(body.name).to eq('Renamed') } - I18n.with_locale(:fr) { expect(body.name).to eq('Le Geraldine Quango') } - end - - it 'skips empty translations' do - body = public_bodies(:geraldine_public_body) - translation = body.translation_for(:es) - - expect(body.translations.size).to eq(2) - - body.translations_attributes = { - 'es' => { :locale => 'es', - :name => 'Renamed' }, - 'fr' => { :locale => 'fr' } - } - - expect(body.translations.size).to eq(2) - end - - end - - context 'translation_attrs is an Array' do - - it 'takes the correct code path for an Array' do - attrs = [] - attrs.should_receive(:each) - PublicBody.new().translations_attributes = attrs - end - - it 'creates a new translation' do - body = public_bodies(:geraldine_public_body) - body.translation_for(:es).destroy - body.reload - - expect(body.translations.size).to eq(1) - - body.translations_attributes = [ { - :locale => 'es', - :name => 'Renamed' - } - ] - - expect(body.translations.size).to eq(2) - I18n.with_locale(:es) { expect(body.name).to eq('Renamed') } - end - - it 'skips empty translations' do - body = public_bodies(:geraldine_public_body) - body.translation_for(:es).destroy - body.reload - - expect(body.translations.size).to eq(1) - - body.translations_attributes = [ - { :locale => 'empty' } - ] - - expect(body.translations.size).to eq(1) - end - - end - - end - + describe :translations_attributes= do + + context 'translation_attrs is a Hash' do + + it 'does not persist translations' do + body = FactoryGirl.create(:public_body) + body.translations_attributes = { :es => { :locale => 'es', + :name => 'El Body' } } + + expect(PublicBody.find(body.id).translations.size).to eq(1) + end + + it 'creates a new translation' do + body = FactoryGirl.create(:public_body) + body.translations_attributes = { :es => { :locale => 'es', + :name => 'El Body' } } + body.save + body.reload + expect(body.name(:es)).to eq('El Body') + end + + it 'updates an existing translation' do + body = FactoryGirl.create(:public_body) + body.translations_attributes = { 'es' => { :locale => 'es', + :name => 'El Body' } } + body.save + + body.translations_attributes = { 'es' => { :id => body.translation_for(:es).id, + :locale => 'es', + :name => 'Renamed' } } + body.save + expect(body.name(:es)).to eq('Renamed') + end + + it 'updates an existing translation and creates a new translation' do + body = FactoryGirl.create(:public_body) + body.translations.create(:locale => 'es', + :name => 'El Body') + + expect(body.translations.size).to eq(2) + + body.translations_attributes = { + 'es' => { :id => body.translation_for(:es).id, + :locale => 'es', + :name => 'Renamed' }, + 'fr' => { :locale => 'fr', + :name => 'Le Body' } + } + + expect(body.translations.size).to eq(3) + I18n.with_locale(:es) { expect(body.name).to eq('Renamed') } + I18n.with_locale(:fr) { expect(body.name).to eq('Le Body') } + end + + it 'skips empty translations' do + body = FactoryGirl.create(:public_body) + body.translations.create(:locale => 'es', + :name => 'El Body') + + expect(body.translations.size).to eq(2) + + body.translations_attributes = { + 'es' => { :id => body.translation_for(:es).id, + :locale => 'es', + :name => 'Renamed' }, + 'fr' => { :locale => 'fr' } + } + + expect(body.translations.size).to eq(2) + end + end + end end + describe PublicBody, " using tags" do before do @public_body = PublicBody.new(:name => 'Aardvark Monitoring Service', @@ -548,7 +523,7 @@ describe PublicBody, " when loading CSV files" do PublicBody.find_by_name('Fake Authority of Northern Ireland').tag_array_for_search.should == ['aTag', 'fake'] # Import again to check the 'add' tag functionality works - new_tags_file = load_file_fixture('fake-authority-add-tags.rb') + new_tags_file = load_file_fixture('fake-authority-add-tags.csv') errors, notes = PublicBody.import_csv(new_tags_file, '', 'add', false, 'someadmin') # false means real run # Check tags were added successfully @@ -567,15 +542,284 @@ describe PublicBody, " when loading CSV files" do PublicBody.find_by_name('Fake Authority of Northern Ireland').tag_array_for_search.should == ['aTag', 'fake'] # Import again to check the 'replace' tag functionality works - new_tags_file = load_file_fixture('fake-authority-add-tags.rb') + new_tags_file = load_file_fixture('fake-authority-add-tags.csv') errors, notes = PublicBody.import_csv(new_tags_file, 'fake', 'replace', false, 'someadmin') # false means real run # Check tags were added successfully - PublicBody.find_by_name('North West Fake Authority').tag_array_for_search.should == ['aTag'] - PublicBody.find_by_name('Scottish Fake Authority').tag_array_for_search.should == ['aTag'] + PublicBody.find_by_name('North West Fake Authority').tag_array_for_search.should == ['aTag', 'fake'] + PublicBody.find_by_name('Scottish Fake Authority').tag_array_for_search.should == ['aTag', 'fake'] PublicBody.find_by_name('Fake Authority of Northern Ireland').tag_array_for_search.should == ['aTag', 'fake'] end + + context 'when the import tag is set' do + + context 'with a new body' do + + it 'appends the import tag when no tag_string is specified' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + ,q@localhost,Quango,,http://example.org + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, 'imported', 'add', false, 'someadmin') + + expected = %W(imported) + expect(PublicBody.find_by_name('Quango').tag_array_for_search).to eq(expected) + end + + it 'appends the import tag when a tag_string is specified' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + ,q@localhost,Quango,first_tag second_tag,http://example.org + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, 'imported', 'add', false, 'someadmin') + + expected = %W(first_tag imported second_tag) + expect(PublicBody.find_by_name('Quango').tag_array_for_search).to eq(expected) + end + + it 'replaces with the import tag when no tag_string is specified' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + ,q@localhost,Quango,,http://example.org + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, 'imported', 'replace', false, 'someadmin') + + expected = %W(imported) + expect(PublicBody.find_by_name('Quango').tag_array_for_search).to eq(expected) + end + + it 'replaces with the import tag and tag_string when a tag_string is specified' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + ,q@localhost,Quango,first_tag second_tag,http://example.org + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, 'imported', 'replace', false, 'someadmin') + + expected = %W(first_tag imported second_tag) + expect(PublicBody.find_by_name('Quango').tag_array_for_search).to eq(expected) + end + + end + + context 'an existing body without tags' do + + before do + @body = FactoryGirl.create(:public_body, :name => 'Existing Body') + end + + it 'will not import if there is an existing body without the tag' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + #{ @body.id },#{ @body.request_email },"#{ @body.name }",,#{ @body.home_page } + CSV + + # csv, tag, tag_behaviour, dry_run, editor + errors, notes = PublicBody.import_csv(csv, 'imported', 'add', false, 'someadmin') + + expected = %W(imported) + errors.should include("error: line 2: Name Name is already taken for authority 'Existing Body'") + end + + end + + context 'an existing body with tags' do + + before do + @body = FactoryGirl.create(:public_body, :tag_string => 'imported first_tag second_tag') + end + + it 'created with tags, different tags in csv, add import tag' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + #{ @body.id },#{ @body.request_email },"#{ @body.name }","first_tag new_tag",#{ @body.home_page } + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, 'imported', 'add', false, 'someadmin') + expected = %W(first_tag imported new_tag second_tag) + expect(PublicBody.find(@body.id).tag_array_for_search).to eq(expected) + end + + it 'created with tags, different tags in csv, replace import tag' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + #{ @body.id },#{ @body.request_email },"#{ @body.name }","first_tag new_tag",#{ @body.home_page } + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, 'imported', 'replace', false, 'someadmin') + + expected = %W(first_tag imported new_tag) + expect(PublicBody.find(@body.id).tag_array_for_search).to eq(expected) + end + + end + + end + + context 'when the import tag is not set' do + + context 'with a new body' do + + it 'it is empty if no tag_string is set' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + ,q@localhost,Quango,,http://example.org + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, '', 'add', false, 'someadmin') + + expected = [] + expect(PublicBody.find_by_name('Quango').tag_array_for_search).to eq(expected) + end + + it 'uses the specified tag_string' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + ,q@localhost,Quango,first_tag,http://example.org + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, '', 'add', false, 'someadmin') + + expected = %W(first_tag) + expect(PublicBody.find_by_name('Quango').tag_array_for_search).to eq(expected) + end + + it 'replaces with empty if no tag_string is set' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + ,q@localhost,Quango,,http://example.org + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, '', 'replace', false, 'someadmin') + + expected = [] + expect(PublicBody.find_by_name('Quango').tag_array_for_search).to eq(expected) + end + + it 'replaces with the specified tag_string' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + ,q@localhost,Quango,first_tag,http://example.org + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, '', 'replace', false, 'someadmin') + + expected = %W(first_tag) + expect(PublicBody.find_by_name('Quango').tag_array_for_search).to eq(expected) + end + + end + + context 'with an existing body without tags' do + + before do + @body = FactoryGirl.create(:public_body) + end + + it 'appends when no tag_string is specified' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + #{ @body.id },#{ @body.request_email },"#{ @body.name }",,#{ @body.home_page } + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, '', 'add', false, 'someadmin') + + expected = [] + expect(PublicBody.find(@body.id).tag_array_for_search).to eq(expected) + end + + it 'appends when a tag_string is specified' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + #{ @body.id },#{ @body.request_email },"#{ @body.name }",new_tag,#{ @body.home_page } + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, '', 'add', false, 'someadmin') + + expected = %W(new_tag) + expect(PublicBody.find(@body.id).tag_array_for_search).to eq(expected) + end + + it 'replaces when no tag_string is specified' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + #{ @body.id },#{ @body.request_email },"#{ @body.name }",,#{ @body.home_page } + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, '', 'replace', false, 'someadmin') + + expected = [] + expect(PublicBody.find(@body.id).tag_array_for_search).to eq(expected) + end + + it 'replaces when a tag_string is specified' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + #{ @body.id },#{ @body.request_email },"#{ @body.name }",new_tag,#{ @body.home_page } + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, '', 'replace', false, 'someadmin') + + expected = %W(new_tag) + expect(PublicBody.find(@body.id).tag_array_for_search).to eq(expected) + end + + end + + describe 'with an existing body with tags' do + + before do + @body = FactoryGirl.create(:public_body, :tag_string => 'first_tag second_tag') + end + + it 'created with tags, different tags in csv, add tags' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + #{ @body.id },#{ @body.request_email },"#{ @body.name }","first_tag new_tag",#{ @body.home_page } + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, '', 'add', false, 'someadmin') + + expected = %W(first_tag new_tag second_tag) + expect(PublicBody.find(@body.id).tag_array_for_search).to eq(expected) + end + + it 'created with tags, different tags in csv, replace' do + csv = <<-CSV.strip_heredoc + #id,request_email,name,tag_string,home_page + #{ @body.id },#{ @body.request_email },"#{ @body.name }","first_tag new_tag",#{ @body.home_page } + CSV + + # csv, tag, tag_behaviour, dry_run, editor + PublicBody.import_csv(csv, '', 'replace', false, 'someadmin') + + expected = %W(first_tag new_tag) + expect(PublicBody.find(@body.id).tag_array_for_search).to eq(expected) + end + + end + + end + it "should create bodies with names in multiple locales" do original_count = PublicBody.count @@ -700,6 +944,22 @@ CSV PublicBody.csv_import_fields = old_csv_import_fields end + it "should import translations for fields whose values are the same as the default locale's" do + original_count = PublicBody.count + + csv_contents = load_file_fixture("multiple-locales-same-name.csv") + + errors, notes = PublicBody.import_csv(csv_contents, '', 'replace', true, 'someadmin', ['en', 'es']) # true means dry run + errors.should == [] + notes.size.should == 3 + notes[0..1].should == [ + "line 2: creating new authority 'Test' (locale: en):\n\t{\"name\":\"Test\",\"request_email\":\"test@test.es\",\"home_page\":\"http://www.test.es/\",\"tag_string\":\"37\"}", + "line 2: creating new authority 'Test' (locale: es):\n\t{\"name\":\"Test\"}", + ] + notes[2].should =~ /Notes: Some bodies are in database, but not in CSV file:\n( .+\n)*You may want to delete them manually.\n/ + + PublicBody.count.should == original_count + end end describe PublicBody do @@ -762,6 +1022,53 @@ describe PublicBody do end + describe :has_request_email? do + + before do + @body = PublicBody.new(:request_email => 'test@example.com') + end + + it 'should return false if request_email is nil' do + @body.request_email = nil + @body.has_request_email?.should == false + end + + it 'should return false if the request email is "blank"' do + @body.request_email = 'blank' + @body.has_request_email?.should == false + end + + it 'should return false if the request email is an empty string' do + @body.request_email = '' + @body.has_request_email?.should == false + end + + it 'should return true if the request email is an email address' do + @body.has_request_email?.should == true + end + end + + describe :special_not_requestable_reason do + + before do + @body = PublicBody.new + end + + it 'should return true if the body is defunct' do + @body.stub!(:defunct?).and_return(true) + @body.special_not_requestable_reason?.should == true + end + + it 'should return true if FOI does not apply' do + @body.stub!(:not_apply?).and_return(true) + @body.special_not_requestable_reason?.should == true + end + + it 'should return false if the body is not defunct and FOI applies' do + @body.special_not_requestable_reason?.should == false + end + end + end describe PublicBody, " when override all public body request emails set" do @@ -854,3 +1161,95 @@ describe PublicBody, 'when asked for popular bodies' do end end + +describe PublicBody do + + describe :is_requestable? do + + before do + @body = PublicBody.new(:request_email => 'test@example.com') + end + + it 'should return false if the body is defunct' do + @body.stub!(:defunct?).and_return true + @body.is_requestable?.should == false + end + + it 'should return false if FOI does not apply' do + @body.stub!(:not_apply?).and_return true + @body.is_requestable?.should == false + end + + it 'should return false there is no request_email' do + @body.stub!(:has_request_email?).and_return false + @body.is_requestable?.should == false + end + + it 'should return true if the request email is an email address' do + @body.is_requestable?.should == true + end + + end + + describe :is_followupable? do + + before do + @body = PublicBody.new(:request_email => 'test@example.com') + end + + it 'should return false there is no request_email' do + @body.stub!(:has_request_email?).and_return false + @body.is_followupable?.should == false + end + + it 'should return true if the request email is an email address' do + @body.is_followupable?.should == true + end + + end + + describe :not_requestable_reason do + + before do + @body = PublicBody.new(:request_email => 'test@example.com') + end + + it 'should return "defunct" if the body is defunct' do + @body.stub!(:defunct?).and_return true + @body.not_requestable_reason.should == 'defunct' + end + + it 'should return "not_apply" if FOI does not apply' do + @body.stub!(:not_apply?).and_return true + @body.not_requestable_reason.should == 'not_apply' + end + + + it 'should return "bad_contact" there is no request_email' do + @body.stub!(:has_request_email?).and_return false + @body.not_requestable_reason.should == 'bad_contact' + end + + it 'should raise an error if the body is not defunct, FOI applies and has an email address' do + expected_error = "not_requestable_reason called with type that has no reason" + lambda{ @body.not_requestable_reason }.should raise_error(expected_error) + end + + end + +end + +describe PublicBody::Translation do + + it 'requires a locale' do + translation = PublicBody::Translation.new + translation.valid? + expect(translation.errors[:locale]).to eq(["can't be blank"]) + end + + it 'is valid if all required attributes are assigned' do + translation = PublicBody::Translation.new(:locale => I18n.default_locale) + expect(translation).to be_valid + end + +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 7dcd3ab8a..2245a024f 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -369,3 +369,21 @@ describe User, "when calculating if a user has exceeded the request limit" do end + +describe User do + + describe :banned? do + + it 'is banned if the user has ban_text' do + user = FactoryGirl.build(:user, :ban_text => 'banned') + expect(user).to be_banned + end + + it 'is not banned if the user has no ban_text' do + user = FactoryGirl.build(:user, :ban_text => '') + expect(user).to_not be_banned + end + + end + +end |