diff --git a/app/components/projects/index_sub_header_component.rb b/app/components/projects/index_sub_header_component.rb index e231720bed35..427a48a06ee6 100644 --- a/app/components/projects/index_sub_header_component.rb +++ b/app/components/projects/index_sub_header_component.rb @@ -84,10 +84,8 @@ def new_workspace_label(type) def allowed_new_workspace_types @allowed_new_workspace_types ||= [].tap do |types| - if OpenProject::FeatureDecisions.portfolio_models_active? - types << "portfolio" if @current_user.allowed_globally?(:add_portfolios) - types << "program" if @current_user.allowed_globally?(:add_programs) - end + types << "portfolio" if @current_user.allowed_globally?(:add_portfolios) + types << "program" if @current_user.allowed_globally?(:add_programs) types << "project" if @current_user.allowed_globally?(:add_project) end end diff --git a/app/components/projects/row_component.rb b/app/components/projects/row_component.rb index 8cd0697a8127..38a47067611d 100644 --- a/app/components/projects/row_component.rb +++ b/app/components/projects/row_component.rb @@ -172,7 +172,6 @@ def name_link_section end def workspace_type_badge - return unless OpenProject::FeatureDecisions.portfolio_models_active? # Only show icon and type for non-project workspaces return unless project.workspace_type.in?(["portfolio", "program"]) diff --git a/app/controllers/portfolios/menus_controller.rb b/app/controllers/portfolios/menus_controller.rb index f301f114563e..b8b5e7a2c8d9 100644 --- a/app/controllers/portfolios/menus_controller.rb +++ b/app/controllers/portfolios/menus_controller.rb @@ -31,7 +31,6 @@ module Portfolios class MenusController < ApplicationController authorization_checked! :show - before_action :not_authorized_on_feature_flag_inactive before_action :authorize_portfolio_access, only: %i[show] def show @@ -47,9 +46,5 @@ def authorize_portfolio_access render_403 unless User.current.allowed_globally?(:add_portfolios) || Project.portfolio.allowed_to(User.current, :view_project).any? end - - def not_authorized_on_feature_flag_inactive - render_403 unless OpenProject::FeatureDecisions.portfolio_models_active? - end end end diff --git a/app/controllers/portfolios_controller.rb b/app/controllers/portfolios_controller.rb index 883eee115635..9c23460bbcfb 100644 --- a/app/controllers/portfolios_controller.rb +++ b/app/controllers/portfolios_controller.rb @@ -34,7 +34,6 @@ # projects in these cases. class PortfoliosController < ProjectsController before_action :authorize_portfolio_access, only: %i[index] - before_action :not_authorized_on_feature_flag_inactive skip_before_action :load_query_or_deny_access # skip using the superclass's before action because the next must be called first before_action :set_default_query, only: %i[index] # Must be called before `load_query_or_deny_access` diff --git a/app/controllers/programs_controller.rb b/app/controllers/programs_controller.rb index 582b9d7b369f..b480a1022d3c 100644 --- a/app/controllers/programs_controller.rb +++ b/app/controllers/programs_controller.rb @@ -29,5 +29,4 @@ # ++ class ProgramsController < ProjectsController - before_action :not_authorized_on_feature_flag_inactive end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 124afd6d046a..915a21f4c0fc 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -330,10 +330,6 @@ def supported_export_formats ::Exports::Register.list_formats(Project).map(&:to_s) end - def not_authorized_on_feature_flag_inactive - render_403 unless OpenProject::FeatureDecisions.portfolio_models_active? - end - def layout_for_new if portfolio_management_feature_missing? "global" diff --git a/config/initializers/feature_decisions.rb b/config/initializers/feature_decisions.rb index 33879704458c..bdf1edfe62d8 100644 --- a/config/initializers/feature_decisions.rb +++ b/config/initializers/feature_decisions.rb @@ -53,10 +53,6 @@ description: "Allow exporting a meeting with FITKO styling. " \ "See #65124 for details." -OpenProject::FeatureDecisions.add :portfolio_models, - description: "Enables the creation and management of portfolio and program work spaces.", - force_active: true - OpenProject::FeatureDecisions.add :user_working_times, description: "Enables tracking of user working hours and non-working days." diff --git a/config/initializers/menus.rb b/config/initializers/menus.rb index c1dff6e8bf4d..01b9812e815d 100644 --- a/config/initializers/menus.rb +++ b/config/initializers/menus.rb @@ -37,8 +37,7 @@ caption: I18n.t("label_portfolio_plural"), icon: "briefcase", if: ->(_) { - OpenProject::FeatureDecisions.portfolio_models_active? && - (User.current.logged? || !Setting.login_required?) && + (User.current.logged? || !Setting.login_required?) && (User.current.allowed_globally?(:add_portfolios) || Project.portfolio.allowed_to(User.current, :view_project).any?) }, @@ -198,8 +197,7 @@ icon: "briefcase", after: :my_page, if: ->(_) { - OpenProject::FeatureDecisions.portfolio_models_active? && - (User.current.logged? || !Setting.login_required?) && + (User.current.logged? || !Setting.login_required?) && (User.current.allowed_globally?(:add_portfolios) || Project.portfolio.allowed_to(User.current, :view_project).any?) }, diff --git a/config/initializers/permissions.rb b/config/initializers/permissions.rb index 785337e54b08..1a24afa7f6be 100644 --- a/config/initializers/permissions.rb +++ b/config/initializers/permissions.rb @@ -42,14 +42,12 @@ { portfolios: %i[new create] }, permissible_on: :global, require: :loggedin, - visible: -> { OpenProject::FeatureDecisions.portfolio_models_active? }, contract_actions: { portfolios: %i[create] } map.permission :add_programs, { programs: %i[new create] }, permissible_on: :global, require: :loggedin, - visible: -> { OpenProject::FeatureDecisions.portfolio_models_active? }, contract_actions: { programs: %i[create] } map.permission :archive_project, diff --git a/lib/api/v3/portfolios/portfolios_api.rb b/lib/api/v3/portfolios/portfolios_api.rb index 48e2df8e5fea..9e06c3384d2c 100644 --- a/lib/api/v3/portfolios/portfolios_api.rb +++ b/lib/api/v3/portfolios/portfolios_api.rb @@ -33,10 +33,6 @@ module V3 module Portfolios class PortfoliosAPI < ::API::OpenProjectAPI resources :portfolios do - after_validation do - guard_feature_flag :portfolio_models - end - get &::API::V3::Utilities::Endpoints::SqlFallbackedIndex.new(model: Project, scope: -> { Project diff --git a/lib/api/v3/programs/programs_api.rb b/lib/api/v3/programs/programs_api.rb index 1bf54a0ee8a3..b113d61160b7 100644 --- a/lib/api/v3/programs/programs_api.rb +++ b/lib/api/v3/programs/programs_api.rb @@ -33,10 +33,6 @@ module V3 module Programs class ProgramsAPI < ::API::OpenProjectAPI resources :programs do - after_validation do - guard_feature_flag :portfolio_models - end - get &::API::V3::Utilities::Endpoints::SqlFallbackedIndex.new(model: Project, scope: -> { Project diff --git a/spec/components/projects/index_sub_header_component_spec.rb b/spec/components/projects/index_sub_header_component_spec.rb index bcd507c4b03f..682f9874cb07 100644 --- a/spec/components/projects/index_sub_header_component_spec.rb +++ b/spec/components/projects/index_sub_header_component_spec.rb @@ -112,36 +112,24 @@ def self.workspace_types = %i[portfolio program project] context "when user has add_portfolios permission" do let(:global_permissions) { %i[add_portfolios] } - context "without feature flag", with_flag: { portfolio_models: false } do - include_examples "renders no buttons" + context "without enterprise feature enabled", with_ee: [] do + include_examples "renders add button directly", :portfolio, upsell: true end - context "with feature flag", with_flag: { portfolio_models: true } do - context "without enterprise feature enabled", with_ee: [] do - include_examples "renders add button directly", :portfolio, upsell: true - end - - context "with enterprise feature enabled", with_ee: :portfolio_management do - include_examples "renders add button directly", :portfolio, upsell: false - end + context "with enterprise feature enabled", with_ee: :portfolio_management do + include_examples "renders add button directly", :portfolio, upsell: false end end context "when user has add_programs permission" do let(:global_permissions) { %i[add_programs] } - context "without feature flag", with_flag: { portfolio_models: false } do - include_examples "renders no buttons" + context "without enterprise feature enabled", with_ee: [] do + include_examples "renders add button directly", :program, upsell: true end - context "with feature flag", with_flag: { portfolio_models: true } do - context "without enterprise feature enabled", with_ee: [] do - include_examples "renders add button directly", :program, upsell: true - end - - context "with enterprise feature enabled", with_ee: :portfolio_management do - include_examples "renders add button directly", :program, upsell: false - end + context "with enterprise feature enabled", with_ee: :portfolio_management do + include_examples "renders add button directly", :program, upsell: false end end @@ -150,46 +138,32 @@ def self.workspace_types = %i[portfolio program project] include_examples "renders add button directly", :project, upsell: false - context "with feature flag", with_flag: { portfolio_models: true } do - context "with enterprise feature enabled", with_ee: :portfolio_management do - include_examples "renders add button directly", :project, upsell: false - end + context "with enterprise feature enabled", with_ee: :portfolio_management do + include_examples "renders add button directly", :project, upsell: false end end context "when user has only part (add_project and add_programs) of permissions" do let(:global_permissions) { %i[add_project add_programs] } - context "without feature flag", with_flag: { portfolio_models: false } do - include_examples "renders add button directly", :project, upsell: false + context "without enterprise feature enabled", with_ee: [] do + include_examples "renders add buttons in a pulldown", %i[program project], upsell: %i[program] end - context "with feature flag", with_flag: { portfolio_models: true } do - context "without enterprise feature enabled", with_ee: [] do - include_examples "renders add buttons in a pulldown", %i[program project], upsell: %i[program] - end - - context "with enterprise feature enabled", with_ee: :portfolio_management do - include_examples "renders add buttons in a pulldown", %i[program project], upsell: [] - end + context "with enterprise feature enabled", with_ee: :portfolio_management do + include_examples "renders add buttons in a pulldown", %i[program project], upsell: [] end end context "when user has all permissions" do let(:global_permissions) { %i[add_project add_portfolios add_programs] } - context "without feature flag", with_flag: { portfolio_models: false } do - include_examples "renders add button directly", :project, upsell: false + context "without enterprise feature enabled", with_ee: [] do + include_examples "renders add buttons in a pulldown", workspace_types, upsell: %i[portfolio program] end - context "with feature flag", with_flag: { portfolio_models: true } do - context "without enterprise feature enabled", with_ee: [] do - include_examples "renders add buttons in a pulldown", workspace_types, upsell: %i[portfolio program] - end - - context "with enterprise feature enabled", with_ee: :portfolio_management do - include_examples "renders add buttons in a pulldown", workspace_types, upsell: [] - end + context "with enterprise feature enabled", with_ee: :portfolio_management do + include_examples "renders add buttons in a pulldown", workspace_types, upsell: [] end end end diff --git a/spec/controllers/portfolios_controller_spec.rb b/spec/controllers/portfolios_controller_spec.rb index bb64687aabc3..c0cbeb64f77b 100644 --- a/spec/controllers/portfolios_controller_spec.rb +++ b/spec/controllers/portfolios_controller_spec.rb @@ -30,7 +30,7 @@ require "spec_helper" -RSpec.describe PortfoliosController, with_flag: { portfolio_models: true } do +RSpec.describe PortfoliosController do shared_let(:admin) { create(:admin) } shared_let(:restricted_user) { create(:user) } @@ -92,41 +92,21 @@ let(:parent) { nil } context "as an admin" do - context "with flag enabled", with_flag: { portfolio_models: true } do - it_behaves_like "successful request" - end - - context "with flag disabled", with_flag: { portfolio_models: false } do - it "returns 403 Not Authorized" do - expect(response).not_to be_successful - expect(response).to have_http_status :forbidden - end - end + it_behaves_like "successful request" end context "as a non-admin with global add_portfolios permission" do let(:user) { create(:user, global_permissions: [:add_portfolios]) } - context "with flag enabled", with_flag: { portfolio_models: true } do - it_behaves_like "successful request" - end - - context "with flag disabled", with_flag: { portfolio_models: false } do - it "returns 403 Not Authorized" do - expect(response).not_to be_successful - expect(response).to have_http_status :forbidden - end - end + it_behaves_like "successful request" end context "as a non-admin without add_portfolios permission" do let(:user) { create(:user) } - context "with flag enabled", with_flag: { portfolio_models: true } do - it "returns 403 Not Authorized" do - expect(response).not_to be_successful - expect(response).to have_http_status :forbidden - end + it "returns 403 Not Authorized" do + expect(response).not_to be_successful + expect(response).to have_http_status :forbidden end end @@ -172,49 +152,43 @@ end end - context "without the portfolio feature flag set", with_flag: { portfolio_models: false } do - it_behaves_like "forbidden index request" - end + it_behaves_like "successful index" - context "with the portfolio feature flag set" do - it_behaves_like "successful index" + it "includes active portfolios in the result" do + query = assigns(:query) + expect(query).to be_a_new(ProjectQuery) + expect(query).to be_valid - it "includes active portfolios in the result" do - query = assigns(:query) - expect(query).to be_a_new(ProjectQuery) - expect(query).to be_valid + expect(query.results.portfolio).to eq([portfolio_a, portfolio_b, portfolio_c]) + end - expect(query.results.portfolio).to eq([portfolio_a, portfolio_b, portfolio_c]) - end + context "with a user who does not have permission to see the portfolio module" do + let(:user) { restricted_user } - context "with a user who does not have permission to see the portfolio module" do - let(:user) { restricted_user } + it_behaves_like "forbidden index request" + end - it_behaves_like "forbidden index request" - end + context "with a user who has permission to see the portfolio module" do + context "when the user has the global add_portfolios permission" do + let(:user) { create(:user, global_permissions: [:add_portfolios]) } - context "with a user who has permission to see the portfolio module" do - context "when the user has the global add_portfolios permission" do - let(:user) { create(:user, global_permissions: [:add_portfolios]) } + it_behaves_like "successful index" + end - it_behaves_like "successful index" + context "when the user has a view_project permission on an active portfolio" do + let(:user) do + create(:user, member_with_permissions: { portfolio_a => [:view_project] }) end - context "when the user has a view_project permission on an active portfolio" do - let(:user) do - create(:user, member_with_permissions: { portfolio_a => [:view_project] }) - end + it_behaves_like "successful index" + end - it_behaves_like "successful index" + context "when the user has a view_project permission on an inactive portfolio" do + let(:user) do + create(:user, member_with_permissions: { portfolio_d => [:view_project] }) end - context "when the user has a view_project permission on an inactive portfolio" do - let(:user) do - create(:user, member_with_permissions: { portfolio_d => [:view_project] }) - end - - it_behaves_like "forbidden index request" - end + it_behaves_like "forbidden index request" end end end diff --git a/spec/controllers/programs_controller_spec.rb b/spec/controllers/programs_controller_spec.rb index 28229accfec3..9ef7957446b5 100644 --- a/spec/controllers/programs_controller_spec.rb +++ b/spec/controllers/programs_controller_spec.rb @@ -30,7 +30,7 @@ require "spec_helper" -RSpec.describe ProgramsController, with_flag: { portfolio_models: true } do +RSpec.describe ProgramsController do shared_let(:admin) { create(:admin) } shared_let(:add_programs_user) { create(:user, global_permissions: [:add_programs]) } shared_let(:no_permission_user) { create(:user) } @@ -94,41 +94,21 @@ let(:parent) { nil } context "as an admin" do - context "with flag enabled", with_flag: { portfolio_models: true } do - it_behaves_like "successful request" - end - - context "with flag disabled", with_flag: { portfolio_models: false } do - it "returns 403 Not Authorized" do - expect(response).not_to be_successful - expect(response).to have_http_status :forbidden - end - end + it_behaves_like "successful request" end context "as a non-admin with global add_programs permission" do let(:user) { add_programs_user } - context "with flag enabled", with_flag: { portfolio_models: true } do - it_behaves_like "successful request" - end - - context "with flag disabled", with_flag: { portfolio_models: false } do - it "returns 403 Not Authorized" do - expect(response).not_to be_successful - expect(response).to have_http_status :forbidden - end - end + it_behaves_like "successful request" end context "as a non-admin without add_programs permission" do let(:user) { no_permission_user } - context "with flag enabled", with_flag: { portfolio_models: true } do - it "returns 403 Not Authorized" do - expect(response).not_to be_successful - expect(response).to have_http_status :forbidden - end + it "returns 403 Not Authorized" do + expect(response).not_to be_successful + expect(response).to have_http_status :forbidden end end @@ -162,7 +142,7 @@ post :create, params: { project: { name: "New Program" }, parent_id: parent&.id } end - context "as a non-admin without global add_programs permission", with_flag: { portfolio_models: true } do + context "as a non-admin without global add_programs permission" do let(:user) { no_permission_user } it "returns 403 Not Authorized" do @@ -171,7 +151,7 @@ end end - context "as a non-admin with global add_programs permission", with_flag: { portfolio_models: true } do + context "as a non-admin with global add_programs permission" do let(:user) { add_programs_user } it "redirects to project show", :aggregate_failures do diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index a4f7d0f13c28..5d68e1fb2b28 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -270,7 +270,7 @@ end end - context "when the parent is invalid", with_flag: { portfolio_models: true } do + context "when the parent is invalid" do shared_let(:invalid_parent) { create(:project, workspace_type: :program) } let(:project_params) { { name: "Valid Project", parent_id: invalid_parent.id, workspace_type: :portfolio } } @@ -417,7 +417,7 @@ end end - context "when service call fails", with_flag: { portfolio_models: true } do + context "when service call fails" do let(:name) { "" } let(:project) { Project.new } let(:service_result) { ServiceResult.failure(result: project, message: "") } diff --git a/spec/features/global_roles/global_create_project_spec.rb b/spec/features/global_roles/global_create_project_spec.rb index f019cb3184c0..2b581a0bfa99 100644 --- a/spec/features/global_roles/global_create_project_spec.rb +++ b/spec/features/global_roles/global_create_project_spec.rb @@ -30,8 +30,7 @@ require "spec_helper" -RSpec.describe "Global role: Global Create project", - :js do +RSpec.describe "Global role: Global Create project", :js do shared_let(:admin) { create(:admin) } shared_let(:user) { create(:user) } shared_let(:project) { create(:project) } @@ -113,31 +112,16 @@ end end - describe "portfolio_models feature flag" do - context "when enabled", with_flag: { portfolio_models: true } do - let(:projects_menu) { Components::Projects::TopMenu.new } + describe "projects menu" do + let(:projects_menu) { Components::Projects::TopMenu.new } - current_user { admin } - - it "does not show the button for project creation and list" do - projects_page.visit! - projects_menu.toggle! - projects_menu.expect_no_project_create_button - projects_menu.expect_no_project_list_button - end - end - - describe "when disabled", with_flag: { portfolio_models: false } do - let(:projects_menu) { Components::Projects::TopMenu.new } - - current_user { admin } + current_user { admin } - it "shows the button for project creation and list" do - projects_page.visit! - projects_menu.toggle! - projects_menu.expect_project_create_button - projects_menu.expect_project_list_button - end + it "does not show the button for project creation and list" do + projects_page.visit! + projects_menu.toggle! + projects_menu.expect_no_project_create_button + projects_menu.expect_no_project_list_button end end end diff --git a/spec/features/portfolios/create_spec.rb b/spec/features/portfolios/create_spec.rb index cd298de15b39..8dabd3e1c63d 100644 --- a/spec/features/portfolios/create_spec.rb +++ b/spec/features/portfolios/create_spec.rb @@ -58,7 +58,7 @@ current_user { user_with_permissions } context "with enterprise feature enabled", with_ee: :portfolio_management do - it "can create a portfolio", with_flag: { portfolio_models: true } do + it "can create a portfolio" do projects_page.visit! projects_page.create_new_workspace @@ -87,7 +87,7 @@ expect(portfolio.parent).to be_nil end - it "redirects to portfolios#index when users cancels", with_flag: { portfolio_models: true } do + it "redirects to portfolios#index when users cancels" do visit new_portfolio_path expect(page).to have_heading "New portfolio" @@ -96,7 +96,7 @@ expect(page).to have_current_path portfolios_path end - context "without the necessary permissions to create portfolios", with_flag: { portfolio_models: true } do + context "without the necessary permissions to create portfolios" do current_user { create(:user) } it "cannot create the portfolio" do @@ -105,18 +105,10 @@ expect(page).to have_content "[Error 403] You are not authorized to access this page." end end - - context "without the feature flag being active", with_flag: { portfolio_models: false } do - it "cannot create the portfolio" do - visit new_portfolio_path - - expect(page).to have_content "[Error 403] You are not authorized to access this page." - end - end end context "without enterprise feature enabled", with_ee: [] do - it "shows enterprise banner instead of the form", with_flag: { portfolio_models: true } do + it "shows enterprise banner instead of the form" do projects_page.visit! projects_page.create_new_workspace diff --git a/spec/features/portfolios/index_spec.rb b/spec/features/portfolios/index_spec.rb index ee41bb6e92a5..6e131b1ef37f 100644 --- a/spec/features/portfolios/index_spec.rb +++ b/spec/features/portfolios/index_spec.rb @@ -58,174 +58,166 @@ portfolios_page.visit! end - context "with the feature flag enabled", with_flag: { portfolio_models: true } do - it "lists available active portfolios" do - expect(page).to have_title("Portfolios") - portfolios_page.expect_title("Active portfolios") - - portfolios_page.expect_portfolios_listed(portfolio_a, portfolio_b, portfolio_favorited) - portfolios_page.expect_portfolios_not_listed(inactive_portfolio) + it "lists available active portfolios" do + expect(page).to have_title("Portfolios") + portfolios_page.expect_title("Active portfolios") - portfolios_page.within_row(portfolio_a) do - # Portfolios link to their overview page - expect(page).to have_link(portfolio_a.name, href: project_overview_path(portfolio_a)) - - expect(page).to have_text("2 projects") - expect(page).to have_text("1 program") - end - end + portfolios_page.expect_portfolios_listed(portfolio_a, portfolio_b, portfolio_favorited) + portfolios_page.expect_portfolios_not_listed(inactive_portfolio) - it "shows the create new portfolio button" do - portfolios_page.expect_new_portfolio_button - portfolios_page.create_new_portfolio + portfolios_page.within_row(portfolio_a) do + # Portfolios link to their overview page + expect(page).to have_link(portfolio_a.name, href: project_overview_path(portfolio_a)) - expect(page).to have_current_path(new_portfolio_path) + expect(page).to have_text("2 projects") + expect(page).to have_text("1 program") end + end - context "with a restricted user" do - let(:user) do - create(:user, - global_permissions: [], - member_with_permissions: { portfolio_a => [:view_project] }) - end - - it "does not show the create new portfolio button" do - portfolios_page.expect_title("Active portfolios") - portfolios_page.expect_portfolios_listed(portfolio_a) + it "shows the create new portfolio button" do + portfolios_page.expect_new_portfolio_button + portfolios_page.create_new_portfolio - portfolios_page.expect_no_new_portfolio_button - end + expect(page).to have_current_path(new_portfolio_path) + end - it "only lists visible portfolios" do - portfolios_page.expect_portfolios_not_listed(inactive_portfolio, portfolio_b, portfolio_favorited) - end + context "with a restricted user" do + let(:user) do + create(:user, + global_permissions: [], + member_with_permissions: { portfolio_a => [:view_project] }) end - it "offers queries in the menu items" do - menu_items = portfolios_page.sidebar_menu_items - - expected_menu_items = [ - "Active portfolios", - "My portfolios", - "Favorite portfolios", - "Archived portfolios" - ] + it "does not show the create new portfolio button" do + portfolios_page.expect_title("Active portfolios") + portfolios_page.expect_portfolios_listed(portfolio_a) - expect(menu_items).to eq(expected_menu_items) + portfolios_page.expect_no_new_portfolio_button end - it "lets you select a query by clicking on its menu item" do - click_on "Favorite portfolios" - portfolios_page.expect_title("Favorite portfolios") - portfolios_page.expect_portfolios_listed(portfolio_favorited) - portfolios_page.expect_portfolios_not_listed(portfolio_a, portfolio_b, inactive_portfolio) - - click_on "My portfolios" - portfolios_page.expect_title("My portfolios") - portfolios_page.expect_portfolios_listed(portfolio_a) - portfolios_page.expect_portfolios_not_listed(portfolio_favorited, portfolio_b, inactive_portfolio) - - click_on "Archived portfolios" - portfolios_page.expect_title("Archived portfolios") - portfolios_page.expect_portfolios_listed(inactive_portfolio) - portfolios_page.expect_portfolios_not_listed(portfolio_a, portfolio_b, portfolio_favorited) - - # For archived portfolios, no status bar, favorite button or project count is shown: - portfolios_page.within_row(inactive_portfolio) do - expect(page).to have_no_test_selector("op-portfolios--favorite-button") - expect(page).to have_no_test_selector("op-portfolios--sub-status-bar") - expect(page).to have_no_test_selector("op-portfolios--status") - expect(page).to have_no_text("0 projects") - expect(page).to have_no_text("0 programs") - end + it "only lists visible portfolios" do + portfolios_page.expect_portfolios_not_listed(inactive_portfolio, portfolio_b, portfolio_favorited) end + end - it "allows you to favorite and unfavorite portfolios" do - expect(portfolio_a).not_to be_favorited_by(current_user) - - portfolios_page.within_row(portfolio_a) do - page.find_test_selector("op-portfolios--favorite-button").click - end + it "offers queries in the menu items" do + menu_items = portfolios_page.sidebar_menu_items - expect(portfolio_a).to be_favorited_by(current_user) - end + expected_menu_items = [ + "Active portfolios", + "My portfolios", + "Favorite portfolios", + "Archived portfolios" + ] - it "lets you link to the desired query via param" do - visit "#{portfolios_page.path}?query_id=favorited_portfolios" + expect(menu_items).to eq(expected_menu_items) + end - portfolios_page.expect_title("Favorite portfolios") + it "lets you select a query by clicking on its menu item" do + click_on "Favorite portfolios" + portfolios_page.expect_title("Favorite portfolios") + portfolios_page.expect_portfolios_listed(portfolio_favorited) + portfolios_page.expect_portfolios_not_listed(portfolio_a, portfolio_b, inactive_portfolio) + + click_on "My portfolios" + portfolios_page.expect_title("My portfolios") + portfolios_page.expect_portfolios_listed(portfolio_a) + portfolios_page.expect_portfolios_not_listed(portfolio_favorited, portfolio_b, inactive_portfolio) + + click_on "Archived portfolios" + portfolios_page.expect_title("Archived portfolios") + portfolios_page.expect_portfolios_listed(inactive_portfolio) + portfolios_page.expect_portfolios_not_listed(portfolio_a, portfolio_b, portfolio_favorited) + + # For archived portfolios, no status bar, favorite button or project count is shown: + portfolios_page.within_row(inactive_portfolio) do + expect(page).to have_no_test_selector("op-portfolios--favorite-button") + expect(page).to have_no_test_selector("op-portfolios--sub-status-bar") + expect(page).to have_no_test_selector("op-portfolios--status") + expect(page).to have_no_text("0 projects") + expect(page).to have_no_text("0 programs") end + end - it "lets you apply filters" do - portfolios_page.filter_by_name_and_identifier("Favorited") - portfolios_page.expect_portfolios_listed(portfolio_favorited) - portfolios_page.expect_portfolios_not_listed(portfolio_a, portfolio_b, inactive_portfolio) - page.find_by_id("portfolio-filters-form-clear-button").click + it "allows you to favorite and unfavorite portfolios" do + expect(portfolio_a).not_to be_favorited_by(current_user) - portfolios_page.toggle_filters_section - portfolios_page.filter_by_active("no") - portfolios_page.expect_portfolios_listed(inactive_portfolio) - portfolios_page.expect_portfolios_not_listed(portfolio_a, portfolio_b, portfolio_favorited) + portfolios_page.within_row(portfolio_a) do + page.find_test_selector("op-portfolios--favorite-button").click end - it "allows seeing and changing the portfolio status" do - portfolios_page.expect_status_of(portfolio_a, "Not set") - portfolios_page.expect_status_of(portfolio_favorited, "Not set") + expect(portfolio_a).to be_favorited_by(current_user) + end - portfolios_page.select_status_from_dropdown(portfolio_favorited, "At risk") + it "lets you link to the desired query via param" do + visit "#{portfolios_page.path}?query_id=favorited_portfolios" - portfolios_page.expect_status_of(portfolio_favorited, "At risk") - portfolios_page.expect_status_of(portfolio_a, "Not set") - end + portfolios_page.expect_title("Favorite portfolios") + end - describe "status of sub-items" do - it "shows the status summary of sub-items" do - portfolios_page.within_row(portfolio_a) do - expect(page).to have_test_selector("op-portfolios--sub-status-bar") + it "lets you apply filters" do + portfolios_page.filter_by_name_and_identifier("Favorited") + portfolios_page.expect_portfolios_listed(portfolio_favorited) + portfolios_page.expect_portfolios_not_listed(portfolio_a, portfolio_b, inactive_portfolio) + page.find_by_id("portfolio-filters-form-clear-button").click - portfolios_page.expect_status_bar_percentage(portfolio_a, "on_track", "66.7", find_row: false) - portfolios_page.expect_status_bar_percentage(portfolio_a, "at_risk", "33.3", find_row: false) + portfolios_page.toggle_filters_section + portfolios_page.filter_by_active("no") + portfolios_page.expect_portfolios_listed(inactive_portfolio) + portfolios_page.expect_portfolios_not_listed(portfolio_a, portfolio_b, portfolio_favorited) + end - # The status bar shows a hover card on hover: - page.find_test_selector("op-portfolios--sub-status-bar").hover - end - portfolios_page.expect_hover_card(portfolio_a, text: /3\ssub-items\s2\sOn track\s1\sAt risk/) - end + it "allows seeing and changing the portfolio status" do + portfolios_page.expect_status_of(portfolio_a, "Not set") + portfolios_page.expect_status_of(portfolio_favorited, "Not set") - it "does show an empty status bar if no sub-item has a status" do - # Statusless sub-item: - create(:project, parent: portfolio_favorited) - portfolios_page.visit! + portfolios_page.select_status_from_dropdown(portfolio_favorited, "At risk") - portfolios_page.within_row(portfolio_favorited) do - expect(page).to have_text("1 project") - expect(page).to have_test_selector("op-portfolios--sub-status-bar") + portfolios_page.expect_status_of(portfolio_favorited, "At risk") + portfolios_page.expect_status_of(portfolio_a, "Not set") + end - portfolios_page.expect_status_bar_percentage(portfolio_favorited, "not_set", "100.0", find_row: false) + describe "status of sub-items" do + it "shows the status summary of sub-items" do + portfolios_page.within_row(portfolio_a) do + expect(page).to have_test_selector("op-portfolios--sub-status-bar") - page.find_test_selector("op-portfolios--sub-status-bar").hover - end + portfolios_page.expect_status_bar_percentage(portfolio_a, "on_track", "66.7", find_row: false) + portfolios_page.expect_status_bar_percentage(portfolio_a, "at_risk", "33.3", find_row: false) - portfolios_page.expect_hover_card(portfolio_favorited, text: /1\ssub-item\s1\sNot set/) + # The status bar shows a hover card on hover: + page.find_test_selector("op-portfolios--sub-status-bar").hover end + portfolios_page.expect_hover_card(portfolio_a, text: /3\ssub-items\s2\sOn track\s1\sAt risk/) end - context "when using the more menu" do - it "offers the zen mode" do - portfolios_page.expect_more_menu_item("Zen mode") - end - end + it "does show an empty status bar if no sub-item has a status" do + # Statusless sub-item: + create(:project, parent: portfolio_favorited) + portfolios_page.visit! + + portfolios_page.within_row(portfolio_favorited) do + expect(page).to have_text("1 project") + expect(page).to have_test_selector("op-portfolios--sub-status-bar") - context "without the necessary permissions to see portfolios" do - current_user { create(:user) } + portfolios_page.expect_status_bar_percentage(portfolio_favorited, "not_set", "100.0", find_row: false) - it "cannot see portfolios" do - expect(page).to have_content "[Error 403] You are not authorized to access this page." + page.find_test_selector("op-portfolios--sub-status-bar").hover end + + portfolios_page.expect_hover_card(portfolio_favorited, text: /1\ssub-item\s1\sNot set/) end end - context "without the feature flag being active", with_flag: { portfolio_models: false } do + context "when using the more menu" do + it "offers the zen mode" do + portfolios_page.expect_more_menu_item("Zen mode") + end + end + + context "without the necessary permissions to see portfolios" do + current_user { create(:user) } + it "cannot see portfolios" do expect(page).to have_content "[Error 403] You are not authorized to access this page." end diff --git a/spec/features/programs/create_spec.rb b/spec/features/programs/create_spec.rb index 35f10ce602c7..a9721dcf2114 100644 --- a/spec/features/programs/create_spec.rb +++ b/spec/features/programs/create_spec.rb @@ -58,7 +58,7 @@ current_user { user_with_permissions } context "with enterprise feature enabled", with_ee: :portfolio_management do - it "can create a program", with_flag: { portfolio_models: true } do + it "can create a program" do projects_page.visit! projects_page.create_new_workspace @@ -87,7 +87,7 @@ expect(program.parent).to eq root_portfolio end - context "without the necessary permissions to create programs", with_flag: { portfolio_models: true } do + context "without the necessary permissions to create programs" do current_user { create(:user) } it "cannot create the program" do @@ -96,18 +96,10 @@ expect(page).to have_content "[Error 403] You are not authorized to access this page." end end - - context "without the feature flag being active", with_flag: { portfolio_models: false } do - it "cannot create the program" do - visit new_program_path - - expect(page).to have_content "[Error 403] You are not authorized to access this page." - end - end end context "without enterprise feature enabled", with_ee: [] do - it "shows enterprise banner instead of the form", with_flag: { portfolio_models: true } do + it "shows enterprise banner instead of the form" do projects_page.visit! projects_page.create_new_workspace diff --git a/spec/features/projects/create_spec.rb b/spec/features/projects/create_spec.rb index ec94eba93373..270855e22e8d 100644 --- a/spec/features/projects/create_spec.rb +++ b/spec/features/projects/create_spec.rb @@ -602,7 +602,7 @@ end end - context "with workspace type badges in parent field", with_flag: { portfolio_models: true } do + context "with workspace type badges in parent field" do include_context "ng-select-autocomplete helpers" shared_let(:portfolio) { create(:portfolio, name: "Parent Portfolio") } diff --git a/spec/features/projects/edit_settings_spec.rb b/spec/features/projects/edit_settings_spec.rb index 73c65a1fd069..c5bf33d26e74 100644 --- a/spec/features/projects/edit_settings_spec.rb +++ b/spec/features/projects/edit_settings_spec.rb @@ -334,7 +334,7 @@ end end - describe "workspace type badges in Subproject of field", with_flag: { portfolio_models: true } do + describe "workspace type badges in Subproject of field" do shared_let(:portfolio) { create(:portfolio, name: "Parent Portfolio") } shared_let(:program) { create(:program, name: "Parent Program") } shared_let(:regular_project) { create(:project, name: "Regular Project") } diff --git a/spec/features/projects/lists/table_spec.rb b/spec/features/projects/lists/table_spec.rb index 2c8a32c8edba..a1f934292053 100644 --- a/spec/features/projects/lists/table_spec.rb +++ b/spec/features/projects/lists/table_spec.rb @@ -663,7 +663,7 @@ def load_and_open_filters(user) end end - describe "workspace type badges", with_flag: { portfolio_models: true } do + describe "workspace type badges" do shared_let(:portfolio_project) { create(:portfolio, name: "Test Portfolio") } shared_let(:program_project) { create(:program, name: "Test Program") } shared_let(:regular_project) { project } diff --git a/spec/features/projects/navigation_spec.rb b/spec/features/projects/navigation_spec.rb index 42b78260ae44..8300c55c1cc0 100644 --- a/spec/features/projects/navigation_spec.rb +++ b/spec/features/projects/navigation_spec.rb @@ -87,7 +87,7 @@ end end - context "with workspace type badges in project dropdown", with_flag: { portfolio_models: true } do + context "with workspace type badges in project dropdown" do shared_let(:portfolio_project) { create(:portfolio, name: "Test Portfolio") } shared_let(:program_project) { create(:program, name: "Test Program") } shared_let(:regular_project) { project } diff --git a/spec/features/projects/project_autocomplete_spec.rb b/spec/features/projects/project_autocomplete_spec.rb index 7af5b299cff0..536732c5b6b3 100644 --- a/spec/features/projects/project_autocomplete_spec.rb +++ b/spec/features/projects/project_autocomplete_spec.rb @@ -186,8 +186,7 @@ top_menu.expect_current_project project2.name end - it "displays workspace type badges for portfolios and programs", - with_flag: { portfolio_models: true } do + it "displays workspace type badges for portfolios and programs" do retry_block do top_menu.toggle unless top_menu.open? top_menu.expect_open diff --git a/spec/features/work_packages/table/edit_work_packages_spec.rb b/spec/features/work_packages/table/edit_work_packages_spec.rb index dd8299c67be4..b367be612235 100644 --- a/spec/features/work_packages/table/edit_work_packages_spec.rb +++ b/spec/features/work_packages/table/edit_work_packages_spec.rb @@ -204,8 +204,7 @@ end end - context "when editing the project field with workspace types", - with_flag: { portfolio_models: true } do + context "when editing the project field with workspace types" do let!(:portfolio) { create(:portfolio, name: "Test Portfolio") } let!(:program) { create(:program, name: "Test Program") } let(:manager_permissions) { %i[view_work_packages edit_work_packages move_work_packages] } diff --git a/spec/requests/api/v3/portfolios/delete_resource_spec.rb b/spec/requests/api/v3/portfolios/delete_resource_spec.rb index e84188027353..cae51cddc56e 100644 --- a/spec/requests/api/v3/portfolios/delete_resource_spec.rb +++ b/spec/requests/api/v3/portfolios/delete_resource_spec.rb @@ -33,7 +33,7 @@ require_relative "../workspaces/delete_resource_examples" RSpec.describe "API v3 Portfolio resource delete", content_type: :json do - describe "DELETE /api/v3/portfolios/:id", with_flag: { portfolio_models: true } do + describe "DELETE /api/v3/portfolios/:id" do include_examples "APIv3 deleting a workspace" do let(:workspace) { create(:portfolio) } let(:path_id) { workspace.id } @@ -46,10 +46,6 @@ it_behaves_like "not found" end - - context "without the feature flag enabled", with_flag: { portfolio_models: false } do - it_behaves_like "not found" - end end end end diff --git a/spec/requests/api/v3/portfolios/index_resource_spec.rb b/spec/requests/api/v3/portfolios/index_resource_spec.rb index f40e15ab19a0..85a622fa7fbc 100644 --- a/spec/requests/api/v3/portfolios/index_resource_spec.rb +++ b/spec/requests/api/v3/portfolios/index_resource_spec.rb @@ -78,74 +78,68 @@ get get_path end - context "with the feature flag enabled", with_flag: { portfolio_models: true } do - it_behaves_like "API V3 collection response", 2, 2, "Portfolio" do - let(:elements) { [public_portfolio, portfolio] } - end + it_behaves_like "API V3 collection response", 2, 2, "Portfolio" do + let(:elements) { [public_portfolio, portfolio] } + end - context "with a pageSize and offset" do - let(:get_path) do - api_v3_paths.path_for :portfolios, sort_by: { id: :asc }, page_size: 1, offset: 1 - end + context "with a pageSize and offset" do + let(:get_path) do + api_v3_paths.path_for :portfolios, sort_by: { id: :asc }, page_size: 1, offset: 1 + end - it_behaves_like "API V3 collection response", 2, 1, "Portfolio" do - let(:elements) { [portfolio] } - end + it_behaves_like "API V3 collection response", 2, 1, "Portfolio" do + let(:elements) { [portfolio] } end + end - context "when signaling the properties to include" do - let(:select) { "elements/id,elements/name,elements/_type,total" } - let(:get_path) do - api_v3_paths.path_for :portfolios, select: - end - let(:expected) do - { - total: 2, - _embedded: { - elements: [ - { - id: public_portfolio.id, - name: public_portfolio.name, - _type: "Portfolio" - }, - { - id: portfolio.id, - name: portfolio.name, - _type: "Portfolio" - } - ] - } + context "when signaling the properties to include" do + let(:select) { "elements/id,elements/name,elements/_type,total" } + let(:get_path) do + api_v3_paths.path_for :portfolios, select: + end + let(:expected) do + { + total: 2, + _embedded: { + elements: [ + { + id: public_portfolio.id, + name: public_portfolio.name, + _type: "Portfolio" + }, + { + id: portfolio.id, + name: portfolio.name, + _type: "Portfolio" + } + ] } - end - - it "is the reduced set of properties of the embedded elements" do - expect(last_response.body) - .to be_json_eql(expected.to_json) - end + } end - context "when filtering by typeahead" do - let(:filters) do - [{ typeahead: { operator: "**", values: [search_string] } }] - end - - let(:search_string) { public_portfolio.name } + it "is the reduced set of properties of the embedded elements" do + expect(last_response.body) + .to be_json_eql(expected.to_json) + end + end - it_behaves_like "API V3 collection response", 1, 1, "Portfolio" do - let(:elements) { [public_portfolio] } - end + context "when filtering by typeahead" do + let(:filters) do + [{ typeahead: { operator: "**", values: [search_string] } }] end - context "when not being logged in and login is required" do - current_user { create(:anonymous) } + let(:search_string) { public_portfolio.name } - context "if user is not logged in" do - it_behaves_like "unauthenticated access" - end + it_behaves_like "API V3 collection response", 1, 1, "Portfolio" do + let(:elements) { [public_portfolio] } end end - context "without the feature flag enabled", with_flag: { portfolio_models: false } do - it_behaves_like "not found" + context "when not being logged in and login is required" do + current_user { create(:anonymous) } + + context "if user is not logged in" do + it_behaves_like "unauthenticated access" + end end end diff --git a/spec/requests/api/v3/portfolios/show_resource_spec.rb b/spec/requests/api/v3/portfolios/show_resource_spec.rb index d7836ff61b27..2e3d562f0b61 100644 --- a/spec/requests/api/v3/portfolios/show_resource_spec.rb +++ b/spec/requests/api/v3/portfolios/show_resource_spec.rb @@ -56,81 +56,71 @@ last_response end - context "with the feature flag enabled", with_flag: { portfolio_models: true } do - context "for a logged in user" do - it "responds with 200 OK" do - expect(subject.status).to eq(200) - end - - it "responds with the correct project" do - expect(subject.body).to include_json("Portfolio".to_json).at_path("_type") - expect(subject.body).to be_json_eql(portfolio.identifier.to_json).at_path("identifier") - end + context "for a logged in user" do + it "responds with 200 OK" do + expect(subject.status).to eq(200) + end - context "when requesting nonexistent portfolio" do - let(:get_path) { api_v3_paths.portfolio 9999 } + it "responds with the correct project" do + expect(subject.body).to include_json("Portfolio".to_json).at_path("_type") + expect(subject.body).to be_json_eql(portfolio.identifier.to_json).at_path("identifier") + end - before do - response - end + context "when requesting nonexistent portfolio" do + let(:get_path) { api_v3_paths.portfolio 9999 } - it_behaves_like "not found" + before do + response end - context "when requesting a project" do - let(:portfolio) { create(:project, public: true) } + it_behaves_like "not found" + end - before do - response - end + context "when requesting a project" do + let(:portfolio) { create(:project, public: true) } - it_behaves_like "not found" + before do + response end - context "with the project being archived/inactive" do - before do - portfolio.update_attribute(:active, false) - end + it_behaves_like "not found" + end - context "with the user being admin" do - current_user { admin } + context "with the project being archived/inactive" do + before do + portfolio.update_attribute(:active, false) + end - it "responds with 200 OK" do - expect(subject.status).to eq(200) - end + context "with the user being admin" do + current_user { admin } - it "responds with the correct project" do - expect(subject.body).to include_json("Portfolio".to_json).at_path("_type") - expect(subject.body).to be_json_eql(portfolio.identifier.to_json).at_path("identifier") - end + it "responds with 200 OK" do + expect(subject.status).to eq(200) end - context "with the user being no admin" do - before do - response - end - - it_behaves_like "not found" + it "responds with the correct project" do + expect(subject.body).to include_json("Portfolio".to_json).at_path("_type") + expect(subject.body).to be_json_eql(portfolio.identifier.to_json).at_path("identifier") end end - end - context "for a not logged in user" do - current_user { create(:anonymous) } + context "with the user being no admin" do + before do + response + end - before do - get get_path + it_behaves_like "not found" end - - it_behaves_like "not found response based on login_required" end end - context "without the feature flag enabled", with_flag: { portfolio_models: false } do + context "for a not logged in user" do + current_user { create(:anonymous) } + before do - response + get get_path end - it_behaves_like "not found" + it_behaves_like "not found response based on login_required" end end diff --git a/spec/requests/api/v3/portfolios/update_form_resource_spec.rb b/spec/requests/api/v3/portfolios/update_form_resource_spec.rb index dca7fc7d4d05..6c5a4183bde2 100644 --- a/spec/requests/api/v3/portfolios/update_form_resource_spec.rb +++ b/spec/requests/api/v3/portfolios/update_form_resource_spec.rb @@ -33,7 +33,7 @@ require_relative "../workspaces/update_form_resource_examples" RSpec.describe "API v3 Portfolio resource update form", content_type: :json do - describe "POST /api/v3/portfolios/:id/form", with_flag: { portfolio_models: true } do + describe "POST /api/v3/portfolios/:id/form" do include_examples "APIv3 workspace update form" do shared_let(:workspace, reload: true) { create(:portfolio) } @@ -45,10 +45,6 @@ it_behaves_like "not found" end - - context "without the feature flag enabled", with_flag: { portfolio_models: false } do - it_behaves_like "not found" - end end end end diff --git a/spec/requests/api/v3/portfolios/update_resource_spec.rb b/spec/requests/api/v3/portfolios/update_resource_spec.rb index 203f3121c611..9f2d0c8791bb 100644 --- a/spec/requests/api/v3/portfolios/update_resource_spec.rb +++ b/spec/requests/api/v3/portfolios/update_resource_spec.rb @@ -33,7 +33,7 @@ require_relative "../workspaces/update_resource_examples" RSpec.describe "API v3 Portfolio resource update", content_type: :json do - describe "PATCH /api/v3/programs/:id", with_flag: { portfolio_models: true } do + describe "PATCH /api/v3/programs/:id" do include_examples "APIv3 workspace update" do let(:path) { api_v3_paths.portfolio(workspace.id) } let(:workspace_factory_key) { :portfolio } @@ -46,10 +46,6 @@ it_behaves_like "not found" end - - context "without the feature flag enabled", with_flag: { portfolio_models: false } do - it_behaves_like "not found" - end end end end diff --git a/spec/requests/api/v3/programs/delete_resource_spec.rb b/spec/requests/api/v3/programs/delete_resource_spec.rb index c2e8ec3addda..bb1cdcc1714e 100644 --- a/spec/requests/api/v3/programs/delete_resource_spec.rb +++ b/spec/requests/api/v3/programs/delete_resource_spec.rb @@ -33,7 +33,7 @@ require_relative "../workspaces/delete_resource_examples" RSpec.describe "API v3 Program resource delete", content_type: :json do - describe "DELETE /api/v3/programs/:id", with_flag: { portfolio_models: true } do + describe "DELETE /api/v3/programs/:id" do include_examples "APIv3 deleting a workspace" do let(:workspace) { create(:program) } let(:path_id) { workspace.id } @@ -46,10 +46,6 @@ it_behaves_like "not found" end - - context "without the feature flag enabled", with_flag: { portfolio_models: false } do - it_behaves_like "not found" - end end end end diff --git a/spec/requests/api/v3/programs/index_resource_spec.rb b/spec/requests/api/v3/programs/index_resource_spec.rb index 292923c8cb94..055ee18461f2 100644 --- a/spec/requests/api/v3/programs/index_resource_spec.rb +++ b/spec/requests/api/v3/programs/index_resource_spec.rb @@ -78,74 +78,68 @@ get get_path end - context "with the feature flag enabled", with_flag: { portfolio_models: true } do - it_behaves_like "API V3 collection response", 2, 2, "Program" do - let(:elements) { [public_program, program] } - end + it_behaves_like "API V3 collection response", 2, 2, "Program" do + let(:elements) { [public_program, program] } + end - context "with a pageSize and offset" do - let(:get_path) do - api_v3_paths.path_for :programs, sort_by: { id: :asc }, page_size: 1, offset: 1 - end + context "with a pageSize and offset" do + let(:get_path) do + api_v3_paths.path_for :programs, sort_by: { id: :asc }, page_size: 1, offset: 1 + end - it_behaves_like "API V3 collection response", 2, 1, "Program" do - let(:elements) { [program] } - end + it_behaves_like "API V3 collection response", 2, 1, "Program" do + let(:elements) { [program] } end + end - context "when signaling the properties to include" do - let(:select) { "elements/id,elements/name,elements/_type,total" } - let(:get_path) do - api_v3_paths.path_for :programs, select: - end - let(:expected) do - { - total: 2, - _embedded: { - elements: [ - { - id: public_program.id, - name: public_program.name, - _type: "Program" - }, - { - id: program.id, - name: program.name, - _type: "Program" - } - ] - } + context "when signaling the properties to include" do + let(:select) { "elements/id,elements/name,elements/_type,total" } + let(:get_path) do + api_v3_paths.path_for :programs, select: + end + let(:expected) do + { + total: 2, + _embedded: { + elements: [ + { + id: public_program.id, + name: public_program.name, + _type: "Program" + }, + { + id: program.id, + name: program.name, + _type: "Program" + } + ] } - end - - it "is the reduced set of properties of the embedded elements" do - expect(last_response.body) - .to be_json_eql(expected.to_json) - end + } end - context "when filtering by typeahead" do - let(:filters) do - [{ typeahead: { operator: "**", values: [search_string] } }] - end - - let(:search_string) { public_program.name } + it "is the reduced set of properties of the embedded elements" do + expect(last_response.body) + .to be_json_eql(expected.to_json) + end + end - it_behaves_like "API V3 collection response", 1, 1, "Program" do - let(:elements) { [public_program] } - end + context "when filtering by typeahead" do + let(:filters) do + [{ typeahead: { operator: "**", values: [search_string] } }] end - context "when not being logged in and login is required" do - current_user { create(:anonymous) } + let(:search_string) { public_program.name } - context "if user is not logged in" do - it_behaves_like "unauthenticated access" - end + it_behaves_like "API V3 collection response", 1, 1, "Program" do + let(:elements) { [public_program] } end end - context "without the feature flag enabled", with_flag: { portfolio_models: false } do - it_behaves_like "not found" + context "when not being logged in and login is required" do + current_user { create(:anonymous) } + + context "if user is not logged in" do + it_behaves_like "unauthenticated access" + end end end diff --git a/spec/requests/api/v3/programs/show_resource_spec.rb b/spec/requests/api/v3/programs/show_resource_spec.rb index b5ffeaf980f4..b16c7180d8c9 100644 --- a/spec/requests/api/v3/programs/show_resource_spec.rb +++ b/spec/requests/api/v3/programs/show_resource_spec.rb @@ -56,81 +56,71 @@ last_response end - context "with the feature flag enabled", with_flag: { portfolio_models: true } do - context "for a logged in user" do - it "responds with 200 OK" do - expect(subject.status).to eq(200) - end - - it "responds with the correct project" do - expect(subject.body).to include_json("Program".to_json).at_path("_type") - expect(subject.body).to be_json_eql(program.identifier.to_json).at_path("identifier") - end + context "for a logged in user" do + it "responds with 200 OK" do + expect(subject.status).to eq(200) + end - context "when requesting nonexistent program" do - let(:get_path) { api_v3_paths.program 9999 } + it "responds with the correct project" do + expect(subject.body).to include_json("Program".to_json).at_path("_type") + expect(subject.body).to be_json_eql(program.identifier.to_json).at_path("identifier") + end - before do - response - end + context "when requesting nonexistent program" do + let(:get_path) { api_v3_paths.program 9999 } - it_behaves_like "not found" + before do + response end - context "when requesting a project" do - let(:program) { create(:project, public: true) } + it_behaves_like "not found" + end - before do - response - end + context "when requesting a project" do + let(:program) { create(:project, public: true) } - it_behaves_like "not found" + before do + response end - context "with the project being archived/inactive" do - before do - program.update_attribute(:active, false) - end + it_behaves_like "not found" + end - context "with the user being admin" do - current_user { admin } + context "with the project being archived/inactive" do + before do + program.update_attribute(:active, false) + end - it "responds with 200 OK" do - expect(subject.status).to eq(200) - end + context "with the user being admin" do + current_user { admin } - it "responds with the correct project" do - expect(subject.body).to include_json("Program".to_json).at_path("_type") - expect(subject.body).to be_json_eql(program.identifier.to_json).at_path("identifier") - end + it "responds with 200 OK" do + expect(subject.status).to eq(200) end - context "with the user being no admin" do - before do - response - end - - it_behaves_like "not found" + it "responds with the correct project" do + expect(subject.body).to include_json("Program".to_json).at_path("_type") + expect(subject.body).to be_json_eql(program.identifier.to_json).at_path("identifier") end end - end - context "for a not logged in user" do - current_user { create(:anonymous) } + context "with the user being no admin" do + before do + response + end - before do - get get_path + it_behaves_like "not found" end - - it_behaves_like "not found response based on login_required" end end - context "without the feature flag enabled", with_flag: { portfolio_models: false } do + context "for a not logged in user" do + current_user { create(:anonymous) } + before do - response + get get_path end - it_behaves_like "not found" + it_behaves_like "not found response based on login_required" end end diff --git a/spec/requests/api/v3/programs/update_form_resource_spec.rb b/spec/requests/api/v3/programs/update_form_resource_spec.rb index dcf68c0463af..a2ad6fbb142b 100644 --- a/spec/requests/api/v3/programs/update_form_resource_spec.rb +++ b/spec/requests/api/v3/programs/update_form_resource_spec.rb @@ -33,7 +33,7 @@ require_relative "../workspaces/update_form_resource_examples" RSpec.describe "API v3 Program resource update form", content_type: :json do - describe "POST /api/v3/programs/:id/form", with_flag: { portfolio_models: true } do + describe "POST /api/v3/programs/:id/form" do include_examples "APIv3 workspace update form" do shared_let(:workspace, reload: true) { create(:program) } @@ -45,10 +45,6 @@ it_behaves_like "not found" end - - context "without the feature flag enabled", with_flag: { portfolio_models: false } do - it_behaves_like "not found" - end end end end diff --git a/spec/requests/api/v3/programs/update_resource_spec.rb b/spec/requests/api/v3/programs/update_resource_spec.rb index 762509675aba..effd95347849 100644 --- a/spec/requests/api/v3/programs/update_resource_spec.rb +++ b/spec/requests/api/v3/programs/update_resource_spec.rb @@ -33,7 +33,7 @@ require_relative "../workspaces/update_resource_examples" RSpec.describe "API v3 Program resource update", content_type: :json do - describe "PATCH /api/v3/programs/:id", with_flag: { portfolio_models: true } do + describe "PATCH /api/v3/programs/:id" do include_examples "APIv3 workspace update" do let(:path) { api_v3_paths.program(workspace.id) } let(:workspace_factory_key) { :program } @@ -46,10 +46,6 @@ it_behaves_like "not found" end - - context "without the feature flag enabled", with_flag: { portfolio_models: false } do - it_behaves_like "not found" - end end end end