From 71ef47fa623681fcdf58bcd30b70397f6bf5584e Mon Sep 17 00:00:00 2001 From: Graeme Porteous Date: Thu, 11 Apr 2024 12:30:08 +0100 Subject: [PATCH 1/5] Refactor RequestController#list specs Remove unused double and there is no reason to load the raw emails. --- spec/controllers/request_controller_spec.rb | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/spec/controllers/request_controller_spec.rb b/spec/controllers/request_controller_spec.rb index f18b69692b..2d80c2a517 100644 --- a/spec/controllers/request_controller_spec.rb +++ b/spec/controllers/request_controller_spec.rb @@ -1,11 +1,6 @@ require 'spec_helper' RSpec.describe RequestController, "when listing recent requests" do - before(:each) do - load_raw_emails_data - update_xapian_index - end - it "should be successful" do get :list, params: { view: 'all' } expect(response).to be_successful @@ -17,11 +12,6 @@ end it "should return 404 for pages we don't want to serve up" do - xap_results = double( - ActsAsXapian::Search, - results: (1..25).to_a.map { |m| { model: m } }, - matches_estimated: 1_000_000 - ) expect { get :list, params: { view: 'all', page: 100 } }.to raise_error(ActiveRecord::RecordNotFound) From cefbdf2ba20e3264d9b1a027d365b352859985d4 Mon Sep 17 00:00:00 2001 From: Graeme Porteous Date: Wed, 10 Apr 2024 16:37:13 +0100 Subject: [PATCH 2/5] Update request pagination setup Extract setup into before action hook. This will be reused in a new list by tag action. --- app/controllers/request_controller.rb | 35 ++++++++++++--------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/app/controllers/request_controller.rb b/app/controllers/request_controller.rb index cb23b6ce70..e3ccc4aae6 100644 --- a/app/controllers/request_controller.rb +++ b/app/controllers/request_controller.rb @@ -14,6 +14,7 @@ class RequestController < ApplicationController before_action :set_info_request, only: [:show] before_action :redirect_new_form_to_pro_version, only: [:select_authority, :new] before_action :set_in_pro_area, only: [:select_authority, :show] + before_action :setup_results_pagination, only: [:list, :similar] helper_method :state_transitions_empty? @@ -110,13 +111,6 @@ def details # Requests similar to this one def similar short_cache - @per_page = 25 - @page = (params[:page] || "1").to_i - - # Later pages are very expensive to load - if @page > MAX_RESULTS / PER_PAGE - raise ActiveRecord::RecordNotFound, "Sorry. No pages after #{MAX_RESULTS / PER_PAGE}." - end @info_request = InfoRequest.find_by_url_title!(params[:url_title]) @@ -134,20 +128,10 @@ def similar def list medium_cache @view = params[:view] - unless @page # used in cache case, as perform_search sets @page as side effect - @page = get_search_page_from_params - end - @per_page = PER_PAGE - @max_results = MAX_RESULTS if @view == "recent" return redirect_to request_list_all_url(action: "list", view: "all", page: @page), status: :moved_permanently end - # Later pages are very expensive to load - if @page > MAX_RESULTS / PER_PAGE - raise ActiveRecord::RecordNotFound, "Sorry. No pages after #{MAX_RESULTS / PER_PAGE}." - end - @filters = params.merge(latest_status: @view) if @page > 1 @@ -158,9 +142,6 @@ def list @track_thing = TrackThing.create_track_for_search_query(InfoRequestEvent.make_query_from_params(@filters)) @feed_autodetect = [ { url: do_track_url(@track_thing, 'feed'), title: @track_thing.params[:title_in_rss], has_json: true } ] - - # Don't let robots go more than 20 pages in - @no_crawl = true if @page > 20 end # Page new form posts to @@ -474,6 +455,20 @@ def outgoing_message_params params.require(:outgoing_message).permit(:body, :what_doing) end + def setup_results_pagination + @page ||= get_search_page_from_params + @per_page = PER_PAGE + @max_results = MAX_RESULTS + + # Don't let robots go more than 20 pages in + @no_crawl = true if @page > 20 + + # Later pages are very expensive to load + if @page > MAX_RESULTS / PER_PAGE + raise ActiveRecord::RecordNotFound, "Sorry. No pages after #{MAX_RESULTS / PER_PAGE}." + end + end + def can_update_status(info_request) # Don't allow status update on external requests, otherwise accept param info_request.is_external? ? false : params[:update_status] == "1" From d0070d53b914eeaf1fb3abd67a54820bb0af8967 Mon Sep 17 00:00:00 2001 From: Graeme Porteous Date: Thu, 11 Apr 2024 09:37:55 +0100 Subject: [PATCH 3/5] Add RequestControlle#list_by_tag action Allow users to view requests by tag. In the tag belongs to a category then, load the category and render a different title. The rendered the list action view template for consistency. In here we will add a conditional for the category and render notes and the rich body. --- app/controllers/request_controller.rb | 30 ++++++++++- app/views/request/_list_results.html.erb | 2 +- config/routes.rb | 3 ++ spec/controllers/request_controller_spec.rb | 57 +++++++++++++++++++++ spec/factories/categories.rb | 4 ++ 5 files changed, 94 insertions(+), 2 deletions(-) diff --git a/app/controllers/request_controller.rb b/app/controllers/request_controller.rb index e3ccc4aae6..b4e335c6eb 100644 --- a/app/controllers/request_controller.rb +++ b/app/controllers/request_controller.rb @@ -14,7 +14,7 @@ class RequestController < ApplicationController before_action :set_info_request, only: [:show] before_action :redirect_new_form_to_pro_version, only: [:select_authority, :new] before_action :set_in_pro_area, only: [:select_authority, :show] - before_action :setup_results_pagination, only: [:list, :similar] + before_action :setup_results_pagination, only: [:list, :list_by_tag, :similar] helper_method :state_transitions_empty? @@ -144,6 +144,34 @@ def list @feed_autodetect = [ { url: do_track_url(@track_thing, 'feed'), title: @track_thing.params[:title_in_rss], has_json: true } ] end + def list_by_tag + medium_cache + + @tag = params[:tag] + @filters = { query: "tag:#{@tag}" } + @results = InfoRequest.request_list(@filters, @page, @per_page, @max_results) + + @category = InfoRequest.category_list.find_by(category_tag: @tag) + @title = if @category.nil? + n_('Found {{count}} request tagged ‘{{tag_name}}’', + 'Found {{count}} requests tagged ‘{{tag_name}}’', + @results[:matches_estimated], + count: @results[:matches_estimated], + tag_name: @tag) + else + n_('Found {{count}} request in the category ‘{{category_title}}’', + 'Found {{count}} requests in the category ‘{{category_title}}’', + @results[:matches_estimated], + count: @results[:matches_estimated], + category_title: @category.title) + end + + @track_thing = TrackThing.create_track_for_search_query(InfoRequestEvent.make_query_from_params(@filters)) + @feed_autodetect = [ { url: do_track_url(@track_thing, 'feed'), title: @track_thing.params[:title_in_rss], has_json: true } ] + + render :list + end + # Page new form posts to def new # All new requests are of normal_sort diff --git a/app/views/request/_list_results.html.erb b/app/views/request/_list_results.html.erb index 8824ff0245..251ceffeab 100644 --- a/app/views/request/_list_results.html.erb +++ b/app/views/request/_list_results.html.erb @@ -1,4 +1,4 @@ -<% @results = InfoRequest.request_list(@filters, @page, @per_page, @max_results) %> +<% @results ||= InfoRequest.request_list(@filters, @page, @per_page, @max_results) %> <% if @results[:results].empty? %>

<%= _('No requests of this sort yet.')%>

<% else %> diff --git a/config/routes.rb b/config/routes.rb index 87ab3dbc7a..5eed4a1ac5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -98,6 +98,9 @@ def matches?(request) match '/list' => 'request#list', :as => :request_list, :via => :get + match '/list/:tag' => 'request#list_by_tag', + :as => :request_list_by_tag, + :via => :get match '/select_authority' => 'request#select_authority', :as => :select_authority, diff --git a/spec/controllers/request_controller_spec.rb b/spec/controllers/request_controller_spec.rb index 2d80c2a517..6f2b5d65c4 100644 --- a/spec/controllers/request_controller_spec.rb +++ b/spec/controllers/request_controller_spec.rb @@ -29,6 +29,63 @@ end end +RSpec.describe RequestController, "when listing recent requests by tag" do + it "should be successful" do + get :list_by_tag, params: { tag: 'climate' } + expect(response).to be_successful + end + + it "should render with 'list' template" do + get :list_by_tag, params: { tag: 'climate' } + expect(response).to render_template('list') + end + + it "should return 404 for pages we don't want to serve up" do + expect { + get :list_by_tag, params: { tag: 'climate', page: 100 } + }.to raise_error(ActiveRecord::RecordNotFound) + end + + it "raise unknown format error" do + expect { get :list_by_tag, params: { tag: "climate", format: :json } }.to( + raise_error ActionController::UnknownFormat + ) + end + + it 'should not raise an error for a page param of less than zero, but should treat it as a param of 1' do + expect { get :list_by_tag, params: { tag: 'climate', page: "-1" } }. + not_to raise_error + expect(assigns[:page]).to eq(1) + end + + it 'sets title based on if tag matches an request category' do + FactoryBot.create(:category, :info_request, + title: 'Climate requests', category_tag: 'climate') + + update_xapian_index + get :list_by_tag, params: { tag: 'climate' } + expect(assigns[:title]). + to eq("Found 0 requests in the category ‘Climate requests’") + + FactoryBot.create(:info_request, tag_string: 'climate') + update_xapian_index + get :list_by_tag, params: { tag: 'climate' } + expect(assigns[:title]). + to eq("Found 1 request in the category ‘Climate requests’") + end + + it 'sets title based on if tag does not match an request category' do + update_xapian_index + get :list_by_tag, params: { tag: 'other' } + expect(assigns[:title]).to eq("Found 0 requests tagged ‘other’") + + FactoryBot.create(:info_request, tag_string: 'other') + update_xapian_index + get :list_by_tag, params: { tag: 'other' } + expect(assigns[:title]).to eq("Found 1 request tagged ‘other’") + end +end + RSpec.describe RequestController, "when showing one request" do render_views diff --git a/spec/factories/categories.rb b/spec/factories/categories.rb index 180df1d690..72685e174c 100644 --- a/spec/factories/categories.rb +++ b/spec/factories/categories.rb @@ -20,5 +20,9 @@ trait :public_body do parents { [PublicBody.category_root] } end + + trait :info_request do + parents { [InfoRequest.category_root] } + end end end From 6606fd95b00ad2d2d75820d38b216866f5441424 Mon Sep 17 00:00:00 2001 From: Graeme Porteous Date: Thu, 11 Apr 2024 13:07:28 +0100 Subject: [PATCH 4/5] Update RequestController#list view Render any category notes and it's rich text body. --- app/views/request/_category.html.erb | 2 ++ app/views/request/list.html.erb | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 app/views/request/_category.html.erb diff --git a/app/views/request/_category.html.erb b/app/views/request/_category.html.erb new file mode 100644 index 0000000000..2f96b70660 --- /dev/null +++ b/app/views/request/_category.html.erb @@ -0,0 +1,2 @@ +<%= render_notes(@category.all_notes) %> +<%= @category.body %> diff --git a/app/views/request/list.html.erb b/app/views/request/list.html.erb index 498c45e7ee..5a89b11565 100644 --- a/app/views/request/list.html.erb +++ b/app/views/request/list.html.erb @@ -2,6 +2,8 @@

<%= @title %>

<%= render :partial => 'request/request_search_form', :locals => { :after_form_fields => render(:partial => 'request/request_filter_form') } %> + + <%= render partial: 'category' if @category %>