diff options
-rw-r--r-- | app/assets/stylesheets/responsive/_user_layout.scss | 5 | ||||
-rw-r--r-- | app/controllers/admin_controller.rb | 3 | ||||
-rw-r--r-- | app/controllers/application_controller.rb | 8 | ||||
-rw-r--r-- | app/controllers/general_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/user_controller.rb | 6 | ||||
-rw-r--r-- | app/models/censor_rule.rb | 6 | ||||
-rw-r--r-- | app/models/info_request.rb | 13 | ||||
-rw-r--r-- | app/models/outgoing_message.rb | 216 | ||||
-rwxr-xr-x | config/sysvinit-thin.ugly | 3 | ||||
-rw-r--r-- | doc/CHANGES.md | 11 | ||||
-rw-r--r-- | lib/tasks/config_files.rake | 3 | ||||
-rw-r--r-- | spec/controllers/user_controller_spec.rb | 10 | ||||
-rw-r--r-- | spec/integration/alaveteli_dsl.rb | 9 | ||||
-rw-r--r-- | spec/integration/view_request_spec.rb | 22 | ||||
-rw-r--r-- | spec/models/censor_rule_spec.rb | 33 | ||||
-rw-r--r-- | spec/models/info_request_spec.rb | 17 |
16 files changed, 249 insertions, 118 deletions
diff --git a/app/assets/stylesheets/responsive/_user_layout.scss b/app/assets/stylesheets/responsive/_user_layout.scss index 8087f978c..a568a5fa3 100644 --- a/app/assets/stylesheets/responsive/_user_layout.scss +++ b/app/assets/stylesheets/responsive/_user_layout.scss @@ -1,2 +1,7 @@ /* Layout for user pages */ +#user_profile_search { + #search_form { + margin-top: 2rem; + } +} diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 8b606ea85..3bf40b8f9 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -25,8 +25,7 @@ class AdminController < ApplicationController def expire_for_request(info_request) # Clear out cached entries, by removing files from disk (the built in # Rails fragment cache made doing this and other things too hard) - cache_subpath = foi_fragment_cache_all_for_request(info_request) - FileUtils.rm_rf(cache_subpath) + info_request.foi_fragment_cache_directories.each{ |dir| FileUtils.rm_rf(dir) } # Remove any download zips FileUtils.rm_rf(info_request.download_zip_dir) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 0c5f5bd02..4d3f40d40 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -189,14 +189,6 @@ class ApplicationController < ActionController::Base return File.join(File.split(path).map{|x| x[0...max_file_length]}) end - def foi_fragment_cache_all_for_request(info_request) - # return stub path so admin can expire it - first_three_digits = info_request.id.to_s()[0..2] - path = "views/request/#{first_three_digits}/#{info_request.id}" - foi_cache_path = File.expand_path(File.join(File.dirname(__FILE__), '../../cache')) - return File.join(foi_cache_path, path) - end - def foi_fragment_cache_exists?(key_path) return File.exists?(key_path) end diff --git a/app/controllers/general_controller.rb b/app/controllers/general_controller.rb index 158492eb2..2c8abbaf4 100644 --- a/app/controllers/general_controller.rb +++ b/app/controllers/general_controller.rb @@ -32,7 +32,7 @@ class GeneralController < ApplicationController if !content.empty? @data = XmlSimple.xml_in(content) @channel = @data['channel'][0] - @blog_items = @channel['item'] + @blog_items = @channel.fetch('item') { [] } @feed_autodetect = [{:url => @feed_url, :title => "#{site_name} blog"}] end end diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb index fcc500e06..f23343ddb 100644 --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@ -199,7 +199,7 @@ class UserController < ApplicationController work_out_post_redirect @request_from_foreign_country = country_from_ip != AlaveteliConfiguration::iso_country_code # Make the user and try to save it - @user_signup = User.new(params[:user_signup]) + @user_signup = User.new(user_params(:user_signup)) error = false if @request_from_foreign_country && !verify_recaptcha flash.now[:error] = _("There was an error with the words you entered, please try again.") @@ -601,6 +601,10 @@ class UserController < ApplicationController private + def user_params(key = :user) + params[key].slice(:name, :email, :password, :password_confirmation) + end + def is_modal_dialog (params[:modal].to_i != 0) end diff --git a/app/models/censor_rule.rb b/app/models/censor_rule.rb index 3c5c77563..62cf8112f 100644 --- a/app/models/censor_rule.rb +++ b/app/models/censor_rule.rb @@ -30,7 +30,11 @@ class CensorRule < ActiveRecord::Base attr_accessor :allow_global validate :require_user_request_or_public_body, :unless => proc{ |rule| rule.allow_global == true } validate :require_valid_regexp, :if => proc{ |rule| rule.regexp? == true } - validates_presence_of :text + + validates_presence_of :text, + :replacement, + :last_edit_comment, + :last_edit_editor scope :global, {:conditions => {:info_request_id => nil, :user_id => nil, diff --git a/app/models/info_request.rb b/app/models/info_request.rb index aed651ad3..d0052603a 100644 --- a/app/models/info_request.rb +++ b/app/models/info_request.rb @@ -1048,6 +1048,19 @@ public File.join(Rails.root, "cache", "zips", "#{Rails.env}") end + def foi_fragment_cache_directories + # return stub path so admin can expire it + directories = [] + path = File.join("request", request_dirs) + foi_cache_path = File.expand_path(File.join(Rails.root, 'cache', 'views')) + directories << File.join(foi_cache_path, path) + I18n.available_locales.each do |locale| + directories << File.join(foi_cache_path, locale.to_s, path) + end + + directories + end + def request_dirs first_three_digits = id.to_s()[0..2] File.join(first_three_digits.to_s, id.to_s) diff --git a/app/models/outgoing_message.rb b/app/models/outgoing_message.rb index 160f69d0b..9424113fc 100644 --- a/app/models/outgoing_message.rb +++ b/app/models/outgoing_message.rb @@ -28,106 +28,115 @@ class OutgoingMessage < ActiveRecord::Base extend MessageProminence include Rails.application.routes.url_helpers include LinkToHelper - self.default_url_options[:host] = AlaveteliConfiguration::domain - # https links in emails if forcing SSL - if AlaveteliConfiguration::force_ssl - self.default_url_options[:protocol] = "https" - end - strip_attributes! - - has_prominence + # To override the default letter + attr_accessor :default_letter - belongs_to :info_request validates_presence_of :info_request - validates_inclusion_of :status, :in => ['ready', 'sent', 'failed'] - validates_inclusion_of :message_type, :in => ['initial_request', 'followup' ] #, 'complaint'] + validates_inclusion_of :message_type, :in => ['initial_request', 'followup'] validate :format_of_body + belongs_to :info_request belongs_to :incoming_message_followup, :foreign_key => 'incoming_message_followup_id', :class_name => 'IncomingMessage' # can have many events, for items which were resent by site admin e.g. if # contact address changed has_many :info_request_events - # To override the default letter - attr_accessor :default_letter - + after_initialize :set_default_letter + after_save :purge_in_cache # reindex if body text is edited (e.g. by admin interface) after_update :xapian_reindex_after_update - def xapian_reindex_after_update - if self.changes.include?('body') - for info_request_event in self.info_request_events - info_request_event.xapian_mark_needs_index - end - end - end - after_initialize :set_default_letter + strip_attributes! + has_prominence - # How the default letter starts and ends - def get_salutation - if self.info_request.is_batch_request_template? - return OutgoingMessage.placeholder_salutation - end - ret = "" - if self.message_type == 'followup' && !self.incoming_message_followup.nil? && !self.incoming_message_followup.safe_mail_from.nil? && self.incoming_message_followup.valid_to_reply_to? - ret = ret + OutgoingMailer.name_for_followup(self.info_request, self.incoming_message_followup) - else - return OutgoingMessage.default_salutation(self.info_request.public_body) - end - salutation = _("Dear {{public_body_name}},", :public_body_name => ret) + self.default_url_options[:host] = AlaveteliConfiguration.domain + + # https links in emails if forcing SSL + if AlaveteliConfiguration::force_ssl + self.default_url_options[:protocol] = "https" end - def OutgoingMessage.default_salutation(public_body) + def self.default_salutation(public_body) _("Dear {{public_body_name}},", :public_body_name => public_body.name) end - def OutgoingMessage.placeholder_salutation + def self.placeholder_salutation _("Dear [Authority name],") end - def OutgoingMessage.fill_in_salutation(body, public_body) + def self.fill_in_salutation(body, public_body) body.gsub(placeholder_salutation, default_salutation(public_body)) end + # How the default letter starts and ends + def get_salutation + if info_request.is_batch_request_template? + return OutgoingMessage.placeholder_salutation + end + + ret = "" + if message_type == 'followup' && + !incoming_message_followup.nil? && + !incoming_message_followup.safe_mail_from.nil? && + incoming_message_followup.valid_to_reply_to? + + ret += OutgoingMailer.name_for_followup(info_request, incoming_message_followup) + else + return OutgoingMessage.default_salutation(info_request.public_body) + end + salutation = _("Dear {{public_body_name}},", :public_body_name => ret) + end + def get_signoff - if self.message_type == 'followup' && !self.incoming_message_followup.nil? && !self.incoming_message_followup.safe_mail_from.nil? && self.incoming_message_followup.valid_to_reply_to? - return _("Yours sincerely,") + if message_type == 'followup' && + !incoming_message_followup.nil? && + !incoming_message_followup.safe_mail_from.nil? && + incoming_message_followup.valid_to_reply_to? + + _("Yours sincerely,") else - return _("Yours faithfully,") + _("Yours faithfully,") end end + def get_internal_review_insert_here_note - return _("GIVE DETAILS ABOUT YOUR COMPLAINT HERE") + _("GIVE DETAILS ABOUT YOUR COMPLAINT HERE") end - def get_default_letter - if self.default_letter - return self.default_letter - end - if self.what_doing == 'internal_review' - _("Please pass this on to the person who conducts Freedom of Information reviews.") + - "\n\n" + - _("I am writing to request an internal review of {{public_body_name}}'s handling of my FOI request '{{info_request_title}}'.", - :public_body_name => self.info_request.public_body.name, - :info_request_title => self.info_request.title) + - "\n\n\n\n [ " + self.get_internal_review_insert_here_note + " ] \n\n\n\n" + - _("A full history of my FOI request and all correspondence is available on the Internet at this address: {{url}}", - :url => request_url(self.info_request)) + - "\n" + def get_default_letter + return default_letter if default_letter + + if what_doing == 'internal_review' + letter = _("Please pass this on to the person who conducts Freedom of Information reviews.") + letter += "\n\n" + letter += _("I am writing to request an internal review of {{public_body_name}}'s handling of my FOI request '{{info_request_title}}'.", + :public_body_name => info_request.public_body.name, + :info_request_title => info_request.title) + letter += "\n\n\n\n [ #{ get_internal_review_insert_here_note } ] \n\n\n\n" + letter += _("A full history of my FOI request and all correspondence is available on the Internet at this address: {{url}}", + :url => request_url(info_request)) + letter += "\n" else "" end end + def get_default_message - get_salutation + "\n\n" + get_default_letter + "\n\n" + get_signoff + "\n\n" + msg = get_salutation + msg += "\n\n" + msg += get_default_letter + msg += "\n\n" + msg += get_signoff + msg += "\n\n" end + def set_signature_name(name) # TODO: We use raw_body here to get unstripped one - if self.raw_body == self.get_default_message - self.body = self.raw_body + name + if raw_body == get_default_message + self.body = raw_body + name end end @@ -142,84 +151,88 @@ class OutgoingMessage < ActiveRecord::Base ret.gsub!(/(?:\n\s*){2,}/, "\n\n") # remove excess linebreaks that unnecessarily space it out # Remove things from censor rules - if !self.info_request.nil? + unless info_request.nil? self.info_request.apply_censor_rules_to_text!(ret) end ret end + def raw_body read_attribute(:body) end # Used to give warnings when writing new messages def contains_email? - MySociety::Validate.email_find_regexp.match(self.body) + MySociety::Validate.email_find_regexp.match(body) end + def contains_postcode? - MySociety::Validate.contains_postcode?(self.body) + MySociety::Validate.contains_postcode?(body) end # Deliver outgoing message # Note: You can test this from script/console with, say: # InfoRequest.find(1).outgoing_messages[0].send_message def send_message(log_event_type = 'sent') - if self.status == 'ready' - if self.message_type == 'initial_request' + if status == 'ready' + if message_type == 'initial_request' self.last_sent_at = Time.now self.status = 'sent' self.save! - mail_message = OutgoingMailer.initial_request(self.info_request, self).deliver + mail_message = OutgoingMailer.initial_request(info_request, self).deliver self.info_request.log_event(log_event_type, { :email => mail_message.to_addrs.join(", "), :outgoing_message_id => self.id, :smtp_message_id => mail_message.message_id }) self.info_request.set_described_state('waiting_response') - elsif self.message_type == 'followup' + elsif message_type == 'followup' self.last_sent_at = Time.now self.status = 'sent' self.save! - mail_message = OutgoingMailer.followup(self.info_request, self, self.incoming_message_followup).deliver + mail_message = OutgoingMailer.followup(info_request, self, incoming_message_followup).deliver self.info_request.log_event('followup_' + log_event_type, { :email => mail_message.to_addrs.join(", "), :outgoing_message_id => self.id, :smtp_message_id => mail_message.message_id }) - if self.info_request.described_state == 'waiting_clarification' + if info_request.described_state == 'waiting_clarification' self.info_request.set_described_state('waiting_response') end - if self.what_doing == 'internal_review' + if what_doing == 'internal_review' self.info_request.set_described_state('internal_review') end else - raise "Message id #{self.id} has type '#{self.message_type}' which send_message can't handle" + raise "Message id #{id} has type '#{message_type}' which send_message can't handle" end - elsif self.status == 'sent' - raise "Message id #{self.id} has already been sent" + elsif status == 'sent' + raise "Message id #{id} has already been sent" else - raise "Message id #{self.id} not in state for send_message" + raise "Message id #{id} not in state for send_message" end end # An admin function def resend_message - if ['initial_request', 'followup'].include?(self.message_type) and self.status == 'sent' + if ['initial_request', 'followup'].include?(message_type) and status == 'sent' self.status = 'ready' send_message('resent') else - raise "Message id #{self.id} has type '#{self.message_type}' status '#{self.status}' which resend_message can't handle" + raise "Message id #{id} has type '#{message_type}' status '#{status}' which resend_message can't handle" end end # Returns the text to quote the original message when sending this one def quoted_part_to_append_to_email - if self.message_type == 'followup' && !self.incoming_message_followup.nil? - return "\n\n-----Original Message-----\n\n" + self.incoming_message_followup.get_body_for_quoting + "\n" + if message_type == 'followup' && !incoming_message_followup.nil? + quoted = "\n\n-----Original Message-----\n\n" + quoted += incoming_message_followup.get_body_for_quoting + quoted += "\n" else - return "" + "" end end @@ -229,8 +242,8 @@ class OutgoingMessage < ActiveRecord::Base end # Returns text for indexing / text display - def get_text_for_indexing(strip_salutation=true) - text = self.body.strip + def get_text_for_indexing(strip_salutation = true) + text = body.strip # Remove salutation text.sub!(/Dear .+,/, "") if strip_salutation @@ -238,19 +251,20 @@ class OutgoingMessage < ActiveRecord::Base # Remove email addresses from display/index etc. self.remove_privacy_sensitive_things!(text) - return text + text end # Return body for display as HTML def get_body_for_html_display - text = self.body.strip + text = body.strip self.remove_privacy_sensitive_things!(text) - text = MySociety::Format.wrap_email_body_by_lines(text) # reparagraph and wrap it so is good preview of emails + # reparagraph and wrap it so is good preview of emails + text = MySociety::Format.wrap_email_body_by_lines(text) text = CGI.escapeHTML(text) text = MySociety::Format.make_clickable(text, :contract => 1) text.gsub!(/\[(email address|mobile number)\]/, '[<a href="/help/officers#mobiles">\1</a>]') text = text.gsub(/\n/, '<br>') - return text.html_safe + text.html_safe end # Return body for display as text @@ -261,17 +275,16 @@ class OutgoingMessage < ActiveRecord::Base def fully_destroy ActiveRecord::Base.transaction do - info_request_event = InfoRequestEvent.find_by_outgoing_message_id(self.id) + info_request_event = InfoRequestEvent.find_by_outgoing_message_id(id) info_request_event.track_things_sent_emails.each { |a| a.destroy } info_request_event.user_info_request_sent_alerts.each { |a| a.destroy } info_request_event.destroy - self.destroy + destroy end end - after_save(:purge_in_cache) def purge_in_cache - self.info_request.purge_in_cache + info_request.purge_in_cache end def for_admin_column @@ -280,18 +293,24 @@ class OutgoingMessage < ActiveRecord::Base end end + def xapian_reindex_after_update + if changes.include?('body') + info_request_events.each do |event| + event.xapian_mark_needs_index + end + end + end + private def set_default_letter - if self.body.nil? - self.body = get_default_message - end + self.body = get_default_message if body.nil? end def format_of_body - if self.body.empty? || self.body =~ /\A#{Regexp.escape(get_salutation)}\s+#{Regexp.escape(get_signoff)}/ || self.body =~ /#{Regexp.escape(get_internal_review_insert_here_note)}/ - if self.message_type == 'followup' - if self.what_doing == 'internal_review' + if body.empty? || body =~ /\A#{Regexp.escape(get_salutation)}\s+#{Regexp.escape(get_signoff)}/ || body =~ /#{Regexp.escape(get_internal_review_insert_here_note)}/ + if message_type == 'followup' + if what_doing == 'internal_review' errors.add(:body, _("Please give details explaining why you want a review")) else errors.add(:body, _("Please enter your follow up message")) @@ -299,16 +318,19 @@ class OutgoingMessage < ActiveRecord::Base elsif errors.add(:body, _("Please enter your letter requesting information")) else - raise "Message id #{self.id} has type '#{self.message_type}' which validate can't handle" + raise "Message id #{id} has type '#{message_type}' which validate can't handle" end end - if self.body =~ /#{get_signoff}\s*\Z/m + + if body =~ /#{get_signoff}\s*\Z/m errors.add(:body, _("Please sign at the bottom with your name, or alter the \"{{signoff}}\" signature", :signoff => get_signoff)) end - if !MySociety::Validate.uses_mixed_capitals(self.body) + + unless MySociety::Validate.uses_mixed_capitals(body) errors.add(:body, _('Please write your message using a mixture of capital and lower case letters. This makes it easier for others to read.')) end - if self.what_doing.nil? || !['new_information', 'internal_review', 'normal_sort'].include?(self.what_doing) + + if what_doing.nil? || !['new_information', 'internal_review', 'normal_sort'].include?(what_doing) errors.add(:what_doing_dummy, _('Please choose what sort of reply you are making.')) end end diff --git a/config/sysvinit-thin.ugly b/config/sysvinit-thin.ugly index cc604d994..b333f3738 100755 --- a/config/sysvinit-thin.ugly +++ b/config/sysvinit-thin.ugly @@ -17,6 +17,7 @@ NAME=!!(*= $site *)!! SITE_HOME=!!(*= $vhost_dir *)!!/!!(*= $vcspath *)!! DESC="Alaveteli app server" USER=!!(*= $user *)!! +RAILS_ENV=!!(*= $rails_env *)!! set -e @@ -26,7 +27,7 @@ su -l -c "cd $SITE_HOME && bundle exec thin --version &> /dev/null || exit 0" $U start_daemon() { echo -n "Starting $DESC: " cd "$SITE_HOME" && bundle exec thin \ - --environment=production \ + --environment=$RAILS_ENV \ --user="$USER" \ --group="$USER" \ --address=127.0.0.1 \ diff --git a/doc/CHANGES.md b/doc/CHANGES.md index 237355c1d..748b37665 100644 --- a/doc/CHANGES.md +++ b/doc/CHANGES.md @@ -1,3 +1,14 @@ +# rails-3-develop + +## Highlighted Features + +## Upgrade Notes + +* `CensorRule` now validates the presence of all attributes at the model layer, + rather than only as a database constraint. If you have added a `CensorRule` in + your theme, you will now have to satisfy the additional validations on the + `:replacement`, `:last_edit_comment` and `:last_edit_editor` attributes. + # Version 0.19 ## Highlighted Features diff --git a/lib/tasks/config_files.rake b/lib/tasks/config_files.rake index 5dda64a04..1528d7324 100644 --- a/lib/tasks/config_files.rake +++ b/lib/tasks/config_files.rake @@ -32,7 +32,8 @@ namespace :config_files do :user => ENV['DEPLOY_USER'], :vhost_dir => ENV['VHOST_DIR'], :vcspath => ENV.fetch('VCSPATH') { 'alaveteli' }, - :site => ENV.fetch('SITE') { 'foi' } + :site => ENV.fetch('SITE') { 'foi' }, + :rails_env => ENV.fetch('RAILS_ENV') { 'development' } } # Use the filename for the $daemon_name ugly variable diff --git a/spec/controllers/user_controller_spec.rb b/spec/controllers/user_controller_spec.rb index 6ecdf1ad4..e4854fe6b 100644 --- a/spec/controllers/user_controller_spec.rb +++ b/spec/controllers/user_controller_spec.rb @@ -327,6 +327,16 @@ describe UserController, "when signing up" do deliveries[0].body.should match(/when\s+you\s+already\s+have\s+an/) end + it 'accepts only whitelisted parameters' do + post :signup, { :user_signup => { :email => 'silly@localhost', + :name => 'New Person', + :password => 'sillypassword', + :password_confirmation => 'sillypassword', + :admin_level => 'super' } } + + expect(assigns(:user_signup).admin_level).to eq('none') + end + # TODO: need to do bob@localhost signup and check that sends different email end diff --git a/spec/integration/alaveteli_dsl.rb b/spec/integration/alaveteli_dsl.rb index 119bb05a0..1d56abbdf 100644 --- a/spec/integration/alaveteli_dsl.rb +++ b/spec/integration/alaveteli_dsl.rb @@ -64,5 +64,14 @@ def close_request(request) request.save! end +def cache_directories_exist?(request) + cache_path = File.join(Rails.root, 'cache', 'views') + paths = [File.join(cache_path, 'request', request.request_dirs)] + I18n.available_locales.each do |locale| + paths << File.join(cache_path, locale.to_s, 'request', request.request_dirs) + end + paths.any?{ |path| File.exist?(path) } +end + diff --git a/spec/integration/view_request_spec.rb b/spec/integration/view_request_spec.rb index 814e20fb3..eecb984f5 100644 --- a/spec/integration/view_request_spec.rb +++ b/spec/integration/view_request_spec.rb @@ -19,6 +19,28 @@ describe "When viewing requests" do @unregistered.browses_request("#{@info_request.url_title}?action=add") end + context "when a request is hidden by an admin" do + + it 'should not retain any cached attachments to be served up by the webserver' do + admin = login(FactoryGirl.create(:admin_user)) + non_owner = login(FactoryGirl.create(:user)) + info_request = FactoryGirl.create(:info_request_with_incoming_attachments) + incoming_message = info_request.incoming_messages.first + attachment_url = "/es/request/#{info_request.id}/response/#{incoming_message.id}/attach/2/interesting.pdf" + non_owner.get(attachment_url) + cache_directories_exist?(info_request).should be_true + + # Admin makes the incoming message requester only + post_data = {:incoming_message => {:prominence => 'hidden', + :prominence_reason => 'boring'}} + admin.post_via_redirect "/admin/incoming/update/#{info_request.incoming_messages.first.id}", post_data + admin.response.should be_success + + cache_directories_exist?(info_request).should be_false + end + + end + context 'when a response has prominence "normal"' do before do diff --git a/spec/models/censor_rule_spec.rb b/spec/models/censor_rule_spec.rb index 5b41cc0d4..4ecd2d3e1 100644 --- a/spec/models/censor_rule_spec.rb +++ b/spec/models/censor_rule_spec.rb @@ -90,17 +90,32 @@ end describe 'when validating rules' do - it 'should be invalid without text' do + it 'must have the text to redact' do censor_rule = CensorRule.new - censor_rule.valid?.should == false - censor_rule.errors[:text].should == ["can't be blank"] + expect(censor_rule).to have(1).error_on(:text) + expect(censor_rule.errors[:text]).to eql(["can't be blank"]) + end + + it 'must have a replacement' do + expect(CensorRule.new).to have(1).error_on(:replacement) + end + + it 'must have a last_edit_editor' do + expect(CensorRule.new).to have(1).error_on(:last_edit_editor) + end + + it 'must have a last_edit_comment' do + expect(CensorRule.new).to have(1).error_on(:last_edit_comment) end describe 'when validating a regexp rule' do before do @censor_rule = CensorRule.new(:regexp => true, - :text => '*') + :text => '*', + :replacement => '---', + :last_edit_comment => 'test', + :last_edit_editor => 'rspec') end it 'should try to create a regexp from the text' do @@ -133,7 +148,10 @@ describe 'when validating rules' do describe 'when the allow_global flag has been set' do before do - @censor_rule = CensorRule.new(:text => 'some text') + @censor_rule = CensorRule.new(:text => 'some text', + :replacement => '---', + :last_edit_comment => 'test', + :last_edit_editor => 'rspec') @censor_rule.allow_global = true end @@ -146,7 +164,10 @@ describe 'when validating rules' do describe 'when the allow_global flag has not been set' do before do - @censor_rule = CensorRule.new(:text => '/./') + @censor_rule = CensorRule.new(:text => '/./', + :replacement => '---', + :last_edit_comment => 'test', + :last_edit_editor => 'rspec') end it 'should not allow a global text censor rule (without user_id, request_id or public_body_id)' do diff --git a/spec/models/info_request_spec.rb b/spec/models/info_request_spec.rb index 12499f50a..afb8e0949 100644 --- a/spec/models/info_request_spec.rb +++ b/spec/models/info_request_spec.rb @@ -147,6 +147,23 @@ describe InfoRequest do end + describe 'when managing the cache directories' do + before do + @info_request = info_requests(:fancy_dog_request) + end + + it 'should return the default locale cache path without locale parts' do + default_locale_path = File.join(Rails.root, 'cache', 'views', 'request', '101', '101') + @info_request.foi_fragment_cache_directories.include?(default_locale_path).should == true + end + + it 'should return the cache path for any other locales' do + other_locale_path = File.join(Rails.root, 'cache', 'views', 'es', 'request', '101', '101') + @info_request.foi_fragment_cache_directories.include?(other_locale_path).should == true + end + + end + describe " when emailing" do before do |