diff --git a/lib/engines/content_block_manager/app/components/content_block_manager/content_block/document/index/filter_options_component.html.erb b/lib/engines/content_block_manager/app/components/content_block_manager/content_block/document/index/filter_options_component.html.erb
new file mode 100644
index 00000000000..9522d6b46be
--- /dev/null
+++ b/lib/engines/content_block_manager/app/components/content_block_manager/content_block/document/index/filter_options_component.html.erb
@@ -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 %>
diff --git a/lib/engines/content_block_manager/app/components/content_block_manager/content_block/document/index/filter_options_component.rb b/lib/engines/content_block_manager/app/components/content_block_manager/content_block/document/index/filter_options_component.rb
new file mode 100644
index 00000000000..ee44f71154d
--- /dev/null
+++ b/lib/engines/content_block_manager/app/components/content_block_manager/content_block/document/index/filter_options_component.rb
@@ -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
diff --git a/lib/engines/content_block_manager/app/controllers/content_block_manager/content_block/documents_controller.rb b/lib/engines/content_block_manager/app/controllers/content_block_manager/content_block/documents_controller.rb
index 9e4185d8e76..3a24f7cb273 100644
--- a/lib/engines/content_block_manager/app/controllers/content_block_manager/content_block/documents_controller.rb
+++ b/lib/engines/content_block_manager/app/controllers/content_block_manager/content_block/documents_controller.rb
@@ -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
diff --git a/lib/engines/content_block_manager/app/models/content_block_manager/content_block/document.rb b/lib/engines/content_block_manager/app/models/content_block_manager/content_block/document.rb
index afe2424b5d4..dd877073bb0 100644
--- a/lib/engines/content_block_manager/app/models/content_block_manager/content_block/document.rb
+++ b/lib/engines/content_block_manager/app/models/content_block_manager/content_block/document.rb
@@ -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
diff --git a/lib/engines/content_block_manager/app/models/content_block_manager/content_block/document/document_filter.rb b/lib/engines/content_block_manager/app/models/content_block_manager/content_block/document/document_filter.rb
index c2bb05713fd..ba30dd275e9 100644
--- a/lib/engines/content_block_manager/app/models/content_block_manager/content_block/document/document_filter.rb
+++ b/lib/engines/content_block_manager/app/models/content_block_manager/content_block/document/document_filter.rb
@@ -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
diff --git a/lib/engines/content_block_manager/app/models/content_block_manager/content_block/document/scopes/searchable_by_lead_organisation.rb b/lib/engines/content_block_manager/app/models/content_block_manager/content_block/document/scopes/searchable_by_lead_organisation.rb
new file mode 100644
index 00000000000..6bc1cb1897d
--- /dev/null
+++ b/lib/engines/content_block_manager/app/models/content_block_manager/content_block/document/scopes/searchable_by_lead_organisation.rb
@@ -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
diff --git a/lib/engines/content_block_manager/app/views/content_block_manager/content_block/documents/_filter_options.html.erb b/lib/engines/content_block_manager/app/views/content_block_manager/content_block/documents/_filter_options.html.erb
deleted file mode 100644
index ad99cf2b49b..00000000000
--- a/lib/engines/content_block_manager/app/views/content_block_manager/content_block/documents/_filter_options.html.erb
+++ /dev/null
@@ -1,17 +0,0 @@
-<%= form_with url: 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/button", {
- text: "View results",
- margin_bottom: 4,
- } %>
-<% end %>
diff --git a/lib/engines/content_block_manager/app/views/content_block_manager/content_block/documents/index.html.erb b/lib/engines/content_block_manager/app/views/content_block_manager/content_block/documents/index.html.erb
index ba03c68400f..7e8f26b99fb 100644
--- a/lib/engines/content_block_manager/app/views/content_block_manager/content_block/documents/index.html.erb
+++ b/lib/engines/content_block_manager/app/views/content_block_manager/content_block/documents/index.html.erb
@@ -12,7 +12,11 @@
- <%= render "filter_options" %>
+ <%= render(
+ ContentBlockManager::ContentBlock::Document::Index::FilterOptionsComponent.new(
+ filters: @filters,
+ ),
+ ) %>
<%= pluralize(@content_block_documents.count, "result") %>
diff --git a/lib/engines/content_block_manager/features/search_for_object.feature b/lib/engines/content_block_manager/features/search_for_object.feature
index e2ef49bf02d..102cde00df6 100644
--- a/lib/engines/content_block_manager/features/search_for_object.feature
+++ b/lib/engines/content_block_manager/features/search_for_object.feature
@@ -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
@@ -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
\ No newline at end of file
+ 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
diff --git a/lib/engines/content_block_manager/features/step_definitions/content_block_manager_steps.rb b/lib/engines/content_block_manager/features/step_definitions/content_block_manager_steps.rb
index 6ad8ed550b7..63ea4e4c0b2 100644
--- a/lib/engines/content_block_manager/features/step_definitions/content_block_manager_steps.rb
+++ b/lib/engines/content_block_manager/features/step_definitions/content_block_manager_steps.rb
@@ -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 ||= []
@@ -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
diff --git a/lib/engines/content_block_manager/test/components/content_block/document/index/filter_options_component_test.rb b/lib/engines/content_block_manager/test/components/content_block/document/index/filter_options_component_test.rb
new file mode 100644
index 00000000000..37bb8a0ab06
--- /dev/null
+++ b/lib/engines/content_block_manager/test/components/content_block/document/index/filter_options_component_test.rb
@@ -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
diff --git a/lib/engines/content_block_manager/test/unit/app/models/content_block_edition/document/document_filter_test.rb b/lib/engines/content_block_manager/test/unit/app/models/content_block_edition/document/document_filter_test.rb
index 5aaa7da7bc4..b0f02eace43 100644
--- a/lib/engines/content_block_manager/test/unit/app/models/content_block_edition/document/document_filter_test.rb
+++ b/lib/engines/content_block_manager/test/unit/app/models/content_block_edition/document/document_filter_test.rb
@@ -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
@@ -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
diff --git a/lib/engines/content_block_manager/test/unit/app/models/content_block_edition/document/scopes/searchable_by_lead_organisation_test.rb b/lib/engines/content_block_manager/test/unit/app/models/content_block_edition/document/scopes/searchable_by_lead_organisation_test.rb
new file mode 100644
index 00000000000..3950b086423
--- /dev/null
+++ b/lib/engines/content_block_manager/test/unit/app/models/content_block_edition/document/scopes/searchable_by_lead_organisation_test.rb
@@ -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