diff options
Diffstat (limited to 'spec/controllers/projects/feature_flags_controller_spec.rb')
-rw-r--r-- | spec/controllers/projects/feature_flags_controller_spec.rb | 418 |
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 |