From 16346a35227a51f6300e48825b3de67c80ea5326 Mon Sep 17 00:00:00 2001 From: CatalinVoineag <11318084+CatalinVoineag@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:18:51 +0100 Subject: [PATCH] Support claims index page filters We need to allow our support users to filter the claims. Two filters, School and Provider filters have 2 search fields where you can search by school name or provider to get the filter you want. This is done by javascript in a stimulus controller. The other 2 filters, Submitted after and Submitted before filters are date filters and use the govuk_date_field form helper. You cannot set the value of this helper as it's sending 3 params not just 1. So to persist the value of these filters we need a form object. Claims::Support::Claims::FilterForm is a form object that is meant to just house the params and all the logic that these filter need. All the params of the filters are in the url. --- app/assets/images/icon-magnifying-glass.svg | 3 + app/assets/stylesheets/filter-form.scss | 24 +- app/components/claim/card_component.html.erb | 2 +- .../claims/support/claims_controller.rb | 27 +- .../claims/support/claims/filter_form.rb | 111 ++++++++ ...claims_support_filter_search_controller.js | 48 ++++ app/javascript/controllers/index.js | 3 + app/queries/claims/claims_query.rb | 15 + .../claims/support/claims/_filter.html.erb | 159 +++++++++++ .../claims/support/claims/index.html.erb | 42 ++- config/locales/en.yml | 4 + config/locales/en/claims/support/claims.yml | 11 + spec/components/claim/card_component_spec.rb | 2 +- .../claims/support/claims/filter_form_spec.rb | 260 ++++++++++++++++++ spec/queries/claims/claims_query_spec.rb | 22 ++ .../claims/support/claims/view_claims_spec.rb | 137 ++++++++- 16 files changed, 843 insertions(+), 27 deletions(-) create mode 100644 app/assets/images/icon-magnifying-glass.svg create mode 100644 app/forms/claims/support/claims/filter_form.rb create mode 100644 app/javascript/controllers/claims_support_filter_search_controller.js create mode 100644 app/views/claims/support/claims/_filter.html.erb create mode 100644 spec/forms/claims/support/claims/filter_form_spec.rb diff --git a/app/assets/images/icon-magnifying-glass.svg b/app/assets/images/icon-magnifying-glass.svg new file mode 100644 index 000000000..997be4315 --- /dev/null +++ b/app/assets/images/icon-magnifying-glass.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/assets/stylesheets/filter-form.scss b/app/assets/stylesheets/filter-form.scss index 2714e5193..971deb743 100644 --- a/app/assets/stylesheets/filter-form.scss +++ b/app/assets/stylesheets/filter-form.scss @@ -238,7 +238,6 @@ &:hover:after { background-image: url("icon-tag-remove-cross-white.svg"); } - } .app-filter__options { @@ -258,3 +257,26 @@ } } } + +.app-filter__option .govuk-checkboxes { + position: relative; + max-height: 200px; + overflow-x: hidden; + overflow-y: auto; +} + +.app-filter__option input[type=search] { + background: url("icon-magnifying-glass.svg") no-repeat; + background-color: govuk-colour("white"); + padding-left: govuk-spacing(6); +} + +.app-filter__option:not(:last-of-type) { + border-bottom: 1px solid $govuk-border-colour; + margin-bottom: govuk-spacing(4); + + div:last-of-type { + margin-bottom: govuk-spacing(1); + } +} + diff --git a/app/components/claim/card_component.html.erb b/app/components/claim/card_component.html.erb index df9123c50..a86c93e55 100644 --- a/app/components/claim/card_component.html.erb +++ b/app/components/claim/card_component.html.erb @@ -13,7 +13,7 @@
-
<%= l(claim.created_at.to_date, format: :short) %>
+
<%= l(claim.submitted_at.to_date, format: :short) %>
<%= humanized_money_with_symbol(claim.amount) %>
diff --git a/app/controllers/claims/support/claims_controller.rb b/app/controllers/claims/support/claims_controller.rb index e41a89643..70ef6b79a 100644 --- a/app/controllers/claims/support/claims_controller.rb +++ b/app/controllers/claims/support/claims_controller.rb @@ -1,9 +1,12 @@ class Claims::Support::ClaimsController < Claims::Support::ApplicationController before_action :set_claim, only: %i[show] before_action :authorize_claim + helper_method :filter_form def index - @pagy, @claims = pagy(Claims::ClaimsQuery.call(params:)) + @pagy, @claims = pagy(Claims::ClaimsQuery.call(params: filter_form.query_params)) + @schools = Claims::School.all + @providers = Claims::Provider.private_beta_providers end def show; end @@ -16,6 +19,28 @@ def download_csv private + def filter_form + Claims::Support::Claims::FilterForm.new(filter_params) + end + + def filter_params + params.fetch(:claims_support_claims_filter_form, {}).permit( + :search, + :search_school, + :search_provider, + "submitted_after(1i)", + "submitted_after(2i)", + "submitted_after(3i)", + "submitted_before(1i)", + "submitted_before(2i)", + "submitted_before(3i)", + :submitted_after, + :submitted_before, + provider_ids: [], + school_ids: [], + ) + end + def set_claim @claim = Claims::Claim.find(params.require(:id)) end diff --git a/app/forms/claims/support/claims/filter_form.rb b/app/forms/claims/support/claims/filter_form.rb new file mode 100644 index 000000000..dfe61ec89 --- /dev/null +++ b/app/forms/claims/support/claims/filter_form.rb @@ -0,0 +1,111 @@ +class Claims::Support::Claims::FilterForm < ApplicationForm + include ActiveModel::Attributes + + attribute :search + attribute :search_school + attribute :search_provider + attribute "submitted_after(1i)" + attribute "submitted_after(2i)" + attribute "submitted_after(3i)" + attribute "submitted_before(1i)" + attribute "submitted_before(2i)" + attribute "submitted_before(3i)" + attribute :school_ids, default: [] + attribute :provider_ids, default: [] + + def initialize(params = {}) + params[:school_ids].compact_blank! if params[:school_ids].present? + params[:provider_ids].compact_blank! if params[:provider_ids].present? + + super(params) + end + + def filters_selected? + school_ids.present? || + provider_ids.present? || + submitted_after.present? || + submitted_before.present? + end + + def index_path_without_filter(filter:, value: nil) + without_filter = compacted_attributes.merge( + filter => compacted_attributes[filter].reject { |filter_value| filter_value == value }, + ) + + claims_support_claims_path( + params: { claims_support_claims_filter_form: without_filter }, + ) + end + + def index_path_without_submitted_dates(filter) + without_filter = compacted_attributes.except( + "#{filter}(1i)", + "#{filter}(2i)", + "#{filter}(3i)", + ) + + claims_support_claims_path( + params: { claims_support_claims_filter_form: without_filter }, + ) + end + + def clear_filters_path + filter_params = search.present? ? { claims_support_claims_filter_form: { search: } } : {} + + claims_support_claims_path( + params: filter_params, + ) + end + + def clear_search_path + claims_support_claims_path( + params: { claims_support_claims_filter_form: compacted_attributes.except("search") }, + ) + end + + def schools + @schools ||= Claims::School.find(school_ids) + end + + def providers + @providers ||= Claims::Provider.find(provider_ids) + end + + def query_params + { + search:, + search_school:, + search_provider:, + school_ids:, + provider_ids:, + submitted_after:, + submitted_before:, + } + end + + def submitted_after + Date.new( + attributes["submitted_after(1i)"].to_i, # year + attributes["submitted_after(2i)"].to_i, # month + attributes["submitted_after(3i)"].to_i, # day + ) + rescue Date::Error + nil + end + + def submitted_before + Date.new( + attributes["submitted_before(1i)"].to_i, # year + attributes["submitted_before(2i)"].to_i, # month + attributes["submitted_before(3i)"].to_i, # day + ) + rescue Date::Error + nil + end + + private + + def compacted_attributes + @compacted_attributes ||= attributes.compact_blank + end +end diff --git a/app/javascript/controllers/claims_support_filter_search_controller.js b/app/javascript/controllers/claims_support_filter_search_controller.js new file mode 100644 index 000000000..64bccab75 --- /dev/null +++ b/app/javascript/controllers/claims_support_filter_search_controller.js @@ -0,0 +1,48 @@ +import { Controller } from "@hotwired/stimulus" + +// Connects to data-controller="claims-support-filter-search" +export default class extends Controller { + static targets = [ "schoolInput", "schoolList", "providerInput", "providerList" ] + + connect() { + if (this.schoolInputTarget.value !== "") { + this.searchSchool() + } + + if (this.providerInputTarget.value !== "") { + this.searchProvider() + } + } + + searchSchool() { + const schoolItems = this.schoolListTarget.children + const searchValue = this.schoolInputTarget.value.toLowerCase() + + Array.from(schoolItems).forEach(function (item) { + const inputField = item.querySelector("input") + + if (item.textContent.toLowerCase().indexOf(searchValue) > -1 ) { + item.style.display = "" + } else { + item.style.display = "none" + inputField.checked = false + } + }) + } + + searchProvider() { + const providerItems = this.providerListTarget.children + const searchValue = this.providerInputTarget.value.toLowerCase() + + Array.from(providerItems).forEach(function (item) { + const inputField = item.querySelector("input") + + if (item.textContent.toLowerCase().indexOf(searchValue) > -1 ) { + item.style.display = "" + } else { + item.style.display = "none" + inputField.checked = false + } + }) + } +} diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js index 779e8e8a2..75ad505c4 100644 --- a/app/javascript/controllers/index.js +++ b/app/javascript/controllers/index.js @@ -4,6 +4,9 @@ import { application } from "./application" +import ClaimsSupportFilterSearchController from "./claims_support_filter_search_controller" +application.register("claims-support-filter-search", ClaimsSupportFilterSearchController ) + import AutocompleteController from "./autocomplete_controller" application.register("autocomplete", AutocompleteController) diff --git a/app/queries/claims/claims_query.rb b/app/queries/claims/claims_query.rb index 185ab42e9..087b920c6 100644 --- a/app/queries/claims/claims_query.rb +++ b/app/queries/claims/claims_query.rb @@ -4,6 +4,9 @@ def call scope = search_condition(scope) scope = school_condition(scope) scope = provider_condition(scope) + scope = submitted_after(scope) + scope = submitted_before(scope) + scope.order_created_at_desc end @@ -26,4 +29,16 @@ def provider_condition(scope) scope.where(provider_id: params[:provider_ids]) end + + def submitted_after(scope) + return scope if params[:submitted_after].nil? + + scope.where(submitted_at: params[:submitted_after]..) + end + + def submitted_before(scope) + return scope if params[:submitted_before].nil? + + scope.where(submitted_at: ..params[:submitted_before]) + end end diff --git a/app/views/claims/support/claims/_filter.html.erb b/app/views/claims/support/claims/_filter.html.erb new file mode 100644 index 000000000..2d5ce5b8f --- /dev/null +++ b/app/views/claims/support/claims/_filter.html.erb @@ -0,0 +1,159 @@ +
+
+
+
+

<%= t("filter") %>

+
+
+
+
+ <% if filter_form.filters_selected? %> +
+
+
+

<%= t("selected_filters") %>

+

+ <%= govuk_link_to( + t("clear_filters"), + filter_form.clear_filters_path, + no_visited_state: true, + ) %> +

+
+
+ + <% if filter_form.school_ids.present? %> +

<%= t("claims.support.claims.index.school") %>

+
    + <% filter_form.schools.each do |school| %> +
  • + <%= govuk_link_to( + school.name, + filter_form.index_path_without_filter(filter: "school_ids", value: school.id), + class: "app-filter__tag", + no_visited_state: true, + ) %> +
  • + <% end %> +
+ <% end %> + + <% if filter_form.provider_ids.present? %> +

<%= t("claims.support.claims.index.accredited_provider") %>

+
    + <% filter_form.providers.each do |provider| %> +
  • + <%= govuk_link_to( + provider.name, + filter_form.index_path_without_filter(filter: "provider_ids", value: provider.id), + class: "app-filter__tag", + no_visited_state: true, + ) %> +
  • + <% end %> +
+ <% end %> + + <% if filter_form.submitted_after.present? %> +

<%= t("claims.support.claims.index.submitted_after") %>

+ <%= govuk_link_to( + safe_l(filter_form.submitted_after, format: :short), + filter_form.index_path_without_submitted_dates("submitted_after"), + class: "app-filter__tag", + no_visited_state: true, + ) %> + <% end %> + + <% if filter_form.submitted_before.present? %> +

<%= t("claims.support.claims.index.submitted_before") %>

+ <%= govuk_link_to( + safe_l(filter_form.submitted_before, format: :short), + filter_form.index_path_without_submitted_dates("submitted_before"), + class: "app-filter__tag", + no_visited_state: true, + ) %> + <% end %> +
+ <% end %> + +
+ <%= form_with( + model: filter_form, + url: claims_support_claims_path, + method: "get", + data: { turbo: false, controller: "claims-support-filter-search" }, + ) do |form| %> + <%= form.govuk_submit t("apply_filters") %> + + <%= form.hidden_field :search, value: filter_form.search %> + +
+ <%= form.govuk_text_field( + :search_school, + type: :search, + data: { + claims_support_filter_search_target: "schoolInput", + action: "input->claims-support-filter-search#searchSchool", + }, + label: { text: t("claims.support.claims.index.school"), size: "s" }, + ) %> + + <%= form.govuk_check_boxes_fieldset( + :school_ids, + legend: { hidden: "true" }, + data: { claims_support_filter_search_target: "schoolList" }, + small: true, + ) do %> + + <% @schools.find_each do |school| %> + <%= form.govuk_check_box :school_ids, school.id, label: { text: school.name } %> + <% end %> + <% end %> +
+ +
+ <%= form.govuk_text_field( + :search_provider, + data: { + claims_support_filter_search_target: "providerInput", + action: "input->claims-support-filter-search#searchProvider", + }, + type: :search, + label: { text: t("claims.support.claims.index.provider"), size: "s" }, + ) %> + + <%= form.govuk_check_boxes_fieldset( + :provider_ids, + legend: { hidden: "true" }, + small: true, + data: { claims_support_filter_search_target: "providerList" }, + ) do %> + <% @providers.each do |provider| %> + <%= form.govuk_check_box :provider_ids, provider.id, label: { text: provider.name } %> + <% end %> + <% end %> +
+ +
+ <%= form.govuk_date_field( + :submitted_after, + date_of_birth: true, + maxlength_enabled: true, + legend: { text: t("claims.support.claims.index.submitted_after") }, + hint: { text: t("claims.support.claims.index.submitted_after_hint") }, + ) %> +
+ +
+ <%= form.govuk_date_field( + :submitted_before, + maxlength_enabled: true, + legend: { text: t("claims.support.claims.index.submitted_before") }, + hint: { text: t("claims.support.claims.index.submitted_before_hint") }, + ) %> +
+ <% end %> +
+
+
+
diff --git a/app/views/claims/support/claims/index.html.erb b/app/views/claims/support/claims/index.html.erb index 7800b0ab0..e6a15583f 100644 --- a/app/views/claims/support/claims/index.html.erb +++ b/app/views/claims/support/claims/index.html.erb @@ -8,20 +8,40 @@
-
-
-
Filter
-
-
+ <%= render partial: "filter" %>
- <%= render partial: "shared/search_form", locals: { - url: claims_support_claims_path, - label: { text: t(".search_label"), size: "s" }, - name: :search, - clear_search_url: claims_support_claims_path, - } %> +
+ <%= form_with( + url: claims_support_claims_path, + scope: :claims_support_claims_filter_form, + class: "search-form", + method: :get, + data: { turbo: false }, + ) do |f| %> + <%= f.govuk_text_field :search, type: :search, value: filter_form.search, label: { text: t(".search_label"), size: "s" } %> + <%= f.govuk_submit t(".submit") %> + + <% filter_form.attributes.except("search", "school_ids", "provider_ids").each do |key, value| %> + <%= f.hidden_field key, value: %> + <% end %> + + <% filter_form.school_ids.each do |school_id| %> + <%= f.hidden_field :school_ids, value: school_id, multiple: true %> + <% end %> + + <% filter_form.provider_ids.each do |provider_id| %> + <%= f.hidden_field :provider_ids, value: provider_id, multiple: true %> + <% end %> + <% end %> +
+ + <% unless filter_form.search.blank? %> + + <% end %>
diff --git a/config/locales/en.yml b/config/locales/en.yml index 135180d32..6dc6d74ba 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -11,6 +11,10 @@ en: cancel: Cancel continue: Continue change: Change + filter: Filter + apply_filters: Apply filters + selected_filters: Selected filters + clear_filters: Clear filters date: formats: month: "%B" diff --git a/config/locales/en/claims/support/claims.yml b/config/locales/en/claims/support/claims.yml index e5cd73eb5..9e57dcff5 100644 --- a/config/locales/en/claims/support/claims.yml +++ b/config/locales/en/claims/support/claims.yml @@ -6,6 +6,17 @@ en: heading: Claims (%{count}) download_csv: Download claims search_label: Search by claim reference + school: School + accredited_provider: Accredited provider + submitted_after: Submitted after + submitted_after_hint: For example, 31 3 2024 + submitted_before: Submitted before + submitted_before_hint: For example, 31 7 2024 + school_ids: School + provider_ids: Accredited prvoider + provider: Accredited prvoider + submit: Search + clear: Clear search show: heading: Claim status: Status diff --git a/spec/components/claim/card_component_spec.rb b/spec/components/claim/card_component_spec.rb index 816b7ed87..02eb6fda2 100644 --- a/spec/components/claim/card_component_spec.rb +++ b/spec/components/claim/card_component_spec.rb @@ -6,7 +6,7 @@ subject(:component) { described_class.new(claim:) } let(:claim) do - create(:claim, :submitted, created_at: "2024/04/08", school:) do |claim| + create(:claim, :submitted, submitted_at: "2024/04/08", school:) do |claim| claim.mentor_trainings << create(:mentor_training, hours_completed: 20) end end diff --git a/spec/forms/claims/support/claims/filter_form_spec.rb b/spec/forms/claims/support/claims/filter_form_spec.rb new file mode 100644 index 000000000..06690f879 --- /dev/null +++ b/spec/forms/claims/support/claims/filter_form_spec.rb @@ -0,0 +1,260 @@ +require "rails_helper" + +describe Claims::Support::Claims::FilterForm, type: :model do + include Rails.application.routes.url_helpers + + describe "#filters_selected?" do + it "returns true if school_ids present" do + params = { school_ids: %w[school_id] } + form = described_class.new(params) + + expect(form.filters_selected?).to eq(true) + end + + it "returns true if provider_ids present" do + params = { provider_ids: %w[provider_id] } + form = described_class.new(params) + + expect(form.filters_selected?).to eq(true) + end + + it "returns true if submitted_after is present" do + params = { + "submitted_after(1i)" => "2024", + "submitted_after(2i)" => "1", + "submitted_after(3i)" => "2", + } + form = described_class.new(params) + + expect(form.filters_selected?).to eq(true) + end + + it "returns true if submitted_before is present" do + params = { + "submitted_before(1i)" => "2024", + "submitted_before(2i)" => "1", + "submitted_before(3i)" => "2", + } + form = described_class.new(params) + + expect(form.filters_selected?).to eq(true) + end + + context "when filters are not present" do + it "returns false" do + form = described_class.new({}) + + expect(form.filters_selected?).to eq(false) + end + end + end + + describe "#index_path_without_filter" do + it "returns the support claims index path without a filter" do + params = { school_ids: %w[school_id] } + call = described_class.new(params).index_path_without_filter(filter: "school_ids", value: "school_id") + + expect(call).to eq( + claims_support_claims_path( + params: { claims_support_claims_filter_form: { school_ids: [], provider_ids: [] } }, + ), + ) + end + end + + describe "#index_path_without_submitted_dates" do + context "with submitted_after" do + it "returns the support claims index path without submitted dates" do + params = { + "submitted_after(1i)" => "2024", + "submitted_after(2i)" => "1", + "submitted_after(3i)" => "2", + } + call = described_class.new(params).index_path_without_submitted_dates("submitted_after") + + expect(call).to eq( + claims_support_claims_path( + params: { claims_support_claims_filter_form: { school_ids: [], provider_ids: [] } }, + ), + ) + end + end + + context "with submitted_before" do + it "returns the support claims index path without submitted dates" do + params = { + "submitted_before(1i)" => "2024", + "submitted_before(2i)" => "1", + "submitted_before(3i)" => "2", + } + call = described_class.new(params).index_path_without_submitted_dates("submitted_before") + + expect(call).to eq( + claims_support_claims_path( + params: { claims_support_claims_filter_form: { school_ids: [], provider_ids: [] } }, + ), + ) + end + end + end + + describe "#clear_filters_path" do + it "returns the support claims index path without filters but with search" do + params = { school_ids: %w[school_id], search: "search" } + call = described_class.new(params).clear_filters_path + + expect(call).to eq( + claims_support_claims_path( + params: { claims_support_claims_filter_form: { search: "search" } }, + ), + ) + end + + context "when search param is not present" do + it "returns the support claims index path without filters and search" do + params = { school_ids: %w[school_id] } + call = described_class.new(params).clear_filters_path + + expect(call).to eq(claims_support_claims_path) + end + end + end + + describe "#clear_search_path" do + it "returns the support claims index path without search but with filters" do + params = { school_ids: %w[school_id], search: "search" } + call = described_class.new(params).clear_search_path + + expect(call).to eq( + claims_support_claims_path( + params: { claims_support_claims_filter_form: { school_ids: %w[school_id] } }, + ), + ) + end + + context "when filters are not present" do + it "returns the support claims index path without search and without filters" do + params = { search: "search" } + call = described_class.new(params).clear_search_path + + expect(call).to eq(claims_support_claims_path) + end + end + end + + describe "#schools" do + it "returns a collection of claims schools based on school_ids param" do + school = create(:claims_school) + params = { school_ids: [school.id] } + call = described_class.new(params).schools + + expect(call).to eq([school]) + end + + context "when school_ids is empty" do + it "returns empty array" do + params = { school_ids: [] } + call = described_class.new(params).schools + + expect(call).to eq([]) + end + end + end + + describe "#providers" do + it "returns a collection of claims providers based on provider_ids param" do + provider = create(:claims_provider) + params = { provider_ids: [provider.id] } + call = described_class.new(params).providers + + expect(call).to eq([provider]) + end + + context "when provider_ids is empty" do + it "returns empty array" do + params = { provider_ids: [] } + call = described_class.new(params).providers + + expect(call).to eq([]) + end + end + end + + describe "#query_params" do + it "returns the query params meant for searching the database" do + params = { + search: "claim_reference", + search_school: "school_name", + search_provider: "provider", + "submitted_after(1i)" => "2024", + "submitted_after(2i)" => "1", + "submitted_after(3i)" => "2", + "submitted_before(1i)" => "2023", + "submitted_before(2i)" => "1", + "submitted_before(3i)" => "2", + school_ids: %w[school_id], + provider_ids: %w[provider_id], + } + + call = described_class.new(params).query_params + + expect(call).to eq( + provider_ids: %w[provider_id], + school_ids: %w[school_id], + search: "claim_reference", + search_provider: "provider", + search_school: "school_name", + submitted_after: Date.new(2024, 1, 2), + submitted_before: Date.new(2023, 1, 2), + ) + end + end + + describe "#submitted_after" do + it "the Submitted after date in Date format" do + params = { + "submitted_after(1i)" => "2024", + "submitted_after(2i)" => "1", + "submitted_after(3i)" => "2", + } + call = described_class.new(params).submitted_after + + expect(call).to eq(Date.new(2024, 1, 2)) + end + + context "when submitted after params are not valid" do + it "the Submitted after date in Date format" do + params = { + "submitted_after(1i)" => "invalid", + } + call = described_class.new(params).submitted_after + + expect(call).to eq(nil) + end + end + end + + describe "#submitted_before" do + it "the Submitted before date in Date format" do + params = { + "submitted_before(1i)" => "2024", + "submitted_before(2i)" => "1", + "submitted_before(3i)" => "2", + } + call = described_class.new(params).submitted_before + + expect(call).to eq(Date.new(2024, 1, 2)) + end + + context "when submitted before params are not valid" do + it "the Submitted before date in Date format" do + params = { + "submitted_before(1i)" => "invalid", + } + call = described_class.new(params).submitted_before + + expect(call).to eq(nil) + end + end + end +end diff --git a/spec/queries/claims/claims_query_spec.rb b/spec/queries/claims/claims_query_spec.rb index aabdb10ed..419472790 100644 --- a/spec/queries/claims/claims_query_spec.rb +++ b/spec/queries/claims/claims_query_spec.rb @@ -48,5 +48,27 @@ expect(claims_query).to match_array([claim_belonging_to_filtered_provider]) end end + + context "when given submitted_after" do + let(:params) { { submitted_after: 2.days.ago } } + + it "filters the results by provided provider ids" do + expected_claim = create(:claim, :submitted, submitted_at: 1.day.ago) + _unexpected_claim = create(:claim, :submitted, submitted_at: 3.days.ago) + + expect(claims_query).to match_array([expected_claim]) + end + end + + context "when given submitted_before" do + let(:params) { { submitted_before: 2.days.ago } } + + it "filters the results by provided provider ids" do + expected_claim = create(:claim, :submitted, submitted_at: 3.days.ago) + _unexpected_claim = create(:claim, :submitted, submitted_at: 1.day.ago) + + expect(claims_query).to match_array([expected_claim]) + end + end end end diff --git a/spec/system/claims/support/claims/view_claims_spec.rb b/spec/system/claims/support/claims/view_claims_spec.rb index 3a754685f..e23bcf0d6 100644 --- a/spec/system/claims/support/claims/view_claims_spec.rb +++ b/spec/system/claims/support/claims/view_claims_spec.rb @@ -1,9 +1,18 @@ require "rails_helper" -RSpec.describe "View claims", type: :system, service: :claims do +RSpec.describe "View claims", type: :system, service: :claims, js: true do let!(:support_user) { create(:claims_support_user) } - let!(:claim_2) { create(:claim, :submitted) } - let!(:claim_1) { create(:claim, :draft) } + let!(:school_1) { create(:claims_school) } + let!(:school_2) { create(:claims_school) } + let!(:provider_1) { create(:claims_provider, :best_practice_network) } + let!(:provider_2) { create(:claims_provider, :niot) } + let!(:claim_1) { create(:claim, :draft, school: school_1) } + let!(:claim_2) { create(:claim, :submitted, school: school_1, provider: provider_1, submitted_at: Date.new(2024, 4, 7), created_at: Date.new(2024, 4, 7)) } + let!(:claim_3) { create(:claim, :submitted, school: school_1, provider: provider_1, submitted_at: Date.new(2024, 4, 6), created_at: Date.new(2024, 4, 6)) } + let!(:claim_4) { create(:claim, :submitted, school: school_1, provider: provider_1, submitted_at: Date.new(2024, 4, 5), created_at: Date.new(2024, 4, 5)) } + let!(:claim_5) { create(:claim, :submitted, school: school_1, provider: provider_1, submitted_at: Date.new(2024, 4, 4), created_at: Date.new(2024, 4, 4)) } + let!(:claim_6) { create(:claim, :submitted, school: school_1, provider: provider_2, submitted_at: Date.new(2024, 4, 3), created_at: Date.new(2024, 4, 3)) } + let!(:claim_7) { create(:claim, :submitted, school: school_2, provider: provider_2, submitted_at: Date.new(2024, 4, 2), created_at: Date.new(2024, 4, 2)) } before do user_exists_in_dfe_sign_in(user: support_user) @@ -12,8 +21,41 @@ scenario "Support user visits the claims index page" do when_i_visit_claim_index_page - then_i_see_a_list_of_submitted_claims + then_i_see_a_list_of_submitted_claims([claim_2, claim_3, claim_4, claim_5, claim_6, claim_7]) and_i_see_no_draft_claims + when_i_check_school_filter(school_1) + then_i_see_a_list_of_submitted_claims([claim_2, claim_3, claim_4, claim_5, claim_6]) + when_i_check_provider_filter(provider_1) + then_i_see_a_list_of_submitted_claims([claim_2, claim_3, claim_4, claim_5]) + when_i_set_submitted_after(5, 4, 2024) + then_i_see_a_list_of_submitted_claims([claim_2, claim_3, claim_4]) + when_i_set_submitted_before(6, 4, 2024) + then_i_see_a_list_of_submitted_claims([claim_3, claim_4]) + when_i_search_for_claim_reference(claim_3.reference) + then_i_see_a_list_of_submitted_claims([claim_3]) + when_i_remove_my_search + then_i_see_a_list_of_submitted_claims([claim_3, claim_4]) + when_i_remove_the_filter("06/04/2024") + then_i_see_a_list_of_submitted_claims([claim_2, claim_3, claim_4]) + when_i_remove_the_filter("05/04/2024") + then_i_see_a_list_of_submitted_claims([claim_2, claim_3, claim_4, claim_5]) + when_i_remove_the_filter(provider_1.name) + then_i_see_a_list_of_submitted_claims([claim_2, claim_3, claim_4, claim_5, claim_6]) + when_i_remove_the_filter(school_1.name) + then_i_see_a_list_of_submitted_claims([claim_2, claim_3, claim_4, claim_5, claim_6, claim_7]) + end + + scenario "Support user uses the js filter search" do + when_i_visit_claim_index_page + then_i_see_a_list_of_submitted_claims([claim_2, claim_3, claim_4, claim_5, claim_6, claim_7]) + when_i_search_the_school_filer_with(school_2.name) + then_i_see_only_my_filter_school_as_an_option + when_i_check_school_filter(school_2) + then_i_see_a_list_of_submitted_claims([claim_7]) + then_i_see_my_search_school_filter_populated(school_2.name) + when_i_search_the_provider_filer_with(provider_2.name) + when_i_check_provider_filter(provider_2) + then_i_see_a_list_of_submitted_claims([claim_7]) end private @@ -27,18 +69,89 @@ def when_i_visit_claim_index_page click_on("Claims") end - def then_i_see_a_list_of_submitted_claims - within(".claim-card:nth-child(1)") do - expect(page).to have_content(claim_2.school.name) - expect(page).to have_content(claim_2.reference) - expect(page).to have_content("Submitted") - expect(page).to have_content(claim_2.provider.name) - expect(page).to have_content(I18n.l(claim_2.created_at.to_date, format: :short)) - expect(page).to have_content(claim_2.amount.format(no_cents_if_whole: true)) + def then_i_see_a_list_of_submitted_claims(claims) + claims.each_with_index do |claim, index| + within(".claim-card:nth-child(#{index + 1})") do + expect(page).to have_content(claim.school.name) + expect(page).to have_content(claim.reference) + expect(page).to have_content("Submitted") + expect(page).to have_content(claim.provider.name) + expect(page).to have_content(I18n.l(claim.submitted_at.to_date, format: :short)) + expect(page).to have_content(claim.amount.format(no_cents_if_whole: true)) + end end + expect(claims.count).to eq(page.find_all(".claim-card").count) end def and_i_see_no_draft_claims expect(page).not_to have_content(claim_1.reference) end + + def when_i_check_school_filter(school) + page.find("#claims-support-claims-filter-form-school-ids-#{school.id}-field", visible: :all).check + click_on("Apply filters") + end + + def when_i_check_provider_filter(provider) + page.find("#claims-support-claims-filter-form-provider-ids-#{provider.id}-field", visible: :all).check + click_on("Apply filters") + end + + def when_i_set_submitted_after(day, month, year) + within_fieldset("Submitted after") do + fill_in("Day", with: day) + fill_in("Month", with: month) + fill_in("Year", with: year) + end + click_on("Apply filters") + end + + def when_i_set_submitted_before(day, month, year) + within_fieldset("Submitted before") do + fill_in("Day", with: day) + fill_in("Month", with: month) + fill_in("Year", with: year) + end + click_on("Apply filters") + end + + def when_i_search_for_claim_reference(reference) + fill_in("Search by claim reference", with: reference) + click_on("Search") + end + + def when_i_remove_my_search + fill_in("Search by claim reference", with: nil) + click_on("Search") + end + + def when_i_remove_the_filter(filter) + within(".app-filter-layout__selected") do + click_link(filter) + end + end + + def when_i_search_the_school_filer_with(school_name) + fill_in("School", with: school_name) + end + + def when_i_search_the_provider_filer_with(provider_name) + fill_in("Accredited prvoider", with: provider_name) + end + + def then_i_see_only_my_filter_school_as_an_option + my_selection = page.find("#claims-support-claims-filter-form-school-ids-#{school_2.id}-field", visible: :all) + expect(my_selection.present?).to eq(true) + + other_school_option = page.find_all("#claims-support-claims-filter-form-school-ids-#{school_1.id}-field") + expect(other_school_option.blank?).to eq(true) + end + + def then_i_see_my_search_school_filter_populated(school_name) + expect(page).to have_field("School", with: school_name) + end + + def then_i_see_my_search_provider_filter_populated(provider_name) + expect(page).to have_field("Accredited prvoider", with: provider_name) + end end