[#43123] Remove files storages feature flag

https://community.openproject.org/work_packages/43123
pull/11017/head
Andreas Pfohl 2 years ago
parent 6b6326134f
commit 5d2a9a5872
No known key found for this signature in database
GPG Key ID: FF58F3B771328EB4
  1. 10
      config/configuration.yml.example
  2. 10
      config/constants/settings/definitions.rb
  3. 8
      lib/open_project/feature_decisions.rb
  4. 6
      modules/storages/app/controllers/storages/admin/oauth_clients_controller.rb
  5. 10
      modules/storages/app/controllers/storages/admin/projects_storages_controller.rb
  6. 10
      modules/storages/app/controllers/storages/admin/storages_controller.rb
  7. 41
      modules/storages/app/models/queries/storages/work_packages/filter/concerns/validate_storages_module_available.rb
  8. 1
      modules/storages/app/models/queries/storages/work_packages/filter/file_link_origin_id_filter.rb
  9. 1
      modules/storages/app/models/queries/storages/work_packages/filter/linkable_to_storage_id_filter.rb
  10. 1
      modules/storages/app/models/queries/storages/work_packages/filter/linkable_to_storage_url_filter.rb
  11. 1
      modules/storages/app/models/queries/storages/work_packages/filter/storage_id_filter.rb
  12. 1
      modules/storages/app/models/queries/storages/work_packages/filter/storage_url_filter.rb
  13. 4
      modules/storages/lib/api/v3/file_links/file_links_api.rb
  14. 4
      modules/storages/lib/api/v3/file_links/work_packages_file_links_api.rb
  15. 4
      modules/storages/lib/api/v3/storages/storages_api.rb
  16. 4
      modules/storages/lib/api/v3/utilities/storages_helpers.rb
  17. 6
      modules/storages/lib/open_project/storages/engine.rb
  18. 2
      modules/storages/spec/contracts/storages/file_links/create_contract_spec.rb
  19. 2
      modules/storages/spec/contracts/storages/file_links/delete_contract_spec.rb
  20. 2
      modules/storages/spec/contracts/storages/project_storages/create_contract_spec.rb
  21. 2
      modules/storages/spec/contracts/storages/project_storages/delete_contract_spec.rb
  22. 2
      modules/storages/spec/contracts/storages/storages/base_contract_spec.rb
  23. 2
      modules/storages/spec/contracts/storages/storages/create_contract_spec.rb
  24. 2
      modules/storages/spec/contracts/storages/storages/delete_contract_spec.rb
  25. 2
      modules/storages/spec/contracts/storages/storages/update_contract_spec.rb
  26. 2
      modules/storages/spec/controller/storages_controller_spec.rb
  27. 2
      modules/storages/spec/features/admin_storages_spec.rb
  28. 2
      modules/storages/spec/features/create_and_delete_project_storage_spec.rb
  29. 2
      modules/storages/spec/features/delete_project_storage_and_file_links_spec.rb
  30. 48
      modules/storages/spec/features/ensure_storages_module_spec.rb
  31. 2
      modules/storages/spec/features/show_file_links_spec.rb
  32. 5
      modules/storages/spec/permissions/manage_storage_in_project_spec.rb
  33. 22
      modules/storages/spec/requests/api/v3/file_links/file_links_spec.rb
  34. 2
      modules/storages/spec/requests/api/v3/file_links/mixed_case_file_links_integration_spec.rb
  35. 6
      modules/storages/spec/requests/api/v3/storages/storages_spec.rb
  36. 38
      modules/storages/spec/requests/api/v3/work_packages/shared_filter_examples.rb
  37. 6
      modules/storages/spec/requests/api/v3/work_packages/work_packages_linkable_filter_spec.rb
  38. 8
      modules/storages/spec/requests/api/v3/work_packages/work_packages_linked_filter_spec.rb
  39. 2
      modules/storages/spec/services/storages/project_storages/delete_service_spec.rb
  40. 8
      spec/features/menu_items/admin_menu_item_spec.rb
  41. 2
      spec/requests/oauth_clients/callback_flow_spec.rb
  42. 6
      spec/support/shared/with_settings.rb

@ -162,14 +162,14 @@
# - 'types' # - 'types'
# - 'admin/roles' # - 'admin/roles'
# #
# Enable file storages module: # Beta features
# #
# The file storages module is currently under development and can # Some features are hidden behind a feature flag during development.
# be enabled for beta usage by setting a feature flag: # To activate one or more features set the correspondig flag inside the section.
# #
# Example:
# production: # production:
# feature_storages_module_active: true # feature_your_module_active: true
#
# default configuration options for all environments # default configuration options for all environments
default: default:

@ -401,9 +401,13 @@ Settings::Definition.define do
default: 'enterprise-on-premises---euro---1-year', default: 'enterprise-on-premises---euro---1-year',
writable: false writable: false
add :feature_storages_module_active, # feature flags
default: Rails.env.development?, # To add a feature flag register a new definition for a configuration variable
format: :boolean #
# Example:
# add :feature_your_module_active,
# default: Rails.env.development?,
# format: :boolean
add :feeds_enabled, add :feeds_enabled,
default: true default: true

@ -35,15 +35,11 @@ module OpenProject
# #
# For example: # For example:
# #
# def self.storages_module_active? # def self.your_module_active?
# release_date = Date.new(2022,01,01) # release_date = Date.new(2022,01,01)
# Setting.feature_storages_module_active || Date.today > release_date # Setting.feature_your_module_active || Date.today > release_date
# end # end
def self.storages_module_active?
Setting.feature_storages_module_active
end
def self.work_packages_duration_field_active? def self.work_packages_duration_field_active?
Setting.work_packages_duration_field_active Setting.work_packages_duration_field_active
end end

@ -85,12 +85,6 @@ class Storages::Admin::OAuthClientsController < ApplicationController
private private
def ensure_storages_module_active
return if OpenProject::FeatureDecisions.storages_module_active?
raise ActionController::RoutingError, 'Not Found'
end
# Called by create and update above in order to check if the # Called by create and update above in order to check if the
# update parameters are correctly set. # update parameters are correctly set.
def permitted_oauth_client_params def permitted_oauth_client_params

@ -39,10 +39,6 @@ class Storages::Admin::ProjectsStoragesController < Projects::SettingsController
# This defines @object as the model instance. # This defines @object as the model instance.
model_object Storages::ProjectStorage model_object Storages::ProjectStorage
# Will return a 404 if the storages module has not been made available through
# a feature flag.
before_action :ensure_storages_module_active
before_action :find_model_object, only: %i[destroy] # Fill @object with ProjectStorage before_action :find_model_object, only: %i[destroy] # Fill @object with ProjectStorage
# No need to before_action :find_project_by_project_id as SettingsController already checks # No need to before_action :find_project_by_project_id as SettingsController already checks
# No need to check for before_action :authorize, as the SettingsController already checks this. # No need to check for before_action :authorize, as the SettingsController already checks this.
@ -118,12 +114,6 @@ class Storages::Admin::ProjectsStoragesController < Projects::SettingsController
private private
def ensure_storages_module_active
return if OpenProject::FeatureDecisions.storages_module_active?
raise ActionController::RoutingError, 'Not Found'
end
# Define the list of permitted parameters for creating/updating a ProjectStorage. # Define the list of permitted parameters for creating/updating a ProjectStorage.
# Called by create and update actions above. # Called by create and update actions above.
def permitted_create_params def permitted_create_params

@ -34,10 +34,6 @@ class Storages::Admin::StoragesController < ApplicationController
# specify which model #find_model_object should look up # specify which model #find_model_object should look up
model_object Storages::Storage model_object Storages::Storage
# Will return a 404 if the storages module has not been made available through
# a feature flag.
before_action :ensure_storages_module_active
# Before executing any action below: Make sure the current user is an admin # Before executing any action below: Make sure the current user is an admin
# and set the @<controller_name> variable to the object referenced in the URL. # and set the @<controller_name> variable to the object referenced in the URL.
before_action :require_admin before_action :require_admin
@ -175,12 +171,6 @@ class Storages::Admin::StoragesController < ApplicationController
service_result.dependent_results&.first&.result service_result.dependent_results&.first&.result
end end
def ensure_storages_module_active
return if OpenProject::FeatureDecisions.storages_module_active?
raise ActionController::RoutingError, 'Not Found'
end
# Called by create and update above in order to check if the # Called by create and update above in order to check if the
# update parameters are correctly set. # update parameters are correctly set.
def permitted_storage_params def permitted_storage_params

@ -1,41 +0,0 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2022 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
module Queries::Storages::WorkPackages::Filter::Concerns::ValidateStoragesModuleAvailable
extend ActiveSupport::Concern
included do
validate :storages_module_available
def storages_module_available
return if OpenProject::FeatureDecisions.storages_module_active?
errors.add :base, I18n.t('activerecord.errors.messages.filter_does_not_exist')
end
end
end

@ -29,7 +29,6 @@
module Queries::Storages::WorkPackages::Filter module Queries::Storages::WorkPackages::Filter
class FileLinkOriginIdFilter < ::Queries::WorkPackages::Filter::WorkPackageFilter class FileLinkOriginIdFilter < ::Queries::WorkPackages::Filter::WorkPackageFilter
include StoragesFilterMixin include StoragesFilterMixin
include Concerns::ValidateStoragesModuleAvailable
def filter_model def filter_model
::Storages::FileLink ::Storages::FileLink

@ -29,7 +29,6 @@
module Queries::Storages::WorkPackages::Filter module Queries::Storages::WorkPackages::Filter
class LinkableToStorageIdFilter < ::Queries::WorkPackages::Filter::WorkPackageFilter class LinkableToStorageIdFilter < ::Queries::WorkPackages::Filter::WorkPackageFilter
include StoragesFilterMixin include StoragesFilterMixin
include Concerns::ValidateStoragesModuleAvailable
def filter_model def filter_model
::Storages::Storage ::Storages::Storage

@ -29,7 +29,6 @@
module Queries::Storages::WorkPackages::Filter module Queries::Storages::WorkPackages::Filter
class LinkableToStorageUrlFilter < ::Queries::WorkPackages::Filter::WorkPackageFilter class LinkableToStorageUrlFilter < ::Queries::WorkPackages::Filter::WorkPackageFilter
include StoragesFilterMixin include StoragesFilterMixin
include Concerns::ValidateStoragesModuleAvailable
def filter_model def filter_model
::Storages::Storage ::Storages::Storage

@ -29,7 +29,6 @@
module Queries::Storages::WorkPackages::Filter module Queries::Storages::WorkPackages::Filter
class StorageIdFilter < ::Queries::WorkPackages::Filter::WorkPackageFilter class StorageIdFilter < ::Queries::WorkPackages::Filter::WorkPackageFilter
include StoragesFilterMixin include StoragesFilterMixin
include Concerns::ValidateStoragesModuleAvailable
def filter_model def filter_model
::Storages::FileLink ::Storages::FileLink

@ -29,7 +29,6 @@
module Queries::Storages::WorkPackages::Filter module Queries::Storages::WorkPackages::Filter
class StorageUrlFilter < ::Queries::WorkPackages::Filter::WorkPackageFilter class StorageUrlFilter < ::Queries::WorkPackages::Filter::WorkPackageFilter
include StoragesFilterMixin include StoragesFilterMixin
include Concerns::ValidateStoragesModuleAvailable
def filter_model def filter_model
::Storages::Storage ::Storages::Storage

@ -37,10 +37,6 @@ module API
# module available from within the endpoint context. # module available from within the endpoint context.
helpers API::V3::Utilities::StoragesHelpers helpers API::V3::Utilities::StoragesHelpers
before do
reply_with_not_found_if_module_inactive
end
# The `:resources` keyword defines the API namespace -> /api/v3/file_links/... # The `:resources` keyword defines the API namespace -> /api/v3/file_links/...
resources :file_links do resources :file_links do
# `route_param` extends the route by a route parameter of the endpoint. # `route_param` extends the route by a route parameter of the endpoint.

@ -38,10 +38,6 @@ module API
# module available from within the endpoint context. # module available from within the endpoint context.
helpers API::V3::Utilities::StoragesHelpers helpers API::V3::Utilities::StoragesHelpers
before do
reply_with_not_found_if_module_inactive
end
# The `:resources` keyword defines the API namespace -> /api/v3/work_packages/:id/file_links/... # The `:resources` keyword defines the API namespace -> /api/v3/work_packages/:id/file_links/...
resources :file_links do resources :file_links do
# Get the list of FileLinks related to a work package, with updated information from Nextcloud. # Get the list of FileLinks related to a work package, with updated information from Nextcloud.

@ -39,10 +39,6 @@ module API
# module available from within the endpoint context. # module available from within the endpoint context.
helpers API::V3::Utilities::StoragesHelpers helpers API::V3::Utilities::StoragesHelpers
before do
reply_with_not_found_if_module_inactive
end
# The `:resources` keyword defines the API namespace -> /api/v3/storages/... # The `:resources` keyword defines the API namespace -> /api/v3/storages/...
resources :storages do resources :storages do
# `route_param` extends the route by a route parameter of the endpoint. # `route_param` extends the route by a route parameter of the endpoint.

@ -28,10 +28,6 @@
module API::V3::Utilities module API::V3::Utilities
module StoragesHelpers module StoragesHelpers
def reply_with_not_found_if_module_inactive
raise ::API::Errors::NotFound unless OpenProject::FeatureDecisions.storages_module_active?
end
def visible_storages_scope def visible_storages_scope
::Storages::Storage.visible(current_user) ::Storages::Storage.visible(current_user)
end end

@ -51,8 +51,7 @@ module OpenProject::Storages
# Defines permission constraints used in the module (controller, etc.) # Defines permission constraints used in the module (controller, etc.)
# Permissions documentation: https://www.openproject.org/docs/development/concepts/permissions/#definition-of-permissions # Permissions documentation: https://www.openproject.org/docs/development/concepts/permissions/#definition-of-permissions
project_module :storages, project_module :storages,
dependencies: :work_package_tracking, dependencies: :work_package_tracking do
if: ->(*) { OpenProject::FeatureDecisions.storages_module_active? } do
permission :view_file_links, permission :view_file_links,
{}, {},
dependencies: %i[view_work_packages], dependencies: %i[view_work_packages],
@ -72,14 +71,13 @@ module OpenProject::Storages
menu :admin_menu, menu :admin_menu,
:storages_admin_settings, :storages_admin_settings,
{ controller: '/storages/admin/storages', action: :index }, { controller: '/storages/admin/storages', action: :index },
if: Proc.new { User.current.admin? && OpenProject::FeatureDecisions.storages_module_active? }, if: Proc.new { User.current.admin? },
caption: :project_module_storages, caption: :project_module_storages,
icon: 'icon2 icon-hosting' icon: 'icon2 icon-hosting'
menu :project_menu, menu :project_menu,
:settings_projects_storages, :settings_projects_storages,
{ controller: '/storages/admin/projects_storages', action: 'index' }, { controller: '/storages/admin/projects_storages', action: 'index' },
if: Proc.new { OpenProject::FeatureDecisions.storages_module_active? },
caption: :project_module_storages, caption: :project_module_storages,
parent: :settings parent: :settings
end end

@ -31,7 +31,7 @@ require_module_spec_helper
require 'contracts/shared/model_contract_shared_context' require 'contracts/shared/model_contract_shared_context'
require_relative 'shared_contract_examples' require_relative 'shared_contract_examples'
describe Storages::FileLinks::CreateContract, with_flag: { storages_module_active: true } do describe Storages::FileLinks::CreateContract do
include_context 'ModelContract shared context' include_context 'ModelContract shared context'
it_behaves_like 'file_link contract' do it_behaves_like 'file_link contract' do

@ -30,7 +30,7 @@ require 'spec_helper'
require_module_spec_helper require_module_spec_helper
require 'contracts/shared/model_contract_shared_context' require 'contracts/shared/model_contract_shared_context'
describe ::Storages::FileLinks::DeleteContract, with_flag: { storages_module_active: true } do describe ::Storages::FileLinks::DeleteContract do
include_context 'ModelContract shared context' include_context 'ModelContract shared context'
let(:current_user) { create(:user) } let(:current_user) { create(:user) }

@ -31,7 +31,7 @@ require_module_spec_helper
require 'contracts/shared/model_contract_shared_context' require 'contracts/shared/model_contract_shared_context'
require_relative 'shared_contract_examples' require_relative 'shared_contract_examples'
describe Storages::ProjectStorages::CreateContract, with_flag: { storages_module_active: true } do describe Storages::ProjectStorages::CreateContract do
include_context 'ModelContract shared context' include_context 'ModelContract shared context'
it_behaves_like 'ProjectStorages contract' do it_behaves_like 'ProjectStorages contract' do

@ -30,7 +30,7 @@ require 'spec_helper'
require_module_spec_helper require_module_spec_helper
require 'contracts/shared/model_contract_shared_context' require 'contracts/shared/model_contract_shared_context'
describe ::Storages::ProjectStorages::DeleteContract, with_flag: { storages_module_active: true } do describe ::Storages::ProjectStorages::DeleteContract do
include_context 'ModelContract shared context' include_context 'ModelContract shared context'
let(:current_user) { create(:user) } let(:current_user) { create(:user) }

@ -28,7 +28,7 @@
require_relative '../../../spec_helper' require_relative '../../../spec_helper'
describe Storages::Storages::BaseContract, :storage_server_helpers, with_flag: { storages_module_active: true }, webmock: true do describe Storages::Storages::BaseContract, :storage_server_helpers, webmock: true do
let(:current_user) { create(:admin) } let(:current_user) { create(:admin) }
let(:storage_host) { 'https://host1.example.com' } let(:storage_host) { 'https://host1.example.com' }
let(:storage) { build(:storage, host: storage_host) } let(:storage) { build(:storage, host: storage_host) }

@ -31,7 +31,7 @@ require_module_spec_helper
require 'contracts/shared/model_contract_shared_context' require 'contracts/shared/model_contract_shared_context'
require_relative 'shared_contract_examples' require_relative 'shared_contract_examples'
describe Storages::Storages::CreateContract, with_flag: { storages_module_active: true } do describe Storages::Storages::CreateContract do
include_context 'ModelContract shared context' include_context 'ModelContract shared context'
it_behaves_like 'storage contract' do it_behaves_like 'storage contract' do

@ -30,7 +30,7 @@ require 'spec_helper'
require_module_spec_helper require_module_spec_helper
require 'contracts/shared/model_contract_shared_context' require 'contracts/shared/model_contract_shared_context'
describe ::Storages::Storages::DeleteContract, with_flag: { storages_module_active: true } do describe ::Storages::Storages::DeleteContract do
include_context 'ModelContract shared context' include_context 'ModelContract shared context'
let(:storage) { create(:storage) } let(:storage) { create(:storage) }

@ -31,7 +31,7 @@ require_module_spec_helper
require 'contracts/shared/model_contract_shared_context' require 'contracts/shared/model_contract_shared_context'
require_relative 'shared_contract_examples' require_relative 'shared_contract_examples'
describe ::Storages::Storages::UpdateContract, with_flag: { storages_module_active: true } do describe ::Storages::Storages::UpdateContract do
include_context 'ModelContract shared context' include_context 'ModelContract shared context'
it_behaves_like 'storage contract' do it_behaves_like 'storage contract' do

@ -30,7 +30,7 @@ require_relative '../spec_helper'
# These specs mainly check that error messages from a sub-service # These specs mainly check that error messages from a sub-service
# (about unsafe hosts with HTTP protocol) are passed to the main form. # (about unsafe hosts with HTTP protocol) are passed to the main form.
describe ::Storages::Admin::StoragesController, with_flag: { storages_module_active: true }, webmock: true, type: :controller do describe ::Storages::Admin::StoragesController, webmock: true, type: :controller do
render_views # rendering views is stubbed by default in controller specs render_views # rendering views is stubbed by default in controller specs
include StorageServerHelpers include StorageServerHelpers

@ -28,7 +28,7 @@
require_relative '../spec_helper' require_relative '../spec_helper'
describe 'Admin storages', :storage_server_helpers, with_flag: { storages_module_active: true }, type: :feature, js: true do describe 'Admin storages', :storage_server_helpers, type: :feature, js: true do
let(:admin) { create(:admin) } let(:admin) { create(:admin) }
before do before do

@ -31,7 +31,7 @@ require_relative '../spec_helper'
# Setup storages in Project -> Settings -> File Storages # Setup storages in Project -> Settings -> File Storages
# This tests assumes that a Storage has already been setup # This tests assumes that a Storage has already been setup
# in the Admin section, tested by admin_storage_spec.rb. # in the Admin section, tested by admin_storage_spec.rb.
describe 'Activation of storages in projects', with_flag: { storages_module_active: true }, type: :feature, js: true do describe 'Activation of storages in projects', type: :feature, js: true do
let(:user) { create(:user) } let(:user) { create(:user) }
# The first page is the Project -> Settings -> General page, so we need # The first page is the Project -> Settings -> General page, so we need
# to provide the user with the edit_project permission in the role. # to provide the user with the edit_project permission in the role.

@ -30,7 +30,7 @@ require_relative '../spec_helper'
# Test if the deletion of a ProjectStorage actually deletes related FileLink # Test if the deletion of a ProjectStorage actually deletes related FileLink
# objects. # objects.
describe 'Delete ProjectStorage with FileLinks', with_flag: { storages_module_active: true }, type: :feature, js: true do describe 'Delete ProjectStorage with FileLinks', type: :feature, js: true do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:role) { create(:existing_role, permissions: [:manage_storages_in_project]) } let(:role) { create(:existing_role, permissions: [:manage_storages_in_project]) }
let(:project) do let(:project) do

@ -28,10 +28,7 @@
require_relative '../spec_helper' require_relative '../spec_helper'
# Checks that disabling storages modules hides everything related to it in web describe 'Ensure storages module', type: :feature, js: true do
# interface. Enable it first, check everything present, then disable it, and
# check everything present.
describe 'Disablement of storages module', type: :feature, js: true do
current_user { create(:admin) } current_user { create(:admin) }
let(:role) do let(:role) do
@ -59,70 +56,61 @@ describe 'Disablement of storages module', type: :feature, js: true do
Capybara.raise_server_errors = old_value Capybara.raise_server_errors = old_value
end end
it 'removes storages from administration and project pages' do it 'shows storages on administration and project pages' do
Setting.feature_storages_module_active = true
expect_pages_to_include_storages_information expect_pages_to_include_storages_information
Setting.feature_storages_module_active = false
expect_pages_not_to_include_storages_information
end end
def expect_pages_to_include_storages_information def expect_pages_to_include_storages_information
run_administration_pages_assertions_about_storages_visibility(expectation_target: :to) run_administration_pages_assertions_about_storages_visibility
run_project_pages_assertions_about_storages_visibility(expectation_target: :to) run_project_pages_assertions_about_storages_visibility
run_permissions_pages_assertions_about_storages_visibility(expectation_target: :to) run_permissions_pages_assertions_about_storages_visibility
end end
def expect_pages_not_to_include_storages_information def run_administration_pages_assertions_about_storages_visibility
run_administration_pages_assertions_about_storages_visibility(expectation_target: :not_to)
run_project_pages_assertions_about_storages_visibility(expectation_target: :not_to)
run_permissions_pages_assertions_about_storages_visibility(expectation_target: :not_to)
end
def run_administration_pages_assertions_about_storages_visibility(expectation_target:)
visit admin_index_path visit admin_index_path
within '#menu-sidebar' do within '#menu-sidebar' do
expect(page).send(expectation_target, have_text(I18n.t(:project_module_storages))) expect(page).to have_text(I18n.t(:project_module_storages))
end end
within '#content' do within '#content' do
expect(page).send(expectation_target, have_text(I18n.t(:project_module_storages))) expect(page).to have_text(I18n.t(:project_module_storages))
end end
visit admin_settings_projects_path visit admin_settings_projects_path
within '#content' do within '#content' do
expect(page).send(expectation_target, have_text(I18n.t(:project_module_storages))) expect(page).to have_text(I18n.t(:project_module_storages))
end end
visit admin_settings_storages_path visit admin_settings_storages_path
expect(page).send(expectation_target, have_text(I18n.t(:project_module_storages))) expect(page).to have_text(I18n.t(:project_module_storages))
end end
def run_project_pages_assertions_about_storages_visibility(expectation_target:) def run_project_pages_assertions_about_storages_visibility
visit project_settings_modules_path(project) visit project_settings_modules_path(project)
within '#menu-sidebar' do within '#menu-sidebar' do
expect(page).send(expectation_target, have_text(I18n.t(:project_module_storages))) expect(page).to have_text(I18n.t(:project_module_storages))
end end
within '#content' do within '#content' do
expect(page).send(expectation_target, have_text(I18n.t(:project_module_storages))) expect(page).to have_text(I18n.t(:project_module_storages))
end end
visit project_settings_projects_storages_path(project) visit project_settings_projects_storages_path(project)
expect(page).send(expectation_target, have_text(I18n.t('storages.page_titles.project_settings.index'))) expect(page).to have_text(I18n.t('storages.page_titles.project_settings.index'))
end end
def run_permissions_pages_assertions_about_storages_visibility(expectation_target:) def run_permissions_pages_assertions_about_storages_visibility
visit new_role_path visit new_role_path
within '#content' do within '#content' do
expect(page).send(expectation_target, have_text(I18n.t(:project_module_storages).upcase)) expect(page).to have_text(I18n.t(:project_module_storages).upcase)
end end
visit edit_role_path(role) visit edit_role_path(role)
within '#content' do within '#content' do
expect(page).send(expectation_target, have_text(I18n.t(:project_module_storages).upcase)) expect(page).to have_text(I18n.t(:project_module_storages).upcase)
end end
visit report_roles_path(role) visit report_roles_path(role)
within '#content' do within '#content' do
expect(page).send(expectation_target, have_text(I18n.t(:project_module_storages).upcase)) expect(page).to have_text(I18n.t(:project_module_storages).upcase)
end end
end end
end end

@ -28,7 +28,7 @@
require_relative '../spec_helper' require_relative '../spec_helper'
describe 'Showing of file links in work package', with_flag: { storages_module_active: true }, type: :feature, js: true do describe 'Showing of file links in work package', type: :feature, js: true do
let(:permissions) { %i(view_work_packages edit_work_packages view_file_links manage_file_links) } let(:permissions) { %i(view_work_packages edit_work_packages view_file_links manage_file_links) }
let(:project) { create(:project) } let(:project) { create(:project) }
let(:current_user) { create(:user, member_in_project: project, member_with_permissions: permissions) } let(:current_user) { create(:user, member_in_project: project, member_with_permissions: permissions) }

@ -31,10 +31,7 @@ require 'support/permission_specs'
require_module_spec_helper require_module_spec_helper
# rubocop:disable RSpec/EmptyExampleGroup # rubocop:disable RSpec/EmptyExampleGroup
describe Storages::Admin::ProjectsStoragesController, describe Storages::Admin::ProjectsStoragesController, 'manage_storage_in_project permission', type: :controller do
'manage_storage_in_project permission',
with_flag: { storages_module_active: true },
type: :controller do
include PermissionSpecs include PermissionSpecs
controller_actions.each do |action| controller_actions.each do |action|

@ -29,7 +29,7 @@
require 'spec_helper' require 'spec_helper'
require_module_spec_helper require_module_spec_helper
describe 'API v3 file links resource', with_flag: { storages_module_active: true }, type: :request do describe 'API v3 file links resource', type: :request do
include API::V3::Utilities::PathHelper include API::V3::Utilities::PathHelper
let(:permissions) { %i(view_work_packages view_file_links) } let(:permissions) { %i(view_work_packages view_file_links) }
@ -122,10 +122,6 @@ describe 'API v3 file links resource', with_flag: { storages_module_active: true
end end
end end
context 'if storages feature is inactive', with_flag: { storages_module_active: false } do
it_behaves_like 'not found'
end
describe 'with filter by storage' do describe 'with filter by storage' do
let!(:another_project_storage) { create(:project_storage, project:, storage: another_storage) } let!(:another_project_storage) { create(:project_storage, project:, storage: another_storage) }
let(:path) { "#{api_v3_paths.file_links(work_package.id)}?filters=#{CGI.escape(filters.to_json)}" } let(:path) { "#{api_v3_paths.file_links(work_package.id)}?filters=#{CGI.escape(filters.to_json)}" }
@ -217,10 +213,6 @@ describe 'API v3 file links resource', with_flag: { storages_module_active: true
end end
end end
end end
context 'when storages module is inactive', with_flag: { storages_module_active: false } do
it_behaves_like 'not found'
end
end end
context 'when some embedded file link elements are NOT valid' do context 'when some embedded file link elements are NOT valid' do
@ -412,10 +404,6 @@ describe 'API v3 file links resource', with_flag: { storages_module_active: true
it_behaves_like 'not found' it_behaves_like 'not found'
end end
context 'when storages module is inactive', with_flag: { storages_module_active: false } do
it_behaves_like 'not found'
end
end end
describe 'DELETE /api/v3/file_links/:file_link_id' do describe 'DELETE /api/v3/file_links/:file_link_id' do
@ -449,10 +437,6 @@ describe 'API v3 file links resource', with_flag: { storages_module_active: true
it_behaves_like 'not found' it_behaves_like 'not found'
end end
context 'when storages module is inactive', with_flag: { storages_module_active: false } do
it_behaves_like 'not found'
end
end end
describe 'GET /api/v3/file_links/:file_link_id/open' do describe 'GET /api/v3/file_links/:file_link_id/open' do
@ -485,10 +469,6 @@ describe 'API v3 file links resource', with_flag: { storages_module_active: true
it_behaves_like 'not found' it_behaves_like 'not found'
end end
context 'when storages module is inactive', with_flag: { storages_module_active: false } do
it_behaves_like 'not found'
end
end end
describe 'GET /api/v3/file_links/:file_link_id/download' do describe 'GET /api/v3/file_links/:file_link_id/download' do

@ -30,7 +30,7 @@ require 'spec_helper'
require_module_spec_helper require_module_spec_helper
# We want to check the case of file_links from multiple storages # We want to check the case of file_links from multiple storages
describe 'API v3 file links resource', with_flag: { storages_module_active: true }, type: :request do describe 'API v3 file links resource', type: :request do
include API::V3::Utilities::PathHelper include API::V3::Utilities::PathHelper
let(:project) { create(:project) } let(:project) { create(:project) }

@ -29,7 +29,7 @@
require 'spec_helper' require 'spec_helper'
require_module_spec_helper require_module_spec_helper
describe 'API v3 storages resource', with_flag: { storages_module_active: true }, type: :request, content_type: :json do describe 'API v3 storages resource', type: :request, content_type: :json do
include API::V3::Utilities::PathHelper include API::V3::Utilities::PathHelper
let(:permissions) { %i(view_work_packages view_file_links) } let(:permissions) { %i(view_work_packages view_file_links) }
@ -106,10 +106,6 @@ describe 'API v3 storages resource', with_flag: { storages_module_active: true }
it_behaves_like 'successful storage response' it_behaves_like 'successful storage response'
end end
context 'when storages module is inactive', with_flag: { storages_module_active: false } do
it_behaves_like 'not found'
end
context 'when OAuth authorization server is involved' do context 'when OAuth authorization server is involved' do
shared_examples 'a storage authorization result' do |expected:, has_authorize_link:| shared_examples 'a storage authorization result' do |expected:, has_authorize_link:|
subject { last_response.body } subject { last_response.body }

@ -1,38 +0,0 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2022 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
require 'spec_helper'
shared_examples_for 'filter unavailable when storages module is inactive' do
context 'when storages module is inactive', with_flag: { storages_module_active: false } do
it_behaves_like 'error response',
400,
'InvalidQuery',
'filter does not exist.'
end
end

@ -28,10 +28,8 @@
require 'spec_helper' require 'spec_helper'
require_module_spec_helper require_module_spec_helper
require_relative 'shared_filter_examples'
describe 'API v3 work packages resource with filters for the linkable to storage attribute', describe 'API v3 work packages resource with filters for the linkable to storage attribute',
with_flag: { storages_module_active: true },
type: :request, type: :request,
content_type: :json do content_type: :json do
include API::V3::Utilities::PathHelper include API::V3::Utilities::PathHelper
@ -123,8 +121,6 @@ describe 'API v3 work packages resource with filters for the linkable to storage
let(:elements) { [] } let(:elements) { [] }
end end
end end
include_examples 'filter unavailable when storages module is inactive'
end end
context 'with filter for storage url' do context 'with filter for storage url' do
@ -167,8 +163,6 @@ describe 'API v3 work packages resource with filters for the linkable to storage
let(:elements) { [] } let(:elements) { [] }
end end
end end
include_examples 'filter unavailable when storages module is inactive'
end end
end end
end end

@ -28,10 +28,8 @@
require 'spec_helper' require 'spec_helper'
require_module_spec_helper require_module_spec_helper
require_relative 'shared_filter_examples'
describe 'API v3 work packages resource with filters for linked storage file', describe 'API v3 work packages resource with filters for linked storage file',
with_flag: { storages_module_active: true },
type: :request, type: :request,
content_type: :json do content_type: :json do
include API::V3::Utilities::PathHelper include API::V3::Utilities::PathHelper
@ -139,8 +137,6 @@ describe 'API v3 work packages resource with filters for linked storage file',
end end
end end
include_examples 'filter unavailable when storages module is inactive'
context 'if using signaling' do context 'if using signaling' do
let(:path) { api_v3_paths.path_for :work_packages, select: 'total,count,_type,elements/*', filters: } let(:path) { api_v3_paths.path_for :work_packages, select: 'total,count,_type,elements/*', filters: }
@ -182,8 +178,6 @@ describe 'API v3 work packages resource with filters for linked storage file',
let(:elements) { [] } let(:elements) { [] }
end end
end end
include_examples 'filter unavailable when storages module is inactive'
end end
context 'with single filter for storage url' do context 'with single filter for storage url' do
@ -226,8 +220,6 @@ describe 'API v3 work packages resource with filters for linked storage file',
let(:elements) { [] } let(:elements) { [] }
end end
end end
include_examples 'filter unavailable when storages module is inactive'
end end
context 'with combined filter of file id and storage id' do context 'with combined filter of file id and storage id' do

@ -30,7 +30,7 @@ require 'spec_helper'
require_module_spec_helper require_module_spec_helper
require 'services/base_services/behaves_like_delete_service' require 'services/base_services/behaves_like_delete_service'
describe ::Storages::ProjectStorages::DeleteService, with_flag: { storages_module_active: true }, type: :model do describe ::Storages::ProjectStorages::DeleteService, type: :model do
context 'with records written to DB' do context 'with records written to DB' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:role) { create(:existing_role, permissions: [:manage_storages_in_project]) } let(:role) { create(:existing_role, permissions: [:manage_storages_in_project]) }

@ -44,8 +44,8 @@ describe 'Admin menu items', js: true do
visit admin_index_path visit admin_index_path
expect(page).to have_selector('[data-qa-selector="menu-blocks--container"]') expect(page).to have_selector('[data-qa-selector="menu-blocks--container"]')
expect(page).to have_selector('[data-qa-selector="menu-block"]', count: 18) expect(page).to have_selector('[data-qa-selector="menu-block"]', count: 19)
expect(page).to have_selector('[data-qa-selector="op-menu--item-action"]', count: 19) # All plus 'overview' expect(page).to have_selector('[data-qa-selector="op-menu--item-action"]', count: 20) # All plus 'overview'
end end
end end
@ -57,10 +57,10 @@ describe 'Admin menu items', js: true do
visit admin_index_path visit admin_index_path
expect(page).to have_selector('[data-qa-selector="menu-blocks--container"]') expect(page).to have_selector('[data-qa-selector="menu-blocks--container"]')
expect(page).to have_selector('[data-qa-selector="menu-block"]', count: 17) expect(page).to have_selector('[data-qa-selector="menu-block"]', count: 18)
expect(page).not_to have_selector('[data-qa-selector="menu-block"]', text: I18n.t('timelines.admin_menu.colors')) expect(page).not_to have_selector('[data-qa-selector="menu-block"]', text: I18n.t('timelines.admin_menu.colors'))
expect(page).to have_selector('[data-qa-selector="op-menu--item-action"]', count: 18) # All plus 'overview' expect(page).to have_selector('[data-qa-selector="op-menu--item-action"]', count: 19) # All plus 'overview'
expect(page).not_to have_selector('[data-qa-selector="op-menu--item-action"]', text: I18n.t('timelines.admin_menu.colors')) expect(page).not_to have_selector('[data-qa-selector="op-menu--item-action"]', text: I18n.t('timelines.admin_menu.colors'))
end end
end end

@ -29,7 +29,7 @@
require 'spec_helper' require 'spec_helper'
require 'rack/test' require 'rack/test'
describe 'OAuthClient callback endpoint', with_flag: { storages_module_active: true }, type: :request do describe 'OAuthClient callback endpoint', type: :request do
include Rack::Test::Methods include Rack::Test::Methods
include API::V3::Utilities::PathHelper include API::V3::Utilities::PathHelper

@ -39,8 +39,6 @@ def aggregate_mocked_settings(example, settings)
end end
RSpec.shared_context 'with settings reset' do RSpec.shared_context 'with settings reset' do
let(:storages_module_active) { true }
around do |example| around do |example|
definitions_before = Settings::Definition.all.dup definitions_before = Settings::Definition.all.dup
Settings::Definition.send(:reset) Settings::Definition.send(:reset)
@ -49,10 +47,6 @@ RSpec.shared_context 'with settings reset' do
Settings::Definition.send(:reset) Settings::Definition.send(:reset)
Settings::Definition.instance_variable_set(:@all, definitions_before) Settings::Definition.instance_variable_set(:@all, definitions_before)
end end
before do
allow(OpenProject::FeatureDecisions).to receive(:storages_module_active?).and_return(storages_module_active)
end
end end
module WithSettingsMixin module WithSettingsMixin

Loading…
Cancel
Save