require "rails_helper" RSpec.describe FormController, type: :request do let(:page) { Capybara::Node::Simple.new(response.body) } let(:user) { create(:user) } let(:organisation) { user.organisation } let(:other_user) { create(:user) } let(:other_organisation) { other_user.organisation } let!(:unauthorized_lettings_log) do create( :lettings_log, created_by: other_user, ) end let(:setup_complete_lettings_log) do create( :lettings_log, :setup_completed, status: 1, created_by: user, ) end let(:completed_lettings_log) do create( :lettings_log, :completed, created_by: user, ) end let(:headers) { { "Accept" => "text/html" } } let(:fake_2021_2022_form) { Form.new("spec/fixtures/forms/2021_2022.json") } before do allow(fake_2021_2022_form).to receive(:new_logs_end_date).and_return(Time.zone.today + 1.day) allow(fake_2021_2022_form).to receive(:edit_end_date).and_return(Time.zone.today + 2.months) allow(FormHandler.instance).to receive(:current_lettings_form).and_return(fake_2021_2022_form) allow(FormHandler.instance).to receive(:lettings_in_crossover_period?).and_return(true) end context "when a user is not signed in" do let!(:lettings_log) do create( :lettings_log, created_by: user, ) end describe "GET" do it "does not let you get lettings logs pages you don't have access to" do get "/lettings-logs/#{lettings_log.id}/person-1-age", headers: headers, params: {} expect(response).to redirect_to("/account/sign-in") end it "does not let you get lettings log check answer pages you don't have access to" do get "/lettings-logs/#{lettings_log.id}/household-characteristics/check-answers", headers: headers, params: {} expect(response).to redirect_to("/account/sign-in") end end describe "POST" do it "does not let you post form answers to lettings logs you don't have access to" do post "/lettings-logs/#{lettings_log.id}/net-income", params: {} expect(response).to redirect_to("/account/sign-in") end end end context "when signed in as a support user" do let!(:lettings_log) do create( :lettings_log, created_by: user, ) end let(:page) { Capybara::Node::Simple.new(response.body) } let(:managing_organisation) { create(:organisation) } let(:managing_organisation_too) { create(:organisation) } let(:stock_owner) { create(:organisation) } let(:support_user) { create(:user, :support) } before do organisation.stock_owners << stock_owner organisation.managing_agents << managing_organisation organisation.managing_agents << managing_organisation_too organisation.reload allow(support_user).to receive(:need_two_factor_authentication?).and_return(false) sign_in support_user end context "with invalid organisation answers" do let(:params) do { id: lettings_log.id, lettings_log: { page: "managing_organisation", managing_organisation_id: other_organisation.id, }, } end before do lettings_log.update!(owning_organisation: stock_owner, created_by: user, managing_organisation: organisation) lettings_log.reload end it "resets created by and renders the next page" do post "/lettings-logs/#{lettings_log.id}/net-income", params: params expect(response).to redirect_to("/lettings-logs/#{lettings_log.id}/created-by") follow_redirect! lettings_log.reload expect(lettings_log.created_by).to eq(nil) end end context "with valid owning organisation" do let(:params) do { id: lettings_log.id, lettings_log: { page: "managing_organisation", managing_organisation_id: other_organisation.id, }, } end before do lettings_log.update!(owning_organisation: organisation, created_by: user, managing_organisation: organisation) lettings_log.reload end it "does not reset created by" do post "/lettings-logs/#{lettings_log.id}/net-income", params: params expect(response).to redirect_to("/lettings-logs/#{lettings_log.id}/created-by") follow_redirect! lettings_log.reload expect(lettings_log.created_by).to eq(user) end end context "when owning organisation doesn't have any managing agents" do let(:params) do { id: lettings_log.id, lettings_log: { page: "stock_owner", owning_organisation_id: managing_organisation.id, }, } end before do lettings_log.update!(owning_organisation: nil, created_by: nil, managing_organisation: nil) lettings_log.reload end it "sets managing organisation to owning organisation" do post "/lettings-logs/#{lettings_log.id}/stock-owner", params: params expect(response).to redirect_to("/lettings-logs/#{lettings_log.id}/created-by") follow_redirect! lettings_log.reload expect(lettings_log.owning_organisation).to eq(managing_organisation) expect(lettings_log.managing_organisation).to eq(managing_organisation) end end context "when submitting a sales log for organisation that doesn't have any managing agents" do let(:sales_log) { create(:sales_log) } let(:params) do { id: sales_log.id, sales_log: { page: "owning_organisation", owning_organisation_id: managing_organisation.id, }, } end before do sales_log.update!(owning_organisation: nil, created_by: nil) sales_log.reload end it "correctly sets owning organisation" do post "/sales-logs/#{sales_log.id}/owning-organisation", params: params expect(response).to redirect_to("/sales-logs/#{sales_log.id}/created-by") follow_redirect! sales_log.reload expect(sales_log.owning_organisation).to eq(managing_organisation) end end context "when submitting a sales log with valid owning organisation" do let(:sales_log) { create(:sales_log) } let(:created_by) { managing_organisation.users.first } let(:params) do { id: sales_log.id, sales_log: { page: "owning_organisation", owning_organisation_id: managing_organisation.id, }, } end before do sales_log.update!(owning_organisation: managing_organisation, created_by:) sales_log.reload end it "does not reset created by" do post "/sales-logs/#{sales_log.id}/owning-organisation", params: params expect(response).to redirect_to("/sales-logs/#{sales_log.id}/created-by") follow_redirect! sales_log.reload expect(sales_log.created_by).to eq(created_by) end end context "when submitting a sales log with valid merged owning organisation" do let(:sales_log) { create(:sales_log) } let(:created_by) { managing_organisation.users.first } let(:merged_organisation) { create(:organisation) } let(:params) do { id: sales_log.id, sales_log: { page: "owning_organisation", owning_organisation_id: merged_organisation.id, }, } end before do merged_organisation.update!(merge_date: Time.zone.today, absorbing_organisation: managing_organisation) sales_log.update!(owning_organisation: managing_organisation, created_by:) sales_log.reload end it "does not reset created by" do post "/sales-logs/#{sales_log.id}/owning-organisation", params: params expect(response).to redirect_to("/sales-logs/#{sales_log.id}/created-by") follow_redirect! sales_log.reload expect(sales_log.created_by).to eq(created_by) end end context "with valid managing organisation" do let(:params) do { id: lettings_log.id, lettings_log: { page: "stock_owner", owning_organisation_id: stock_owner.id, }, } end before do lettings_log.update!(owning_organisation: organisation, created_by: user, managing_organisation: organisation) lettings_log.reload end it "does not reset created by" do post "/lettings-logs/#{lettings_log.id}/stock-owner", params: params expect(response).to redirect_to("/lettings-logs/#{lettings_log.id}/managing-organisation") follow_redirect! lettings_log.reload expect(lettings_log.created_by).to eq(user) end end context "with valid absorbed managing organisation" do let(:params) do { id: lettings_log.id, lettings_log: { page: "stock_owner", owning_organisation_id: stock_owner.id, }, } end let(:merged_org) { create(:organisation) } before do merged_org.update!(merge_date: Time.zone.today, absorbing_organisation: organisation) lettings_log.update!(owning_organisation: merged_org, created_by: user, managing_organisation: merged_org) lettings_log.reload end it "does not reset created by" do post "/lettings-logs/#{lettings_log.id}/stock-owner", params: params expect(response).to redirect_to("/lettings-logs/#{lettings_log.id}/managing-organisation") follow_redirect! lettings_log.reload expect(lettings_log.created_by).to eq(user) end end context "with only adding the stock owner" do let(:params) do { id: lettings_log.id, lettings_log: { page: "stock_owner", owning_organisation_id: stock_owner.id, }, } end before do lettings_log.update!(owning_organisation: nil, created_by: user, managing_organisation: nil) lettings_log.reload end it "does not reset created by" do post "/lettings-logs/#{lettings_log.id}/stock-owner", params: params expect(response).to redirect_to("/lettings-logs/#{lettings_log.id}/managing-organisation") follow_redirect! lettings_log.reload expect(lettings_log.created_by).to eq(user) end end context "when the sale date changes from 2024 to 2023" do let(:sales_log) { create(:sales_log, owning_organisation: organisation, managing_organisation:, created_by: user) } let(:params) do { id: sales_log.id, sales_log: { page: "completion_date", "saledate(3i)" => 30, "saledate(2i)" => 6, "saledate(1i)" => 2023, }, } end before do sales_log.saledate = Time.zone.local(2024, 12, 1) sales_log.save!(validate: false) sales_log.reload end it "does not set managing organisation to created by organisation" do post "/sales-logs/#{sales_log.id}/completion-date", params: params sales_log.reload expect(sales_log.owning_organisation).to eq(organisation) expect(sales_log.managing_organisation).to eq(managing_organisation) end end end context "when a user is signed in" do let!(:lettings_log) do create( :lettings_log, created_by: user, ) end before do allow(user).to receive(:need_two_factor_authentication?).and_return(false) sign_in user end describe "GET" do around do |example| Timecop.freeze(Time.zone.local(2022, 5, 1)) do Singleton.__init__(FormHandler) example.run end Timecop.return Singleton.__init__(FormHandler) end context "with form pages" do context "when forms exist" do let(:lettings_log) { create(:lettings_log, :setup_completed, startdate: Time.zone.local(2022, 5, 1), owning_organisation: organisation, created_by: user) } it "displays the question details" do get "/lettings-logs/#{lettings_log.id}/tenant-code-test", headers: headers, params: {} expect(response).to be_ok expect(response.body).to match("Different question header text for this year - 2023") end end context "when question not routed to" do let(:lettings_log) { create(:lettings_log, :setup_completed, startdate: Time.zone.local(2022, 5, 1), owning_organisation: organisation, created_by: user) } it "redirects to log" do get "/lettings-logs/#{lettings_log.id}/scheme", headers: headers, params: {} expect(response).to redirect_to("/lettings-logs/#{lettings_log.id}") end end context "when lettings logs are not owned or managed by your organisation" do it "does not show form pages for lettings logs you don't have access to" do get "/lettings-logs/#{unauthorized_lettings_log.id}/person-1-age", headers: headers, params: {} expect(response).to have_http_status(:not_found) end end context "with a form page that has custom guidance" do it "displays the correct partial" do get "/lettings-logs/#{lettings_log.id}/net-income", headers: headers, params: {} expect(response.body).to match("What counts as income?") end end context "when viewing the setup section schemes page" do context "when the user is support" do let(:user) { create(:user, :support) } context "when organisation and user have not been selected yet" do let(:lettings_log) do create( :lettings_log, owning_organisation: nil, managing_organisation: nil, created_by: nil, needstype: 2, ) end before do locations = create_list(:location, 5) locations.each { |location| location.scheme.update!(arrangement_type: "The same organisation that owns the housing stock") } end it "returns an unfiltered list of schemes" do get "/lettings-logs/#{lettings_log.id}/scheme", headers: headers, params: {} expect(response.body.scan("