diff options
33 files changed, 502 insertions, 254 deletions
diff --git a/.travis.yml b/.travis.yml index c1e66c0e4..4c8fbef6a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ before_install: - export DEBIAN_FRONTEND=noninteractive - sudo apt-get -y install exim4-daemon-light - sudo apt-get -y install `cut -d " " -f 1 config/packages | egrep -v "(^#|wkhtml|bundler)"` - - ./script/rails-post-deploy + - RAILS_ENV=test ./script/rails-post-deploy before_script: notifications: irc: "irc.freenode.org#alaveteli" diff --git a/app/controllers/admin_censor_rule_controller.rb b/app/controllers/admin_censor_rule_controller.rb index 52df8dfc1..ec86cdf8e 100644 --- a/app/controllers/admin_censor_rule_controller.rb +++ b/app/controllers/admin_censor_rule_controller.rb @@ -31,6 +31,8 @@ class AdminCensorRuleController < AdminController redirect_to admin_url('request/show/' + @censor_rule.info_request.id.to_s) elsif !@censor_rule.user.nil? redirect_to admin_url('user/show/' + @censor_rule.user.id.to_s) + elsif @censor_rule.regexp? + redirect_to admin_url('') else raise "internal error" end diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 524aa44b7..4db07b4c9 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -155,6 +155,58 @@ class ApiController < ApplicationController head :no_content end + def body_request_events + feed_type = params[:feed_type] + raise PermissionDenied.new("#{@public_body.id} != #{params[:id]}") if @public_body.id != params[:id].to_i + + @events = InfoRequestEvent.find_by_sql([ + %(select info_request_events.* + from info_requests + join info_request_events on info_requests.id = info_request_events.info_request_id + where info_requests.public_body_id = ? + and info_request_events.event_type in ( + 'sent', 'followup_sent', 'resent', 'followup_resent' + ) + order by info_request_events.created_at desc + ), @public_body.id + ]) + if feed_type == "atom" + render :template => "api/request_events.atom", :layout => false + elsif feed_type == "json" + # For the JSON feed, we take a "since" parameter that allows the client + # to restrict to events more recent than a certain other event + if params[:since_event_id] + @since_event_id = params[:since_event_id].to_i + end + @event_data = [] + @events.each do |event| + break if event.id == @since_event_id + + request = event.info_request + this_event = { + :request_id => request.id, + :event_id => event.id, + :created_at => event.created_at.iso8601, + :event_type => event.event_type, + :request_url => main_url(request_url(request)), + :request_email => request.incoming_email, + :title => request.title, + :body => event.outgoing_message.body, + + :user_name => request.user_name, + } + if request.user + this_event[:user_url] = main_url(user_url(request.user)) + end + + @event_data.push(this_event) + end + render :json => @event_data + else + raise ActiveRecord::RecordNotFound.new("Unrecognised feed type: #{feed_type}") + end + end + protected def check_api_key raise "Missing required parameter 'k'" if params[:k].nil? diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 41adf1848..11f21025c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -27,6 +27,7 @@ class ApplicationController < ActionController::Base before_filter :check_in_post_redirect before_filter :session_remember_me before_filter :set_vary_header + before_filter :set_popup_banner # scrub sensitive parameters from the logs filter_parameter_logging :password @@ -553,6 +554,9 @@ class ApplicationController < ActionController::Base return country end + def set_popup_banner + @popup_banner = render_to_string(:partial => "general/popup_banner").strip + end # URL generating functions are needed by all controllers (for redirects), # views (for links) and mailers (for use in emails), so include them into # all of all. diff --git a/app/models/censor_rule.rb b/app/models/censor_rule.rb index a477d2568..cedbd767e 100644 --- a/app/models/censor_rule.rb +++ b/app/models/censor_rule.rb @@ -9,6 +9,7 @@ # public_body_id :integer # text :text not null # replacement :text not null +# regexp :boolean # last_edit_editor :string(255) not null # last_edit_comment :text not null # created_at :datetime not null @@ -28,6 +29,8 @@ class CensorRule < ActiveRecord::Base belongs_to :user belongs_to :public_body + named_scope :regexps, {:conditions => {:regexp => true}} + def binary_replacement self.text.gsub(/./, 'x') end @@ -36,8 +39,10 @@ class CensorRule < ActiveRecord::Base if text.nil? return nil end - text.gsub!(self.text, self.replacement) + to_replace = regexp? ? Regexp.new(self.text, Regexp::MULTILINE) : self.text + text.gsub!(to_replace, self.replacement) end + def apply_to_binary!(binary) if binary.nil? return nil @@ -45,9 +50,8 @@ class CensorRule < ActiveRecord::Base binary.gsub!(self.text, self.binary_replacement) end - def validate - if self.info_request.nil? && self.user.nil? && self.public_body.nil? + if !self.regexp? && self.info_request.nil? && self.user.nil? && self.public_body.nil? errors.add("Censor must apply to an info request a user or a body; ") end end diff --git a/app/models/incoming_message.rb b/app/models/incoming_message.rb index 593590fb8..13fc316cd 100644 --- a/app/models/incoming_message.rb +++ b/app/models/incoming_message.rb @@ -375,25 +375,10 @@ class IncomingMessage < ActiveRecord::Base # http://www.whatdotheyknow.com/request/common_purpose_training_graduate#incoming-774 text.gsub!(/(Mobile|Mob)([\s\/]*(Fax|Tel))*\s*:?[\s\d]*\d/, "[mobile number]") - # Specific removals # XXX remove these and turn them into censor rules in database - # http://www.whatdotheyknow.com/request/total_number_of_objects_in_the_n_6 - text.gsub!(/\*\*\*+\nPolly Tucker.*/ms, "") - # http://www.whatdotheyknow.com/request/cctv_data_retention_and_use - text.gsub!(/Andy 079.*/, "Andy [mobile number]") - # http://www.whatdotheyknow.com/request/how_do_the_pct_deal_with_retirin_113 - text.gsub!(/(Complaints and Corporate Affairs Officer)\s+Westminster Primary Care Trust.+/ms, "\\1") - # Remove WhatDoTheyKnow signup links domain = MySociety::Config.get('DOMAIN') text.gsub!(/http:\/\/#{domain}\/c\/[^\s]+/, "[WDTK login link]") - # Remove Home Office survey links - # e.g. http://www.whatdotheyknow.com/request/serious_crime_act_2007_section_7#incoming-12650 - if self.info_request.public_body.url_name == 'home_office' - text.gsub!(/Your password:-\s+[^\s]+/, '[password]') - text.gsub!(/Password=[^\s]+/, '[password]') - end - # Remove things from censor rules self.info_request.apply_censor_rules_to_text!(text) end @@ -599,7 +584,6 @@ class IncomingMessage < ActiveRecord::Base # Remove existing quoted sections folded_quoted_text = self.remove_lotus_quoting(text, 'FOLDED_QUOTED_SECTION') folded_quoted_text = IncomingMessage.remove_quoted_sections(text, "FOLDED_QUOTED_SECTION") - self.cached_main_body_text_unfolded = text self.cached_main_body_text_folded = folded_quoted_text self.save! diff --git a/app/models/info_request.rb b/app/models/info_request.rb index d09acbcf6..4c8181faa 100644 --- a/app/models/info_request.rb +++ b/app/models/info_request.rb @@ -1,11 +1,10 @@ # == Schema Information -# Schema version: 114 # # Table name: info_requests # # id :integer not null, primary key # title :text not null -# user_id :integer not null +# user_id :integer # public_body_id :integer not null # created_at :datetime not null # updated_at :datetime not null @@ -17,10 +16,11 @@ # allow_new_responses_from :string(255) default("anybody"), not null # handle_rejected_responses :string(255) default("bounce"), not null # idhash :string(255) not null +# external_user_name :string(255) +# external_url :string(255) # attention_requested :boolean default(FALSE) # - require 'digest/sha1' class InfoRequest < ActiveRecord::Base @@ -136,7 +136,7 @@ class InfoRequest < ActiveRecord::Base else fake_slug = external_user_name.parameterize end - public_body.url_name + "_"+fake_slug + (public_body.url_name || "") + "_" + fake_slug else user.url_name end @@ -997,14 +997,11 @@ public # Call groups of censor rules def apply_censor_rules_to_text!(text) - for censor_rule in self.censor_rules - censor_rule.apply_to_text!(text) - end - if self.user # requests during construction have no user - for censor_rule in self.user.censor_rules + [self.censor_rules, self.user.try(:censor_rules), + CensorRule.regexps.all].flatten.compact.each do |censor_rule| censor_rule.apply_to_text!(text) end - end + return text end def apply_censor_rules_to_binary!(binary) diff --git a/app/models/public_body.rb b/app/models/public_body.rb index bc8f084bb..9efeadf55 100644 --- a/app/models/public_body.rb +++ b/app/models/public_body.rb @@ -1,5 +1,4 @@ # == Schema Information -# Schema version: 114 # # Table name: public_bodies # @@ -19,7 +18,6 @@ # publication_scheme :text default(""), not null # api_key :string(255) not null # - # models/public_body.rb: # A public body, from which information can be requested. # @@ -583,5 +581,3 @@ class PublicBody < ActiveRecord::Base end end - - diff --git a/app/models/user.rb b/app/models/user.rb index a21676f68..657ea2a4a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,4 @@ # == Schema Information -# Schema version: 114 # # Table name: users # @@ -21,9 +20,7 @@ # email_bounce_message :text default(""), not null # no_limit :boolean default(FALSE), not null # receive_email_alerts :boolean default(TRUE), not null -# user_similarity_id :integer # - # models/user.rb: # Model of people who use the site to file requests, make comments etc. # diff --git a/app/views/admin_censor_rule/_form.rhtml b/app/views/admin_censor_rule/_form.rhtml index d077afd9a..d8a8f05d7 100644 --- a/app/views/admin_censor_rule/_form.rhtml +++ b/app/views/admin_censor_rule/_form.rhtml @@ -11,6 +11,9 @@ <% end %> </p> +<p><label for="censor_rule_regexp">Is it regexp replacement?</label> (Leave unchecked if you are not sure about this)<br/> +<%= check_box 'censor_rule', 'regexp' %></p> + <p><label for="censor_rule_text">Text</label> (that you want to remove, case sensitive)<br/> <%= text_field 'censor_rule', 'text', :size => 60 %></p> @@ -21,9 +24,9 @@ <%= text_area 'censor_rule', 'last_edit_comment', :rows => 2, :cols => 60 %></p> <p><strong>Warning and notes:</strong> This does replace text in binary files, but for -most formats only in a naive way. It works well on surprisingly many Word documents. Notably -it doesn't even do UCS-2 (unicode sometimes used in Word). There is also special code -which works on some PDFs. Please <strong>carefully check</strong> all attachments have +most formats only in a naive way. It works well on surprisingly many Word documents. Notably +it doesn't even do UCS-2 (unicode sometimes used in Word). There is also special code +which works on some PDFs. Please <strong>carefully check</strong> all attachments have changed in the way you expect, and haven't become corrupted. </p> diff --git a/app/views/api/request_events.atom.builder b/app/views/api/request_events.atom.builder new file mode 100644 index 000000000..4f0133051 --- /dev/null +++ b/app/views/api/request_events.atom.builder @@ -0,0 +1,25 @@ +atom_feed("xmlns:alaveteli" => "http://www.alaveteli.org/API/v2/RequestEvents/Atom") do |feed| + feed.title("Events relating to #{@public_body.name}") + feed.updated(@events.first.created_at) + + for event in @events + feed.entry(event) do |entry| + request = event.info_request + + entry.published(event.created_at) + entry.tag!("alaveteli:event_type", event.event_type) + entry.tag!("alaveteli:request_url", main_url(request_url(request))) + entry.title(request.title) + + entry.content(event.outgoing_message.body, :type => 'text') + + entry.author do |author| + author.name(request.user_name) + if !request.user.nil? + author.uri(main_url(user_url(request.user))) + end + author.email(request.incoming_email) + end + end + end +end diff --git a/app/views/general/_popup_banner.rhtml b/app/views/general/_popup_banner.rhtml new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/app/views/general/_popup_banner.rhtml @@ -0,0 +1 @@ + diff --git a/app/views/general/_stylesheet_includes.rhtml b/app/views/general/_stylesheet_includes.rhtml new file mode 100644 index 000000000..2ffa5dadf --- /dev/null +++ b/app/views/general/_stylesheet_includes.rhtml @@ -0,0 +1,21 @@ + <%= stylesheet_link_tag 'main', :title => "Main", :rel => "stylesheet", :media => "all" %> + <%= stylesheet_link_tag 'fonts', :rel => "stylesheet", :media => "all" %> + <%= stylesheet_link_tag 'print', :rel => "stylesheet", :media => "print" %> + <% if !params[:print_stylesheet].nil? %> + <%= stylesheet_link_tag 'print', :rel => "stylesheet", :media => "all" %> + <% end %> + <%= stylesheet_link_tag 'admin-theme/jquery-ui-1.8.15.custom.css', :rel => 'stylesheet'%> + <!--[if LT IE 7]> + <style type="text/css">@import url("/stylesheets/ie6.css");</style> + <![endif]--> + <!--[if LT IE 7]> + <style type="text/css">@import url("/stylesheets/ie6-custom.css");</style> + <![endif]--> + <!--[if LT IE 8]> + <style type="text/css">@import url("/stylesheets/ie7.css");</style> + <![endif]--> + <!-- the following method for customising CSS is deprecated; see `doc/THEMES.md` for detail --> + <%= stylesheet_link_tag 'custom', :title => "Main", :rel => "stylesheet" %> + <% if force_registration_on_new_request %> + <%= stylesheet_link_tag 'jquery.fancybox-1.3.4', :rel => "stylesheet" %> + <% end %> diff --git a/app/views/layouts/default.rhtml b/app/views/layouts/default.rhtml index 5c3499c93..876cf07c4 100644 --- a/app/views/layouts/default.rhtml +++ b/app/views/layouts/default.rhtml @@ -1,87 +1,65 @@ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="<%= I18n.locale %>"> <head> - <title> - <% if @title %> - <%=@title%> - <%= site_name %> - <% else %> - <%= site_name %> - <%= _('Make and browse Freedom of Information (FOI) requests') %> - <% end %> - </title> - - <link rel="shortcut icon" href="/favicon.ico"> - <%= stylesheet_link_tag 'main', :title => "Main", :rel => "stylesheet", :media => "all" %> - <%= stylesheet_link_tag 'fonts', :rel => "stylesheet", :media => "all" %> - <%= stylesheet_link_tag 'print', :rel => "stylesheet", :media => "print" %> - <% if !params[:print_stylesheet].nil? %> - <%= stylesheet_link_tag 'print', :rel => "stylesheet", :media => "all" %> - <% end %> + <title> + <% if @title %> + <%=@title%> - <%= site_name %> + <% else %> + <%= site_name %> - <%= _('Make and browse Freedom of Information (FOI) requests') %> + <% end %> + </title> + + <link rel="shortcut icon" href="/favicon.ico"> + <%= render :partial => 'general/stylesheet_includes' %> <% if is_admin? %> - <%= stylesheet_link_tag "/adminbootstraptheme/stylesheets/admin", :title => "Main", :rel => "stylesheet" %> + <%= stylesheet_link_tag "/adminbootstraptheme/stylesheets/admin", :title => "Main", :rel => "stylesheet" %> + <% end %> + + <%= javascript_include_tag 'jquery.js', 'jquery-ui.min','jquery.cookie.js', 'general.js' %> + <% if @profile_photo_javascript %> + <script type="text/javascript" src="/javascripts/jquery.Jcrop.js"></script> + <script type="text/javascript" src="/javascripts/profile_photo.js"></script> + <link rel="stylesheet" href="/stylesheets/jquery.Jcrop.css" type="text/css" > + <% end %> + + <% if @feed_autodetect %> + <% for feed in @feed_autodetect %> + <link rel="alternate" type="application/atom+xml" title="<%=h feed[:title] %>" href="<%=h feed[:url]%>"> + <% if feed[:has_json] %> + <link rel="alternate" type="application/json" title="JSON version of <%=h feed[:title] %>" href="<%=h feed[:url]%>.json"> + <% end %> + <% end %> + <% end %> + <% if @has_json %> + <link rel="alternate" type="application/json" title="JSON version of this page" href="<%=h main_url(request.request_uri, '.json') %>"> <% end %> - <%= javascript_include_tag 'jquery.js', 'jquery-ui.min','jquery.cookie.js', 'general.js' %> - - <% if @profile_photo_javascript %> - <script type="text/javascript" src="/javascripts/jquery.Jcrop.js"></script> - <script type="text/javascript" src="/javascripts/profile_photo.js"></script> - <link rel="stylesheet" href="/stylesheets/jquery.Jcrop.css" type="text/css" > - <% end %> - - <%= stylesheet_link_tag 'admin-theme/jquery-ui-1.8.15.custom.css', :rel => 'stylesheet'%> - <!--[if LT IE 7]> - <style type="text/css">@import url("/stylesheets/ie6.css");</style> - <![endif]--> - <!--[if LT IE 7]> - <style type="text/css">@import url("/stylesheets/ie6-custom.css");</style> - <![endif]--> - <!--[if LT IE 8]> - <style type="text/css">@import url("/stylesheets/ie7.css");</style> - <![endif]--> - <!-- the following method for customising CSS is deprecated; see `doc/THEMES.md` for detail --> - <%= stylesheet_link_tag 'custom', :title => "Main", :rel => "stylesheet" %> - <% if force_registration_on_new_request %> - <%= stylesheet_link_tag 'jquery.fancybox-1.3.4', :rel => "stylesheet" %> - <% end %> - - <% if @feed_autodetect %> - <% for feed in @feed_autodetect %> - <link rel="alternate" type="application/atom+xml" title="<%=h feed[:title] %>" href="<%=h feed[:url]%>"> - <% if feed[:has_json] %> - <link rel="alternate" type="application/json" title="JSON version of <%=h feed[:title] %>" href="<%=h feed[:url]%>.json"> - <% end %> - <% end %> - <% end %> - <% if @has_json %> - <link rel="alternate" type="application/json" title="JSON version of this page" href="<%=h main_url(request.request_uri, '.json') %>"> - <% end %> - - <% if @no_crawl %> - <meta name="robots" content="noindex, nofollow"> - <% end %> - - <%= render :partial => 'general/before_head_end' %> + + <% if @no_crawl %> + <meta name="robots" content="noindex, nofollow"> + <% end %> + + <%= render :partial => 'general/before_head_end' %> </head> <body class="<%= 'admin' if is_admin? %> <%= 'front' if params[:action] == 'frontpage' %>"> - <!-- XXX: move to a separate file --> <% if force_registration_on_new_request && !@user %> <%= javascript_include_tag 'jquery.fancybox-1.3.4.pack' %> <script type="text/javascript"> - $(document).ready(function() { - $("#make-request-link").fancybox({ - 'modal': false, - 'width': 920, - 'height': 400, - 'type': 'iframe', - 'href': '/<%= I18n.locale %>/profile/sign_in?modal=1', - 'onClosed': function() { - // modal_signin_successful variable set by modal dialog box - if (typeof modal_signin_successful != 'undefined' ) { - window.location.href = '<%= select_authority_url %>'; - } - } - }); - }); + $(document).ready(function() { + $("#make-request-link").fancybox({ + 'modal': false, + 'width': 920, + 'height': 400, + 'type': 'iframe', + 'href': '/<%= I18n.locale %>/profile/sign_in?modal=1', + 'onClosed': function() { + // modal_signin_successful variable set by modal dialog box + if (typeof modal_signin_successful != 'undefined' ) { + window.location.href = '<%= select_authority_url %>'; + } + } + }); + }); </script> <% end %> @@ -89,67 +67,66 @@ <%= render :partial => 'admin_general/admin_navbar' %> <% end %> -<% # code for popup advert for a campaign etc. -=begin - <div id="everypage" class="jshide"> - <p style="float:right"><a href="#top" onclick="$.cookie('seen_foi2', 1, { expires: 7, path: '/' }); $('#everypage').hide('slow'); return false;">Close</a></p> - [ message goes here ] - <p style="text-align: right"><a href="#top" onclick="$.cookie('seen_foi2', 1, { expires: 7, path: '/' }); $('#everypage').hide('slow'); return false;">Close</a></p> - </div> -=end -%> +<% if !@popup_banner.blank? %> +<div id="everypage" class="jshide"> + <p style="float:right"><a href="#top" onclick="$.cookie('seen_foi2', 1, { expires: 7, path: '/' }); $('#everypage').hide('slow'); return false;"><%= _('Close') %></a></p> + <%= @popup_banner %> + <p style="text-align: right"><a href="#top" onclick="$.cookie('seen_foi2', 1, { expires: 7, path: '/' }); $('#everypage').hide('slow'); return false;"><%= _('Close') %></a></p> +</div> +<% end %> + <div class="entirebody"> <div id="banner"> <div id="banner_inner"> - <div class="lang"><%= render :partial => 'general/locale_switcher' %></div> - - <% if not (controller.action_name == 'signin' or controller.action_name == 'signup') %> - <div id="logged_in_bar"> - <% if @user %> - <%= _('Hello, {{username}}!', :username => h(@user.name))%> - - <% if @user %> - <%=link_to _("My requests"), show_user_requests_path(:url_name => @user.url_name) %> - <%=link_to _("My profile"), show_user_profile_path(:url_name => @user.url_name) %> - <%=link_to _("My wall"), show_user_wall_path(:url_name => @user.url_name) %> - <% end %> - - - <%= link_to _("Sign out"), signout_url(:r => request.request_uri) %> - <% else %> - <%= link_to _("Sign in or sign up"), signin_url(:r => request.request_uri) %> - <% end %> - </div> - <% end %> - - <div id="navigation_search"> - <% form_tag({:controller => "general", :action => "search_redirect"}, {:id => "navigation_search_form"}) do %> - <p> - <%= text_field_tag 'query', params[:query], { :size => 40, :id => "navigation_search_query" } %> - <%= image_submit_tag('search-button.png') %> - </p> - <% end %> - </div> - - <%= render :partial => 'general/orglink' %> - - <%= render :partial => 'general/topnav' %> + <div class="lang"><%= render :partial => 'general/locale_switcher' %></div> + + <% if not (controller.action_name == 'signin' or controller.action_name == 'signup') %> + <div id="logged_in_bar"> + <% if @user %> + <%= _('Hello, {{username}}!', :username => h(@user.name))%> + + <% if @user %> + <%=link_to _("My requests"), show_user_requests_path(:url_name => @user.url_name) %> + <%=link_to _("My profile"), show_user_profile_path(:url_name => @user.url_name) %> + <%=link_to _("My wall"), show_user_wall_path(:url_name => @user.url_name) %> + <% end %> + + + <%= link_to _("Sign out"), signout_url(:r => request.request_uri) %> + <% else %> + <%= link_to _("Sign in or sign up"), signin_url(:r => request.request_uri) %> + <% end %> + </div> + <% end %> + + <div id="navigation_search"> + <% form_tag({:controller => "general", :action => "search_redirect"}, {:id => "navigation_search_form"}) do %> + <p> + <%= text_field_tag 'query', params[:query], { :size => 40, :id => "navigation_search_query" } %> + <%= submit_tag 'search', :id => "navigation_search_button" %> + </p> + <% end %> + </div> + + <%= render :partial => 'general/orglink' %> + + <%= render :partial => 'general/topnav' %> </div> </div> <div id="wrapper"> - <div id="content"> - <% if flash[:notice] %> - <div id="notice"><%= flash[:notice] %></div> - <% end %> - <% if flash[:error] %> - <div id="error"><%= flash[:error] %></div> - <% end %> - - <div id="<%= controller.controller_name + "_" + controller.action_name %>" class="controller_<%= controller.controller_name %>"> - <%= yield :layout %> - </div> - <div style="clear:both"></div> - </div> + <div id="content"> + <% if flash[:notice] %> + <div id="notice"><%= flash[:notice] %></div> + <% end %> + <% if flash[:error] %> + <div id="error"><%= flash[:error] %></div> + <% end %> + + <div id="<%= controller.controller_name + "_" + controller.action_name %>" class="controller_<%= controller.controller_name %>"> + <%= yield :layout %> + </div> + <div style="clear:both"></div> + </div> </div> <%= render :partial => 'general/footer' %> @@ -163,20 +140,19 @@ </div> <% ga_code = MySociety::Config.get('GA_CODE', '') - + unless ga_code.empty? %> - <script> - var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); - document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); - </script> - <script> - var pageTracker = _gat._getTracker("<%=ga_code%>"); - pageTracker._trackPageview(); - </script> - + <script> + var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); + document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); + </script> + <script> + var pageTracker = _gat._getTracker("<%=ga_code%>"); + pageTracker._trackPageview(); + </script> + <% end %> <%= render :partial => 'general/before_body_end' %> </body> </html> - diff --git a/app/views/request/show_response.rhtml b/app/views/request/show_response.rhtml index d8647d1ec..c40b37c3b 100644 --- a/app/views/request/show_response.rhtml +++ b/app/views/request/show_response.rhtml @@ -1,9 +1,9 @@ <% if @incoming_message.nil? %> - <% @title = "Send follow up to '" + h(@info_request.title) + "'" %> + <% @title = _("Send follow up to '{{title}}'", :title => h(@info_request.title)) %> <% elsif @incoming_message.recently_arrived %> - <% @title = "New response to '" + h(@info_request.title) + "'" %> + <% @title = _("New response to '{{title}}'", :title => h(@info_request.title)) %> <% else %> - <% @title = "Response to '" + h(@info_request.title) + "'" %> + <% @title = _("Response to '{{title}}'", :title => h(@info_request.title)) %> <% end %> <%= foi_error_messages_for :incoming_message, :outgoing_message %> @@ -34,11 +34,11 @@ <%= _('You want to <strong>give your postal address</strong> to the authority in private.') %> </dt> <dd> - <%= _('To do that please send a private email to ') %><%=h(@postal_email_name)%> + <%= _('To do that please send a private email to ') %><%=h(@postal_email_name)%> <<%=link_to h(@postal_email), "mailto:" + @postal_email%>> <%= _('containing your postal address, and asking them to reply to this request. Or you could phone them.') %> - + <%= _('When you receive the paper response, please help others find out what it says:') %> <ul> @@ -68,7 +68,7 @@ <h2>Response to <%=h(@info_request.law_used_short)%> request '<%= request_link @info_request %>'</h2> <% end %> <% end %> - + <% if @incoming_message.nil? %> <%= render :partial => 'correspondence', :locals => { :info_request_event => @info_request.get_last_outgoing_event, :incoming_message => nil } %> <% else %> diff --git a/app/views/user/_show_user_info.rhtml b/app/views/user/_show_user_info.rhtml new file mode 100644 index 000000000..5dfecee1e --- /dev/null +++ b/app/views/user/_show_user_info.rhtml @@ -0,0 +1,20 @@ + + <% if !@display_user.get_about_me_for_html_display.empty? || @is_you %> + <div class="user_about_me"> + <img class="comment_quote" src="/images/quote.png" alt=""> + <%= @display_user.get_about_me_for_html_display %> + <% if @is_you %> + (<%= link_to _("edit text about you"), set_profile_about_me_url() %>) + <% end %> + </div> + <% end %> + + <% if @is_you %> + <p id="user_change_password_email"> + <% if @display_user.profile_photo %> + <%= link_to _('Change profile photo'), set_profile_photo_url() %> | + <% end %> + <%= link_to _('Change your password'), signchangepassword_url() %> | + <%= link_to _('Change your email'), signchangeemail_url() %> + </p> + <% end %> diff --git a/app/views/user/contact.rhtml b/app/views/user/contact.rhtml index 4bbb15789..3329ba6ca 100644 --- a/app/views/user/contact.rhtml +++ b/app/views/user/contact.rhtml @@ -9,39 +9,37 @@ <% form_for :contact do |f| %> <div class="form_note"> - <h1>Contact <%=h @recipient_user.name%></h1> + <h1><%= _("Contact {{recipient}}", :recipient => h(@recipient_user.name)) %></h1> </div> <p> - <label class="form_label">From:</label> - <%= h(@user.name_and_email) %> + <label class="form_label"><%= _("From") %>:</label> + <%= h(@user.name_and_email) %> </p> <p> - <label class="form_label" for="contact_subject">Subject:</label> - <%= f.text_field :subject, :size => 50 %> + <label class="form_label" for="contact_subject"><%= _("Subject") %>:</label> + <%= f.text_field :subject, :size => 50 %> </p> <p> - <label class="form_label" for="contact_message">Message:</label> - <%= f.text_area :message, :rows => 10, :cols => 50 %> + <label class="form_label" for="contact_message"><%= _("Message") %>:</label> + <%= f.text_area :message, :rows => 10, :cols => 50 %> </p> <p class="form_note"> - <% if @user == @recipient_user %> - <%= _('<strong>Note:</strong> You\'re sending a message to yourself, presumably - to try out how it works.')%> - <% else %> - <%= _(' <strong>Privacy note:</strong> Your email address will be given to')%> - <%= user_link(@recipient_user) %><%= _(' when you send this message.')%> - <% end %> + <% if @user == @recipient_user %> + <%= _('<strong>Note:</strong> You\'re sending a message to yourself, presumably + to try out how it works.')%> + <% else %> + <%= _(' <strong>Privacy note:</strong> Your email address will be given to')%> + <%= user_link(@recipient_user) %><%= _(' when you send this message.')%> + <% end %> </p> <div class="form_button"> - <%= hidden_field_tag(:submitted_contact_form, { :value => 1 } ) %> - <%= submit_tag "Send message" %> + <%= hidden_field_tag(:submitted_contact_form, { :value => 1 } ) %> + <%= submit_tag _("Send message") %> </div> <% end %> - - diff --git a/app/views/user/set_crop_profile_photo.rhtml b/app/views/user/set_crop_profile_photo.rhtml index db18d10a1..eed0304d2 100644 --- a/app/views/user/set_crop_profile_photo.rhtml +++ b/app/views/user/set_crop_profile_photo.rhtml @@ -20,7 +20,7 @@ <div style="width:96px;height:96px;overflow:hidden;"> <img src="<%= get_draft_profile_photo_url(:id => @draft_profile_photo.id) %>" id="profile_photo_preview" /> </div> - + </td> </tr> </table> @@ -32,12 +32,12 @@ <%= hidden_field_tag 'draft_profile_photo_id', @draft_profile_photo.id %> - <p><%= _('<strong>Privacy note:</strong> Your photo will be shown in public on the Internet, + <p><%= _('<strong>Privacy note:</strong> Your photo will be shown in public on the Internet, wherever you do something on {{site_name}}.', :site_name=>site_name)%> <p> <%= hidden_field_tag 'submitted_crop_profile_photo', 1 %> - <%= submit_tag "Done >>" %> + <%= submit_tag _("Done") + " >>" %> </p> <% end %> diff --git a/app/views/user/set_draft_profile_photo.rhtml b/app/views/user/set_draft_profile_photo.rhtml index 90be49600..b3faba7fc 100644 --- a/app/views/user/set_draft_profile_photo.rhtml +++ b/app/views/user/set_draft_profile_photo.rhtml @@ -10,12 +10,12 @@ <% form_tag 'set_photo', :id => 'set_draft_profile_photo_form', :multipart => true do %> <p> - <label class="form_label" for="file_1"><%= _('Photo of you:')%></label> + <label class="form_label" for="file_1"><%= _('Photo of you:')%></label> <%= file_field_tag :file, :size => 35, :id => 'file_1' %> </p> <ul> - <li><%= _('Your photo will be shown in public <strong>on the Internet</strong>, + <li><%= _('Your photo will be shown in public <strong>on the Internet</strong>, wherever you do something on {{site_name}}.', :site_name=>site_name)%> </li> @@ -36,7 +36,7 @@ <noscript> <div> <%= hidden_field_tag 'automatically_crop', 1 %> - <%= submit_tag "Done >>" %> + <%= submit_tag _("Done >>") %> </div> </noscript> <% end %> @@ -46,7 +46,7 @@ <h2><%= _('OR remove the existing photo')%></h2> <% form_tag 'clear_photo', :id => 'clear_profile_photo_form', :multipart => true do %> - <%= submit_tag "Clear photo" %> + <%= submit_tag _("Clear photo") %> <% end %> <% end %> diff --git a/app/views/user/show.rhtml b/app/views/user/show.rhtml index d723196d3..12a9d3f74 100644 --- a/app/views/user/show.rhtml +++ b/app/views/user/show.rhtml @@ -1,14 +1,14 @@ <% if @show_requests %> - <% @title = h(@display_user.name) + _(" - Freedom of Information requests") %> + <% @title = _("{{user_name}} - Freedom of Information requests", :user_name => h(@display_user.name)) %> <% else %> - <% @title = h(@display_user.name) + _(" - user profile") %> + <% @title = _("{{user_name}} - user profile", :user_name => h(@display_user.name)) %> <% end %> <% if (@same_name_users.size >= 1) %> - <p><%= _('There is <strong>more than one person</strong> who uses this site and has this name. + <p><%= _('There is <strong>more than one person</strong> who uses this site and has this name. One of them is shown below, you may mean a different one:')%> <% for @same_name_user in @same_name_users %> <%= user_link(@same_name_user) %> - <% end %> + <% end %> <% end%> <% if @show_profile && @is_you && @undescribed_requests.size > 0 %> @@ -40,11 +40,11 @@ <a href="#foi_requests"><%= _('FOI requests')%></a> <br><a href="#annotations"><%= _('Annotations')%></a> <% end %> - </div> + </div> <div class="header_left"> <p id="user_photo_on_profile"> - <% if @display_user.profile_photo %> + <% if @display_user.profile_photo %> <% if @is_you %> <a href="<%= set_profile_photo_url() %>"> <% end %> @@ -93,25 +93,7 @@ </div> <% end %> - <% if !@display_user.get_about_me_for_html_display.empty? || @is_you %> - <div class="user_about_me"> - <img class="comment_quote" src="/images/quote.png" alt=""> - <%= @display_user.get_about_me_for_html_display %> - <% if @is_you %> - (<%= link_to _("edit text about you"), set_profile_about_me_url() %>) - <% end %> - </div> - <% end %> - - <% if @is_you %> - <p id="user_change_password_email"> - <% if @display_user.profile_photo %> - <%= link_to _('Change profile photo'), set_profile_photo_url() %> | - <% end %> - <%= link_to _('Change your password'), signchangepassword_url() %> | - <%= link_to _('Change your email'), signchangeemail_url() %> - </p> - <% end %> + <%= render :partial => 'user/show_user_info' %> <% if not @is_you %> <p id="user_not_logged_in"> @@ -127,7 +109,7 @@ <div id="user_profile_search"> <% form_tag(show_user_url, :method => "get", :id=>"search_form") do %> <div> - <%= text_field_tag(:user_query, params[:user_query]) %> + <%= text_field_tag(:user_query, params[:user_query]) %> <% if @is_you %> <%= submit_tag(_("Search your contributions")) %> <% else %> @@ -146,7 +128,7 @@ <% end %> <% else %> <h2 class="foi_results" id="foi_requests"> - <%= @is_you ? n_('Your %d Freedom of Information request', 'Your %d Freedom of Information requests', @xapian_requests.matches_estimated.to_s) % @xapian_requests.matches_estimated.to_s : n_('This person\'s %d Freedom of Information request', 'This person\'s %d Freedom of Information requests', @xapian_requests.matches_estimated.to_s) % @xapian_requests.matches_estimated %> + <%= @is_you ? n_('Your %d Freedom of Information request', 'Your %d Freedom of Information requests', @xapian_requests.matches_estimated) % @xapian_requests.matches_estimated.to_s : n_('This person\'s %d Freedom of Information request', 'This person\'s %d Freedom of Information requests', @xapian_requests.matches_estimated) % @xapian_requests.matches_estimated %> <!-- matches_estimated <%=@xapian_requests.matches_estimated%> --> <%= @match_phrase %> <%= @page_desc %> @@ -159,12 +141,12 @@ <%= will_paginate WillPaginate::Collection.new(@page, @per_page, @display_user.info_requests.size) %> <% end %> - <% else %> + <% else %> <% if @show_requests %> <h2 class="foi_results" id="foi_requests"><%= @is_you ? _('Freedom of Information requests made by you') : _('Freedom of Information requests made by this person') %> </h2> <p><%= _('The search index is currently offline, so we can\'t show the Freedom of Information requests this person has made.')%></p> <% end %> - <% end %> + <% end %> <% if !@xapian_comments.nil? %> <% if @xapian_comments.results.empty? %> @@ -221,7 +203,7 @@ <%= hidden_field_tag 'r', request.request_uri %> <% if track_things.size > 1 %> <%= submit_tag _('unsubscribe all')%> - <% end %> + <% end %> </h3> <% end %> <% end %> @@ -231,7 +213,7 @@ <li> <% form_tag({:controller => 'track', :action => 'update', :track_id => track_thing.id}, :class => "feed_form") do %> <div> - <%= track_thing.params[:list_description] %> + <%= track_thing.params[:list_description] %> <%= hidden_field_tag 'track_medium', "delete", { :id => 'track_medium_' + track_thing.id.to_s } %> <%= hidden_field_tag 'r', request.request_uri, { :id => 'r_' + track_thing.id.to_s } %> <%= submit_tag _('unsubscribe') %> diff --git a/config/packages b/config/packages index dcf1dc5b4..d059d2906 100644 --- a/config/packages +++ b/config/packages @@ -33,5 +33,6 @@ libpq-dev uuid-dev ruby1.8-dev rubygems +rake build-essential bundler diff --git a/config/routes.rb b/config/routes.rb index 13ab6669e..a9c2c889a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -244,8 +244,10 @@ ActionController::Routing::Routes.draw do |map| map.with_options :controller => 'api' do |api| api.api_create_request '/api/v2/request.json', :action => 'create_request', :conditions => { :method => :post } - api.api_show_request '/api/v2/request/:id.json', :action => 'show_request', :conditions => { :method => :get } - api.api_add_correspondence '/api/v2/request/:id.json', :action => 'add_correspondence', :conditions => { :method => :post } + api.api_show_request '/api/v2/request/:id.json', :action => 'show_request', :conditions => { :method => :get } + api.api_add_correspondence '/api/v2/request/:id.json', :action => 'add_correspondence', :conditions => { :method => :post } + + api.api_body_request_events '/api/v2/body/:id/request_events.:feed_type', :action => 'body_request_events', :feed_type => '^(json|atom)$' end map.filter('conditionallyprependlocale') diff --git a/db/migrate/116_add_censor_rule_regexp.rb b/db/migrate/116_add_censor_rule_regexp.rb new file mode 100644 index 000000000..d9c4664cd --- /dev/null +++ b/db/migrate/116_add_censor_rule_regexp.rb @@ -0,0 +1,9 @@ +class AddCensorRuleRegexp < ActiveRecord::Migration + def self.up + add_column :censor_rules, :regexp, :boolean + end + + def self.down + remove_column :censor_rules, :regexp + end +end diff --git a/doc/INSTALL.md b/doc/INSTALL.md index 325ccfbdd..b71b89676 100644 --- a/doc/INSTALL.md +++ b/doc/INSTALL.md @@ -318,6 +318,9 @@ like `!!(*= $this *)!!`. The variables are: * `user`: the user that the software runs as * `site`: a string to identify your alaveteli instance +There is a dumb python script at `script/make-crontab` which you can +edit and run to do some basic substitution for you. + One of the cron jobs refers to a script at `/etc/init.d/foi-alert-tracks`. This is an init script, a copy of which lives in `config/alert-tracks-debian.ugly`. As with the cron diff --git a/doc/THEMES.md b/doc/THEMES.md index 50335c082..e33371df7 100644 --- a/doc/THEMES.md +++ b/doc/THEMES.md @@ -36,13 +36,17 @@ places: This document is about what you can do in a theme. -To get started, install the sample theme by running +By default, the sample theme ("alavetelitheme") has already been +installed. See the setting `THEME_URLS` in `general.yml` for an +explanation. + +You can also install the sample theme by hand, by running: ./script/plugin install git://github.com/sebbacon/alavetelitheme.git -This downloads and installs the theme in -`vendor/plugins/alavetelitheme` and contains examples for nearly -everything you might want to customise. +The sample theme contains examples for nearly everything you might +want to customise. You should probably make a copy, rename it, and +use that as the basis for your own theme. # Make sure your theme is as lightweight as possible @@ -81,7 +85,7 @@ instead of the core "about us" file. Rails expects all its stylesheets to live at `<railshome>/public`, which presents a problem for plugins. Here's how we solve it: the stylesheet and associated resources for your theme live (by -convention) in at `alavetelitheme/public/`. This is symlinked from +convention) in `alavetelitheme/public/`. This is symlinked from the main Rails app -- see `alavetelitheme/install.rb` to see how this happens. diff --git a/public/javascripts/general.js b/public/javascripts/general.js index ab74cf318..9ae10593c 100644 --- a/public/javascripts/general.js +++ b/public/javascripts/general.js @@ -12,7 +12,7 @@ $(document).ready(function() { } } }) - + } } @@ -33,7 +33,7 @@ $(document).ready(function() { at: "left bottom", of: this, collision: "fit" }); - + }); $('.close-button').click(function() { $(this).parent().hide() }); $('div#variety-filter a').each(function() { @@ -44,4 +44,9 @@ $(document).ready(function() { return false; }) }) -})
\ No newline at end of file + + if($.cookie('seen_foi2') == 1) { + $('#everypage').hide(); + } + +}) diff --git a/public/stylesheets/main.css b/public/stylesheets/main.css index 31a8ba63c..decce951d 100644 --- a/public/stylesheets/main.css +++ b/public/stylesheets/main.css @@ -40,11 +40,24 @@ border-style:solid; border-width:1px; } +#navigation_search input#navigation_search_button { +background: url(/images/search-button.png) no-repeat center center; +width: 27px; +height: 26px; +color: transparent; +font-size: 0; +margin: 0; +padding: 0; +position: relative; +top: -4px; +left: -5px; +} + #navigation_search input#navigation_search_query { width:20.25em; font-size: 0.8em; padding: 5px; -margin: -1px -1px 0 0; +margin: 5px -1px 0 0; } diff --git a/script/make-crontab b/script/make-crontab new file mode 100755 index 000000000..1b4fbabbd --- /dev/null +++ b/script/make-crontab @@ -0,0 +1,16 @@ +#!/usr/bin/env python +import re + +mailto = "recipient-of-any-errors@localhost" +user = "user-to-run-as" +location = "/path/to/alaveteli" + +template = open("config/crontab.ugly").read() +template = re.sub(r"MAILTO=.*", "MAILTO=%s" % mailto, template) +template = template.replace("!!(*= $user *)!!", user) +template = re.sub(r"/data/vhost/.*/script", location + "/script", template) + +print template + + + diff --git a/script/rails-post-deploy b/script/rails-post-deploy index 193d0bbec..6100bb1d0 100755 --- a/script/rails-post-deploy +++ b/script/rails-post-deploy @@ -96,6 +96,12 @@ if [ -n "$OPTION_THEME_URL" ] then echo "Installing $OPTION_THEME_URL using deprecated THEME_URL..." script/plugin install --force $OPTION_THEME_URL + NAME=`sed -re 's/.*\/(.*)\.git.?/\1/'` + POST_INSTALL="vendor/plugins/$NAME/post_install.rb" + if [ -e $POST_INSTALL ] + then + script/runner $POST_INSTALL + fi fi # upgrade database 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/models/censor_rule_spec.rb b/spec/models/censor_rule_spec.rb index 44087c5a6..d5797ec74 100644 --- a/spec/models/censor_rule_spec.rb +++ b/spec/models/censor_rule_spec.rb @@ -21,5 +21,45 @@ describe CensorRule, "substituting things" do body.should == "I don't know why you say xxxxxxx" body.should_not == orig_body # be sure duplicated as expected end + + context "when regexp type" do + before do + CensorRule.delete_all + CensorRule.create(:last_edit_editor => 1, + :last_edit_comment => 'comment') + @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 + end + + it "replaces with the regexp" do + body = +<<BODY +Some public information +--PRIVATE +Some private information +--PRIVATE +BODY + @censor_rule.apply_to_text!(body) + body.should == +<<BODY +Some public information +--REMOVED +Hidden private info +--REMOVED +BODY + end + + it "validates without info_request, user or public body set" do + @censor_rule.save.should be_true + end + + it "has scope for regexps" do + @censor_rule.save + CensorRule.regexps.all.should == [@censor_rule] + end + end end - + diff --git a/spec/models/info_request_spec.rb b/spec/models/info_request_spec.rb index a18a4bd1d..230884c38 100644 --- a/spec/models/info_request_spec.rb +++ b/spec/models/info_request_spec.rb @@ -398,7 +398,27 @@ describe InfoRequest 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 + context "with regexp censor rule" do + before do + Time.stub!(:now).and_return(Time.utc(2007, 11, 9, 23, 59)) + @info_request = InfoRequest.create!(:prominence => 'normal', + :awaiting_description => true, + :title => 'title', + :public_body => public_bodies(:geraldine_public_body), + :user_id => 1) + @censor_rule = CensorRule.create(:last_edit_editor => 1, + :last_edit_comment => 'comment', + :text => 'text', + :replacement => 'replacement', + :regexp => true) + end + it "applies regexp censor rule" do + body = 'text' + @info_request.apply_censor_rules_to_text!(body) + body.should == 'replacement' + 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 |