require "rails_helper" RSpec.describe OrganisationRelationshipsController, type: :request do let(:organisation) { user.organisation } let!(:unauthorised_organisation) { FactoryBot.create(:organisation) } let(:headers) { { "Accept" => "text/html" } } let(:page) { Capybara::Node::Simple.new(response.body) } context "when user is signed in" do let(:user) { FactoryBot.create(:user, :data_coordinator) } context "with a data coordinator user" do before do sign_in user end context "when accessing the stock owners tab" do context "with an organisation that the user belongs to" do let!(:stock_owner) { FactoryBot.create(:organisation) } let!(:other_org_stock_owner) { FactoryBot.create(:organisation, name: "Foobar LTD") } let!(:inactive_stock_owner) { FactoryBot.create(:organisation, name: "Inactive LTD", active: false) } let!(:other_organisation) { FactoryBot.create(:organisation, name: "Foobar LTD 2") } before do FactoryBot.create(:organisation_relationship, child_organisation: organisation, parent_organisation: stock_owner) FactoryBot.create(:organisation_relationship, child_organisation: other_organisation, parent_organisation: other_org_stock_owner) FactoryBot.create(:organisation_relationship, child_organisation: organisation, parent_organisation: inactive_stock_owner) get "/organisations/#{organisation.id}/stock-owners", 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 an add stock owner button" do expect(page).to have_link("Add a stock owner") end it "shows a table of stock owners" do expected_html = "<table class=\"govuk-table\"" expect(response.body).to include(expected_html) expect(response.body).to include(stock_owner.name) end it "shows only stock owners for the current user's organisation" do expect(page).to have_content(stock_owner.name) expect(page).not_to have_content(other_org_stock_owner.name) end it "does not show inactive stock owners" do expect(page).not_to have_content(inactive_stock_owner.name) end it "shows the pagination count" do expect(page).to have_content("1 total stock owners") end context "when adding a stock owner" do let!(:active_organisation) { FactoryBot.create(:organisation, name: "Active Org", active: true) } let!(:inactive_organisation) { FactoryBot.create(:organisation, name: "Inactive LTD", active: false) } before do get "/organisations/#{organisation.id}/stock-owners/add", headers:, params: {} end it "has the correct header" do expect(response.body).to include("What is the name of your stock owner?") end it "shows an add button" do expect(page).to have_button("Add") end it "shows a cancel button" do expect(page).to have_link("Cancel", href: "/organisations/#{organisation.id}/stock-owners") end it "includes only active organisations as options" do expect(response.body).to include(active_organisation.name) expect(response.body).not_to include(inactive_organisation.name) end end context "and current organisation is deactivated" do before do organisation.update!(active: false) get "/organisations/#{organisation.id}/stock-owners", headers:, params: {} end it "does not show the add stock owner button" do expect(page).not_to have_link("Add a stock owner") end it "shows a banner" do expect(page).to have_content("This organisation is deactivated.") expect(page).to have_content("You cannot add any new stock owners.") end 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}/stock-owners", headers:, params: {} end it "returns not found 404 from users page" do expect(response).to have_http_status(:not_found) end end end context "when accessing the managing agents tab" do context "with an organisation that the user belongs to" do let!(:managing_agent) { FactoryBot.create(:organisation) } let!(:other_org_managing_agent) { FactoryBot.create(:organisation, name: "Foobar LTD") } let!(:inactive_managing_agent) { FactoryBot.create(:organisation, name: "Inactive LTD", active: false) } let!(:other_organisation) { FactoryBot.create(:organisation, name: "Foobar LTD") } before do FactoryBot.create(:organisation_relationship, parent_organisation: organisation, child_organisation: managing_agent) FactoryBot.create(:organisation_relationship, parent_organisation: other_organisation, child_organisation: other_org_managing_agent) FactoryBot.create(:organisation_relationship, parent_organisation: organisation, child_organisation: inactive_managing_agent) get "/organisations/#{organisation.id}/managing-agents", 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 an add managing-agent button" do expect(page).to have_link("Add a managing agent") end it "shows a table of managing-agents" do expected_html = "<table class=\"govuk-table\"" expect(response.body).to include(expected_html) expect(response.body).to include(managing_agent.name) end it "shows only managing-agents for the current user's organisation" do expect(page).to have_content(managing_agent.name) expect(page).not_to have_content(other_org_managing_agent.name) end it "does not show inactive managing-agents" do expect(page).not_to have_content(inactive_managing_agent.name) end it "shows the pagination count" do expect(page).to have_content("1 total managing agents") end context "and current organisation is deactivated" do before do organisation.update!(active: false) get "/organisations/#{organisation.id}/managing-agents", headers:, params: {} end it "does not show the add managing agent button" do expect(page).not_to have_link("Add a managing agent") end it "shows a banner" do expect(page).to have_content("This organisation is deactivated.") expect(page).to have_content("You cannot add any new managing agents.") end end end context "when adding a managing agent" do let!(:active_organisation) { FactoryBot.create(:organisation, name: "Active Org", active: true) } let!(:inactive_organisation) { FactoryBot.create(:organisation, name: "Inactive LTD", active: false) } before do get "/organisations/#{organisation.id}/managing-agents/add", headers:, params: {} end it "has the correct header" do expect(response.body).to include("What is the name of your managing agent?") end it "includes only active organisations as options" do expect(response.body).to include(active_organisation.name) expect(response.body).not_to include(inactive_organisation.name) 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}/managing-agents", headers:, params: {} end it "returns not found 404 from users page" do expect(response).to have_http_status(:not_found) end end end describe "organisation_relationships#create_stock_owner" do let!(:stock_owner) { FactoryBot.create(:organisation) } let(:params) do { "organisation_relationship": { "parent_organisation_id": stock_owner.id, }, } end let(:request) { post "/organisations/#{organisation.id}/stock-owners", headers:, params: } it "creates a new organisation relationship" do expect { request }.to change(OrganisationRelationship, :count).by(1) end it "sets the organisation relationship attributes correctly" do request expect(OrganisationRelationship).to exist(child_organisation_id: organisation.id, parent_organisation_id: stock_owner.id) end it "redirects to the organisation list" do request expect(response).to redirect_to("/organisations/#{organisation.id}/stock-owners") end end describe "organisation_relationships#create_managing_agent" do let!(:managing_agent) { FactoryBot.create(:organisation) } let(:params) do { "organisation_relationship": { "child_organisation_id": managing_agent.id, }, } end let(:request) { post "/organisations/#{organisation.id}/managing-agents", headers:, params: } it "creates a new organisation relationship" do expect { request }.to change(OrganisationRelationship, :count).by(1) end it "sets the organisation relationship attributes correctly" do request expect(OrganisationRelationship).to exist(parent_organisation_id: organisation.id, child_organisation_id: managing_agent.id) end it "redirects to the organisation list" do request expect(response).to redirect_to("/organisations/#{organisation.id}/managing-agents") end end describe "organisation_relationships#delete_stock_owner" do let!(:stock_owner) { FactoryBot.create(:organisation) } let(:params) do { "target_organisation_id": stock_owner.id, } end let(:request) { delete "/organisations/#{organisation.id}/stock-owners", headers:, params: } before do FactoryBot.create(:organisation_relationship, child_organisation: organisation, parent_organisation: stock_owner) end it "deletes the new organisation relationship" do expect { request }.to change(OrganisationRelationship, :count).by(-1) end it "redirects to the organisation list" do request expect(response).to redirect_to("/organisations/#{organisation.id}/stock-owners") end end describe "organisation_relationships#delete_managing_agent" do let!(:managing_agent) { FactoryBot.create(:organisation) } let(:params) do { "target_organisation_id": managing_agent.id, } end let(:request) { delete "/organisations/#{organisation.id}/managing-agents", headers:, params: } before do FactoryBot.create( :organisation_relationship, parent_organisation: organisation, child_organisation: managing_agent, ) end it "deletes the new organisation relationship" do expect { request }.to change(OrganisationRelationship, :count).by(-1) end it "redirects to the organisation list" do request expect(response).to redirect_to("/organisations/#{organisation.id}/managing-agents") end end end context "with a data provider user" do let(:user) { FactoryBot.create(:user) } before do sign_in user end context "when accessing the stock owners tab" do context "with an organisation that the user belongs to" do let!(:stock_owner) { FactoryBot.create(:organisation) } let!(:other_org_stock_owner) { FactoryBot.create(:organisation, name: "Foobar LTD") } let!(:other_organisation) { FactoryBot.create(:organisation, name: "Foobar LTD") } before do FactoryBot.create(:organisation_relationship, child_organisation: organisation, parent_organisation: stock_owner) FactoryBot.create(:organisation_relationship, child_organisation: other_organisation, parent_organisation: other_org_stock_owner) get "/organisations/#{organisation.id}/stock-owners", 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 "doesn't show an add stock owner button" do expect(page).not_to have_link("Add a stock owner") end it "shows a table of stock owners" do expected_html = "<table class=\"govuk-table\"" expect(response.body).to include(expected_html) expect(response.body).to include(stock_owner.name) end it "shows only stock owners for the current user's organisation" do expect(page).to have_content(stock_owner.name) expect(page).not_to have_content(other_org_stock_owner.name) end it "shows the pagination count" do expect(page).to have_content("1 total stock owners") 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}/stock-owners", headers:, params: {} end it "returns not found 404 from users page" do expect(response).to have_http_status(:not_found) end end end context "when directly accessing the page to add a stock owner" do let(:request) { get "/organisations/#{organisation.id}/stock-owners/add" } it "returns 401" do request expect(response).to have_http_status(:unauthorized) end end context "when directly adding a stock owner" do let!(:stock_owner) { FactoryBot.create(:organisation) } let(:params) do { "organisation_relationship": { "parent_organisation_id": stock_owner.id, }, } end let(:request) { post "/organisations/#{organisation.id}/stock-owners", params: } it "returns 401" do request expect(response).to have_http_status(:unauthorized) end it "does not create a new organisation relationship" do expect { request }.not_to change(OrganisationRelationship, :count) end end context "when directly removing a stock owner" do let(:stock_owner) { FactoryBot.create(:organisation) } let(:request) { get "/organisations/#{organisation.id}/stock-owners/remove?target_organisation_id=#{stock_owner.id}" } before do FactoryBot.create(:organisation_relationship, parent_organisation: stock_owner, child_organisation: organisation) end it "returns 401" do request expect(response).to have_http_status(:unauthorized) end end context "when directly accessing the page to add a managing agent" do let(:request) { get "/organisations/#{organisation.id}/managing-agents/add" } it "returns 401" do request expect(response).to have_http_status(:unauthorized) end end context "when directly adding a managing agent" do let!(:managing_agent) { FactoryBot.create(:organisation) } let(:params) do { "organisation_relationship": { "child_organisation_id": managing_agent.id, }, } end let(:request) { post "/organisations/#{organisation.id}/managing-agents", params: } it "returns 401" do request expect(response).to have_http_status(:unauthorized) end it "does not create a new organisation relationship" do expect { request }.not_to change(OrganisationRelationship, :count) end end context "when directly removing a managing agent" do let(:managing_agent) { FactoryBot.create(:organisation) } let(:request) { get "/organisations/#{organisation.id}/managing-agents/remove?target_organisation_id=#{managing_agent.id}" } before do FactoryBot.create(:organisation_relationship, parent_organisation: organisation, child_organisation: managing_agent) end it "returns 401" do request expect(response).to have_http_status(:unauthorized) end end context "when accessing the managing agents tab" do context "with an organisation that the user belongs to" do let!(:managing_agent) { FactoryBot.create(:organisation) } let!(:other_org_managing_agent) { FactoryBot.create(:organisation, name: "Foobar LTD") } let!(:other_organisation) { FactoryBot.create(:organisation, name: "Foobar LTD") } before do FactoryBot.create(:organisation_relationship, parent_organisation: organisation, child_organisation: managing_agent) FactoryBot.create(:organisation_relationship, parent_organisation: other_organisation, child_organisation: other_org_managing_agent) get "/organisations/#{organisation.id}/managing-agents", 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 "doesn't show an add managing agent button" do expect(page).not_to have_link("Add a managing agent") end it "shows a table of managing agents" do expected_html = "<table class=\"govuk-table\"" expect(response.body).to include(expected_html) expect(response.body).to include(managing_agent.name) end it "shows only managing agents for the current user's organisation" do expect(page).to have_content(managing_agent.name) expect(page).not_to have_content(other_org_managing_agent.name) end it "shows the pagination count" do expect(page).to have_content("1 total managing agents") 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}/managing-agents", headers:, params: {} end it "returns not found 404 from users page" do expect(response).to have_http_status(:not_found) end end end end context "with a support user" do let(:user) { FactoryBot.create(:user, :support) } before do allow(user).to receive(:need_two_factor_authentication?).and_return(false) sign_in user end describe "organisation_relationships#create_stock_owner" do let!(:stock_owner) { FactoryBot.create(:organisation) } let(:params) do { "organisation_relationship": { "parent_organisation_id": stock_owner.id, }, } end let(:request) { post "/organisations/#{organisation.id}/stock-owners", headers:, params: } it "creates a new organisation relationship" do expect { request }.to change(OrganisationRelationship, :count).by(1) end it "sets the organisation relationship attributes correctly" do request expect(OrganisationRelationship).to exist(child_organisation_id: organisation.id, parent_organisation_id: stock_owner.id) end it "redirects to the organisation list" do request expect(response).to redirect_to("/organisations/#{organisation.id}/stock-owners") end end describe "organisation_relationships#create_managing_agent" do let!(:managing_agent) { FactoryBot.create(:organisation) } let(:params) do { "organisation_relationship": { "child_organisation_id": managing_agent.id, }, } end let(:request) { post "/organisations/#{organisation.id}/managing-agents", headers:, params: } it "creates a new organisation relationship" do expect { request }.to change(OrganisationRelationship, :count).by(1) end it "sets the organisation relationship attributes correctly" do request expect(OrganisationRelationship).to exist(parent_organisation_id: organisation.id, child_organisation_id: managing_agent.id) end it "redirects to the organisation list" do request expect(response).to redirect_to("/organisations/#{organisation.id}/managing-agents") end end describe "organisation_relationships#delete_stock_owner" do let!(:stock_owner) { FactoryBot.create(:organisation) } let(:params) do { "target_organisation_id": stock_owner.id, } end let(:request) { delete "/organisations/#{organisation.id}/stock-owners", headers:, params: } before do FactoryBot.create(:organisation_relationship, child_organisation: organisation, parent_organisation: stock_owner) end it "deletes the new organisation relationship" do expect { request }.to change(OrganisationRelationship, :count).by(-1) end it "redirects to the organisation list" do request expect(response).to redirect_to("/organisations/#{organisation.id}/stock-owners") end end describe "organisation_relationships#delete_managing_agent" do let!(:managing_agent) { FactoryBot.create(:organisation) } let(:params) do { "target_organisation_id": managing_agent.id, } end let(:request) { delete "/organisations/#{organisation.id}/managing-agents", headers:, params: } before do FactoryBot.create( :organisation_relationship, parent_organisation: organisation, child_organisation: managing_agent, ) end it "deletes the new organisation relationship" do expect { request }.to change(OrganisationRelationship, :count).by(-1) end it "redirects to the organisation list" do request expect(response).to redirect_to("/organisations/#{organisation.id}/managing-agents") end end context "when viewing a specific organisation's stock owners" do let!(:stock_owner) { FactoryBot.create(:organisation) } let!(:other_org_stock_owner) { FactoryBot.create(:organisation, name: "Foobar LTD") } let!(:other_organisation) { FactoryBot.create(:organisation, name: "Foobar LTD 2") } before do FactoryBot.create(:organisation_relationship, child_organisation: organisation, parent_organisation: stock_owner) FactoryBot.create(:organisation_relationship, child_organisation: other_organisation, parent_organisation: other_org_stock_owner) get "/organisations/#{organisation.id}/stock-owners", 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 "shows a table of stock owners" do expected_html = "<table class=\"govuk-table\"" expect(response.body).to include(expected_html) expect(response.body).to include(stock_owner.name) end it "shows only stock owners for this organisation" do expect(page).to have_content(stock_owner.name) expect(page).not_to have_content(other_org_stock_owner.name) end it "shows remove link(s)" do expect(response.body).to include("Remove") end it "shows the pagination count" do expect(page).to have_content("1 total stock owners") end context "when adding a stock owner" do before do get "/organisations/#{organisation.id}/stock-owners/add", headers:, params: {} end it "has the correct header" do expect(response.body).to include("What is the name of this organisation's stock owner?") end it "shows an add button" do expect(page).to have_button("Add") end end end context "when viewing a specific organisation's managing agents" do let!(:managing_agent) { FactoryBot.create(:organisation) } let!(:other_org_managing_agent) { FactoryBot.create(:organisation, name: "Foobar LTD") } let!(:other_organisation) { FactoryBot.create(:organisation, name: "Foobar LTD 2") } before do FactoryBot.create(:organisation_relationship, parent_organisation: organisation, child_organisation: managing_agent) FactoryBot.create(:organisation_relationship, parent_organisation: other_organisation, child_organisation: other_org_managing_agent) get "/organisations/#{organisation.id}/managing-agents", 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 "shows a table of managing agents" do expected_html = "<table class=\"govuk-table\"" expect(response.body).to include(expected_html) expect(response.body).to include(managing_agent.name) end it "shows only managing agents for this organisation" do expect(page).to have_content(managing_agent.name) expect(page).not_to have_content(other_org_managing_agent.name) end it "shows the pagination count" do expect(page).to have_content("1 total managing agents") end it "shows remove link(s)" do expect(response.body).to include("Remove") end context "when adding a managing agent" do before do get "/organisations/#{organisation.id}/managing-agents/add", headers:, params: {} end it "has the correct header" do expect(response.body).to include("What is the name of this organisation's managing agent?") end it "shows an add button" do expect(page).to have_button("Add") end it "shows a cancel button" do expect(page).to have_link("Cancel", href: "/organisations/#{organisation.id}/managing-agents") end end end end end end