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, assigned_to: user) } let!(:log_2) { create(:lettings_log, :completed, assigned_to: 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 = { "status" => %w[in_progress], "assigned_to" => "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, assigned_to: user) } let!(:log_2) { create(:lettings_log, :completed, assigned_to: 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 = { "status" => %w[in_progress], "assigned_to" => "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: 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: 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, assigned_to: 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, assigned_to: 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 context "when an authorized user deletes a log that had duplicates" do context "and only 1 log remains in the duplicate set" do let!(:log_1) { create(:lettings_log, :duplicate, duplicate_set_id: 5, assigned_to: user) } let!(:log_2) { create(:lettings_log, :duplicate, duplicate_set_id: 5, assigned_to: user) } let!(:log_3) { create(:lettings_log, :duplicate, duplicate_set_id: 5, assigned_to: user) } it "deletes the log and marks related logs deduplicated" 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 expect(log_1.duplicates.count).to eq(0) expect(log_1.duplicate_set_id).to be nil log_2.reload expect(log_2.status).to eq "deleted" expect(log_2.discarded_at).not_to be nil expect(log_2.duplicates.count).to eq(0) expect(log_2.duplicate_set_id).to be nil log_3.reload expect(log_3.duplicates.count).to eq(0) expect(log_3.duplicate_set_id).to be nil end end context "and multiple logs remains in the duplicate set" do let!(:log_1) { create(:lettings_log, :duplicate, duplicate_set_id: 5, assigned_to: user) } let!(:log_2) { create(:lettings_log, :duplicate, duplicate_set_id: 5, assigned_to: user) } let!(:log_3) { create(:lettings_log, :duplicate, duplicate_set_id: 5, assigned_to: user) } let(:params) { { ids: [log_1.id] } } it "deletes the log and marks related logs deduplicated" 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 expect(log_1.duplicates.count).to eq(0) expect(log_1.duplicate_set_id).to be nil log_2.reload log_3.reload expect(log_2.duplicates.count).to eq(1) expect(log_3.duplicates.count).to eq(1) expect(log_3.duplicate_set_id).not_to be nil expect(log_3.duplicate_set_id).to eq(log_2.duplicate_set_id) end end end end describe "GET sales-logs/delete-logs" do let!(:log_1) { create(:sales_log, :in_progress, assigned_to: user) } let!(:log_2) { create(:sales_log, :completed, assigned_to: 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 = { "status" => %w[in_progress], "assigned_to" => "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, assigned_to: user) } let!(:log_2) { create(:sales_log, :completed, assigned_to: 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 = { "status" => %w[in_progress], "assigned_to" => "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: 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: 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, assigned_to: 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, assigned_to: 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 context "when an authorized user deletes a log that had duplicates" do context "and only 1 log remains in the duplicate set" do let!(:log_1) { create(:sales_log, :duplicate, duplicate_set_id: 5, assigned_to: user) } let!(:log_2) { create(:sales_log, :duplicate, duplicate_set_id: 5, assigned_to: user) } let!(:log_3) { create(:sales_log, :duplicate, duplicate_set_id: 5, assigned_to: user) } it "deletes the log and marks related logs deduplicated" 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 expect(log_1.duplicates.count).to eq(0) expect(log_1.duplicate_set_id).to be nil log_2.reload expect(log_2.status).to eq "deleted" expect(log_2.discarded_at).not_to be nil expect(log_2.duplicates.count).to eq(0) expect(log_2.duplicate_set_id).to be nil log_3.reload expect(log_3.duplicates.count).to eq(0) expect(log_3.duplicate_set_id).to be nil end end context "and multiple logs remains in the duplicate set" do let!(:log_1) { create(:sales_log, :duplicate, duplicate_set_id: 5, assigned_to: user) } let!(:log_2) { create(:sales_log, :duplicate, duplicate_set_id: 5, assigned_to: user) } let!(:log_3) { create(:sales_log, :duplicate, duplicate_set_id: 5, assigned_to: user) } let(:params) { { ids: [log_1.id] } } it "deletes the log and marks related logs deduplicated" 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 expect(log_1.duplicates.count).to eq(0) expect(log_1.duplicate_set_id).to be nil log_2.reload log_3.reload expect(log_2.duplicates.count).to eq(1) expect(log_3.duplicates.count).to eq(1) expect(log_3.duplicate_set_id).not_to be nil expect(log_3.duplicate_set_id).to eq(log_2.duplicate_set_id) end 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 = { "status" => %w[in_progress], "assigned_to" => "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 = { "status" => %w[in_progress], "assigned_to" => "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: 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 = { "status" => %w[in_progress], "assigned_to" => "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 = { "status" => %w[in_progress], "assigned_to" => "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: 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