diff options
-rw-r--r-- | app/controllers/admin_controller.rb | 2 | ||||
-rw-r--r-- | app/models/info_request.rb | 15 | ||||
-rw-r--r-- | app/models/outgoing_message.rb | 5 | ||||
-rw-r--r-- | app/models/public_body.rb | 5 | ||||
-rw-r--r-- | app/models/user.rb | 7 | ||||
-rw-r--r-- | config/environment.rb | 1 | ||||
-rw-r--r-- | config/test.yml | 1 | ||||
-rw-r--r-- | db/migrate/111_create_purge_requests.rb | 14 | ||||
-rw-r--r-- | lib/varnish_purge.rb | 11 | ||||
-rw-r--r-- | spec/controllers/admin_censor_rule_controller_spec.rb | 19 | ||||
-rw-r--r-- | spec/controllers/request_controller_spec.rb | 59 | ||||
-rw-r--r-- | spec/spec_helper.rb | 3 |
12 files changed, 140 insertions, 2 deletions
diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index adb506b91..1612e5179 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -36,6 +36,8 @@ class AdminController < ApplicationController # also force a search reindexing (so changed text reflected in search) info_request.reindex_request_events + # and remove from varnsi + info_request.purge_in_cache end # Expire cached attachment files for a user diff --git a/app/models/info_request.rb b/app/models/info_request.rb index b5a1cd833..3a1f4b9f3 100644 --- a/app/models/info_request.rb +++ b/app/models/info_request.rb @@ -1042,6 +1042,21 @@ public end return ret end + + before_save(:mark_view_is_dirty) + def mark_view_is_dirty + self.view_is_dirty = true + self.save! + end + + def self.purge_varnish + for info_request in InfoRequest.find_by_view_is_dirty(true) + url = "/request/#{info_request.url_title}" + purge(url) + info_request.view_is_dirty = true + info_request.save! + end + end end diff --git a/app/models/outgoing_message.rb b/app/models/outgoing_message.rb index cc561b21d..de3c916aa 100644 --- a/app/models/outgoing_message.rb +++ b/app/models/outgoing_message.rb @@ -267,7 +267,10 @@ class OutgoingMessage < ActiveRecord::Base end end - + after_save(:purge_in_cache) + def purge_in_cache + self.info_request.purge_in_cache + end end diff --git a/app/models/public_body.rb b/app/models/public_body.rb index a18af8c69..11c6f6033 100644 --- a/app/models/public_body.rb +++ b/app/models/public_body.rb @@ -547,6 +547,11 @@ class PublicBody < ActiveRecord::Base } end + after_save(:purge_in_cache) + def purge_in_cache + self.info_requests.each {|x| x.purge_in_cache} + end + end diff --git a/app/models/user.rb b/app/models/user.rb index 59a84b7aa..73d65a8ca 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -422,5 +422,12 @@ class User < ActiveRecord::Base end return true end + + after_save(:purge_in_cache) + def purge_in_cache + # XXX should only be if specific attributes have changed + self.info_requests.each {|x| x.purge_in_cache} + end + end diff --git a/config/environment.rb b/config/environment.rb index e35194bc7..7366179bf 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -135,6 +135,7 @@ require 'i18n_fixes.rb' require 'rack_quote_monkeypatch.rb' require 'world_foi_websites.rb' require 'alaveteli_external_command.rb' +require 'varnish_purge.rb' ExceptionNotification::Notifier.sender_address = MySociety::Config::get('EXCEPTION_NOTIFICATIONS_FROM') ExceptionNotification::Notifier.exception_recipients = MySociety::Config::get('EXCEPTION_NOTIFICATIONS_TO') diff --git a/config/test.yml b/config/test.yml index 90689395a..991588f81 100644 --- a/config/test.yml +++ b/config/test.yml @@ -124,3 +124,4 @@ EXCEPTION_NOTIFICATIONS_TO: MAX_REQUESTS_PER_USER_PER_DAY: 2 +VARNISH_URL: http://varnish diff --git a/db/migrate/111_create_purge_requests.rb b/db/migrate/111_create_purge_requests.rb new file mode 100644 index 000000000..0b4fd1d1d --- /dev/null +++ b/db/migrate/111_create_purge_requests.rb @@ -0,0 +1,14 @@ +class CreatePurgeRequests < ActiveRecord::Migration + def self.up + create_table :purge_requests do |t| + t.column :url, :string + t.column :created_at, :datetime, :null => false + t.column :model, :string, :null => false + t.column :model_id, :integer, :null => false + end + end + + def self.down + drop_table :purge_requests + end +end diff --git a/lib/varnish_purge.rb b/lib/varnish_purge.rb new file mode 100644 index 000000000..ef0cbd7ea --- /dev/null +++ b/lib/varnish_purge.rb @@ -0,0 +1,11 @@ +require 'open-uri' + +def purge(url) + config = MySociety::Config.load_default() + varnish_url = config['VARNISH_URL'] + url = "#{varnish_url}#{url}" + result = open(url).read + if result != "OK" + raise + end +end diff --git a/spec/controllers/admin_censor_rule_controller_spec.rb b/spec/controllers/admin_censor_rule_controller_spec.rb new file mode 100644 index 000000000..952830f02 --- /dev/null +++ b/spec/controllers/admin_censor_rule_controller_spec.rb @@ -0,0 +1,19 @@ +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') + +describe AdminCensorRuleController, "when making censor rules from the admin interface" do + integrate_views + before { basic_auth_login @request } + + it "should create a censor rule and purge the corresponding request from varnish" do + ir = info_requests(:fancy_dog_request) + ir.should_receive(:purge_in_cache) + post :create, :censor_rule => { + :text => "meat", + :replacement => "tofu", + :last_edit_comment => "none", + :info_request => ir + } + end + + +end diff --git a/spec/controllers/request_controller_spec.rb b/spec/controllers/request_controller_spec.rb index 81c69db76..89d165587 100644 --- a/spec/controllers/request_controller_spec.rb +++ b/spec/controllers/request_controller_spec.rb @@ -117,6 +117,62 @@ describe RequestController, "when listing recent requests" do end +describe RequestController, "when changing things that appear on the request page" do + + integrate_views + + before(:each) do + FakeWeb.last_request = nil + end + + it "should purge the downstream cache when mail is received" do + ir = info_requests(:fancy_dog_request) + receive_incoming_mail('incoming-request-plain.email', ir.incoming_email) + FakeWeb.last_request.path.should include(ir.url_title) + end + it "should purge the downstream cache when a comment is added" do + ir = info_requests(:fancy_dog_request) + ir.should_receive(:purge_in_cache) + new_comment = info_requests(:fancy_dog_request).add_comment('I also love making annotations.', users(:bob_smith_user)) + end + it "should purge the downstream cache when a followup is made" do + session[:user_id] = users(:bob_smith_user).id + ir = info_requests(:fancy_dog_request) + post :show_response, :outgoing_message => { :body => "What a useless response! You suck.", :what_doing => 'normal_sort' }, :id => ir.id, :incoming_message_id => incoming_messages(:useless_incoming_message), :submitted_followup => 1 + FakeWeb.last_request.path.should include(ir.url_title) + end + it "should purge the downstream cache when the request is categorised" do + ir = info_requests(:fancy_dog_request) + ir.should_receive(:purge_in_cache) + ir.set_described_state('waiting_clarification') + end + it "should purge the downstream cache when the authority data is changed" do + ir = info_requests(:fancy_dog_request) + ir.public_body.name = "Something new" + ir.public_body.save! + FakeWeb.last_request.path.should include(ir.url_title) + end + it "should purge the downstream cache when the user details are changed" do + ir = info_requests(:fancy_dog_request) + ir.user.name = "Something new" + FakeWeb.last_request.should == nil + ir.user.save! + FakeWeb.last_request.path.should include(ir.url_title) + end + it "should purge the downstream cache when censor rules have changed" do + # XXX really, CensorRules should execute expiry logic as part + # of the after_save of the model. Currently this is part of + # the AdminController logic, so must be tested from + # there. Leaving this stub test in place as a reminder + end + it "should purge the downstream cache when something is hidden by an admin" do + ir = info_requests(:fancy_dog_request) + ir.should_receive(:purge_in_cache) + ir.prominence = 'hidden' + ir.save! + end +end + describe RequestController, "when showing one request" do before(:each) do @@ -185,7 +241,7 @@ describe RequestController, "when showing one request" do describe 'when handling incoming mail' do integrate_views - + it "should receive incoming messages, send email to creator, and show them" do ir = info_requests(:fancy_dog_request) ir.incoming_messages.each { |x| x.parse_raw_email! } @@ -1768,6 +1824,7 @@ describe RequestController, "when showing similar requests" do get :similar, :url_title => "there_is_really_no_such_path_owNAFkHR" }.should raise_error(ActiveRecord::RecordNotFound) end + end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 99cf8a2c8..5ca4b6de9 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -13,6 +13,9 @@ config['ADMIN_PASSWORD'] = 'baz' # tests assume 20 days config['REPLY_LATE_AFTER_DAYS'] = 20 +# register a fake Varnish server +require 'fakeweb' +FakeWeb.register_uri(:get, %r|varnish|, :body => "OK") # Uncomment the next line to use webrat's matchers #require 'webrat/integrations/rspec-rails' |