Browse Source

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
pull/1657/head
Arthur Campbell 3 years ago
parent
commit
eabf668ec5
  1. 130
      app/controllers/delete_logs_controller.rb
  2. 4
      app/controllers/organisations_controller.rb
  3. 5
      app/models/forms/delete_logs_form.rb
  4. 4
      app/views/logs/delete_lettings_logs.html.erb
  5. 4
      app/views/logs/delete_logs_confirmation.html.erb
  6. 4
      app/views/logs/delete_sales_logs.html.erb
  7. 2
      app/views/organisations/logs.html.erb
  8. 8
      config/routes.rb
  9. 730
      spec/requests/delete_logs_controller_spec.rb
  10. 11
      spec/views/logs/delete_lettings_logs_spec.rb

130
app/controllers/delete_logs_controller.rb

@ -6,13 +6,13 @@ class DeleteLogsController < ApplicationController
before_action :session_filters, if: :current_user, except: [:delete_logs] before_action :session_filters, if: :current_user, except: [:delete_logs]
def delete_lettings_logs def delete_lettings_logs
@delete_logs_form = delete_logs_form(log_type: :lettings) @delete_logs_form = delete_logs_form(log_type: :lettings, paths: lettings_logs_paths)
render "logs/delete_lettings_logs" render "logs/delete_lettings_logs"
end end
def delete_lettings_logs_with_selected_ids def delete_lettings_logs_with_selected_ids
selected_ids = params.require(:selected_ids).split.map(&:to_i) selected_ids = params.require(:selected_ids).split.map(&:to_i)
@delete_logs_form = delete_logs_form(selected_ids:, log_type: :lettings) @delete_logs_form = delete_logs_form(selected_ids:, log_type: :lettings, paths: lettings_logs_paths)
render "logs/delete_lettings_logs" render "logs/delete_lettings_logs"
end end
@ -21,11 +21,9 @@ class DeleteLogsController < ApplicationController
current_user:, current_user:,
log_filters: @session_filters, log_filters: @session_filters,
log_type: :lettings, log_type: :lettings,
} }.merge lettings_logs_paths
form_attributes = params.require(:forms_delete_logs_form).permit(:search_term, selected_ids: [])
attributes = form_attributes.merge(default_attributes) attributes = form_attributes.merge(default_attributes)
attributes[:selected_ids] = [] unless attributes.key? :selected_ids attributes[:selected_ids] = [] unless attributes.key? :selected_ids
@delete_path = delete_logs_lettings_logs_path
@delete_logs_form = Forms::DeleteLogsForm.new(attributes) @delete_logs_form = Forms::DeleteLogsForm.new(attributes)
if @delete_logs_form.valid? if @delete_logs_form.valid?
render "logs/delete_logs_confirmation" render "logs/delete_logs_confirmation"
@ -45,13 +43,13 @@ class DeleteLogsController < ApplicationController
end end
def delete_sales_logs def delete_sales_logs
@delete_logs_form = delete_logs_form(log_type: :sales) @delete_logs_form = delete_logs_form(log_type: :sales, paths: sales_logs_paths)
render "logs/delete_sales_logs" render "logs/delete_sales_logs"
end end
def delete_sales_logs_with_selected_ids def delete_sales_logs_with_selected_ids
selected_ids = params.require(:selected_ids).split.map(&:to_i) selected_ids = params.require(:selected_ids).split.map(&:to_i)
@delete_logs_form = delete_logs_form(selected_ids:, log_type: :sales) @delete_logs_form = delete_logs_form(selected_ids:, log_type: :sales, paths: sales_logs_paths)
render "logs/delete_sales_logs" render "logs/delete_sales_logs"
end end
@ -60,11 +58,9 @@ class DeleteLogsController < ApplicationController
current_user:, current_user:,
log_filters: @session_filters, log_filters: @session_filters,
log_type: :sales, log_type: :sales,
} }.merge sales_logs_paths
form_attributes = params.require(:forms_delete_logs_form).permit(:search_term, selected_ids: [])
attributes = form_attributes.merge(default_attributes) attributes = form_attributes.merge(default_attributes)
attributes[:selected_ids] = [] unless attributes.key? :selected_ids attributes[:selected_ids] = [] unless attributes.key? :selected_ids
@delete_path = delete_logs_sales_logs_path
@delete_logs_form = Forms::DeleteLogsForm.new(attributes) @delete_logs_form = Forms::DeleteLogsForm.new(attributes)
if @delete_logs_form.valid? if @delete_logs_form.valid?
render "logs/delete_logs_confirmation" render "logs/delete_logs_confirmation"
@ -83,10 +79,120 @@ class DeleteLogsController < ApplicationController
redirect_to sales_logs_path, notice: I18n.t("notification.logs_deleted", count: logs.count) redirect_to sales_logs_path, notice: I18n.t("notification.logs_deleted", count: logs.count)
end end
def delete_lettings_logs_for_organisation
@delete_logs_form = delete_logs_form(log_type: :lettings, paths: lettings_logs_for_organisation_paths)
render "logs/delete_lettings_logs"
end
def delete_lettings_logs_for_organisation_with_selected_ids
selected_ids = params.require(:selected_ids).split.map(&:to_i)
@delete_logs_form = delete_logs_form(selected_ids:, log_type: :lettings, paths: lettings_logs_for_organisation_paths)
render "logs/delete_lettings_logs"
end
def delete_lettings_logs_for_organisation_confirmation
default_attributes = {
current_user:,
log_filters: @session_filters,
log_type: :lettings,
}.merge lettings_logs_for_organisation_paths
attributes = form_attributes.merge(default_attributes)
attributes[:selected_ids] = [] unless attributes.key? :selected_ids
@delete_logs_form = Forms::DeleteLogsForm.new(attributes)
if @delete_logs_form.valid?
render "logs/delete_logs_confirmation"
else
render "logs/delete_lettings_logs"
end
end
def discard_lettings_logs_for_organisation
logs = LettingsLog.find(params.require(:ids))
logs.each do |log|
authorize log, :destroy?
log.discard!
end
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, paths: sales_logs_for_organisation_paths)
render "logs/delete_sales_logs"
end
def delete_sales_logs_for_organisation_with_selected_ids
selected_ids = params.require(:selected_ids).split.map(&:to_i)
@delete_logs_form = delete_logs_form(selected_ids:, log_type: :sales, paths: sales_logs_for_organisation_paths)
render "logs/delete_sales_logs"
end
def delete_sales_logs_for_organisation_confirmation
default_attributes = {
current_user:,
log_filters: @session_filters,
log_type: :sales,
}.merge sales_logs_for_organisation_paths
attributes = form_attributes.merge(default_attributes)
attributes[:selected_ids] = [] unless attributes.key? :selected_ids
@delete_logs_form = Forms::DeleteLogsForm.new(attributes)
if @delete_logs_form.valid?
render "logs/delete_logs_confirmation"
else
render "logs/delete_sales_logs"
end
end
def discard_sales_logs_for_organisation
logs = SalesLog.find(params.require(:ids))
logs.each do |log|
authorize log, :destroy?
log.discard!
end
redirect_to sales_logs_organisation_path, notice: I18n.t("notification.logs_deleted", count: logs.count)
end
private private
def delete_logs_form(selected_ids: nil, log_type:) def delete_logs_form(log_type:, paths:, selected_ids: nil)
Forms::DeleteLogsForm.new(current_user:, search_term:, log_filters: @session_filters, log_type:, selected_ids:) Forms::DeleteLogsForm.new(current_user:, search_term:, log_filters: @session_filters, log_type:, selected_ids:, **paths)
end
def form_attributes
params.require(:forms_delete_logs_form).permit(:search_term, selected_ids: [])
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 end
def search_term def search_term

4
app/controllers/organisations_controller.rb

@ -96,6 +96,7 @@ class OrganisationsController < ApplicationController
format.html do format.html do
@search_term = search_term @search_term = search_term
@pagy, @logs = pagy(unpaginated_filtered_logs) @pagy, @logs = pagy(unpaginated_filtered_logs)
@delete_logs_path = delete_lettings_logs_organisation_path
@searched = search_term.presence @searched = search_term.presence
@total_count = organisation_logs.size @total_count = organisation_logs.size
@log_type = :lettings @log_type = :lettings
@ -119,13 +120,14 @@ class OrganisationsController < ApplicationController
end end
def sales_logs def sales_logs
organisation_logs = SalesLog.where(owning_organisation_id: @organisation.id) organisation_logs = SalesLog.visible.where(owning_organisation_id: @organisation.id)
unpaginated_filtered_logs = filter_manager.filtered_logs(organisation_logs, search_term, session_filters) unpaginated_filtered_logs = filter_manager.filtered_logs(organisation_logs, search_term, session_filters)
respond_to do |format| respond_to do |format|
format.html do format.html do
@search_term = search_term @search_term = search_term
@pagy, @logs = pagy(unpaginated_filtered_logs) @pagy, @logs = pagy(unpaginated_filtered_logs)
@delete_logs_path = delete_sales_logs_organisation_path
@searched = search_term.presence @searched = search_term.presence
@total_count = organisation_logs.size @total_count = organisation_logs.size
@log_type = :sales @log_type = :sales

5
app/models/forms/delete_logs_form.rb

@ -3,7 +3,7 @@ module Forms
include ActiveModel::Model include ActiveModel::Model
include ActiveModel::Validations include ActiveModel::Validations
attr_reader :logs, :log_type, :selected_ids, :search_term attr_reader :logs, :log_type, :selected_ids, :search_term, :delete_confirmation_path, :back_to_logs_path, :delete_path
validate :at_least_one_log_selected validate :at_least_one_log_selected
@ -13,6 +13,9 @@ module Forms
@current_user = attributes[:current_user] @current_user = attributes[:current_user]
@logs = FilterService.filter_logs(all_logs, @search_term, attributes[:log_filters], nil, @current_user) @logs = FilterService.filter_logs(all_logs, @search_term, attributes[:log_filters], nil, @current_user)
@selected_ids = attributes[:selected_ids] || @logs.map(&:id) @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 end
def log_count def log_count

4
app/views/logs/delete_lettings_logs.html.erb

@ -10,7 +10,7 @@
</h1> </h1>
<p>You've selected <%= @delete_logs_form.log_count %> <%= "log".pluralize(@delete_logs_form.log_count) %> to delete</p> <p>You've selected <%= @delete_logs_form.log_count %> <%= "log".pluralize(@delete_logs_form.log_count) %> to delete</p>
<%= form_with model: @delete_logs_form, url: delete_logs_confirmation_lettings_logs_path do |f| %> <%= 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.hidden_field :search_term, value: @delete_logs_form.search_term %>
<%= f.govuk_error_summary %> <%= f.govuk_error_summary %>
<%= govuk_table do |table| %> <%= govuk_table do |table| %>
@ -43,6 +43,6 @@
<% end %> <% end %>
<% end %> <% end %>
<%= f.govuk_submit "Continue" do %> <%= f.govuk_submit "Continue" do %>
<%= govuk_button_link_to "Cancel", lettings_logs_path(search: @delete_logs_form.search_term), secondary: true %> <%= govuk_button_link_to "Cancel", @delete_logs_form.back_to_logs_path, secondary: true %>
<% end %> <% end %>
<% end %> <% end %>

4
app/views/logs/delete_logs_confirmation.html.erb

@ -16,8 +16,8 @@
<% end %> <% end %>
<div class="govuk-button-group"> <div class="govuk-button-group">
<%= govuk_button_to "Delete logs", @delete_path, method: "delete", params: { ids: @delete_logs_form.selected_ids } %> <%= govuk_button_to "Delete logs", @delete_logs_form.delete_path, method: "delete", params: { ids: @delete_logs_form.selected_ids } %>
<%= form_with url: @delete_path do |f| %> <%= form_with url: @delete_logs_form.delete_path do |f| %>
<%= f.hidden_field :selected_ids, value: @delete_logs_form.selected_ids %> <%= f.hidden_field :selected_ids, value: @delete_logs_form.selected_ids %>
<%= f.hidden_field :search, value: @delete_logs_form.search_term %> <%= f.hidden_field :search, value: @delete_logs_form.search_term %>
<%= f.govuk_submit "Cancel", secondary: true %> <%= f.govuk_submit "Cancel", secondary: true %>

4
app/views/logs/delete_sales_logs.html.erb

@ -10,7 +10,7 @@
</h1> </h1>
<p>You've selected <%= @delete_logs_form.log_count %> <%= "log".pluralize(@delete_logs_form.log_count) %> to delete</p> <p>You've selected <%= @delete_logs_form.log_count %> <%= "log".pluralize(@delete_logs_form.log_count) %> to delete</p>
<%= form_with model: @delete_logs_form, url: delete_logs_confirmation_sales_logs_path do |f| %> <%= 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.hidden_field :search_term, value: @delete_logs_form.search_term %>
<%= f.govuk_error_summary %> <%= f.govuk_error_summary %>
<%= govuk_table do |table| %> <%= govuk_table do |table| %>
@ -43,6 +43,6 @@
<% end %> <% end %>
<% end %> <% end %>
<%= f.govuk_submit "Continue" do %> <%= f.govuk_submit "Continue" do %>
<%= govuk_button_link_to "Cancel", sales_logs_path(search: @delete_logs_form.search_term), secondary: true %> <%= govuk_button_link_to "Cancel", @delete_logs_form.back_to_logs_path, secondary: true %>
<% end %> <% end %>
<% end %> <% end %>

2
app/views/organisations/logs.html.erb

@ -34,7 +34,7 @@
total_count: @total_count, total_count: @total_count,
csv_download_url: csv_download_url_by_log_type(@log_type, @organisation, search: @search_term, codes_only: false), csv_download_url: csv_download_url_by_log_type(@log_type, @organisation, search: @search_term, codes_only: false),
csv_codes_only_download_url: csv_download_url_by_log_type(@log_type, @organisation, search: @search_term, codes_only: true), csv_codes_only_download_url: csv_download_url_by_log_type(@log_type, @organisation, search: @search_term, codes_only: true),
delete_logs_path: "#", delete_logs_path: @delete_logs_path,
} %> } %>
<%= render partial: "pagy/nav", locals: { pagy: @pagy, item_name: "logs" } %> <%= render partial: "pagy/nav", locals: { pagy: @pagy, item_name: "logs" } %>
</div> </div>

8
config/routes.rb

@ -122,7 +122,15 @@ Rails.application.routes.draw do
get "users", to: "organisations#users" get "users", to: "organisations#users"
get "users/invite", to: "users/account#new" get "users/invite", to: "users/account#new"
get "lettings-logs", to: "organisations#lettings_logs" get "lettings-logs", to: "organisations#lettings_logs"
get "delete-lettings-logs", to: "delete_logs#delete_lettings_logs_for_organisation"
post "delete-lettings-logs", to: "delete_logs#delete_lettings_logs_for_organisation_with_selected_ids"
post "delete-lettings-logs-confirmation", to: "delete_logs#delete_lettings_logs_for_organisation_confirmation"
delete "delete-lettings-logs", to: "delete_logs#discard_lettings_logs_for_organisation"
get "sales-logs", to: "organisations#sales_logs" get "sales-logs", to: "organisations#sales_logs"
get "delete-sales-logs", to: "delete_logs#delete_sales_logs_for_organisation"
post "delete-sales-logs", to: "delete_logs#delete_sales_logs_for_organisation_with_selected_ids"
post "delete-sales-logs-confirmation", to: "delete_logs#delete_sales_logs_for_organisation_confirmation"
delete "delete-sales-logs", to: "delete_logs#discard_sales_logs_for_organisation"
get "lettings-logs/csv-download", to: "organisations#download_lettings_csv" get "lettings-logs/csv-download", to: "organisations#download_lettings_csv"
post "lettings-logs/email-csv", to: "organisations#email_lettings_csv" post "lettings-logs/email-csv", to: "organisations#email_lettings_csv"
get "lettings-logs/csv-confirmation", to: "lettings_logs#csv_confirmation" get "lettings-logs/csv-confirmation", to: "lettings_logs#csv_confirmation"

730
spec/requests/delete_logs_controller_spec.rb

@ -2,15 +2,18 @@ require "rails_helper"
RSpec.describe "DeleteLogs", type: :request do RSpec.describe "DeleteLogs", type: :request do
let(:page) { Capybara::Node::Simple.new(response.body) } let(:page) { Capybara::Node::Simple.new(response.body) }
let(:user) { create(:user, name: "Richard MacDuff") }
describe "GET delete-logs" do before do
let(:user) { create(:user, name: "Richard MacDuff") } 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_1) { create(:lettings_log, :in_progress, created_by: user) }
let!(:log_2) { create(:lettings_log, :completed, created_by: user) } let!(:log_2) { create(:lettings_log, :completed, created_by: user) }
before do before do
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
sign_in user
allow(FilterService).to receive(:filter_logs).and_return LettingsLog.all allow(FilterService).to receive(:filter_logs).and_return LettingsLog.all
end end
@ -50,15 +53,12 @@ RSpec.describe "DeleteLogs", type: :request do
end end
end end
describe "POST delete-logs" do describe "POST lettings-logs/delete-logs" do
let(:user) { create(:user, name: "Richard MacDuff") }
let!(:log_1) { create(:lettings_log, :in_progress, created_by: user) } let!(:log_1) { create(:lettings_log, :in_progress, created_by: user) }
let!(:log_2) { create(:lettings_log, :completed, created_by: user) } let!(:log_2) { create(:lettings_log, :completed, created_by: user) }
let(:selected_ids) { log_1.id } let(:selected_ids) { log_1.id }
before do before do
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
sign_in user
allow(FilterService).to receive(:filter_logs).and_return LettingsLog.all allow(FilterService).to receive(:filter_logs).and_return LettingsLog.all
end end
@ -104,8 +104,7 @@ RSpec.describe "DeleteLogs", type: :request do
end end
end end
describe "POST delete-logs-confirmation" do describe "POST lettings-logs/delete-logs-confirmation" do
let(:user) { create(:user, name: "Urban Chronotis") }
let(:log_1) { create(:lettings_log, :in_progress) } let(:log_1) { create(:lettings_log, :in_progress) }
let(:log_2) { create(:lettings_log, :completed) } let(:log_2) { create(:lettings_log, :completed) }
let(:log_3) { create(:lettings_log, :in_progress) } let(:log_3) { create(:lettings_log, :in_progress) }
@ -119,8 +118,6 @@ RSpec.describe "DeleteLogs", type: :request do
end end
before do before do
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
sign_in user
post delete_logs_confirmation_lettings_logs_path, params: params post delete_logs_confirmation_lettings_logs_path, params: params
end end
@ -147,8 +144,6 @@ RSpec.describe "DeleteLogs", type: :request do
end end
it "shows the correct information text to the user in the singular" do it "shows the correct information text to the user in the singular" do
post delete_logs_confirmation_lettings_logs_path, params: params
expect(page).to have_selector("p", text: "You've selected 1 log to delete") expect(page).to have_selector("p", text: "You've selected 1 log to delete")
end end
end end
@ -213,18 +208,12 @@ RSpec.describe "DeleteLogs", type: :request do
end end
end end
describe "DELETE delete-logs" do describe "DELETE lettings-logs/delete-logs" do
let(:urban_chronotis) { create(:user, :data_provider, name: "Urban Chronotis") } let(:log_1) { create(:lettings_log, :in_progress, created_by: user) }
let(:log_1) { create(:lettings_log, :in_progress, created_by: urban_chronotis) }
let(:params) { { ids: [log_1.id, log_2.id] } } let(:params) { { ids: [log_1.id, log_2.id] } }
before do
allow(urban_chronotis).to receive(:need_two_factor_authentication?).and_return(false)
sign_in urban_chronotis
end
context "when the user is authorized to delete the logs provided" do context "when the user is authorized to delete the logs provided" do
let(:log_2) { create(:lettings_log, :completed, created_by: urban_chronotis) } let(:log_2) { create(:lettings_log, :completed, created_by: user) }
it "deletes the logs provided" do it "deletes the logs provided" do
delete delete_logs_lettings_logs_path, params: params delete delete_logs_lettings_logs_path, params: params
@ -259,4 +248,699 @@ RSpec.describe "DeleteLogs", type: :request do
end end
end 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(FilterService).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(FilterService).to receive(:filter_logs) { |arg1, arg2, arg3, _arg4, _arg5|
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 }
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(FilterService).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(FilterService).to receive(:filter_logs) { |arg1, arg2, arg3, _arg4, _arg5|
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 }
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(FilterService).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(FilterService).to receive(:filter_logs) { |arg1, arg2, arg3, _arg4, _arg5|
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_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 }
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(FilterService).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(FilterService).to receive(:filter_logs) { |arg1, arg2, arg3, _arg4, _arg5|
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_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 }
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(FilterService).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(FilterService).to receive(:filter_logs) { |arg1, arg2, arg3, _arg4, _arg5|
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_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 }
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(FilterService).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(FilterService).to receive(:filter_logs) { |arg1, arg2, arg3, _arg4, _arg5|
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_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 }
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 end

11
spec/views/logs/delete_lettings_logs_spec.rb

@ -4,7 +4,14 @@ RSpec.describe "logs/delete_lettings_logs.html.erb" do
let(:user) { create(:user, :support, name: "Dirk Gently") } 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_log_1) { create(:lettings_log, tenancycode: "Holistic", propcode: "Detective Agency", created_by: user) }
let(:lettings_logs) { [lettings_log_1] } let(:lettings_logs) { [lettings_log_1] }
let(:delete_logs_form) { Forms::DeleteLogsForm.new(log_type: :lettings, current_user: user) } 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 before do
sign_in user sign_in user
@ -34,7 +41,7 @@ RSpec.describe "logs/delete_lettings_logs.html.erb" do
before do before do
lettings_logs << lettings_log_2 lettings_logs << lettings_log_2
allow(FilterService).to receive(:filter_logs).and_return lettings_logs allow(FilterService).to receive(:filter_logs).and_return lettings_logs
delete_logs_form = Forms::DeleteLogsForm.new(log_type: :lettings, current_user: user) delete_logs_form = Forms::DeleteLogsForm.new(log_type: :lettings, current_user: user, **paths)
assign(:delete_logs_form, delete_logs_form) assign(:delete_logs_form, delete_logs_form)
end end

Loading…
Cancel
Save