require "rails_helper"
RSpec.describe OrganisationsController, type: :request do
let(:organisation) { user.organisation }
let!(:unauthorised_organisation) { create(:organisation) }
let(:headers) { { "Accept" => "text/html" } }
let(:page) { Capybara::Node::Simple.new(response.body) }
let(:user) { create(:user, :data_coordinator) }
let(:new_value) { "Test Name 35" }
let(:active) { nil }
let(:params) { { id: organisation.id, organisation: { name: new_value, active:, rent_periods: [], all_rent_periods: [] } } }
before do
Timecop.freeze(Time.zone.local(2024, 3, 1))
Singleton.__init__(FormHandler)
end
after do
Timecop.return
Singleton.__init__(FormHandler)
end
context "when user is not signed in" do
describe "#show" do
it "does not let you see organisation details from org route" do
get "/organisations/#{organisation.id}", headers: headers, params: {}
expect(response).to redirect_to("/account/sign-in")
end
it "does not let you see organisation details from details route" do
get "/organisations/#{organisation.id}/details", headers: headers, params: {}
expect(response).to redirect_to("/account/sign-in")
end
it "does not let you see organisation users" do
get "/organisations/#{organisation.id}/users", headers: headers, params: {}
expect(response).to redirect_to("/account/sign-in")
end
it "does not let you see organisations list" do
get "/organisations", headers: headers, params: {}
expect(response).to redirect_to("/account/sign-in")
end
it "does not let you see schemes list" do
get "/organisations/#{organisation.id}/schemes", headers: headers, params: {}
expect(response).to redirect_to("/account/sign-in")
end
end
describe "#delete-confirmation" do
let(:organisation) { create(:organisation) }
before do
get "/organisations/#{organisation.id}/delete-confirmation"
end
context "when not signed in" do
it "redirects to the sign in page" do
expect(response).to redirect_to("/account/sign-in")
end
end
end
describe "#delete" do
let(:organisation) { create(:organisation) }
before do
delete "/organisations/#{organisation.id}/delete"
end
context "when not signed in" do
it "redirects to the sign in page" do
expect(response).to redirect_to("/account/sign-in")
end
end
end
describe "#search" do
it "redirects to the sign in page" do
get "/organisations/search"
expect(response).to redirect_to("/account/sign-in")
end
end
end
context "when user is signed in" do
describe "#schemes" do
context "when support user" do
let(:user) { create(:user, :support) }
let!(:schemes) { create_list(:scheme, 5) }
let!(:same_org_scheme) { create(:scheme, owning_organisation: user.organisation) }
let!(:deleted_scheme) { create(:scheme, owning_organisation: user.organisation, discarded_at: Time.zone.yesterday) }
before do
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
sign_in user
get "/organisations/#{organisation.id}/schemes", headers:, params: {}
end
it "has page heading" do
expect(page).to have_content("Schemes")
end
it "shows a search bar" do
expect(page).to have_field("search", type: "search")
end
describe "scheme and location csv downloads" do
let!(:specific_organisation) { create(:organisation) }
let!(:specific_org_scheme) { create(:scheme, owning_organisation: specific_organisation) }
before do
create_list(:scheme, 5, owning_organisation: specific_organisation)
create_list(:location, 3, scheme: specific_org_scheme)
get "/organisations/#{specific_organisation.id}/schemes", headers:, params: {}
end
it "shows scheme and location download links" do
expect(page).to have_link("Download schemes (CSV)", href: schemes_csv_download_organisation_path(specific_organisation, download_type: "schemes"))
expect(page).to have_link("Download locations (CSV)", href: schemes_csv_download_organisation_path(specific_organisation, download_type: "locations"))
expect(page).to have_link("Download schemes and locations (CSV)", href: schemes_csv_download_organisation_path(specific_organisation, download_type: "combined"))
end
context "when there are no schemes for this organisation" do
before do
specific_organisation.owned_schemes.destroy_all
get "/organisations/#{specific_organisation.id}/schemes", headers:, params: {}
end
it "does not display CSV download links" do
expect(page).not_to have_link("Download schemes (CSV)")
expect(page).not_to have_link("Download locations (CSV)")
expect(page).not_to have_link("Download schemes and locations (CSV)")
end
end
context "when downloading scheme data" do
before do
get schemes_csv_download_organisation_path(specific_organisation, download_type: "schemes")
end
it "redirects to the correct download page" do
expect(page).to have_content("You've selected 6 schemes.")
end
end
context "when downloading location data" do
before do
get schemes_csv_download_organisation_path(specific_organisation, download_type: "locations")
end
it "redirects to the correct download page" do
expect(page).to have_content("You've selected 3 locations from 6 schemes.")
end
end
context "when downloading scheme and location data" do
before do
get schemes_csv_download_organisation_path(specific_organisation, download_type: "combined")
end
it "redirects to the correct download page" do
expect(page).to have_content("You've selected 6 schemes with 3 locations.")
end
end
end
it "has hidden accessibility field with description" do
expected_field = "
Supported housing schemes
"
expect(CGI.unescape_html(response.body)).to include(expected_field)
end
it "shows only schemes belonging to the same organisation" do
expect(page).to have_content(same_org_scheme.id_to_display)
schemes.each do |scheme|
expect(page).not_to have_content(scheme.id_to_display)
end
end
it "does not show deleted schemes" do
expect(page).not_to have_content(deleted_scheme.id_to_display)
end
context "when searching" do
let!(:searched_scheme) { create(:scheme, owning_organisation: user.organisation) }
let(:search_param) { searched_scheme.id }
before do
create(:location, scheme: searched_scheme)
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
get "/organisations/#{organisation.id}/schemes?search=#{search_param}"
end
it "returns matching results" do
expect(page).to have_content(searched_scheme.id_to_display)
schemes.each do |scheme|
expect(page).not_to have_content(scheme.id_to_display)
end
end
it "updates the table caption" do
expect(page).to have_content("1 scheme matching search")
end
it "has search in the title" do
expect(page).to have_title("#{user.organisation.name} (1 scheme matching ‘#{search_param}’) - Submit social housing lettings and sales data (CORE) - GOV.UK")
end
end
context "when organisation has absorbed other organisations" do
before do
create(:organisation, merge_date: Time.zone.today, absorbing_organisation: organisation)
end
context "and it has duplicate schemes or locations" do
before do
create_list(:scheme, 2, :duplicate, owning_organisation: organisation)
get "/organisations/#{organisation.id}/schemes", headers:, params: {}
end
it "displays a banner with correct content" do
expect(page).to have_content("Some schemes and locations might be duplicates.")
expect(page).to have_link("Review possible duplicates", href: "/organisations/#{organisation.id}/schemes/duplicates")
end
end
end
end
context "when data coordinator user" do
let(:user) { create(:user, :data_coordinator) }
let!(:schemes) { create_list(:scheme, 5) }
let!(:same_org_scheme) { create(:scheme, owning_organisation: user.organisation) }
before do
sign_in user
get "/organisations/#{organisation.id}/schemes", headers:, params: {}
end
it "has page heading" do
expect(page).to have_content("Schemes")
end
it "shows a search bar" do
expect(page).to have_field("search", type: "search")
end
describe "scheme and location csv downloads" do
before do
create_list(:scheme, 5, owning_organisation: user.organisation)
create_list(:location, 3, scheme: same_org_scheme)
end
it "shows scheme and location download links" do
expect(page).to have_link("Download schemes (CSV)", href: csv_download_schemes_path(download_type: "schemes"))
expect(page).to have_link("Download locations (CSV)", href: csv_download_schemes_path(download_type: "locations"))
expect(page).to have_link("Download schemes and locations (CSV)", href: csv_download_schemes_path(download_type: "combined"))
end
context "when there are no schemes for this organisation" do
before do
user.organisation.owned_schemes.destroy_all
get "/organisations/#{organisation.id}/schemes", headers:, params: {}
end
it "does not display CSV download links" do
expect(page).not_to have_link("Download schemes (CSV)")
expect(page).not_to have_link("Download locations (CSV)")
expect(page).not_to have_link("Download schemes and locations (CSV)")
end
end
context "when downloading scheme data" do
before do
get csv_download_schemes_path(download_type: "schemes")
end
it "redirects to the correct download page" do
expect(page).to have_content("You've selected 6 schemes.")
end
end
context "when downloading location data" do
before do
get csv_download_schemes_path(download_type: "locations")
end
it "redirects to the correct download page" do
expect(page).to have_content("You've selected 3 locations from 6 schemes.")
end
end
context "when downloading scheme and location data" do
before do
get csv_download_schemes_path(download_type: "combined")
end
it "redirects to the correct download page" do
expect(page).to have_content("You've selected 6 schemes with 3 locations.")
end
end
end
it "shows only schemes belonging to the same organisation" do
expect(page).to have_content(same_org_scheme.id_to_display)
schemes.each do |scheme|
expect(page).not_to have_content(scheme.id_to_display)
end
end
it "shows schemes in alphabetical order" do
schemes[0].update!(service_name: "aaa", owning_organisation: user.organisation)
schemes[1].update!(service_name: "daa", owning_organisation: user.organisation)
schemes[2].update!(service_name: "baa", owning_organisation: user.organisation)
schemes[3].update!(service_name: "Faa", owning_organisation: user.organisation)
schemes[4].update!(service_name: "Caa", owning_organisation: user.organisation)
same_org_scheme.update!(service_name: "zzz", owning_organisation: user.organisation)
get "/organisations/#{organisation.id}/schemes", headers:, params: {}
all_links = page.all(".govuk-link")
scheme_links = all_links.select { |link| link[:href] =~ %r{^/schemes/\d+$} }
expect(scheme_links[0][:href]).to eq("/schemes/#{schemes[0].id}")
expect(scheme_links[1][:href]).to eq("/schemes/#{schemes[2].id}")
expect(scheme_links[2][:href]).to eq("/schemes/#{schemes[4].id}")
expect(scheme_links[3][:href]).to eq("/schemes/#{schemes[1].id}")
expect(scheme_links[4][:href]).to eq("/schemes/#{schemes[3].id}")
expect(scheme_links[5][:href]).to eq("/schemes/#{same_org_scheme.id}")
end
context "with schemes that are not in scope for the user, i.e. that they do not belong to" do
let!(:unauthorised_organisation) { create(:organisation) }
before do
get "/organisations/#{unauthorised_organisation.id}/schemes", headers:, params: {}
end
it "returns not found 404 from org details route" do
expect(response).to have_http_status(:not_found)
end
end
context "when searching" do
let!(:searched_scheme) { create(:scheme, owning_organisation: user.organisation) }
let(:search_param) { searched_scheme.id_to_display }
before do
create(:location, scheme: searched_scheme)
get "/organisations/#{organisation.id}/schemes?search=#{search_param}"
end
it "returns matching results" do
expect(page).to have_content(searched_scheme.id_to_display)
schemes.each do |scheme|
expect(page).not_to have_content(scheme.id_to_display)
end
end
it "updates the table caption" do
expect(page).to have_content("1 scheme matching search")
end
it "has search in the title" do
expect(page).to have_title("Supported housing schemes (1 scheme matching ‘#{search_param}’) - Submit social housing lettings and sales data (CORE) - GOV.UK")
end
end
end
end
describe "#duplicate_schemes" do
context "with support user" do
let(:user) { create(:user, :support) }
before do
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
sign_in user
get "/organisations/#{organisation.id}/schemes/duplicates", headers:
end
context "with duplicate schemes and locations" do
let(:schemes) { create_list(:scheme, 5, :duplicate, owning_organisation: organisation) }
before do
create_list(:location, 2, scheme: schemes.first, postcode: "M1 1AA", mobility_type: "M")
create_list(:location, 2, scheme: schemes.first, postcode: "M1 1AA", mobility_type: "A")
get "/organisations/#{organisation.id}/schemes/duplicates", headers:
end
it "displays the duplicate schemes" do
expect(page).to have_content("This set of schemes might have duplicates")
end
it "displays the duplicate locations" do
expect(page).to have_content("These 2 sets of locations might have duplicates")
end
it "has page heading" do
expect(page).to have_content("Review these sets of schemes and locations")
end
end
context "without duplicate schemes and locations" do
it "does not display the schemes" do
expect(page).not_to have_content("schemes might have duplicates")
end
it "does not display the locations" do
expect(page).not_to have_content("locations might have duplicates")
end
end
end
context "with data coordinator user" do
let(:user) { create(:user, :data_coordinator) }
before do
sign_in user
create_list(:scheme, 5, :duplicate, owning_organisation: organisation)
get "/organisations/#{organisation.id}/schemes/duplicates", headers:
end
it "has page heading" do
expect(page).to have_content("Review these sets of schemes")
end
end
context "with data provider user" do
let(:user) { create(:user, :data_provider) }
before do
sign_in user
get "/organisations/#{organisation.id}/schemes/duplicates", headers:
end
it "be unauthorised" do
expect(response).to have_http_status(:unauthorized)
end
end
end
describe "#show" do
context "with an organisation that the user belongs to" do
let(:set_time) {}
before do
set_time
sign_in user
get "/organisations/#{organisation.id}", headers:, params: {}
end
it "redirects to details" do
expect(response).to have_http_status(:redirect)
end
end
context "with an organisation that are not in scope for the user, i.e. that they do not belong to" do
before do
sign_in user
get "/organisations/#{unauthorised_organisation.id}", headers:, params: {}
end
it "returns not found 404 from org route" do
expect(response).to have_http_status(:not_found)
end
it "shows the 404 view" do
expect(page).to have_content("Page not found")
end
end
end
context "with a data coordinator user" do
before do
sign_in user
end
context "when we access the details tab" do
context "with an organisation that the user belongs to" do
before do
get "/organisations/#{organisation.id}/details", headers:, params: {}
end
it "shows the tab navigation" do
expected_html = "