Browse Source
* add a button to the logs list to delete multiple logs style and position of button helpers for displaying the button conditionally depending on user role and what filters and search are active * correct indentation from 4 spaces to 2 in view file * test appearance of delete logs button on index page for lettings logs * write a happy path feature test for the entire journey * create basic tests for the view component for listing logs to delete * create request tests for the GET delete-logs path * create request tests for the GET delete-logs-confirmation path * create request tests for the DELETE delete-logs path * comprehensive reworking after code review ensure that we are not passing lists of ids through params in the query string, risking overflowing the maximum URL length, adjust tests accordingly, do not attempt to reuse the same table for sales and lettings * alter config to allow creating controllers from the command line with associated spec files that matches how we test * extract controller methods and associated tests to do with the delete logs feature into their own controller, amend routes accordingly * implement same work for sales as for lettings * implement the story for lettings and sales logs under the organisation tab routing and controller methods testing for deleting sales logs, lettings or sales logs for an organisation move storage of relevant routes inside the form object as a comprehensive view model * merge the delete pages for lettings logs and sales logs, add to the tests for the lettings page to test sales specific content * minor refactor to delete logs controller: ensure session filters are only fetched from teh session when needed and extract discard logs method to private method * extract tables for lettings and sales to own partials * refactor delete logs controller after tech review improve the private method that builds the form object so that it has the flexibility to do so for all controller methods ensure that the search term is passed to the delete logs controller when navigating through the organisations tab ensure that noly logs for that organisation are displayed when navigating to delete logs through the organisations tab * remove unnecessary untested arguments * test new helper methods * implement dirty fiddle to get the checkboxes smaller and also not misaligned * ensure delete logs button is always visible on log lists when in the organisations tab * minor linting corrections * revert change, causing errors and outside the scope of this ticket * simplify tests for whether delete logs button appears on index page * replicate request specs from lettings for sales and organisations controllers * minor refactor of lettings log feature spec setup, replicate happy path for sales * minor refactors after rebasing onto Nat's work * temp * write tests for the delete logs form object * lint: add new line at end of file * respond to PO feedback the log id in the delte logs table should be a link to the log the delete logs button should be visible when the user is in a bulk upload journey updated associated testspull/1705/head
Arthur Campbell
2 years ago
committed by
GitHub
31 changed files with 2115 additions and 228 deletions
@ -0,0 +1,196 @@
|
||||
class DeleteLogsController < ApplicationController |
||||
rescue_from ActiveRecord::RecordNotFound, with: :render_not_found |
||||
|
||||
before_action :session_filters, if: :current_user, except: %i[discard_lettings_logs discard_sales_logs discard_lettings_logs_for_organisation discard_sales_logs_for_organisation] |
||||
before_action :add_organisation_to_filters, only: %i[delete_lettings_logs_for_organisation delete_lettings_logs_for_organisation_with_selected_ids delete_lettings_logs_for_organisation_confirmation delete_sales_logs_for_organisation delete_sales_logs_for_organisation_with_selected_ids delete_sales_logs_for_organisation_confirmation] |
||||
|
||||
def delete_lettings_logs |
||||
@delete_logs_form = delete_logs_form(log_type: :lettings) |
||||
render "logs/delete_logs" |
||||
end |
||||
|
||||
def delete_lettings_logs_with_selected_ids |
||||
@delete_logs_form = delete_logs_form(log_type: :lettings, selected_ids:) |
||||
render "logs/delete_logs" |
||||
end |
||||
|
||||
def delete_lettings_logs_confirmation |
||||
@delete_logs_form = delete_logs_form(log_type: :lettings, form_params:) |
||||
if @delete_logs_form.valid? |
||||
render "logs/delete_logs_confirmation" |
||||
else |
||||
render "logs/delete_logs" |
||||
end |
||||
end |
||||
|
||||
def discard_lettings_logs |
||||
logs = LettingsLog.find(params.require(:ids)) |
||||
discard logs |
||||
|
||||
redirect_to lettings_logs_path, notice: I18n.t("notification.logs_deleted", count: logs.count) |
||||
end |
||||
|
||||
def delete_sales_logs |
||||
@delete_logs_form = delete_logs_form(log_type: :sales) |
||||
render "logs/delete_logs" |
||||
end |
||||
|
||||
def delete_sales_logs_with_selected_ids |
||||
@delete_logs_form = delete_logs_form(log_type: :sales, selected_ids:) |
||||
render "logs/delete_logs" |
||||
end |
||||
|
||||
def delete_sales_logs_confirmation |
||||
@delete_logs_form = delete_logs_form(log_type: :sales, form_params:) |
||||
if @delete_logs_form.valid? |
||||
render "logs/delete_logs_confirmation" |
||||
else |
||||
render "logs/delete_logs" |
||||
end |
||||
end |
||||
|
||||
def discard_sales_logs |
||||
logs = SalesLog.find(params.require(:ids)) |
||||
discard logs |
||||
|
||||
redirect_to sales_logs_path, notice: I18n.t("notification.logs_deleted", count: logs.count) |
||||
end |
||||
|
||||
def delete_lettings_logs_for_organisation |
||||
@delete_logs_form = delete_logs_form(log_type: :lettings, organisation: true) |
||||
render "logs/delete_logs" |
||||
end |
||||
|
||||
def delete_lettings_logs_for_organisation_with_selected_ids |
||||
@delete_logs_form = delete_logs_form(log_type: :lettings, organisation: true, selected_ids:) |
||||
render "logs/delete_logs" |
||||
end |
||||
|
||||
def delete_lettings_logs_for_organisation_confirmation |
||||
@delete_logs_form = delete_logs_form(log_type: :lettings, organisation: true, form_params:) |
||||
if @delete_logs_form.valid? |
||||
render "logs/delete_logs_confirmation" |
||||
else |
||||
render "logs/delete_logs" |
||||
end |
||||
end |
||||
|
||||
def discard_lettings_logs_for_organisation |
||||
logs = LettingsLog.where(owning_organisation: params[:id]).find(params.require(:ids)) |
||||
discard logs |
||||
|
||||
redirect_to lettings_logs_organisation_path, notice: I18n.t("notification.logs_deleted", count: logs.count) |
||||
end |
||||
|
||||
def delete_sales_logs_for_organisation |
||||
@delete_logs_form = delete_logs_form(log_type: :sales, organisation: true) |
||||
render "logs/delete_logs" |
||||
end |
||||
|
||||
def delete_sales_logs_for_organisation_with_selected_ids |
||||
@delete_logs_form = delete_logs_form(log_type: :sales, organisation: true, selected_ids:) |
||||
render "logs/delete_logs" |
||||
end |
||||
|
||||
def delete_sales_logs_for_organisation_confirmation |
||||
@delete_logs_form = delete_logs_form(log_type: :sales, organisation: true, form_params:) |
||||
if @delete_logs_form.valid? |
||||
render "logs/delete_logs_confirmation" |
||||
else |
||||
render "logs/delete_logs" |
||||
end |
||||
end |
||||
|
||||
def discard_sales_logs_for_organisation |
||||
logs = SalesLog.where(owning_organisation: params[:id]).find(params.require(:ids)) |
||||
discard logs |
||||
|
||||
redirect_to sales_logs_organisation_path, notice: I18n.t("notification.logs_deleted", count: logs.count) |
||||
end |
||||
|
||||
private |
||||
|
||||
def session_filters |
||||
@session_filters ||= filter_manager.session_filters |
||||
end |
||||
|
||||
def filter_manager |
||||
log_type = action_name.include?("lettings") ? "lettings_logs" : "sales_logs" |
||||
FilterManager.new(current_user:, session:, params:, filter_type: log_type) |
||||
end |
||||
|
||||
def delete_logs_form(log_type:, organisation: false, selected_ids: nil, form_params: {}) |
||||
paths = case log_type |
||||
when :lettings |
||||
organisation ? lettings_logs_for_organisation_paths : lettings_logs_paths |
||||
when :sales |
||||
organisation ? sales_logs_for_organisation_paths : sales_logs_paths |
||||
end |
||||
attributes = { |
||||
log_type:, |
||||
current_user:, |
||||
log_filters: @session_filters, |
||||
search_term:, |
||||
selected_ids:, |
||||
**paths, |
||||
}.merge(form_params).transform_keys(&:to_sym) |
||||
Forms::DeleteLogsForm.new(attributes) |
||||
end |
||||
|
||||
def form_params |
||||
form_attributes = params.require(:forms_delete_logs_form).permit(:search_term, selected_ids: []) |
||||
form_attributes[:selected_ids] = [] unless form_attributes.key? :selected_ids |
||||
form_attributes |
||||
end |
||||
|
||||
def lettings_logs_paths |
||||
{ |
||||
delete_confirmation_path: delete_logs_confirmation_lettings_logs_path, |
||||
back_to_logs_path: lettings_logs_path(search: search_term), |
||||
delete_path: delete_logs_lettings_logs_path, |
||||
} |
||||
end |
||||
|
||||
def sales_logs_paths |
||||
{ |
||||
delete_confirmation_path: delete_logs_confirmation_sales_logs_path, |
||||
back_to_logs_path: sales_logs_path(search: search_term), |
||||
delete_path: delete_logs_sales_logs_path, |
||||
} |
||||
end |
||||
|
||||
def lettings_logs_for_organisation_paths |
||||
{ |
||||
delete_confirmation_path: delete_lettings_logs_confirmation_organisation_path, |
||||
back_to_logs_path: lettings_logs_organisation_path(search: search_term), |
||||
delete_path: delete_lettings_logs_organisation_path, |
||||
} |
||||
end |
||||
|
||||
def sales_logs_for_organisation_paths |
||||
{ |
||||
delete_confirmation_path: delete_sales_logs_confirmation_organisation_path, |
||||
back_to_logs_path: sales_logs_organisation_path(search: search_term), |
||||
delete_path: delete_sales_logs_organisation_path, |
||||
} |
||||
end |
||||
|
||||
def add_organisation_to_filters |
||||
@session_filters[:organisation] = params[:id] |
||||
end |
||||
|
||||
def search_term |
||||
params["search"] |
||||
end |
||||
|
||||
def selected_ids |
||||
params.require(:selected_ids).split.map(&:to_i) |
||||
end |
||||
|
||||
def discard(logs) |
||||
logs.each do |log| |
||||
authorize log, :destroy? |
||||
log.discard! |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,5 @@
|
||||
.checkbox-cell { |
||||
.govuk-checkboxes__item { |
||||
margin-top: -7px; |
||||
} |
||||
} |
@ -0,0 +1,13 @@
|
||||
module LogListHelper |
||||
def display_delete_logs?(current_user, search_term, filter_type) |
||||
if current_user.data_provider? |
||||
filter_selected?("user", "yours", filter_type) |
||||
else |
||||
any_filter_selected?(filter_type) || search_term.present? |
||||
end |
||||
end |
||||
|
||||
def in_organisations_tab? |
||||
controller.class.name.start_with? "Organisation" |
||||
end |
||||
end |
@ -0,0 +1,44 @@
|
||||
module Forms |
||||
class DeleteLogsForm |
||||
include ActiveModel::Model |
||||
include ActiveModel::Validations |
||||
|
||||
attr_reader :logs, :log_type, :selected_ids, :search_term, :delete_confirmation_path, :back_to_logs_path, :delete_path |
||||
|
||||
validate :at_least_one_log_selected |
||||
|
||||
def initialize(attributes) |
||||
@log_type = attributes[:log_type] |
||||
@search_term = attributes[:search_term] |
||||
@current_user = attributes[:current_user] |
||||
@logs = FilterManager.filter_logs(visible_logs, @search_term, attributes[:log_filters], nil, @current_user) |
||||
@selected_ids = attributes[:selected_ids] || @logs.map(&:id) |
||||
@delete_confirmation_path = attributes[:delete_confirmation_path] |
||||
@back_to_logs_path = attributes[:back_to_logs_path] |
||||
@delete_path = attributes[:delete_path] |
||||
end |
||||
|
||||
def log_count |
||||
@logs.count |
||||
end |
||||
|
||||
def table_partial_name |
||||
"logs/delete_logs_table_#{@log_type}" |
||||
end |
||||
|
||||
private |
||||
|
||||
def at_least_one_log_selected |
||||
if selected_ids.blank? || selected_ids.reject(&:blank?).blank? |
||||
errors.add(:log_ids, "Select at least one log to delete or press cancel to return") |
||||
end |
||||
end |
||||
|
||||
def visible_logs |
||||
case @log_type |
||||
when :lettings then @current_user.lettings_logs.visible |
||||
when :sales then @current_user.sales_logs.visible |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,30 @@
|
||||
<%= govuk_table do |table| %> |
||||
<% table.head do |head| %> |
||||
<% head.row do |row| %> |
||||
<% row.cell header: true, text: "Log ID" %> |
||||
<% row.cell header: true, text: "Tenancy code" %> |
||||
<% row.cell header: true, text: "Property reference" %> |
||||
<% row.cell header: true, text: "Status" %> |
||||
<% row.cell header: true, text: "Delete?" %> |
||||
<% end %> |
||||
<% end %> |
||||
<% table.body do |body| %> |
||||
<% f.govuk_check_boxes_fieldset :selected_ids, small: true do %> |
||||
<% delete_logs_form.logs.each do |log| %> |
||||
<% body.row do |row| %> |
||||
<% row.cell do %> |
||||
<%= govuk_link_to log.id, url_for(log) %> |
||||
<% end %> |
||||
<% row.cell text: log.tenancycode %> |
||||
<% row.cell text: log.propcode %> |
||||
<% row.cell text: status_tag(log.status) %> |
||||
<% row.cell html_attributes: { class: "checkbox-cell" } do %> |
||||
<% f.govuk_check_box :selected_ids, log.id, |
||||
label: { text: log.id, hidden: true }, |
||||
checked: delete_logs_form.selected_ids.include?(log.id) %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
@ -0,0 +1,30 @@
|
||||
<%= govuk_table do |table| %> |
||||
<% table.head do |head| %> |
||||
<% head.row do |row| %> |
||||
<% row.cell header: true, text: "Log ID" %> |
||||
<% row.cell header: true, text: "Purchaser code" %> |
||||
<% row.cell header: true, text: "Sale completion date" %> |
||||
<% row.cell header: true, text: "Status" %> |
||||
<% row.cell header: true, text: "Delete?" %> |
||||
<% end %> |
||||
<% end %> |
||||
<% table.body do |body| %> |
||||
<% f.govuk_check_boxes_fieldset :selected_ids, small: true do %> |
||||
<% delete_logs_form.logs.each do |log| %> |
||||
<% body.row do |row| %> |
||||
<% row.cell do %> |
||||
<%= govuk_link_to log.id, url_for(log) %> |
||||
<% end %> |
||||
<% row.cell text: log.purchid %> |
||||
<% row.cell text: log.saledate&.to_formatted_s(:govuk_date) %> |
||||
<% row.cell text: status_tag(log.status) %> |
||||
<% row.cell html_attributes: { class: "checkbox-cell" } do %> |
||||
<% f.govuk_check_box :selected_ids, log.id, |
||||
label: { text: log.id, hidden: true }, |
||||
checked: delete_logs_form.selected_ids.include?(log.id) %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
@ -0,0 +1,22 @@
|
||||
<% title = "Delete logs" %> |
||||
<% content_for :title, title %> |
||||
<% content_for :before_content do %> |
||||
<%= govuk_back_link(href: :back) %> |
||||
<% end %> |
||||
|
||||
<h1 class="govuk-heading-l"> |
||||
<span class="govuk-caption-l"><%= title %></span> |
||||
Review the logs you want to delete |
||||
</h1> |
||||
<p>You've selected <%= @delete_logs_form.log_count %> <%= "log".pluralize(@delete_logs_form.log_count) %> to delete</p> |
||||
|
||||
<div class="govuk-checkboxes govuk-checkboxes--small"> |
||||
<%= form_with model: @delete_logs_form, url: @delete_logs_form.delete_confirmation_path do |f| %> |
||||
<%= f.hidden_field :search_term, value: @delete_logs_form.search_term %> |
||||
<%= f.govuk_error_summary %> |
||||
<%= render partial: @delete_logs_form.table_partial_name, locals: { f:, delete_logs_form: @delete_logs_form } %> |
||||
<%= f.govuk_submit "Continue" do %> |
||||
<%= govuk_button_link_to "Cancel", @delete_logs_form.back_to_logs_path, secondary: true %> |
||||
<% end %> |
||||
<% end %> |
||||
</div> |
@ -0,0 +1,25 @@
|
||||
<% title = "Delete logs" %> |
||||
<% content_for :title, title %> |
||||
<% content_for :before_content do %> |
||||
<%= govuk_back_link(href: :back) %> |
||||
<% end %> |
||||
|
||||
<h1 class="govuk-heading-l"> |
||||
<span class="govuk-caption-l"><%= title %></span> |
||||
Are you sure you want to delete these logs? |
||||
</h1> |
||||
<% log_count = @delete_logs_form.selected_ids.count %> |
||||
<p>You've selected <%= log_count %> <%= "log".pluralize(log_count) %> to delete</p> |
||||
|
||||
<%= govuk_warning_text(icon_fallback_text: "Danger") do %> |
||||
You will not be able to undo this action |
||||
<% end %> |
||||
|
||||
<div class="govuk-button-group"> |
||||
<%= govuk_button_to "Delete logs", @delete_logs_form.delete_path, method: "delete", params: { ids: @delete_logs_form.selected_ids } %> |
||||
<%= form_with url: @delete_logs_form.delete_path do |f| %> |
||||
<%= f.hidden_field :selected_ids, value: @delete_logs_form.selected_ids %> |
||||
<%= f.hidden_field :search, value: @delete_logs_form.search_term %> |
||||
<%= f.govuk_submit "Cancel", secondary: true %> |
||||
<% end %> |
||||
</div> |
@ -0,0 +1,72 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe LogListHelper, type: :helper do |
||||
include FiltersHelper |
||||
|
||||
describe "#display_delete_logs?" do |
||||
let(:search_term) { nil } |
||||
let(:filter_type) { "lettings_logs" } |
||||
|
||||
context "when logged in as a data provider" do |
||||
let(:result) { display_delete_logs?(user, search_term, filter_type) } |
||||
let(:user) { create(:user) } |
||||
|
||||
it "returns false if no filters or search are set" do |
||||
allow(self).to receive(:filter_selected?).and_return false |
||||
expect(result).to be false |
||||
end |
||||
|
||||
it "returns true if the user filter is set to 'yours'" do |
||||
allow(self).to receive(:filter_selected?).with("user", "yours", filter_type).and_return true |
||||
expect(result).to be true |
||||
end |
||||
|
||||
it "returns false if any filters other than the user filter are set" do |
||||
allow(self).to receive(:filter_selected?).and_return true |
||||
allow(self).to receive(:filter_selected?).with("user", "yours", filter_type).and_return false |
||||
expect(result).to be false |
||||
end |
||||
|
||||
context "when there is a search term present" do |
||||
let(:search_term) { "word" } |
||||
|
||||
it "still returns false as long as the user filter is not set to yours" do |
||||
allow(self).to receive(:filter_selected?).with("user", "yours", filter_type).and_return false |
||||
expect(result).to be false |
||||
end |
||||
end |
||||
end |
||||
|
||||
context "when logged in as a support user or data coordinator" do |
||||
let(:support_user) { create(:user, :support) } |
||||
let(:data_coordinator) { create(:user, :data_coordinator) } |
||||
let(:support_result) { display_delete_logs?(support_user, search_term, filter_type) } |
||||
let(:coordinator_result) { display_delete_logs?(data_coordinator, search_term, filter_type) } |
||||
let(:results) { [support_result, coordinator_result] } |
||||
|
||||
it "returns false if no filters or search are set" do |
||||
allow(self).to receive(:any_filter_selected?).and_return false |
||||
expect(results).to all be false |
||||
end |
||||
|
||||
it "returns true if any filter is set" do |
||||
allow(self).to receive(:any_filter_selected?).and_return true |
||||
expect(results).to all be true |
||||
end |
||||
|
||||
context "when there is a search term present" do |
||||
let(:search_term) { "word" } |
||||
|
||||
it "returns true if no filter is selected" do |
||||
allow(self).to receive(:any_filter_selected?).and_return false |
||||
expect(results).to all be true |
||||
end |
||||
|
||||
it "returns true if any filter is selected" do |
||||
allow(self).to receive(:any_filter_selected?).and_return true |
||||
expect(results).to all be true |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,89 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe Forms::DeleteLogsForm do |
||||
let(:delete_logs_form) { described_class.new(attributes) } |
||||
|
||||
let(:attributes) do |
||||
{ |
||||
log_type:, |
||||
search_term:, |
||||
current_user:, |
||||
log_filters:, |
||||
selected_ids:, |
||||
delete_confirmation_path:, |
||||
back_to_logs_path:, |
||||
delete_path:, |
||||
} |
||||
end |
||||
let(:log_type) { :lettings } |
||||
let(:search_term) { "meaning" } |
||||
let(:current_user) { create(:user) } |
||||
let(:log_filters) do |
||||
{ |
||||
"years" => [""], |
||||
"status" => ["", "completed"], |
||||
"user" => "yours", |
||||
} |
||||
end |
||||
let(:selected_ids) { [visible_logs.first.id] } |
||||
let(:delete_confirmation_path) { "/lettings-logs/delete-logs-confirmation" } |
||||
let(:back_to_logs_path) { "/lettings-logs?search=meaning" } |
||||
let(:delete_path) { "/lettings-logs/delete-logs" } |
||||
|
||||
let(:visible_logs) { create_list(:lettings_log, 3, created_by: current_user) } |
||||
|
||||
before do |
||||
allow(FilterManager).to receive(:filter_logs).and_return visible_logs |
||||
end |
||||
|
||||
it "exposes the log type" do |
||||
expect(delete_logs_form.log_type).to be log_type |
||||
end |
||||
|
||||
it "exposes the search term" do |
||||
expect(delete_logs_form.search_term).to be search_term |
||||
end |
||||
|
||||
it "exposes the paths" do |
||||
expect(delete_logs_form.delete_confirmation_path).to be delete_confirmation_path |
||||
expect(delete_logs_form.back_to_logs_path).to be back_to_logs_path |
||||
expect(delete_logs_form.delete_path).to be delete_path |
||||
end |
||||
|
||||
it "exposes the logs returned by the filter manager" do |
||||
expect(delete_logs_form.logs).to be visible_logs |
||||
end |
||||
|
||||
it "exposes the selected ids" do |
||||
expect(delete_logs_form.selected_ids).to be selected_ids |
||||
end |
||||
|
||||
context "when selected ids are not provided to the initializer" do |
||||
let(:selected_ids) { nil } |
||||
|
||||
it "sets the selected ids to be all logs" do |
||||
expect(delete_logs_form.selected_ids).to match_array visible_logs.map(&:id) |
||||
end |
||||
end |
||||
|
||||
it "calls the filter manager with the correct arguments" do |
||||
create(:lettings_log) |
||||
|
||||
expect(FilterManager).to receive(:filter_logs) { |arg1, arg2, arg3, arg4, arg5| |
||||
expect(arg1).to contain_exactly(*visible_logs) |
||||
expect(arg2).to eq search_term |
||||
expect(arg3).to eq log_filters |
||||
expect(arg4).to be nil |
||||
expect(arg5).to be current_user |
||||
}.and_return visible_logs |
||||
delete_logs_form |
||||
end |
||||
|
||||
it "exposes the number of logs" do |
||||
expect(delete_logs_form.log_count).to be visible_logs.count |
||||
end |
||||
|
||||
it "provides the name of the table partial relevant to the log type" do |
||||
expect(delete_logs_form.table_partial_name).to eq "logs/delete_logs_table_lettings" |
||||
end |
||||
end |
@ -0,0 +1,946 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe "DeleteLogs", type: :request do |
||||
let(:page) { Capybara::Node::Simple.new(response.body) } |
||||
let(:user) { create(:user, name: "Richard MacDuff") } |
||||
|
||||
before do |
||||
allow(user).to receive(:need_two_factor_authentication?).and_return(false) |
||||
sign_in user |
||||
end |
||||
|
||||
describe "GET lettings-logs/delete-logs" do |
||||
let!(:log_1) { create(:lettings_log, :in_progress, created_by: user) } |
||||
let!(:log_2) { create(:lettings_log, :completed, created_by: user) } |
||||
|
||||
before do |
||||
allow(FilterManager).to receive(:filter_logs).and_return LettingsLog.all |
||||
end |
||||
|
||||
it "calls the filter service with the filters in the session and the search term from the query params" do |
||||
search = "Schrödinger's cat" |
||||
logs_filters = { |
||||
"years" => [""], |
||||
"status" => ["", "in_progress"], |
||||
"user" => "all", |
||||
} |
||||
get lettings_logs_path(logs_filters) # adds the filters to the session |
||||
|
||||
expect(FilterManager).to receive(:filter_logs) { |arg1, arg2, arg3| |
||||
expect(arg1).to contain_exactly(log_1, log_2) |
||||
expect(arg2).to eq search |
||||
expect(arg3).to eq logs_filters |
||||
}.and_return LettingsLog.all |
||||
|
||||
get delete_logs_lettings_logs_path(search:) |
||||
end |
||||
|
||||
it "displays the logs returned by the filter service" do |
||||
get delete_logs_lettings_logs_path |
||||
|
||||
table_body_rows = page.find_all("tbody tr") |
||||
expect(table_body_rows.count).to be 2 |
||||
ids_in_table = table_body_rows.map { |row| row.first("td").text.strip } |
||||
expect(ids_in_table).to match_array [log_1.id.to_s, log_2.id.to_s] |
||||
end |
||||
|
||||
it "checks all checkboxes by default" do |
||||
get delete_logs_lettings_logs_path |
||||
|
||||
checkboxes = page.find_all("tbody tr").map { |row| row.find("input") } |
||||
expect(checkboxes.count).to be 2 |
||||
expect(checkboxes).to all be_checked |
||||
end |
||||
end |
||||
|
||||
describe "POST lettings-logs/delete-logs" do |
||||
let!(:log_1) { create(:lettings_log, :in_progress, created_by: user) } |
||||
let!(:log_2) { create(:lettings_log, :completed, created_by: user) } |
||||
let(:selected_ids) { log_1.id } |
||||
|
||||
before do |
||||
allow(FilterManager).to receive(:filter_logs).and_return LettingsLog.all |
||||
end |
||||
|
||||
it "throws an error if selected ids are not provided" do |
||||
expect { post delete_logs_lettings_logs_path }.to raise_error ActionController::ParameterMissing |
||||
end |
||||
|
||||
it "calls the filter service with the filters in the session and the search term from the query params" do |
||||
search = "Schrödinger's cat" |
||||
logs_filters = { |
||||
"years" => [""], |
||||
"status" => ["", "in_progress"], |
||||
"user" => "all", |
||||
} |
||||
get lettings_logs_path(logs_filters) # adds the filters to the session |
||||
|
||||
expect(FilterManager).to receive(:filter_logs) { |arg1, arg2, arg3| |
||||
expect(arg1).to contain_exactly(log_1, log_2) |
||||
expect(arg2).to eq search |
||||
expect(arg3).to eq logs_filters |
||||
}.and_return LettingsLog.all |
||||
|
||||
post delete_logs_lettings_logs_path(search:, selected_ids:) |
||||
end |
||||
|
||||
it "displays the logs returned by the filter service" do |
||||
post delete_logs_lettings_logs_path(selected_ids:) |
||||
|
||||
table_body_rows = page.find_all("tbody tr") |
||||
expect(table_body_rows.count).to be 2 |
||||
ids_in_table = table_body_rows.map { |row| row.first("td").text.strip } |
||||
expect(ids_in_table).to match_array [log_1.id.to_s, log_2.id.to_s] |
||||
end |
||||
|
||||
it "only checks the selected checkboxes when selected_ids provided" do |
||||
post delete_logs_lettings_logs_path(selected_ids:) |
||||
|
||||
checkboxes = page.find_all("tbody tr").map { |row| row.find("input") } |
||||
checkbox_expected_checked = checkboxes.find { |cb| cb.value == log_1.id.to_s } |
||||
checkbox_expected_unchecked = checkboxes.find { |cb| cb.value == log_2.id.to_s } |
||||
expect(checkbox_expected_checked).to be_checked |
||||
expect(checkbox_expected_unchecked).not_to be_checked |
||||
end |
||||
end |
||||
|
||||
describe "POST lettings-logs/delete-logs-confirmation" do |
||||
let(:log_1) { create(:lettings_log, :in_progress) } |
||||
let(:log_2) { create(:lettings_log, :completed) } |
||||
let(:log_3) { create(:lettings_log, :in_progress) } |
||||
let(:params) do |
||||
{ |
||||
forms_delete_logs_form: { |
||||
search_term: "milk", |
||||
selected_ids: [log_1, log_2].map(&:id), |
||||
}, |
||||
} |
||||
end |
||||
|
||||
before do |
||||
post delete_logs_confirmation_lettings_logs_path, params: params |
||||
end |
||||
|
||||
it "requires delete logs form data to be provided" do |
||||
expect { post delete_logs_confirmation_lettings_logs_path }.to raise_error(ActionController::ParameterMissing) |
||||
end |
||||
|
||||
it "shows the correct title" do |
||||
expect(page.find("h1").text).to include "Are you sure you want to delete these logs?" |
||||
end |
||||
|
||||
it "shows the correct information text to the user" do |
||||
expect(page).to have_selector("p", text: "You've selected 2 logs to delete") |
||||
end |
||||
|
||||
context "when only one log is selected" do |
||||
let(:params) do |
||||
{ |
||||
forms_delete_logs_form: { |
||||
search_term: "milk", |
||||
selected_ids: [log_1].map(&:id), |
||||
}, |
||||
} |
||||
end |
||||
|
||||
it "shows the correct information text to the user in the singular" do |
||||
expect(page).to have_selector("p", text: "You've selected 1 log to delete") |
||||
end |
||||
end |
||||
|
||||
it "shows a warning to the user" do |
||||
expect(page).to have_selector(".govuk-warning-text", text: "You will not be able to undo this action") |
||||
end |
||||
|
||||
it "shows a button to delete the selected logs" do |
||||
expect(page).to have_selector("form.button_to button", text: "Delete logs") |
||||
end |
||||
|
||||
it "the delete logs button submits the correct data to the correct path" do |
||||
form_containing_button = page.find("form.button_to") |
||||
|
||||
expect(form_containing_button[:action]).to eq delete_logs_lettings_logs_path |
||||
expect(form_containing_button).to have_field "_method", type: :hidden, with: "delete" |
||||
expect(form_containing_button).to have_field "ids[]", type: :hidden, with: log_1.id |
||||
expect(form_containing_button).to have_field "ids[]", type: :hidden, with: log_2.id |
||||
end |
||||
|
||||
it "shows a cancel button with the correct style" do |
||||
expect(page).to have_selector("button.govuk-button--secondary", text: "Cancel") |
||||
end |
||||
|
||||
it "the cancel button submits the correct data to the correct path" do |
||||
form_containing_cancel = page.find_all("form").find { |form| form.has_selector?("button.govuk-button--secondary") } |
||||
expect(form_containing_cancel).to have_field("selected_ids", type: :hidden, with: [log_1, log_2].map(&:id).join(" ")) |
||||
expect(form_containing_cancel).to have_field("search", type: :hidden, with: "milk") |
||||
expect(form_containing_cancel[:method]).to eq "post" |
||||
expect(form_containing_cancel[:action]).to eq delete_logs_lettings_logs_path |
||||
end |
||||
|
||||
context "when no logs are selected" do |
||||
let(:params) do |
||||
{ |
||||
forms_delete_logs_form: { |
||||
log_type: :lettings, |
||||
log_ids: [log_1, log_2, log_3].map(&:id).join(" "), |
||||
}, |
||||
} |
||||
end |
||||
|
||||
before do |
||||
post delete_logs_confirmation_lettings_logs_path, params: params |
||||
end |
||||
|
||||
it "renders the list of logs table again" do |
||||
expect(page.find("h1").text).to include "Review the logs you want to delete" |
||||
end |
||||
|
||||
it "displays an error message" do |
||||
expect(page).to have_selector(".govuk-error-summary", text: "Select at least one log to delete or press cancel to return") |
||||
end |
||||
|
||||
it "renders the table with all checkboxes unchecked" do |
||||
checkboxes = page.find_all("tbody tr").map { |row| row.find("input") } |
||||
checkboxes.each do |checkbox| |
||||
expect(checkbox).not_to be_checked |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe "DELETE lettings-logs/delete-logs" do |
||||
let(:log_1) { create(:lettings_log, :in_progress, created_by: user) } |
||||
let(:params) { { ids: [log_1.id, log_2.id] } } |
||||
|
||||
context "when the user is authorized to delete the logs provided" do |
||||
let(:log_2) { create(:lettings_log, :completed, created_by: user) } |
||||
|
||||
it "deletes the logs provided" do |
||||
delete delete_logs_lettings_logs_path, params: params |
||||
log_1.reload |
||||
expect(log_1.status).to eq "deleted" |
||||
expect(log_1.discarded_at).not_to be nil |
||||
log_2.reload |
||||
expect(log_2.status).to eq "deleted" |
||||
expect(log_2.discarded_at).not_to be nil |
||||
end |
||||
|
||||
it "redirects to the lettings log index and displays a notice that the logs have been deleted" do |
||||
delete delete_logs_lettings_logs_path, params: params |
||||
expect(response).to redirect_to lettings_logs_path |
||||
follow_redirect! |
||||
expect(page).to have_selector(".govuk-notification-banner--success") |
||||
expect(page).to have_selector(".govuk-notification-banner--success", text: "2 logs have been deleted") |
||||
end |
||||
end |
||||
|
||||
context "when the user is not authorized to delete all the logs provided" do |
||||
let(:log_2) { create(:lettings_log, :completed) } |
||||
|
||||
it "returns unauthorised and only deletes logs for which the user is authorised" do |
||||
delete delete_logs_lettings_logs_path, params: params |
||||
expect(response).to have_http_status(:unauthorized) |
||||
log_1.reload |
||||
expect(log_1.status).to eq "deleted" |
||||
expect(log_1.discarded_at).not_to be nil |
||||
log_2.reload |
||||
expect(log_2.discarded_at).to be nil |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe "GET sales-logs/delete-logs" do |
||||
let!(:log_1) { create(:sales_log, :in_progress, created_by: user) } |
||||
let!(:log_2) { create(:sales_log, :completed, created_by: user) } |
||||
|
||||
before do |
||||
allow(FilterManager).to receive(:filter_logs).and_return SalesLog.all |
||||
end |
||||
|
||||
it "calls the filter service with the filters in the session and the search term from the query params" do |
||||
search = "Schrödinger's cat" |
||||
logs_filters = { |
||||
"years" => [""], |
||||
"status" => ["", "in_progress"], |
||||
"user" => "all", |
||||
} |
||||
get sales_logs_path(logs_filters) # adds the filters to the session |
||||
|
||||
expect(FilterManager).to receive(:filter_logs) { |arg1, arg2, arg3| |
||||
expect(arg1).to contain_exactly(log_1, log_2) |
||||
expect(arg2).to eq search |
||||
expect(arg3).to eq logs_filters |
||||
}.and_return SalesLog.all |
||||
|
||||
get delete_logs_sales_logs_path(search:) |
||||
end |
||||
|
||||
it "displays the logs returned by the filter service" do |
||||
get delete_logs_sales_logs_path |
||||
|
||||
table_body_rows = page.find_all("tbody tr") |
||||
expect(table_body_rows.count).to be 2 |
||||
ids_in_table = table_body_rows.map { |row| row.first("td").text.strip } |
||||
expect(ids_in_table).to match_array [log_1.id.to_s, log_2.id.to_s] |
||||
end |
||||
|
||||
it "checks all checkboxes by default" do |
||||
get delete_logs_sales_logs_path |
||||
|
||||
checkboxes = page.find_all("tbody tr").map { |row| row.find("input") } |
||||
expect(checkboxes.count).to be 2 |
||||
expect(checkboxes).to all be_checked |
||||
end |
||||
end |
||||
|
||||
describe "POST sales-logs/delete-logs" do |
||||
let!(:log_1) { create(:sales_log, :in_progress, created_by: user) } |
||||
let!(:log_2) { create(:sales_log, :completed, created_by: user) } |
||||
let(:selected_ids) { log_1.id } |
||||
|
||||
before do |
||||
allow(FilterManager).to receive(:filter_logs).and_return SalesLog.all |
||||
end |
||||
|
||||
it "throws an error if selected ids are not provided" do |
||||
expect { post delete_logs_sales_logs_path }.to raise_error ActionController::ParameterMissing |
||||
end |
||||
|
||||
it "calls the filter service with the filters in the session and the search term from the query params" do |
||||
search = "Schrödinger's cat" |
||||
logs_filters = { |
||||
"years" => [""], |
||||
"status" => ["", "in_progress"], |
||||
"user" => "all", |
||||
} |
||||
get sales_logs_path(logs_filters) # adds the filters to the session |
||||
|
||||
expect(FilterManager).to receive(:filter_logs) { |arg1, arg2, arg3| |
||||
expect(arg1).to contain_exactly(log_1, log_2) |
||||
expect(arg2).to eq search |
||||
expect(arg3).to eq logs_filters |
||||
}.and_return SalesLog.all |
||||
|
||||
post delete_logs_sales_logs_path(search:, selected_ids:) |
||||
end |
||||
|
||||
it "displays the logs returned by the filter service" do |
||||
post delete_logs_sales_logs_path(selected_ids:) |
||||
|
||||
table_body_rows = page.find_all("tbody tr") |
||||
expect(table_body_rows.count).to be 2 |
||||
ids_in_table = table_body_rows.map { |row| row.first("td").text.strip } |
||||
expect(ids_in_table).to match_array [log_1.id.to_s, log_2.id.to_s] |
||||
end |
||||
|
||||
it "only checks the selected checkboxes when selected_ids provided" do |
||||
post delete_logs_sales_logs_path(selected_ids:) |
||||
|
||||
checkboxes = page.find_all("tbody tr").map { |row| row.find("input") } |
||||
checkbox_expected_checked = checkboxes.find { |cb| cb.value == log_1.id.to_s } |
||||
checkbox_expected_unchecked = checkboxes.find { |cb| cb.value == log_2.id.to_s } |
||||
expect(checkbox_expected_checked).to be_checked |
||||
expect(checkbox_expected_unchecked).not_to be_checked |
||||
end |
||||
end |
||||
|
||||
describe "POST sales-logs/delete-logs-confirmation" do |
||||
let(:log_1) { create(:sales_log, :in_progress) } |
||||
let(:log_2) { create(:sales_log, :completed) } |
||||
let(:log_3) { create(:sales_log, :in_progress) } |
||||
let(:params) do |
||||
{ |
||||
forms_delete_logs_form: { |
||||
search_term: "milk", |
||||
selected_ids: [log_1, log_2].map(&:id), |
||||
}, |
||||
} |
||||
end |
||||
|
||||
before do |
||||
post delete_logs_confirmation_sales_logs_path, params: params |
||||
end |
||||
|
||||
it "requires delete logs form data to be provided" do |
||||
expect { post delete_logs_confirmation_sales_logs_path }.to raise_error(ActionController::ParameterMissing) |
||||
end |
||||
|
||||
it "shows the correct title" do |
||||
expect(page.find("h1").text).to include "Are you sure you want to delete these logs?" |
||||
end |
||||
|
||||
it "shows the correct information text to the user" do |
||||
expect(page).to have_selector("p", text: "You've selected 2 logs to delete") |
||||
end |
||||
|
||||
context "when only one log is selected" do |
||||
let(:params) do |
||||
{ |
||||
forms_delete_logs_form: { |
||||
search_term: "milk", |
||||
selected_ids: [log_1].map(&:id), |
||||
}, |
||||
} |
||||
end |
||||
|
||||
it "shows the correct information text to the user in the singular" do |
||||
expect(page).to have_selector("p", text: "You've selected 1 log to delete") |
||||
end |
||||
end |
||||
|
||||
it "shows a warning to the user" do |
||||
expect(page).to have_selector(".govuk-warning-text", text: "You will not be able to undo this action") |
||||
end |
||||
|
||||
it "shows a button to delete the selected logs" do |
||||
expect(page).to have_selector("form.button_to button", text: "Delete logs") |
||||
end |
||||
|
||||
it "the delete logs button submits the correct data to the correct path" do |
||||
form_containing_button = page.find("form.button_to") |
||||
|
||||
expect(form_containing_button[:action]).to eq delete_logs_sales_logs_path |
||||
expect(form_containing_button).to have_field "_method", type: :hidden, with: "delete" |
||||
expect(form_containing_button).to have_field "ids[]", type: :hidden, with: log_1.id |
||||
expect(form_containing_button).to have_field "ids[]", type: :hidden, with: log_2.id |
||||
end |
||||
|
||||
it "shows a cancel button with the correct style" do |
||||
expect(page).to have_selector("button.govuk-button--secondary", text: "Cancel") |
||||
end |
||||
|
||||
it "the cancel button submits the correct data to the correct path" do |
||||
form_containing_cancel = page.find_all("form").find { |form| form.has_selector?("button.govuk-button--secondary") } |
||||
expect(form_containing_cancel).to have_field("selected_ids", type: :hidden, with: [log_1, log_2].map(&:id).join(" ")) |
||||
expect(form_containing_cancel).to have_field("search", type: :hidden, with: "milk") |
||||
expect(form_containing_cancel[:method]).to eq "post" |
||||
expect(form_containing_cancel[:action]).to eq delete_logs_sales_logs_path |
||||
end |
||||
|
||||
context "when no logs are selected" do |
||||
let(:params) do |
||||
{ |
||||
forms_delete_logs_form: { |
||||
log_type: :sales, |
||||
log_ids: [log_1, log_2, log_3].map(&:id).join(" "), |
||||
}, |
||||
} |
||||
end |
||||
|
||||
before do |
||||
post delete_logs_confirmation_sales_logs_path, params: params |
||||
end |
||||
|
||||
it "renders the list of logs table again" do |
||||
expect(page.find("h1").text).to include "Review the logs you want to delete" |
||||
end |
||||
|
||||
it "displays an error message" do |
||||
expect(page).to have_selector(".govuk-error-summary", text: "Select at least one log to delete or press cancel to return") |
||||
end |
||||
|
||||
it "renders the table with all checkboxes unchecked" do |
||||
checkboxes = page.find_all("tbody tr").map { |row| row.find("input") } |
||||
checkboxes.each do |checkbox| |
||||
expect(checkbox).not_to be_checked |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe "DELETE sales-logs/delete-logs" do |
||||
let(:log_1) { create(:sales_log, :in_progress, created_by: user) } |
||||
let(:params) { { ids: [log_1.id, log_2.id] } } |
||||
|
||||
context "when the user is authorized to delete the logs provided" do |
||||
let(:log_2) { create(:sales_log, :completed, created_by: user) } |
||||
|
||||
it "deletes the logs provided" do |
||||
delete delete_logs_sales_logs_path, params: params |
||||
log_1.reload |
||||
expect(log_1.status).to eq "deleted" |
||||
expect(log_1.discarded_at).not_to be nil |
||||
log_2.reload |
||||
expect(log_2.status).to eq "deleted" |
||||
expect(log_2.discarded_at).not_to be nil |
||||
end |
||||
|
||||
it "redirects to the sales log index and displays a notice that the logs have been deleted" do |
||||
delete delete_logs_sales_logs_path, params: params |
||||
expect(response).to redirect_to sales_logs_path |
||||
follow_redirect! |
||||
expect(page).to have_selector(".govuk-notification-banner--success") |
||||
expect(page).to have_selector(".govuk-notification-banner--success", text: "2 logs have been deleted") |
||||
end |
||||
end |
||||
|
||||
context "when the user is not authorized to delete all the logs provided" do |
||||
let(:log_2) { create(:sales_log, :completed) } |
||||
|
||||
it "returns unauthorised and only deletes logs for which the user is authorised" do |
||||
delete delete_logs_sales_logs_path, params: params |
||||
expect(response).to have_http_status(:unauthorized) |
||||
log_1.reload |
||||
expect(log_1.status).to eq "deleted" |
||||
expect(log_1.discarded_at).not_to be nil |
||||
log_2.reload |
||||
expect(log_2.discarded_at).to be nil |
||||
end |
||||
end |
||||
end |
||||
|
||||
context "when a support user navigates to the organisations tab" do |
||||
let(:organisation) { create(:organisation, name: "Schmorganisation") } |
||||
let(:user) { create(:user, :support, name: "Urban Chronotis") } |
||||
|
||||
describe "GET organisations/delete-lettings-logs" do |
||||
let!(:log_1) { create(:lettings_log, :in_progress, owning_organisation: organisation) } |
||||
let!(:log_2) { create(:lettings_log, :completed, owning_organisation: organisation) } |
||||
|
||||
before do |
||||
allow(FilterManager).to receive(:filter_logs).and_return LettingsLog.all |
||||
end |
||||
|
||||
it "calls the filter service with the filters in the session and the search term from the query params" do |
||||
search = "Schrödinger's cat" |
||||
logs_filters = { |
||||
"years" => [""], |
||||
"status" => ["", "in_progress"], |
||||
"user" => "all", |
||||
} |
||||
get lettings_logs_path(logs_filters) # adds the filters to the session |
||||
|
||||
expect(FilterManager).to receive(:filter_logs) { |arg1, arg2, arg3| |
||||
expect(arg1).to contain_exactly(log_1, log_2) |
||||
expect(arg2).to eq search |
||||
expect(arg3).to eq logs_filters.merge(organisation: organisation.id.to_s) |
||||
}.and_return LettingsLog.all |
||||
|
||||
get delete_lettings_logs_organisation_path(id: organisation, search:) |
||||
end |
||||
|
||||
it "displays the logs returned by the filter service" do |
||||
get delete_lettings_logs_organisation_path(id: organisation) |
||||
|
||||
table_body_rows = page.find_all("tbody tr") |
||||
expect(table_body_rows.count).to be 2 |
||||
ids_in_table = table_body_rows.map { |row| row.first("td").text.strip } |
||||
expect(ids_in_table).to match_array [log_1.id.to_s, log_2.id.to_s] |
||||
end |
||||
|
||||
it "checks all checkboxes by default" do |
||||
get delete_lettings_logs_organisation_path(id: organisation) |
||||
|
||||
checkboxes = page.find_all("tbody tr").map { |row| row.find("input") } |
||||
expect(checkboxes.count).to be 2 |
||||
expect(checkboxes).to all be_checked |
||||
end |
||||
end |
||||
|
||||
describe "POST organisations/delete-lettings-logs" do |
||||
let!(:log_1) { create(:lettings_log, :in_progress, owning_organisation: organisation) } |
||||
let!(:log_2) { create(:lettings_log, :completed, owning_organisation: organisation) } |
||||
let(:selected_ids) { log_1.id } |
||||
|
||||
before do |
||||
allow(FilterManager).to receive(:filter_logs).and_return LettingsLog.all |
||||
end |
||||
|
||||
it "throws an error if selected ids are not provided" do |
||||
expect { post delete_lettings_logs_organisation_path(id: organisation) }.to raise_error ActionController::ParameterMissing |
||||
end |
||||
|
||||
it "calls the filter service with the filters in the session and the search term from the query params" do |
||||
search = "Schrödinger's cat" |
||||
logs_filters = { |
||||
"years" => [""], |
||||
"status" => ["", "in_progress"], |
||||
"user" => "all", |
||||
} |
||||
get lettings_logs_path(logs_filters) # adds the filters to the session |
||||
|
||||
expect(FilterManager).to receive(:filter_logs) { |arg1, arg2, arg3| |
||||
expect(arg1).to contain_exactly(log_1, log_2) |
||||
expect(arg2).to eq search |
||||
expect(arg3).to eq logs_filters.merge(organisation: organisation.id.to_s) |
||||
}.and_return LettingsLog.all |
||||
|
||||
post delete_lettings_logs_organisation_path(id: organisation, search:, selected_ids:) |
||||
end |
||||
|
||||
it "displays the logs returned by the filter service" do |
||||
post delete_lettings_logs_organisation_path(id: organisation, selected_ids:) |
||||
|
||||
table_body_rows = page.find_all("tbody tr") |
||||
expect(table_body_rows.count).to be 2 |
||||
ids_in_table = table_body_rows.map { |row| row.first("td").text.strip } |
||||
expect(ids_in_table).to match_array [log_1.id.to_s, log_2.id.to_s] |
||||
end |
||||
|
||||
it "only checks the selected checkboxes when selected_ids provided" do |
||||
post delete_lettings_logs_organisation_path(id: organisation, selected_ids:) |
||||
|
||||
checkboxes = page.find_all("tbody tr").map { |row| row.find("input") } |
||||
checkbox_expected_checked = checkboxes.find { |cb| cb.value == log_1.id.to_s } |
||||
checkbox_expected_unchecked = checkboxes.find { |cb| cb.value == log_2.id.to_s } |
||||
expect(checkbox_expected_checked).to be_checked |
||||
expect(checkbox_expected_unchecked).not_to be_checked |
||||
end |
||||
end |
||||
|
||||
describe "POST organisations/delete-lettings-logs-confirmation" do |
||||
let(:log_1) { create(:lettings_log, :in_progress, owning_organisation: organisation) } |
||||
let(:log_2) { create(:lettings_log, :completed, owning_organisation: organisation) } |
||||
let(:log_3) { create(:lettings_log, :in_progress, owning_organisation: organisation) } |
||||
let(:params) do |
||||
{ |
||||
forms_delete_logs_form: { |
||||
search_term: "milk", |
||||
selected_ids: [log_1, log_2].map(&:id), |
||||
}, |
||||
} |
||||
end |
||||
|
||||
before do |
||||
post delete_lettings_logs_confirmation_organisation_path(id: organisation), params: params |
||||
end |
||||
|
||||
it "requires delete logs form data to be provided" do |
||||
expect { post delete_lettings_logs_confirmation_organisation_path(id: organisation) }.to raise_error(ActionController::ParameterMissing) |
||||
end |
||||
|
||||
it "shows the correct title" do |
||||
expect(page.find("h1").text).to include "Are you sure you want to delete these logs?" |
||||
end |
||||
|
||||
it "shows the correct information text to the user" do |
||||
expect(page).to have_selector("p", text: "You've selected 2 logs to delete") |
||||
end |
||||
|
||||
context "when only one log is selected" do |
||||
let(:params) do |
||||
{ |
||||
forms_delete_logs_form: { |
||||
search_term: "milk", |
||||
selected_ids: [log_1].map(&:id), |
||||
}, |
||||
} |
||||
end |
||||
|
||||
it "shows the correct information text to the user in the singular" do |
||||
expect(page).to have_selector("p", text: "You've selected 1 log to delete") |
||||
end |
||||
end |
||||
|
||||
it "shows a warning to the user" do |
||||
expect(page).to have_selector(".govuk-warning-text", text: "You will not be able to undo this action") |
||||
end |
||||
|
||||
it "shows a button to delete the selected logs" do |
||||
expect(page).to have_selector("form.button_to button", text: "Delete logs") |
||||
end |
||||
|
||||
it "the delete logs button submits the correct data to the correct path" do |
||||
form_containing_button = page.find("form.button_to") |
||||
|
||||
expect(form_containing_button[:action]).to eq delete_lettings_logs_organisation_path(id: organisation) |
||||
expect(form_containing_button).to have_field "_method", type: :hidden, with: "delete" |
||||
expect(form_containing_button).to have_field "ids[]", type: :hidden, with: log_1.id |
||||
expect(form_containing_button).to have_field "ids[]", type: :hidden, with: log_2.id |
||||
end |
||||
|
||||
it "shows a cancel button with the correct style" do |
||||
expect(page).to have_selector("button.govuk-button--secondary", text: "Cancel") |
||||
end |
||||
|
||||
it "the cancel button submits the correct data to the correct path" do |
||||
form_containing_cancel = page.find_all("form").find { |form| form.has_selector?("button.govuk-button--secondary") } |
||||
expect(form_containing_cancel).to have_field("selected_ids", type: :hidden, with: [log_1, log_2].map(&:id).join(" ")) |
||||
expect(form_containing_cancel).to have_field("search", type: :hidden, with: "milk") |
||||
expect(form_containing_cancel[:method]).to eq "post" |
||||
expect(form_containing_cancel[:action]).to eq delete_lettings_logs_organisation_path(id: organisation) |
||||
end |
||||
|
||||
context "when no logs are selected" do |
||||
let(:params) do |
||||
{ |
||||
forms_delete_logs_form: { |
||||
log_type: :lettings, |
||||
log_ids: [log_1, log_2, log_3].map(&:id).join(" "), |
||||
}, |
||||
} |
||||
end |
||||
|
||||
before do |
||||
post delete_lettings_logs_confirmation_organisation_path(id: organisation, params:) |
||||
end |
||||
|
||||
it "renders the list of logs table again" do |
||||
expect(page.find("h1").text).to include "Review the logs you want to delete" |
||||
end |
||||
|
||||
it "displays an error message" do |
||||
expect(page).to have_selector(".govuk-error-summary", text: "Select at least one log to delete or press cancel to return") |
||||
end |
||||
|
||||
it "renders the table with all checkboxes unchecked" do |
||||
checkboxes = page.find_all("tbody tr").map { |row| row.find("input") } |
||||
checkboxes.each do |checkbox| |
||||
expect(checkbox).not_to be_checked |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe "DELETE organisations/delete-lettings-logs" do |
||||
let(:log_1) { create(:lettings_log, :in_progress, owning_organisation: organisation) } |
||||
let(:log_2) { create(:lettings_log, :completed, owning_organisation: organisation) } |
||||
let(:params) { { ids: [log_1.id, log_2.id] } } |
||||
|
||||
before do |
||||
delete delete_lettings_logs_organisation_path(id: organisation, params:) |
||||
end |
||||
|
||||
it "deletes the logs provided" do |
||||
log_1.reload |
||||
expect(log_1.status).to eq "deleted" |
||||
expect(log_1.discarded_at).not_to be nil |
||||
log_2.reload |
||||
expect(log_2.status).to eq "deleted" |
||||
expect(log_2.discarded_at).not_to be nil |
||||
end |
||||
|
||||
it "redirects to the lettings log index for that organisation and displays a notice that the logs have been deleted" do |
||||
expect(response).to redirect_to lettings_logs_organisation_path(id: organisation) |
||||
follow_redirect! |
||||
expect(page).to have_selector(".govuk-notification-banner--success") |
||||
expect(page).to have_selector(".govuk-notification-banner--success", text: "2 logs have been deleted") |
||||
end |
||||
end |
||||
|
||||
describe "GET organisations/delete-sales-logs" do |
||||
let!(:log_1) { create(:sales_log, :in_progress, owning_organisation: organisation) } |
||||
let!(:log_2) { create(:sales_log, :completed, owning_organisation: organisation) } |
||||
|
||||
before do |
||||
allow(FilterManager).to receive(:filter_logs).and_return SalesLog.all |
||||
end |
||||
|
||||
it "calls the filter service with the filters in the session and the search term from the query params" do |
||||
search = "Schrödinger's cat" |
||||
logs_filters = { |
||||
"years" => [""], |
||||
"status" => ["", "in_progress"], |
||||
"user" => "all", |
||||
} |
||||
get sales_logs_path(logs_filters) # adds the filters to the session |
||||
|
||||
expect(FilterManager).to receive(:filter_logs) { |arg1, arg2, arg3| |
||||
expect(arg1).to contain_exactly(log_1, log_2) |
||||
expect(arg2).to eq search |
||||
expect(arg3).to eq logs_filters.merge(organisation: organisation.id.to_s) |
||||
}.and_return SalesLog.all |
||||
|
||||
get delete_sales_logs_organisation_path(id: organisation, search:) |
||||
end |
||||
|
||||
it "displays the logs returned by the filter service" do |
||||
get delete_sales_logs_organisation_path(id: organisation) |
||||
|
||||
table_body_rows = page.find_all("tbody tr") |
||||
expect(table_body_rows.count).to be 2 |
||||
ids_in_table = table_body_rows.map { |row| row.first("td").text.strip } |
||||
expect(ids_in_table).to match_array [log_1.id.to_s, log_2.id.to_s] |
||||
end |
||||
|
||||
it "checks all checkboxes by default" do |
||||
get delete_sales_logs_organisation_path(id: organisation) |
||||
|
||||
checkboxes = page.find_all("tbody tr").map { |row| row.find("input") } |
||||
expect(checkboxes.count).to be 2 |
||||
expect(checkboxes).to all be_checked |
||||
end |
||||
end |
||||
|
||||
describe "POST organisations/delete-sales-logs" do |
||||
let!(:log_1) { create(:sales_log, :in_progress, owning_organisation: organisation) } |
||||
let!(:log_2) { create(:sales_log, :completed, owning_organisation: organisation) } |
||||
let(:selected_ids) { log_1.id } |
||||
|
||||
before do |
||||
allow(FilterManager).to receive(:filter_logs).and_return SalesLog.all |
||||
end |
||||
|
||||
it "throws an error if selected ids are not provided" do |
||||
expect { post delete_sales_logs_organisation_path(id: organisation) }.to raise_error ActionController::ParameterMissing |
||||
end |
||||
|
||||
it "calls the filter service with the filters in the session and the search term from the query params" do |
||||
search = "Schrödinger's cat" |
||||
logs_filters = { |
||||
"years" => [""], |
||||
"status" => ["", "in_progress"], |
||||
"user" => "all", |
||||
} |
||||
get sales_logs_path(logs_filters) # adds the filters to the session |
||||
|
||||
expect(FilterManager).to receive(:filter_logs) { |arg1, arg2, arg3| |
||||
expect(arg1).to contain_exactly(log_1, log_2) |
||||
expect(arg2).to eq search |
||||
expect(arg3).to eq logs_filters.merge(organisation: organisation.id.to_s) |
||||
}.and_return SalesLog.all |
||||
|
||||
post delete_sales_logs_organisation_path(id: organisation, search:, selected_ids:) |
||||
end |
||||
|
||||
it "displays the logs returned by the filter service" do |
||||
post delete_sales_logs_organisation_path(id: organisation, selected_ids:) |
||||
|
||||
table_body_rows = page.find_all("tbody tr") |
||||
expect(table_body_rows.count).to be 2 |
||||
ids_in_table = table_body_rows.map { |row| row.first("td").text.strip } |
||||
expect(ids_in_table).to match_array [log_1.id.to_s, log_2.id.to_s] |
||||
end |
||||
|
||||
it "only checks the selected checkboxes when selected_ids provided" do |
||||
post delete_sales_logs_organisation_path(id: organisation, selected_ids:) |
||||
|
||||
checkboxes = page.find_all("tbody tr").map { |row| row.find("input") } |
||||
checkbox_expected_checked = checkboxes.find { |cb| cb.value == log_1.id.to_s } |
||||
checkbox_expected_unchecked = checkboxes.find { |cb| cb.value == log_2.id.to_s } |
||||
expect(checkbox_expected_checked).to be_checked |
||||
expect(checkbox_expected_unchecked).not_to be_checked |
||||
end |
||||
end |
||||
|
||||
describe "POST organisations/delete-sales-logs-confirmation" do |
||||
let(:log_1) { create(:sales_log, :in_progress, owning_organisation: organisation) } |
||||
let(:log_2) { create(:sales_log, :completed, owning_organisation: organisation) } |
||||
let(:log_3) { create(:sales_log, :in_progress, owning_organisation: organisation) } |
||||
let(:params) do |
||||
{ |
||||
forms_delete_logs_form: { |
||||
search_term: "milk", |
||||
selected_ids: [log_1, log_2].map(&:id), |
||||
}, |
||||
} |
||||
end |
||||
|
||||
before do |
||||
post delete_sales_logs_confirmation_organisation_path(id: organisation), params: params |
||||
end |
||||
|
||||
it "requires delete logs form data to be provided" do |
||||
expect { post delete_sales_logs_confirmation_organisation_path(id: organisation) }.to raise_error(ActionController::ParameterMissing) |
||||
end |
||||
|
||||
it "shows the correct title" do |
||||
expect(page.find("h1").text).to include "Are you sure you want to delete these logs?" |
||||
end |
||||
|
||||
it "shows the correct information text to the user" do |
||||
expect(page).to have_selector("p", text: "You've selected 2 logs to delete") |
||||
end |
||||
|
||||
context "when only one log is selected" do |
||||
let(:params) do |
||||
{ |
||||
forms_delete_logs_form: { |
||||
search_term: "milk", |
||||
selected_ids: [log_1].map(&:id), |
||||
}, |
||||
} |
||||
end |
||||
|
||||
it "shows the correct information text to the user in the singular" do |
||||
expect(page).to have_selector("p", text: "You've selected 1 log to delete") |
||||
end |
||||
end |
||||
|
||||
it "shows a warning to the user" do |
||||
expect(page).to have_selector(".govuk-warning-text", text: "You will not be able to undo this action") |
||||
end |
||||
|
||||
it "shows a button to delete the selected logs" do |
||||
expect(page).to have_selector("form.button_to button", text: "Delete logs") |
||||
end |
||||
|
||||
it "the delete logs button submits the correct data to the correct path" do |
||||
form_containing_button = page.find("form.button_to") |
||||
|
||||
expect(form_containing_button[:action]).to eq delete_sales_logs_organisation_path(id: organisation) |
||||
expect(form_containing_button).to have_field "_method", type: :hidden, with: "delete" |
||||
expect(form_containing_button).to have_field "ids[]", type: :hidden, with: log_1.id |
||||
expect(form_containing_button).to have_field "ids[]", type: :hidden, with: log_2.id |
||||
end |
||||
|
||||
it "shows a cancel button with the correct style" do |
||||
expect(page).to have_selector("button.govuk-button--secondary", text: "Cancel") |
||||
end |
||||
|
||||
it "the cancel button submits the correct data to the correct path" do |
||||
form_containing_cancel = page.find_all("form").find { |form| form.has_selector?("button.govuk-button--secondary") } |
||||
expect(form_containing_cancel).to have_field("selected_ids", type: :hidden, with: [log_1, log_2].map(&:id).join(" ")) |
||||
expect(form_containing_cancel).to have_field("search", type: :hidden, with: "milk") |
||||
expect(form_containing_cancel[:method]).to eq "post" |
||||
expect(form_containing_cancel[:action]).to eq delete_sales_logs_organisation_path(id: organisation) |
||||
end |
||||
|
||||
context "when no logs are selected" do |
||||
let(:params) do |
||||
{ |
||||
forms_delete_logs_form: { |
||||
log_type: :sales, |
||||
log_ids: [log_1, log_2, log_3].map(&:id).join(" "), |
||||
}, |
||||
} |
||||
end |
||||
|
||||
before do |
||||
post delete_sales_logs_confirmation_organisation_path(id: organisation, params:) |
||||
end |
||||
|
||||
it "renders the list of logs table again" do |
||||
expect(page.find("h1").text).to include "Review the logs you want to delete" |
||||
end |
||||
|
||||
it "displays an error message" do |
||||
expect(page).to have_selector(".govuk-error-summary", text: "Select at least one log to delete or press cancel to return") |
||||
end |
||||
|
||||
it "renders the table with all checkboxes unchecked" do |
||||
checkboxes = page.find_all("tbody tr").map { |row| row.find("input") } |
||||
checkboxes.each do |checkbox| |
||||
expect(checkbox).not_to be_checked |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
describe "DELETE organisations/delete-sales-logs" do |
||||
let(:log_1) { create(:sales_log, :in_progress, owning_organisation: organisation) } |
||||
let(:log_2) { create(:sales_log, :completed, owning_organisation: organisation) } |
||||
let(:params) { { ids: [log_1.id, log_2.id] } } |
||||
|
||||
before do |
||||
delete delete_sales_logs_organisation_path(id: organisation, params:) |
||||
end |
||||
|
||||
it "deletes the logs provided" do |
||||
log_1.reload |
||||
expect(log_1.status).to eq "deleted" |
||||
expect(log_1.discarded_at).not_to be nil |
||||
log_2.reload |
||||
expect(log_2.status).to eq "deleted" |
||||
expect(log_2.discarded_at).not_to be nil |
||||
end |
||||
|
||||
it "redirects to the sales log index for that organisation and displays a notice that the logs have been deleted" do |
||||
expect(response).to redirect_to sales_logs_organisation_path(id: organisation) |
||||
follow_redirect! |
||||
expect(page).to have_selector(".govuk-notification-banner--success") |
||||
expect(page).to have_selector(".govuk-notification-banner--success", text: "2 logs have been deleted") |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,121 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe "logs/delete_logs.html.erb" do |
||||
let(:user) { create(:user, :support, name: "Dirk Gently") } |
||||
let(:lettings_log_1) { create(:lettings_log, tenancycode: "Holistic", propcode: "Detective Agency", created_by: user) } |
||||
let(:lettings_logs) { [lettings_log_1] } |
||||
let(:paths) do |
||||
{ |
||||
delete_confirmation_path: delete_logs_confirmation_lettings_logs_path, |
||||
back_to_logs_path: lettings_logs_path(search: "search_term"), |
||||
delete_path: delete_logs_lettings_logs_path, |
||||
} |
||||
end |
||||
let(:delete_logs_form) { Forms::DeleteLogsForm.new(log_type: :lettings, current_user: user, **paths) } |
||||
|
||||
before do |
||||
sign_in user |
||||
allow(FilterManager).to receive(:filter_logs).and_return lettings_logs |
||||
assign(:delete_logs_form, delete_logs_form) |
||||
end |
||||
|
||||
it "has the correct h1 content" do |
||||
render |
||||
fragment = Capybara::Node::Simple.new(rendered) |
||||
h1 = fragment.find("h1") |
||||
expect(h1.text).to include "Review the logs you want to delete" |
||||
end |
||||
|
||||
context "when there is one log to delete" do |
||||
it "shows the informative text in the singular" do |
||||
render |
||||
fragment = Capybara::Node::Simple.new(rendered) |
||||
info_text = fragment.first("p").text |
||||
expect(info_text).to eq "You've selected 1 log to delete" |
||||
end |
||||
end |
||||
|
||||
context "when there is more than one log to delete" do |
||||
let(:lettings_log_2) { create(:lettings_log, tenancycode: "01-354", propcode: "9112") } |
||||
|
||||
before do |
||||
lettings_logs << lettings_log_2 |
||||
allow(FilterManager).to receive(:filter_logs).and_return lettings_logs |
||||
delete_logs_form = Forms::DeleteLogsForm.new(log_type: :lettings, current_user: user, **paths) |
||||
assign(:delete_logs_form, delete_logs_form) |
||||
end |
||||
|
||||
it "shows the informative text in the plural" do |
||||
render |
||||
fragment = Capybara::Node::Simple.new(rendered) |
||||
info_text = fragment.first("p").text |
||||
expect(info_text).to eq "You've selected #{lettings_logs.count} logs to delete" |
||||
end |
||||
end |
||||
|
||||
context "when the table contains lettings logs" do |
||||
it "shows the correct headers in the table" do |
||||
render |
||||
fragment = Capybara::Node::Simple.new(rendered) |
||||
headers = fragment.find_all("table thead tr th").map(&:text) |
||||
expect(headers).to eq ["Log ID", "Tenancy code", "Property reference", "Status", "Delete?"] |
||||
end |
||||
|
||||
it "shows the correct information in each row" do |
||||
render |
||||
fragment = Capybara::Node::Simple.new(rendered) |
||||
row_data = fragment.find_all("table tbody tr td").map(&:text)[0...-1].map(&:strip) |
||||
expect(row_data).to eq [lettings_log_1.id.to_s, lettings_log_1.tenancycode, lettings_log_1.propcode, lettings_log_1.status.humanize.capitalize] |
||||
end |
||||
|
||||
it "links to the relevant log on each row" do |
||||
render |
||||
fragment = Capybara::Node::Simple.new(rendered) |
||||
first_cell = fragment.first("table tbody tr td") |
||||
expect(first_cell).to have_link lettings_log_1.id.to_s, href: lettings_log_path(lettings_log_1) |
||||
end |
||||
end |
||||
|
||||
context "when the table contains sales logs" do |
||||
let(:sales_log) { create(:sales_log, purchid: "Interconnectedness", saledate: Time.zone.today, created_by: user) } |
||||
let(:sales_logs) { [sales_log] } |
||||
let(:delete_logs_form_sales) { Forms::DeleteLogsForm.new(log_type: :sales, current_user: user, **paths) } |
||||
|
||||
before do |
||||
sign_in user |
||||
allow(FilterManager).to receive(:filter_logs).and_return sales_logs |
||||
assign(:delete_logs_form, delete_logs_form_sales) |
||||
end |
||||
|
||||
it "shows the correct headers in the table" do |
||||
render |
||||
fragment = Capybara::Node::Simple.new(rendered) |
||||
headers = fragment.find_all("table thead tr th").map(&:text) |
||||
expect(headers).to eq ["Log ID", "Purchaser code", "Sale completion date", "Status", "Delete?"] |
||||
end |
||||
|
||||
it "shows the correct information in each row" do |
||||
render |
||||
fragment = Capybara::Node::Simple.new(rendered) |
||||
row_data = fragment.find_all("table tbody tr td").map(&:text)[0...-1].map(&:strip) |
||||
expect(row_data).to eq [sales_log.id.to_s, sales_log.purchid, sales_log.saledate.to_formatted_s(:govuk_date), sales_log.status.humanize.capitalize] |
||||
end |
||||
|
||||
it "links to the relevant log on each row" do |
||||
render |
||||
fragment = Capybara::Node::Simple.new(rendered) |
||||
first_cell = fragment.first("table tbody tr td") |
||||
expect(first_cell).to have_link sales_log.id.to_s, href: sales_log_path(sales_log) |
||||
end |
||||
end |
||||
|
||||
it "shows a checkbox with the correct hidden label in the final cell of each row" do |
||||
render |
||||
fragment = Capybara::Node::Simple.new(rendered) |
||||
final_cell = fragment.find_all("table tbody tr td")[-1] |
||||
expect(final_cell.find("input")[:type]).to eq "checkbox" |
||||
checkbox_label = final_cell.find("label span") |
||||
expect(checkbox_label.text).to eq lettings_log_1.id.to_s |
||||
expect(checkbox_label[:class]).to include "govuk-visually-hidden" |
||||
end |
||||
end |
Loading…
Reference in new issue