100 changed files with 1861 additions and 205 deletions
@ -0,0 +1,37 @@
|
||||
<article class="app-log-summary"> |
||||
<div class="govuk-grid-row"> |
||||
<div class="govuk-grid-column-two-thirds"> |
||||
<header class="app-log-summary__header"> |
||||
<h2 class="govuk-heading-m govuk-!-font-weight-regular govuk-!-margin-bottom-0 text-normal-break "> |
||||
<span class="govuk-!-margin-right-1"><%= bulk_upload.filename %></span> |
||||
<span class="app-metadata app-log-summary__details" style="white-space: nowrap;"><%= bulk_upload.year %>/<%= bulk_upload.year + 1 %></span> |
||||
</h2> |
||||
</header> |
||||
<div class="govuk-!-margin-bottom-2"> |
||||
<p class="govuk-hint govuk-!-font-size-16 govuk-!-margin-bottom-1">Uploaded by: <%= bulk_upload.user.name %> (<%= bulk_upload.user.email %>)</p> |
||||
<p class="govuk-hint govuk-!-font-size-16 govuk-!-margin-bottom-1">Uploading organisation: <%= bulk_upload.organisation.name %></p> |
||||
<p class="govuk-hint govuk-!-font-size-16 govuk-!-margin-bottom-1">Time of upload: <%= bulk_upload.created_at.to_formatted_s(:govuk_date_and_time) %></p> |
||||
</div> |
||||
<p class="govuk-body govuk-!-margin-bottom-3"> |
||||
<%= download_file_link(bulk_upload) %> |
||||
<%= view_error_report_link(bulk_upload) %> |
||||
<%= view_logs_link(bulk_upload) %> |
||||
</p> |
||||
</div> |
||||
<footer class="govuk-grid-column-one-third app-log-summary__footer"> |
||||
<p class="govuk-body govuk-!-margin-bottom-3"> |
||||
<%= upload_status %> |
||||
</p> |
||||
<% unless bulk_upload.processing %> |
||||
<div> |
||||
<%= counts( |
||||
[bulk_upload.total_logs_count, "total log"], |
||||
[setup_errors_count, "error on important questions", "errors on important questions"], |
||||
[critical_errors_count, "critical error"], |
||||
[potential_errors_count, "potential error"], |
||||
) %> |
||||
</div> |
||||
<% end %> |
||||
</footer> |
||||
</div> |
||||
</article> |
||||
@ -0,0 +1,72 @@
|
||||
class BulkUploadSummaryComponent < ViewComponent::Base |
||||
attr_reader :bulk_upload |
||||
|
||||
def initialize(bulk_upload:) |
||||
@bulk_upload = bulk_upload |
||||
@bulk_upload_errors = bulk_upload.bulk_upload_errors |
||||
super |
||||
end |
||||
|
||||
def upload_status |
||||
helpers.status_tag(bulk_upload.status, ["app-tag--small govuk-!-font-weight-regular no-max-width"]) |
||||
end |
||||
|
||||
def setup_errors_count |
||||
@bulk_upload_errors.where(category: "setup").count |
||||
end |
||||
|
||||
def critical_errors_count |
||||
@bulk_upload_errors.where(category: [nil, "", "not_answered"]).count |
||||
end |
||||
|
||||
def potential_errors_count |
||||
@bulk_upload_errors.where(category: "soft_validation").count |
||||
end |
||||
|
||||
def formatted_count_text(count, singular_text, plural_text = nil) |
||||
return if count.nil? || count <= 0 |
||||
|
||||
text = count > 1 ? (plural_text || singular_text.pluralize(count)) : singular_text |
||||
content_tag(:p, class: "govuk-!-font-size-16 govuk-!-margin-bottom-1") do |
||||
concat(content_tag(:strong, count)) |
||||
concat(" #{text}") |
||||
end |
||||
end |
||||
|
||||
def counts(*counts_with_texts) |
||||
counts_with_texts.map { |count, singular_text, plural_text| |
||||
formatted_count_text(count, singular_text, plural_text) if count.present? |
||||
}.compact.join("").html_safe |
||||
end |
||||
|
||||
def download_file_link(bulk_upload) |
||||
send("download_#{bulk_upload.log_type}_file_link", bulk_upload) |
||||
end |
||||
|
||||
def download_lettings_file_link(bulk_upload) |
||||
govuk_link_to "Download file", download_lettings_bulk_upload_path(bulk_upload), class: "govuk-link govuk-!-margin-right-2" |
||||
end |
||||
|
||||
def download_sales_file_link(bulk_upload) |
||||
govuk_link_to "Download file", download_sales_bulk_upload_path(bulk_upload), class: "govuk-link govuk-!-margin-right-2" |
||||
end |
||||
|
||||
def view_error_report_link(bulk_upload) |
||||
status = bulk_upload.status.to_s |
||||
return unless %w[important_errors critical_errors potential_errors].include?(status) |
||||
|
||||
path = if status == "important_errors" |
||||
"summary_bulk_upload_#{bulk_upload.log_type}_result_url" |
||||
else |
||||
"bulk_upload_#{bulk_upload.log_type}_result_path" |
||||
end |
||||
|
||||
govuk_link_to "View error report", send(path, bulk_upload), class: "govuk-link" |
||||
end |
||||
|
||||
def view_logs_link(bulk_upload) |
||||
return unless bulk_upload.status.to_s == "logs_uploaded_with_errors" |
||||
|
||||
govuk_link_to "View logs with errors", send("#{bulk_upload.log_type}_logs_path", bulk_upload_id: [bulk_upload.id]), class: "govuk-link" |
||||
end |
||||
end |
||||
@ -1,10 +1,11 @@
|
||||
<% if display_actions? %> |
||||
<div class="govuk-button-group app-filter-toggle govuk-!-margin-bottom-6"> |
||||
<% if create_button_href.present? %> |
||||
<%= govuk_button_to create_button_copy, create_button_href, class: "govuk-!-margin-right-6" %> |
||||
<%= govuk_button_to create_button_copy, create_button_href, class: "govuk-!-margin-right-6" %> |
||||
<% unless user.support? %> |
||||
<%= govuk_button_link_to upload_button_copy, upload_button_href, secondary: true %> |
||||
<% end %> |
||||
<% if upload_button_href.present? && !user.support? %> |
||||
<%= govuk_button_link_to upload_button_copy, upload_button_href, secondary: true %> |
||||
<% if user.support? %> |
||||
<%= govuk_button_link_to view_uploads_button_copy, view_uploads_button_href, secondary: true %> |
||||
<% end %> |
||||
</div> |
||||
<% end %> |
||||
|
||||
@ -0,0 +1,18 @@
|
||||
.grouped-rows td { |
||||
border-top: none; |
||||
border-bottom: none; |
||||
} |
||||
|
||||
.grouped-rows.first-row td { |
||||
border-top: 1px solid #b1b4b6; |
||||
} |
||||
|
||||
.grouped-rows.last-row td, |
||||
.grouped-rows .grouped-multirow-cell { |
||||
border-bottom: 1px solid #b1b4b6; |
||||
} |
||||
|
||||
.text-normal-break { |
||||
white-space: normal; |
||||
word-break: break-all; |
||||
} |
||||
@ -0,0 +1,12 @@
|
||||
module BulkUploadHelper |
||||
def bulk_upload_title(controller_name) |
||||
case controller_name |
||||
when "lettings_logs" |
||||
"Lettings bulk uploads" |
||||
when "sales_logs" |
||||
"Sales bulk uploads" |
||||
else |
||||
"Bulk uploads" |
||||
end |
||||
end |
||||
end |
||||
@ -1,15 +1,22 @@
|
||||
module CollectionResourcesHelper |
||||
HUMAN_READABLE_CONTENT_TYPE = { "application/pdf": "PDF", |
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "Microsoft Excel", |
||||
"application/vnd.ms-excel": "Microsoft Excel (Old Format)", |
||||
"application/msword": "Microsoft Word", |
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "Microsoft Word (DOCX)", |
||||
"image/jpeg": "JPEG Image", |
||||
"image/png": "PNG Image", |
||||
"text/plain": "Text Document", |
||||
"text/html": "HTML Document" }.freeze |
||||
|
||||
def file_type_size_and_pages(file, number_of_pages: nil) |
||||
extension_mapping = { |
||||
"xlsx" => "Microsoft Excel", |
||||
"pdf" => "PDF", |
||||
} |
||||
extension = File.extname(file)[1..] |
||||
file_pages = number_of_pages ? pluralize(number_of_pages, "page") : nil |
||||
metadata = CollectionResourcesService.new.get_file_metadata(file) |
||||
|
||||
file_type = extension_mapping.fetch(extension, extension) |
||||
return [file_pages].compact.join(", ") unless metadata |
||||
|
||||
file_size = number_to_human_size(File.size("public/files/#{file}"), precision: 0, significant: false) |
||||
file_pages = number_of_pages ? pluralize(number_of_pages, "page") : nil |
||||
file_size = number_to_human_size(metadata["content_length"].to_i) |
||||
file_type = HUMAN_READABLE_CONTENT_TYPE[metadata["content_type"].to_sym] || "Unknown File Type" |
||||
[file_type, file_size, file_pages].compact.join(", ") |
||||
end |
||||
end |
||||
|
||||
@ -0,0 +1,21 @@
|
||||
class CollectionResourcesService |
||||
def initialize |
||||
@storage_service = if FeatureToggle.local_storage? |
||||
Storage::LocalDiskService.new |
||||
else |
||||
Storage::S3Service.new(Configuration::EnvConfigurationService.new, ENV["COLLECTION_RESOURCES_BUCKET"]) |
||||
end |
||||
end |
||||
|
||||
def get_file(file) |
||||
@storage_service.get_file_io(file) |
||||
rescue StandardError |
||||
nil |
||||
end |
||||
|
||||
def get_file_metadata(file) |
||||
@storage_service.get_file_metadata(file) |
||||
rescue StandardError |
||||
nil |
||||
end |
||||
end |
||||
@ -0,0 +1,78 @@
|
||||
<div class="app-filter-layout__filter"> |
||||
<div class="app-filter"> |
||||
<div class="app-filter__header"> |
||||
<h2 class="govuk-heading-m">Filters</h2> |
||||
</div> |
||||
|
||||
<div class="app-filter__content"> |
||||
<%= form_with html: { method: :get } do |f| %> |
||||
|
||||
<div class="govuk-grid-row" style="white-space: nowrap"> |
||||
<p class="govuk-grid-column-one-half"> |
||||
<%= filters_applied_text(@filter_type) %> |
||||
</p> |
||||
<p class="govuk-!-text-align-right govuk-grid-column-one-half"> |
||||
<%= reset_filters_link(@filter_type, { search: request.params["search"] }.compact) %> |
||||
</p> |
||||
</div> |
||||
|
||||
<%= render partial: "filters/checkbox_filter", |
||||
locals: { |
||||
f:, |
||||
options: collection_year_options, |
||||
label: "Collection year", |
||||
category: "years", |
||||
size: "s", |
||||
} %> |
||||
|
||||
<%= render partial: "filters/radio_filter", |
||||
locals: { |
||||
f:, |
||||
options: { |
||||
"all": { label: "Any user" }, |
||||
"you": { label: "You" }, |
||||
"specific_user": { |
||||
label: "Specific user", |
||||
conditional_filter: { |
||||
type: "text_select", |
||||
label: "User", |
||||
category: "user", |
||||
options: uploaded_by_filter_options, |
||||
caption_text: "User's name or email", |
||||
}, |
||||
}, |
||||
}, |
||||
label: "Uploaded by", |
||||
category: "uploaded_by", |
||||
size: "s", |
||||
} %> |
||||
|
||||
<%= render partial: "filters/radio_filter", locals: { |
||||
f:, |
||||
options: { |
||||
"all": { label: "Any organisation" }, |
||||
"specific_org": { |
||||
label: "Specific organisation", |
||||
conditional_filter: { |
||||
type: "select", |
||||
label: "Uploading Organisation", |
||||
category: "uploading_organisation", |
||||
options: all_owning_organisation_filter_options(current_user), |
||||
caption_text: "Organisation name", |
||||
}, |
||||
}, |
||||
}, |
||||
label: "Uploading organisation", |
||||
category: "uploading_organisation_select", |
||||
size: "s", |
||||
} %> |
||||
|
||||
<% if request.params["search"].present? %> |
||||
<%= f.hidden_field :search, value: request.params["search"] %> |
||||
<% end %> |
||||
|
||||
<%= f.govuk_submit "Apply filters", class: "govuk-!-margin-bottom-0" %> |
||||
<% end %> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
@ -0,0 +1,15 @@
|
||||
<h2 class="govuk-body"> |
||||
<div class="govuk-grid-row app-search__caption"> |
||||
<div class="govuk-grid-column-three-quarters"> |
||||
<%= render(SearchResultCaptionComponent.new(searched:, count: pagy.count, item_label:, total_count:, item: "files uploaded in the last 30 days", filters_count: applied_filters_count(@filter_type))) %> |
||||
</div> |
||||
<div class="govuk-grid-column-one-quarter govuk-!-text-align-right"> |
||||
<% if searched || applied_filters_count(@filter_type).positive? %> |
||||
<br> |
||||
<% end %> |
||||
</div> |
||||
</div> |
||||
</h2> |
||||
<% bulk_uploads.map do |bulk_upload| %> |
||||
<%= render BulkUploadSummaryComponent.new(bulk_upload:) %> |
||||
<% end %> |
||||
@ -0,0 +1,28 @@
|
||||
<% item_label = format_label(@pagy.count, "uploads") %> |
||||
<% title = format_title(@searched, bulk_upload_title(controller.controller_name), current_user, item_label, @pagy.count, nil) %> |
||||
|
||||
<% content_for :title, title %> |
||||
|
||||
<h1 class="govuk-heading-l govuk-!-margin-bottom-7"> |
||||
<%= bulk_upload_title(controller.controller_name) %> |
||||
</h1> |
||||
|
||||
<div class="app-filter-layout" data-controller="filter-layout"> |
||||
<%= render partial: "bulk_upload_shared/upload_filters" %> |
||||
|
||||
<div class="app-filter-layout__content"> |
||||
<%= render SearchComponent.new(current_user:, search_label: "Search by file name, user's name or email, or organisation", value: @searched) %> |
||||
<%= govuk_section_break(visible: true, size: "m") %> |
||||
<%= render partial: "bulk_upload_shared/upload_list", |
||||
locals: { |
||||
bulk_uploads: @bulk_uploads, |
||||
title: "Bulk uploads", |
||||
pagy: @pagy, |
||||
searched: @searched, |
||||
item_label:, |
||||
total_count: @total_count, |
||||
filter_type: @filter_type, |
||||
} %> |
||||
<%== render partial: "pagy/nav", locals: { pagy: @pagy, item_name: "bulk uploads" } %> |
||||
</div> |
||||
</div> |
||||
@ -1,12 +1,14 @@
|
||||
<div class="govuk-button-group app-filter-toggle"> |
||||
<% if @organisation.data_protection_confirmed? %> |
||||
<% if current_page?(controller: 'organisations', action: 'lettings_logs') %> |
||||
<%= govuk_button_to "Create a new lettings log for this organisation", lettings_logs_path(lettings_log: { owning_organisation_id: @organisation.id }, method: :post), class: "govuk-!-margin-right-6" %> |
||||
<%= govuk_button_link_to "Upload lettings logs in bulk", bulk_upload_lettings_log_path(id: "start", organisation_id: @organisation.id), secondary: true %> |
||||
<%= govuk_button_to "Create a new lettings log", lettings_logs_path(lettings_log: { owning_organisation_id: @organisation.id }, method: :post), class: "govuk-!-margin-right-6" %> |
||||
<%= govuk_button_link_to "Upload lettings logs in bulk", bulk_upload_lettings_log_path(id: "start", organisation_id: @organisation.id), secondary: true, class: "govuk-!-margin-right-6" %> |
||||
<%= govuk_button_link_to "View lettings bulk uploads", bulk_uploads_lettings_logs_path(organisation_id: @organisation.id, clear_old_filters: true), secondary: true %> |
||||
<% end %> |
||||
<% if current_page?(controller: 'organisations', action: 'sales_logs') %> |
||||
<%= govuk_button_to "Create a new sales log for this organisation", sales_logs_path(sales_log: { owning_organisation_id: @organisation.id }, method: :post), class: "govuk-!-margin-right-6" %> |
||||
<%= govuk_button_link_to "Upload sales logs in bulk", bulk_upload_sales_log_path(id: "start", organisation_id: @organisation.id), secondary: true %> |
||||
<%= govuk_button_to "Create a new sales log", sales_logs_path(sales_log: { owning_organisation_id: @organisation.id }, method: :post), class: "govuk-!-margin-right-6" %> |
||||
<%= govuk_button_link_to "Upload sales logs in bulk", bulk_upload_sales_log_path(id: "start", organisation_id: @organisation.id), secondary: true, class: "govuk-!-margin-right-6" %> |
||||
<%= govuk_button_link_to "View sales bulk uploads", bulk_uploads_sales_logs_path(organisation_id: @organisation.id, clear_old_filters: true), secondary: true %> |
||||
<% end %> |
||||
<% end %> |
||||
</div> |
||||
|
||||
@ -0,0 +1,138 @@
|
||||
<% content_for :before_content do %> |
||||
<%= govuk_back_link href: schemes_organisation_path(@organisation) %> |
||||
<% end %> |
||||
<%= form_with model: @organisation, url: schemes_duplicates_organisation_path(@organisation), method: "post" do |f| %> |
||||
<%= f.govuk_error_summary %> |
||||
|
||||
<% if @duplicate_schemes.any? %> |
||||
<% if @duplicate_locations.any? %> |
||||
<% title = "Review these sets of schemes and locations" %> |
||||
<% else %> |
||||
<% title = "Review these sets of schemes" %> |
||||
<% end %> |
||||
<% else %> |
||||
<% title = "Review these sets of locations" %> |
||||
<% end %> |
||||
|
||||
<% content_for :title, title %> |
||||
|
||||
<% if current_user.support? %> |
||||
<%= render SubNavigationComponent.new( |
||||
items: secondary_items(request.path, @organisation.id), |
||||
) %> |
||||
<% end %> |
||||
|
||||
<div class="govuk-grid-row"> |
||||
<div class="govuk-grid-column-two-thirds-from-desktop"> |
||||
<h1 class="govuk-heading-xl"><%= title %></h1> |
||||
|
||||
<p class="govuk-body">Since your organisation recently merged, we’ve reviewed your schemes for possible duplicates.</p> |
||||
<p class="govuk-body">These sets of schemes and locations might be duplicates because they have the same answers for certain fields.</p> |
||||
<h2 class="govuk-heading-m">What you need to do</h2> |
||||
<ul class="govuk-list govuk-list--bullet"> |
||||
<li>Review each set of schemes or locations and decide if they are duplicates.</li> |
||||
<li>If they are, choose one to keep and deactivate the others on the date your organisation merged.</li> |
||||
<li>When you have resolved all duplicates, confirm below.</li> |
||||
</ul> |
||||
<p class="govuk-body">If you need help with this, <%= govuk_link_to "contact the helpdesk (opens in a new tab)", GlobalConstants::HELPDESK_URL, target: "#" %>.</p> |
||||
|
||||
<% if @duplicate_schemes.any? %> |
||||
<h2 class="govuk-heading-m"><%= @duplicate_schemes.count == 1 ? "This set" : "These #{@duplicate_schemes.count} sets" %> of schemes might have duplicates</h2> |
||||
|
||||
<%= govuk_details(summary_text: "Why are these schemes identified as duplicates?") do %> |
||||
<p class="govuk-body"> |
||||
These schemes have the same answers for the following fields: |
||||
</p> |
||||
<ul class="govuk-list govuk-list--bullet"> |
||||
<li>Type of scheme</li> |
||||
<li>Registered under Care Standards Act 2000</li> |
||||
<li>Housing stock owned by</li> |
||||
<li>Support services provided by</li> |
||||
<li>Primary client group</li> |
||||
<li>Has another client group</li> |
||||
<li>Secondary client group</li> |
||||
<li>Level of support given</li> |
||||
<li>Intended length of stay</li> |
||||
</ul> |
||||
<% end %> |
||||
|
||||
<%= govuk_table do |table| %> |
||||
<%= table.with_head do |head| %> |
||||
<% head.with_row do |row| %> |
||||
<% row.with_cell(header: true, text: "Schemes") %> |
||||
<% end %> |
||||
|
||||
<%= table.with_body do |body| %> |
||||
<% @duplicate_schemes.each do |duplicate_set| %> |
||||
<% body.with_row do |row| %> |
||||
<% row.with_cell do %> |
||||
<ol class="govuk-list govuk-list--number"> |
||||
<% duplicate_set.each do |scheme| %> |
||||
<li> |
||||
<%= govuk_link_to scheme.service_name, scheme %> |
||||
</li> |
||||
<% end %> |
||||
</ol> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
|
||||
<% if @duplicate_locations.any? %> |
||||
<h2 class="govuk-heading-m"><%= @duplicate_locations.count == 1 ? "This set" : "These #{@duplicate_locations.count} sets" %> of locations might have duplicates</h2> |
||||
<%= govuk_details(summary_text: "Why are these locations identified as duplicates?") do %> |
||||
<p class="govuk-body"> |
||||
These locations belong to the same scheme and have the same answers for the following fields: |
||||
</p> |
||||
<ul class="govuk-list govuk-list--bullet"> |
||||
<li>Postcode</li> |
||||
<li>Mobility standards</li> |
||||
</ul> |
||||
<% end %> |
||||
|
||||
<%= govuk_table do |table| %> |
||||
<%= table.with_head do |head| %> |
||||
<% head.with_row do |row| %> |
||||
<% row.with_cell(header: true, text: "Locations") %> |
||||
<% row.with_cell(header: true, text: "Scheme") %> |
||||
<% end %> |
||||
|
||||
<%= table.with_body do |body| %> |
||||
<% @duplicate_locations.each do |duplicate_set| %> |
||||
<% body.with_row do |row| %> |
||||
<% row.with_cell do %> |
||||
<ol class="govuk-list govuk-list--number"> |
||||
<% duplicate_set[:locations].each do |location| %> |
||||
<li> |
||||
<%= govuk_link_to location.name, scheme_location_path(location) %> |
||||
</li> |
||||
<% end %> |
||||
</ol> |
||||
<% end %> |
||||
<% row.with_cell do %> |
||||
<%= govuk_link_to duplicate_set[:scheme].service_name, duplicate_set[:scheme] %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
<% end %> |
||||
|
||||
<%= f.govuk_check_boxes_fieldset :scheme_duplicates_checked, |
||||
legend: { text: "Have you resolved all duplicates?" } do %> |
||||
<%= f.govuk_check_box :scheme_duplicates_checked, |
||||
true, |
||||
false, |
||||
multiple: false, |
||||
checked: false, |
||||
label: { text: "Yes, none of the schemes and locations above are duplicates" } %> |
||||
<% end %> |
||||
|
||||
<%= f.govuk_submit "Confirm" %> |
||||
</div> |
||||
</div> |
||||
<% end %> |
||||
@ -0,0 +1,5 @@
|
||||
class AddSchemesDeduplicatedAt < ActiveRecord::Migration[7.0] |
||||
def change |
||||
add_column :organisations, :schemes_deduplicated_at, :datetime |
||||
end |
||||
end |
||||
@ -0,0 +1,8 @@
|
||||
class AddFailureReasonAndProcessingToBulkUploads < ActiveRecord::Migration[7.0] |
||||
def change |
||||
change_table :bulk_uploads, bulk: true do |t| |
||||
t.string :failure_reason |
||||
t.boolean :processing |
||||
end |
||||
end |
||||
end |
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,148 @@
|
||||
require "rails_helper" |
||||
|
||||
RSpec.describe BulkUploadSummaryComponent, type: :component do |
||||
let(:user) { create(:user) } |
||||
let(:support_user) { create(:user, :support) } |
||||
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, year: 2024, total_logs_count: 10) } |
||||
|
||||
it "shows the file name" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_content(bulk_upload.filename) |
||||
end |
||||
|
||||
it "shows the collection year" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_content("2024/2025") |
||||
end |
||||
|
||||
it "includes a download file link" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_link("Download file", href: "/lettings-logs/bulk-uploads/#{bulk_upload.id}/download") |
||||
end |
||||
|
||||
it "shows the total log count" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_content("10 total logs") |
||||
end |
||||
|
||||
it "shows the uploaded by user" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_content("Uploaded by: #{bulk_upload.user.name}") |
||||
end |
||||
|
||||
it "shows the uploading organisation" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_content("Uploading organisation: #{bulk_upload.user.organisation.name}") |
||||
end |
||||
|
||||
it "shows the time of upload" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_content("Time of upload: #{bulk_upload.created_at.to_formatted_s(:govuk_date_and_time)}") |
||||
end |
||||
|
||||
context "when bulk upload has only critical errors" do |
||||
let(:bulk_upload_errors) { create_list(:bulk_upload_error, 2, category: nil) } |
||||
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, bulk_upload_errors:, total_logs_count: 10) } |
||||
|
||||
it "shows the critical errors status and error count" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_content("Critical errors in CSV") |
||||
expect(result).to have_content("2 critical errors") |
||||
expect(result).to have_no_content("errors on important") |
||||
expect(result).to have_no_content("potential") |
||||
end |
||||
|
||||
it "includes a view error report link" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_link("View error report", href: "/lettings-logs/bulk-upload-results/#{bulk_upload.id}") |
||||
end |
||||
end |
||||
|
||||
context "when bulk upload has only potential errors" do |
||||
let(:bulk_upload_errors) { create_list(:bulk_upload_error, 2, category: "soft_validation") } |
||||
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, bulk_upload_errors:, total_logs_count: 16) } |
||||
|
||||
it "shows the potential errors status and error count" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_content("Potential errors in CSV") |
||||
expect(result).to have_content("2 potential errors") |
||||
expect(result).to have_content("16 total logs") |
||||
expect(result).to have_no_content("errors on important") |
||||
expect(result).to have_no_content("critical") |
||||
end |
||||
end |
||||
|
||||
context "when bulk upload has only errors on important questions" do |
||||
let(:bulk_upload_errors) { create_list(:bulk_upload_error, 2, category: "setup") } |
||||
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, bulk_upload_errors:, total_logs_count: 16) } |
||||
|
||||
it "shows the errors on important questions status and error count" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_content("Errors on important questions in CSV") |
||||
expect(result).to have_content("2 errors on important questions") |
||||
expect(result).to have_content("16 total logs") |
||||
expect(result).to have_no_content("potential") |
||||
expect(result).to have_no_content("critical") |
||||
end |
||||
|
||||
it "includes a view error report link to the summary page" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_link("View error report", href: %r{.*/lettings-logs/bulk-upload-results/#{bulk_upload.id}/summary}) |
||||
end |
||||
end |
||||
|
||||
context "when a bulk upload is uploaded with no errors" do |
||||
let(:bulk_upload) { create(:bulk_upload, :sales, user:, total_logs_count: 1) } |
||||
|
||||
it "shows the logs uploaded with no errors status and no error counts" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_content("Logs uploaded with no errors") |
||||
expect(result).to have_content("1 total log") |
||||
expect(result).to have_no_content("important questions") |
||||
expect(result).to have_no_content("potential") |
||||
expect(result).to have_no_content("critical") |
||||
end |
||||
end |
||||
|
||||
context "when a bulk upload is uploaded with errors" do |
||||
let(:bulk_upload_errors) { create_list(:bulk_upload_error, 1) } |
||||
let(:bulk_upload) { create(:bulk_upload, :sales, user:, bulk_upload_errors:, total_logs_count: 21) } |
||||
|
||||
before do |
||||
create_list(:sales_log, 21, bulk_upload:) |
||||
end |
||||
|
||||
it "shows the logs upload with errors status and error count" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_content("Logs uploaded with errors") |
||||
expect(result).to have_content("21 total logs") |
||||
expect(result).to have_content("1 critical error") |
||||
expect(result).to have_no_content("important questions") |
||||
expect(result).to have_no_content("potential") |
||||
end |
||||
end |
||||
|
||||
context "when a bulk upload uses the wrong template" do |
||||
let(:bulk_upload) { create(:bulk_upload, :sales, user:, failure_reason: "wrong_template") } |
||||
|
||||
it "shows the wrong template status and no error counts" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_content("Wrong template") |
||||
expect(result).to have_no_content("important questions") |
||||
expect(result).to have_no_content("potential") |
||||
expect(result).to have_no_content("critical") |
||||
end |
||||
end |
||||
|
||||
context "when a bulk upload uses a blank template" do |
||||
let(:bulk_upload) { create(:bulk_upload, :sales, user:, failure_reason: "blank_template") } |
||||
|
||||
it "shows the wrong template status and no error counts" do |
||||
result = render_inline(described_class.new(bulk_upload:)) |
||||
expect(result).to have_content("Blank template") |
||||
expect(result).to have_no_content("important questions") |
||||
expect(result).to have_no_content("potential") |
||||
expect(result).to have_no_content("critical") |
||||
end |
||||
end |
||||
end |
||||
Loading…
Reference in new issue