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(:params) { { id: organisation.id, organisation: { name: new_value } } }

  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
  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) }

        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

        it "has hidden accessibility field with description" do
          expected_field = "<h2 class=\"govuk-visually-hidden\">Supported housing schemes</h2>"
          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

        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 found matching ‘#{search_param}’")
          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
      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

        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 incomplete schemes at the top" do
          schemes[0].update!(confirmed: nil, owning_organisation: user.organisation)
          schemes[2].update!(confirmed: false, owning_organisation: user.organisation)
          schemes[4].update!(confirmed: false, owning_organisation: user.organisation)
          get "/organisations/#{organisation.id}/schemes", headers:, params: {}

          expect(page.all(".govuk-tag")[1].text).to eq("Incomplete")
          expect(page.all(".govuk-tag")[2].text).to eq("Incomplete")
          expect(page.all(".govuk-tag")[3].text).to eq("Incomplete")
        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 found matching ‘#{search_param}’")
          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 "#show" do
      context "with an organisation that the user belongs to" do
        before do
          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 = "<nav class=\"app-primary-navigation\""
            expect(response.body).to include(expected_html)
          end

          it "shows a summary list of org details" do
            expected_html = "<dl class=\"govuk-summary-list\""
            expect(response.body).to include(expected_html)
            expect(response.body).to include(organisation.name)
          end

          it "has a change details link" do
            expected_html = "data-qa=\"change-name\" href=\"/organisations/#{organisation.id}/edit\""
            expect(response.body).to include(expected_html)
          end

          it "displays a link to merge organisations" do
            expect(page).to have_content("Is your organisation merging with another?")
            expect(page).to have_link("Let us know using this form", href: "/organisations/#{organisation.id}/merge-request")
          end
        end

        context "with organisation that are not in scope for the user, i.e. that they do not belong to" do
          before do
            get "/organisations/#{unauthorised_organisation.id}/details", headers:, params: {}
          end

          it "returns not found 404 from org details route" do
            expect(response).to have_http_status(:not_found)
          end
        end
      end

      context "when accessing the users tab" do
        context "with an organisation that the user belongs to" do
          let!(:other_user) { create(:user, organisation: user.organisation, name: "User 2") }
          let!(:inactive_user) { create(:user, organisation: user.organisation, active: false, name: "User 3") }
          let!(:other_org_user) { create(:user, name: "User 4") }

          before do
            get "/organisations/#{organisation.id}/users", headers:, params: {}
          end

          it "shows the tab navigation" do
            expected_html = "<nav class=\"app-primary-navigation\""
            expect(response.body).to include(expected_html)
          end

          it "shows a new user button" do
            expect(page).to have_link("Invite user")
          end

          it "shows a table of users" do
            expected_html = "<table class=\"govuk-table\""
            expect(response.body).to include(expected_html)
            expect(response.body).to include(user.email)
          end

          it "shows hidden accessibility fields only for active users in the current user's organisation" do
            expected_case_row_log = "<span class=\"govuk-visually-hidden\">User </span><span class=\"govuk-!-font-weight-regular app-!-colour-muted\">#{user.email}</span>"
            unauthorized_case_row_log = "<span class=\"govuk-visually-hidden\">User </span><span class=\"govuk-!-font-weight-regular app-!-colour-muted\">#{other_org_user.email}</span>"
            expect(CGI.unescape_html(response.body)).to include(expected_case_row_log)
            expect(CGI.unescape_html(response.body)).not_to include(unauthorized_case_row_log)
          end

          it "shows only active users in the current user's organisation" do
            expect(page).to have_content(user.name)
            expect(page).to have_content(other_user.name)
            expect(page).to have_content(inactive_user.name)
            expect(page).not_to have_content(other_org_user.name)
          end

          it "shows the pagination count" do
            expect(page).to have_content("3 total users")
          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
            get "/organisations/#{unauthorised_organisation.id}/users", headers:, params: {}
          end

          it "returns not found 404 from users page" do
            expect(response).to have_http_status(:not_found)
          end
        end
      end

      describe "#edit" do
        context "with an organisation that the user belongs to" do
          before do
            get "/organisations/#{organisation.id}/edit", headers:, params: {}
          end

          it "shows an edit form" do
            expect(response.body).to include("Change #{organisation.name}’s details")
            expect(page).to have_field("organisation-name-field")
            expect(page).to have_field("organisation-phone-field")
          end
        end

        context "with an organisation that the user does not belong to" do
          before do
            get "/organisations/#{unauthorised_organisation.id}/edit", headers:, params: {}
          end

          it "returns a 404 not found" 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

      describe "#update" do
        context "with an organisation that the user belongs to" do
          before do
            patch "/organisations/#{organisation.id}", headers:, params:
          end

          it "updates the org" do
            organisation.reload
            expect(organisation.name).to eq(new_value)
          end

          it "redirects to the organisation details page" do
            expect(response).to redirect_to("/organisations/#{organisation.id}/details")
          end

          it "shows a success banner" do
            follow_redirect!
            expect(page).to have_css(".govuk-notification-banner.govuk-notification-banner--success")
          end

          it "tracks who updated the record" do
            organisation.reload
            whodunnit_actor = organisation.versions.last.actor
            expect(whodunnit_actor).to be_a(User)
            expect(whodunnit_actor.id).to eq(user.id)
          end
        end

        context "with an organisation that the user does not belong to" do
          before do
            patch "/organisations/#{unauthorised_organisation.id}", headers:, params: {}
          end

          it "returns a 404 not found" do
            expect(response).to have_http_status(:not_found)
          end
        end
      end

      context "when viewing lettings logs for other organisation" do
        it "does not display the lettings logs" do
          get "/organisations/#{unauthorised_organisation.id}/lettings-logs", headers:, params: {}
          expect(response).to have_http_status(:unauthorized)
        end

        it "prevents CSV download" do
          expect {
            post "/organisations/#{unauthorised_organisation.id}/lettings-logs/email-csv", headers:, params: {}
          }.not_to enqueue_job(EmailCsvJob)
          expect(response).to have_http_status(:unauthorized)
        end
      end

      context "when viewing lettings logs for your organisation" do
        it "does not display the logs" do
          get "/organisations/#{organisation.id}/lettings-logs", headers:, params: {}
          expect(response).to have_http_status(:unauthorized)
        end

        it "prevents CSV download" do
          expect {
            post "/organisations/#{organisation.id}/lettings-logs/email-csv", headers:, params: {}
          }.not_to enqueue_job(EmailCsvJob)
          expect(response).to have_http_status(:unauthorized)
        end
      end

      context "when viewing sales logs for other organisation" do
        it "does not display the sales logs" do
          get "/organisations/#{unauthorised_organisation.id}/sales-logs", headers:, params: {}
          expect(response).to have_http_status(:unauthorized)
        end

        it "prevents CSV download" do
          expect {
            post "/organisations/#{unauthorised_organisation.id}/sales-logs/email-csv", headers:, params: {}
          }.not_to enqueue_job(EmailCsvJob)
          expect(response).to have_http_status(:unauthorized)
        end
      end

      context "when viewing sales logs for your organisation" do
        it "does not display the logs" do
          get "/organisations/#{organisation.id}/sales-logs", headers:, params: {}
          expect(response).to have_http_status(:unauthorized)
        end

        it "prevents CSV download" do
          expect {
            post "/organisations/#{organisation.id}/sales-logs/email-csv", headers:, params: {}
          }.not_to enqueue_job(EmailCsvJob)
          expect(response).to have_http_status(:unauthorized)
        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

      describe "#merge" do
        context "with an organisation that the user belongs to" do
          before do
            get "/organisations/#{organisation.id}/merge-request", headers:, params: {}
          end

          it "shows the correct content" do
            expect(page).to have_content("Tell us if your organisation is merging")
          end

          it "has a correct back link" do
            expect(page).to have_link("Back", href: "/organisations/#{organisation.id}")
          end

          it "has a correct start now button" do
            expect(page).to have_button("Start now")
          end
        end

        context "with organisation that are not in scope for the user, i.e. that they do not belong to" do
          before do
            get "/organisations/#{unauthorised_organisation.id}/merge-request", headers:, params: {}
          end

          it "returns not found 404 from org details route" do
            expect(response).to have_http_status(:not_found)
          end
        end
      end
    end

    context "with a data provider user" do
      let(:user) { create(:user) }

      before do
        sign_in user
      end

      context "when accessing 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 = "<nav class=\"app-primary-navigation\""
            expect(response.body).to include(expected_html)
          end

          it "shows a summary list of org details" do
            expected_html = "<dl class=\"govuk-summary-list\""
            expect(response.body).to include(expected_html)
            expect(response.body).to include(organisation.name)
          end

          it "does not have a change details link" do
            expected_html = "data-qa=\"change-name\" href=\"/organisations/#{organisation.id}/edit\""
            expect(response.body).not_to include(expected_html)
          end
        end

        context "with an organisation that is 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}/details", headers:, params: {}
          end

          it "returns not found 404" do
            expect(response).to have_http_status(:not_found)
          end
        end
      end

      context "when accessing the users tab" do
        before do
          get "/organisations/#{organisation.id}/users", headers:, params: {}
        end

        it "returns 200" do
          expect(response).to have_http_status(:ok)
        end
      end

      describe "#edit" do
        before do
          get "/organisations/#{organisation.id}/edit", headers:, params: {}
        end

        it "redirects to home" do
          expect(response).to have_http_status(:unauthorized)
        end
      end

      describe "#update" do
        before do
          patch "/organisations/#{organisation.id}", headers:, params:
        end

        it "redirects to home" do
          expect(response).to have_http_status(:unauthorized)
        end
      end

      context "when viewing lettings logs for other organisation" do
        it "does not display the logs" do
          get "/organisations/#{unauthorised_organisation.id}/lettings-logs", headers:, params: {}
          expect(response).to have_http_status(:unauthorized)
        end

        it "prevents CSV download" do
          expect {
            post "/organisations/#{unauthorised_organisation.id}/lettings-logs/email-csv", headers:, params: {}
          }.not_to enqueue_job(EmailCsvJob)
          expect(response).to have_http_status(:unauthorized)
        end
      end

      context "when viewing lettings logs for your organisation" do
        it "does not display the logs" do
          get "/organisations/#{organisation.id}/lettings-logs", headers:, params: {}
          expect(response).to have_http_status(:unauthorized)
        end

        it "prevents CSV download" do
          expect {
            post "/organisations/#{organisation.id}/lettings-logs/email-csv", headers:, params: {}
          }.not_to enqueue_job(EmailCsvJob)
          expect(response).to have_http_status(:unauthorized)
        end
      end

      context "when viewing sales logs for other organisation" do
        it "does not display the logs" do
          get "/organisations/#{unauthorised_organisation.id}/sales-logs", headers:, params: {}
          expect(response).to have_http_status(:unauthorized)
        end

        it "prevents CSV download" do
          expect {
            post "/organisations/#{unauthorised_organisation.id}/sales-logs/email-csv", headers:, params: {}
          }.not_to enqueue_job(EmailCsvJob)
          expect(response).to have_http_status(:unauthorized)
        end
      end

      context "when viewing sales logs for your organisation" do
        it "does not display the logs" do
          get "/organisations/#{organisation.id}/sales-logs", headers:, params: {}
          expect(response).to have_http_status(:unauthorized)
        end

        it "prevents CSV download" do
          expect {
            post "/organisations/#{organisation.id}/sales-logs/email-csv", headers:, params: {}
          }.not_to enqueue_job(EmailCsvJob)
          expect(response).to have_http_status(:unauthorized)
        end
      end
    end

    context "with a support user" do
      let(:user) { create(:user, :support) }

      before do
        allow(user).to receive(:need_two_factor_authentication?).and_return(false)
        sign_in user
      end

      describe "#new" do
        let(:request) { get "/organisations/new", headers:, params: }

        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

      describe "#index" do
        before do
          get "/organisations", headers:, params: {}
        end

        it "shows the organisation list" do
          expect(page).to have_content("Organisations")
        end

        it "has a create new organisation button" do
          expect(page).to have_link("Create a new organisation", href: "/organisations/new")
        end

        it "shows all organisations" do
          total_number_of_orgs = Organisation.all.count
          expect(page).to have_link organisation.name, href: "organisations/#{organisation.id}/lettings-logs"
          expect(page).to have_link unauthorised_organisation.name, href: "organisations/#{unauthorised_organisation.id}/lettings-logs"
          expect(page).to have_content("#{total_number_of_orgs} total organisations")
        end

        it "shows a search bar" do
          expect(page).to have_field("search", type: "search")
        end

        context "when viewing a specific organisation's lettings logs" do
          let(:number_of_org1_lettings_logs) { 2 }
          let(:number_of_org2_lettings_logs) { 4 }

          before do
            create_list(:lettings_log, number_of_org1_lettings_logs, created_by: user)
            create(:lettings_log, created_by: user, status: "pending", skip_update_status: true)
            create_list(:lettings_log, number_of_org2_lettings_logs, created_by: nil, owning_organisation_id: unauthorised_organisation.id, managing_organisation_id: unauthorised_organisation.id)

            get "/organisations/#{organisation.id}/lettings-logs", headers:, params: {}
          end

          it "only shows logs for that organisation" do
            expect(page).to have_content("#{number_of_org1_lettings_logs} total logs")

            organisation.lettings_logs.visible.map(&:id).each do |lettings_log_id|
              expect(page).to have_link lettings_log_id.to_s, href: "/lettings-logs/#{lettings_log_id}"
            end

            unauthorised_organisation.lettings_logs.map(&:id).each do |lettings_log_id|
              expect(page).not_to have_link lettings_log_id.to_s, href: "/lettings-logs/#{lettings_log_id}"
            end
          end

          it "has filters" do
            expect(page).to have_content("Filters")
            expect(page).to have_content("Collection year")
          end

          it "does not have specific organisation filter" do
            expect(page).not_to have_content("Specific 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

          context "when using a search query" do
            let(:logs) { create_list(:lettings_log, 3, :completed, owning_organisation: user.organisation, created_by: user) }
            let(:log_to_search) { create(:lettings_log, :completed, owning_organisation: user.organisation, created_by: user) }
            let(:log_total_count) { LettingsLog.where(owning_organisation: user.organisation).count }

            it "has search results in the title" do
              get "/organisations/#{organisation.id}/lettings-logs?search=#{log_to_search.id}", headers: headers, params: {}
              expect(page).to have_title("#{organisation.name} (1 logs matching ‘#{log_to_search.id}’) - Submit social housing lettings and sales data (CORE) - GOV.UK")
            end

            it "shows lettings logs matching the id" do
              get "/organisations/#{organisation.id}/lettings-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)
              end
            end

            it "shows lettings logs matching the tenant code" do
              get "/organisations/#{organisation.id}/lettings-logs?search=#{log_to_search.tenancycode}", 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

            it "shows lettings logs matching the property reference" do
              get "/organisations/#{organisation.id}/lettings-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
            end

            it "shows lettings logs matching the property postcode" do
              get "/organisations/#{organisation.id}/lettings-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
            end

            context "when more than one results with matching postcode" do
              let!(:matching_postcode_log) { create(:lettings_log, :completed, owning_organisation: user.organisation, postcode_full: log_to_search.postcode_full) }

              it "displays all matching logs" do
                get "/organisations/#{organisation.id}/lettings-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

            context "when there are more than 1 page of search results" do
              let(:postcode) { "XX11YY" }
              let(:logs) { create_list(:lettings_log, 30, :completed, owning_organisation: user.organisation, postcode_full: postcode) }
              let(:log_total_count) { LettingsLog.where(owning_organisation: user.organisation).count }

              it "has title with pagination details for page 1" do
                get "/organisations/#{organisation.id}/lettings-logs?search=#{logs[0].postcode_full}", headers: headers, params: {}
                expect(page).to have_title("#{organisation.name} (#{logs.count} logs matching ‘#{postcode}’) (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}/lettings-logs?search=#{logs[0].postcode_full}&page=2", headers: headers, params: {}
                expect(page).to have_title("#{organisation.name} (#{logs.count} logs matching ‘#{postcode}’) (page 2 of 2) - Submit social housing lettings and sales data (CORE) - GOV.UK")
              end
            end

            context "when search query doesn't match any logs" do
              it "doesn't display any logs" do
                get "/organisations/#{organisation.id}/lettings-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

            context "when search query is empty" do
              it "doesn't display any logs" do
                get "/organisations/#{organisation.id}/lettings-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

            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) { create(:lettings_log, :in_progress, owning_organisation: user.organisation, postcode_full: matching_postcode, created_by: user) }

              it "shows only logs matching both search and filters" do
                get "/organisations/#{organisation.id}/lettings-logs?search=#{matching_postcode}&status[]=#{matching_status}", headers: headers, params: {}
                expect(page).to have_link(log_matching_filter_and_search.id.to_s)
                expect(page).not_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
          end
        end

        context "when viewing a specific organisation's sales logs" do
          let(:number_of_org1_sales_logs) { 2 }
          let(:number_of_org2_sales_logs) { 4 }

          before do
            create_list(:sales_log, number_of_org1_sales_logs, owning_organisation_id: organisation.id)
            create_list(:sales_log, number_of_org2_sales_logs, owning_organisation_id: unauthorised_organisation.id)

            get "/organisations/#{organisation.id}/sales-logs", headers:, params: {}
          end

          it "only shows logs for that organisation" do
            expect(page).to have_content("#{number_of_org1_sales_logs} total logs")
            organisation.sales_logs.map(&:id).each do |sales_log_id|
              expect(page).to have_link sales_log_id.to_s, href: "/sales-logs/#{sales_log_id}"
            end

            unauthorised_organisation.sales_logs.map(&:id).each do |sales_log_id|
              expect(page).not_to have_link sales_log_id.to_s, href: "/sales-logs/#{sales_log_id}"
            end
          end

          it "has filters" do
            expect(page).to have_content("Filters")
            expect(page).to have_content("Collection year")
          end

          it "does not have specific organisation filter" do
            expect(page).not_to have_content("Specific 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

          context "when using a search query" do
            let(:logs) { create_list(:sales_log, 3, :completed, owning_organisation: user.organisation, created_by: user) }
            let(:log_to_search) { create(:sales_log, :completed, owning_organisation: user.organisation, created_by: user) }
            let(:log_total_count) { LettingsLog.where(owning_organisation: user.organisation).count }

            it "has search results in the title" do
              get "/organisations/#{organisation.id}/sales-logs?search=#{log_to_search.id}", headers: headers, params: {}
              expect(page).to have_title("#{organisation.name} (1 logs matching ‘#{log_to_search.id}’) - Submit social housing lettings and sales data (CORE) - GOV.UK")
            end

            it "shows sales logs matching the id" do
              get "/organisations/#{organisation.id}/sales-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)
              end
            end

            context "when search query doesn't match any logs" do
              it "doesn't display any logs" do
                get "/organisations/#{organisation.id}/sales-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

            context "when search query is empty" do
              it "doesn't display any logs" do
                get "/organisations/#{organisation.id}/sales-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

            context "when search and filter is present" do
              let(:matching_status) { "completed" }
              let!(:log_matching_filter_and_search) { create(:sales_log, :completed, owning_organisation: user.organisation, created_by: user) }
              let(:matching_id) { log_matching_filter_and_search.id }

              it "shows only logs matching both search and filters" do
                get "/organisations/#{organisation.id}/sales-logs?search=#{matching_id}&status[]=#{matching_status}", headers: headers, params: {}
                expect(page).to have_link(log_matching_filter_and_search.id.to_s)
                expect(page).not_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
          end
        end

        context "when viewing a specific organisation's users" do
          let!(:users) { create_list(:user, 5, organisation:) }
          let!(:different_org_users) { create_list(:user, 5) }

          before do
            get "/organisations/#{organisation.id}/users", headers:, params: {}
          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("Users")
          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

          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

          context "when a search parameter is passed" do
            let!(:matching_user) { 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 our search string matches case" 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)

                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("1 user found matching ‘#{search_param}’ of #{org_user_count} total users.")
              end

              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)

                  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("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" }

              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

                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.")
              end

              context "when our search term matches an email and a name" do
                let!(:matching_user) { create(:user, organisation:, name: "Foobar", email: "some@example.com") }
                let!(:another_matching_user) { 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

        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 "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)
          end
        end

        context "when there are more than 20 organisations" do
          let(:total_organisations_count) { Organisation.all.count }

          before do
            create_list(:organisation, 25)
            get "/organisations"
          end

          context "when on the first page" do
            it "has pagination links" do
              expect(page).not_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 <b>1</b> to <b>20</b> of <b>#{total_organisations_count}</b> organisations")
            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

            it "shows the total organisations count" do
              expect(CGI.unescape_html(response.body)).to match("<strong>#{total_organisations_count}</strong> total organisations")
            end

            it "has pagination links" do
              expect(page).to have_content("Previous")
              expect(page).to have_link("Previous")
              expect(page).not_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 <b>21</b> to <b>#{total_organisations_count}</b> of <b>#{total_organisations_count}</b> organisations")
            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) { create(:organisation, name: "Unusual name") }
            let!(:other_organisation) { create(:organisation, name: "Some other name") }
            let(:search_param) { "Unusual" }

            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 "updates the table caption" do
              expect(page).to have_content("1 organisations found matching ‘#{search_param}’")
            end

            it "has search in the title" do
              expect(page).to have_title("Organisations (1 organisations matching ‘#{search_param}’) - 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" }

              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}’")
              end

              it "has search in the title" do
                expect(page).to have_title("Organisations (2 organisations matching ‘#{search_param}’) - 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 and pagination in the title" do
                expect(page).to have_title("Organisations (27 organisations matching ‘#{search_param}’) (page 1 of 2) - Submit social housing lettings and sales data (CORE) - GOV.UK")
              end
            end
          end
        end
      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("Unique new org 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

        context "when required params are missing" do
          let(:name) { "" }
          let(:provider_type) { "" }

          it "displays the form with an error message" do
            request
            expect(response).to have_http_status(:unprocessable_entity)
            expect(page).to have_content(I18n.t("validations.organisation.name_missing"))
            expect(page).to have_content(I18n.t("validations.organisation.provider_type_missing"))
          end
        end
      end
    end
  end

  context "when the user is a support user" do
    let(:user) { create(:user, :support) }

    before do
      allow(user).to receive(:need_two_factor_authentication?).and_return(false)
      sign_in user
    end

    context "when they view the lettings logs tab" do
      before do
        create(:lettings_log, owning_organisation: organisation)
      end

      it "has CSV download buttons with the correct paths if at least 1 log exists" do
        get "/organisations/#{organisation.id}/lettings-logs"
        expect(page).to have_link("Download (CSV)", href: "/organisations/#{organisation.id}/lettings-logs/csv-download?codes_only=false")
        expect(page).to have_link("Download (CSV, codes only)", href: "/organisations/#{organisation.id}/lettings-logs/csv-download?codes_only=true")
      end

      context "when you download the CSV" do
        let(:other_organisation) { create(:organisation) }

        before do
          create_list(:lettings_log, 2, owning_organisation: organisation)
          create(:lettings_log, owning_organisation: organisation, status: "pending", skip_update_status: true)
          create_list(:lettings_log, 2, owning_organisation: other_organisation)
        end

        it "only includes logs from that organisation" do
          get "/organisations/#{organisation.id}/lettings-logs/csv-download?codes_only=false"

          expect(page).to have_text("You've selected 3 logs.")
        end

        it "provides the organisation to the mail job" do
          expect {
            post "/organisations/#{organisation.id}/lettings-logs/email-csv?status[]=completed&codes_only=false", headers:, params: {}
          }.to enqueue_job(EmailCsvJob).with(user, nil, { "status" => %w[completed] }, false, organisation, false)
        end

        it "provides the export type to the mail job" do
          codes_only_export_type = false
          expect {
            post "/organisations/#{organisation.id}/lettings-logs/email-csv?codes_only=#{codes_only_export_type}", headers:, params: {}
          }.to enqueue_job(EmailCsvJob).with(user, nil, {}, false, organisation, codes_only_export_type)
          codes_only_export_type = true
          expect {
            post "/organisations/#{organisation.id}/lettings-logs/email-csv?codes_only=#{codes_only_export_type}", headers:, params: {}
          }.to enqueue_job(EmailCsvJob).with(user, nil, {}, false, organisation, codes_only_export_type)
        end
      end
    end

    context "when they view the sales logs tab" do
      before do
        create(:sales_log, owning_organisation: organisation)
      end

      it "has CSV download buttons with the correct paths if at least 1 log exists" do
        get "/organisations/#{organisation.id}/sales-logs"
        expect(page).to have_link("Download (CSV)", href: "/organisations/#{organisation.id}/sales-logs/csv-download?codes_only=false")
        expect(page).to have_link("Download (CSV, codes only)", href: "/organisations/#{organisation.id}/sales-logs/csv-download?codes_only=true")
      end

      context "when you download the CSV" do
        let(:other_organisation) { create(:organisation) }

        before do
          create_list(:sales_log, 2, owning_organisation: organisation)
          create(:sales_log, owning_organisation: organisation, status: "pending", skip_update_status: true)
          create_list(:sales_log, 2, owning_organisation: other_organisation)
        end

        it "only includes logs from that organisation" do
          get "/organisations/#{organisation.id}/sales-logs/csv-download?codes_only=false"

          expect(page).to have_text("You've selected 3 logs.")
        end

        it "provides the organisation to the mail job" do
          expect {
            post "/organisations/#{organisation.id}/sales-logs/email-csv?status[]=completed&codes_only=false", headers:, params: {}
          }.to enqueue_job(EmailCsvJob).with(user, nil, { "status" => %w[completed] }, false, organisation, false, "sales")
        end

        it "provides the log type to the mail job" do
          log_type = "sales"
          expect {
            post "/organisations/#{organisation.id}/sales-logs/email-csv?status[]=completed&codes_only=false", headers:, params: {}
          }.to enqueue_job(EmailCsvJob).with(user, nil, { "status" => %w[completed] }, false, organisation, false, log_type)
        end

        it "provides the export type to the mail job" do
          codes_only_export_type = false
          expect {
            post "/organisations/#{organisation.id}/sales-logs/email-csv?codes_only=#{codes_only_export_type}", headers:, params: {}
          }.to enqueue_job(EmailCsvJob).with(user, nil, {}, false, organisation, codes_only_export_type, "sales")
          codes_only_export_type = true
          expect {
            post "/organisations/#{organisation.id}/sales-logs/email-csv?codes_only=#{codes_only_export_type}", headers:, params: {}
          }.to enqueue_job(EmailCsvJob).with(user, nil, {}, false, organisation, codes_only_export_type, "sales")
        end
      end
    end

    describe "GET #download_lettings_csv" do
      it "renders a page with the correct header" do
        get "/organisations/#{organisation.id}/lettings-logs/csv-download?codes_only=false", headers:, params: {}
        header = page.find_css("h1")
        expect(header.text).to include("Download CSV")
      end

      it "renders a form with the correct target containing a button with the correct text" do
        get "/organisations/#{organisation.id}/lettings-logs/csv-download?codes_only=false", headers:, params: {}
        form = page.find("form.button_to")
        expect(form[:method]).to eq("post")
        expect(form[:action]).to eq("/organisations/#{organisation.id}/lettings-logs/email-csv")
        expect(form).to have_button("Send email")
      end

      it "when codes_only query parameter is false, form contains hidden field with correct value" do
        codes_only = false
        get "/organisations/#{organisation.id}/lettings-logs/csv-download?codes_only=#{codes_only}", headers:, params: {}
        hidden_field = page.find("form.button_to").find_field("codes_only", type: "hidden")
        expect(hidden_field.value).to eq(codes_only.to_s)
      end

      it "when codes_only query parameter is true, form contains hidden field with correct value" do
        codes_only = true
        get "/organisations/#{organisation.id}/lettings-logs/csv-download?codes_only=#{codes_only}", headers:, params: {}
        hidden_field = page.find("form.button_to").find_field("codes_only", type: "hidden")
        expect(hidden_field.value).to eq(codes_only.to_s)
      end

      it "when query string contains search parameter, form contains hidden field with correct value" do
        search_term = "blam"
        get "/organisations/#{organisation.id}/lettings-logs/csv-download?codes_only=true&search=#{search_term}", headers:, params: {}
        hidden_field = page.find("form.button_to").find_field("search", type: "hidden")
        expect(hidden_field.value).to eq(search_term)
      end
    end

    describe "GET #download_sales_csv" do
      it "renders a page with the correct header" do
        get "/organisations/#{organisation.id}/sales-logs/csv-download?codes_only=false", headers:, params: {}
        header = page.find_css("h1")
        expect(header.text).to include("Download CSV")
      end

      it "renders a form with the correct target containing a button with the correct text" do
        get "/organisations/#{organisation.id}/sales-logs/csv-download?codes_only=false", headers:, params: {}
        form = page.find("form.button_to")
        expect(form[:method]).to eq("post")
        expect(form[:action]).to eq("/organisations/#{organisation.id}/sales-logs/email-csv")
        expect(form).to have_button("Send email")
      end

      it "when codes_only query parameter is false, form contains hidden field with correct value" do
        codes_only = false
        get "/organisations/#{organisation.id}/sales-logs/csv-download?codes_only=#{codes_only}", headers:, params: {}
        hidden_field = page.find("form.button_to").find_field("codes_only", type: "hidden")
        expect(hidden_field.value).to eq(codes_only.to_s)
      end

      it "when codes_only query parameter is true, form contains hidden field with correct value" do
        codes_only = true
        get "/organisations/#{organisation.id}/sales-logs/csv-download?codes_only=#{codes_only}", headers:, params: {}
        hidden_field = page.find("form.button_to").find_field("codes_only", type: "hidden")
        expect(hidden_field.value).to eq(codes_only.to_s)
      end

      it "when query string contains search parameter, form contains hidden field with correct value" do
        search_term = "blam"
        get "/organisations/#{organisation.id}/sales-logs/csv-download?codes_only=true&search=#{search_term}", headers:, params: {}
        hidden_field = page.find("form.button_to").find_field("search", type: "hidden")
        expect(hidden_field.value).to eq(search_term)
      end
    end

    context "when they view the users tab" do
      before do
        get "/organisations/#{organisation.id}/users"
      end

      it "has a CSV download button with the correct path" do
        expect(page).to have_link("Download (CSV)", href: "/organisations/#{organisation.id}/users.csv")
      end

      context "when you download the CSV" do
        let(:headers) { { "Accept" => "text/csv" } }
        let(:other_organisation) { create(:organisation) }

        before do
          create_list(:user, 3, organisation:)
          create_list(:user, 2, organisation: other_organisation)
        end

        it "only includes users from that organisation" do
          get "/organisations/#{other_organisation.id}/users", headers:, params: {}
          csv = CSV.parse(response.body)
          expect(csv.count).to eq(3)
        end
      end
    end
  end

  describe "GET #data_sharing_agreement" do
    context "when not signed in" do
      it "redirects to sign in" do
        get "/organisations/#{organisation.id}/data-sharing-agreement", headers: headers
        expect(response).to redirect_to("/account/sign-in")
      end
    end

    context "when signed in" do
      before do
        allow(user).to receive(:need_two_factor_authentication?).and_return(false)
        sign_in user
      end

      context "when flag not enabled" do
        before do
          allow(FeatureToggle).to receive(:new_data_sharing_agreement?).and_return(false)
        end

        it "returns not found" do
          get "/organisations/#{organisation.id}/data-sharing-agreement", headers: headers
          expect(response).to have_http_status(:not_found)
        end
      end

      context "when flag enabled" do
        before do
          allow(FeatureToggle).to receive(:new_data_sharing_agreement?).and_return(true)
        end

        it "returns ok" do
          get "/organisations/#{organisation.id}/data-sharing-agreement", headers: headers
          expect(response).to have_http_status(:ok)
        end
      end
    end
  end

  describe "POST #data_sharing_agreement" do
    context "when not signed in" do
      it "redirects to sign in" do
        post "/organisations/#{organisation.id}/data-sharing-agreement", headers: headers
        expect(response).to redirect_to("/account/sign-in")
      end
    end

    context "when signed in" do
      before do
        allow(user).to receive(:need_two_factor_authentication?).and_return(false)
        sign_in user
      end

      context "when flag not enabled" do
        before do
          allow(FeatureToggle).to receive(:new_data_sharing_agreement?).and_return(false)
        end

        it "returns not found" do
          post "/organisations/#{organisation.id}/data-sharing-agreement", headers: headers
          expect(response).to have_http_status(:not_found)
        end
      end

      context "when flag enabled" do
        before do
          allow(FeatureToggle).to receive(:new_data_sharing_agreement?).and_return(true)
        end

        context "when user not dpo" do
          let(:user) { create(:user, is_dpo: false) }

          it "returns not found" do
            post "/organisations/#{organisation.id}/data-sharing-agreement", headers: headers
            expect(response).to have_http_status(:not_found)
          end
        end

        context "when user is dpo" do
          let(:user) { create(:user, is_dpo: true) }

          it "returns redirects to details page" do
            post "/organisations/#{organisation.id}/data-sharing-agreement", headers: headers

            expect(response).to redirect_to("/organisations/#{organisation.id}/details")
            expect(flash[:notice]).to eq("You have accepted the Data Sharing Agreement")
            expect(flash[:notification_banner_body]).to eq("Your organisation can now submit logs.")
          end

          context "when the user has already accepted the agreement" do
            before do
              DataSharingAgreement.create!(
                organisation: user.organisation,
                signed_at: Time.zone.now - 1.day,
                data_protection_officer: user,
              )
            end

            it "returns not found" do
              post "/organisations/#{organisation.id}/data-sharing-agreement", headers: headers
              expect(response).to have_http_status(:not_found)
            end
          end
        end
      end
    end
  end
end