diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 10:08:36 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 10:08:36 +0300 |
commit | 48aff82709769b098321c738f3444b9bdaa694c6 (patch) | |
tree | e00c7c43e2d9b603a5a6af576b1685e400410dee /spec/requests/api/feature_flags_user_lists_spec.rb | |
parent | 879f5329ee916a948223f8f43d77fba4da6cd028 (diff) |
Add latest changes from gitlab-org/gitlab@13-5-stable-eev13.5.0-rc42
Diffstat (limited to 'spec/requests/api/feature_flags_user_lists_spec.rb')
-rw-r--r-- | spec/requests/api/feature_flags_user_lists_spec.rb | 371 |
1 files changed, 371 insertions, 0 deletions
diff --git a/spec/requests/api/feature_flags_user_lists_spec.rb b/spec/requests/api/feature_flags_user_lists_spec.rb new file mode 100644 index 00000000000..469210040dd --- /dev/null +++ b/spec/requests/api/feature_flags_user_lists_spec.rb @@ -0,0 +1,371 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe API::FeatureFlagsUserLists do + let_it_be(:project, refind: true) { create(:project) } + let_it_be(:developer) { create(:user) } + let_it_be(:reporter) { create(:user) } + + before_all do + project.add_developer(developer) + project.add_reporter(reporter) + end + + def create_list(name: 'mylist', user_xids: 'user1') + create(:operations_feature_flag_user_list, project: project, name: name, user_xids: user_xids) + end + + def disable_repository(project) + project.project_feature.update!( + repository_access_level: ::ProjectFeature::DISABLED, + merge_requests_access_level: ::ProjectFeature::DISABLED, + builds_access_level: ::ProjectFeature::DISABLED + ) + end + + describe 'GET /projects/:id/feature_flags_user_lists' do + it 'forbids the request for a reporter' do + get api("/projects/#{project.id}/feature_flags_user_lists", reporter) + + expect(response).to have_gitlab_http_status(:forbidden) + end + + it 'returns forbidden if the feature is unavailable' do + disable_repository(project) + + get api("/projects/#{project.id}/feature_flags_user_lists", developer) + + expect(response).to have_gitlab_http_status(:forbidden) + end + + it 'returns all the user lists' do + create_list(name: 'list_a', user_xids: 'user1') + create_list(name: 'list_b', user_xids: 'user1,user2,user3') + + get api("/projects/#{project.id}/feature_flags_user_lists", developer) + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response.map { |list| list['name'] }.sort).to eq(%w[list_a list_b]) + end + + it 'returns all the data for a user list' do + user_list = create_list(name: 'list_a', user_xids: 'user1') + + get api("/projects/#{project.id}/feature_flags_user_lists", developer) + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to eq([{ + 'id' => user_list.id, + 'iid' => user_list.iid, + 'project_id' => project.id, + 'created_at' => user_list.created_at.as_json, + 'updated_at' => user_list.updated_at.as_json, + 'name' => 'list_a', + 'user_xids' => 'user1', + 'path' => project_feature_flags_user_list_path(user_list.project, user_list), + 'edit_path' => edit_project_feature_flags_user_list_path(user_list.project, user_list) + }]) + end + + it 'paginates user lists' do + create_list(name: 'list_a', user_xids: 'user1') + create_list(name: 'list_b', user_xids: 'user1,user2,user3') + + get api("/projects/#{project.id}/feature_flags_user_lists?page=2&per_page=1", developer) + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response.map { |list| list['name'] }).to eq(['list_b']) + end + + it 'returns the user lists for only the specified project' do + create(:operations_feature_flag_user_list, project: project, name: 'list') + other_project = create(:project) + create(:operations_feature_flag_user_list, project: other_project, name: 'other_list') + + get api("/projects/#{project.id}/feature_flags_user_lists", developer) + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response.map { |list| list['name'] }).to eq(['list']) + end + + it 'returns an empty list' do + get api("/projects/#{project.id}/feature_flags_user_lists", developer) + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to eq([]) + end + end + + describe 'GET /projects/:id/feature_flags_user_lists/:iid' do + it 'forbids the request for a reporter' do + list = create_list + + get api("/projects/#{project.id}/feature_flags_user_lists/#{list.iid}", reporter) + + expect(response).to have_gitlab_http_status(:forbidden) + end + + it 'returns forbidden if the feature is unavailable' do + disable_repository(project) + list = create_list + + get api("/projects/#{project.id}/feature_flags_user_lists/#{list.iid}", developer) + + expect(response).to have_gitlab_http_status(:forbidden) + end + + it 'returns the user list' do + list = create_list(name: 'testers', user_xids: 'test1,test2') + + get api("/projects/#{project.id}/feature_flags_user_lists/#{list.iid}", developer) + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to eq({ + 'name' => 'testers', + 'user_xids' => 'test1,test2', + 'id' => list.id, + 'iid' => list.iid, + 'project_id' => project.id, + 'created_at' => list.created_at.as_json, + 'updated_at' => list.updated_at.as_json, + 'path' => project_feature_flags_user_list_path(list.project, list), + 'edit_path' => edit_project_feature_flags_user_list_path(list.project, list) + }) + end + + it 'returns the correct user list identified by the iid' do + create_list(name: 'list_a', user_xids: 'test1') + list_b = create_list(name: 'list_b', user_xids: 'test2') + + get api("/projects/#{project.id}/feature_flags_user_lists/#{list_b.iid}", developer) + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response['name']).to eq('list_b') + end + + it 'scopes the iid search to the project' do + other_project = create(:project) + other_project.add_developer(developer) + create(:operations_feature_flag_user_list, project: other_project, name: 'other_list') + list = create(:operations_feature_flag_user_list, project: project, name: 'list') + + get api("/projects/#{project.id}/feature_flags_user_lists/#{list.iid}", developer) + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response['name']).to eq('list') + end + + it 'returns not found when the list does not exist' do + get api("/projects/#{project.id}/feature_flags_user_lists/1", developer) + + expect(response).to have_gitlab_http_status(:not_found) + expect(json_response).to eq({ 'message' => '404 Not found' }) + end + end + + describe 'POST /projects/:id/feature_flags_user_lists' do + it 'forbids the request for a reporter' do + post api("/projects/#{project.id}/feature_flags_user_lists", reporter), params: { + name: 'mylist', user_xids: 'user1' + } + + expect(response).to have_gitlab_http_status(:forbidden) + expect(project.operations_feature_flags_user_lists.count).to eq(0) + end + + it 'returns forbidden if the feature is unavailable' do + disable_repository(project) + + post api("/projects/#{project.id}/feature_flags_user_lists", developer), params: { + name: 'mylist', user_xids: 'user1' + } + + expect(response).to have_gitlab_http_status(:forbidden) + end + + it 'creates the flag' do + post api("/projects/#{project.id}/feature_flags_user_lists", developer), params: { + name: 'mylist', user_xids: 'user1' + } + + expect(response).to have_gitlab_http_status(:created) + expect(json_response.slice('name', 'user_xids', 'project_id', 'iid')).to eq({ + 'name' => 'mylist', + 'user_xids' => 'user1', + 'project_id' => project.id, + 'iid' => 1 + }) + expect(project.operations_feature_flags_user_lists.count).to eq(1) + expect(project.operations_feature_flags_user_lists.last.name).to eq('mylist') + end + + it 'requires name' do + post api("/projects/#{project.id}/feature_flags_user_lists", developer), params: { + user_xids: 'user1' + } + + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response).to eq({ 'message' => 'name is missing' }) + expect(project.operations_feature_flags_user_lists.count).to eq(0) + end + + it 'requires user_xids' do + post api("/projects/#{project.id}/feature_flags_user_lists", developer), params: { + name: 'empty_list' + } + + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response).to eq({ 'message' => 'user_xids is missing' }) + expect(project.operations_feature_flags_user_lists.count).to eq(0) + end + + it 'returns an error when name is already taken' do + create_list(name: 'myname') + post api("/projects/#{project.id}/feature_flags_user_lists", developer), params: { + name: 'myname', user_xids: 'a' + } + + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response).to eq({ 'message' => ['Name has already been taken'] }) + expect(project.operations_feature_flags_user_lists.count).to eq(1) + end + + it 'does not create a flag for a project of which the developer is not a member' do + other_project = create(:project) + + post api("/projects/#{other_project.id}/feature_flags_user_lists", developer), params: { + name: 'mylist', user_xids: 'user1' + } + + expect(response).to have_gitlab_http_status(:not_found) + expect(other_project.operations_feature_flags_user_lists.count).to eq(0) + expect(project.operations_feature_flags_user_lists.count).to eq(0) + end + end + + describe 'PUT /projects/:id/feature_flags_user_lists/:iid' do + it 'forbids the request for a reporter' do + list = create_list(name: 'original_name') + + put api("/projects/#{project.id}/feature_flags_user_lists/#{list.iid}", reporter), params: { + name: 'mylist' + } + + expect(response).to have_gitlab_http_status(:forbidden) + expect(list.reload.name).to eq('original_name') + end + + it 'returns forbidden if the feature is unavailable' do + list = create_list(name: 'original_name') + disable_repository(project) + + put api("/projects/#{project.id}/feature_flags_user_lists/#{list.iid}", developer), params: { + name: 'mylist', user_xids: '456,789' + } + + expect(response).to have_gitlab_http_status(:forbidden) + end + + it 'updates the list' do + list = create_list(name: 'original_name', user_xids: '123') + + put api("/projects/#{project.id}/feature_flags_user_lists/#{list.iid}", developer), params: { + name: 'mylist', user_xids: '456,789' + } + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response.slice('name', 'user_xids')).to eq({ + 'name' => 'mylist', + 'user_xids' => '456,789' + }) + expect(list.reload.name).to eq('mylist') + end + + it 'preserves attributes not listed in the request' do + list = create_list(name: 'original_name', user_xids: '123') + + put api("/projects/#{project.id}/feature_flags_user_lists/#{list.iid}", developer), params: {} + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response.slice('name', 'user_xids')).to eq({ + 'name' => 'original_name', + 'user_xids' => '123' + }) + expect(list.reload.name).to eq('original_name') + expect(list.reload.user_xids).to eq('123') + end + + it 'returns an error when the update is invalid' do + create_list(name: 'taken', user_xids: '123') + list = create_list(name: 'original_name', user_xids: '123') + + put api("/projects/#{project.id}/feature_flags_user_lists/#{list.iid}", developer), params: { + name: 'taken' + } + + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response).to eq({ 'message' => ['Name has already been taken'] }) + end + + it 'returns not found when the list does not exist' do + list = create_list(name: 'original_name', user_xids: '123') + + put api("/projects/#{project.id}/feature_flags_user_lists/#{list.iid + 1}", developer), params: { + name: 'new_name' + } + + expect(response).to have_gitlab_http_status(:not_found) + expect(json_response).to eq({ 'message' => '404 Not found' }) + end + end + + describe 'DELETE /projects/:id/feature_flags_user_lists/:iid' do + it 'forbids the request for a reporter' do + list = create_list + + delete api("/projects/#{project.id}/feature_flags_user_lists/#{list.iid}", reporter) + + expect(response).to have_gitlab_http_status(:forbidden) + expect(project.operations_feature_flags_user_lists.count).to eq(1) + end + + it 'returns forbidden if the feature is unavailable' do + list = create_list + disable_repository(project) + + delete api("/projects/#{project.id}/feature_flags_user_lists/#{list.iid}", developer) + + expect(response).to have_gitlab_http_status(:forbidden) + end + + it 'returns not found when the list does not exist' do + delete api("/projects/#{project.id}/feature_flags_user_lists/1", developer) + + expect(response).to have_gitlab_http_status(:not_found) + expect(json_response).to eq({ 'message' => '404 Not found' }) + end + + it 'deletes the list' do + list = create_list + + delete api("/projects/#{project.id}/feature_flags_user_lists/#{list.iid}", developer) + + expect(response).to have_gitlab_http_status(:no_content) + expect(response.body).to be_blank + expect(project.operations_feature_flags_user_lists.count).to eq(0) + end + + it 'does not delete the list if it is associated with a strategy' do + list = create_list + feature_flag = create(:operations_feature_flag, :new_version_flag, project: project) + create(:operations_strategy, feature_flag: feature_flag, name: 'gitlabUserList', user_list: list) + + delete api("/projects/#{project.id}/feature_flags_user_lists/#{list.iid}", developer) + + expect(response).to have_gitlab_http_status(:conflict) + expect(json_response).to eq({ 'message' => ['User list is associated with a strategy'] }) + expect(list.reload).to be_persisted + end + end +end |