Skip to content

Commit

Permalink
Merge pull request #9557 from alphagov/content-modelling/627-filter-b…
Browse files Browse the repository at this point in the history
…y-type

Content modelling/627 filter by type and lead organisation
  • Loading branch information
Harriethw authored Oct 28, 2024
2 parents 83c5f32 + 66a7a99 commit db797c1
Show file tree
Hide file tree
Showing 13 changed files with 232 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<%= form_with url: helpers.content_block_manager.content_block_manager_content_block_documents_path, method: :get do %>
<%= render "govuk_publishing_components/components/input", {
label: {
text: "Keyword",
bold: true,
},
hint: 'For example, "driving standards"',
name: "keyword",
id: "keyword_filter",
value: !@filters.nil? && @filters[:keyword],
} %>
<%= render "govuk_publishing_components/components/checkboxes", {
heading: "Content block type",
heading_size: "s",
no_hint_text: true,
id: "block_type",
name: "block_type[]",
items: items_for_block_type,
} %>
<%= render "components/select_with_search", {
id: "lead_organisation",
name: "lead_organisation",
label: "Lead organisation",
heading_size: "s",
include_blank: true,
options: options_for_lead_organisation,
} %>
<%= render "govuk_publishing_components/components/button", {
text: "View results",
margin_bottom: 4,
} %>
<% end %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
class ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent < ViewComponent::Base
include ActionView::Helpers::RecordTagHelper
def initialize(filters:)
@filters = filters
end

private

def items_for_block_type
ContentBlockManager::ContentBlock::Schema.valid_schemas.map do |schema_name|
{
label: schema_name.humanize,
value: schema_name,
checked: !@filters.nil? && @filters[:block_type]&.include?(schema_name),
}
end
end

def options_for_lead_organisation
helpers.taggable_organisations_container.map do |name, id|
{
text: name,
value: id,
selected: !@filters.nil? && @filters[:lead_organisation] == id.to_s,
}
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def new_document_options_redirect
private

def params_filters
params.slice(:keyword)
params.slice(:keyword, :block_type, :lead_organisation)
.permit!
.to_h
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module ContentBlockManager
module ContentBlock
class Document < ApplicationRecord
include Scopes::SearchableByKeyword
include Scopes::SearchableByLeadOrganisation

extend FriendlyId
friendly_id :title, use: :slugged, slug_column: :content_id_alias, routes: :default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ def documents
documents = ContentBlock::Document
documents = documents.live
documents = documents.with_keyword(@filters[:keyword]) if @filters[:keyword].present?
documents = documents.where(block_type: @filters[:block_type]) if @filters[:block_type].present?
documents = documents.with_lead_organisation(@filters[:lead_organisation]) if @filters[:lead_organisation].present?
documents
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module ContentBlockManager
module ContentBlock::Document::Scopes::SearchableByLeadOrganisation
extend ActiveSupport::Concern

included do
scope :with_lead_organisation,
lambda { |id|
joins(latest_edition: :edition_organisation).where("content_block_edition_organisations.organisation_id = :id", id:)
}
end
end
end

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@

<div class="govuk-grid-row">
<div class="govuk-grid-column-one-third">
<%= render "filter_options" %>
<%= render(
ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(
filters: @filters,
),
) %>
</div>
<div class="govuk-grid-column-two-thirds">
<h2 class="govuk-heading-m"><%= pluralize(@content_block_documents.count, "result") %></h2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,23 @@ Feature: Search for a content object
Background:
Given the content block manager feature flag is enabled
Given I am a GDS admin
And the organisation "Ministry of Example" exists
And the organisation "Department of Placeholder" exists
And a schema "email_address" exists with the following fields:
| email_address |
And a schema "postal_address" exists with the following fields:
| an_address |
And an email address content block has been created
And an email address content block has been created with the following email address and title:
| title | "example search title" |
| email_address | "ministry@justice.com" |
| title | example search title |
| email_address | ministry@justice.com |
And a "postal_address" type of content block has been created with fields:
| an_address | ABC123 |
| organisation | Department of Placeholder |

Scenario: GDS Editor searches for a content object by keyword in title
When I visit the Content Block Manager home page
Then I should see the details for all documents
And "2" content blocks are returned
And "3" content blocks are returned
When I enter the keyword "example search"
And I click to view results
Then I should see the content block with title "example search title" returned
Expand All @@ -22,8 +27,24 @@ Feature: Search for a content object
Scenario: GDS Editor searches for a content object by keyword in details
When I visit the Content Block Manager home page
Then I should see the details for all documents
And "2" content blocks are returned
And "3" content blocks are returned
When I enter the keyword "ministry justice"
And I click to view results
Then I should see the content block with title "example search title" returned
And "1" content blocks are returned
And "1" content blocks are returned

Scenario: GDS Editor searches for a content object by block type
When I visit the Content Block Manager home page
Then I should see the details for all documents
And "3" content blocks are returned
When I check the block type "Email address"
And I click to view results
And "2" content blocks are returned

Scenario: GDS Editor searches for a content object by lead organisation
When I visit the Content Block Manager home page
Then I should see the details for all documents
And "3" content blocks are returned
When I select the lead organisation "Department of Placeholder"
And I click to view results
And "1" content blocks are returned
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,19 @@
@content_blocks.push(@content_block)
end

Given("a {string} type of content block has been created with fields:") do |block_type, table|
fields = table.rows_hash
organisation_name = fields.delete("organisation")
organisation = Organisation.where(name: organisation_name).first
create(
:content_block_edition,
block_type.to_sym,
organisation:,
details: fields,
creator: @user,
)
end

Given("an email address content block has been created with the following email address and title:") do |table|
fields = table.rows_hash
@content_blocks ||= []
Expand Down Expand Up @@ -435,6 +448,14 @@ def should_show_edit_form_for_email_address_content_block(document_title, email_
choose "Publish the change now"
end

Then("I check the block type {string}") do |checkbox_name|
check checkbox_name
end

Then("I select the lead organisation {string}") do |organisation|
select organisation, from: "lead_organisation"
end

When("I revisit the edit page") do
@content_block = @content_block.document.latest_edition
visit_edit_page
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
require "test_helper"

class ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponentTest < ViewComponent::TestCase
test "adds value of keyword to text input from filter" do
render_inline(ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(
filters: { keyword: "ministry defense" },
))

assert_selector "input[name='keyword'][value='ministry defense']"
end

test "renders checkbox items for all valid schemas" do
ContentBlockManager::ContentBlock::Schema.expects(:valid_schemas).returns(%w[email_address postal_address])
render_inline(ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(
filters: {},
))

assert_selector "input[type='checkbox'][name='block_type[]'][value='email_address']"
assert_selector "input[type='checkbox'][name='block_type[]'][value='postal_address']"
end

test "checks checkbox items if checked in filters" do
ContentBlockManager::ContentBlock::Schema.expects(:valid_schemas).returns(%w[email_address postal_address])
render_inline(ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(
filters: { block_type: %w[email_address] },
))

assert_selector "input[type='checkbox'][name='block_type[]'][value='email_address'][checked]"
assert_selector "input[type='checkbox'][name='block_type[]'][value='postal_address']"
end

test "selects organisation if selected in filters" do
helper_mock = mock
ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.any_instance.stubs(:helpers).returns(helper_mock)
helper_mock.stubs(:content_block_manager).returns(helper_mock)
helper_mock.stubs(:content_block_manager_content_block_documents_path).returns("path")
helper_mock.stubs(:taggable_organisations_container).returns(
[["Department of Placeholder", 1], ["Ministry of Example", 2]],
)
render_inline(ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(
filters: { lead_organisation: "2" },
))

assert_selector "select[name='lead_organisation']"
assert_selector "option[selected='selected'][value=2]"
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class ContentBlockManager::DocumentFilterTest < ActiveSupport::TestCase
document_scope_mock = mock
ContentBlockManager::ContentBlock::Document.expects(:live).returns(document_scope_mock)
document_scope_mock.expects(:with_keyword).never
document_scope_mock.expects(:where).never
document_scope_mock.expects(:with_lead_organisation).never

ContentBlockManager::ContentBlock::Document::DocumentFilter.new({}).documents
end
Expand All @@ -22,5 +24,36 @@ class ContentBlockManager::DocumentFilterTest < ActiveSupport::TestCase
ContentBlockManager::ContentBlock::Document::DocumentFilter.new({ keyword: "ministry of example" }).documents
end
end

describe "when a block type is given" do
it "returns live documents of the type given" do
document_scope_mock = mock
ContentBlockManager::ContentBlock::Document.expects(:live).returns(document_scope_mock)
document_scope_mock.expects(:where).with(block_type: %w[email_address]).returns([])
ContentBlockManager::ContentBlock::Document::DocumentFilter.new({ block_type: %w[email_address] }).documents
end
end

describe "when a lead organisation id is given" do
it "returns live documents with lead org given" do
document_scope_mock = mock
ContentBlockManager::ContentBlock::Document.expects(:live).returns(document_scope_mock)
document_scope_mock.expects(:with_lead_organisation).with("123").returns([])
ContentBlockManager::ContentBlock::Document::DocumentFilter.new({ lead_organisation: "123" }).documents
end
end

describe "when block types, keyword and organisation is given" do
it "returns live documents with the filters given" do
document_scope_mock = mock
ContentBlockManager::ContentBlock::Document.expects(:live).returns(document_scope_mock)
document_scope_mock.expects(:with_keyword).with("ministry of example").returns(document_scope_mock)
document_scope_mock.expects(:where).with(block_type: %w[email_address]).returns(document_scope_mock)
document_scope_mock.expects(:with_lead_organisation).with("123").returns([])
ContentBlockManager::ContentBlock::Document::DocumentFilter.new(
{ block_type: %w[email_address], keyword: "ministry of example", lead_organisation: "123" },
).documents
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require "test_helper"

class ContentBlockManager::SearchableByLeadOrganisationTest < ActiveSupport::TestCase
extend Minitest::Spec::DSL

describe ".with_lead_organisation" do
test "finds documents with lead organisation on latest edition" do
matching_organisation = create(:organisation, id: "1234")
document_with_org = create(:content_block_document, :email_address)
_edition_with_org = create(:content_block_edition,
:email_address,
document: document_with_org,
organisation: matching_organisation)
document_without_org = create(:content_block_document, :email_address)
_edition_without_org = create(:content_block_edition, :email_address, document: document_without_org)
_document_without_latest_edition = create(:content_block_document, :email_address)
assert_equal [document_with_org], ContentBlockManager::ContentBlock::Document.with_lead_organisation("1234")
end
end
end

0 comments on commit db797c1

Please sign in to comment.