Commit cdc4c62c authored by Shinya Maeda's avatar Shinya Maeda

Remove feature_flags_environment_scope feature flag

Remove the feature flag as we confirmed the feature is
deemed stable.

Fix pot

Remove feature flag from frontend

Remove unnecessary partial

Fix
parent 7163d138
import initEditFeatureFlags from 'ee/feature_flags/edit';
if (gon.features && gon.features.featureFlagsEnvironmentScope) {
document.addEventListener('DOMContentLoaded', initEditFeatureFlags);
}
document.addEventListener('DOMContentLoaded', initEditFeatureFlags);
import initNewFeatureFlags from 'ee/feature_flags/new';
if (gon.features && gon.features.featureFlagsEnvironmentScope) {
document.addEventListener('DOMContentLoaded', initNewFeatureFlags);
}
document.addEventListener('DOMContentLoaded', initNewFeatureFlags);
......@@ -3,7 +3,6 @@
class Projects::FeatureFlagsController < Projects::ApplicationController
respond_to :html
before_action :push_feature_flag_to_frontend!
before_action :authorize_read_feature_flag!
before_action :authorize_create_feature_flag!, only: [:new, :create]
before_action :authorize_update_feature_flag!, only: [:edit, :update]
......@@ -138,8 +137,4 @@ class Projects::FeatureFlagsController < Projects::ApplicationController
render json: { message: feature_flag.errors.full_messages },
status: :bad_request
end
def push_feature_flag_to_frontend!
push_frontend_feature_flag(:feature_flags_environment_scope, project)
end
end
......@@ -36,10 +36,6 @@ class FeatureFlagsFinder
end
def for_list(items)
if Feature.enabled?(:feature_flags_environment_scope, project)
items.for_list
else
items
end
end
end
......@@ -36,19 +36,11 @@ module Operations
scope :ordered, -> { order(:name) }
scope :enabled, -> do
if Feature.enabled?(:feature_flags_environment_scope)
where('EXISTS (?)', join_enabled_scopes)
else
where(active: true)
end
end
scope :disabled, -> do
if Feature.enabled?(:feature_flags_environment_scope)
where('NOT EXISTS (?)', join_enabled_scopes)
else
where(active: false)
end
end
scope :for_environment, -> (environment) do
......
- if @feature_flag.errors.any?
= render 'errors'
%fieldset
.row
.form-group.col-md-4
= f.label :name, class: 'label-bold', for: 'feature_flag_name' do
= s_('FeatureFlags|Name')
= f.text_field :name, class: "form-control", id: "feature_flag_name"
.row
.form-group.col-md-4
= f.label :description, class: 'label-bold', for: 'feature_flag_description' do
= s_('FeatureFlags|Description')
= f.text_area :description, class: "form-control", id: "feature_flag_description", rows: 4
.row
.form-group.col-md-1
= f.label :active, class: 'label-bold' do
= s_('FeatureFlags|Status')
.form-check
= f.check_box :active, id: 'feature_flag_status', class: 'form-check-input'
= f.label :active, for: 'feature_flag_status', class: 'form-check-label' do
= s_('FeatureFlags|Active')
.form-actions
- if @feature_flag.persisted?
= f.submit s_('FeatureFlags|Save changes'), class: "btn btn-success"
- else
= f.submit s_('FeatureFlags|Create feature flag'), class: "btn btn-success"
.float-right
= link_to _('Cancel'), project_feature_flags_path(@project), class: 'btn btn-cancel'
......@@ -2,12 +2,4 @@
- breadcrumb_title @feature_flag.name
- page_title s_('FeatureFlags|Edit Feature Flag')
- if Feature.enabled?(:feature_flags_environment_scope, @project)
#js-edit-feature-flag{ data: { endpoint: project_feature_flag_path(@project, @feature_flag), feature_flags_path: project_feature_flags_path(@project), environments_endpoint: search_project_environments_path(@project, format: :json)} }
- else
%h3.page-title
= s_('FeatureFlags|Edit %{feature_flag_name}') % { feature_flag_name: @feature_flag.name }
%hr.clearfix
%div
= form_for [@project, @feature_flag], url: project_feature_flag_path(@project, @feature_flag), html: { class: 'fieldset-form' } do |f|
= render 'form', { f: f }
#js-edit-feature-flag{ data: { endpoint: project_feature_flag_path(@project, @feature_flag), feature_flags_path: project_feature_flags_path(@project), environments_endpoint: search_project_environments_path(@project, format: :json)} }
......@@ -3,12 +3,4 @@
- breadcrumb_title s_('FeatureFlags|New')
- page_title s_('FeatureFlags|New Feature Flag')
- if Feature.enabled?(:feature_flags_environment_scope, @project)
#js-new-feature-flag{ data: { endpoint: project_feature_flags_path(@project, format: :json), feature_flags_path: project_feature_flags_path(@project), environments_endpoint: search_project_environments_path(@project, format: :json) } }
- else
%h3.page-title
= s_('FeatureFlags|New Feature Flag')
%hr.clearfix
%div
= form_for [@project, @feature_flag], url: project_feature_flags_path(@project), html: { class: 'fieldset-form' } do |f|
= render 'form', { f: f }
#js-new-feature-flag{ data: { endpoint: project_feature_flags_path(@project, format: :json), feature_flags_path: project_feature_flags_path(@project), environments_endpoint: search_project_environments_path(@project, format: :json) } }
......@@ -70,14 +70,10 @@ module API
end
def feature_flags
if Feature.enabled?(:feature_flags_environment_scope, project)
return [] unless unleash_app_name.present?
project.operations_feature_flags.for_environment(unleash_app_name)
.ordered
else
project.operations_feature_flags.ordered
end
end
end
end
......
require 'spec_helper'
describe 'Feature Flags', :js do
using RSpec::Parameterized::TableSyntax
invalid_input_table = proc do
'with space' | '' | 'Name can contain only'
'<script>' | '' | 'Name can contain only'
'x' * 100 | '' | 'Name is too long'
'some-name' | 'y' * 1001 | 'Description is too long'
end
let(:user) {create(:user)}
let(:project) {create(:project, namespace: user.namespace)}
before do
stub_licensed_features(feature_flags: true)
stub_feature_flags(feature_flags_environment_scope: false)
sign_in(user)
end
it 'shows empty state' do
visit(project_feature_flags_path(project))
expect_empty_state
end
context 'when creating a new feature flag' do
context 'and input is valid' do
where(:name, :description, :status) do
'my-active-flag' | 'a new flag' | true
'my-inactive-flag' | '' | false
end
with_them do
it 'adds the feature flag to the table' do
add_feature_flag(name, description, status)
expect_feature_flag(name, description, status)
expect(page).to have_selector '.flash-container', text: 'successfully created'
end
end
end
context 'and input is invalid' do
where(:name, :description, :error_message, &invalid_input_table)
with_them do
it 'displays an error message' do
add_feature_flag(name, description, false)
expect(page).to have_selector '.alert-danger', text: error_message
end
end
end
end
context 'when editing a feature flag' do
before do
add_feature_flag('feature-flag-to-edit', 'with some description', false)
end
shared_examples_for 'correct edit behavior' do
context 'and input is valid' do
it 'updates the feature flag' do
name = 'new-name'
description = 'new description'
edit_feature_flag('feature-flag-to-edit', name, description, true)
expect_feature_flag(name, description, true)
expect(page).to have_selector '.flash-container', text: 'successfully updated'
end
end
context 'and input is invalid' do
where(:name, :description, :error_message, &invalid_input_table)
with_them do
it 'displays an error message' do
edit_feature_flag('feature-flag-to-edit', name, description, false)
expect(page).to have_selector '.alert-danger', text: error_message
end
end
end
end
it_behaves_like 'correct edit behavior'
end
context 'when deleting a feature flag' do
before do
add_feature_flag('feature-flag-to-delete', 'with some description', false)
end
shared_examples_for 'correct delete behavior' do
context 'and no feature flags are left' do
it 'shows empty state' do
visit(project_feature_flags_path(project))
delete_feature_flag('feature-flag-to-delete')
expect_empty_state
end
end
context 'and there is a feature flag left' do
before do
add_feature_flag('another-feature-flag', '', true)
end
it 'shows feature flag table without deleted feature flag' do
visit(project_feature_flags_path(project))
delete_feature_flag('feature-flag-to-delete')
expect_feature_flag('another-feature-flag', '', true)
end
end
it 'does not delete if modal is cancelled' do
visit(project_feature_flags_path(project))
delete_feature_flag('feature-flag-to-delete', false)
expect_feature_flag('feature-flag-to-delete', 'with some description', false)
end
end
it_behaves_like 'correct delete behavior'
end
context 'when user sees empty index page' do
before do
visit(project_feature_flags_path(project))
end
shared_examples_for 'correct empty index behavior' do
it 'shows empty state' do
expect(page).to have_content('Get started with Feature Flags')
expect(page).to have_link('New Feature Flag')
expect(page).to have_button('Configure')
end
end
it_behaves_like 'correct empty index behavior'
end
context 'when user sees index page' do
let!(:feature_flag_enabled) { create(:operations_feature_flag, project: project, active: true) }
let!(:feature_flag_disabled) { create(:operations_feature_flag, project: project, active: false) }
before do
visit(project_feature_flags_path(project))
end
context 'when user sees all tab' do
it 'shows all feature flags' do
expect(page).to have_content(feature_flag_enabled.name)
expect(page).to have_content(feature_flag_disabled.name)
expect(page).to have_link('New Feature Flag')
expect(page).to have_button('Configure')
end
end
context 'when user sees enabled tab' do
it 'shows only active feature flags' do
find('.js-featureflags-tab-enabled').click
expect(page).to have_content(feature_flag_enabled.name)
expect(page).not_to have_content(feature_flag_disabled.name)
end
end
context 'when user sees disabled tab' do
it 'shows only inactive feature flags' do
find('.js-featureflags-tab-disabled').click
expect(page).not_to have_content(feature_flag_enabled.name)
expect(page).to have_content(feature_flag_disabled.name)
end
end
end
private
def add_feature_flag(name, description, status)
visit(new_project_feature_flag_path(project))
fill_in 'Name', with: name
fill_in 'Description', with: description
if status
check('Active')
else
uncheck('Active')
end
click_button 'Create feature flag'
end
def delete_feature_flag(name, confirm = true)
delete_button = find('.gl-responsive-table-row', text: name).find('.js-feature-flag-delete-button')
delete_button.click
within '.modal' do
if confirm
click_button 'Delete'
else
click_button 'Cancel'
end
end
end
def edit_feature_flag(old_name, new_name, new_description, new_status)
visit(project_feature_flags_path(project))
edit_button = find('.gl-responsive-table-row', text: old_name).find('.js-feature-flag-edit-button')
edit_button.click
fill_in 'Name', with: new_name
fill_in 'Description', with: new_description
if new_status
check('Active')
else
uncheck('Active')
end
click_button 'Save changes'
end
def expect_empty_state
expect(page).to have_selector('.js-feature-flags-empty-state')
expect(page).to have_selector('.btn-success', text: 'New Feature Flag')
expect(page).to have_selector('.btn-primary.btn-inverted', text: 'Configure')
end
def expect_feature_flag(name, description, status)
expect(current_path).to eq project_feature_flags_path(project)
expect(page).to have_selector '.table-section .badge', text: status ? 'Active' : 'Inactive'
expect(page).to have_selector '.table-section', text: name
expect(page).to have_selector '.table-section', text: description
end
end
......@@ -95,10 +95,6 @@ describe Operations::FeatureFlag do
describe '.for_environment' do
subject { described_class.for_environment(environment_name) }
before do
stub_feature_flags(feature_flags_environment_scope: true)
end
context 'when feature flag is off on production' do
before do
feature_flag = create(:operations_feature_flag, active: true)
......@@ -166,10 +162,6 @@ describe Operations::FeatureFlag do
describe '.for_list' do
subject { described_class.for_list }
before do
stub_feature_flags(feature_flags_environment_scope: true)
end
context 'when all scopes are active' do
let!(:feature_flag) { create(:operations_feature_flag, active: true) }
let!(:scope) { create_scope(feature_flag, 'production', true) }
......
......@@ -98,18 +98,6 @@ describe API::Unleash do
subject
end
context 'when the feature is disabled on the project' do
before do
stub_feature_flags(feature_flags_environment_scope: { enabled: false, thing: project })
end
it 'does not call for_environment method' do
expect(Operations::FeatureFlag).not_to receive(:for_environment)
subject
end
end
context 'when app name is staging' do
let(:headers) { base_headers.merge({ "UNLEASH-APPNAME" => "staging" }) }
......@@ -169,10 +157,6 @@ describe API::Unleash do
let!(:enable_feature_flag) { create(:operations_feature_flag, project: project, name: 'feature1', active: true) }
let!(:disabled_feature_flag) { create(:operations_feature_flag, project: project, name: 'feature2', active: false) }
before do
stub_feature_flags(feature_flags_environment_scope: false)
end
it 'responds with a list' do
subject
......
......@@ -4056,9 +4056,6 @@ msgstr ""
msgid "FeatureFlags|Description"
msgstr ""
msgid "FeatureFlags|Edit %{feature_flag_name}"
msgstr ""
msgid "FeatureFlags|Edit Feature Flag"
msgstr ""
......@@ -4116,9 +4113,6 @@ msgstr ""
msgid "FeatureFlags|New Feature Flag"
msgstr ""
msgid "FeatureFlags|Save changes"
msgstr ""
msgid "FeatureFlags|Status"
msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment