summaryrefslogtreecommitdiff
path: root/spec/controllers/projects/feature_flags_controller_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/controllers/projects/feature_flags_controller_spec.rb')
-rw-r--r--spec/controllers/projects/feature_flags_controller_spec.rb418
1 files changed, 30 insertions, 388 deletions
diff --git a/spec/controllers/projects/feature_flags_controller_spec.rb b/spec/controllers/projects/feature_flags_controller_spec.rb
index d5fc80bd5a7..f69cc0ddfd8 100644
--- a/spec/controllers/projects/feature_flags_controller_spec.rb
+++ b/spec/controllers/projects/feature_flags_controller_spec.rb
@@ -845,413 +845,64 @@ RSpec.describe Projects::FeatureFlagsController do
put(:update, params: params, format: :json, as: :json)
end
- before do
- stub_feature_flags(
- feature_flags_legacy_read_only: false,
- feature_flags_legacy_read_only_override: false
- )
- end
-
- subject { put(:update, params: params, format: :json) }
-
- let!(:feature_flag) do
- create(:operations_feature_flag,
- :legacy_flag,
- name: 'ci_live_trace',
- active: true,
- project: project)
- end
-
- let(:params) do
- {
- namespace_id: project.namespace,
- project_id: project,
- iid: feature_flag.iid,
- operations_feature_flag: {
- name: 'ci_new_live_trace'
- }
- }
- end
-
- it 'returns 200' do
- is_expected.to have_gitlab_http_status(:ok)
- end
-
- it 'updates the name of the feature flag name' do
- subject
-
- expect(json_response['name']).to eq('ci_new_live_trace')
- end
-
- it 'matches json schema' do
- is_expected.to match_response_schema('feature_flag')
- end
-
- context 'when updates active' do
- let(:params) do
- {
- namespace_id: project.namespace,
- project_id: project,
- iid: feature_flag.iid,
- operations_feature_flag: {
- active: false
- }
- }
- end
-
- it 'updates active from true to false' do
- expect { subject }
- .to change { feature_flag.reload.active }.from(true).to(false)
- end
-
- it "does not change default scope's active" do
- expect { subject }
- .not_to change { feature_flag.default_scope.reload.active }.from(true)
- end
-
- it 'updates active from false to true when an inactive feature flag has an active scope' do
- feature_flag = create(:operations_feature_flag, project: project, name: 'my_flag', active: false)
- create(:operations_feature_flag_scope, feature_flag: feature_flag, environment_scope: 'production', active: true)
-
- put_request(feature_flag, { active: true })
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to match_response_schema('feature_flag')
- expect(json_response['active']).to eq(true)
- expect(feature_flag.reload.active).to eq(true)
- expect(feature_flag.default_scope.reload.active).to eq(false)
- end
- end
-
- context 'when user is reporter' do
- let(:user) { reporter }
-
- it 'returns 404' do
- is_expected.to have_gitlab_http_status(:not_found)
- end
- end
-
- context "when creates an additional scope for production environment" do
- let(:params) do
- {
- namespace_id: project.namespace,
- project_id: project,
- iid: feature_flag.iid,
- operations_feature_flag: {
- scopes_attributes: [{ environment_scope: 'production', active: false }]
- }
- }
- end
-
- it 'creates a production scope' do
- expect { subject }.to change { feature_flag.reload.scopes.count }.by(1)
-
- expect(json_response['scopes'].last['environment_scope']).to eq('production')
- expect(json_response['scopes'].last['active']).to be_falsy
- end
- end
-
- context "when creates a default scope" do
- let(:params) do
- {
- namespace_id: project.namespace,
- project_id: project,
- iid: feature_flag.iid,
- operations_feature_flag: {
- scopes_attributes: [{ environment_scope: '*', active: false }]
- }
- }
- end
-
- it 'returns 400' do
- is_expected.to have_gitlab_http_status(:bad_request)
- end
- end
-
- context "when updates a default scope's active value" do
- let(:params) do
- {
- namespace_id: project.namespace,
- project_id: project,
- iid: feature_flag.iid,
- operations_feature_flag: {
- scopes_attributes: [
- {
- id: feature_flag.default_scope.id,
- environment_scope: '*',
- active: false
- }
- ]
- }
- }
- end
-
- it "updates successfully" do
- subject
-
- expect(json_response['scopes'].first['environment_scope']).to eq('*')
- expect(json_response['scopes'].first['active']).to be_falsy
- end
- end
-
- context "when changes default scope's spec" do
- let(:params) do
- {
- namespace_id: project.namespace,
- project_id: project,
- iid: feature_flag.iid,
- operations_feature_flag: {
- scopes_attributes: [
- {
- id: feature_flag.default_scope.id,
- environment_scope: 'review/*'
- }
- ]
- }
- }
- end
-
- it 'returns 400' do
- is_expected.to have_gitlab_http_status(:bad_request)
- end
- end
+ context 'with a legacy feature flag' do
+ subject { put(:update, params: params, format: :json) }
- context "when destroys the default scope" do
- let(:params) do
- {
- namespace_id: project.namespace,
- project_id: project,
- iid: feature_flag.iid,
- operations_feature_flag: {
- scopes_attributes: [
- {
- id: feature_flag.default_scope.id,
- _destroy: 1
- }
- ]
- }
- }
- end
-
- it 'raises an error' do
- expect { subject }.to raise_error(ActiveRecord::ReadOnlyRecord)
+ let!(:feature_flag) do
+ create(:operations_feature_flag,
+ :legacy_flag,
+ name: 'ci_live_trace',
+ active: true,
+ project: project)
end
- end
- context "when destroys a production scope" do
- let!(:production_scope) { create_scope(feature_flag, 'production', true) }
let(:params) do
{
namespace_id: project.namespace,
project_id: project,
iid: feature_flag.iid,
operations_feature_flag: {
- scopes_attributes: [
- {
- id: production_scope.id,
- _destroy: 1
- }
- ]
+ name: 'ci_new_live_trace'
}
}
end
- it 'destroys successfully' do
- subject
-
- scopes = json_response['scopes']
- expect(scopes.any? { |scope| scope['environment_scope'] == 'production' })
- .to be_falsy
- end
- end
-
- describe "updating the strategy" do
- it 'creates a default strategy' do
- scope = create_scope(feature_flag, 'production', true, [])
-
- put_request(feature_flag, scopes_attributes: [{
- id: scope.id,
- strategies: [{ name: 'default', parameters: {} }]
- }])
+ context 'when user is reporter' do
+ let(:user) { reporter }
- expect(response).to have_gitlab_http_status(:ok)
- scope_json = json_response['scopes'].find do |s|
- s['environment_scope'] == 'production'
+ it 'returns 404' do
+ is_expected.to have_gitlab_http_status(:not_found)
end
- expect(scope_json['strategies']).to eq([{
- "name" => "default",
- "parameters" => {}
- }])
end
- it 'creates a gradualRolloutUserId strategy' do
- scope = create_scope(feature_flag, 'production', true, [])
-
- put_request(feature_flag, scopes_attributes: [{
- id: scope.id,
- strategies: [{ name: 'gradualRolloutUserId',
- parameters: { groupId: 'default', percentage: "70" } }]
- }])
-
- expect(response).to have_gitlab_http_status(:ok)
- scope_json = json_response['scopes'].find do |s|
- s['environment_scope'] == 'production'
- end
- expect(scope_json['strategies']).to eq([{
- "name" => "gradualRolloutUserId",
- "parameters" => {
- "groupId" => "default",
- "percentage" => "70"
- }
- }])
- end
-
- it 'creates a userWithId strategy' do
- scope = create_scope(feature_flag, 'production', true, [{ name: 'default', parameters: {} }])
-
- put_request(feature_flag, scopes_attributes: [{
- id: scope.id,
- strategies: [{ name: 'userWithId', parameters: { userIds: 'sam,fred' } }]
- }])
-
- expect(response).to have_gitlab_http_status(:ok)
- scope_json = json_response['scopes'].find do |s|
- s['environment_scope'] == 'production'
- end
- expect(scope_json['strategies']).to eq([{
- "name" => "userWithId",
- "parameters" => { "userIds" => "sam,fred" }
- }])
- end
-
- it 'updates an existing strategy' do
- scope = create_scope(feature_flag, 'production', true, [{ name: 'default', parameters: {} }])
-
- put_request(feature_flag, scopes_attributes: [{
- id: scope.id,
- strategies: [{ name: 'gradualRolloutUserId',
- parameters: { groupId: 'default', percentage: "50" } }]
- }])
-
- expect(response).to have_gitlab_http_status(:ok)
- scope_json = json_response['scopes'].find do |s|
- s['environment_scope'] == 'production'
- end
- expect(scope_json['strategies']).to eq([{
- "name" => "gradualRolloutUserId",
- "parameters" => {
- "groupId" => "default",
- "percentage" => "50"
+ context "when changing default scope's spec" do
+ let(:params) do
+ {
+ namespace_id: project.namespace,
+ project_id: project,
+ iid: feature_flag.iid,
+ operations_feature_flag: {
+ scopes_attributes: [
+ {
+ id: feature_flag.default_scope.id,
+ environment_scope: 'review/*'
+ }
+ ]
+ }
}
- }])
- end
-
- it 'clears an existing strategy' do
- scope = create_scope(feature_flag, 'production', true, [{ name: 'default', parameters: {} }])
-
- put_request(feature_flag, scopes_attributes: [{
- id: scope.id,
- strategies: []
- }])
-
- expect(response).to have_gitlab_http_status(:ok)
- scope_json = json_response['scopes'].find do |s|
- s['environment_scope'] == 'production'
- end
- expect(scope_json['strategies']).to eq([])
- end
-
- it 'accepts multiple strategies' do
- scope = create_scope(feature_flag, 'production', true, [{ name: 'default', parameters: {} }])
-
- put_request(feature_flag, scopes_attributes: [{
- id: scope.id,
- strategies: [
- { name: 'gradualRolloutUserId', parameters: { groupId: 'mygroup', percentage: '55' } },
- { name: 'userWithId', parameters: { userIds: 'joe' } }
- ]
- }])
-
- expect(response).to have_gitlab_http_status(:ok)
- scope_json = json_response['scopes'].find do |s|
- s['environment_scope'] == 'production'
- end
- expect(scope_json['strategies'].length).to eq(2)
- expect(scope_json['strategies']).to include({
- "name" => "gradualRolloutUserId",
- "parameters" => { "groupId" => "mygroup", "percentage" => "55" }
- })
- expect(scope_json['strategies']).to include({
- "name" => "userWithId",
- "parameters" => { "userIds" => "joe" }
- })
- end
-
- it 'does not modify strategies when there is no strategies key in the params' do
- scope = create_scope(feature_flag, 'production', true, [{ name: 'default', parameters: {} }])
-
- put_request(feature_flag, scopes_attributes: [{ id: scope.id }])
-
- expect(response).to have_gitlab_http_status(:ok)
- scope_json = json_response['scopes'].find do |s|
- s['environment_scope'] == 'production'
end
- expect(scope_json['strategies']).to eq([{
- "name" => "default",
- "parameters" => {}
- }])
- end
-
- it 'leaves an existing strategy when there are no strategies in the params' do
- scope = create_scope(feature_flag, 'production', true, [{ name: 'gradualRolloutUserId',
- parameters: { groupId: 'default', percentage: '10' } }])
- put_request(feature_flag, scopes_attributes: [{ id: scope.id }])
-
- expect(response).to have_gitlab_http_status(:ok)
- scope_json = json_response['scopes'].find do |s|
- s['environment_scope'] == 'production'
+ it 'returns 400' do
+ is_expected.to have_gitlab_http_status(:bad_request)
end
- expect(scope_json['strategies']).to eq([{
- "name" => "gradualRolloutUserId",
- "parameters" => { "groupId" => "default", "percentage" => "10" }
- }])
end
- it 'does not accept extra parameters in the strategy params' do
- scope = create_scope(feature_flag, 'production', true, [{ name: 'default', parameters: {} }])
-
- put_request(feature_flag, scopes_attributes: [{
- id: scope.id,
- strategies: [{ name: 'userWithId', parameters: { userIds: 'joe', groupId: 'default' } }]
- }])
-
- expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response['message']).to eq(["Scopes strategies parameters are invalid"])
- end
- end
-
- context 'when legacy feature flags are set to be read only' do
- it 'does not update the flag' do
- stub_feature_flags(feature_flags_legacy_read_only: true)
-
+ it 'does not update a legacy feature flag' do
put_request(feature_flag, name: 'ci_new_live_trace')
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to eq(["Legacy feature flags are read-only"])
end
-
- it 'updates the flag if the legacy read-only override is enabled for a particular project' do
- stub_feature_flags(
- feature_flags_legacy_read_only: true,
- feature_flags_legacy_read_only_override: project
- )
-
- put_request(feature_flag, name: 'ci_new_live_trace')
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['name']).to eq('ci_new_live_trace')
- end
end
context 'with a version 2 feature flag' do
@@ -1517,15 +1168,6 @@ RSpec.describe Projects::FeatureFlagsController do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['strategies'].first['scopes']).to eq([])
end
-
- it 'updates the flag when legacy feature flags are set to be read only' do
- stub_feature_flags(feature_flags_legacy_read_only: true)
-
- put_request(new_version_flag, name: 'some-other-name')
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(new_version_flag.reload.name).to eq('some-other-name')
- end
end
end