From 922b8d13c262a7cffcf5c0c3b1e0e53576e05f31 Mon Sep 17 00:00:00 2001 From: baarkerlounger <5101747+baarkerlounger@users.noreply.github.com> Date: Mon, 6 Jun 2022 13:28:01 +0100 Subject: [PATCH] CLDC-1281: Enable support users to create organisations (#636) * Allow support users to create organisations * Lint * Add registration number field * Lint * Check params are set correctly --- app/controllers/organisations_controller.rb | 28 +- app/views/organisations/index.html.erb | 4 + app/views/organisations/new.html.erb | 65 ++ .../requests/organisations_controller_spec.rb | 654 +++++++++++------- 4 files changed, 477 insertions(+), 274 deletions(-) create mode 100644 app/views/organisations/new.html.erb diff --git a/app/controllers/organisations_controller.rb b/app/controllers/organisations_controller.rb index 4452fc4a0..d57f9b215 100644 --- a/app/controllers/organisations_controller.rb +++ b/app/controllers/organisations_controller.rb @@ -4,8 +4,8 @@ class OrganisationsController < ApplicationController include Modules::SearchFilter before_action :authenticate_user! - before_action :find_resource, except: [:index] - before_action :authenticate_scope! + before_action :find_resource, except: %i[index new create] + before_action :authenticate_scope!, except: [:index] def index redirect_to organisation_path(current_user.organisation) unless current_user.support? @@ -27,7 +27,7 @@ class OrganisationsController < ApplicationController if current_user.support? render "users", layout: "application" else - render "/users/index" + render "users/index" end end @@ -35,6 +35,20 @@ class OrganisationsController < ApplicationController render "show" end + def new + @resource = Organisation.new + render "new", layout: "application" + end + + def create + organisation = Organisation.create(org_params) + if organisation.persisted? + redirect_to organisations_path + else + render :new, status: :unprocessable_entity + end + end + def edit if current_user.data_coordinator? || current_user.support? render "edit", layout: "application" @@ -74,7 +88,7 @@ class OrganisationsController < ApplicationController private def org_params - params.require(:organisation).permit(:name, :address_line1, :address_line2, :postcode, :phone) + params.require(:organisation).permit(:name, :address_line1, :address_line2, :postcode, :phone, :holds_own_stock, :provider_type, :housing_registration_no) end def search_term @@ -82,7 +96,11 @@ private end def authenticate_scope! - render_not_found if current_user.organisation != @organisation && !current_user.support? + if %w[create new].include? action_name + head :unauthorized and return unless current_user.support? + elsif current_user.organisation != @organisation && !current_user.support? + render_not_found + end end def find_resource diff --git a/app/views/organisations/index.html.erb b/app/views/organisations/index.html.erb index b8560f072..15456642a 100644 --- a/app/views/organisations/index.html.erb +++ b/app/views/organisations/index.html.erb @@ -7,6 +7,10 @@ <% content_for :title, title %> +<% if current_user.support? %> + <%= govuk_button_link_to "Create a new organisation", new_organisation_path, html: { method: :get } %> +<% end %> + <%= render SearchComponent.new(current_user:, search_label: "Search by organisation name", value: @searched) %>
diff --git a/app/views/organisations/new.html.erb b/app/views/organisations/new.html.erb new file mode 100644 index 000000000..39d372528 --- /dev/null +++ b/app/views/organisations/new.html.erb @@ -0,0 +1,65 @@ +<% content_for :title, "Create a new organisation" %> + +<% content_for :before_content do %> + <%= govuk_back_link( + text: "Back", + href: :back, + ) %> +<% end %> + +<%= form_for(@resource, as: :organisation, html: { method: :post }) do |f| %> +
+
+ <%= f.govuk_error_summary %> + +

+ <%= content_for(:title) %> +

+ + <%= f.govuk_text_field :name, + label: { size: "m" }, + autocomplete: "name" %> + + <%= f.govuk_text_field :address_line1, + label: { text: "Address line 1", size: "m" }, + autocomplete: "address-line1" %> + + <%= f.govuk_text_field :address_line2, + label: { text: "Address line 2", size: "m" }, + autocomplete: "address-line2" %> + + <%= f.govuk_text_field :postcode, + label: { size: "m" }, + autocomplete: "postal-code", + width: 10 %> + + <%= f.govuk_phone_field :phone, + label: { text: "Telephone number", size: "m" }, + autocomplete: "tel", + width: 20 %> + + <%= f.govuk_text_field :housing_registration_no, + label: { text: "Regulator of Social Housing registration number", size: "m" }, + width: 10 %> + + <% null_option = [OpenStruct.new(id: "", name: "Select an option")] %> + <% types = Organisation::PROVIDER_TYPE.map { |key, _val| OpenStruct.new(id: key, name: Organisation::DISPLAY_PROVIDER_TYPE[key]) } %> + <% type_answer_options = null_option + types %> + + <%= f.govuk_collection_select :provider_type, + type_answer_options, + :id, + :name, + label: { text: "Organisation type", size: "m" }, + options: { disabled: [""], selected: @resource.provider_type || "" } %> + + <%= f.govuk_collection_radio_buttons :holds_own_stock, + [OpenStruct.new(id: true, name: "Yes"), OpenStruct.new(id: false, name: "No")], + :id, + :name, + legend: { text: "Does the organisation hold it's own stock?", size: "m" } %> + + <%= f.govuk_submit "Create organisation" %> +
+
+<% end %> diff --git a/spec/requests/organisations_controller_spec.rb b/spec/requests/organisations_controller_spec.rb index 5647cfe7a..74d7aba46 100644 --- a/spec/requests/organisations_controller_spec.rb +++ b/spec/requests/organisations_controller_spec.rb @@ -251,6 +251,52 @@ RSpec.describe OrganisationsController, type: :request do expect(response).to redirect_to("/logs") end end + + describe "#index" do + before do + get "/organisations", headers:, params: + end + + it "redirects to the user's organisation" do + expect(response).to redirect_to("/organisations/#{user.organisation.id}") + end + end + + describe "#new" do + let(:request) { get "/organisations/new", headers:, params: } + + it "returns 401 unauthorized" do + request + expect(response).to have_http_status(:unauthorized) + end + end + + describe "#create" do + let(:params) do + { + "organisation": { + name: "new organisation", + address_line1: "12 Random Street", + address_line2: "Manchester", + postcode: "MD1 5TR", + phone: "011101101", + provider_type: "LA", + holds_own_stock: "true", + housing_registration_no: "7917937", + }, + } + end + let(:request) { post "/organisations", headers:, params: } + + it "returns 401 unauthorized" do + request + expect(response).to have_http_status(:unauthorized) + end + + it "does not create an organisation" do + expect { request }.not_to change(Organisation, :count) + end + end end context "with a data provider user" do @@ -361,224 +407,231 @@ RSpec.describe OrganisationsController, type: :request do before do allow(user).to receive(:need_two_factor_authentication?).and_return(false) sign_in user - get "/organisations" end - it "shows all organisations" do - total_number_of_orgs = Organisation.all.count - expect(page).to have_link organisation.name, href: "organisations/#{organisation.id}/logs" - expect(page).to have_link unauthorised_organisation.name, href: "organisations/#{unauthorised_organisation.id}/logs" - expect(page).to have_content("#{total_number_of_orgs} total organisations") - end + describe "#new" do + let(:request) { get "/organisations/new", headers:, params: } - it "shows a search bar" do - expect(page).to have_field("search", type: "search") + it "shows the create organisation form" do + request + expect(page).to have_field("organisation[name]") + expect(page).to have_field("organisation[phone]") + expect(page).to have_field("organisation[provider_type]") + expect(page).to have_field("organisation[address_line1]") + expect(page).to have_field("organisation[address_line2]") + expect(page).to have_field("organisation[postcode]") + expect(page).to have_field("organisation[holds_own_stock]") + end end - context "when viewing a specific organisation" do - let(:number_of_org1_case_logs) { 2 } - let(:number_of_org2_case_logs) { 4 } - + describe "#index" do before do - FactoryBot.create_list(:case_log, number_of_org1_case_logs, owning_organisation_id: organisation.id, managing_organisation_id: organisation.id) - FactoryBot.create_list(:case_log, number_of_org2_case_logs, owning_organisation_id: unauthorised_organisation.id, managing_organisation_id: unauthorised_organisation.id) - - get "/organisations/#{organisation.id}/logs", headers:, params: {} + get "/organisations", headers:, params: {} end - it "only shows logs for that organisation" do - expect(page).to have_content("#{number_of_org1_case_logs} total logs") - organisation.case_logs.map(&:id).each do |case_log_id| - expect(page).to have_link case_log_id.to_s, href: "/logs/#{case_log_id}" - end - - unauthorised_organisation.case_logs.map(&:id).each do |case_log_id| - expect(page).not_to have_link case_log_id.to_s, href: "/logs/#{case_log_id}" - end + it "shows the organisation list" do + expect(page).to have_content("Organisations") end - it "has filters" do - expect(page).to have_content("Filters") - expect(page).to have_content("Collection year") + it "has a create new organisation button" do + expect(page).to have_link("Create a new organisation", href: "/organisations/new") end - it "does not have specific organisation filter" do - expect(page).not_to have_content("Specific organisation") + it "shows all organisations" do + total_number_of_orgs = Organisation.all.count + expect(page).to have_link organisation.name, href: "organisations/#{organisation.id}/logs" + expect(page).to have_link unauthorised_organisation.name, href: "organisations/#{unauthorised_organisation.id}/logs" + expect(page).to have_content("#{total_number_of_orgs} total organisations") end - it "has a sub-navigation with correct tabs" do - expect(page).to have_css(".app-sub-navigation") - expect(page).to have_content("About this organisation") + it "shows a search bar" do + expect(page).to have_field("search", type: "search") end - context "when using a search query" do - let(:logs) { FactoryBot.create_list(:case_log, 3, :completed, owning_organisation: user.organisation) } - let(:log_to_search) { FactoryBot.create(:case_log, :completed, owning_organisation: user.organisation) } - let(:log_total_count) { CaseLog.where(owning_organisation: user.organisation).count } + context "when viewing a specific organisation's logs" do + let(:number_of_org1_case_logs) { 2 } + let(:number_of_org2_case_logs) { 4 } - it "has search results in the title" do - get "/organisations/#{organisation.id}/logs?search=#{log_to_search.id}", headers: headers, params: {} - expect(page).to have_title("Your organisation (1 log matching ‘#{log_to_search.id}’ of #{log_total_count} total logs) - Submit social housing lettings and sales data (CORE) - GOV.UK") + before do + FactoryBot.create_list(:case_log, number_of_org1_case_logs, owning_organisation_id: organisation.id, managing_organisation_id: organisation.id) + FactoryBot.create_list(:case_log, number_of_org2_case_logs, owning_organisation_id: unauthorised_organisation.id, managing_organisation_id: unauthorised_organisation.id) + + get "/organisations/#{organisation.id}/logs", headers:, params: {} end - it "shows case logs matching the id" do - get "/organisations/#{organisation.id}/logs?search=#{log_to_search.id}", headers: headers, params: {} - expect(page).to have_link(log_to_search.id.to_s) - logs.each do |log| - expect(page).not_to have_link(log.id.to_s) + it "only shows logs for that organisation" do + expect(page).to have_content("#{number_of_org1_case_logs} total logs") + organisation.case_logs.map(&:id).each do |case_log_id| + expect(page).to have_link case_log_id.to_s, href: "/logs/#{case_log_id}" end - end - it "shows case logs matching the tenant code" do - get "/organisations/#{organisation.id}/logs?search=#{log_to_search.tenant_code}", headers: headers, params: {} - expect(page).to have_link(log_to_search.id.to_s) - logs.each do |log| - expect(page).not_to have_link(log.id.to_s) + unauthorised_organisation.case_logs.map(&:id).each do |case_log_id| + expect(page).not_to have_link case_log_id.to_s, href: "/logs/#{case_log_id}" end end - it "shows case logs matching the property reference" do - get "/organisations/#{organisation.id}/logs?search=#{log_to_search.propcode}", headers: headers, params: {} - expect(page).to have_link(log_to_search.id.to_s) - logs.each do |log| - expect(page).not_to have_link(log.id.to_s) - end + it "has filters" do + expect(page).to have_content("Filters") + expect(page).to have_content("Collection year") end - it "shows case logs matching the property postcode" do - get "/organisations/#{organisation.id}/logs?search=#{log_to_search.postcode_full}", headers: headers, params: {} - expect(page).to have_link(log_to_search.id.to_s) - logs.each do |log| - expect(page).not_to have_link(log.id.to_s) - end + it "does not have specific organisation filter" do + expect(page).not_to have_content("Specific organisation") end - context "when more than one results with matching postcode" do - let!(:matching_postcode_log) { FactoryBot.create(:case_log, :completed, owning_organisation: user.organisation, postcode_full: log_to_search.postcode_full) } + it "has a sub-navigation with correct tabs" do + expect(page).to have_css(".app-sub-navigation") + expect(page).to have_content("About this organisation") + end - it "displays all matching logs" do - get "/organisations/#{organisation.id}/logs?search=#{log_to_search.postcode_full}", headers: headers, params: {} + context "when using a search query" do + let(:logs) { FactoryBot.create_list(:case_log, 3, :completed, owning_organisation: user.organisation) } + let(:log_to_search) { FactoryBot.create(:case_log, :completed, owning_organisation: user.organisation) } + let(:log_total_count) { CaseLog.where(owning_organisation: user.organisation).count } + + it "has search results in the title" do + get "/organisations/#{organisation.id}/logs?search=#{log_to_search.id}", headers: headers, params: {} + expect(page).to have_title("Your organisation (1 log matching ‘#{log_to_search.id}’ of #{log_total_count} total logs) - Submit social housing lettings and sales data (CORE) - GOV.UK") + end + + it "shows case logs matching the id" do + get "/organisations/#{organisation.id}/logs?search=#{log_to_search.id}", headers: headers, params: {} expect(page).to have_link(log_to_search.id.to_s) - expect(page).to have_link(matching_postcode_log.id.to_s) logs.each do |log| expect(page).not_to have_link(log.id.to_s) end end - end - - context "when there are more than 1 page of search results" do - let(:postcode) { "XX11YY" } - let(:logs) { FactoryBot.create_list(:case_log, 30, :completed, owning_organisation: user.organisation, postcode_full: postcode) } - let(:log_total_count) { CaseLog.where(owning_organisation: user.organisation).count } - - it "has title with pagination details for page 1" do - get "/organisations/#{organisation.id}/logs?search=#{logs[0].postcode_full}", headers: headers, params: {} - expect(page).to have_title("Your organisation (#{logs.count} logs matching ‘#{postcode}’ of #{log_total_count} total logs) (page 1 of 2) - Submit social housing lettings and sales data (CORE) - GOV.UK") - end - it "has title with pagination details for page 2" do - get "/organisations/#{organisation.id}/logs?search=#{logs[0].postcode_full}&page=2", headers: headers, params: {} - expect(page).to have_title("Your organisation (#{logs.count} logs matching ‘#{postcode}’ of #{log_total_count} total logs) (page 2 of 2) - Submit social housing lettings and sales data (CORE) - GOV.UK") + it "shows case logs matching the tenant code" do + get "/organisations/#{organisation.id}/logs?search=#{log_to_search.tenant_code}", headers: headers, params: {} + expect(page).to have_link(log_to_search.id.to_s) + logs.each do |log| + expect(page).not_to have_link(log.id.to_s) + end end - end - context "when search query doesn't match any logs" do - it "doesn't display any logs" do - get "/organisations/#{organisation.id}/logs?search=foobar", headers:, params: {} + it "shows case logs matching the property reference" do + get "/organisations/#{organisation.id}/logs?search=#{log_to_search.propcode}", headers: headers, params: {} + expect(page).to have_link(log_to_search.id.to_s) logs.each do |log| expect(page).not_to have_link(log.id.to_s) end - expect(page).not_to have_link(log_to_search.id.to_s) end - end - context "when search query is empty" do - it "doesn't display any logs" do - get "/organisations/#{organisation.id}/logs?search=", headers:, params: {} + it "shows case logs matching the property postcode" do + get "/organisations/#{organisation.id}/logs?search=#{log_to_search.postcode_full}", headers: headers, params: {} + expect(page).to have_link(log_to_search.id.to_s) logs.each do |log| expect(page).not_to have_link(log.id.to_s) end - expect(page).not_to have_link(log_to_search.id.to_s) end - end - context "when search and filter is present" do - let(:matching_postcode) { log_to_search.postcode_full } - let(:matching_status) { "in_progress" } - let!(:log_matching_filter_and_search) { FactoryBot.create(:case_log, :in_progress, owning_organisation: user.organisation, postcode_full: matching_postcode) } + context "when more than one results with matching postcode" do + let!(:matching_postcode_log) { FactoryBot.create(:case_log, :completed, owning_organisation: user.organisation, postcode_full: log_to_search.postcode_full) } - it "shows only logs matching both search and filters" do - get "/organisations/#{organisation.id}/logs?search=#{matching_postcode}&status[]=#{matching_status}", headers: headers, params: {} - expect(page).to have_content(log_matching_filter_and_search.id) - expect(page).not_to have_content(log_to_search.id) - logs.each do |log| - expect(page).not_to have_content(log.id) + it "displays all matching logs" do + get "/organisations/#{organisation.id}/logs?search=#{log_to_search.postcode_full}", headers: headers, params: {} + expect(page).to have_link(log_to_search.id.to_s) + expect(page).to have_link(matching_postcode_log.id.to_s) + logs.each do |log| + expect(page).not_to have_link(log.id.to_s) + end end end - end - end - end - context "when viewing a specific organisation users" do - let!(:users) { FactoryBot.create_list(:user, 5, organisation:) } - let!(:different_org_users) { FactoryBot.create_list(:user, 5) } + context "when there are more than 1 page of search results" do + let(:postcode) { "XX11YY" } + let(:logs) { FactoryBot.create_list(:case_log, 30, :completed, owning_organisation: user.organisation, postcode_full: postcode) } + let(:log_total_count) { CaseLog.where(owning_organisation: user.organisation).count } - before do - get "/organisations/#{organisation.id}/users", headers:, params: {} - end + it "has title with pagination details for page 1" do + get "/organisations/#{organisation.id}/logs?search=#{logs[0].postcode_full}", headers: headers, params: {} + expect(page).to have_title("Your organisation (#{logs.count} logs matching ‘#{postcode}’ of #{log_total_count} total logs) (page 1 of 2) - Submit social housing lettings and sales data (CORE) - GOV.UK") + end - it "displays the name of the organisation" do - expect(page).to have_content(organisation.name) - end + it "has title with pagination details for page 2" do + get "/organisations/#{organisation.id}/logs?search=#{logs[0].postcode_full}&page=2", headers: headers, params: {} + expect(page).to have_title("Your organisation (#{logs.count} logs matching ‘#{postcode}’ of #{log_total_count} total logs) (page 2 of 2) - Submit social housing lettings and sales data (CORE) - GOV.UK") + end + end - it "has a sub-navigation with correct tabs" do - expect(page).to have_css(".app-sub-navigation") - expect(page).to have_content("Users") - end + context "when search query doesn't match any logs" do + it "doesn't display any logs" do + get "/organisations/#{organisation.id}/logs?search=foobar", headers:, params: {} + logs.each do |log| + expect(page).not_to have_link(log.id.to_s) + end + expect(page).not_to have_link(log_to_search.id.to_s) + end + end - it "displays users for this organisation" do - expect(page).to have_content(user.email) - users.each do |user| - expect(page).to have_content(user.email) - end - end + context "when search query is empty" do + it "doesn't display any logs" do + get "/organisations/#{organisation.id}/logs?search=", headers:, params: {} + logs.each do |log| + expect(page).not_to have_link(log.id.to_s) + end + expect(page).not_to have_link(log_to_search.id.to_s) + end + end - it "doesn't display users for other organisations" do - different_org_users.each do |different_org_user| - expect(page).not_to have_content(different_org_user.email) + context "when search and filter is present" do + let(:matching_postcode) { log_to_search.postcode_full } + let(:matching_status) { "in_progress" } + let!(:log_matching_filter_and_search) { FactoryBot.create(:case_log, :in_progress, owning_organisation: user.organisation, postcode_full: matching_postcode) } + + it "shows only logs matching both search and filters" do + get "/organisations/#{organisation.id}/logs?search=#{matching_postcode}&status[]=#{matching_status}", headers: headers, params: {} + expect(page).to have_content(log_matching_filter_and_search.id) + expect(page).not_to have_content(log_to_search.id) + logs.each do |log| + expect(page).not_to have_content(log.id) + end + end + end end end - context "when a search parameter is passed" do - let!(:matching_user) { FactoryBot.create(:user, organisation:, name: "joe", email: "matching@example.com") } - let(:org_user_count) { User.where(organisation:).count } + context "when viewing a specific organisation's users" do + let!(:users) { FactoryBot.create_list(:user, 5, organisation:) } + let!(:different_org_users) { FactoryBot.create_list(:user, 5) } before do - get "/organisations/#{user.organisation.id}/users?search=#{search_param}" + get "/organisations/#{organisation.id}/users", headers:, params: {} end - context "when our search string matches case" do - let(:search_param) { "joe" } + it "displays the name of the organisation" do + expect(page).to have_content(organisation.name) + end - it "returns only matching results" do - expect(page).to have_content(matching_user.name) - expect(page).not_to have_link(user.name) + it "has a sub-navigation with correct tabs" do + expect(page).to have_css(".app-sub-navigation") + expect(page).to have_content("Users") + end - different_org_users.each do |different_org_user| - expect(page).not_to have_content(different_org_user.email) - end + it "displays users for this organisation" do + expect(page).to have_content(user.email) + users.each do |user| + expect(page).to have_content(user.email) + end + end - users.each do |org_user| - expect(page).not_to have_content(org_user.email) - end + it "doesn't display users for other organisations" do + different_org_users.each do |different_org_user| + expect(page).not_to have_content(different_org_user.email) end + end - it "updates the table caption" do - expect(page).to have_content("1 user found matching ‘#{search_param}’ of #{org_user_count} total users.") + context "when a search parameter is passed" do + let!(:matching_user) { FactoryBot.create(:user, organisation:, name: "joe", email: "matching@example.com") } + let(:org_user_count) { User.where(organisation:).count } + + before do + get "/organisations/#{user.organisation.id}/users?search=#{search_param}" end - context "when we need case insensitive search" do - let(:search_param) { "Joe" } + context "when our search string matches case" do + let(:search_param) { "joe" } it "returns only matching results" do expect(page).to have_content(matching_user.name) @@ -596,42 +649,34 @@ RSpec.describe OrganisationsController, type: :request do it "updates the table caption" do expect(page).to have_content("1 user found matching ‘#{search_param}’ of #{org_user_count} total users.") end - end - end - context "when our search term matches an email" do - let(:search_param) { "matching@example.com" } + context "when we need case insensitive search" do + let(:search_param) { "Joe" } - it "returns only matching results" do - expect(page).to have_content(matching_user.name) - expect(page).not_to have_link(user.name) + it "returns only matching results" do + expect(page).to have_content(matching_user.name) + expect(page).not_to have_link(user.name) - different_org_users.each do |different_org_user| - expect(page).not_to have_content(different_org_user.email) - end + different_org_users.each do |different_org_user| + expect(page).not_to have_content(different_org_user.email) + end - users.each do |org_user| - expect(page).not_to have_content(org_user.email) - end - end + users.each do |org_user| + expect(page).not_to have_content(org_user.email) + end + end - it "updates the table caption" do - expect(page).to have_content("1 user found matching ‘#{search_param}’ of #{org_user_count} total users.") + it "updates the table caption" do + expect(page).to have_content("1 user found matching ‘#{search_param}’ of #{org_user_count} total users.") + end + end end - context "when our search term matches an email and a name" do - let!(:matching_user) { FactoryBot.create(:user, organisation:, name: "Foobar", email: "some@example.com") } - let!(:another_matching_user) { FactoryBot.create(:user, organisation:, name: "Joe", email: "foobar@example.com") } - let!(:org_user_count) { User.where(organisation:).count } - let(:search_param) { "Foobar" } - - before do - get "/organisations/#{user.organisation.id}/users?search=#{search_param}" - end + context "when our search term matches an email" do + let(:search_param) { "matching@example.com" } it "returns only matching results" do - expect(page).to have_link(matching_user.name) - expect(page).to have_link(another_matching_user.name) + expect(page).to have_content(matching_user.name) expect(page).not_to have_link(user.name) different_org_users.each do |different_org_user| @@ -644,132 +689,203 @@ RSpec.describe OrganisationsController, type: :request do end it "updates the table caption" do - expect(page).to have_content("2 users found matching ‘#{search_param}’ of #{org_user_count} total users.") + expect(page).to have_content("1 user found matching ‘#{search_param}’ of #{org_user_count} total users.") + end + + context "when our search term matches an email and a name" do + let!(:matching_user) { FactoryBot.create(:user, organisation:, name: "Foobar", email: "some@example.com") } + let!(:another_matching_user) { FactoryBot.create(:user, organisation:, name: "Joe", email: "foobar@example.com") } + let!(:org_user_count) { User.where(organisation:).count } + let(:search_param) { "Foobar" } + + before do + get "/organisations/#{user.organisation.id}/users?search=#{search_param}" + end + + it "returns only matching results" do + expect(page).to have_link(matching_user.name) + expect(page).to have_link(another_matching_user.name) + expect(page).not_to have_link(user.name) + + different_org_users.each do |different_org_user| + expect(page).not_to have_content(different_org_user.email) + end + + users.each do |org_user| + expect(page).not_to have_content(org_user.email) + end + end + + it "updates the table caption" do + expect(page).to have_content("2 users found matching ‘#{search_param}’ of #{org_user_count} total users.") + end end end end end - end - context "when viewing a specific organisation details" do - before do - get "/organisations/#{organisation.id}/details", headers:, params: {} - end + context "when viewing a specific organisation's details" do + before do + get "/organisations/#{organisation.id}/details", headers:, params: {} + end - it "displays the name of the organisation" do - expect(page).to have_content(organisation.name) - end + it "displays the name of the organisation" do + expect(page).to have_content(organisation.name) + end - it "has a sub-navigation with correct tabs" do - expect(page).to have_css(".app-sub-navigation") - expect(page).to have_content("About this organisation") - end + it "has a sub-navigation with correct tabs" do + expect(page).to have_css(".app-sub-navigation") + expect(page).to have_content("About this organisation") + end - it "allows to edit the organisation details" do - expect(page).to have_link("Change", count: 3) + it "allows to edit the organisation details" do + expect(page).to have_link("Change", count: 3) + end end - end - end - context "when there are more than 20 organisations" do - let(:support_user) { FactoryBot.create(:user, :support) } + context "when there are more than 20 organisations" do + let(:total_organisations_count) { Organisation.all.count } - let(:total_organisations_count) { Organisation.all.count } + before do + FactoryBot.create_list(:organisation, 25) + get "/organisations" + end - before do - FactoryBot.create_list(:organisation, 25) - allow(support_user).to receive(:need_two_factor_authentication?).and_return(false) - sign_in support_user - get "/organisations" - end + context "when on the first page" do + it "has pagination links" do + expect(page).to have_content("Previous") + expect(page).not_to have_link("Previous") + expect(page).to have_content("Next") + expect(page).to have_link("Next") + end - context "when on the first page" do - it "has pagination links" do - expect(page).to have_content("Previous") - expect(page).not_to have_link("Previous") - expect(page).to have_content("Next") - expect(page).to have_link("Next") - end + it "shows which organisations are being shown on the current page" do + expect(CGI.unescape_html(response.body)).to match("Showing 1 to 20 of #{total_organisations_count} organisations") + end - it "shows which organisations are being shown on the current page" do - expect(CGI.unescape_html(response.body)).to match("Showing 1 to 20 of #{total_organisations_count} organisations") - end + it "has pagination in the title" do + expect(page).to have_title("Organisations (page 1 of 2)") + end + end - it "has pagination in the title" do - expect(page).to have_title("Organisations (page 1 of 2)") - end - end + context "when on the second page" do + before do + get "/organisations?page=2", headers:, params: {} + end - context "when on the second page" do - before do - get "/organisations?page=2", headers:, params: {} - end + it "shows the total organisations count" do + expect(CGI.unescape_html(response.body)).to match("#{total_organisations_count} total organisations.") + end - it "shows the total organisations count" do - expect(CGI.unescape_html(response.body)).to match("#{total_organisations_count} total organisations.") - end + it "has pagination links" do + expect(page).to have_content("Previous") + expect(page).to have_link("Previous") + expect(page).to have_content("Next") + expect(page).not_to have_link("Next") + end - it "has pagination links" do - expect(page).to have_content("Previous") - expect(page).to have_link("Previous") - expect(page).to have_content("Next") - expect(page).not_to have_link("Next") - end + it "shows which logs are being shown on the current page" do + expect(CGI.unescape_html(response.body)).to match("Showing 21 to #{total_organisations_count} of #{total_organisations_count} organisations") + end - it "shows which logs are being shown on the current page" do - expect(CGI.unescape_html(response.body)).to match("Showing 21 to #{total_organisations_count} of #{total_organisations_count} organisations") - end + it "has pagination in the title" do + expect(page).to have_title("Organisations (page 2 of 2)") + end + end - it "has pagination in the title" do - expect(page).to have_title("Organisations (page 2 of 2)") - end - end + context "when searching" do + let!(:searched_organisation) { FactoryBot.create(:organisation, name: "Unusual name") } + let!(:other_organisation) { FactoryBot.create(:organisation, name: "Some other name") } + let(:search_param) { "Unusual" } - context "when searching" do - let!(:searched_organisation) { FactoryBot.create(:organisation, name: "Unusual name") } - let!(:other_organisation) { FactoryBot.create(:organisation, name: "Some other name") } - let(:search_param) { "Unusual" } + before do + get "/organisations?search=#{search_param}" + end - before do - get "/organisations?search=#{search_param}" - end + it "returns matching results" do + expect(page).to have_content(searched_organisation.name) + expect(page).not_to have_content(other_organisation.name) + end - it "returns matching results" do - expect(page).to have_content(searched_organisation.name) - expect(page).not_to have_content(other_organisation.name) - end + it "updates the table caption" do + expect(page).to have_content("1 organisation found matching ‘#{search_param}’ of 29 total organisations.") + end - it "updates the table caption" do - expect(page).to have_content("1 organisation found matching ‘#{search_param}’ of 29 total organisations.") - end + it "has search in the title" do + expect(page).to have_title("Organisations (1 organisation matching ‘#{search_param}’ of 29 total organisations) - Submit social housing lettings and sales data (CORE) - GOV.UK") + end - it "has search in the title" do - expect(page).to have_title("Organisations (1 organisation matching ‘#{search_param}’ of 29 total organisations) - Submit social housing lettings and sales data (CORE) - GOV.UK") - end + context "when the search term matches more than 1 result" do + let(:search_param) { "name" } - context "when the search term matches more than 1 result" do - let(:search_param) { "name" } + it "returns matching results" do + expect(page).to have_content(searched_organisation.name) + expect(page).to have_content(other_organisation.name) + end - it "returns matching results" do - expect(page).to have_content(searched_organisation.name) - expect(page).to have_content(other_organisation.name) - end + it "updates the table caption" do + expect(page).to have_content("2 organisations found matching ‘#{search_param}’ of 29 total organisations.") + end - it "updates the table caption" do - expect(page).to have_content("2 organisations found matching ‘#{search_param}’ of 29 total organisations.") - end + it "has search in the title" do + expect(page).to have_title("Organisations (2 organisations matching ‘#{search_param}’ of 29 total organisations) - Submit social housing lettings and sales data (CORE) - GOV.UK") + end + end + + context "when search results require pagination" do + let(:search_param) { "DLUHC" } - it "has search in the title" do - expect(page).to have_title("Organisations (2 organisations matching ‘#{search_param}’ of 29 total organisations) - Submit social housing lettings and sales data (CORE) - GOV.UK") + it "has search and pagination in the title" do + expect(page).to have_title("Organisations (27 organisations matching ‘#{search_param}’ of 29 total organisations) (page 1 of 2) - Submit social housing lettings and sales data (CORE) - GOV.UK") + end + end end end + end - context "when search results require pagination" do - let(:search_param) { "DLUHC" } - - it "has search and pagination in the title" do - expect(page).to have_title("Organisations (27 organisations matching ‘#{search_param}’ of 29 total organisations) (page 1 of 2) - Submit social housing lettings and sales data (CORE) - GOV.UK") - end + describe "#create" do + let(:name) { "Unique new org name" } + let(:address_line1) { "12 Random Street" } + let(:address_line2) { "Manchester" } + let(:postcode) { "MD1 5TR" } + let(:phone) { "011101101" } + let(:provider_type) { "LA" } + let(:holds_own_stock) { "true" } + let(:housing_registration_no) { "7917937" } + let(:params) do + { + "organisation": { + name:, + address_line1:, + address_line2:, + postcode:, + phone:, + provider_type:, + holds_own_stock:, + housing_registration_no:, + }, + } + end + let(:request) { post "/organisations", headers:, params: } + + it "creates a new organisation" do + expect { request }.to change(Organisation, :count).by(1) + end + + it "sets the organisation attributes correctly" do + request + organisation = Organisation.find_by(housing_registration_no:) + expect(organisation.name).to eq(name) + expect(organisation.address_line1).to eq(address_line1) + expect(organisation.address_line2).to eq(address_line2) + expect(organisation.postcode).to eq(postcode) + expect(organisation.phone).to eq(phone) + expect(organisation.holds_own_stock).to be true + end + + it "redirects to the organisation list" do + request + expect(response).to redirect_to("/organisations") end end end