Submit social housing lettings and sales data (CORE)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

947 lines
37 KiB

CLDC-2290 implement delete multiple logs story (#1657) * 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 tests
1 year ago
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:
CLDC-2290 implement delete multiple logs story (#1657) * 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 tests
1 year ago
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:
CLDC-2290 implement delete multiple logs story (#1657) * 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 tests
1 year ago
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:
CLDC-2290 implement delete multiple logs story (#1657) * 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 tests
1 year ago
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:
CLDC-2290 implement delete multiple logs story (#1657) * 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 tests
1 year ago
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:
CLDC-2290 implement delete multiple logs story (#1657) * 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 tests
1 year ago
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:
CLDC-2290 implement delete multiple logs story (#1657) * 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 tests
1 year ago
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