diff options
Diffstat (limited to 'spec')
452 files changed, 3050 insertions, 1389 deletions
diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index f044a068938..f350641a643 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -13,7 +13,7 @@ describe Admin::UsersController do let!(:issue) { create(:issue, author: user) } before do - project.team << [user, :developer] + project.add_developer(user) end it 'deletes user and ghosts their contributions' do diff --git a/spec/controllers/boards/issues_controller_spec.rb b/spec/controllers/boards/issues_controller_spec.rb index 44d504d5852..79bbc29e80d 100644 --- a/spec/controllers/boards/issues_controller_spec.rb +++ b/spec/controllers/boards/issues_controller_spec.rb @@ -13,8 +13,8 @@ describe Boards::IssuesController do let!(:list2) { create(:list, board: board, label: development, position: 1) } before do - project.team << [user, :master] - project.team << [guest, :guest] + project.add_master(user) + project.add_guest(guest) end describe 'GET index' do @@ -221,7 +221,7 @@ describe Boards::IssuesController do let(:guest) { create(:user) } before do - project.team << [guest, :guest] + project.add_guest(guest) end it 'returns a forbidden 403 response' do diff --git a/spec/controllers/boards/lists_controller_spec.rb b/spec/controllers/boards/lists_controller_spec.rb index a2b432af23a..71d45a22d91 100644 --- a/spec/controllers/boards/lists_controller_spec.rb +++ b/spec/controllers/boards/lists_controller_spec.rb @@ -7,8 +7,8 @@ describe Boards::ListsController do let(:guest) { create(:user) } before do - project.team << [user, :master] - project.team << [guest, :guest] + project.add_master(user) + project.add_guest(guest) end describe 'GET index' do diff --git a/spec/controllers/dashboard/milestones_controller_spec.rb b/spec/controllers/dashboard/milestones_controller_spec.rb index 2f3d7be9abe..60547db82b6 100644 --- a/spec/controllers/dashboard/milestones_controller_spec.rb +++ b/spec/controllers/dashboard/milestones_controller_spec.rb @@ -17,7 +17,7 @@ describe Dashboard::MilestonesController do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) end it_behaves_like 'milestone tabs' diff --git a/spec/controllers/dashboard/todos_controller_spec.rb b/spec/controllers/dashboard/todos_controller_spec.rb index f9faa4fa59a..b4a731fd3a3 100644 --- a/spec/controllers/dashboard/todos_controller_spec.rb +++ b/spec/controllers/dashboard/todos_controller_spec.rb @@ -8,7 +8,7 @@ describe Dashboard::TodosController do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) end describe 'GET #index' do diff --git a/spec/controllers/dashboard_controller_spec.rb b/spec/controllers/dashboard_controller_spec.rb index 566d8515198..97c2c3fb940 100644 --- a/spec/controllers/dashboard_controller_spec.rb +++ b/spec/controllers/dashboard_controller_spec.rb @@ -5,7 +5,7 @@ describe DashboardController do let(:project) { create(:project) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/controllers/groups/milestones_controller_spec.rb b/spec/controllers/groups/milestones_controller_spec.rb index c1aba46be04..733386500ca 100644 --- a/spec/controllers/groups/milestones_controller_spec.rb +++ b/spec/controllers/groups/milestones_controller_spec.rb @@ -28,7 +28,7 @@ describe Groups::MilestonesController do before do sign_in(user) group.add_owner(user) - project.team << [user, :master] + project.add_master(user) end describe '#index' do diff --git a/spec/controllers/notification_settings_controller_spec.rb b/spec/controllers/notification_settings_controller_spec.rb index 9014b8b5084..e133950e684 100644 --- a/spec/controllers/notification_settings_controller_spec.rb +++ b/spec/controllers/notification_settings_controller_spec.rb @@ -6,7 +6,7 @@ describe NotificationSettingsController do let(:user) { create(:user) } before do - project.team << [user, :developer] + project.add_developer(user) end describe '#create' do diff --git a/spec/controllers/projects/artifacts_controller_spec.rb b/spec/controllers/projects/artifacts_controller_spec.rb index d1051741430..12cb7b2647f 100644 --- a/spec/controllers/projects/artifacts_controller_spec.rb +++ b/spec/controllers/projects/artifacts_controller_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Projects::ArtifactsController do - set(:user) { create(:user) } + let(:user) { project.owner } set(:project) { create(:project, :repository, :public) } let(:pipeline) do @@ -15,14 +15,12 @@ describe Projects::ArtifactsController do let(:job) { create(:ci_build, :success, :artifacts, pipeline: pipeline) } before do - project.add_developer(user) - sign_in(user) end describe 'GET download' do it 'sends the artifacts file' do - expect(controller).to receive(:send_file).with(job.artifacts_file.path, disposition: 'attachment').and_call_original + expect(controller).to receive(:send_file).with(job.artifacts_file.path, hash_including(disposition: 'attachment')).and_call_original get :download, namespace_id: project.namespace, project_id: project, job_id: job end @@ -113,20 +111,43 @@ describe Projects::ArtifactsController do end describe 'GET raw' do + subject { get(:raw, namespace_id: project.namespace, project_id: project, job_id: job, path: path) } + context 'when the file exists' do - it 'serves the file using workhorse' do - get :raw, namespace_id: project.namespace, project_id: project, job_id: job, path: 'ci_artifacts.txt' + let(:path) { 'ci_artifacts.txt' } - send_data = response.headers[Gitlab::Workhorse::SEND_DATA_HEADER] + shared_examples 'a valid file' do + it 'serves the file using workhorse' do + subject - expect(send_data).to start_with('artifacts-entry:') + expect(response).to have_gitlab_http_status(200) + expect(send_data).to start_with('artifacts-entry:') - base64_params = send_data.sub(/\Aartifacts\-entry:/, '') - params = JSON.parse(Base64.urlsafe_decode64(base64_params)) + expect(params.keys).to eq(%w(Archive Entry)) + expect(params['Archive']).to start_with(archive_path) + # On object storage, the URL can end with a query string + expect(params['Archive']).to match(/build_artifacts.zip(\?[^?]+)?$/) + expect(params['Entry']).to eq(Base64.encode64('ci_artifacts.txt')) + end + + def send_data + response.headers[Gitlab::Workhorse::SEND_DATA_HEADER] + end - expect(params.keys).to eq(%w(Archive Entry)) - expect(params['Archive']).to end_with('build_artifacts.zip') - expect(params['Entry']).to eq(Base64.encode64('ci_artifacts.txt')) + def params + @params ||= begin + base64_params = send_data.sub(/\Aartifacts\-entry:/, '') + JSON.parse(Base64.urlsafe_decode64(base64_params)) + end + end + end + + context 'when using local file storage' do + it_behaves_like 'a valid file' do + let(:job) { create(:ci_build, :success, :artifacts, pipeline: pipeline) } + let(:store) { ObjectStoreUploader::LOCAL_STORE } + let(:archive_path) { JobArtifactUploader.local_store_path } + end end end end diff --git a/spec/controllers/projects/avatars_controller_spec.rb b/spec/controllers/projects/avatars_controller_spec.rb index f5ea097af8b..3bbe168f6d5 100644 --- a/spec/controllers/projects/avatars_controller_spec.rb +++ b/spec/controllers/projects/avatars_controller_spec.rb @@ -6,7 +6,7 @@ describe Projects::AvatarsController do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) controller.instance_variable_set(:@project, project) end diff --git a/spec/controllers/projects/blame_controller_spec.rb b/spec/controllers/projects/blame_controller_spec.rb index 54282aa4001..88d4f4e9cd0 100644 --- a/spec/controllers/projects/blame_controller_spec.rb +++ b/spec/controllers/projects/blame_controller_spec.rb @@ -7,7 +7,7 @@ describe Projects::BlameController do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) controller.instance_variable_set(:@project, project) end diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb index 6a1c07b4a0b..00a7df6ccc8 100644 --- a/spec/controllers/projects/blob_controller_spec.rb +++ b/spec/controllers/projects/blob_controller_spec.rb @@ -89,7 +89,7 @@ describe Projects::BlobController do end before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end @@ -147,7 +147,7 @@ describe Projects::BlobController do let(:developer) { create(:user) } before do - project.team << [developer, :developer] + project.add_developer(developer) sign_in(developer) get :edit, default_params end @@ -161,7 +161,7 @@ describe Projects::BlobController do let(:master) { create(:user) } before do - project.team << [master, :master] + project.add_master(master) sign_in(master) get :edit, default_params end @@ -190,7 +190,7 @@ describe Projects::BlobController do end before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/controllers/projects/boards_controller_spec.rb b/spec/controllers/projects/boards_controller_spec.rb index d6ccb92c54b..305af289531 100644 --- a/spec/controllers/projects/boards_controller_spec.rb +++ b/spec/controllers/projects/boards_controller_spec.rb @@ -5,7 +5,7 @@ describe Projects::BoardsController do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb index d731200f70f..734396ddf7b 100644 --- a/spec/controllers/projects/branches_controller_spec.rb +++ b/spec/controllers/projects/branches_controller_spec.rb @@ -6,8 +6,8 @@ describe Projects::BranchesController do let(:developer) { create(:user) } before do - project.team << [user, :master] - project.team << [user, :developer] + project.add_master(user) + project.add_developer(user) allow(project).to receive(:branches).and_return(['master', 'foo/bar/baz']) allow(project).to receive(:tags).and_return(['v1.0.0', 'v2.0.0']) @@ -148,6 +148,20 @@ describe Projects::BranchesController do end end + context 'when create branch service fails' do + let(:branch) { "./invalid-branch-name" } + + it "doesn't post a system note" do + expect(SystemNoteService).not_to receive(:new_issue_branch) + + post :create, + namespace_id: project.namespace, + project_id: project, + branch_name: branch, + issue_iid: issue.iid + end + end + context 'without issue feature access' do before do project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) diff --git a/spec/controllers/projects/commits_controller_spec.rb b/spec/controllers/projects/commits_controller_spec.rb index c459d732507..73fb90d73ec 100644 --- a/spec/controllers/projects/commits_controller_spec.rb +++ b/spec/controllers/projects/commits_controller_spec.rb @@ -6,7 +6,7 @@ describe Projects::CommitsController do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) end describe "GET show" do diff --git a/spec/controllers/projects/compare_controller_spec.rb b/spec/controllers/projects/compare_controller_spec.rb index fe5818da0bc..046ce027965 100644 --- a/spec/controllers/projects/compare_controller_spec.rb +++ b/spec/controllers/projects/compare_controller_spec.rb @@ -8,7 +8,7 @@ describe Projects::CompareController do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) end it 'compare shows some diffs' do diff --git a/spec/controllers/projects/cycle_analytics_controller_spec.rb b/spec/controllers/projects/cycle_analytics_controller_spec.rb index 6fae52edbad..7c708a418a7 100644 --- a/spec/controllers/projects/cycle_analytics_controller_spec.rb +++ b/spec/controllers/projects/cycle_analytics_controller_spec.rb @@ -6,7 +6,7 @@ describe Projects::CycleAnalyticsController do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) end describe 'cycle analytics not set up flag' do diff --git a/spec/controllers/projects/deploy_keys_controller_spec.rb b/spec/controllers/projects/deploy_keys_controller_spec.rb index c3208357694..97db69427e9 100644 --- a/spec/controllers/projects/deploy_keys_controller_spec.rb +++ b/spec/controllers/projects/deploy_keys_controller_spec.rb @@ -5,7 +5,7 @@ describe Projects::DeployKeysController do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end @@ -48,7 +48,7 @@ describe Projects::DeployKeysController do end before do - project2.team << [user, :developer] + project2.add_developer(user) end it 'returns json in a correct format' do diff --git a/spec/controllers/projects/deployments_controller_spec.rb b/spec/controllers/projects/deployments_controller_spec.rb index 3164fd5c143..73e7921fab7 100644 --- a/spec/controllers/projects/deployments_controller_spec.rb +++ b/spec/controllers/projects/deployments_controller_spec.rb @@ -8,7 +8,7 @@ describe Projects::DeploymentsController do let(:environment) { create(:environment, name: 'production', project: project) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/controllers/projects/discussions_controller_spec.rb b/spec/controllers/projects/discussions_controller_spec.rb index 3bf676637a2..00328d3ea51 100644 --- a/spec/controllers/projects/discussions_controller_spec.rb +++ b/spec/controllers/projects/discussions_controller_spec.rb @@ -31,7 +31,7 @@ describe Projects::DiscussionsController do context "when the user is authorized to resolve the discussion" do before do - project.team << [user, :developer] + project.add_developer(user) end context "when the discussion is not resolvable" do @@ -92,7 +92,7 @@ describe Projects::DiscussionsController do context "when the user is authorized to resolve the discussion" do before do - project.team << [user, :developer] + project.add_developer(user) end context "when the discussion is not resolvable" do diff --git a/spec/controllers/projects/find_file_controller_spec.rb b/spec/controllers/projects/find_file_controller_spec.rb index 6a5433bcc9c..505fe82851a 100644 --- a/spec/controllers/projects/find_file_controller_spec.rb +++ b/spec/controllers/projects/find_file_controller_spec.rb @@ -7,7 +7,7 @@ describe Projects::FindFileController do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) controller.instance_variable_set(:@project, project) end diff --git a/spec/controllers/projects/forks_controller_spec.rb b/spec/controllers/projects/forks_controller_spec.rb index 1bedb8ebdff..c4b32dc3a09 100644 --- a/spec/controllers/projects/forks_controller_spec.rb +++ b/spec/controllers/projects/forks_controller_spec.rb @@ -51,7 +51,7 @@ describe Projects::ForksController do context 'when user is a member of the Project' do before do - forked_project.team << [project.creator, :developer] + forked_project.add_developer(project.creator) end it 'sees the project listed' do diff --git a/spec/controllers/projects/graphs_controller_spec.rb b/spec/controllers/projects/graphs_controller_spec.rb index 5af03ae118c..c3605555fe7 100644 --- a/spec/controllers/projects/graphs_controller_spec.rb +++ b/spec/controllers/projects/graphs_controller_spec.rb @@ -6,7 +6,7 @@ describe Projects::GraphsController do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) end describe 'GET languages' do diff --git a/spec/controllers/projects/group_links_controller_spec.rb b/spec/controllers/projects/group_links_controller_spec.rb index f8c792cd0f0..5bfc3d31401 100644 --- a/spec/controllers/projects/group_links_controller_spec.rb +++ b/spec/controllers/projects/group_links_controller_spec.rb @@ -7,7 +7,7 @@ describe Projects::GroupLinksController do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/controllers/projects/hooks_controller_spec.rb b/spec/controllers/projects/hooks_controller_spec.rb index 07174660f46..aba70c6d4c1 100644 --- a/spec/controllers/projects/hooks_controller_spec.rb +++ b/spec/controllers/projects/hooks_controller_spec.rb @@ -5,7 +5,7 @@ describe Projects::HooksController do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/controllers/projects/imports_controller_spec.rb b/spec/controllers/projects/imports_controller_spec.rb index 2a5ec6d584b..7fb4c1b7425 100644 --- a/spec/controllers/projects/imports_controller_spec.rb +++ b/spec/controllers/projects/imports_controller_spec.rb @@ -9,7 +9,7 @@ describe Projects::ImportsController do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) end it 'renders template' do @@ -30,7 +30,7 @@ describe Projects::ImportsController do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) end context 'when import is in progress' do diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index a2ef937609b..6b7db947216 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -37,7 +37,7 @@ describe Projects::IssuesController do context 'internal issue tracker' do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) end it_behaves_like "issuables list meta-data", :issue @@ -69,7 +69,7 @@ describe Projects::IssuesController do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) allow(Kaminari.config).to receive(:default_per_page).and_return(1) end @@ -116,7 +116,7 @@ describe Projects::IssuesController do context 'internal issue tracker' do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) end it 'builds a new issue' do @@ -127,7 +127,7 @@ describe Projects::IssuesController do it 'fills in an issue for a merge request' do project_with_repository = create(:project, :repository) - project_with_repository.team << [user, :developer] + project_with_repository.add_developer(user) mr = create(:merge_request_with_diff_notes, source_project: project_with_repository) get :new, namespace_id: project_with_repository.namespace, project_id: project_with_repository, merge_request_to_resolve_discussions_of: mr.iid @@ -153,7 +153,7 @@ describe Projects::IssuesController do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) external = double allow(project).to receive(:external_issue_tracker).and_return(external) @@ -329,7 +329,7 @@ describe Projects::IssuesController do it 'does not list confidential issues for project members with guest role' do sign_in(member) - project.team << [member, :guest] + project.add_guest(member) get_issues @@ -354,7 +354,7 @@ describe Projects::IssuesController do it 'lists confidential issues for project members' do sign_in(member) - project.team << [member, :developer] + project.add_developer(member) get_issues @@ -394,7 +394,7 @@ describe Projects::IssuesController do it 'returns 404 for project members with guest role' do sign_in(member) - project.team << [member, :guest] + project.add_guest(member) go(id: unescaped_parameter_value.to_param) expect(response).to have_gitlab_http_status :not_found @@ -416,7 +416,7 @@ describe Projects::IssuesController do it "returns #{http_status[:success]} for project members" do sign_in(member) - project.team << [member, :developer] + project.add_developer(member) go(id: unescaped_parameter_value.to_param) expect(response).to have_gitlab_http_status http_status[:success] @@ -450,7 +450,7 @@ describe Projects::IssuesController do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) end it_behaves_like 'restricted action', success: 200 @@ -594,7 +594,7 @@ describe Projects::IssuesController do let(:deleted_user) { create(:user) } before do - project.team << [user, :developer] + project.add_developer(user) issue.update!(last_edited_by: deleted_user, last_edited_at: Time.now) @@ -638,7 +638,7 @@ describe Projects::IssuesController do def post_new_issue(issue_attrs = {}, additional_params = {}) sign_in(user) project = create(:project, :public) - project.team << [user, :developer] + project.add_developer(user) post :create, { namespace_id: project.namespace.to_param, @@ -655,7 +655,7 @@ describe Projects::IssuesController do let(:project) { merge_request.source_project } before do - project.team << [user, :master] + project.add_master(user) sign_in user end @@ -829,7 +829,7 @@ describe Projects::IssuesController do def post_spam admin = create(:admin) create(:user_agent_detail, subject: issue) - project.team << [admin, :master] + project.add_master(admin) sign_in(admin) post :mark_as_spam, { namespace_id: project.namespace, diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb index 7490f8fefce..e6a4e7c8257 100644 --- a/spec/controllers/projects/jobs_controller_spec.rb +++ b/spec/controllers/projects/jobs_controller_spec.rb @@ -374,7 +374,7 @@ describe Projects::JobsController do let(:role) { :master } before do - project.team << [user, role] + project.add_role(user, role) sign_in(user) post_erase diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb index cf83f2f3265..452d7e23983 100644 --- a/spec/controllers/projects/labels_controller_spec.rb +++ b/spec/controllers/projects/labels_controller_spec.rb @@ -6,7 +6,7 @@ describe Projects::LabelsController do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/controllers/projects/mattermosts_controller_spec.rb b/spec/controllers/projects/mattermosts_controller_spec.rb index 33d48ff94d1..c5ac0be27bb 100644 --- a/spec/controllers/projects/mattermosts_controller_spec.rb +++ b/spec/controllers/projects/mattermosts_controller_spec.rb @@ -5,7 +5,7 @@ describe Projects::MattermostsController do let!(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/controllers/projects/merge_requests/creations_controller_spec.rb b/spec/controllers/projects/merge_requests/creations_controller_spec.rb index 7fdddc02fd3..7e2366847f4 100644 --- a/spec/controllers/projects/merge_requests/creations_controller_spec.rb +++ b/spec/controllers/projects/merge_requests/creations_controller_spec.rb @@ -6,7 +6,7 @@ describe Projects::MergeRequests::CreationsController do let(:fork_project) { create(:forked_project_with_submodules) } before do - fork_project.team << [user, :master] + fork_project.add_master(user) sign_in(user) end @@ -86,7 +86,7 @@ describe Projects::MergeRequests::CreationsController do let(:other_project) { create(:project, :repository) } before do - other_project.team << [user, :master] + other_project.add_master(user) end context 'when the path exists in the diff' do diff --git a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb index ba97ccfbbd4..5d297c654bf 100644 --- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb +++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb @@ -151,7 +151,7 @@ describe Projects::MergeRequests::DiffsController do let(:other_project) { create(:project) } before do - other_project.team << [user, :master] + other_project.add_master(user) diff_for_path(old_path: existing_path, new_path: existing_path, project_id: other_project) end diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb index 209979e642d..00cf464ec5b 100644 --- a/spec/controllers/projects/milestones_controller_spec.rb +++ b/spec/controllers/projects/milestones_controller_spec.rb @@ -11,7 +11,7 @@ describe Projects::MilestonesController do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) controller.instance_variable_set(:@project, project) end diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb index 37e9f863fc4..de132dfaa21 100644 --- a/spec/controllers/projects/notes_controller_spec.rb +++ b/spec/controllers/projects/notes_controller_spec.rb @@ -32,7 +32,7 @@ describe Projects::NotesController do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) end it 'passes last_fetched_at from headers to NotesFinder' do @@ -351,7 +351,7 @@ describe Projects::NotesController do before do sign_in(note.author) - project.team << [note.author, :developer] + project.add_developer(note.author) end it "updates the note" do @@ -372,7 +372,7 @@ describe Projects::NotesController do context 'user is the author of a note' do before do sign_in(note.author) - project.team << [note.author, :developer] + project.add_developer(note.author) end it "returns status 200 for html" do @@ -389,7 +389,7 @@ describe Projects::NotesController do context 'user is not the author of a note' do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) end it "returns status 404" do @@ -403,7 +403,7 @@ describe Projects::NotesController do describe 'POST toggle_award_emoji' do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) end it "toggles the award emoji" do @@ -445,7 +445,7 @@ describe Projects::NotesController do context "when the user is authorized to resolve the note" do before do - project.team << [user, :developer] + project.add_developer(user) end context "when the note is not resolvable" do @@ -506,7 +506,7 @@ describe Projects::NotesController do context "when the user is authorized to resolve the note" do before do - project.team << [user, :developer] + project.add_developer(user) end context "when the note is not resolvable" do diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb index 290dba0610a..46b08a03b19 100644 --- a/spec/controllers/projects/project_members_controller_spec.rb +++ b/spec/controllers/projects/project_members_controller_spec.rb @@ -21,7 +21,7 @@ describe Projects::ProjectMembersController do context 'when user does not have enough rights' do before do - project.team << [user, :developer] + project.add_developer(user) end it 'returns 404' do @@ -37,7 +37,7 @@ describe Projects::ProjectMembersController do context 'when user has enough rights' do before do - project.team << [user, :master] + project.add_master(user) end it 'adds user to members' do @@ -106,7 +106,7 @@ describe Projects::ProjectMembersController do context 'when member is found' do context 'when user does not have enough rights' do before do - project.team << [user, :developer] + project.add_developer(user) end it 'returns 404' do @@ -121,7 +121,7 @@ describe Projects::ProjectMembersController do context 'when user has enough rights' do before do - project.team << [user, :master] + project.add_master(user) end it '[HTML] removes user from members' do @@ -164,7 +164,7 @@ describe Projects::ProjectMembersController do context 'when member is found' do context 'and is not an owner' do before do - project.team << [user, :developer] + project.add_developer(user) end it 'removes user from members' do @@ -181,7 +181,7 @@ describe Projects::ProjectMembersController do let(:project) { create(:project, namespace: user.namespace) } before do - project.team << [user, :master] + project.add_master(user) end it 'cannot remove himself from the project' do @@ -248,7 +248,7 @@ describe Projects::ProjectMembersController do context 'when member is found' do context 'when user does not have enough rights' do before do - project.team << [user, :developer] + project.add_developer(user) end it 'returns 404' do @@ -263,7 +263,7 @@ describe Projects::ProjectMembersController do context 'when user has enough rights' do before do - project.team << [user, :master] + project.add_master(user) end it 'adds user to members' do @@ -285,8 +285,8 @@ describe Projects::ProjectMembersController do let(:member) { create(:user) } before do - project.team << [user, :master] - another_project.team << [member, :guest] + project.add_master(user) + another_project.add_guest(member) sign_in(user) end @@ -300,7 +300,7 @@ describe Projects::ProjectMembersController do context 'when user can access source project members' do before do - another_project.team << [user, :guest] + another_project.add_guest(user) end include_context 'import applied' @@ -332,7 +332,7 @@ describe Projects::ProjectMembersController do context 'when creating owner' do before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end @@ -348,7 +348,7 @@ describe Projects::ProjectMembersController do context 'when create master' do before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/controllers/projects/refs_controller_spec.rb b/spec/controllers/projects/refs_controller_spec.rb index 748ae040928..ceaffd92623 100644 --- a/spec/controllers/projects/refs_controller_spec.rb +++ b/spec/controllers/projects/refs_controller_spec.rb @@ -6,7 +6,7 @@ describe Projects::RefsController do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) end describe 'GET #logs_tree' do diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb index 358f26dfb02..fc1619acec6 100644 --- a/spec/controllers/projects/releases_controller_spec.rb +++ b/spec/controllers/projects/releases_controller_spec.rb @@ -7,7 +7,7 @@ describe Projects::ReleasesController do let!(:tag) { release.tag } before do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) end diff --git a/spec/controllers/projects/repositories_controller_spec.rb b/spec/controllers/projects/repositories_controller_spec.rb index 8b777eb68ca..04d16e98913 100644 --- a/spec/controllers/projects/repositories_controller_spec.rb +++ b/spec/controllers/projects/repositories_controller_spec.rb @@ -17,7 +17,7 @@ describe Projects::RepositoriesController do let(:user) { create(:user) } before do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) end diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb index a907da2b60f..847ac6f2be0 100644 --- a/spec/controllers/projects/services_controller_spec.rb +++ b/spec/controllers/projects/services_controller_spec.rb @@ -9,7 +9,7 @@ describe Projects::ServicesController do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) end describe '#test' do @@ -114,5 +114,41 @@ describe Projects::ServicesController do expect(flash[:notice]).to eq 'HipChat settings saved, but not activated.' end end + + context 'with a deprecated service' do + let(:service) { create(:kubernetes_service, project: project) } + + before do + put :update, + namespace_id: project.namespace, project_id: project, id: service.to_param, service: { namespace: 'updated_namespace' } + end + + it 'should not update the service' do + service.reload + expect(service.namespace).not_to eq('updated_namespace') + end + end + end + + describe "GET #edit" do + before do + get :edit, namespace_id: project.namespace, project_id: project, id: service_id + end + + context 'with approved services' do + let(:service_id) { 'jira' } + + it 'should render edit page' do + expect(response).to be_success + end + end + + context 'with a deprecated service' do + let(:service_id) { 'kubernetes' } + + it 'should render edit page' do + expect(response).to be_success + end + end end end diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb index b8fe0f46f57..77a47f0ad13 100644 --- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb +++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb @@ -5,7 +5,7 @@ describe Projects::Settings::CiCdController do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/controllers/projects/settings/integrations_controller_spec.rb b/spec/controllers/projects/settings/integrations_controller_spec.rb index 3068837f394..77df9a6f567 100644 --- a/spec/controllers/projects/settings/integrations_controller_spec.rb +++ b/spec/controllers/projects/settings/integrations_controller_spec.rb @@ -5,7 +5,7 @@ describe Projects::Settings::IntegrationsController do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/controllers/projects/templates_controller_spec.rb b/spec/controllers/projects/templates_controller_spec.rb index 70e7f9ca96e..8fcfa3c9ecd 100644 --- a/spec/controllers/projects/templates_controller_spec.rb +++ b/spec/controllers/projects/templates_controller_spec.rb @@ -8,7 +8,7 @@ describe Projects::TemplatesController do let(:body) { JSON.parse(response.body) } before do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) end diff --git a/spec/controllers/projects/todos_controller_spec.rb b/spec/controllers/projects/todos_controller_spec.rb index 4622e27e60f..e2524be7724 100644 --- a/spec/controllers/projects/todos_controller_spec.rb +++ b/spec/controllers/projects/todos_controller_spec.rb @@ -20,7 +20,7 @@ describe Projects::TodosController do context 'when authorized' do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) end it 'creates todo for issue' do @@ -88,7 +88,7 @@ describe Projects::TodosController do context 'when authorized' do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) end it 'creates todo for merge request' do diff --git a/spec/controllers/projects/tree_controller_spec.rb b/spec/controllers/projects/tree_controller_spec.rb index 65b821c9486..d3188f054cf 100644 --- a/spec/controllers/projects/tree_controller_spec.rb +++ b/spec/controllers/projects/tree_controller_spec.rb @@ -7,7 +7,7 @@ describe Projects::TreeController do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) controller.instance_variable_set(:@project, project) end diff --git a/spec/controllers/projects/variables_controller_spec.rb b/spec/controllers/projects/variables_controller_spec.rb index d065cd00d00..9fde6544215 100644 --- a/spec/controllers/projects/variables_controller_spec.rb +++ b/spec/controllers/projects/variables_controller_spec.rb @@ -6,7 +6,7 @@ describe Projects::VariablesController do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) end describe 'POST #create' do diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index e61187fb518..5202ffdd8bb 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -102,7 +102,7 @@ describe ProjectsController do render_views before do - project.team << [user, :developer] + project.add_developer(user) project.project_feature.update_attribute(:repository_access_level, ProjectFeature::DISABLED) end @@ -437,7 +437,7 @@ describe ProjectsController do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true) end @@ -465,7 +465,7 @@ describe ProjectsController do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true) end diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb index 7e42e43345c..b1f601a19e5 100644 --- a/spec/controllers/uploads_controller_spec.rb +++ b/spec/controllers/uploads_controller_spec.rb @@ -265,13 +265,13 @@ describe UploadsController do context "when the user has access to the project" do before do - project.team << [user, :master] + project.add_master(user) end context "when the user is blocked" do before do user.block - project.team << [user, :master] + project.add_master(user) end it "redirects to the sign in page" do @@ -465,13 +465,13 @@ describe UploadsController do context "when the user has access to the project" do before do - project.team << [user, :master] + project.add_master(user) end context "when the user is blocked" do before do user.block - project.team << [user, :master] + project.add_master(user) end it "redirects to the sign in page" do diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 01ab59aa363..2898c4b119e 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -91,7 +91,7 @@ describe UsersController do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) push_data = Gitlab::DataBuilder::Push.build_sample(project, user) @@ -117,7 +117,7 @@ describe UsersController do allow_any_instance_of(User).to receive(:contributed_projects_ids).and_return([project.id]) sign_in(user) - project.team << [user, :developer] + project.add_developer(user) end it 'assigns @calendar_date' do diff --git a/spec/factories/keys.rb b/spec/factories/keys.rb index e6eb76f71d3..552b4b7e06e 100644 --- a/spec/factories/keys.rb +++ b/spec/factories/keys.rb @@ -21,12 +21,14 @@ FactoryBot.define do factory :rsa_key_2048 do key do - 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFf6RYK3qu/RKF/3ndJmL5xgMLp3O9' \ - '6x8lTay+QGZ0+9FnnAXMdUqBq/ZU6d/gyMB4IaW3nHzM1w049++yAB6UPCzMB8Uo27K5' \ - '/jyZCtj7Vm9PFNjF/8am1kp46c/SeYicQgQaSBdzIW3UDEa1Ef68qroOlvpi9PYZ/tA7' \ - 'M0YP0K5PXX+E36zaIRnJVMPT3f2k+GnrxtjafZrwFdpOP/Fol5BQLBgcsyiU+LM1SuaC' \ - 'rzd8c9vyaTA1CxrkxaZh+buAi0PmdDtaDrHd42gqZkXCKavyvgM5o2CkQ5LJHCgzpXy0' \ - '5qNFzmThBSkb+XtoxbyagBiGbVZtSVow6Xa7qewz= dummy@gitlab.com' + <<~KEY.delete("\n") + ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFf6RYK3qu/RKF/3ndJmL5xgMLp3O9 + 6x8lTay+QGZ0+9FnnAXMdUqBq/ZU6d/gyMB4IaW3nHzM1w049++yAB6UPCzMB8Uo27K5 + /jyZCtj7Vm9PFNjF/8am1kp46c/SeYicQgQaSBdzIW3UDEa1Ef68qroOlvpi9PYZ/tA7 + M0YP0K5PXX+E36zaIRnJVMPT3f2k+GnrxtjafZrwFdpOP/Fol5BQLBgcsyiU+LM1SuaC + rzd8c9vyaTA1CxrkxaZh+buAi0PmdDtaDrHd42gqZkXCKavyvgM5o2CkQ5LJHCgzpXy0 + 5qNFzmThBSkb+XtoxbyagBiGbVZtSVow6Xa7qewz= dummy@gitlab.com + KEY end factory :rsa_deploy_key_2048, class: 'DeployKey' @@ -34,37 +36,44 @@ FactoryBot.define do factory :dsa_key_2048 do key do - 'ssh-dss AAAAB3NzaC1kc3MAAAEBAO/3/NPLA/zSFkMOCaTtGo+uos1flfQ5f038Uk+G' \ - 'Y9AeLGzX+Srhw59GdVXmOQLYBrOt5HdGwqYcmLnE2VurUGmhtfeO5H+3p5pGJbkS0Gxp' \ - 'YH1HRO9lWsncF3Hh1w4lYsDjkclDiSTdfTuN8F4Kb3DXNnVSCieeonp+B25F/CXagyTQ' \ - '/pvNmHFeYgGCVdnBtFdi+xfxaZ8NKdPrGggzokbKHElDZQ4Xo5EpdcyLajgM7nB2r2Rz' \ - 'OrmeaevKi5lV68ehRa9Yyrb7vxvwiwBwOgqR/mnN7Gnaq1jUdmJY+ct04Qwx37f5jvhv' \ - '5gA4U40SGMoiHM8RFIN7Ksz0jsyX73MAAAAVALRWOfjfzHpK7KLz4iqDvvTUAevJAAAB' \ - 'AEa9NZ+6y9iQ5erGsdfLTXFrhSefTG0NhghoO/5IFkSGfd8V7kzTvCHaFrcfpEA5kP8t' \ - 'poeOG0TASB6tgGOxm1Bq4Wncry5RORBPJlAVpDGRcvZ931ddH7IgltEInS6za2uH6F/1' \ - 'M1QfKePSLr6xJ1ZLYfP0Og5KTp1x6yMQvfwV0a+XdA+EPgaJWLWp/pWwKWa0oLUgjsIH' \ - 'MYzuOGh5c708uZrmkzqvgtW2NgXhcIroRgynT3IfI2lP2rqqb3uuuE/qH5UCUFO+Dc3H' \ - 'nAFNeQDT/M25AERdPYBAY5a+iPjIgO+jT7BfmfByT+AZTqZySrCyc7nNZL3YgGLK0l6A' \ - '1GgAAAEBAN9FpFOdIXE+YEZhKl1vPmbcn+b1y5zOl6N4x1B7Q8pD/pLMziWROIS8uLzb' \ - 'aZ0sMIWezHIkxuo1iROMeT+jtCubn7ragaN6AX7nMpxYUH9+mYZZs/fyElt6wCviVhTI' \ - 'zM+u7VdQsnZttOOlQfogHdL+SpeAft0DsfJjlcgQnsLlHQKv6aPqCPYUST2nE7RyW/Ex' \ - 'PrMxLtOWt0/j8RYHbwwqvyeZqBz3ESBgrS9c5tBdBfauwYUV/E7gPLOU3OZFw9ue7o+z' \ - 'wzoTZqW6Xouy5wtWvSLQSLT5XwOslmQz8QMBxD0AQyDfEFGsBCWzmbTgKv9uqrBjubsS' \ - 'Taja+Cf9kMo== dummy@gitlab.com' + <<~KEY.delete("\n") + ssh-dss AAAAB3NzaC1kc3MAAAEBAO/3/NPLA/zSFkMOCaTtGo+uos1flfQ5f038Uk+G + Y9AeLGzX+Srhw59GdVXmOQLYBrOt5HdGwqYcmLnE2VurUGmhtfeO5H+3p5pGJbkS0Gxp + YH1HRO9lWsncF3Hh1w4lYsDjkclDiSTdfTuN8F4Kb3DXNnVSCieeonp+B25F/CXagyTQ + /pvNmHFeYgGCVdnBtFdi+xfxaZ8NKdPrGggzokbKHElDZQ4Xo5EpdcyLajgM7nB2r2Rz + OrmeaevKi5lV68ehRa9Yyrb7vxvwiwBwOgqR/mnN7Gnaq1jUdmJY+ct04Qwx37f5jvhv + 5gA4U40SGMoiHM8RFIN7Ksz0jsyX73MAAAAVALRWOfjfzHpK7KLz4iqDvvTUAevJAAAB + AEa9NZ+6y9iQ5erGsdfLTXFrhSefTG0NhghoO/5IFkSGfd8V7kzTvCHaFrcfpEA5kP8t + poeOG0TASB6tgGOxm1Bq4Wncry5RORBPJlAVpDGRcvZ931ddH7IgltEInS6za2uH6F/1 + M1QfKePSLr6xJ1ZLYfP0Og5KTp1x6yMQvfwV0a+XdA+EPgaJWLWp/pWwKWa0oLUgjsIH + MYzuOGh5c708uZrmkzqvgtW2NgXhcIroRgynT3IfI2lP2rqqb3uuuE/qH5UCUFO+Dc3H + nAFNeQDT/M25AERdPYBAY5a+iPjIgO+jT7BfmfByT+AZTqZySrCyc7nNZL3YgGLK0l6A + 1GgAAAEBAN9FpFOdIXE+YEZhKl1vPmbcn+b1y5zOl6N4x1B7Q8pD/pLMziWROIS8uLzb + aZ0sMIWezHIkxuo1iROMeT+jtCubn7ragaN6AX7nMpxYUH9+mYZZs/fyElt6wCviVhTI + zM+u7VdQsnZttOOlQfogHdL+SpeAft0DsfJjlcgQnsLlHQKv6aPqCPYUST2nE7RyW/Ex + PrMxLtOWt0/j8RYHbwwqvyeZqBz3ESBgrS9c5tBdBfauwYUV/E7gPLOU3OZFw9ue7o+z + wzoTZqW6Xouy5wtWvSLQSLT5XwOslmQz8QMBxD0AQyDfEFGsBCWzmbTgKv9uqrBjubsS + Taja+Cf9kMo== dummy@gitlab.com + KEY end end factory :ecdsa_key_256 do key do - 'ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYA' \ - 'AABBBJZmkzTgY0fiCQ+DVReyH/fFwTFz0XoR3RUO0u+199H19KFw7mNPxRSMOVS7tEtO' \ - 'Nj3Q7FcZXfqthHvgAzDiHsc= dummy@gitlab.com' + <<~KEY.delete("\n") + ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYA + AABBBJZmkzTgY0fiCQ+DVReyH/fFwTFz0XoR3RUO0u+199H19KFw7mNPxRSMOVS7tEtO + Nj3Q7FcZXfqthHvgAzDiHsc= dummy@gitlab.com + KEY end end factory :ed25519_key_256 do key do - 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIETnVTgzqC1gatgSlC4zH6aYt2CAQzgJOhDRvf59ohL6 dummy@gitlab.com' + <<~KEY.delete("\n") + ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIETnVTgzqC1gatgSlC4zH6aYt2CAQzgJ + OhDRvf59ohL6 dummy@gitlab.com + KEY end end end diff --git a/spec/factories/services.rb b/spec/factories/services.rb index 4b0377967c7..110ef33c6f7 100644 --- a/spec/factories/services.rb +++ b/spec/factories/services.rb @@ -18,6 +18,7 @@ FactoryBot.define do factory :kubernetes_service do project + type 'KubernetesService' active true properties({ api_url: 'https://kubernetes.example.com', diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb index 94b12105088..d02ac6c2e2a 100644 --- a/spec/features/admin/admin_projects_spec.rb +++ b/spec/features/admin/admin_projects_spec.rb @@ -88,7 +88,7 @@ describe "Admin::Projects" do describe 'add admin himself to a project' do before do - project.team << [user, :master] + project.add_master(user) end it 'adds admin a to a project as developer', :js do @@ -110,8 +110,8 @@ describe "Admin::Projects" do describe 'admin remove himself from a project' do before do - project.team << [user, :master] - project.team << [current_user, :developer] + project.add_master(user) + project.add_developer(current_user) end it 'removes admin from the project' do diff --git a/spec/features/atom/dashboard_issues_spec.rb b/spec/features/atom/dashboard_issues_spec.rb index 89c9d377003..d673bac4995 100644 --- a/spec/features/atom/dashboard_issues_spec.rb +++ b/spec/features/atom/dashboard_issues_spec.rb @@ -8,8 +8,8 @@ describe "Dashboard Issues Feed" do let!(:project2) { create(:project) } before do - project1.team << [user, :master] - project2.team << [user, :master] + project1.add_master(user) + project2.add_master(user) end describe "atom feed" do diff --git a/spec/features/atom/dashboard_spec.rb b/spec/features/atom/dashboard_spec.rb index 2c0c331b6db..c6683bb3bc9 100644 --- a/spec/features/atom/dashboard_spec.rb +++ b/spec/features/atom/dashboard_spec.rb @@ -26,7 +26,7 @@ describe "Dashboard Feed" do let(:note) { create(:note, noteable: issue, author: user, note: 'Bug confirmed', project: project) } before do - project.team << [user, :master] + project.add_master(user) issue_event(issue, user) note_event(note, user) visit dashboard_projects_path(:atom, rss_token: user.rss_token) diff --git a/spec/features/atom/issues_spec.rb b/spec/features/atom/issues_spec.rb index 4102ac0588a..525ce23aa56 100644 --- a/spec/features/atom/issues_spec.rb +++ b/spec/features/atom/issues_spec.rb @@ -9,7 +9,7 @@ describe 'Issues Feed' do let!(:issue) { create(:issue, author: user, assignees: [assignee], project: project) } before do - project.team << [user, :developer] + project.add_developer(user) group.add_developer(user) end diff --git a/spec/features/atom/users_spec.rb b/spec/features/atom/users_spec.rb index 2b934d81674..782f42aab04 100644 --- a/spec/features/atom/users_spec.rb +++ b/spec/features/atom/users_spec.rb @@ -47,7 +47,7 @@ describe "User Feed" do let!(:push_event_payload) { create(:push_event_payload, event: push_event) } before do - project.team << [user, :master] + project.add_master(user) issue_event(issue, user) note_event(note, user) merge_request_event(merge_request, user) diff --git a/spec/features/auto_deploy_spec.rb b/spec/features/auto_deploy_spec.rb index 7a395f62511..9aef68b7156 100644 --- a/spec/features/auto_deploy_spec.rb +++ b/spec/features/auto_deploy_spec.rb @@ -52,7 +52,7 @@ describe 'Auto deploy' do context 'when user configured kubernetes from Integration > Kubernetes' do before do create :kubernetes_service, project: project - project.team << [user, :master] + project.add_master(user) sign_in user end @@ -65,7 +65,7 @@ describe 'Auto deploy' do context 'when user configured kubernetes from CI/CD > Clusters' do before do create(:cluster, :provided_by_gcp, projects: [project]) - project.team << [user, :master] + project.add_master(user) sign_in user end diff --git a/spec/features/boards/add_issues_modal_spec.rb b/spec/features/boards/add_issues_modal_spec.rb index e4cfcea45a5..18901a954cc 100644 --- a/spec/features/boards/add_issues_modal_spec.rb +++ b/spec/features/boards/add_issues_modal_spec.rb @@ -12,7 +12,7 @@ describe 'Issue Boards add issue modal', :js do let!(:issue2) { create(:issue, project: project, title: 'hij', description: 'klm') } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index e8d779f5772..3876d1c76d7 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -11,8 +11,8 @@ describe 'Issue Boards', :js do let!(:user2) { create(:user) } before do - project.team << [user, :master] - project.team << [user2, :master] + project.add_master(user) + project.add_master(user2) set_cookie('sidebar_collapsed', 'true') @@ -551,7 +551,7 @@ describe 'Issue Boards', :js do let(:user_guest) { create(:user) } before do - project.team << [user_guest, :guest] + project.add_guest(user_guest) sign_out(:user) sign_in(user_guest) visit project_board_path(project, board) diff --git a/spec/features/boards/issue_ordering_spec.rb b/spec/features/boards/issue_ordering_spec.rb index 4cbb48e2e6e..5abd02dbb48 100644 --- a/spec/features/boards/issue_ordering_spec.rb +++ b/spec/features/boards/issue_ordering_spec.rb @@ -13,7 +13,7 @@ describe 'Issue Boards', :js do let!(:issue3) { create(:labeled_issue, project: project, title: 'testing 3', labels: [label], relative_position: 1) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/boards/modal_filter_spec.rb b/spec/features/boards/modal_filter_spec.rb index 422d96175f7..5907bb0840f 100644 --- a/spec/features/boards/modal_filter_spec.rb +++ b/spec/features/boards/modal_filter_spec.rb @@ -10,7 +10,7 @@ describe 'Issue Boards add issue modal filtering', :js do let!(:issue1) { create(:issue, project: project) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end @@ -76,7 +76,7 @@ describe 'Issue Boards add issue modal filtering', :js do let!(:issue) { create(:issue, project: project, author: user2) } before do - project.team << [user2, :developer] + project.add_developer(user2) visit_board end @@ -99,7 +99,7 @@ describe 'Issue Boards add issue modal filtering', :js do let!(:issue) { create(:issue, project: project, assignees: [user2]) } before do - project.team << [user2, :developer] + project.add_developer(user2) visit_board end diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb index 5ac4d87e90b..6769acb7c9c 100644 --- a/spec/features/boards/new_issue_spec.rb +++ b/spec/features/boards/new_issue_spec.rb @@ -8,7 +8,7 @@ describe 'Issue Boards new issue', :js do context 'authorized user' do before do - project.team << [user, :master] + project.add_master(user) sign_in(user) diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb index 77dcdf89f37..a28b8905b65 100644 --- a/spec/features/commits_spec.rb +++ b/spec/features/commits_spec.rb @@ -26,7 +26,7 @@ describe 'Commits' do let!(:status) { create(:generic_commit_status, pipeline: pipeline) } before do - project.team << [user, :reporter] + project.add_reporter(user) end describe 'Commit builds' do @@ -51,7 +51,7 @@ describe 'Commits' do context 'when logged as developer' do before do - project.team << [user, :developer] + project.add_developer(user) end describe 'Project commits' do @@ -145,7 +145,7 @@ describe 'Commits' do context "when logged as reporter" do before do - project.team << [user, :reporter] + project.add_reporter(user) build.update_attributes(legacy_artifacts_file: artifacts_file) visit pipeline_path(pipeline) end @@ -188,7 +188,7 @@ describe 'Commits' do let(:branch_name) { 'master' } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) visit project_commits_path(project, branch_name) end diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb index 177cd50dd72..d36954954b6 100644 --- a/spec/features/cycle_analytics_spec.rb +++ b/spec/features/cycle_analytics_spec.rb @@ -95,7 +95,7 @@ feature 'Cycle Analytics', :js do before do user.update_attribute(:preferred_language, 'es') - project.team << [user, :master] + project.add_master(user) sign_in(user) visit project_cycle_analytics_path(project) wait_for_requests diff --git a/spec/features/dashboard/activity_spec.rb b/spec/features/dashboard/activity_spec.rb index bd115785646..a74a8aac2b2 100644 --- a/spec/features/dashboard/activity_spec.rb +++ b/spec/features/dashboard/activity_spec.rb @@ -24,6 +24,7 @@ feature 'Dashboard > Activity' do end let(:note) { create(:note, project: project, noteable: merge_request) } + let(:milestone) { create(:milestone, :active, project: project, title: '1.0') } let!(:push_event) do event = create(:push_event, project: project, author: user) @@ -54,6 +55,10 @@ feature 'Dashboard > Activity' do create(:event, :commented, project: project, target: note, author: user) end + let!(:milestone_event) do + create(:event, :closed, project: project, target: milestone, author: user) + end + before do project.add_master(user) @@ -68,6 +73,7 @@ feature 'Dashboard > Activity' do expect(page).to have_content('accepted') expect(page).to have_content('closed') expect(page).to have_content('commented on') + expect(page).to have_content('closed milestone') end end @@ -107,6 +113,7 @@ feature 'Dashboard > Activity' do expect(page).not_to have_content('accepted') expect(page).to have_content('closed') expect(page).not_to have_content('commented on') + expect(page).to have_content('closed milestone') end end diff --git a/spec/features/dashboard/archived_projects_spec.rb b/spec/features/dashboard/archived_projects_spec.rb index e8d699ff5e0..b36231fd78b 100644 --- a/spec/features/dashboard/archived_projects_spec.rb +++ b/spec/features/dashboard/archived_projects_spec.rb @@ -6,8 +6,8 @@ RSpec.describe 'Dashboard Archived Project' do let(:archived_project) { create(:project, :archived) } before do - project.team << [user, :master] - archived_project.team << [user, :master] + project.add_master(user) + archived_project.add_master(user) sign_in(user) diff --git a/spec/features/dashboard/datetime_on_tooltips_spec.rb b/spec/features/dashboard/datetime_on_tooltips_spec.rb index 349f9a47112..089c388636d 100644 --- a/spec/features/dashboard/datetime_on_tooltips_spec.rb +++ b/spec/features/dashboard/datetime_on_tooltips_spec.rb @@ -8,7 +8,7 @@ feature 'Tooltips on .timeago dates', :js do context 'on the activity tab' do before do - project.team << [user, :master] + project.add_master(user) Event.create( project: project, author_id: user.id, action: Event::JOINED, updated_at: created_date, created_at: created_date) @@ -27,7 +27,7 @@ feature 'Tooltips on .timeago dates', :js do context 'on the snippets tab' do before do - project.team << [user, :master] + project.add_master(user) create(:snippet, author: user, updated_at: created_date, created_at: created_date) sign_in user diff --git a/spec/features/dashboard/groups_list_spec.rb b/spec/features/dashboard/groups_list_spec.rb index d92c002b4e7..a71020002dc 100644 --- a/spec/features/dashboard/groups_list_spec.rb +++ b/spec/features/dashboard/groups_list_spec.rb @@ -94,22 +94,14 @@ feature 'Dashboard Groups page', :js do end it 'can toggle parent group' do - # Collapsed by default - expect(page).not_to have_selector("#group-#{group.id} .fa-caret-down", count: 1) - expect(page).to have_selector("#group-#{group.id} .fa-caret-right") - # expand click_group_caret(group) - expect(page).to have_selector("#group-#{group.id} .fa-caret-down") - expect(page).not_to have_selector("#group-#{group.id} .fa-caret-right", count: 1) expect(page).to have_selector("#group-#{group.id} #group-#{subgroup.id}") # collapse click_group_caret(group) - expect(page).not_to have_selector("#group-#{group.id} .fa-caret-down", count: 1) - expect(page).to have_selector("#group-#{group.id} .fa-caret-right") expect(page).not_to have_selector("#group-#{group.id} #group-#{subgroup.id}") end end diff --git a/spec/features/dashboard/issues_spec.rb b/spec/features/dashboard/issues_spec.rb index 5b4c00b3c7e..54652e2d849 100644 --- a/spec/features/dashboard/issues_spec.rb +++ b/spec/features/dashboard/issues_spec.rb @@ -12,7 +12,7 @@ RSpec.describe 'Dashboard Issues' do let!(:other_issue) { create :issue, project: project } before do - [project, project_with_issues_disabled].each { |project| project.team << [current_user, :master] } + [project, project_with_issues_disabled].each { |project| project.add_master(current_user) } sign_in(current_user) visit issues_dashboard_path(assignee_id: current_user.id) end diff --git a/spec/features/dashboard/milestones_spec.rb b/spec/features/dashboard/milestones_spec.rb index 41d37376cfb..7787772a958 100644 --- a/spec/features/dashboard/milestones_spec.rb +++ b/spec/features/dashboard/milestones_spec.rb @@ -16,7 +16,7 @@ feature 'Dashboard > Milestones' do let(:project) { create(:project, namespace: user.namespace) } let!(:milestone) { create(:milestone, project: project) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) visit dashboard_milestones_path end diff --git a/spec/features/dashboard/project_member_activity_index_spec.rb b/spec/features/dashboard/project_member_activity_index_spec.rb index 8f96899fb4f..6c3093607b0 100644 --- a/spec/features/dashboard/project_member_activity_index_spec.rb +++ b/spec/features/dashboard/project_member_activity_index_spec.rb @@ -5,7 +5,7 @@ feature 'Project member activity', :js do let(:project) { create(:project, :public, name: 'x', namespace: user.namespace) } before do - project.team << [user, :master] + project.add_master(user) end def visit_activities_and_wait_with_event(event_type) diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb index fbf8b5c0db6..586c7b48d0b 100644 --- a/spec/features/dashboard/projects_spec.rb +++ b/spec/features/dashboard/projects_spec.rb @@ -6,7 +6,7 @@ feature 'Dashboard Projects' do let(:project2) { create(:project, :public, name: 'Community project') } before do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) end diff --git a/spec/features/dashboard/todos/todos_filtering_spec.rb b/spec/features/dashboard/todos/todos_filtering_spec.rb index ad0f132da8c..2fc34301d51 100644 --- a/spec/features/dashboard/todos/todos_filtering_spec.rb +++ b/spec/features/dashboard/todos/todos_filtering_spec.rb @@ -15,8 +15,8 @@ feature 'Dashboard > User filters todos', :js do create(:todo, user: user_1, author: user_2, project: project_1, target: issue, action: 1) create(:todo, user: user_1, author: user_1, project: project_2, target: merge_request, action: 2) - project_1.team << [user_1, :developer] - project_2.team << [user_1, :developer] + project_1.add_developer(user_1) + project_2.add_developer(user_1) sign_in(user_1) visit dashboard_todos_path end @@ -66,8 +66,8 @@ feature 'Dashboard > User filters todos', :js do create(:todo, user: user_1, author: user_3, project: project_1, target: issue, action: 1, state: :done) create(:todo, user: user_1, author: user_4, project: project_2, target: merge_request, action: 2, state: :done) - project_1.team << [user_3, :developer] - project_2.team << [user_4, :developer] + project_1.add_developer(user_3) + project_2.add_developer(user_4) visit dashboard_todos_path(state: 'done') diff --git a/spec/features/dashboard/todos/todos_sorting_spec.rb b/spec/features/dashboard/todos/todos_sorting_spec.rb index b7d39a872b0..10e3ad843fd 100644 --- a/spec/features/dashboard/todos/todos_sorting_spec.rb +++ b/spec/features/dashboard/todos/todos_sorting_spec.rb @@ -9,7 +9,7 @@ feature 'Dashboard > User sorts todos' do let(:label_3) { create(:label, title: 'label_3', project: project, priority: 3) } before do - project.team << [user, :developer] + project.add_developer(user) end context 'sort options' do diff --git a/spec/features/dashboard/user_filters_projects_spec.rb b/spec/features/dashboard/user_filters_projects_spec.rb index c352b6ded14..92f4d4b854c 100644 --- a/spec/features/dashboard/user_filters_projects_spec.rb +++ b/spec/features/dashboard/user_filters_projects_spec.rb @@ -7,14 +7,14 @@ describe 'Dashboard > User filters projects' do let(:project2) { create(:project, name: 'Treasure', namespace: user2.namespace) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end describe 'filtering personal projects' do before do - project2.team << [user, :developer] + project2.add_developer(user) visit dashboard_projects_path end diff --git a/spec/features/global_search_spec.rb b/spec/features/global_search_spec.rb index f04e13adba7..4f575613848 100644 --- a/spec/features/global_search_spec.rb +++ b/spec/features/global_search_spec.rb @@ -5,7 +5,7 @@ feature 'Global search' do let(:project) { create(:project, namespace: user.namespace) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/issues/award_emoji_spec.rb b/spec/features/issues/award_emoji_spec.rb index 850b35c4467..1131e1711bf 100644 --- a/spec/features/issues/award_emoji_spec.rb +++ b/spec/features/issues/award_emoji_spec.rb @@ -11,7 +11,7 @@ describe 'Awards Emoji' do context 'authorized user' do before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/issues/bulk_assignment_labels_spec.rb b/spec/features/issues/bulk_assignment_labels_spec.rb index fa4d3a55c62..587ece22ec7 100644 --- a/spec/features/issues/bulk_assignment_labels_spec.rb +++ b/spec/features/issues/bulk_assignment_labels_spec.rb @@ -11,7 +11,7 @@ feature 'Issues > Labels bulk assignment' do context 'as an allowed user', :js do before do - project.team << [user, :master] + project.add_master(user) sign_in user end diff --git a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb index 822ba48e005..e0466aaf422 100644 --- a/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb +++ b/spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb @@ -8,7 +8,7 @@ feature 'Resolving all open discussions in a merge request from an issue', :js d describe 'as a user with access to the project' do before do - project.team << [user, :master] + project.add_master(user) sign_in user visit project_merge_request_path(project, merge_request) end @@ -81,7 +81,7 @@ feature 'Resolving all open discussions in a merge request from an issue', :js d describe 'as a reporter' do before do - project.team << [user, :reporter] + project.add_reporter(user) sign_in user visit new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid) end diff --git a/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb index f0bed85595c..34beb282bad 100644 --- a/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb +++ b/spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb @@ -8,7 +8,7 @@ feature 'Resolve an open discussion in a merge request by creating an issue' do describe 'As a user with access to the project' do before do - project.team << [user, :master] + project.add_master(user) sign_in user visit project_merge_request_path(project, merge_request) end @@ -65,7 +65,7 @@ feature 'Resolve an open discussion in a merge request by creating an issue' do describe 'as a reporter' do before do - project.team << [user, :reporter] + project.add_reporter(user) sign_in user visit new_project_issue_path(project, merge_request_to_resolve_discussions_of: merge_request.iid, discussion_to_resolve: discussion.id) diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb index 2e4a25ee15d..cbd0949c192 100644 --- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb @@ -20,9 +20,9 @@ describe 'Dropdown assignee', :js do end before do - project.team << [user, :master] - project.team << [user_john, :master] - project.team << [user_jacob, :master] + project.add_master(user) + project.add_master(user_john) + project.add_master(user_jacob) sign_in(user) create(:issue, project: project) @@ -222,7 +222,7 @@ describe 'Dropdown assignee', :js do expect(initial_size).to be > 0 new_user = create(:user) - project.team << [new_user, :master] + project.add_master(new_user) find('.filtered-search-box .clear-search').click filtered_search.set('assignee') filtered_search.send_keys(':') diff --git a/spec/features/issues/filtered_search/dropdown_author_spec.rb b/spec/features/issues/filtered_search/dropdown_author_spec.rb index 2fb5e7cdba4..70b4f11410d 100644 --- a/spec/features/issues/filtered_search/dropdown_author_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_author_spec.rb @@ -28,9 +28,9 @@ describe 'Dropdown author', :js do end before do - project.team << [user, :master] - project.team << [user_john, :master] - project.team << [user_jacob, :master] + project.add_master(user) + project.add_master(user_john) + project.add_master(user_jacob) sign_in(user) create(:issue, project: project) @@ -195,7 +195,7 @@ describe 'Dropdown author', :js do expect(initial_size).to be > 0 new_user = create(:user) - project.team << [new_user, :master] + project.add_master(new_user) find('.filtered-search-box .clear-search').click filtered_search.set('author') send_keys_to_filtered_search(':') diff --git a/spec/features/issues/filtered_search/dropdown_emoji_spec.rb b/spec/features/issues/filtered_search/dropdown_emoji_spec.rb index 8db435634fd..436625a6f7b 100644 --- a/spec/features/issues/filtered_search/dropdown_emoji_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_emoji_spec.rb @@ -28,7 +28,7 @@ describe 'Dropdown emoji', :js do end before do - project.team << [user, :master] + project.add_master(user) create_list(:award_emoji, 2, user: user, name: 'thumbsup') create_list(:award_emoji, 1, user: user, name: 'thumbsdown') create_list(:award_emoji, 3, user: user, name: 'star') diff --git a/spec/features/issues/filtered_search/dropdown_hint_spec.rb b/spec/features/issues/filtered_search/dropdown_hint_spec.rb index 0183495a1db..ef40dddfd3a 100644 --- a/spec/features/issues/filtered_search/dropdown_hint_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_hint_spec.rb @@ -13,7 +13,7 @@ describe 'Dropdown hint', :js do end before do - project.team << [user, :master] + project.add_master(user) create(:issue, project: project) end @@ -176,6 +176,7 @@ describe 'Dropdown hint', :js do it 'reuses existing author text' do filtered_search.send_keys('author:') filtered_search.send_keys(:backspace) + filtered_search.send_keys(:backspace) click_hint('author') expect_tokens([{ name: 'author' }]) @@ -185,6 +186,7 @@ describe 'Dropdown hint', :js do it 'reuses existing assignee text' do filtered_search.send_keys('assignee:') filtered_search.send_keys(:backspace) + filtered_search.send_keys(:backspace) click_hint('assignee') expect_tokens([{ name: 'assignee' }]) @@ -194,6 +196,7 @@ describe 'Dropdown hint', :js do it 'reuses existing milestone text' do filtered_search.send_keys('milestone:') filtered_search.send_keys(:backspace) + filtered_search.send_keys(:backspace) click_hint('milestone') expect_tokens([{ name: 'milestone' }]) @@ -203,6 +206,7 @@ describe 'Dropdown hint', :js do it 'reuses existing label text' do filtered_search.send_keys('label:') filtered_search.send_keys(:backspace) + filtered_search.send_keys(:backspace) click_hint('label') expect_tokens([{ name: 'label' }]) @@ -212,6 +216,7 @@ describe 'Dropdown hint', :js do it 'reuses existing emoji text' do filtered_search.send_keys('my-reaction:') filtered_search.send_keys(:backspace) + filtered_search.send_keys(:backspace) click_hint('my-reaction') expect_tokens([{ name: 'my-reaction' }]) diff --git a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb index 031eb06723a..94710c2f71f 100644 --- a/spec/features/issues/filtered_search/dropdown_milestone_spec.rb +++ b/spec/features/issues/filtered_search/dropdown_milestone_spec.rb @@ -29,7 +29,7 @@ describe 'Dropdown milestone', :js do end before do - project.team << [user, :master] + project.add_master(user) sign_in(user) create(:issue, project: project) diff --git a/spec/features/issues/filtered_search/search_bar_spec.rb b/spec/features/issues/filtered_search/search_bar_spec.rb index 88688422dc7..268590da599 100644 --- a/spec/features/issues/filtered_search/search_bar_spec.rb +++ b/spec/features/issues/filtered_search/search_bar_spec.rb @@ -8,7 +8,7 @@ describe 'Search bar', :js do let(:filtered_search) { find('.filtered-search') } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) create(:issue, project: project) diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb index 2db6f9a2982..faf14be4818 100644 --- a/spec/features/issues/form_spec.rb +++ b/spec/features/issues/form_spec.rb @@ -13,8 +13,8 @@ describe 'New/edit issue', :js do let!(:issue) { create(:issue, project: project, assignees: [user], milestone: milestone) } before do - project.team << [user, :master] - project.team << [user2, :master] + project.add_master(user) + project.add_master(user2) sign_in(user) end diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb index 6a9a80235c1..f2624f55c86 100644 --- a/spec/features/issues/gfm_autocomplete_spec.rb +++ b/spec/features/issues/gfm_autocomplete_spec.rb @@ -7,7 +7,7 @@ feature 'GFM autocomplete', :js do let(:issue) { create(:issue, project: project) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) visit project_issue_path(project, issue) diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb index a9de52bd8d5..a5c9d0bde5d 100644 --- a/spec/features/issues/issue_sidebar_spec.rb +++ b/spec/features/issues/issue_sidebar_spec.rb @@ -18,7 +18,7 @@ feature 'Issue Sidebar' do let(:issue2) { create(:issue, project: project, author: user2) } before do - project.team << [user, :developer] + project.add_developer(user) visit_issue(project, issue2) find('.block.assignee .edit-link').click @@ -78,7 +78,7 @@ feature 'Issue Sidebar' do context 'as a allowed user' do before do - project.team << [user, :developer] + project.add_developer(user) visit_issue(project, issue) end @@ -156,7 +156,7 @@ feature 'Issue Sidebar' do context 'as a guest' do before do - project.team << [user, :guest] + project.add_guest(user) visit_issue(project, issue) end diff --git a/spec/features/issues/move_spec.rb b/spec/features/issues/move_spec.rb index 17035b5501c..076a02150a4 100644 --- a/spec/features/issues/move_spec.rb +++ b/spec/features/issues/move_spec.rb @@ -13,7 +13,7 @@ feature 'issue move to another project' do context 'user does not have permission to move issue' do background do - old_project.team << [user, :guest] + old_project.add_guest(user) visit issue_path(issue) end @@ -31,8 +31,8 @@ feature 'issue move to another project' do let(:cross_reference) { old_project.to_reference(new_project) } background do - old_project.team << [user, :reporter] - new_project.team << [user, :reporter] + old_project.add_reporter(user) + new_project.add_reporter(user) visit issue_path(issue) end @@ -50,7 +50,7 @@ feature 'issue move to another project' do end scenario 'searching project dropdown', :js do - new_project_search.team << [user, :reporter] + new_project_search.add_reporter(user) find('.js-move-issue').click wait_for_requests @@ -66,7 +66,7 @@ feature 'issue move to another project' do context 'user does not have permission to move the issue to a project', :js do let!(:private_project) { create(:project, :private) } let(:another_project) { create(:project) } - background { another_project.team << [user, :guest] } + background { another_project.add_guest(user) } scenario 'browsing projects in projects select' do find('.js-move-issue').click diff --git a/spec/features/issues/notes_on_issues_spec.rb b/spec/features/issues/notes_on_issues_spec.rb index 05c93a19253..f08c73f947c 100644 --- a/spec/features/issues/notes_on_issues_spec.rb +++ b/spec/features/issues/notes_on_issues_spec.rb @@ -8,7 +8,7 @@ describe 'Create notes on issues', :js do let(:note_text) { "Check #{mention.to_reference}" } before do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) visit project_issue_path(project, issue) diff --git a/spec/features/issues/spam_issues_spec.rb b/spec/features/issues/spam_issues_spec.rb index d25231d624c..53706ef84bc 100644 --- a/spec/features/issues/spam_issues_spec.rb +++ b/spec/features/issues/spam_issues_spec.rb @@ -17,7 +17,7 @@ describe 'New issue', :js do recaptcha_private_key: 'test private key' ) - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/issues/todo_spec.rb b/spec/features/issues/todo_spec.rb index 29a2d38ae18..8e6493bbd93 100644 --- a/spec/features/issues/todo_spec.rb +++ b/spec/features/issues/todo_spec.rb @@ -6,7 +6,7 @@ feature 'Manually create a todo item from issue', :js do let!(:user) { create(:user)} before do - project.team << [user, :master] + project.add_master(user) sign_in(user) visit project_issue_path(project, issue) end diff --git a/spec/features/issues/update_issues_spec.rb b/spec/features/issues/update_issues_spec.rb index bcc6e9bab0f..7d6edc171f8 100644 --- a/spec/features/issues/update_issues_spec.rb +++ b/spec/features/issues/update_issues_spec.rb @@ -6,7 +6,7 @@ feature 'Multiple issue updating from issues#index', :js do let!(:user) { create(:user)} before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/issues/user_uses_slash_commands_spec.rb b/spec/features/issues/user_uses_slash_commands_spec.rb index c4c06ed514b..e711a191db2 100644 --- a/spec/features/issues/user_uses_slash_commands_spec.rb +++ b/spec/features/issues/user_uses_slash_commands_spec.rb @@ -12,7 +12,7 @@ feature 'Issues > User uses quick actions', :js do let(:project) { create(:project, :public) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) visit project_issue_path(project, issue) end @@ -50,7 +50,7 @@ feature 'Issues > User uses quick actions', :js do context 'when the current user cannot update the due date' do let(:guest) { create(:user) } before do - project.team << [guest, :guest] + project.add_guest(guest) gitlab_sign_out sign_in(guest) visit project_issue_path(project, issue) @@ -90,7 +90,7 @@ feature 'Issues > User uses quick actions', :js do context 'when the current user cannot update the due date' do let(:guest) { create(:user) } before do - project.team << [guest, :guest] + project.add_guest(guest) gitlab_sign_out sign_in(guest) visit project_issue_path(project, issue) @@ -138,7 +138,7 @@ feature 'Issues > User uses quick actions', :js do context 'when the current user cannot update the issue' do let(:guest) { create(:user) } before do - project.team << [guest, :guest] + project.add_guest(guest) gitlab_sign_out sign_in(guest) visit project_issue_path(project, issue) @@ -163,7 +163,7 @@ feature 'Issues > User uses quick actions', :js do let(:target_project) { create(:project, :public) } before do - target_project.team << [user, :master] + target_project.add_master(user) sign_in(user) visit project_issue_path(project, issue) end @@ -220,7 +220,7 @@ feature 'Issues > User uses quick actions', :js do let(:wontfix_target) { create(:label, project: target_project, title: 'wontfix') } before do - target_project.team << [user, :master] + target_project.add_master(user) sign_in(user) visit project_issue_path(project, issue) end diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index d1ff057a0c6..314bd19f586 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -25,7 +25,8 @@ describe 'Issues' do sign_in(user) user2 = create(:user) - project.team << [[user, user2], :developer] + project.add_developer(user) + project.add_developer(user2) end describe 'empty state' do @@ -383,7 +384,7 @@ describe 'Issues' do before do stub_incoming_email_setting(enabled: true, address: "p+%{key}@gl.ab") - project1.team << [user, :master] + project1.add_master(user) visit namespace_project_issues_path(user.namespace, project1) end @@ -491,7 +492,7 @@ describe 'Issues' do let(:guest) { create(:user) } before do - project.team << [[guest], :guest] + project.add_guest(guest) end it 'shows assignee text', :js do @@ -552,7 +553,7 @@ describe 'Issues' do let(:guest) { create(:user) } before do - project.team << [guest, :guest] + project.add_guest(guest) issue.milestone = milestone issue.save end diff --git a/spec/features/merge_requests/assign_issues_spec.rb b/spec/features/merge_requests/assign_issues_spec.rb index d49d145f254..b2d64a62b4f 100644 --- a/spec/features/merge_requests/assign_issues_spec.rb +++ b/spec/features/merge_requests/assign_issues_spec.rb @@ -9,7 +9,7 @@ feature 'Merge request issue assignment', :js do let(:service) { MergeRequests::AssignIssuesService.new(merge_request, user, user, project) } before do - project.team << [user, :developer] + project.add_developer(user) end def visit_merge_request(current_user = nil) diff --git a/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb index fbbfe7942be..892c32c8806 100644 --- a/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb +++ b/spec/features/merge_requests/check_if_mergeable_with_unresolved_discussions_spec.rb @@ -7,7 +7,7 @@ feature 'Check if mergeable with unresolved discussions', :js do before do sign_in user - project.team << [user, :master] + project.add_master(user) end context 'when project.only_allow_merge_if_all_discussions_are_resolved == true' do diff --git a/spec/features/merge_requests/cherry_pick_spec.rb b/spec/features/merge_requests/cherry_pick_spec.rb index 48f370c3ad4..205e38337d1 100644 --- a/spec/features/merge_requests/cherry_pick_spec.rb +++ b/spec/features/merge_requests/cherry_pick_spec.rb @@ -8,7 +8,7 @@ describe 'Cherry-pick Merge Requests', :js do before do sign_in user - project.team << [user, :master] + project.add_master(user) end context "Viewing a merged merge request" do diff --git a/spec/features/merge_requests/closes_issues_spec.rb b/spec/features/merge_requests/closes_issues_spec.rb index 4dd4e40f52c..55de9a01ed5 100644 --- a/spec/features/merge_requests/closes_issues_spec.rb +++ b/spec/features/merge_requests/closes_issues_spec.rb @@ -18,7 +18,7 @@ feature 'Merge Request closing issues message', :js do let(:merge_request_title) { 'Merge Request Title' } before do - project.team << [user, :master] + project.add_master(user) sign_in user diff --git a/spec/features/merge_requests/conflicts_spec.rb b/spec/features/merge_requests/conflicts_spec.rb index 4e2963c116d..05d99a2dff2 100644 --- a/spec/features/merge_requests/conflicts_spec.rb +++ b/spec/features/merge_requests/conflicts_spec.rb @@ -88,7 +88,7 @@ feature 'Merge request conflict resolution', :js do context 'can be resolved in the UI' do before do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) end @@ -175,7 +175,7 @@ feature 'Merge request conflict resolution', :js do let(:merge_request) { create_merge_request(source_branch) } before do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) visit project_merge_request_path(project, merge_request) diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb index db5ce2d11a8..486555ed5cd 100644 --- a/spec/features/merge_requests/create_new_mr_spec.rb +++ b/spec/features/merge_requests/create_new_mr_spec.rb @@ -5,7 +5,7 @@ feature 'Create New Merge Request', :js do let(:project) { create(:project, :public, :repository) } before do - project.team << [user, :master] + project.add_master(user) sign_in user end diff --git a/spec/features/merge_requests/created_from_fork_spec.rb b/spec/features/merge_requests/created_from_fork_spec.rb index ca2225318cd..53b62caf743 100644 --- a/spec/features/merge_requests/created_from_fork_spec.rb +++ b/spec/features/merge_requests/created_from_fork_spec.rb @@ -14,7 +14,7 @@ feature 'Merge request created from fork' do end background do - forked_project.team << [user, :master] + forked_project.add_master(user) sign_in user end diff --git a/spec/features/merge_requests/deleted_source_branch_spec.rb b/spec/features/merge_requests/deleted_source_branch_spec.rb index 7f69e82af4c..56aa0b2ede2 100644 --- a/spec/features/merge_requests/deleted_source_branch_spec.rb +++ b/spec/features/merge_requests/deleted_source_branch_spec.rb @@ -9,7 +9,7 @@ describe 'Deleted source branch', :js do before do sign_in user - merge_request.project.team << [user, :master] + merge_request.project.add_master(user) merge_request.update!(source_branch: 'this-branch-does-not-exist') visit project_merge_request_path(merge_request.project, merge_request) end diff --git a/spec/features/merge_requests/diff_notes_avatars_spec.rb b/spec/features/merge_requests/diff_notes_avatars_spec.rb index 9e816cf041b..ef8f314cc03 100644 --- a/spec/features/merge_requests/diff_notes_avatars_spec.rb +++ b/spec/features/merge_requests/diff_notes_avatars_spec.rb @@ -19,7 +19,7 @@ feature 'Diff note avatars', :js do let!(:note) { create(:diff_note_on_merge_request, project: project, noteable: merge_request, position: position) } before do - project.team << [user, :master] + project.add_master(user) sign_in user set_cookie('sidebar_collapsed', 'true') diff --git a/spec/features/merge_requests/diff_notes_resolve_spec.rb b/spec/features/merge_requests/diff_notes_resolve_spec.rb index 15d380b1bf4..9d4194d8ca0 100644 --- a/spec/features/merge_requests/diff_notes_resolve_spec.rb +++ b/spec/features/merge_requests/diff_notes_resolve_spec.rb @@ -18,7 +18,7 @@ feature 'Diff notes resolve', :js do context 'no discussions' do before do - project.team << [user, :master] + project.add_master(user) sign_in user note.destroy visit_merge_request @@ -32,7 +32,7 @@ feature 'Diff notes resolve', :js do context 'as authorized user' do before do - project.team << [user, :master] + project.add_master(user) sign_in user visit_merge_request end @@ -429,7 +429,7 @@ feature 'Diff notes resolve', :js do let(:guest) { create(:user) } before do - project.team << [guest, :guest] + project.add_guest(guest) sign_in guest end diff --git a/spec/features/merge_requests/edit_mr_spec.rb b/spec/features/merge_requests/edit_mr_spec.rb index 4362f8b3fcc..79be2fbf945 100644 --- a/spec/features/merge_requests/edit_mr_spec.rb +++ b/spec/features/merge_requests/edit_mr_spec.rb @@ -6,7 +6,7 @@ feature 'Edit Merge Request' do let(:merge_request) { create(:merge_request, :simple, source_project: project) } before do - project.team << [user, :master] + project.add_master(user) sign_in user diff --git a/spec/features/merge_requests/filter_by_milestone_spec.rb b/spec/features/merge_requests/filter_by_milestone_spec.rb index 8b9ff9be943..8db94352f73 100644 --- a/spec/features/merge_requests/filter_by_milestone_spec.rb +++ b/spec/features/merge_requests/filter_by_milestone_spec.rb @@ -14,7 +14,7 @@ feature 'Merge Request filtering by Milestone' do end before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/merge_requests/form_spec.rb b/spec/features/merge_requests/form_spec.rb index 1dcc1e139a0..1ebf762a006 100644 --- a/spec/features/merge_requests/form_spec.rb +++ b/spec/features/merge_requests/form_spec.rb @@ -12,8 +12,8 @@ describe 'New/edit merge request', :js do let!(:label2) { create(:label, project: project) } before do - project.team << [user, :master] - project.team << [user2, :master] + project.add_master(user) + project.add_master(user2) end context 'owned projects' do @@ -172,7 +172,7 @@ describe 'New/edit merge request', :js do context 'forked project' do before do - forked_project.team << [user, :master] + forked_project.add_master(user) sign_in(user) end diff --git a/spec/features/merge_requests/image_diff_notes_spec.rb b/spec/features/merge_requests/image_diff_notes_spec.rb index b53570835cb..d0f8da4e6cd 100644 --- a/spec/features/merge_requests/image_diff_notes_spec.rb +++ b/spec/features/merge_requests/image_diff_notes_spec.rb @@ -7,7 +7,7 @@ feature 'image diff notes', :js do let(:project) { create(:project, :public, :repository) } before do - project.team << [user, :master] + project.add_master(user) sign_in user # Stub helper to return any blob file as image from public app folder. diff --git a/spec/features/merge_requests/merge_commit_message_toggle_spec.rb b/spec/features/merge_requests/merge_commit_message_toggle_spec.rb index 82b2b56ef80..ddd034e1376 100644 --- a/spec/features/merge_requests/merge_commit_message_toggle_spec.rb +++ b/spec/features/merge_requests/merge_commit_message_toggle_spec.rb @@ -32,7 +32,7 @@ feature 'Clicking toggle commit message link', :js do end before do - project.team << [user, :master] + project.add_master(user) sign_in user diff --git a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb index 0b5a595acce..e1317b33ad1 100644 --- a/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb +++ b/spec/features/merge_requests/merge_immediately_with_pipeline_spec.rb @@ -19,7 +19,7 @@ feature 'Merge immediately', :js do end before do - project.team << [user, :master] + project.add_master(user) end context 'when there is active pipeline for merge request' do diff --git a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb index 91f207bd339..7d9282b932b 100644 --- a/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb +++ b/spec/features/merge_requests/only_allow_merge_if_build_succeeds_spec.rb @@ -7,7 +7,7 @@ feature 'Only allow merge requests to be merged if the pipeline succeeds', :js d before do sign_in merge_request.author - project.team << [merge_request.author, :master] + project.add_master(merge_request.author) end context 'project does not have CI enabled', :js do diff --git a/spec/features/merge_requests/pipelines_spec.rb b/spec/features/merge_requests/pipelines_spec.rb index 307c860eac4..04e3f4bdcf1 100644 --- a/spec/features/merge_requests/pipelines_spec.rb +++ b/spec/features/merge_requests/pipelines_spec.rb @@ -7,7 +7,7 @@ feature 'Pipelines for Merge Requests', :js do given(:project) { merge_request.target_project } before do - project.team << [user, :master] + project.add_master(user) sign_in user end diff --git a/spec/features/merge_requests/reset_filters_spec.rb b/spec/features/merge_requests/reset_filters_spec.rb index eed95816bdf..daca4422bf1 100644 --- a/spec/features/merge_requests/reset_filters_spec.rb +++ b/spec/features/merge_requests/reset_filters_spec.rb @@ -17,7 +17,7 @@ feature 'Merge requests filter clear button', :js do before do mr2.labels << bug - project.team << [user, :developer] + project.add_developer(user) end context 'when a milestone filter has been applied' do diff --git a/spec/features/merge_requests/target_branch_spec.rb b/spec/features/merge_requests/target_branch_spec.rb index bce36e05e57..d9f7a056dea 100644 --- a/spec/features/merge_requests/target_branch_spec.rb +++ b/spec/features/merge_requests/target_branch_spec.rb @@ -11,7 +11,7 @@ describe 'Target branch', :js do before do sign_in user - project.team << [user, :master] + project.add_master(user) end context 'when branch was deleted' do diff --git a/spec/features/merge_requests/update_merge_requests_spec.rb b/spec/features/merge_requests/update_merge_requests_spec.rb index c5498563b39..a96404b86ed 100644 --- a/spec/features/merge_requests/update_merge_requests_spec.rb +++ b/spec/features/merge_requests/update_merge_requests_spec.rb @@ -6,7 +6,7 @@ feature 'Multiple merge requests updating from merge_requests#index' do let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/merge_requests/user_uses_slash_commands_spec.rb b/spec/features/merge_requests/user_uses_slash_commands_spec.rb index ee0766f1192..5874bf5e187 100644 --- a/spec/features/merge_requests/user_uses_slash_commands_spec.rb +++ b/spec/features/merge_requests/user_uses_slash_commands_spec.rb @@ -15,7 +15,7 @@ feature 'Merge Requests > User uses quick actions', :js do let!(:milestone) { create(:milestone, project: project, title: 'ASAP') } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) visit project_merge_request_path(project, merge_request) end @@ -58,7 +58,7 @@ feature 'Merge Requests > User uses quick actions', :js do context 'when the current user cannot toggle the WIP prefix' do let(:guest) { create(:user) } before do - project.team << [guest, :guest] + project.add_guest(guest) sign_out(:user) sign_in(guest) visit project_merge_request_path(project, merge_request) @@ -104,7 +104,7 @@ feature 'Merge Requests > User uses quick actions', :js do context 'when the current user cannot merge the MR' do let(:guest) { create(:user) } before do - project.team << [guest, :guest] + project.add_guest(guest) sign_out(:user) sign_in(guest) visit project_merge_request_path(project, merge_request) @@ -134,7 +134,7 @@ feature 'Merge Requests > User uses quick actions', :js do before do sign_out(:user) - another_project.team << [user, :master] + another_project.add_master(user) sign_in(user) end @@ -188,7 +188,7 @@ feature 'Merge Requests > User uses quick actions', :js do context 'when current user can not change target branch' do let(:guest) { create(:user) } before do - project.team << [guest, :guest] + project.add_guest(guest) sign_out(:user) sign_in(guest) visit project_merge_request_path(project, merge_request) diff --git a/spec/features/merge_requests/widget_deployments_spec.rb b/spec/features/merge_requests/widget_deployments_spec.rb index 72a52c979b3..ec2da72ddff 100644 --- a/spec/features/merge_requests/widget_deployments_spec.rb +++ b/spec/features/merge_requests/widget_deployments_spec.rb @@ -13,7 +13,7 @@ feature 'Widget Deployments Header', :js do background do sign_in(user) - project.team << [user, role] + project.add_role(user, role) visit project_merge_request_path(project, merge_request) end diff --git a/spec/features/merge_requests/widget_spec.rb b/spec/features/merge_requests/widget_spec.rb index 3ee094c216e..8970586a160 100644 --- a/spec/features/merge_requests/widget_spec.rb +++ b/spec/features/merge_requests/widget_spec.rb @@ -273,7 +273,7 @@ describe 'Merge request', :js do let(:user2) { create(:user) } before do - project.team << [user2, :master] + project.add_master(user2) sign_out(:user) sign_in(user2) merge_request.update(target_project: fork_project) diff --git a/spec/features/merge_requests/wip_message_spec.rb b/spec/features/merge_requests/wip_message_spec.rb index b422c76249d..2617e735c25 100644 --- a/spec/features/merge_requests/wip_message_spec.rb +++ b/spec/features/merge_requests/wip_message_spec.rb @@ -5,7 +5,7 @@ feature 'Work In Progress help message' do let!(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/milestone_spec.rb b/spec/features/milestone_spec.rb index 9f24193a2ac..b02d2d4261c 100644 --- a/spec/features/milestone_spec.rb +++ b/spec/features/milestone_spec.rb @@ -7,7 +7,7 @@ feature 'Milestone' do before do create(:group_member, group: group, user: user) - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/password_reset_spec.rb b/spec/features/password_reset_spec.rb index b45972b7f6b..73a526c3d8a 100644 --- a/spec/features/password_reset_spec.rb +++ b/spec/features/password_reset_spec.rb @@ -33,6 +33,25 @@ feature 'Password reset' do end end + describe 'Changing password while logged in' do + it 'updates the password' do + user = create(:user) + token = user.send_reset_password_instructions + + sign_in(user) + + visit(edit_user_password_path(reset_password_token: token)) + + fill_in 'New password', with: 'hello1234' + fill_in 'Confirm new password', with: 'hello1234' + + click_button 'Change your password' + + expect(page).to have_content(I18n.t('devise.passwords.updated_not_active')) + expect(current_path).to eq new_user_session_path + end + end + def forgot_password(user) visit root_path click_on 'Forgot your password?' diff --git a/spec/features/profiles/keys_spec.rb b/spec/features/profiles/keys_spec.rb index 7d5ba3a7328..b04a5422fed 100644 --- a/spec/features/profiles/keys_spec.rb +++ b/spec/features/profiles/keys_spec.rb @@ -27,6 +27,7 @@ feature 'Profile > SSH Keys' do expect(page).to have_content("Title: #{attrs[:title]}") expect(page).to have_content(attrs[:key]) + expect(find('.breadcrumbs-sub-title')).to have_link(attrs[:title]) end context 'when only DSA and ECDSA keys are allowed' do diff --git a/spec/features/profiles/oauth_applications_spec.rb b/spec/features/profiles/oauth_applications_spec.rb index d1edeef8da4..7d204f89fba 100644 --- a/spec/features/profiles/oauth_applications_spec.rb +++ b/spec/features/profiles/oauth_applications_spec.rb @@ -2,12 +2,20 @@ require 'spec_helper' describe 'Profile > Applications' do let(:user) { create(:user) } + let(:application) { create(:oauth_application, owner: user) } before do sign_in(user) end describe 'User manages applications', :js do + it 'views an application' do + visit oauth_application_path(application) + + expect(page).to have_content("Application: #{application.name}") + expect(find('.breadcrumbs-sub-title')).to have_link(application.name) + end + it 'deletes an application' do create(:oauth_application, owner: user) visit oauth_applications_path diff --git a/spec/features/profiles/user_visits_notifications_tab_spec.rb b/spec/features/profiles/user_visits_notifications_tab_spec.rb index df89918f17a..1952fdae798 100644 --- a/spec/features/profiles/user_visits_notifications_tab_spec.rb +++ b/spec/features/profiles/user_visits_notifications_tab_spec.rb @@ -5,7 +5,7 @@ feature 'User visits the notifications tab', :js do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) visit(profile_notifications_path) end diff --git a/spec/features/profiles/user_visits_profile_preferences_page_spec.rb b/spec/features/profiles/user_visits_profile_preferences_page_spec.rb index 90d6841af0e..266af8f4e3d 100644 --- a/spec/features/profiles/user_visits_profile_preferences_page_spec.rb +++ b/spec/features/profiles/user_visits_profile_preferences_page_spec.rb @@ -32,6 +32,18 @@ describe 'User visits the profile preferences page' do end end + describe 'User changes their multi file editor preferences', :js do + it 'set the new_repo cookie when the option is ON' do + choose 'user_multi_file_on' + expect(get_cookie('new_repo')).not_to be_nil + end + + it 'deletes the new_repo cookie when the option is OFF' do + choose 'user_multi_file_off' + expect(get_cookie('new_repo')).to be_nil + end + end + describe 'User changes their default dashboard', :js do it 'creates a flash message' do select 'Starred Projects', from: 'user_dashboard' diff --git a/spec/features/projects/activity/rss_spec.rb b/spec/features/projects/activity/rss_spec.rb index 84c2faa2015..2693e539268 100644 --- a/spec/features/projects/activity/rss_spec.rb +++ b/spec/features/projects/activity/rss_spec.rb @@ -11,7 +11,7 @@ feature 'Project Activity RSS' do context 'when signed in' do before do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) visit path end diff --git a/spec/features/projects/badges/coverage_spec.rb b/spec/features/projects/badges/coverage_spec.rb index c68e10a2563..821ce88a402 100644 --- a/spec/features/projects/badges/coverage_spec.rb +++ b/spec/features/projects/badges/coverage_spec.rb @@ -6,7 +6,7 @@ feature 'test coverage badge' do context 'when user has access to view badge' do background do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) end diff --git a/spec/features/projects/badges/list_spec.rb b/spec/features/projects/badges/list_spec.rb index 68c4a647958..c705e479690 100644 --- a/spec/features/projects/badges/list_spec.rb +++ b/spec/features/projects/badges/list_spec.rb @@ -4,7 +4,7 @@ feature 'list of badges' do background do user = create(:user) project = create(:project, :repository) - project.team << [user, :master] + project.add_master(user) sign_in(user) visit project_pipelines_settings_path(project) end diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb index 965028a6f90..69e4c9f04a1 100644 --- a/spec/features/projects/blobs/edit_spec.rb +++ b/spec/features/projects/blobs/edit_spec.rb @@ -13,7 +13,7 @@ feature 'Editing file blob', :js do let(:role) { :developer } before do - project.team << [user, role] + project.add_role(user, role) sign_in(user) end @@ -55,7 +55,7 @@ feature 'Editing file blob', :js do let(:user) { create(:user) } before do - project.team << [user, :developer] + project.add_developer(user) visit project_edit_blob_path(project, tree_join(branch, file_path)) end @@ -90,7 +90,7 @@ feature 'Editing file blob', :js do let(:protected_branch) { 'protected-branch' } before do - project.team << [user, :developer] + project.add_developer(user) project.repository.add_branch(user, protected_branch, 'master') create(:protected_branch, project: project, name: protected_branch) sign_in(user) @@ -122,7 +122,7 @@ feature 'Editing file blob', :js do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) visit project_edit_blob_path(project, tree_join(branch, file_path)) end diff --git a/spec/features/projects/branches/download_buttons_spec.rb b/spec/features/projects/branches/download_buttons_spec.rb index 2f407b13c2f..39bcea013e7 100644 --- a/spec/features/projects/branches/download_buttons_spec.rb +++ b/spec/features/projects/branches/download_buttons_spec.rb @@ -23,7 +23,7 @@ feature 'Download buttons in branches page' do background do sign_in(user) - project.team << [user, role] + project.add_role(user, role) end describe 'when checking branches' do diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb index 7a77df83034..2fddd274078 100644 --- a/spec/features/projects/branches_spec.rb +++ b/spec/features/projects/branches_spec.rb @@ -8,7 +8,7 @@ describe 'Branches' do context 'logged in as developer' do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) end describe 'Initial branches page' do @@ -78,7 +78,7 @@ describe 'Branches' do context 'logged in as master' do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) end describe 'Initial branches page' do diff --git a/spec/features/projects/clusters/interchangeability_spec.rb b/spec/features/projects/clusters/interchangeability_spec.rb index 01f9526608f..3ddb35c755c 100644 --- a/spec/features/projects/clusters/interchangeability_spec.rb +++ b/spec/features/projects/clusters/interchangeability_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' feature 'Interchangeability between KubernetesService and Platform::Kubernetes' do - EXCEPT_METHODS = %i[test title description help fields initialize_properties namespace namespace= api_url api_url=].freeze + EXCEPT_METHODS = %i[test title description help fields initialize_properties namespace namespace= api_url api_url= deprecated? deprecation_message].freeze EXCEPT_METHODS_GREP_V = %w[_touched? _changed? _was].freeze it 'Clusters::Platform::Kubernetes covers core interfaces in KubernetesService' do diff --git a/spec/features/projects/commit/builds_spec.rb b/spec/features/projects/commit/builds_spec.rb index 79e84a4f0a6..36a746ac83d 100644 --- a/spec/features/projects/commit/builds_spec.rb +++ b/spec/features/projects/commit/builds_spec.rb @@ -5,7 +5,7 @@ feature 'project commit pipelines', :js do background do user = create(:user) - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/projects/commit/cherry_pick_spec.rb b/spec/features/projects/commit/cherry_pick_spec.rb index c11a95732b2..c4c399e3058 100644 --- a/spec/features/projects/commit/cherry_pick_spec.rb +++ b/spec/features/projects/commit/cherry_pick_spec.rb @@ -9,7 +9,7 @@ describe 'Cherry-pick Commits' do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) visit project_commit_path(project, master_pickable_commit.id) end diff --git a/spec/features/projects/commits/rss_spec.rb b/spec/features/projects/commits/rss_spec.rb index db958346f06..0d9c7355ddd 100644 --- a/spec/features/projects/commits/rss_spec.rb +++ b/spec/features/projects/commits/rss_spec.rb @@ -7,7 +7,7 @@ feature 'Project Commits RSS' do context 'when signed in' do before do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) visit path end diff --git a/spec/features/projects/compare_spec.rb b/spec/features/projects/compare_spec.rb index 87ffc2a0b90..1fb22fd0e4c 100644 --- a/spec/features/projects/compare_spec.rb +++ b/spec/features/projects/compare_spec.rb @@ -5,7 +5,7 @@ describe "Compare", :js do let(:project) { create(:project, :repository) } before do - project.team << [user, :master] + project.add_master(user) sign_in user visit project_compare_index_path(project, from: "master", to: "master") end diff --git a/spec/features/projects/deploy_keys_spec.rb b/spec/features/projects/deploy_keys_spec.rb index e445758cb5e..886c56e7163 100644 --- a/spec/features/projects/deploy_keys_spec.rb +++ b/spec/features/projects/deploy_keys_spec.rb @@ -5,7 +5,7 @@ describe 'Project deploy keys', :js do let(:project) { create(:project_empty_repo) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/projects/developer_views_empty_project_instructions_spec.rb b/spec/features/projects/developer_views_empty_project_instructions_spec.rb index 36809240f76..bf55917bf4c 100644 --- a/spec/features/projects/developer_views_empty_project_instructions_spec.rb +++ b/spec/features/projects/developer_views_empty_project_instructions_spec.rb @@ -5,7 +5,7 @@ feature 'Developer views empty project instructions' do let(:developer) { create(:user) } background do - project.team << [developer, :developer] + project.add_developer(developer) sign_in(developer) end diff --git a/spec/features/projects/edit_spec.rb b/spec/features/projects/edit_spec.rb index 7a372757523..1d4b4d0fdca 100644 --- a/spec/features/projects/edit_spec.rb +++ b/spec/features/projects/edit_spec.rb @@ -7,7 +7,7 @@ feature 'Project edit', :js do context 'feature visibility' do before do - project.team << [user, :master] + project.add_master(user) sign_in(user) visit edit_project_path(project) diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb index dfcf97ad495..64e600144e0 100644 --- a/spec/features/projects/environments/environment_spec.rb +++ b/spec/features/projects/environments/environment_spec.rb @@ -7,7 +7,7 @@ feature 'Environment' do background do sign_in(user) - project.team << [user, role] + project.add_role(user, role) end feature 'environment details page' do diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb index 4a05313c14a..5248a783db4 100644 --- a/spec/features/projects/environments/environments_spec.rb +++ b/spec/features/projects/environments/environments_spec.rb @@ -6,7 +6,7 @@ feature 'Environments page', :js do given(:role) { :developer } background do - project.team << [user, role] + project.add_role(user, role) sign_in(user) end diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb index 033c45a60bf..b0eb7c5b42a 100644 --- a/spec/features/projects/features_visibility_spec.rb +++ b/spec/features/projects/features_visibility_spec.rb @@ -8,7 +8,7 @@ describe 'Edit Project Settings' do describe 'project features visibility selectors', :js do before do - project.team << [member, :master] + project.add_master(member) sign_in(member) end @@ -165,7 +165,7 @@ describe 'Edit Project Settings' do describe 'repository visibility', :js do before do - project.team << [member, :master] + project.add_master(member) sign_in(member) visit edit_project_path(project) end @@ -261,7 +261,7 @@ describe 'Edit Project Settings' do let!(:project) { create(:project, :private) } before do - project.team << [member, :guest] + project.add_guest(member) sign_in(member) visit project_path(project) end diff --git a/spec/features/projects/files/browse_files_spec.rb b/spec/features/projects/files/browse_files_spec.rb index 84197e45dcb..2c38c380d9d 100644 --- a/spec/features/projects/files/browse_files_spec.rb +++ b/spec/features/projects/files/browse_files_spec.rb @@ -5,7 +5,7 @@ feature 'user browses project', :js do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) visit project_tree_path(project, project.default_branch) end diff --git a/spec/features/projects/files/creating_a_file_spec.rb b/spec/features/projects/files/creating_a_file_spec.rb index e1852a6e544..8d982636525 100644 --- a/spec/features/projects/files/creating_a_file_spec.rb +++ b/spec/features/projects/files/creating_a_file_spec.rb @@ -5,7 +5,7 @@ feature 'User wants to create a file' do let(:user) { create(:user) } background do - project.team << [user, :master] + project.add_master(user) sign_in user visit project_new_blob_path(project, project.default_branch) end diff --git a/spec/features/projects/files/dockerfile_dropdown_spec.rb b/spec/features/projects/files/dockerfile_dropdown_spec.rb index 3c3a5326538..f4a39e331fd 100644 --- a/spec/features/projects/files/dockerfile_dropdown_spec.rb +++ b/spec/features/projects/files/dockerfile_dropdown_spec.rb @@ -5,7 +5,7 @@ feature 'User wants to add a Dockerfile file' do before do user = create(:user) project = create(:project, :repository) - project.team << [user, :master] + project.add_master(user) sign_in user diff --git a/spec/features/projects/files/download_buttons_spec.rb b/spec/features/projects/files/download_buttons_spec.rb index d2382d55c0b..2101627f324 100644 --- a/spec/features/projects/files/download_buttons_spec.rb +++ b/spec/features/projects/files/download_buttons_spec.rb @@ -23,7 +23,7 @@ feature 'Download buttons in files tree' do background do sign_in(user) - project.team << [user, role] + project.add_role(user, role) end describe 'when files tree' do diff --git a/spec/features/projects/files/edit_file_soft_wrap_spec.rb b/spec/features/projects/files/edit_file_soft_wrap_spec.rb index 3ab43b3c656..8d32ada5795 100644 --- a/spec/features/projects/files/edit_file_soft_wrap_spec.rb +++ b/spec/features/projects/files/edit_file_soft_wrap_spec.rb @@ -4,7 +4,7 @@ feature 'User uses soft wrap whilst editing file', :js do before do user = create(:user) project = create(:project, :repository) - project.team << [user, :master] + project.add_master(user) sign_in user visit project_new_blob_path(project, 'master', file_name: 'test_file-name') page.within('.file-editor.code') do diff --git a/spec/features/projects/files/editing_a_file_spec.rb b/spec/features/projects/files/editing_a_file_spec.rb index 20be968e89f..d874cdbff8d 100644 --- a/spec/features/projects/files/editing_a_file_spec.rb +++ b/spec/features/projects/files/editing_a_file_spec.rb @@ -16,7 +16,7 @@ feature 'User wants to edit a file' do end background do - project.team << [user, :master] + project.add_master(user) sign_in user visit project_edit_blob_path(project, File.join(project.default_branch, '.gitignore')) diff --git a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb index 702b99de733..ead9f7e9168 100644 --- a/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb +++ b/spec/features/projects/files/files_sort_submodules_with_folders_spec.rb @@ -5,7 +5,7 @@ feature 'User views files page' do let(:project) { create(:forked_project_with_submodules) } before do - project.team << [user, :master] + project.add_master(user) sign_in user visit project_tree_path(project, project.repository.root_ref) end diff --git a/spec/features/projects/files/find_file_keyboard_spec.rb b/spec/features/projects/files/find_file_keyboard_spec.rb index 618725ee781..e9ff06c72d8 100644 --- a/spec/features/projects/files/find_file_keyboard_spec.rb +++ b/spec/features/projects/files/find_file_keyboard_spec.rb @@ -5,7 +5,7 @@ feature 'Find file keyboard shortcuts', :js do let(:project) { create(:project, :repository) } before do - project.team << [user, :master] + project.add_master(user) sign_in user visit project_find_file_path(project, project.repository.root_ref) diff --git a/spec/features/projects/files/gitignore_dropdown_spec.rb b/spec/features/projects/files/gitignore_dropdown_spec.rb index 81d68c3d67c..79f3fd09b48 100644 --- a/spec/features/projects/files/gitignore_dropdown_spec.rb +++ b/spec/features/projects/files/gitignore_dropdown_spec.rb @@ -4,7 +4,7 @@ feature 'User wants to add a .gitignore file' do before do user = create(:user) project = create(:project, :repository) - project.team << [user, :master] + project.add_master(user) sign_in user visit project_new_blob_path(project, 'master', file_name: '.gitignore') end diff --git a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb index 8e58fa7bd56..db6c67b802e 100644 --- a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb +++ b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb @@ -4,7 +4,7 @@ feature 'User wants to add a .gitlab-ci.yml file' do before do user = create(:user) project = create(:project, :repository) - project.team << [user, :master] + project.add_master(user) sign_in user visit project_new_blob_path(project, 'master', file_name: '.gitlab-ci.yml') end diff --git a/spec/features/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/projects/files/project_owner_creates_license_file_spec.rb index 6c5b1086ec1..07599600876 100644 --- a/spec/features/projects/files/project_owner_creates_license_file_spec.rb +++ b/spec/features/projects/files/project_owner_creates_license_file_spec.rb @@ -6,7 +6,7 @@ feature 'project owner creates a license file', :js do background do project.repository.delete_file(project_master, 'LICENSE', message: 'Remove LICENSE', branch_name: 'master') - project.team << [project_master, :master] + project.add_master(project_master) sign_in(project_master) visit project_path(project) end diff --git a/spec/features/projects/files/template_type_dropdown_spec.rb b/spec/features/projects/files/template_type_dropdown_spec.rb index f95a60e5194..97408a9c41e 100644 --- a/spec/features/projects/files/template_type_dropdown_spec.rb +++ b/spec/features/projects/files/template_type_dropdown_spec.rb @@ -5,7 +5,7 @@ feature 'Template type dropdown selector', :js do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in user end diff --git a/spec/features/projects/files/undo_template_spec.rb b/spec/features/projects/files/undo_template_spec.rb index 64fe350f3dc..fbf35fb4e1c 100644 --- a/spec/features/projects/files/undo_template_spec.rb +++ b/spec/features/projects/files/undo_template_spec.rb @@ -5,7 +5,7 @@ feature 'Template Undo Button', :js do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in user end diff --git a/spec/features/projects/guest_navigation_menu_spec.rb b/spec/features/projects/guest_navigation_menu_spec.rb index 98c7ef57a51..199682b943c 100644 --- a/spec/features/projects/guest_navigation_menu_spec.rb +++ b/spec/features/projects/guest_navigation_menu_spec.rb @@ -5,7 +5,7 @@ describe 'Guest navigation menu' do let(:guest) { create(:user) } before do - project.team << [guest, :guest] + project.add_guest(guest) sign_in(guest) end diff --git a/spec/features/projects/issuable_templates_spec.rb b/spec/features/projects/issuable_templates_spec.rb index 4319fc2746c..e26caf1f456 100644 --- a/spec/features/projects/issuable_templates_spec.rb +++ b/spec/features/projects/issuable_templates_spec.rb @@ -8,7 +8,7 @@ feature 'issuable templates', :js do let(:issue_form_location) { '#content-body .issuable-details .detail-page-description' } before do - project.team << [user, :master] + project.add_master(user) sign_in user end @@ -120,7 +120,7 @@ feature 'issuable templates', :js do background do sign_out(:user) - project.team << [fork_user, :developer] + project.add_developer(fork_user) sign_in(fork_user) diff --git a/spec/features/projects/issues/rss_spec.rb b/spec/features/projects/issues/rss_spec.rb index 58eeef8c258..ff91aabc311 100644 --- a/spec/features/projects/issues/rss_spec.rb +++ b/spec/features/projects/issues/rss_spec.rb @@ -12,7 +12,7 @@ feature 'Project Issues RSS' do let(:user) { create(:user) } before do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) visit path end diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index b59d8f37a5d..9a6b27c00f8 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -15,7 +15,7 @@ feature 'Jobs' do end before do - project.team << [user, user_access_level] + project.add_role(user, user_access_level) sign_in(user) end diff --git a/spec/features/projects/labels/subscription_spec.rb b/spec/features/projects/labels/subscription_spec.rb index e8c70dec854..70e8d436dcb 100644 --- a/spec/features/projects/labels/subscription_spec.rb +++ b/spec/features/projects/labels/subscription_spec.rb @@ -9,7 +9,7 @@ feature 'Labels subscription' do context 'when signed in' do before do - project.team << [user, :developer] + project.add_developer(user) sign_in user end diff --git a/spec/features/projects/labels/update_prioritization_spec.rb b/spec/features/projects/labels/update_prioritization_spec.rb index d063f5c27b5..85bd776932b 100644 --- a/spec/features/projects/labels/update_prioritization_spec.rb +++ b/spec/features/projects/labels/update_prioritization_spec.rb @@ -12,7 +12,7 @@ feature 'Prioritize labels' do context 'when user belongs to project team' do before do - project.team << [user, :developer] + project.add_developer(user) sign_in user end diff --git a/spec/features/projects/main/download_buttons_spec.rb b/spec/features/projects/main/download_buttons_spec.rb index 3f2579bb01a..81f08e44cf3 100644 --- a/spec/features/projects/main/download_buttons_spec.rb +++ b/spec/features/projects/main/download_buttons_spec.rb @@ -23,7 +23,7 @@ feature 'Download buttons in project main page' do background do sign_in(user) - project.team << [user, role] + project.add_role(user, role) end describe 'when checking project main page' do diff --git a/spec/features/projects/main/rss_spec.rb b/spec/features/projects/main/rss_spec.rb index 7914180b951..3c98c11b490 100644 --- a/spec/features/projects/main/rss_spec.rb +++ b/spec/features/projects/main/rss_spec.rb @@ -7,7 +7,7 @@ feature 'Project RSS' do context 'when signed in' do before do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) visit path end diff --git a/spec/features/projects/members/anonymous_user_sees_members_spec.rb b/spec/features/projects/members/anonymous_user_sees_members_spec.rb index bf0990d675d..e2a48bfd1d4 100644 --- a/spec/features/projects/members/anonymous_user_sees_members_spec.rb +++ b/spec/features/projects/members/anonymous_user_sees_members_spec.rb @@ -6,7 +6,7 @@ feature 'Projects > Members > Anonymous user sees members' do let(:project) { create(:project, :public) } background do - project.team << [user, :master] + project.add_master(user) create(:project_group_link, project: project, group: group) end diff --git a/spec/features/projects/members/group_members_spec.rb b/spec/features/projects/members/group_members_spec.rb index c140fece41d..e22b6fa6c43 100644 --- a/spec/features/projects/members/group_members_spec.rb +++ b/spec/features/projects/members/group_members_spec.rb @@ -11,7 +11,7 @@ feature 'Projects members' do let(:group_requester) { create(:user) } background do - project.team << [developer, :developer] + project.add_developer(developer) group.add_owner(user) sign_in(user) end diff --git a/spec/features/projects/members/groups_with_access_list_spec.rb b/spec/features/projects/members/groups_with_access_list_spec.rb index 7f067aadec6..e6d0c6e00f8 100644 --- a/spec/features/projects/members/groups_with_access_list_spec.rb +++ b/spec/features/projects/members/groups_with_access_list_spec.rb @@ -6,7 +6,7 @@ feature 'Projects > Members > Groups with access list', :js do let(:project) { create(:project, :public) } background do - project.team << [user, :master] + project.add_master(user) @group_link = create(:project_group_link, project: project, group: group) sign_in(user) diff --git a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb index 0f88f4cb1e8..8fe340d3bae 100644 --- a/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb +++ b/spec/features/projects/members/master_adds_member_with_expiration_date_spec.rb @@ -9,7 +9,7 @@ feature 'Projects > Members > Master adds member with expiration date', :js do let!(:new_member) { create(:user) } background do - project.team << [master, :master] + project.add_master(master) sign_in(master) end diff --git a/spec/features/projects/members/master_manages_access_requests_spec.rb b/spec/features/projects/members/master_manages_access_requests_spec.rb index eb3c8034873..d575596937d 100644 --- a/spec/features/projects/members/master_manages_access_requests_spec.rb +++ b/spec/features/projects/members/master_manages_access_requests_spec.rb @@ -7,7 +7,7 @@ feature 'Projects > Members > Master manages access requests' do background do project.request_access(user) - project.team << [master, :master] + project.add_master(master) sign_in(master) end diff --git a/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb b/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb index 04806f8fd9e..47911c32a72 100644 --- a/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb +++ b/spec/features/projects/members/member_cannot_request_access_to_his_project_spec.rb @@ -5,7 +5,7 @@ feature 'Projects > Members > Member cannot request access to his project' do let(:project) { create(:project) } background do - project.team << [member, :developer] + project.add_developer(member) sign_in(member) visit project_path(project) end diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb index 1bcf827d33c..e54c2c76975 100644 --- a/spec/features/projects/members/member_leaves_project_spec.rb +++ b/spec/features/projects/members/member_leaves_project_spec.rb @@ -5,7 +5,7 @@ feature 'Projects > Members > Member leaves project' do let(:project) { create(:project, :repository) } background do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) visit project_path(project) end diff --git a/spec/features/projects/merge_requests/list_spec.rb b/spec/features/projects/merge_requests/list_spec.rb index a879efef4b5..b34b13db381 100644 --- a/spec/features/projects/merge_requests/list_spec.rb +++ b/spec/features/projects/merge_requests/list_spec.rb @@ -5,7 +5,7 @@ feature 'Merge Requests List' do let(:project) { create(:project, :repository) } background do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) end diff --git a/spec/features/projects/pages_spec.rb b/spec/features/projects/pages_spec.rb index 013ed6f2e58..2e334caa98f 100644 --- a/spec/features/projects/pages_spec.rb +++ b/spec/features/projects/pages_spec.rb @@ -8,7 +8,7 @@ feature 'Pages' do background do allow(Gitlab.config.pages).to receive(:enabled).and_return(true) - project.team << [user, role] + project.add_role(user, role) sign_in(user) end diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb index 3987cea0b4f..266ef693d0b 100644 --- a/spec/features/projects/pipelines/pipeline_spec.rb +++ b/spec/features/projects/pipelines/pipeline_spec.rb @@ -6,7 +6,7 @@ describe 'Pipeline', :js do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) end shared_context 'pipeline builds' do diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index b87b47d0e1a..df261c246f7 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -8,7 +8,7 @@ describe 'Pipelines', :js do before do sign_in(user) - project.team << [user, :developer] + project.add_developer(user) end describe 'GET /:project/pipelines' do diff --git a/spec/features/projects/services/user_activates_jira_spec.rb b/spec/features/projects/services/user_activates_jira_spec.rb index ac78b1dfb1c..028669eeaf2 100644 --- a/spec/features/projects/services/user_activates_jira_spec.rb +++ b/spec/features/projects/services/user_activates_jira_spec.rb @@ -18,7 +18,7 @@ describe 'User activates Jira', :js do end before do - project.team << [user, :master] + project.add_master(user) sign_in(user) visit project_settings_integrations_path(project) diff --git a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb index 6f057137867..b2906e315f7 100644 --- a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb +++ b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb @@ -8,7 +8,7 @@ feature 'Setup Mattermost slash commands', :js do before do stub_mattermost_setting(enabled: mattermost_enabled) - project.team << [user, :master] + project.add_master(user) sign_in(user) visit edit_project_service_path(project, service) end diff --git a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb index a8baf126269..4a88654210c 100644 --- a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb +++ b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb @@ -6,7 +6,7 @@ feature 'Slack slash commands' do given(:service) { project.create_slack_slash_commands_service } background do - project.team << [user, :master] + project.add_master(user) sign_in(user) visit edit_project_service_path(project, service) end diff --git a/spec/features/projects/settings/integration_settings_spec.rb b/spec/features/projects/settings/integration_settings_spec.rb index cbdb7973ac8..f6a1a46df11 100644 --- a/spec/features/projects/settings/integration_settings_spec.rb +++ b/spec/features/projects/settings/integration_settings_spec.rb @@ -8,7 +8,7 @@ feature 'Integration settings' do background do sign_in(user) - project.team << [user, role] + project.add_role(user, role) end context 'for developer' do diff --git a/spec/features/projects/settings/merge_requests_settings_spec.rb b/spec/features/projects/settings/merge_requests_settings_spec.rb index ac76c30cc7c..015db603d33 100644 --- a/spec/features/projects/settings/merge_requests_settings_spec.rb +++ b/spec/features/projects/settings/merge_requests_settings_spec.rb @@ -5,7 +5,7 @@ feature 'Project settings > Merge Requests', :js do let(:user) { create(:user) } background do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb index 561f08cba00..d0720855564 100644 --- a/spec/features/projects/settings/pipelines_settings_spec.rb +++ b/spec/features/projects/settings/pipelines_settings_spec.rb @@ -7,7 +7,7 @@ feature "Pipelines settings" do background do sign_in(user) - project.team << [user, role] + project.add_role(user, role) end context 'for developer' do diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb index e2a5619c22b..81b282502fc 100644 --- a/spec/features/projects/settings/repository_settings_spec.rb +++ b/spec/features/projects/settings/repository_settings_spec.rb @@ -6,7 +6,7 @@ feature 'Repository settings' do let(:role) { :developer } background do - project.team << [user, role] + project.add_role(user, role) sign_in(user) end @@ -66,7 +66,7 @@ feature 'Repository settings' do scenario 'edit a deploy key from projects user has access to' do project2 = create(:project_empty_repo) - project2.team << [user, role] + project2.add_role(user, role) project2.deploy_keys << private_deploy_key visit project_settings_repository_path(project) diff --git a/spec/features/projects/settings/visibility_settings_spec.rb b/spec/features/projects/settings/visibility_settings_spec.rb index 1c3b84d0114..06f6702670b 100644 --- a/spec/features/projects/settings/visibility_settings_spec.rb +++ b/spec/features/projects/settings/visibility_settings_spec.rb @@ -31,7 +31,7 @@ feature 'Visibility settings', :js do let(:master_user) { create(:user) } before do - project.team << [master_user, :master] + project.add_master(master_user) sign_in(master_user) visit edit_project_path(project) end diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb index e4215291f99..3466a3dfb77 100644 --- a/spec/features/projects/snippets/create_snippet_spec.rb +++ b/spec/features/projects/snippets/create_snippet_spec.rb @@ -16,7 +16,7 @@ feature 'Create Snippet', :js do context 'when a user is authenticated' do before do - project.team << [user, :master] + project.add_master(user) sign_in(user) visit project_snippets_path(project) diff --git a/spec/features/projects/snippets/show_spec.rb b/spec/features/projects/snippets/show_spec.rb index 08dc7cf6c5b..216f2af7c88 100644 --- a/spec/features/projects/snippets/show_spec.rb +++ b/spec/features/projects/snippets/show_spec.rb @@ -6,7 +6,7 @@ feature 'Project snippet', :js do let(:snippet) { create(:project_snippet, project: project, file_name: file_name, content: content) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/projects/tags/download_buttons_spec.rb b/spec/features/projects/tags/download_buttons_spec.rb index d38a5b1324b..b62498194c4 100644 --- a/spec/features/projects/tags/download_buttons_spec.rb +++ b/spec/features/projects/tags/download_buttons_spec.rb @@ -24,7 +24,7 @@ feature 'Download buttons in tags page' do background do sign_in(user) - project.team << [user, role] + project.add_role(user, role) end describe 'when checking tags' do diff --git a/spec/features/projects/tree/rss_spec.rb b/spec/features/projects/tree/rss_spec.rb index 4f2e0a76a65..6407370ac0d 100644 --- a/spec/features/projects/tree/rss_spec.rb +++ b/spec/features/projects/tree/rss_spec.rb @@ -7,7 +7,7 @@ feature 'Project Tree RSS' do context 'when signed in' do before do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) visit path end diff --git a/spec/features/projects/user_browses_files_spec.rb b/spec/features/projects/user_browses_files_spec.rb index f5e4d7f5130..62e6419cc42 100644 --- a/spec/features/projects/user_browses_files_spec.rb +++ b/spec/features/projects/user_browses_files_spec.rb @@ -15,7 +15,7 @@ describe 'User browses files' do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/projects/user_creates_directory_spec.rb b/spec/features/projects/user_creates_directory_spec.rb index 052cb3188c5..00e48f6fabd 100644 --- a/spec/features/projects/user_creates_directory_spec.rb +++ b/spec/features/projects/user_creates_directory_spec.rb @@ -11,7 +11,7 @@ feature 'User creates a directory', :js do let(:user) { create(:user) } before do - project.team << [user, :developer] + project.add_developer(user) sign_in(user) visit project_tree_path(project, 'master') end @@ -63,7 +63,7 @@ feature 'User creates a directory', :js do context 'when an user does not have write access' do before do - project2.team << [user, :reporter] + project2.add_reporter(user) visit(project2_tree_path_root_ref) end diff --git a/spec/features/projects/user_creates_files_spec.rb b/spec/features/projects/user_creates_files_spec.rb index d84b91ddc32..7a935dd2477 100644 --- a/spec/features/projects/user_creates_files_spec.rb +++ b/spec/features/projects/user_creates_files_spec.rb @@ -12,7 +12,7 @@ describe 'User creates files' do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end @@ -33,7 +33,7 @@ describe 'User creates files' do context 'when an user does not have write access' do before do - project2.team << [user, :reporter] + project2.add_reporter(user) visit(project2_tree_path_root_ref) end @@ -131,7 +131,7 @@ describe 'User creates files' do context 'when an user does not have write access' do before do - project2.team << [user, :reporter] + project2.add_reporter(user) visit(project2_tree_path_root_ref) end diff --git a/spec/features/projects/user_deletes_files_spec.rb b/spec/features/projects/user_deletes_files_spec.rb index 9e4e92ec076..9d55197e719 100644 --- a/spec/features/projects/user_deletes_files_spec.rb +++ b/spec/features/projects/user_deletes_files_spec.rb @@ -17,7 +17,7 @@ describe 'User deletes files' do context 'when an user has write access' do before do - project.team << [user, :master] + project.add_master(user) visit(project_tree_path_root_ref) end @@ -37,7 +37,7 @@ describe 'User deletes files' do context 'when an user does not have write access' do before do - project2.team << [user, :reporter] + project2.add_reporter(user) visit(project2_tree_path_root_ref) end diff --git a/spec/features/projects/user_edits_files_spec.rb b/spec/features/projects/user_edits_files_spec.rb index d26ee653415..05c2be473da 100644 --- a/spec/features/projects/user_edits_files_spec.rb +++ b/spec/features/projects/user_edits_files_spec.rb @@ -14,7 +14,7 @@ describe 'User edits files' do context 'when an user has write access' do before do - project.team << [user, :master] + project.add_master(user) visit(project_tree_path_root_ref) end @@ -33,7 +33,9 @@ describe 'User edits files' do binary_file = File.join(project.repository.root_ref, 'files/images/logo-black.png') visit(project_blob_path(project, binary_file)) - expect(page).not_to have_link('edit') + page.within '.content' do + expect(page).not_to have_link('edit') + end end it 'commits an edited file', :js do @@ -87,7 +89,7 @@ describe 'User edits files' do context 'when an user does not have write access' do before do - project2.team << [user, :reporter] + project2.add_reporter(user) visit(project2_tree_path_root_ref) end diff --git a/spec/features/projects/user_replaces_files_spec.rb b/spec/features/projects/user_replaces_files_spec.rb index 245b6aa285b..74872403b35 100644 --- a/spec/features/projects/user_replaces_files_spec.rb +++ b/spec/features/projects/user_replaces_files_spec.rb @@ -19,7 +19,7 @@ describe 'User replaces files' do context 'when an user has write access' do before do - project.team << [user, :master] + project.add_master(user) visit(project_tree_path_root_ref) end @@ -45,7 +45,7 @@ describe 'User replaces files' do context 'when an user does not have write access' do before do - project2.team << [user, :reporter] + project2.add_reporter(user) visit(project2_tree_path_root_ref) end diff --git a/spec/features/projects/user_uploads_files_spec.rb b/spec/features/projects/user_uploads_files_spec.rb index ae51901adc6..75898afcda9 100644 --- a/spec/features/projects/user_uploads_files_spec.rb +++ b/spec/features/projects/user_uploads_files_spec.rb @@ -14,7 +14,7 @@ describe 'User uploads files' do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end @@ -50,7 +50,7 @@ describe 'User uploads files' do context 'when an user does not have write access' do before do - project2.team << [user, :reporter] + project2.add_reporter(user) visit(project2_tree_path_root_ref) end diff --git a/spec/features/projects/wiki/markdown_preview_spec.rb b/spec/features/projects/wiki/markdown_preview_spec.rb index 337baaf4dcd..006c15d60c5 100644 --- a/spec/features/projects/wiki/markdown_preview_spec.rb +++ b/spec/features/projects/wiki/markdown_preview_spec.rb @@ -13,7 +13,7 @@ feature 'Projects > Wiki > User previews markdown changes', :js do end background do - project.team << [user, :master] + project.add_master(user) sign_in(user) diff --git a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb index ebb3bd044c1..2682b62fa04 100644 --- a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb +++ b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb @@ -4,7 +4,7 @@ describe 'Projects > Wiki > User views wiki in project page' do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb index 63e6051b571..b66a7dea598 100644 --- a/spec/features/projects_spec.rb +++ b/spec/features/projects_spec.rb @@ -133,7 +133,7 @@ feature 'Project' do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) visit edit_project_path(project) end @@ -151,7 +151,7 @@ feature 'Project' do let(:project) { create(:forked_project_with_submodules) } before do - project.team << [user, :master] + project.add_master(user) sign_in user visit project_path(project) end @@ -180,7 +180,7 @@ feature 'Project' do let(:project) { create(:project, :repository) } before do - project.team << [user, :master] + project.add_master(user) sign_in user visit project_path(project) end diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb index c7f0e342809..aec9de6c7ca 100644 --- a/spec/features/runners_spec.rb +++ b/spec/features/runners_spec.rb @@ -33,6 +33,26 @@ feature 'Runners' do expect(page).to have_content(specific_runner.platform) end + scenario 'user can pause and resume the specific runner' do + visit runners_path(project) + + within '.activated-specific-runners' do + expect(page).to have_content('Pause') + end + + click_on 'Pause' + + within '.activated-specific-runners' do + expect(page).to have_content('Resume') + end + + click_on 'Resume' + + within '.activated-specific-runners' do + expect(page).to have_content('Pause') + end + end + scenario 'user removes an activated specific runner if this is last project for that runners' do visit runners_path(project) diff --git a/spec/features/signed_commits_spec.rb b/spec/features/signed_commits_spec.rb index 8efa5b58141..6088b831c14 100644 --- a/spec/features/signed_commits_spec.rb +++ b/spec/features/signed_commits_spec.rb @@ -5,7 +5,7 @@ describe 'GPG signed commits', :js do it 'changes from unverified to verified when the user changes his email to match the gpg key' do user = create :user, email: 'unrelated.user@example.org' - project.team << [user, :master] + project.add_master(user) Sidekiq::Testing.inline! do create :gpg_key, key: GpgHelpers::User1.public_key, user: user @@ -36,7 +36,7 @@ describe 'GPG signed commits', :js do it 'changes from unverified to verified when the user adds the missing gpg key' do user = create :user, email: GpgHelpers::User1.emails.first - project.team << [user, :master] + project.add_master(user) sign_in(user) @@ -86,7 +86,7 @@ describe 'GPG signed commits', :js do before do user = create :user - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/tags/master_creates_tag_spec.rb b/spec/features/tags/master_creates_tag_spec.rb index 1f8bd8d681e..8a8f6933fa5 100644 --- a/spec/features/tags/master_creates_tag_spec.rb +++ b/spec/features/tags/master_creates_tag_spec.rb @@ -5,7 +5,7 @@ feature 'Master creates tag' do let(:project) { create(:project, :repository, namespace: user.namespace) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) end diff --git a/spec/features/tags/master_deletes_tag_spec.rb b/spec/features/tags/master_deletes_tag_spec.rb index dfda664d673..c0b4fa52526 100644 --- a/spec/features/tags/master_deletes_tag_spec.rb +++ b/spec/features/tags/master_deletes_tag_spec.rb @@ -5,7 +5,7 @@ feature 'Master deletes tag' do let(:project) { create(:project, :repository, namespace: user.namespace) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) visit project_tags_path(project) end diff --git a/spec/features/tags/master_updates_tag_spec.rb b/spec/features/tags/master_updates_tag_spec.rb index b93ad44dfd3..1c370a99b13 100644 --- a/spec/features/tags/master_updates_tag_spec.rb +++ b/spec/features/tags/master_updates_tag_spec.rb @@ -5,7 +5,7 @@ feature 'Master updates tag' do let(:project) { create(:project, :repository, namespace: user.namespace) } before do - project.team << [user, :master] + project.add_master(user) sign_in(user) visit project_tags_path(project) end diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb index bc472e74997..19784120108 100644 --- a/spec/features/triggers_spec.rb +++ b/spec/features/triggers_spec.rb @@ -10,9 +10,9 @@ feature 'Triggers', :js do sign_in(user) @project = create(:project) - @project.team << [user, :master] - @project.team << [user2, :master] - @project.team << [guest_user, :guest] + @project.add_master(user) + @project.add_master(user2) + @project.add_guest(guest_user) visit project_settings_ci_cd_path(@project) end diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb index c9afef2a8de..50ee1656e10 100644 --- a/spec/features/u2f_spec.rb +++ b/spec/features/u2f_spec.rb @@ -264,7 +264,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do end it "deletes u2f registrations" do - visit profile_account_path + visit profile_two_factor_auth_path expect do accept_confirm { click_on "Disable" } end.to change { U2fRegistration.count }.by(-1) diff --git a/spec/features/variables_spec.rb b/spec/features/variables_spec.rb index dde60c83536..79ca2b4bb4a 100644 --- a/spec/features/variables_spec.rb +++ b/spec/features/variables_spec.rb @@ -7,7 +7,7 @@ describe 'Project variables', :js do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) project.variables << variable visit project_settings_ci_cd_path(project) diff --git a/spec/finders/access_requests_finder_spec.rb b/spec/finders/access_requests_finder_spec.rb index 0789d3a9b44..650f7229647 100644 --- a/spec/finders/access_requests_finder_spec.rb +++ b/spec/finders/access_requests_finder_spec.rb @@ -51,7 +51,7 @@ describe AccessRequestsFinder do context 'when current user can see access requests' do before do - project.team << [user, :master] + project.add_master(user) group.add_owner(user) end @@ -78,7 +78,7 @@ describe AccessRequestsFinder do context 'when current user can see access requests' do before do - project.team << [user, :master] + project.add_master(user) group.add_owner(user) end diff --git a/spec/finders/group_projects_finder_spec.rb b/spec/finders/group_projects_finder_spec.rb index c6d257bc479..27a09d7c6f5 100644 --- a/spec/finders/group_projects_finder_spec.rb +++ b/spec/finders/group_projects_finder_spec.rb @@ -45,7 +45,7 @@ describe GroupProjectsFinder do describe 'without group member current_user' do before do - shared_project_2.team << [current_user, Gitlab::Access::MASTER] + shared_project_2.add_master(current_user) current_user.reload end @@ -70,7 +70,7 @@ describe GroupProjectsFinder do context "without external user" do before do - private_project.team << [current_user, Gitlab::Access::MASTER] + private_project.add_master(current_user) end it { is_expected.to match_array([private_project, public_project]) } diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb index 47b173dea0a..47fd98234f9 100644 --- a/spec/finders/issues_finder_spec.rb +++ b/spec/finders/issues_finder_spec.rb @@ -22,9 +22,9 @@ describe IssuesFinder do let(:issues) { described_class.new(search_user, params.reverse_merge(scope: scope, state: 'opened')).execute } before(:context) do - project1.team << [user, :master] - project2.team << [user, :developer] - project2.team << [user2, :developer] + project1.add_master(user) + project2.add_developer(user) + project2.add_developer(user2) issue1 issue2 diff --git a/spec/finders/labels_finder_spec.rb b/spec/finders/labels_finder_spec.rb index afa2a40ed2a..d507af3fd3d 100644 --- a/spec/finders/labels_finder_spec.rb +++ b/spec/finders/labels_finder_spec.rb @@ -27,7 +27,7 @@ describe LabelsFinder do create(:label, project: project_3, title: 'Label 3') create(:group_label, group: group_3, title: 'Group Label 4') - project_1.team << [user, :developer] + project_1.add_developer(user) end context 'with no filter' do @@ -73,7 +73,7 @@ describe LabelsFinder do # project_3 has a label associated to it, which we don't want coming # back when we ask for the isolated project's labels - project_3.team << [admin, :reporter] + project_3.add_reporter(admin) finder = described_class.new(admin, project_id: isolated_project.id) expect(finder.execute).to be_empty diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb index 883bdf3746a..687ffaec7cc 100644 --- a/spec/finders/merge_requests_finder_spec.rb +++ b/spec/finders/merge_requests_finder_spec.rb @@ -20,10 +20,10 @@ describe MergeRequestsFinder do let!(:merge_request4) { create(:merge_request, :simple, author: user, source_project: project3, target_project: project3) } before do - project1.team << [user, :master] - project2.team << [user, :developer] - project3.team << [user, :developer] - project2.team << [user2, :developer] + project1.add_master(user) + project2.add_developer(user) + project3.add_developer(user) + project2.add_developer(user2) end describe "#execute" do diff --git a/spec/finders/move_to_project_finder_spec.rb b/spec/finders/move_to_project_finder_spec.rb index e577083a2d0..74639d4147f 100644 --- a/spec/finders/move_to_project_finder_spec.rb +++ b/spec/finders/move_to_project_finder_spec.rb @@ -15,39 +15,39 @@ describe MoveToProjectFinder do describe '#execute' do context 'filter' do it 'does not return projects under Gitlab::Access::REPORTER' do - guest_project.team << [user, :guest] + guest_project.add_guest(user) expect(subject.execute(project)).to be_empty end it 'returns projects equal or above Gitlab::Access::REPORTER ordered by id in descending order' do - reporter_project.team << [user, :reporter] - developer_project.team << [user, :developer] - master_project.team << [user, :master] + reporter_project.add_reporter(user) + developer_project.add_developer(user) + master_project.add_master(user) expect(subject.execute(project).to_a).to eq([master_project, developer_project, reporter_project]) end it 'does not include the source project' do - project.team << [user, :reporter] + project.add_reporter(user) expect(subject.execute(project).to_a).to be_empty end it 'does not return archived projects' do - reporter_project.team << [user, :reporter] + reporter_project.add_reporter(user) reporter_project.archive! other_reporter_project = create(:project) - other_reporter_project.team << [user, :reporter] + other_reporter_project.add_reporter(user) expect(subject.execute(project).to_a).to eq([other_reporter_project]) end it 'does not return projects for which issues are disabled' do - reporter_project.team << [user, :reporter] + reporter_project.add_reporter(user) reporter_project.update_attributes(issues_enabled: false) other_reporter_project = create(:project) - other_reporter_project.team << [user, :reporter] + other_reporter_project.add_reporter(user) expect(subject.execute(project).to_a).to eq([other_reporter_project]) end @@ -55,9 +55,9 @@ describe MoveToProjectFinder do it 'returns a page of projects ordered by id in descending order' do stub_const 'MoveToProjectFinder::PAGE_SIZE', 2 - reporter_project.team << [user, :reporter] - developer_project.team << [user, :developer] - master_project.team << [user, :master] + reporter_project.add_reporter(user) + developer_project.add_developer(user) + master_project.add_master(user) expect(subject.execute(project).to_a).to eq([master_project, developer_project]) end @@ -65,9 +65,9 @@ describe MoveToProjectFinder do it 'returns projects after the given offset id' do stub_const 'MoveToProjectFinder::PAGE_SIZE', 2 - reporter_project.team << [user, :reporter] - developer_project.team << [user, :developer] - master_project.team << [user, :master] + reporter_project.add_reporter(user) + developer_project.add_developer(user) + master_project.add_master(user) expect(subject.execute(project, search: nil, offset_id: master_project.id).to_a).to eq([developer_project, reporter_project]) expect(subject.execute(project, search: nil, offset_id: developer_project.id).to_a).to eq([reporter_project]) @@ -84,10 +84,10 @@ describe MoveToProjectFinder do it 'returns projects matching a search query' do foo_project = create(:project) - foo_project.team << [user, :master] + foo_project.add_master(user) wadus_project = create(:project, name: 'wadus') - wadus_project.team << [user, :master] + wadus_project.add_master(user) expect(subject.execute(project).to_a).to eq([wadus_project, foo_project]) expect(subject.execute(project, search: 'wadus').to_a).to eq([wadus_project]) diff --git a/spec/finders/notes_finder_spec.rb b/spec/finders/notes_finder_spec.rb index 900fa2b12d1..7b43494eea2 100644 --- a/spec/finders/notes_finder_spec.rb +++ b/spec/finders/notes_finder_spec.rb @@ -5,7 +5,7 @@ describe NotesFinder do let(:project) { create(:project) } before do - project.team << [user, :master] + project.add_master(user) end describe '#execute' do @@ -147,7 +147,7 @@ describe NotesFinder do it 'raises an error for project members with guest role' do user = create(:user) - project.team << [user, :guest] + project.add_guest(user) expect { described_class.new(project, user, params).execute }.to raise_error(ActiveRecord::RecordNotFound) end @@ -189,7 +189,7 @@ describe NotesFinder do it "does not return notes with matching content for project members with guest role" do user = create(:user) - project.team << [user, :guest] + project.add_guest(user) expect(described_class.new(confidential_note.project, user, search: confidential_note.note).execute).to be_empty end diff --git a/spec/finders/personal_projects_finder_spec.rb b/spec/finders/personal_projects_finder_spec.rb index d0113ba87df..5e52898e9c0 100644 --- a/spec/finders/personal_projects_finder_spec.rb +++ b/spec/finders/personal_projects_finder_spec.rb @@ -15,7 +15,7 @@ describe PersonalProjectsFinder do end before do - private_project.team << [current_user, Gitlab::Access::DEVELOPER] + private_project.add_developer(current_user) end describe 'without a current user' do diff --git a/spec/finders/snippets_finder_spec.rb b/spec/finders/snippets_finder_spec.rb index 7ae7b7d2140..0a018d2b417 100644 --- a/spec/finders/snippets_finder_spec.rb +++ b/spec/finders/snippets_finder_spec.rb @@ -188,7 +188,7 @@ describe SnippetsFinder do end it "returns all snippets for project members" do - project1.team << [user, :developer] + project1.add_developer(user) snippets = described_class.new(user, project: project1).execute @@ -196,7 +196,7 @@ describe SnippetsFinder do end it "returns private snippets for project members" do - project1.team << [user, :developer] + project1.add_developer(user) snippets = described_class.new(user, project: project1, visibility: Snippet::PRIVATE).execute diff --git a/spec/finders/todos_finder_spec.rb b/spec/finders/todos_finder_spec.rb index 884ce22091e..90eb0fe21e4 100644 --- a/spec/finders/todos_finder_spec.rb +++ b/spec/finders/todos_finder_spec.rb @@ -7,7 +7,7 @@ describe TodosFinder do let(:finder) { described_class } before do - project.team << [user, :developer] + project.add_developer(user) end describe '#sort' do diff --git a/spec/fixtures/api/schemas/entities/merge_request_metrics.json b/spec/fixtures/api/schemas/entities/merge_request_metrics.json new file mode 100644 index 00000000000..3fa767f85df --- /dev/null +++ b/spec/fixtures/api/schemas/entities/merge_request_metrics.json @@ -0,0 +1,21 @@ +{ + "type": "object", + "required": ["closed_at", "merged_at", "closed_by", "merged_by"], + "properties" : { + "closed_at": { "type": ["datetime", "null"] }, + "merged_at": { "type": ["datetime", "null"] }, + "closed_by": { + "oneOf": [ + { "type": "null" }, + { "$ref": "user.json" } + ] + }, + "merged_by": { + "oneOf": [ + { "type": "null" }, + { "$ref": "user.json" } + ] + } + }, + "additionalProperties": false +} diff --git a/spec/fixtures/api/schemas/entities/merge_request_widget.json b/spec/fixtures/api/schemas/entities/merge_request_widget.json index 342890c3dee..9de27bee751 100644 --- a/spec/fixtures/api/schemas/entities/merge_request_widget.json +++ b/spec/fixtures/api/schemas/entities/merge_request_widget.json @@ -31,8 +31,12 @@ "source_project_id": { "type": "integer" }, "target_branch": { "type": "string" }, "target_project_id": { "type": "integer" }, - "merge_event": { "type": ["object", "null"] }, - "closed_event": { "type": ["object", "null"] }, + "metrics": { + "oneOf": [ + { "type": "null" }, + { "$ref": "merge_request_metrics.json" } + ] + }, "author": { "type": ["object", "null"] }, "merge_user": { "type": ["object", "null"] }, "diff_head_sha": { "type": ["string", "null"] }, diff --git a/spec/fixtures/api/schemas/entities/user.json b/spec/fixtures/api/schemas/entities/user.json new file mode 100644 index 00000000000..6482e0eedd2 --- /dev/null +++ b/spec/fixtures/api/schemas/entities/user.json @@ -0,0 +1,17 @@ +{ + "type": "object", + "required": [ + "id", + "state", + "avatar_url", + "web_url", + "path" + ], + "properties": { + "id": { "type": "integer" }, + "state": { "type": "string" }, + "avatar_url": { "type": "string" }, + "web_url": { "type": "string" }, + "path": { "type": "string" } + } +} diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb index ba0039f3a11..c0dc9293397 100644 --- a/spec/helpers/markup_helper_spec.rb +++ b/spec/helpers/markup_helper_spec.rb @@ -11,7 +11,7 @@ describe MarkupHelper do before do # Ensure the generated reference links aren't redacted - project.team << [user, :master] + project.add_master(user) # Helper expects a @project instance variable helper.instance_variable_set(:@project, project) diff --git a/spec/helpers/notes_helper_spec.rb b/spec/helpers/notes_helper_spec.rb index 36a44f8567a..b992bdb4a5e 100644 --- a/spec/helpers/notes_helper_spec.rb +++ b/spec/helpers/notes_helper_spec.rb @@ -17,9 +17,9 @@ describe NotesHelper do before do group.add_owner(owner) - project.team << [master, :master] - project.team << [reporter, :reporter] - project.team << [guest, :guest] + project.add_master(master) + project.add_reporter(reporter) + project.add_guest(guest) end describe "#notes_max_access_for_users" do @@ -31,7 +31,7 @@ describe NotesHelper do it 'handles access in different projects' do second_project = create(:project) - second_project.team << [master, :reporter] + second_project.add_reporter(master) other_note = create(:note, author: master, project: second_project) expect(helper.note_max_access_for_user(master_note)).to eq(Gitlab::Access::MASTER) diff --git a/spec/javascripts/blob/notebook/index_spec.js b/spec/javascripts/blob/notebook/index_spec.js index c3e67550f05..df1b2c9960b 100644 --- a/spec/javascripts/blob/notebook/index_spec.js +++ b/spec/javascripts/blob/notebook/index_spec.js @@ -1,4 +1,5 @@ -import Vue from 'vue'; +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; import renderNotebook from '~/blob/notebook'; describe('iPython notebook renderer', () => { @@ -17,8 +18,11 @@ describe('iPython notebook renderer', () => { }); describe('successful response', () => { - const response = (request, next) => { - next(request.respondWith(JSON.stringify({ + let mock; + + beforeEach((done) => { + mock = new MockAdapter(axios); + mock.onGet('/test').reply(200, { cells: [{ cell_type: 'markdown', source: ['# test'], @@ -31,13 +35,7 @@ describe('iPython notebook renderer', () => { ], outputs: [], }], - }), { - status: 200, - })); - }; - - beforeEach((done) => { - Vue.http.interceptors.push(response); + }); renderNotebook(); @@ -47,9 +45,7 @@ describe('iPython notebook renderer', () => { }); afterEach(() => { - Vue.http.interceptors = _.without( - Vue.http.interceptors, response, - ); + mock.reset(); }); it('does not show loading icon', () => { @@ -86,14 +82,11 @@ describe('iPython notebook renderer', () => { }); describe('error in JSON response', () => { - const response = (request, next) => { - next(request.respondWith('{ "cells": [{"cell_type": "markdown"} }', { - status: 200, - })); - }; + let mock; beforeEach((done) => { - Vue.http.interceptors.push(response); + mock = new MockAdapter(axios); + mock.onGet('/test').reply(() => Promise.reject({ status: 200, data: '{ "cells": [{"cell_type": "markdown"} }' })); renderNotebook(); @@ -103,9 +96,7 @@ describe('iPython notebook renderer', () => { }); afterEach(() => { - Vue.http.interceptors = _.without( - Vue.http.interceptors, response, - ); + mock.reset(); }); it('does not show loading icon', () => { @@ -122,14 +113,11 @@ describe('iPython notebook renderer', () => { }); describe('error getting file', () => { - const response = (request, next) => { - next(request.respondWith('', { - status: 500, - })); - }; + let mock; beforeEach((done) => { - Vue.http.interceptors.push(response); + mock = new MockAdapter(axios); + mock.onGet('/test').reply(500, ''); renderNotebook(); @@ -139,9 +127,7 @@ describe('iPython notebook renderer', () => { }); afterEach(() => { - Vue.http.interceptors = _.without( - Vue.http.interceptors, response, - ); + mock.reset(); }); it('does not show loading icon', () => { diff --git a/spec/javascripts/boards/board_blank_state_spec.js b/spec/javascripts/boards/board_blank_state_spec.js index 2ee3792dd65..f757dadfada 100644 --- a/spec/javascripts/boards/board_blank_state_spec.js +++ b/spec/javascripts/boards/board_blank_state_spec.js @@ -1,9 +1,8 @@ /* global BoardService */ -/* global mockBoardService */ import Vue from 'vue'; import '~/boards/stores/boards_store'; import boardBlankState from '~/boards/components/board_blank_state'; -import './mock_data'; +import { mockBoardService } from './mock_data'; describe('Boards blank state', () => { let vm; @@ -20,17 +19,15 @@ describe('Boards blank state', () => { reject(); } else { resolve({ - json() { - return [{ - id: 1, - title: 'To Do', - label: { id: 1 }, - }, { - id: 2, - title: 'Doing', - label: { id: 2 }, - }]; - }, + data: [{ + id: 1, + title: 'To Do', + label: { id: 1 }, + }, { + id: 2, + title: 'Doing', + label: { id: 2 }, + }], }); } })); diff --git a/spec/javascripts/boards/board_card_spec.js b/spec/javascripts/boards/board_card_spec.js index 8f607899b20..4e73fa1fe87 100644 --- a/spec/javascripts/boards/board_card_spec.js +++ b/spec/javascripts/boards/board_card_spec.js @@ -1,12 +1,11 @@ /* global List */ /* global ListAssignee */ /* global ListLabel */ -/* global listObj */ -/* global boardsMockInterceptor */ /* global BoardService */ -/* global mockBoardService */ import Vue from 'vue'; +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; import '~/boards/models/assignee'; import eventHub from '~/boards/eventhub'; @@ -14,13 +13,15 @@ import '~/boards/models/list'; import '~/boards/models/label'; import '~/boards/stores/boards_store'; import boardCard from '~/boards/components/board_card.vue'; -import './mock_data'; +import { listObj, boardsMockInterceptor, mockBoardService } from './mock_data'; describe('Board card', () => { let vm; + let mock; beforeEach((done) => { - Vue.http.interceptors.push(boardsMockInterceptor); + mock = new MockAdapter(axios); + mock.onAny().reply(boardsMockInterceptor); gl.boardService = mockBoardService(); gl.issueBoards.BoardsStore.create(); @@ -54,7 +55,7 @@ describe('Board card', () => { }); afterEach(() => { - Vue.http.interceptors = _.without(Vue.http.interceptors, boardsMockInterceptor); + mock.reset(); }); it('returns false when detailIssue is empty', () => { diff --git a/spec/javascripts/boards/board_list_spec.js b/spec/javascripts/boards/board_list_spec.js index 6bd00943a8f..7c5888b6d82 100644 --- a/spec/javascripts/boards/board_list_spec.js +++ b/spec/javascripts/boards/board_list_spec.js @@ -1,11 +1,9 @@ /* global BoardService */ -/* global boardsMockInterceptor */ /* global List */ -/* global listObj */ /* global ListIssue */ -/* global mockBoardService */ import Vue from 'vue'; -import _ from 'underscore'; +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; import Sortable from 'vendor/Sortable'; import BoardList from '~/boards/components/board_list'; import eventHub from '~/boards/eventhub'; @@ -13,18 +11,20 @@ import '~/boards/mixins/sortable_default_options'; import '~/boards/models/issue'; import '~/boards/models/list'; import '~/boards/stores/boards_store'; -import './mock_data'; +import { listObj, boardsMockInterceptor, mockBoardService } from './mock_data'; window.Sortable = Sortable; describe('Board list component', () => { + let mock; let component; beforeEach((done) => { const el = document.createElement('div'); document.body.appendChild(el); - Vue.http.interceptors.push(boardsMockInterceptor); + mock = new MockAdapter(axios); + mock.onAny().reply(boardsMockInterceptor); gl.boardService = mockBoardService(); gl.issueBoards.BoardsStore.create(); gl.IssueBoardsApp = new Vue(); @@ -60,7 +60,7 @@ describe('Board list component', () => { }); afterEach(() => { - Vue.http.interceptors = _.without(Vue.http.interceptors, boardsMockInterceptor); + mock.reset(); }); it('renders component', () => { diff --git a/spec/javascripts/boards/board_new_issue_spec.js b/spec/javascripts/boards/board_new_issue_spec.js index 02e6692dda8..c62c537841c 100644 --- a/spec/javascripts/boards/board_new_issue_spec.js +++ b/spec/javascripts/boards/board_new_issue_spec.js @@ -1,24 +1,22 @@ -/* global boardsMockInterceptor */ /* global BoardService */ /* global List */ -/* global listObj */ -/* global mockBoardService */ import Vue from 'vue'; +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; import boardNewIssue from '~/boards/components/board_new_issue'; import '~/boards/models/list'; -import './mock_data'; +import { listObj, boardsMockInterceptor, mockBoardService } from './mock_data'; describe('Issue boards new issue form', () => { let vm; let list; + let mock; let newIssueMock; const promiseReturn = { - json() { - return { - iid: 100, - }; + data: { + iid: 100, }, }; @@ -35,7 +33,9 @@ describe('Issue boards new issue form', () => { const BoardNewIssueComp = Vue.extend(boardNewIssue); - Vue.http.interceptors.push(boardsMockInterceptor); + mock = new MockAdapter(axios); + mock.onAny().reply(boardsMockInterceptor); + gl.boardService = mockBoardService(); gl.issueBoards.BoardsStore.create(); gl.IssueBoardsApp = new Vue(); @@ -56,7 +56,10 @@ describe('Issue boards new issue form', () => { .catch(done.fail); }); - afterEach(() => vm.$destroy()); + afterEach(() => { + vm.$destroy(); + mock.reset(); + }); it('calls submit if submit button is clicked', (done) => { spyOn(vm, 'submit').and.callFake(e => e.preventDefault()); diff --git a/spec/javascripts/boards/boards_store_spec.js b/spec/javascripts/boards/boards_store_spec.js index 0e656858182..49fb20f4c84 100644 --- a/spec/javascripts/boards/boards_store_spec.js +++ b/spec/javascripts/boards/boards_store_spec.js @@ -1,12 +1,10 @@ /* eslint-disable comma-dangle, one-var, no-unused-vars */ /* global BoardService */ -/* global boardsMockInterceptor */ -/* global listObj */ -/* global listObjDuplicate */ /* global ListIssue */ -/* global mockBoardService */ import Vue from 'vue'; +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; import Cookies from 'js-cookie'; import '~/boards/models/issue'; @@ -15,11 +13,14 @@ import '~/boards/models/list'; import '~/boards/models/assignee'; import '~/boards/services/board_service'; import '~/boards/stores/boards_store'; -import './mock_data'; +import { listObj, listObjDuplicate, boardsMockInterceptor, mockBoardService } from './mock_data'; describe('Store', () => { + let mock; + beforeEach(() => { - Vue.http.interceptors.push(boardsMockInterceptor); + mock = new MockAdapter(axios); + mock.onAny().reply(boardsMockInterceptor); gl.boardService = mockBoardService(); gl.issueBoards.BoardsStore.create(); @@ -34,7 +35,7 @@ describe('Store', () => { }); afterEach(() => { - Vue.http.interceptors = _.without(Vue.http.interceptors, boardsMockInterceptor); + mock.reset(); }); it('starts with a blank state', () => { diff --git a/spec/javascripts/boards/components/board_spec.js b/spec/javascripts/boards/components/board_spec.js index 8dacac20cad..19346e305cf 100644 --- a/spec/javascripts/boards/components/board_spec.js +++ b/spec/javascripts/boards/components/board_spec.js @@ -1,9 +1,8 @@ -/* global mockBoardService */ import Vue from 'vue'; import '~/boards/services/board_service'; import '~/boards/components/board'; import '~/boards/models/list'; -import '../mock_data'; +import { mockBoardService } from '../mock_data'; describe('Board component', () => { let vm; diff --git a/spec/javascripts/boards/issue_card_spec.js b/spec/javascripts/boards/issue_card_spec.js index 7d430ec35e2..8ef221257be 100644 --- a/spec/javascripts/boards/issue_card_spec.js +++ b/spec/javascripts/boards/issue_card_spec.js @@ -1,6 +1,5 @@ /* global ListAssignee */ /* global ListLabel */ -/* global listObj */ /* global ListIssue */ import Vue from 'vue'; @@ -11,7 +10,7 @@ import '~/boards/models/list'; import '~/boards/models/assignee'; import '~/boards/stores/boards_store'; import '~/boards/components/issue_card_inner'; -import './mock_data'; +import { listObj } from './mock_data'; describe('Issue card component', () => { const user = new ListAssignee({ diff --git a/spec/javascripts/boards/issue_spec.js b/spec/javascripts/boards/issue_spec.js index 41dcb19df3c..dbbe14fe3e0 100644 --- a/spec/javascripts/boards/issue_spec.js +++ b/spec/javascripts/boards/issue_spec.js @@ -1,7 +1,6 @@ /* eslint-disable comma-dangle */ /* global BoardService */ /* global ListIssue */ -/* global mockBoardService */ import Vue from 'vue'; import '~/boards/models/issue'; @@ -10,7 +9,7 @@ import '~/boards/models/list'; import '~/boards/models/assignee'; import '~/boards/services/board_service'; import '~/boards/stores/boards_store'; -import './mock_data'; +import { mockBoardService } from './mock_data'; describe('Issue model', () => { let issue; diff --git a/spec/javascripts/boards/list_spec.js b/spec/javascripts/boards/list_spec.js index eead396ca7e..645ce831b53 100644 --- a/spec/javascripts/boards/list_spec.js +++ b/spec/javascripts/boards/list_spec.js @@ -1,13 +1,10 @@ /* eslint-disable comma-dangle */ -/* global boardsMockInterceptor */ /* global BoardService */ -/* global mockBoardService */ /* global List */ /* global ListIssue */ -/* global listObj */ -/* global listObjDuplicate */ -import Vue from 'vue'; +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; import '~/boards/models/issue'; import '~/boards/models/label'; @@ -15,13 +12,15 @@ import '~/boards/models/list'; import '~/boards/models/assignee'; import '~/boards/services/board_service'; import '~/boards/stores/boards_store'; -import './mock_data'; +import { listObj, listObjDuplicate, boardsMockInterceptor, mockBoardService } from './mock_data'; describe('List model', () => { let list; + let mock; beforeEach(() => { - Vue.http.interceptors.push(boardsMockInterceptor); + mock = new MockAdapter(axios); + mock.onAny().reply(boardsMockInterceptor); gl.boardService = mockBoardService({ bulkUpdatePath: '/test/issue-boards/board/1/lists', }); @@ -31,7 +30,7 @@ describe('List model', () => { }); afterEach(() => { - Vue.http.interceptors = _.without(Vue.http.interceptors, boardsMockInterceptor); + mock.reset(); }); it('gets issues when created', (done) => { @@ -158,10 +157,8 @@ describe('List model', () => { describe('newIssue', () => { beforeEach(() => { spyOn(gl.boardService, 'newIssue').and.returnValue(Promise.resolve({ - json() { - return { - id: 42, - }; + data: { + id: 42, }, })); }); diff --git a/spec/javascripts/boards/mock_data.js b/spec/javascripts/boards/mock_data.js index 0a93086985e..9ae2d535398 100644 --- a/spec/javascripts/boards/mock_data.js +++ b/spec/javascripts/boards/mock_data.js @@ -1,20 +1,20 @@ /* global BoardService */ /* eslint-disable comma-dangle, no-unused-vars, quote-props */ -const listObj = { - id: _.random(10000), +export const listObj = { + id: 300, position: 0, title: 'Test', list_type: 'label', label: { - id: _.random(10000), + id: 5000, title: 'Testing', color: 'red', description: 'testing;' } }; -const listObjDuplicate = { +export const listObjDuplicate = { id: listObj.id, position: 1, title: 'Test', @@ -27,9 +27,9 @@ const listObjDuplicate = { } }; -const BoardsMockData = { +export const BoardsMockData = { 'GET': { - '/test/boards/1{/id}/issues': { + '/test/-/boards/1/lists/300/issues?id=300&page=1&=': { issues: [{ title: 'Testing', id: 1, @@ -41,7 +41,7 @@ const BoardsMockData = { } }, 'POST': { - '/test/boards/1{/id}': listObj + '/test/-/boards/1/lists': listObj }, 'PUT': { '/test/issue-boards/board/1/lists{/id}': {} @@ -51,17 +51,14 @@ const BoardsMockData = { } }; -const boardsMockInterceptor = (request, next) => { - const body = BoardsMockData[request.method][request.url]; - - next(request.respondWith(JSON.stringify(body), { - status: 200 - })); +export const boardsMockInterceptor = (config) => { + const body = BoardsMockData[config.method.toUpperCase()][config.url]; + return [200, body]; }; -const mockBoardService = (opts = {}) => { - const boardsEndpoint = opts.boardsEndpoint || '/test/issue-boards/board'; - const listsEndpoint = opts.listsEndpoint || '/test/boards/1'; +export const mockBoardService = (opts = {}) => { + const boardsEndpoint = opts.boardsEndpoint || '/test/issue-boards/boards.json'; + const listsEndpoint = opts.listsEndpoint || '/test/-/boards/1/lists'; const bulkUpdatePath = opts.bulkUpdatePath || ''; const boardId = opts.boardId || '1'; @@ -72,9 +69,3 @@ const mockBoardService = (opts = {}) => { boardId, }); }; - -window.listObj = listObj; -window.listObjDuplicate = listObjDuplicate; -window.BoardsMockData = BoardsMockData; -window.boardsMockInterceptor = boardsMockInterceptor; -window.mockBoardService = mockBoardService; diff --git a/spec/javascripts/filtered_search/filtered_search_manager_spec.js b/spec/javascripts/filtered_search/filtered_search_manager_spec.js index 5111632d681..b8890e4cda1 100644 --- a/spec/javascripts/filtered_search/filtered_search_manager_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_manager_spec.js @@ -252,6 +252,7 @@ describe('Filtered Search Manager', () => { it('removes last token', () => { spyOn(gl.FilteredSearchVisualTokens, 'removeLastTokenPartial').and.callThrough(); dispatchBackspaceEvent(input, 'keyup'); + dispatchBackspaceEvent(input, 'keyup'); expect(gl.FilteredSearchVisualTokens.removeLastTokenPartial).toHaveBeenCalled(); }); @@ -259,6 +260,7 @@ describe('Filtered Search Manager', () => { it('sets the input', () => { spyOn(gl.FilteredSearchVisualTokens, 'getLastTokenPartial').and.callThrough(); dispatchDeleteEvent(input, 'keyup'); + dispatchDeleteEvent(input, 'keyup'); expect(gl.FilteredSearchVisualTokens.getLastTokenPartial).toHaveBeenCalled(); expect(input.value).toEqual('~bug'); @@ -276,6 +278,18 @@ describe('Filtered Search Manager', () => { expect(gl.FilteredSearchVisualTokens.getLastTokenPartial).not.toHaveBeenCalled(); expect(input.value).toEqual('text'); }); + + it('does not remove previous token on single backspace press', () => { + spyOn(gl.FilteredSearchVisualTokens, 'removeLastTokenPartial').and.callThrough(); + spyOn(gl.FilteredSearchVisualTokens, 'getLastTokenPartial').and.callThrough(); + + input.value = 't'; + dispatchDeleteEvent(input, 'keyup'); + + expect(gl.FilteredSearchVisualTokens.removeLastTokenPartial).not.toHaveBeenCalled(); + expect(gl.FilteredSearchVisualTokens.getLastTokenPartial).not.toHaveBeenCalled(); + expect(input.value).toEqual('t'); + }); }); describe('removeToken', () => { diff --git a/spec/javascripts/groups/components/item_caret_spec.js b/spec/javascripts/groups/components/item_caret_spec.js index 4310a07e6e6..8faad455825 100644 --- a/spec/javascripts/groups/components/item_caret_spec.js +++ b/spec/javascripts/groups/components/item_caret_spec.js @@ -16,24 +16,20 @@ describe('ItemCaretComponent', () => { describe('template', () => { it('should render component template correctly', () => { const vm = createComponent(); - vm.$mount(); expect(vm.$el.classList.contains('folder-caret')).toBeTruthy(); + expect(vm.$el.querySelectorAll('svg').length).toBe(1); vm.$destroy(); }); it('should render caret down icon if `isGroupOpen` prop is `true`', () => { const vm = createComponent(true); - vm.$mount(); - expect(vm.$el.querySelectorAll('i.fa.fa-caret-down').length).toBe(1); - expect(vm.$el.querySelectorAll('i.fa.fa-caret-right').length).toBe(0); + expect(vm.$el.querySelector('svg use').getAttribute('xlink:href')).toContain('angle-down'); vm.$destroy(); }); it('should render caret right icon if `isGroupOpen` prop is `false`', () => { const vm = createComponent(); - vm.$mount(); - expect(vm.$el.querySelectorAll('i.fa.fa-caret-down').length).toBe(0); - expect(vm.$el.querySelectorAll('i.fa.fa-caret-right').length).toBe(1); + expect(vm.$el.querySelector('svg use').getAttribute('xlink:href')).toContain('angle-right'); vm.$destroy(); }); }); diff --git a/spec/javascripts/groups/components/item_stats_spec.js b/spec/javascripts/groups/components/item_stats_spec.js index e200f9f08bd..55a7a713ca6 100644 --- a/spec/javascripts/groups/components/item_stats_spec.js +++ b/spec/javascripts/groups/components/item_stats_spec.js @@ -26,7 +26,6 @@ describe('ItemStatsComponent', () => { Object.keys(VISIBILITY_TYPE_ICON).forEach((visibility) => { const item = Object.assign({}, mockParentGroupItem, { visibility }); const vm = createComponent(item); - vm.$mount(); expect(vm.visibilityIcon).toBe(VISIBILITY_TYPE_ICON[visibility]); vm.$destroy(); }); @@ -41,7 +40,6 @@ describe('ItemStatsComponent', () => { type: ITEM_TYPE.GROUP, }); const vm = createComponent(item); - vm.$mount(); expect(vm.visibilityTooltip).toBe(GROUP_VISIBILITY_TYPE[visibility]); vm.$destroy(); }); @@ -54,7 +52,6 @@ describe('ItemStatsComponent', () => { type: ITEM_TYPE.PROJECT, }); const vm = createComponent(item); - vm.$mount(); expect(vm.visibilityTooltip).toBe(PROJECT_VISIBILITY_TYPE[visibility]); vm.$destroy(); }); @@ -68,13 +65,11 @@ describe('ItemStatsComponent', () => { item = Object.assign({}, mockParentGroupItem, { type: ITEM_TYPE.PROJECT }); vm = createComponent(item); - vm.$mount(); expect(vm.isProject).toBeTruthy(); vm.$destroy(); item = Object.assign({}, mockParentGroupItem, { type: ITEM_TYPE.GROUP }); vm = createComponent(item); - vm.$mount(); expect(vm.isProject).toBeFalsy(); vm.$destroy(); }); @@ -87,13 +82,11 @@ describe('ItemStatsComponent', () => { item = Object.assign({}, mockParentGroupItem, { type: ITEM_TYPE.GROUP }); vm = createComponent(item); - vm.$mount(); expect(vm.isGroup).toBeTruthy(); vm.$destroy(); item = Object.assign({}, mockParentGroupItem, { type: ITEM_TYPE.PROJECT }); vm = createComponent(item); - vm.$mount(); expect(vm.isGroup).toBeFalsy(); vm.$destroy(); }); @@ -101,57 +94,37 @@ describe('ItemStatsComponent', () => { }); describe('template', () => { - it('should render component template correctly', () => { + it('renders component container element correctly', () => { const vm = createComponent(); - vm.$mount(); - const visibilityIconEl = vm.$el.querySelector('.item-visibility'); - expect(vm.$el.classList.contains('.stats')).toBeDefined(); - expect(visibilityIconEl).toBeDefined(); - expect(visibilityIconEl.dataset.originalTitle).toBe(vm.visibilityTooltip); - expect(visibilityIconEl.querySelector('i.fa')).toBeDefined(); + expect(vm.$el.classList.contains('stats')).toBeTruthy(); vm.$destroy(); }); - it('should render stat icons if `item.type` is Group', () => { - const item = Object.assign({}, mockParentGroupItem, { type: ITEM_TYPE.GROUP }); - const vm = createComponent(item); - vm.$mount(); - - const subgroupIconEl = vm.$el.querySelector('span.number-subgroups'); - expect(subgroupIconEl).toBeDefined(); - expect(subgroupIconEl.dataset.originalTitle).toBe('Subgroups'); - expect(subgroupIconEl.querySelector('i.fa.fa-folder')).toBeDefined(); - expect(subgroupIconEl.innerText.trim()).toBe(`${vm.item.subgroupCount}`); - - const projectsIconEl = vm.$el.querySelector('span.number-projects'); - expect(projectsIconEl).toBeDefined(); - expect(projectsIconEl.dataset.originalTitle).toBe('Projects'); - expect(projectsIconEl.querySelector('i.fa.fa-bookmark')).toBeDefined(); - expect(projectsIconEl.innerText.trim()).toBe(`${vm.item.projectCount}`); - - const membersIconEl = vm.$el.querySelector('span.number-users'); - expect(membersIconEl).toBeDefined(); - expect(membersIconEl.dataset.originalTitle).toBe('Members'); - expect(membersIconEl.querySelector('i.fa.fa-users')).toBeDefined(); - expect(membersIconEl.innerText.trim()).toBe(`${vm.item.memberCount}`); + it('renders item visibility icon and tooltip correctly', () => { + const vm = createComponent(); + + const visibilityIconEl = vm.$el.querySelector('.item-visibility'); + expect(visibilityIconEl).not.toBe(null); + expect(visibilityIconEl.dataset.originalTitle).toBe(vm.visibilityTooltip); + expect(visibilityIconEl.querySelectorAll('svg').length > 0).toBeTruthy(); vm.$destroy(); }); - it('should render stat icons if `item.type` is Project', () => { + it('renders start count and last updated information for project item correctly', () => { const item = Object.assign({}, mockParentGroupItem, { type: ITEM_TYPE.PROJECT, starCount: 4, }); const vm = createComponent(item); - vm.$mount(); const projectStarIconEl = vm.$el.querySelector('.project-stars'); - expect(projectStarIconEl).toBeDefined(); - expect(projectStarIconEl.querySelector('i.fa.fa-star')).toBeDefined(); - expect(projectStarIconEl.innerText.trim()).toBe(`${vm.item.starCount}`); + expect(projectStarIconEl).not.toBe(null); + expect(projectStarIconEl.querySelectorAll('svg').length > 0).toBeTruthy(); + expect(projectStarIconEl.querySelectorAll('.stat-value').length > 0).toBeTruthy(); + expect(vm.$el.querySelectorAll('.last-updated').length > 0).toBeTruthy(); vm.$destroy(); }); diff --git a/spec/javascripts/groups/components/item_stats_value_spec.js b/spec/javascripts/groups/components/item_stats_value_spec.js new file mode 100644 index 00000000000..e990870aaa6 --- /dev/null +++ b/spec/javascripts/groups/components/item_stats_value_spec.js @@ -0,0 +1,81 @@ +import Vue from 'vue'; + +import itemStatsValueComponent from '~/groups/components/item_stats_value.vue'; + +import mountComponent from '../../helpers/vue_mount_component_helper'; + +const createComponent = ({ title, cssClass, iconName, tooltipPlacement, value }) => { + const Component = Vue.extend(itemStatsValueComponent); + + return mountComponent(Component, { + title, + cssClass, + iconName, + tooltipPlacement, + value, + }); +}; + +describe('ItemStatsValueComponent', () => { + describe('computed', () => { + let vm; + const itemConfig = { + title: 'Subgroups', + cssClass: 'number-subgroups', + iconName: 'folder', + tooltipPlacement: 'left', + }; + + describe('isValuePresent', () => { + it('returns true if non-empty `value` is present', () => { + vm = createComponent(Object.assign({}, itemConfig, { value: 10 })); + expect(vm.isValuePresent).toBeTruthy(); + }); + + it('returns false if empty `value` is present', () => { + vm = createComponent(itemConfig); + expect(vm.isValuePresent).toBeFalsy(); + }); + + afterEach(() => { + vm.$destroy(); + }); + }); + }); + + describe('template', () => { + let vm; + beforeEach(() => { + vm = createComponent({ + title: 'Subgroups', + cssClass: 'number-subgroups', + iconName: 'folder', + tooltipPlacement: 'left', + value: 10, + }); + }); + + it('renders component element correctly', () => { + expect(vm.$el.classList.contains('number-subgroups')).toBeTruthy(); + expect(vm.$el.querySelectorAll('svg').length > 0).toBeTruthy(); + expect(vm.$el.querySelectorAll('.stat-value').length > 0).toBeTruthy(); + }); + + it('renders element tooltip correctly', () => { + expect(vm.$el.dataset.originalTitle).toBe('Subgroups'); + expect(vm.$el.dataset.placement).toBe('left'); + }); + + it('renders element icon correctly', () => { + expect(vm.$el.querySelector('svg use').getAttribute('xlink:href')).toContain('folder'); + }); + + it('renders value count correctly', () => { + expect(vm.$el.querySelector('.stat-value').innerText.trim()).toContain('10'); + }); + + afterEach(() => { + vm.$destroy(); + }); + }); +}); diff --git a/spec/javascripts/groups/components/item_type_icon_spec.js b/spec/javascripts/groups/components/item_type_icon_spec.js index 528e6ed1b4c..495cc97b475 100644 --- a/spec/javascripts/groups/components/item_type_icon_spec.js +++ b/spec/javascripts/groups/components/item_type_icon_spec.js @@ -28,12 +28,12 @@ describe('ItemTypeIconComponent', () => { vm = createComponent(ITEM_TYPE.GROUP, true); vm.$mount(); - expect(vm.$el.querySelector('i.fa.fa-folder-open')).toBeDefined(); + expect(vm.$el.querySelector('use').getAttribute('xlink:href')).toContain('folder-open'); vm.$destroy(); vm = createComponent(ITEM_TYPE.GROUP); vm.$mount(); - expect(vm.$el.querySelector('i.fa.fa-folder')).toBeDefined(); + expect(vm.$el.querySelector('use').getAttribute('xlink:href')).toContain('folder'); vm.$destroy(); }); @@ -42,12 +42,12 @@ describe('ItemTypeIconComponent', () => { vm = createComponent(ITEM_TYPE.PROJECT); vm.$mount(); - expect(vm.$el.querySelectorAll('i.fa.fa-bookmark').length).toBe(1); + expect(vm.$el.querySelector('use').getAttribute('xlink:href')).toContain('bookmark'); vm.$destroy(); vm = createComponent(ITEM_TYPE.GROUP); vm.$mount(); - expect(vm.$el.querySelectorAll('i.fa.fa-bookmark').length).toBe(0); + expect(vm.$el.querySelector('use').getAttribute('xlink:href')).not.toContain('bookmark'); vm.$destroy(); }); }); diff --git a/spec/javascripts/groups/mock_data.js b/spec/javascripts/groups/mock_data.js index 6184d671790..8bf6417487d 100644 --- a/spec/javascripts/groups/mock_data.js +++ b/spec/javascripts/groups/mock_data.js @@ -18,9 +18,9 @@ export const PROJECT_VISIBILITY_TYPE = { }; export const VISIBILITY_TYPE_ICON = { - public: 'fa-globe', - internal: 'fa-shield', - private: 'fa-lock', + public: 'earth', + internal: 'shield', + private: 'lock', }; export const mockParentGroupItem = { @@ -46,6 +46,7 @@ export const mockParentGroupItem = { isOpen: true, isChildrenLoading: false, isBeingRemoved: false, + updatedAt: '2017-04-09T18:40:39.101Z', }; export const mockRawChildren = [ @@ -69,6 +70,7 @@ export const mockRawChildren = [ subgroup_count: 2, can_leave: false, children: [], + updated_at: '2017-04-09T18:40:39.101Z', }, ]; @@ -96,6 +98,7 @@ export const mockChildren = [ isOpen: true, isChildrenLoading: false, isBeingRemoved: false, + updatedAt: '2017-04-09T18:40:39.101Z', }, ]; @@ -119,6 +122,7 @@ export const mockGroups = [ project_count: 2, subgroup_count: 0, can_leave: false, + updated_at: '2017-04-09T18:40:39.101Z', }, { id: 67, @@ -139,6 +143,7 @@ export const mockGroups = [ project_count: 0, subgroup_count: 0, can_leave: false, + updated_at: '2017-04-09T18:40:39.101Z', }, { id: 54, @@ -159,6 +164,7 @@ export const mockGroups = [ project_count: 0, subgroup_count: 1, can_leave: false, + updated_at: '2017-04-09T18:40:39.101Z', }, { id: 5, @@ -179,6 +185,7 @@ export const mockGroups = [ project_count: 1, subgroup_count: 0, can_leave: false, + updated_at: '2017-04-09T18:40:39.101Z', }, { id: 4, @@ -199,6 +206,7 @@ export const mockGroups = [ project_count: 2, subgroup_count: 0, can_leave: false, + updated_at: '2017-04-09T18:40:39.101Z', }, { id: 3, @@ -219,6 +227,7 @@ export const mockGroups = [ project_count: 1, subgroup_count: 0, can_leave: false, + updated_at: '2017-04-09T18:40:39.101Z', }, { id: 2, @@ -239,6 +248,7 @@ export const mockGroups = [ project_count: 4, subgroup_count: 0, can_leave: false, + updated_at: '2017-04-09T18:40:39.101Z', }, ]; @@ -262,6 +272,7 @@ export const mockSearchedGroups = [ project_count: 1, subgroup_count: 2, can_leave: false, + updated_at: '2017-04-09T18:40:39.101Z', children: [ { id: 57, @@ -282,6 +293,7 @@ export const mockSearchedGroups = [ project_count: 4, subgroup_count: 2, can_leave: false, + updated_at: '2017-04-09T18:40:39.101Z', children: [ { id: 60, @@ -302,6 +314,7 @@ export const mockSearchedGroups = [ project_count: 0, subgroup_count: 1, can_leave: false, + updated_at: '2017-04-09T18:40:39.101Z', children: [ { id: 61, @@ -322,6 +335,7 @@ export const mockSearchedGroups = [ project_count: 2, subgroup_count: 0, can_leave: false, + updated_at: '2017-04-09T18:40:39.101Z', children: [ { id: 17, @@ -336,6 +350,7 @@ export const mockSearchedGroups = [ permission: null, edit_path: '/platform/hardware/bsp/kernel/common/v4.4/edit', star_count: 0, + updated_at: '2017-09-12T06:37:04.925Z', }, { id: 16, @@ -350,6 +365,7 @@ export const mockSearchedGroups = [ permission: null, edit_path: '/platform/hardware/bsp/kernel/common/v4.1/edit', star_count: 0, + updated_at: '2017-04-09T18:41:03.112Z', }, ], }, diff --git a/spec/javascripts/issue_show/components/app_spec.js b/spec/javascripts/issue_show/components/app_spec.js index 7159148f8fa..1454ca52018 100644 --- a/spec/javascripts/issue_show/components/app_spec.js +++ b/spec/javascripts/issue_show/components/app_spec.js @@ -1,4 +1,6 @@ import Vue from 'vue'; +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; import '~/render_math'; import '~/render_gfm'; import * as urlUtils from '~/lib/utils/url_utility'; @@ -11,26 +13,29 @@ function formatText(text) { return text.trim().replace(/\s\s+/g, ' '); } +const REALTIME_REQUEST_STACK = [ + issueShowData.initialRequest, + issueShowData.secondRequest, +]; + describe('Issuable output', () => { - let requestData = issueShowData.initialRequest; + let mock; + let realtimeRequestCount = 0; + let vm; document.body.innerHTML = '<span id="task_status"></span>'; - const interceptor = (request, next) => { - next(request.respondWith(JSON.stringify(requestData), { - status: 200, - })); - }; - - let vm; - beforeEach((done) => { spyOn(eventHub, '$emit'); const IssuableDescriptionComponent = Vue.extend(issuableApp); - requestData = issueShowData.initialRequest; - Vue.http.interceptors.push(interceptor); + mock = new MockAdapter(axios); + mock.onGet('/gitlab-org/gitlab-shell/issues/9/realtime_changes/realtime_changes').reply(() => { + const res = Promise.resolve([200, REALTIME_REQUEST_STACK[realtimeRequestCount]]); + realtimeRequestCount += 1; + return res; + }); vm = new IssuableDescriptionComponent({ propsData: { @@ -54,10 +59,10 @@ describe('Issuable output', () => { }); afterEach(() => { - Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor); + mock.reset(); + realtimeRequestCount = 0; vm.poll.stop(); - vm.$destroy(); }); @@ -77,7 +82,6 @@ describe('Issuable output', () => { expect(editedText.querySelector('time')).toBeTruthy(); }) .then(() => { - requestData = issueShowData.secondRequest; vm.poll.makeRequest(); }) .then(() => new Promise(resolve => setTimeout(resolve))) @@ -141,24 +145,19 @@ describe('Issuable output', () => { spyOn(vm.service, 'getData').and.callThrough(); spyOn(vm.service, 'updateIssuable').and.callFake(() => new Promise((resolve) => { resolve({ - json() { - return { - confidential: false, - web_url: location.pathname, - }; + data: { + confidential: false, + web_url: location.pathname, }, }); })); - vm.updateIssuable(); - - setTimeout(() => { - expect( - vm.service.getData, - ).toHaveBeenCalled(); - - done(); - }); + vm.updateIssuable() + .then(() => { + expect(vm.service.getData).toHaveBeenCalled(); + }) + .then(done) + .catch(done.fail); }); it('correctly updates issuable data', (done) => { @@ -166,29 +165,22 @@ describe('Issuable output', () => { resolve(); })); - vm.updateIssuable(); - - setTimeout(() => { - expect( - vm.service.updateIssuable, - ).toHaveBeenCalledWith(vm.formState); - expect( - eventHub.$emit, - ).toHaveBeenCalledWith('close.form'); - - done(); - }); + vm.updateIssuable() + .then(() => { + expect(vm.service.updateIssuable).toHaveBeenCalledWith(vm.formState); + expect(eventHub.$emit).toHaveBeenCalledWith('close.form'); + }) + .then(done) + .catch(done.fail); }); it('does not redirect if issue has not moved', (done) => { spyOn(urlUtils, 'visitUrl'); spyOn(vm.service, 'updateIssuable').and.callFake(() => new Promise((resolve) => { resolve({ - json() { - return { - web_url: location.pathname, - confidential: vm.isConfidential, - }; + data: { + web_url: location.pathname, + confidential: vm.isConfidential, }, }); })); @@ -208,11 +200,9 @@ describe('Issuable output', () => { spyOn(urlUtils, 'visitUrl'); spyOn(vm.service, 'updateIssuable').and.callFake(() => new Promise((resolve) => { resolve({ - json() { - return { - web_url: '/testing-issue-move', - confidential: vm.isConfidential, - }; + data: { + web_url: '/testing-issue-move', + confidential: vm.isConfidential, }, }); })); @@ -283,10 +273,8 @@ describe('Issuable output', () => { let modal; const promise = new Promise((resolve) => { resolve({ - json() { - return { - recaptcha_html: '<div class="g-recaptcha">recaptcha_html</div>', - }; + data: { + recaptcha_html: '<div class="g-recaptcha">recaptcha_html</div>', }, }); }); @@ -323,8 +311,8 @@ describe('Issuable output', () => { spyOn(urlUtils, 'visitUrl'); spyOn(vm.service, 'deleteIssuable').and.callFake(() => new Promise((resolve) => { resolve({ - json() { - return { web_url: '/test' }; + data: { + web_url: '/test', }, }); })); @@ -345,8 +333,8 @@ describe('Issuable output', () => { spyOn(vm.poll, 'stop').and.callThrough(); spyOn(vm.service, 'deleteIssuable').and.callFake(() => new Promise((resolve) => { resolve({ - json() { - return { web_url: '/test' }; + data: { + web_url: '/test', }, }); })); @@ -385,22 +373,21 @@ describe('Issuable output', () => { describe('open form', () => { it('shows locked warning if form is open & data is different', (done) => { - Vue.nextTick() + vm.$nextTick() .then(() => { vm.openForm(); - requestData = issueShowData.secondRequest; vm.poll.makeRequest(); }) - .then(() => new Promise(resolve => setTimeout(resolve))) + // Wait for the request + .then(vm.$nextTick) + // Wait for the successCallback to update the store state + .then(vm.$nextTick) + // Wait for the new state to flow to the Vue components + .then(vm.$nextTick) .then(() => { - expect( - vm.formState.lockedWarningVisible, - ).toBeTruthy(); - - expect( - vm.$el.querySelector('.alert'), - ).not.toBeNull(); + expect(vm.formState.lockedWarningVisible).toEqual(true); + expect(vm.$el.querySelector('.alert')).not.toBeNull(); }) .then(done) .catch(done.fail); diff --git a/spec/javascripts/issue_show/mock_data.js b/spec/javascripts/issue_show/mock_data.js index eb3111412a7..74b3efb014b 100644 --- a/spec/javascripts/issue_show/mock_data.js +++ b/spec/javascripts/issue_show/mock_data.js @@ -19,14 +19,4 @@ export default { updated_by_name: 'Other User', updated_by_path: '/other_user', }, - issueSpecRequest: { - title: '<p>this is a title</p>', - title_text: 'this is a title', - description: '<li class="task-list-item enabled"><input type="checkbox" class="task-list-item-checkbox">Task List Item</li>', - description_text: '- [ ] Task List Item', - task_status: '0 of 1 completed', - updated_at: '2017-05-15T12:31:04.428Z', - updated_by_name: 'Last User', - updated_by_path: '/last_user', - }, }; diff --git a/spec/javascripts/job_spec.js b/spec/javascripts/job_spec.js index 4f06237deb5..b740c9ed893 100644 --- a/spec/javascripts/job_spec.js +++ b/spec/javascripts/job_spec.js @@ -1,4 +1,4 @@ -import { bytesToKiB } from '~/lib/utils/number_utils'; +import { numberToHumanSize } from '~/lib/utils/number_utils'; import * as urlUtils from '~/lib/utils/url_utility'; import '~/lib/utils/datetime_utility'; import Job from '~/job'; @@ -169,7 +169,7 @@ describe('Job', () => { expect( document.querySelector('.js-truncated-info-size').textContent.trim(), - ).toEqual(`${bytesToKiB(size)}`); + ).toEqual(`${numberToHumanSize(size)}`); }); it('shows incremented size', () => { @@ -195,7 +195,7 @@ describe('Job', () => { expect( document.querySelector('.js-truncated-info-size').textContent.trim(), - ).toEqual(`${bytesToKiB(50)}`); + ).toEqual(`${numberToHumanSize(50)}`); jasmine.clock().tick(4001); @@ -209,7 +209,7 @@ describe('Job', () => { expect( document.querySelector('.js-truncated-info-size').textContent.trim(), - ).toEqual(`${bytesToKiB(60)}`); + ).toEqual(`${numberToHumanSize(60)}`); }); it('renders the raw link', () => { diff --git a/spec/javascripts/repo/components/repo_file_spec.js b/spec/javascripts/repo/components/repo_file_spec.js index e8b370f97b4..0810da87e80 100644 --- a/spec/javascripts/repo/components/repo_file_spec.js +++ b/spec/javascripts/repo/components/repo_file_spec.js @@ -32,13 +32,9 @@ describe('RepoFile', () => { vm.$mount(); const name = vm.$el.querySelector('.repo-file-name'); - const fileIcon = vm.$el.querySelector('.file-icon'); - expect(vm.$el.querySelector(`.${vm.file.icon}`).style.marginLeft).toEqual('0px'); expect(name.href).toMatch(''); expect(name.textContent.trim()).toEqual(vm.file.name); - expect(fileIcon.classList.contains(vm.file.icon)).toBeTruthy(); - expect(fileIcon.style.marginLeft).toEqual(`${vm.file.level * 10}px`); }); it('does render if hasFiles is true and is loading tree', () => { @@ -49,17 +45,6 @@ describe('RepoFile', () => { expect(vm.$el.querySelector('.fa-spin.fa-spinner')).toBeFalsy(); }); - it('renders a spinner if the file is loading', () => { - const f = file(); - f.loading = true; - vm = createComponent({ - file: f, - }); - - expect(vm.$el.querySelector('.fa-spin.fa-spinner')).not.toBeNull(); - expect(vm.$el.querySelector('.fa-spin.fa-spinner').style.marginLeft).toEqual(`${vm.file.level * 16}px`); - }); - it('does not render commit message and datetime if mini', (done) => { vm = createComponent({ file: file(), diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js index db7d083065b..6a59dc3c87e 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js @@ -95,10 +95,8 @@ describe('MRWidgetDeployment', () => { const url = '/foo/bar'; const returnPromise = () => new Promise((resolve) => { resolve({ - json() { - return { - redirect_url: url, - }; + data: { + redirect_url: url, }, }); }); diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js index 2ae3adc1f93..07ed7f7f532 100644 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js +++ b/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js @@ -155,9 +155,7 @@ describe('MemoryUsage', () => { describe('loadMetrics', () => { const returnServicePromise = () => new Promise((resolve) => { resolve({ - json() { - return metricsMockData; - }, + data: metricsMockData, }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_closed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_closed_spec.js index d23b558f4ea..1bf97bbf093 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_closed_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_closed_spec.js @@ -4,13 +4,16 @@ import closedComponent from '~/vue_merge_request_widget/components/states/mr_wid const mr = { targetBranch: 'good-branch', targetBranchPath: '/good-branch', - closedEvent: { - author: { + metrics: { + mergedBy: {}, + mergedAt: 'mergedUpdatedAt', + closedBy: { name: 'Fatih Acet', username: 'fatihacet', }, - updatedAt: 'closedEventUpdatedAt', - formattedUpdatedAt: '', + closedAt: 'closedEventUpdatedAt', + readableMergedAt: '', + readableClosedAt: '', }, updatedAt: 'mrUpdatedAt', closedAt: '1 day ago', @@ -56,7 +59,7 @@ describe('MRWidgetClosed', () => { it('should have correct elements', () => { expect(el.querySelector('h4').textContent).toContain('Closed by'); - expect(el.querySelector('h4').textContent).toContain(mr.closedEvent.author.name); + expect(el.querySelector('h4').textContent).toContain(mr.metrics.closedBy.name); expect(el.textContent).toContain('The changes were not merged into'); expect(el.querySelector('.label-branch').getAttribute('href')).toEqual(mr.targetBranchPath); expect(el.querySelector('.label-branch').textContent).toContain(mr.targetBranch); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js index 9a71d0b47d7..5f4df15bcd6 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js @@ -108,9 +108,7 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => { spyOn(eventHub, '$emit'); spyOn(vm.service, 'cancelAutomaticMerge').and.returnValue(new Promise((resolve) => { resolve({ - json() { - return mrObj; - }, + data: mrObj, }); })); @@ -129,10 +127,8 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => { spyOn(eventHub, '$emit'); spyOn(vm.service.mergeResource, 'save').and.returnValue(new Promise((resolve) => { resolve({ - json() { - return { - status: 'merge_when_pipeline_succeeds', - }; + data: { + status: 'merge_when_pipeline_succeeds', }, }); })); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js index 2714e8294fa..2dc3b72ea40 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js @@ -14,10 +14,13 @@ const createComponent = () => { canRevertInCurrentMR: true, canRemoveSourceBranch: true, sourceBranchRemoved: true, - mergedEvent: { - author: {}, - updatedAt: 'mergedUpdatedAt', - formattedUpdatedAt: '', + metrics: { + mergedBy: {}, + mergedAt: 'mergedUpdatedAt', + readableMergedAt: '', + closedBy: {}, + closedAt: 'mergedUpdatedAt', + readableClosedAt: '', }, updatedAt: 'mrUpdatedAt', targetBranch, @@ -111,10 +114,8 @@ describe('MRWidgetMerged', () => { spyOn(eventHub, '$emit'); spyOn(vm.service, 'removeSourceBranch').and.returnValue(new Promise((resolve) => { resolve({ - json() { - return { - message: 'Branch was removed', - }; + data: { + message: 'Branch was removed', }, }); })); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js index df3d29ee1f9..1127576617b 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js @@ -292,8 +292,8 @@ describe('MRWidgetReadyToMerge', () => { describe('handleMergeButtonClick', () => { const returnPromise = status => new Promise((resolve) => { resolve({ - json() { - return { status }; + data: { + status, }, }); }); @@ -364,8 +364,9 @@ describe('MRWidgetReadyToMerge', () => { describe('handleMergePolling', () => { const returnPromise = state => new Promise((resolve) => { resolve({ - json() { - return { state, source_branch_exists: true }; + data: { + state, + source_branch_exists: true, }, }); }); @@ -422,8 +423,8 @@ describe('MRWidgetReadyToMerge', () => { describe('handleRemoveBranchPolling', () => { const returnPromise = state => new Promise((resolve) => { resolve({ - json() { - return { source_branch_exists: state }; + data: { + source_branch_exists: state, }, }); }); diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js index 2cb3aaa6951..98ab61a0367 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js @@ -50,9 +50,7 @@ describe('MRWidgetWIP', () => { spyOn(eventHub, '$emit'); spyOn(vm.service, 'removeWIP').and.returnValue(new Promise((resolve) => { resolve({ - json() { - return mrObj; - }, + data: mrObj, }); })); diff --git a/spec/javascripts/vue_mr_widget/mock_data.js b/spec/javascripts/vue_mr_widget/mock_data.js index 1ad7c2d8efa..ca29c9fee32 100644 --- a/spec/javascripts/vue_mr_widget/mock_data.js +++ b/spec/javascripts/vue_mr_widget/mock_data.js @@ -33,8 +33,8 @@ export default { "source_project_id": 19, "target_branch": "master", "target_project_id": 19, - "merge_event": { - "author": { + "metrics": { + "merged_by": { "name": "Administrator", "username": "root", "id": 1, @@ -42,9 +42,10 @@ export default { "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", "web_url": "http://localhost:3000/root" }, - "updated_at": "2017-04-07T15:39:25.696Z" + "merged_at": "2017-04-07T15:39:25.696Z", + "closed_by": null, + "closed_at": null }, - "closed_event": null, "author": { "name": "Administrator", "username": "root", diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js index 74b343c573e..cd00d0a39a3 100644 --- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js +++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js @@ -8,10 +8,7 @@ import mountComponent from '../helpers/vue_mount_component_helper'; const returnPromise = data => new Promise((resolve) => { resolve({ - json() { - return data; - }, - body: data, + data, }); }); diff --git a/spec/javascripts/vue_shared/components/file_icon_spec.js b/spec/javascripts/vue_shared/components/file_icon_spec.js new file mode 100644 index 00000000000..d99b17bdc79 --- /dev/null +++ b/spec/javascripts/vue_shared/components/file_icon_spec.js @@ -0,0 +1,83 @@ +import Vue from 'vue'; +import fileIcon from '~/vue_shared/components/file_icon.vue'; +import mountComponent from '../../helpers/vue_mount_component_helper'; + +describe('File Icon component', () => { + let vm; + let FileIcon; + + beforeEach(() => { + FileIcon = Vue.extend(fileIcon); + }); + + afterEach(() => { + vm.$destroy(); + }); + + it('should render a span element with an svg', () => { + vm = mountComponent(FileIcon, { + fileName: 'test.js', + }); + + expect(vm.$el.tagName).toEqual('SPAN'); + expect(vm.$el.querySelector('span > svg')).toBeDefined(); + }); + + it('should render a javascript icon based on file ending', () => { + vm = mountComponent(FileIcon, { + fileName: 'test.js', + }); + + expect(vm.$el.firstChild.firstChild.getAttribute('xlink:href')).toBe(`${gon.sprite_file_icons}#javascript`); + }); + + it('should render a image icon based on file ending', () => { + vm = mountComponent(FileIcon, { + fileName: 'test.png', + }); + + expect(vm.$el.firstChild.firstChild.getAttribute('xlink:href')).toBe(`${gon.sprite_file_icons}#image`); + }); + + it('should render a webpack icon based on file namer', () => { + vm = mountComponent(FileIcon, { + fileName: 'webpack.js', + }); + + expect(vm.$el.firstChild.firstChild.getAttribute('xlink:href')).toBe(`${gon.sprite_file_icons}#webpack`); + }); + + it('should render a standard folder icon', () => { + vm = mountComponent(FileIcon, { + fileName: 'js', + folder: true, + }); + + expect(vm.$el.querySelector('span > svg > use').getAttribute('xlink:href')).toBe(`${gon.sprite_file_icons}#folder`); + }); + + it('should render a loading icon', () => { + vm = mountComponent(FileIcon, { + fileName: 'test.js', + loading: true, + }); + + expect( + vm.$el.querySelector('i').getAttribute('class'), + ).toEqual('fa fa-spin fa-spinner fa-1x'); + }); + + it('should add a special class and a size class', () => { + vm = mountComponent(FileIcon, { + fileName: 'test.js', + cssClasses: 'extraclasses', + size: 120, + }); + + const classList = vm.$el.firstChild.classList; + const containsSizeClass = classList.contains('s120'); + const containsCustomClass = classList.contains('extraclasses'); + expect(containsSizeClass).toBe(true); + expect(containsCustomClass).toBe(true); + }); +}); diff --git a/spec/javascripts/vue_shared/components/panel_resizer_spec.js b/spec/javascripts/vue_shared/components/panel_resizer_spec.js new file mode 100644 index 00000000000..70ce3dffaba --- /dev/null +++ b/spec/javascripts/vue_shared/components/panel_resizer_spec.js @@ -0,0 +1,59 @@ +import Vue from 'vue'; +import panelResizer from '~/vue_shared/components/panel_resizer.vue'; +import mountComponent from '../../helpers/vue_mount_component_helper'; + +describe('Panel Resizer component', () => { + let vm; + let PanelResizer; + + const triggerEvent = (eventName, el = vm.$el, clientX = 0) => { + const event = document.createEvent('MouseEvents'); + event.initMouseEvent(eventName, true, true, window, 1, clientX, 0, clientX, 0, false, false, + false, false, 0, null); + + el.dispatchEvent(event); + }; + + beforeEach(() => { + PanelResizer = Vue.extend(panelResizer); + }); + + afterEach(() => { + vm.$destroy(); + }); + + it('should render a div element with the correct classes and styles', () => { + vm = mountComponent(PanelResizer, { + startSize: 100, + side: 'left', + }); + + expect(vm.$el.tagName).toEqual('DIV'); + expect(vm.$el.getAttribute('class')).toBe('dragHandle dragleft'); + expect(vm.$el.getAttribute('style')).toBe('cursor: ew-resize;'); + }); + + it('should render a div element with the correct classes for a right side panel', () => { + vm = mountComponent(PanelResizer, { + startSize: 100, + side: 'right', + }); + + expect(vm.$el.tagName).toEqual('DIV'); + expect(vm.$el.getAttribute('class')).toBe('dragHandle dragright'); + }); + + it('drag the resizer', () => { + vm = mountComponent(PanelResizer, { + startSize: 100, + side: 'left', + }); + + spyOn(vm, '$emit'); + triggerEvent('mousedown', vm.$el); + triggerEvent('mousemove', document); + triggerEvent('mouseup', document); + expect(vm.$emit.calls.allArgs()).toEqual([['resize-start', 100], ['update:size', 100], ['resize-end', 100]]); + expect(vm.size).toBe(100); + }); +}); diff --git a/spec/lib/banzai/filter/redactor_filter_spec.rb b/spec/lib/banzai/filter/redactor_filter_spec.rb index 68643effb66..5a7858e77f3 100644 --- a/spec/lib/banzai/filter/redactor_filter_spec.rb +++ b/spec/lib/banzai/filter/redactor_filter_spec.rb @@ -46,7 +46,7 @@ describe Banzai::Filter::RedactorFilter do it 'allows permitted Project references' do user = create(:user) project = create(:project) - project.team << [user, :master] + project.add_master(user) link = reference_link(project: project.id, reference_type: 'test') doc = filter(link, current_user: user) @@ -94,7 +94,7 @@ describe Banzai::Filter::RedactorFilter do it 'removes references for project members with guest role' do member = create(:user) project = create(:project, :public) - project.team << [member, :guest] + project.add_guest(member) issue = create(:issue, :confidential, project: project) link = reference_link(project: project.id, issue: issue.id, reference_type: 'issue') @@ -128,7 +128,7 @@ describe Banzai::Filter::RedactorFilter do it 'allows references for project members' do member = create(:user) project = create(:project, :public) - project.team << [member, :developer] + project.add_developer(member) issue = create(:issue, :confidential, project: project) link = reference_link(project: project.id, issue: issue.id, reference_type: 'issue') diff --git a/spec/lib/banzai/filter/relative_link_filter_spec.rb b/spec/lib/banzai/filter/relative_link_filter_spec.rb index ef306f1cd4a..f38f0776303 100644 --- a/spec/lib/banzai/filter/relative_link_filter_spec.rb +++ b/spec/lib/banzai/filter/relative_link_filter_spec.rb @@ -76,6 +76,11 @@ describe Banzai::Filter::RelativeLinkFilter do expect { filter(act) }.not_to raise_error end + it 'does not raise an exception with a garbled path' do + act = link("open(/var/tmp/):%20/location%0Afrom:%20/test") + expect { filter(act) }.not_to raise_error + end + it 'ignores ref if commit is passed' do doc = filter(link('non/existent.file'), commit: project.commit('empty-branch') ) expect(doc.at_css('a')['href']) diff --git a/spec/lib/banzai/filter/user_reference_filter_spec.rb b/spec/lib/banzai/filter/user_reference_filter_spec.rb index fc03741976e..c76adc262fc 100644 --- a/spec/lib/banzai/filter/user_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/user_reference_filter_spec.rb @@ -34,11 +34,11 @@ describe Banzai::Filter::UserReferenceFilter do let(:reference) { User.reference_prefix + 'all' } before do - project.team << [project.creator, :developer] + project.add_developer(project.creator) end it 'supports a special @all mention' do - project.team << [user, :developer] + project.add_developer(user) doc = reference_filter("Hey #{reference}", author: user) expect(doc.css('a').length).to eq 1 @@ -47,7 +47,7 @@ describe Banzai::Filter::UserReferenceFilter do end it 'includes a data-author attribute when there is an author' do - project.team << [user, :developer] + project.add_developer(user) doc = reference_filter(reference, author: user) expect(doc.css('a').first.attr('data-author')).to eq(user.id.to_s) diff --git a/spec/lib/banzai/reference_parser/user_parser_spec.rb b/spec/lib/banzai/reference_parser/user_parser_spec.rb index e49726aca6c..b079a3be029 100644 --- a/spec/lib/banzai/reference_parser/user_parser_spec.rb +++ b/spec/lib/banzai/reference_parser/user_parser_spec.rb @@ -63,8 +63,8 @@ describe Banzai::ReferenceParser::UserParser do let(:contributor) { create(:user) } before do - project.team << [user, :developer] - project.team << [contributor, :developer] + project.add_developer(user) + project.add_developer(contributor) end it 'returns the members of a project' do @@ -162,7 +162,7 @@ describe Banzai::ReferenceParser::UserParser do context 'when the link has a data-author attribute' do it 'returns the nodes when the user is a member of the project' do other_project = create(:project) - other_project.team << [user, :developer] + other_project.add_developer(user) link['data-project'] = other_project.id.to_s link['data-author'] = user.id.to_s diff --git a/spec/lib/gitlab/background_migration/delete_conflicting_redirect_routes_range_spec.rb b/spec/lib/gitlab/background_migration/delete_conflicting_redirect_routes_range_spec.rb index 5c471cbdeda..9bae7e53b71 100644 --- a/spec/lib/gitlab/background_migration/delete_conflicting_redirect_routes_range_spec.rb +++ b/spec/lib/gitlab/background_migration/delete_conflicting_redirect_routes_range_spec.rb @@ -24,17 +24,12 @@ describe Gitlab::BackgroundMigration::DeleteConflictingRedirectRoutesRange, :mig redirect_routes.create!(source_id: 1, source_type: 'Namespace', path: 'foo5') end - it 'deletes the conflicting redirect_routes in the range' do + # No-op. See https://gitlab.com/gitlab-com/infrastructure/issues/3460#note_53223252 + it 'NO-OP: does not delete any redirect_routes' do expect(redirect_routes.count).to eq(8) - expect do - described_class.new.perform(1, 3) - end.to change { redirect_routes.where("path like 'foo%'").count }.from(5).to(2) + described_class.new.perform(1, 5) - expect do - described_class.new.perform(4, 5) - end.to change { redirect_routes.where("path like 'foo%'").count }.from(2).to(0) - - expect(redirect_routes.count).to eq(3) + expect(redirect_routes.count).to eq(8) end end diff --git a/spec/lib/gitlab/background_migration/migrate_events_to_push_event_payloads_spec.rb b/spec/lib/gitlab/background_migration/migrate_events_to_push_event_payloads_spec.rb index 7351d45336a..5432d270555 100644 --- a/spec/lib/gitlab/background_migration/migrate_events_to_push_event_payloads_spec.rb +++ b/spec/lib/gitlab/background_migration/migrate_events_to_push_event_payloads_spec.rb @@ -281,6 +281,17 @@ describe Gitlab::BackgroundMigration::MigrateEventsToPushEventPayloads, :migrati migration.process_event(event) end + + it 'handles an error gracefully' do + event1 = create_push_event(project, author, { commits: [] }) + + expect(migration).to receive(:replicate_event).and_call_original + expect(migration).to receive(:create_push_event_payload).and_raise(ActiveRecord::InvalidForeignKey, 'invalid foreign key') + + migration.process_event(event1) + + expect(described_class::EventForMigration.all.count).to eq(0) + end end describe '#replicate_event' do @@ -335,9 +346,8 @@ describe Gitlab::BackgroundMigration::MigrateEventsToPushEventPayloads, :migrati it 'does not create push event payloads for removed events' do allow(event).to receive(:id).and_return(-1) - payload = migration.create_push_event_payload(event) + expect { migration.create_push_event_payload(event) }.to raise_error(ActiveRecord::InvalidForeignKey) - expect(payload).to be_nil expect(PushEventPayload.count).to eq(0) end diff --git a/spec/lib/gitlab/background_migration/populate_merge_request_metrics_with_events_data_spec.rb b/spec/lib/gitlab/background_migration/populate_merge_request_metrics_with_events_data_spec.rb new file mode 100644 index 00000000000..dfe3b31f1c0 --- /dev/null +++ b/spec/lib/gitlab/background_migration/populate_merge_request_metrics_with_events_data_spec.rb @@ -0,0 +1,124 @@ +require 'rails_helper' + +describe Gitlab::BackgroundMigration::PopulateMergeRequestMetricsWithEventsData, :migration, schema: 20171128214150 do + describe '#perform' do + let(:mr_with_event) { create(:merge_request) } + let!(:merged_event) { create(:event, :merged, target: mr_with_event) } + let!(:closed_event) { create(:event, :closed, target: mr_with_event) } + + before do + # Make sure no metrics are created and kept through after_* callbacks. + mr_with_event.metrics.destroy! + end + + it 'inserts metrics and updates closed and merged events' do + subject.perform(mr_with_event.id, mr_with_event.id) + + mr_with_event.reload + + expect(mr_with_event.metrics).to have_attributes(latest_closed_by_id: closed_event.author_id, + merged_by_id: merged_event.author_id) + expect(mr_with_event.metrics.latest_closed_at.to_s).to eq(closed_event.updated_at.to_s) + end + end + + describe '#insert_metrics_for_range' do + let!(:mrs_without_metrics) { create_list(:merge_request, 3) } + let!(:mrs_with_metrics) { create_list(:merge_request, 2) } + + before do + # Make sure no metrics are created and kept through after_* callbacks. + mrs_without_metrics.each { |m| m.metrics.destroy! } + end + + it 'inserts merge_request_metrics for merge_requests without one' do + expect { subject.insert_metrics_for_range(MergeRequest.first.id, MergeRequest.last.id) } + .to change(MergeRequest::Metrics, :count).from(2).to(5) + + mrs_without_metrics.each do |mr_without_metrics| + expect(mr_without_metrics.reload.metrics).to be_present + end + end + + it 'does not inserts merge_request_metrics for MRs out of given range' do + expect { subject.insert_metrics_for_range(mrs_with_metrics.first.id, mrs_with_metrics.last.id) } + .not_to change(MergeRequest::Metrics, :count).from(2) + end + end + + describe '#update_metrics_with_events_data' do + context 'closed events data update' do + let(:users) { create_list(:user, 3) } + let(:mrs_with_event) { create_list(:merge_request, 3) } + + before do + create_list(:event, 2, :closed, author: users.first, target: mrs_with_event.first) + create_list(:event, 3, :closed, author: users.second, target: mrs_with_event.second) + create(:event, :closed, author: users.third, target: mrs_with_event.third) + end + + it 'migrates multiple MR metrics with closed event data' do + mr_without_event = create(:merge_request) + create(:event, :merged) + + subject.update_metrics_with_events_data(mrs_with_event.first.id, mrs_with_event.last.id) + + mrs_with_event.each do |mr_with_event| + latest_event = Event.where(action: 3, target: mr_with_event).last + + mr_with_event.metrics.reload + + expect(mr_with_event.metrics.latest_closed_by).to eq(latest_event.author) + expect(mr_with_event.metrics.latest_closed_at.to_s).to eq(latest_event.updated_at.to_s) + end + + expect(mr_without_event.metrics.reload).to have_attributes(latest_closed_by_id: nil, + latest_closed_at: nil) + end + + it 'does not updates metrics out of given range' do + out_of_range_mr = create(:merge_request) + create(:event, :closed, author: users.last, target: out_of_range_mr) + + expect { subject.perform(mrs_with_event.first.id, mrs_with_event.second.id) } + .not_to change { out_of_range_mr.metrics.reload.merged_by } + .from(nil) + end + end + + context 'merged events data update' do + let(:users) { create_list(:user, 3) } + let(:mrs_with_event) { create_list(:merge_request, 3) } + + before do + create_list(:event, 2, :merged, author: users.first, target: mrs_with_event.first) + create_list(:event, 3, :merged, author: users.second, target: mrs_with_event.second) + create(:event, :merged, author: users.third, target: mrs_with_event.third) + end + + it 'migrates multiple MR metrics with merged event data' do + mr_without_event = create(:merge_request) + create(:event, :merged) + + subject.update_metrics_with_events_data(mrs_with_event.first.id, mrs_with_event.last.id) + + mrs_with_event.each do |mr_with_event| + latest_event = Event.where(action: Event::MERGED, target: mr_with_event).last + + expect(mr_with_event.metrics.reload.merged_by).to eq(latest_event.author) + end + + expect(mr_without_event.metrics.reload).to have_attributes(merged_by_id: nil) + end + + it 'does not updates metrics out of given range' do + out_of_range_mr = create(:merge_request) + create(:event, :merged, author: users.last, target: out_of_range_mr) + + expect { subject.perform(mrs_with_event.first.id, mrs_with_event.second.id) } + .not_to change { out_of_range_mr.metrics.reload.merged_by } + .from(nil) + end + end + end +end diff --git a/spec/lib/gitlab/bare_repository_import/importer_spec.rb b/spec/lib/gitlab/bare_repository_import/importer_spec.rb index 8a83e446935..b5d86df09d2 100644 --- a/spec/lib/gitlab/bare_repository_import/importer_spec.rb +++ b/spec/lib/gitlab/bare_repository_import/importer_spec.rb @@ -68,8 +68,14 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do expect(Project.find_by_full_path(project_path)).not_to be_nil end + it 'does not schedule an import' do + expect_any_instance_of(Project).not_to receive(:import_schedule) + + importer.create_project_if_needed + end + it 'creates the Git repo in disk' do - FileUtils.mkdir_p(File.join(base_dir, "#{project_path}.git")) + create_bare_repository("#{project_path}.git") importer.create_project_if_needed @@ -124,13 +130,14 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do end it 'creates the Git repo in disk' do - FileUtils.mkdir_p(File.join(base_dir, "#{project_path}.git")) + create_bare_repository("#{project_path}.git") importer.create_project_if_needed project = Project.find_by_full_path("#{admin.full_path}/#{project_path}") expect(File).to exist(File.join(project.repository_storage_path, project.disk_path + '.git')) + expect(File).to exist(File.join(project.repository_storage_path, project.disk_path + '.wiki.git')) end it 'moves an existing project to the correct path' do @@ -158,8 +165,11 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do it_behaves_like 'importing a repository' it 'creates the Wiki git repo in disk' do - FileUtils.mkdir_p(File.join(base_dir, "#{project_path}.git")) - FileUtils.mkdir_p(File.join(base_dir, "#{project_path}.wiki.git")) + create_bare_repository("#{project_path}.git") + create_bare_repository("#{project_path}.wiki.git") + + expect(Projects::CreateService).to receive(:new).with(admin, hash_including(skip_wiki: true, + import_type: 'bare_repository')).and_call_original importer.create_project_if_needed @@ -182,4 +192,9 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do end end end + + def create_bare_repository(project_path) + repo_path = File.join(base_dir, project_path) + Gitlab::Git::Repository.create(repo_path, bare: true) + end end diff --git a/spec/lib/gitlab/bare_repository_import/repository_spec.rb b/spec/lib/gitlab/bare_repository_import/repository_spec.rb index 61b73abcba4..9f42cf1dfca 100644 --- a/spec/lib/gitlab/bare_repository_import/repository_spec.rb +++ b/spec/lib/gitlab/bare_repository_import/repository_spec.rb @@ -1,58 +1,122 @@ require 'spec_helper' describe ::Gitlab::BareRepositoryImport::Repository do - let(:project_repo_path) { described_class.new('/full/path/', '/full/path/to/repo.git') } + context 'legacy storage' do + subject { described_class.new('/full/path/', '/full/path/to/repo.git') } - it 'stores the repo path' do - expect(project_repo_path.repo_path).to eq('/full/path/to/repo.git') - end + it 'stores the repo path' do + expect(subject.repo_path).to eq('/full/path/to/repo.git') + end - it 'stores the group path' do - expect(project_repo_path.group_path).to eq('to') - end + it 'stores the group path' do + expect(subject.group_path).to eq('to') + end - it 'stores the project name' do - expect(project_repo_path.project_name).to eq('repo') - end + it 'stores the project name' do + expect(subject.project_name).to eq('repo') + end - it 'stores the wiki path' do - expect(project_repo_path.wiki_path).to eq('/full/path/to/repo.wiki.git') - end + it 'stores the wiki path' do + expect(subject.wiki_path).to eq('/full/path/to/repo.wiki.git') + end + + describe '#processable?' do + it 'returns false if it is a wiki' do + subject = described_class.new('/full/path/', '/full/path/to/a/b/my.wiki.git') + + expect(subject).not_to be_processable + end + + it 'returns true if group path is missing' do + subject = described_class.new('/full/path/', '/full/path/repo.git') - describe '#wiki?' do - it 'returns true if it is a wiki' do - wiki_path = described_class.new('/full/path/', '/full/path/to/a/b/my.wiki.git') + expect(subject).to be_processable + end - expect(wiki_path.wiki?).to eq(true) + it 'returns true when group path and project name are present' do + expect(subject).to be_processable + end end - it 'returns false if it is not a wiki' do - expect(project_repo_path.wiki?).to eq(false) + describe '#project_full_path' do + it 'returns the project full path with trailing slash in the root path' do + expect(subject.project_full_path).to eq('to/repo') + end + + it 'returns the project full path with no trailing slash in the root path' do + subject = described_class.new('/full/path', '/full/path/to/repo.git') + + expect(subject.project_full_path).to eq('to/repo') + end end end - describe '#hashed?' do - it 'returns true if it is a hashed folder' do - path = described_class.new('/full/path/', '/full/path/@hashed/my.repo.git') + context 'hashed storage' do + let(:gitlab_shell) { Gitlab::Shell.new } + let(:repository_storage) { 'default' } + let(:root_path) { Gitlab.config.repositories.storages[repository_storage]['path'] } + let(:hash) { '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b' } + let(:hashed_path) { "@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b" } + let(:repo_path) { File.join(root_path, "#{hashed_path}.git") } + let(:wiki_path) { File.join(root_path, "#{hashed_path}.wiki.git") } - expect(path.hashed?).to eq(true) + before do + gitlab_shell.add_repository(repository_storage, hashed_path) + repository = Rugged::Repository.new(repo_path) + repository.config['gitlab.fullpath'] = 'to/repo' end - it 'returns false if it is not a hashed folder' do - expect(project_repo_path.hashed?).to eq(false) + after do + gitlab_shell.remove_repository(root_path, hashed_path) end - end - describe '#project_full_path' do - it 'returns the project full path' do - expect(project_repo_path.repo_path).to eq('/full/path/to/repo.git') - expect(project_repo_path.project_full_path).to eq('to/repo') + subject { described_class.new(root_path, repo_path) } + + it 'stores the repo path' do + expect(subject.repo_path).to eq(repo_path) + end + + it 'stores the wiki path' do + expect(subject.wiki_path).to eq(wiki_path) + end + + it 'reads the group path from .git/config' do + expect(subject.group_path).to eq('to') + end + + it 'reads the project name from .git/config' do + expect(subject.project_name).to eq('repo') end - it 'with no trailing slash in the root path' do - repo_path = described_class.new('/full/path', '/full/path/to/repo.git') + describe '#processable?' do + it 'returns false if it is a wiki' do + subject = described_class.new(root_path, wiki_path) + + expect(subject).not_to be_processable + end + + it 'returns false when group and project name are missing' do + repository = Rugged::Repository.new(repo_path) + repository.config.delete('gitlab.fullpath') + + expect(subject).not_to be_processable + end + + it 'returns true when group path and project name are present' do + expect(subject).to be_processable + end + end + + describe '#project_full_path' do + it 'returns the project full path with trailing slash in the root path' do + expect(subject.project_full_path).to eq('to/repo') + end + + it 'returns the project full path with no trailing slash in the root path' do + subject = described_class.new(root_path[0...-1], repo_path) - expect(repo_path.project_full_path).to eq('to/repo') + expect(subject.project_full_path).to eq('to/repo') + end end end end diff --git a/spec/lib/gitlab/checks/project_moved_spec.rb b/spec/lib/gitlab/checks/project_moved_spec.rb index fa1575e2177..f90c2d6aded 100644 --- a/spec/lib/gitlab/checks/project_moved_spec.rb +++ b/spec/lib/gitlab/checks/project_moved_spec.rb @@ -35,6 +35,12 @@ describe Gitlab::Checks::ProjectMoved, :clean_gitlab_redis_shared_state do project_moved = described_class.new(project, user, 'foo/bar', 'http') expect(project_moved.add_redirect_message).to eq("OK") end + + it 'should handle anonymous clones' do + project_moved = described_class.new(project, nil, 'foo/bar', 'http') + + expect(project_moved.add_redirect_message).to eq(nil) + end end describe '#redirect_message' do diff --git a/spec/lib/gitlab/ci/ansi2html_spec.rb b/spec/lib/gitlab/ci/ansi2html_spec.rb index 33540eab5d6..05e2d94cbd6 100644 --- a/spec/lib/gitlab/ci/ansi2html_spec.rb +++ b/spec/lib/gitlab/ci/ansi2html_spec.rb @@ -120,6 +120,10 @@ describe Gitlab::Ci::Ansi2html do expect(convert_html("\e[48;5;240mHello")).to eq('<span class="xterm-bg-240">Hello</span>') end + it "can print 256 xterm fg bold colors" do + expect(convert_html("\e[38;5;16;1mHello")).to eq('<span class="xterm-fg-16 term-bold">Hello</span>') + end + it "can print 256 xterm bg colors on normal magenta foreground" do expect(convert_html("\e[48;5;16;35mHello")).to eq('<span class="term-fg-magenta xterm-bg-16">Hello</span>') end diff --git a/spec/lib/gitlab/ci/status/build/common_spec.rb b/spec/lib/gitlab/ci/status/build/common_spec.rb index 03d1f46b517..2cce7a23ea7 100644 --- a/spec/lib/gitlab/ci/status/build/common_spec.rb +++ b/spec/lib/gitlab/ci/status/build/common_spec.rb @@ -18,7 +18,7 @@ describe Gitlab::Ci::Status::Build::Common do describe '#has_details?' do context 'when user has access to read build' do before do - project.team << [user, :developer] + project.add_developer(user) end it { is_expected.to have_details } diff --git a/spec/lib/gitlab/ci/status/external/common_spec.rb b/spec/lib/gitlab/ci/status/external/common_spec.rb index b38fbee2486..40871f86568 100644 --- a/spec/lib/gitlab/ci/status/external/common_spec.rb +++ b/spec/lib/gitlab/ci/status/external/common_spec.rb @@ -29,7 +29,7 @@ describe Gitlab::Ci::Status::External::Common do describe '#has_details?' do context 'when user has access to read commit status' do before do - project.team << [user, :developer] + project.add_developer(user) end it { is_expected.to have_details } diff --git a/spec/lib/gitlab/ci/status/external/factory_spec.rb b/spec/lib/gitlab/ci/status/external/factory_spec.rb index c96fd53e730..529d02a3e39 100644 --- a/spec/lib/gitlab/ci/status/external/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/external/factory_spec.rb @@ -8,7 +8,7 @@ describe Gitlab::Ci::Status::External::Factory do let(:external_url) { 'http://gitlab.com/status' } before do - project.team << [user, :developer] + project.add_developer(user) end context 'when external status has a simple core status' do diff --git a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb index 4a5b45e7cae..57df8325635 100644 --- a/spec/lib/gitlab/ci/status/pipeline/common_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/common_spec.rb @@ -18,7 +18,7 @@ describe Gitlab::Ci::Status::Pipeline::Common do describe '#has_details?' do context 'when user has access to read pipeline' do before do - project.team << [user, :developer] + project.add_developer(user) end it { is_expected.to have_details } diff --git a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb index dd754b849b2..defb3fdc0df 100644 --- a/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/pipeline/factory_spec.rb @@ -7,7 +7,7 @@ describe Gitlab::Ci::Status::Pipeline::Factory do let(:factory) { described_class.new(pipeline, user) } before do - project.team << [user, :developer] + project.add_developer(user) end context 'when pipeline has a core status' do diff --git a/spec/lib/gitlab/ci/status/stage/common_spec.rb b/spec/lib/gitlab/ci/status/stage/common_spec.rb index f5f03ac0395..6ec35f8da7e 100644 --- a/spec/lib/gitlab/ci/status/stage/common_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/common_spec.rb @@ -27,7 +27,7 @@ describe Gitlab::Ci::Status::Stage::Common do context 'when user has permission to read pipeline' do before do - project.team << [user, :master] + project.add_master(user) end it 'has details' do diff --git a/spec/lib/gitlab/ci/status/stage/factory_spec.rb b/spec/lib/gitlab/ci/status/stage/factory_spec.rb index 432b07e4902..dee4f4efd1b 100644 --- a/spec/lib/gitlab/ci/status/stage/factory_spec.rb +++ b/spec/lib/gitlab/ci/status/stage/factory_spec.rb @@ -18,7 +18,7 @@ describe Gitlab::Ci::Status::Stage::Factory do end before do - project.team << [user, :developer] + project.add_developer(user) end context 'when stage has a core status' do diff --git a/spec/lib/gitlab/closing_issue_extractor_spec.rb b/spec/lib/gitlab/closing_issue_extractor_spec.rb index ef7d766a13d..8c79ef54c6c 100644 --- a/spec/lib/gitlab/closing_issue_extractor_spec.rb +++ b/spec/lib/gitlab/closing_issue_extractor_spec.rb @@ -13,8 +13,8 @@ describe Gitlab::ClosingIssueExtractor do subject { described_class.new(project, project.creator) } before do - project.team << [project.creator, :developer] - project2.team << [project.creator, :master] + project.add_developer(project.creator) + project2.add_master(project.creator) end describe "#closed_by_message" do @@ -297,7 +297,7 @@ describe Gitlab::ClosingIssueExtractor do context 'with an external issue tracker reference' do it 'extracts the referenced issue' do jira_project = create(:jira_project, name: 'JIRA_EXT1') - jira_project.team << [jira_project.creator, :master] + jira_project.add_master(jira_project.creator) jira_issue = ExternalIssue.new("#{jira_project.name}-1", project: jira_project) closing_issue_extractor = described_class.new(jira_project, jira_project.creator) message = "Resolve #{jira_issue.to_reference}" diff --git a/spec/lib/gitlab/cycle_analytics/permissions_spec.rb b/spec/lib/gitlab/cycle_analytics/permissions_spec.rb index 2a0dd7be439..6de4bd3dc7c 100644 --- a/spec/lib/gitlab/cycle_analytics/permissions_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/permissions_spec.rb @@ -38,7 +38,7 @@ describe Gitlab::CycleAnalytics::Permissions do context 'user is master' do before do - project.team << [user, :master] + project.add_master(user) end it 'has permissions to issue stage' do @@ -72,7 +72,7 @@ describe Gitlab::CycleAnalytics::Permissions do context 'user has no build permissions' do before do - project.team << [user, :guest] + project.add_guest(user) end it 'has permissions to issue stage' do @@ -90,7 +90,7 @@ describe Gitlab::CycleAnalytics::Permissions do context 'user has no merge request permissions' do before do - project.team << [user, :guest] + project.add_guest(user) end it 'has permissions to issue stage' do @@ -108,7 +108,7 @@ describe Gitlab::CycleAnalytics::Permissions do context 'user has no issue permissions' do before do - project.team << [user, :developer] + project.add_developer(user) project.project_feature.update_attribute(:issues_access_level, ProjectFeature::DISABLED) end diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index 664ba0f7234..7727a1d81b1 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -902,7 +902,7 @@ describe Gitlab::Database::MigrationHelpers do describe '#check_trigger_permissions!' do it 'does nothing when the user has the correct permissions' do expect { model.check_trigger_permissions!('users') } - .not_to raise_error(RuntimeError) + .not_to raise_error end it 'raises RuntimeError when the user does not have the correct permissions' do @@ -1036,4 +1036,93 @@ describe Gitlab::Database::MigrationHelpers do end end end + + describe '#change_column_type_using_background_migration' do + let!(:issue) { create(:issue) } + + let(:issue_model) do + Class.new(ActiveRecord::Base) do + self.table_name = 'issues' + include EachBatch + end + end + + it 'changes the type of a column using a background migration' do + expect(model) + .to receive(:add_column) + .with('issues', 'closed_at_for_type_change', :datetime_with_timezone) + + expect(model) + .to receive(:install_rename_triggers) + .with('issues', :closed_at, 'closed_at_for_type_change') + + expect(BackgroundMigrationWorker) + .to receive(:perform_in) + .ordered + .with( + 10.minutes, + 'CopyColumn', + ['issues', :closed_at, 'closed_at_for_type_change', issue.id, issue.id] + ) + + expect(BackgroundMigrationWorker) + .to receive(:perform_in) + .ordered + .with( + 1.hour + 10.minutes, + 'CleanupConcurrentTypeChange', + ['issues', :closed_at, 'closed_at_for_type_change'] + ) + + expect(Gitlab::BackgroundMigration) + .to receive(:steal) + .ordered + .with('CopyColumn') + + expect(Gitlab::BackgroundMigration) + .to receive(:steal) + .ordered + .with('CleanupConcurrentTypeChange') + + model.change_column_type_using_background_migration( + issue_model.all, + :closed_at, + :datetime_with_timezone + ) + end + end + + describe '#perform_background_migration_inline?' do + it 'returns true in a test environment' do + allow(Rails.env) + .to receive(:test?) + .and_return(true) + + expect(model.perform_background_migration_inline?).to eq(true) + end + + it 'returns true in a development environment' do + allow(Rails.env) + .to receive(:test?) + .and_return(false) + + allow(Rails.env) + .to receive(:development?) + .and_return(true) + + expect(model.perform_background_migration_inline?).to eq(true) + end + + it 'returns false in a production environment' do + allow(Rails.env) + .to receive(:test?) + .and_return(false) + + allow(Rails.env) + .to receive(:development?) + .and_return(false) + + expect(model.perform_background_migration_inline?).to eq(false) + end + end end diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb index ff9acfd08b9..9204ea37963 100644 --- a/spec/lib/gitlab/diff/file_spec.rb +++ b/spec/lib/gitlab/diff/file_spec.rb @@ -431,4 +431,29 @@ describe Gitlab::Diff::File do end end end + + context 'when neither blob exists' do + let(:blank_diff_refs) { Gitlab::Diff::DiffRefs.new(base_sha: Gitlab::Git::BLANK_SHA, head_sha: Gitlab::Git::BLANK_SHA) } + let(:diff_file) { described_class.new(diff, diff_refs: blank_diff_refs, repository: project.repository) } + + describe '#blob' do + it 'returns a concrete nil so it can be used in boolean expressions' do + actual = diff_file.blob && true + + expect(actual).to be_nil + end + end + + describe '#binary?' do + it 'returns false' do + expect(diff_file).not_to be_binary + end + end + + describe '#size' do + it 'returns zero' do + expect(diff_file.size).to be_zero + end + end + end end diff --git a/spec/lib/gitlab/email/handler/create_note_handler_spec.rb b/spec/lib/gitlab/email/handler/create_note_handler_spec.rb index d0fa16ce4d1..031efcf1291 100644 --- a/spec/lib/gitlab/email/handler/create_note_handler_spec.rb +++ b/spec/lib/gitlab/email/handler/create_note_handler_spec.rb @@ -66,7 +66,7 @@ describe Gitlab::Email::Handler::CreateNoteHandler do context 'and current user can update noteable' do before do - project.team << [user, :developer] + project.add_developer(user) end it 'does not raise an error' do @@ -99,7 +99,7 @@ describe Gitlab::Email::Handler::CreateNoteHandler do context 'and current user can update noteable' do before do - project.team << [user, :developer] + project.add_developer(user) end it 'post a note and updates the noteable' do diff --git a/spec/lib/gitlab/encoding_helper_spec.rb b/spec/lib/gitlab/encoding_helper_spec.rb index f6e5c55240f..87ec2698fc1 100644 --- a/spec/lib/gitlab/encoding_helper_spec.rb +++ b/spec/lib/gitlab/encoding_helper_spec.rb @@ -145,4 +145,18 @@ describe Gitlab::EncodingHelper do end end end + + describe 'encode_binary' do + [ + [nil, ""], + ["", ""], + [" ", " "], + %w(a1 a1), + ["编码", "\xE7\xBC\x96\xE7\xA0\x81".b] + ].each do |input, result| + it "encodes #{input.inspect} to #{result.inspect}" do + expect(ext_class.encode_binary(input)).to eq(result) + end + end + end end diff --git a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb index 7dc06c90078..4d2f08f95fc 100644 --- a/spec/lib/gitlab/gfm/reference_rewriter_spec.rb +++ b/spec/lib/gitlab/gfm/reference_rewriter_spec.rb @@ -10,7 +10,7 @@ describe Gitlab::Gfm::ReferenceRewriter do let(:text) { 'some text' } before do - old_project.team << [user, :reporter] + old_project.add_reporter(user) end describe '#rewrite' do diff --git a/spec/lib/gitlab/git/commit_spec.rb b/spec/lib/gitlab/git/commit_spec.rb index 5ed639543e0..6d35734d306 100644 --- a/spec/lib/gitlab/git/commit_spec.rb +++ b/spec/lib/gitlab/git/commit_spec.rb @@ -428,6 +428,11 @@ describe Gitlab::Git::Commit, seed_helper: true do subject { super().deletions } it { is_expected.to eq(6) } end + + describe '#total' do + subject { super().total } + it { is_expected.to eq(17) } + end end describe '#stats with gitaly on' do diff --git a/spec/lib/gitlab/git/gitlab_projects_spec.rb b/spec/lib/gitlab/git/gitlab_projects_spec.rb index 24da9589458..a798b188a0d 100644 --- a/spec/lib/gitlab/git/gitlab_projects_spec.rb +++ b/spec/lib/gitlab/git/gitlab_projects_spec.rb @@ -243,7 +243,6 @@ describe Gitlab::Git::GitlabProjects do let(:dest_repos_path) { tmp_repos_path } let(:dest_repo_name) { File.join('@hashed', 'aa', 'bb', 'xyz.git') } let(:dest_repo) { File.join(dest_repos_path, dest_repo_name) } - let(:dest_namespace) { File.dirname(dest_repo) } subject { gl_projects.fork_repository(dest_repos_path, dest_repo_name) } @@ -255,37 +254,64 @@ describe Gitlab::Git::GitlabProjects do FileUtils.rm_rf(dest_repos_path) end - it 'forks the repository' do - message = "Forking repository from <#{tmp_repo_path}> to <#{dest_repo}>." - expect(logger).to receive(:info).with(message) + shared_examples 'forking a repository' do + it 'forks the repository' do + is_expected.to be_truthy - is_expected.to be_truthy + expect(File.exist?(dest_repo)).to be_truthy + expect(File.exist?(File.join(dest_repo, 'hooks', 'pre-receive'))).to be_truthy + expect(File.exist?(File.join(dest_repo, 'hooks', 'post-receive'))).to be_truthy + end + + it 'does not fork if a project of the same name already exists' do + # create a fake project at the intended destination + FileUtils.mkdir_p(dest_repo) - expect(File.exist?(dest_repo)).to be_truthy - expect(File.exist?(File.join(dest_repo, 'hooks', 'pre-receive'))).to be_truthy - expect(File.exist?(File.join(dest_repo, 'hooks', 'post-receive'))).to be_truthy + is_expected.to be_falsy + end end - it 'does not fork if a project of the same name already exists' do - # create a fake project at the intended destination - FileUtils.mkdir_p(dest_repo) + context 'when Gitaly fork_repository feature is enabled' do + it_behaves_like 'forking a repository' + end - # trying to fork again should fail as the repo already exists - message = "fork-repository failed: destination repository <#{dest_repo}> already exists." - expect(logger).to receive(:error).with(message) + context 'when Gitaly fork_repository feature is disabled', :disable_gitaly do + it_behaves_like 'forking a repository' - is_expected.to be_falsy - end + # We seem to be stuck to having only one working Gitaly storage in tests, changing + # that is not very straight-forward so I'm leaving this test here for now till + # https://gitlab.com/gitlab-org/gitlab-ce/issues/41393 is fixed. + context 'different storages' do + let(:dest_repos_path) { File.join(File.dirname(tmp_repos_path), 'alternative') } - context 'different storages' do - let(:dest_repos_path) { File.join(File.dirname(tmp_repos_path), 'alternative') } + it 'forks the repo' do + is_expected.to be_truthy - it 'forks the repo' do - is_expected.to be_truthy + expect(File.exist?(dest_repo)).to be_truthy + expect(File.exist?(File.join(dest_repo, 'hooks', 'pre-receive'))).to be_truthy + expect(File.exist?(File.join(dest_repo, 'hooks', 'post-receive'))).to be_truthy + end + end - expect(File.exist?(dest_repo)).to be_truthy - expect(File.exist?(File.join(dest_repo, 'hooks', 'pre-receive'))).to be_truthy - expect(File.exist?(File.join(dest_repo, 'hooks', 'post-receive'))).to be_truthy + describe 'log messages' do + describe 'successful fork' do + it do + message = "Forking repository from <#{tmp_repo_path}> to <#{dest_repo}>." + expect(logger).to receive(:info).with(message) + + subject + end + end + + describe 'failed fork due existing destination' do + it do + FileUtils.mkdir_p(dest_repo) + message = "fork-repository failed: destination repository <#{dest_repo}> already exists." + expect(logger).to receive(:error).with(message) + + subject + end + end end end end diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 03a9cc488ca..faccc2c8e00 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -18,9 +18,10 @@ describe Gitlab::Git::Repository, seed_helper: true do end let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') } + let(:storage_path) { TestEnv.repos_path } describe '.create_hooks' do - let(:repo_path) { File.join(TestEnv.repos_path, 'hook-test.git') } + let(:repo_path) { File.join(storage_path, 'hook-test.git') } let(:hooks_dir) { File.join(repo_path, 'hooks') } let(:target_hooks_dir) { Gitlab.config.gitlab_shell.hooks_path } let(:existing_target) { File.join(repo_path, 'foobar') } @@ -645,7 +646,7 @@ describe Gitlab::Git::Repository, seed_helper: true do end after do - Gitlab::Shell.new.remove_repository(TestEnv.repos_path, 'my_project') + Gitlab::Shell.new.remove_repository(storage_path, 'my_project') end it 'fetches a repository as a mirror remote' do @@ -701,21 +702,6 @@ describe Gitlab::Git::Repository, seed_helper: true do end end - describe '#remote_exists?' do - before(:all) do - @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') - @repo.add_remote("new_remote", SeedHelper::GITLAB_GIT_TEST_REPO_URL) - end - - it 'returns true for an existing remote' do - expect(@repo.remote_exists?('new_remote')).to eq(true) - end - - it 'returns false for a non-existing remote' do - expect(@repo.remote_exists?('foo')).to eq(false) - end - end - describe "#log" do let(:commit_with_old_name) do Gitlab::Git::Commit.decorate(repository, @commit_with_old_name_id) @@ -1030,7 +1016,7 @@ describe Gitlab::Git::Repository, seed_helper: true do shared_examples 'extended commit counting' do context 'with after timestamp' do it 'returns the number of commits after timestamp' do - options = { ref: 'master', limit: nil, after: Time.iso8601('2013-03-03T20:15:01+00:00') } + options = { ref: 'master', after: Time.iso8601('2013-03-03T20:15:01+00:00') } expect(repository.count_commits(options)).to eq(25) end @@ -1038,7 +1024,7 @@ describe Gitlab::Git::Repository, seed_helper: true do context 'with before timestamp' do it 'returns the number of commits before timestamp' do - options = { ref: 'feature', limit: nil, before: Time.iso8601('2015-03-03T20:15:01+00:00') } + options = { ref: 'feature', before: Time.iso8601('2015-03-03T20:15:01+00:00') } expect(repository.count_commits(options)).to eq(9) end @@ -1046,11 +1032,19 @@ describe Gitlab::Git::Repository, seed_helper: true do context 'with path' do it 'returns the number of commits with path ' do - options = { ref: 'master', limit: nil, path: "encoding" } + options = { ref: 'master', path: "encoding" } expect(repository.count_commits(options)).to eq(2) end end + + context 'with max_count' do + it 'returns the number of commits up to the passed limit' do + options = { ref: 'master', max_count: 10, after: Time.iso8601('2013-03-03T20:15:01+00:00') } + + expect(repository.count_commits(options)).to eq(10) + end + end end context 'when Gitaly count_commits feature is enabled' do @@ -1670,7 +1664,7 @@ describe Gitlab::Git::Repository, seed_helper: true do let(:branch_name) { "to-be-deleted-soon" } before do - project.team << [user, :developer] + project.add_developer(user) repository.create_branch(branch_name) end @@ -1734,6 +1728,20 @@ describe Gitlab::Git::Repository, seed_helper: true do expect(result.repo_created).to eq(false) expect(result.branch_created).to eq(false) end + + it 'returns nil if there was a concurrent branch update' do + concurrent_update_id = '33f3729a45c02fc67d00adb1b8bca394b0e761d9' + result = repository.merge(user, source_sha, target_branch, 'Test merge') do + # This ref update should make the merge fail + repository.write_ref(Gitlab::Git::BRANCH_REF_PREFIX + target_branch, concurrent_update_id) + end + + # This 'nil' signals that the merge was not applied + expect(result).to be_nil + + # Our concurrent ref update should not have been undone + expect(repository.find_branch(target_branch).target).to eq(concurrent_update_id) + end end context 'with gitaly' do @@ -1843,6 +1851,166 @@ describe Gitlab::Git::Repository, seed_helper: true do end end + describe 'remotes' do + let(:repository) do + Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') + end + let(:remote_name) { 'my-remote' } + + after do + ensure_seeds + end + + describe '#add_remote' do + let(:url) { 'http://my-repo.git' } + let(:mirror_refmap) { '+refs/*:refs/*' } + + it 'creates a new remote via Gitaly' do + expect_any_instance_of(Gitlab::GitalyClient::RemoteService) + .to receive(:add_remote).with(remote_name, url, mirror_refmap) + + repository.add_remote(remote_name, url, mirror_refmap: mirror_refmap) + end + + context 'with Gitaly disabled', :skip_gitaly_mock do + it 'creates a new remote via Rugged' do + expect_any_instance_of(Rugged::RemoteCollection).to receive(:create) + .with(remote_name, url) + expect_any_instance_of(Rugged::Config).to receive(:[]=) + .with("remote.#{remote_name}.mirror", true) + expect_any_instance_of(Rugged::Config).to receive(:[]=) + .with("remote.#{remote_name}.prune", true) + expect_any_instance_of(Rugged::Config).to receive(:[]=) + .with("remote.#{remote_name}.fetch", mirror_refmap) + + repository.add_remote(remote_name, url, mirror_refmap: mirror_refmap) + end + end + end + + describe '#remove_remote' do + it 'removes the remote via Gitaly' do + expect_any_instance_of(Gitlab::GitalyClient::RemoteService) + .to receive(:remove_remote).with(remote_name) + + repository.remove_remote(remote_name) + end + + context 'with Gitaly disabled', :skip_gitaly_mock do + it 'removes the remote via Rugged' do + expect_any_instance_of(Rugged::RemoteCollection).to receive(:delete) + .with(remote_name) + + repository.remove_remote(remote_name) + end + end + end + end + + describe '#gitlab_projects' do + subject { repository.gitlab_projects } + + it { expect(subject.shard_path).to eq(storage_path) } + it { expect(subject.repository_relative_path).to eq(repository.relative_path) } + end + + context 'gitlab_projects commands' do + let(:gitlab_projects) { repository.gitlab_projects } + let(:timeout) { Gitlab.config.gitlab_shell.git_timeout } + + describe '#push_remote_branches' do + subject do + repository.push_remote_branches('downstream-remote', ['master']) + end + + it 'executes the command' do + expect(gitlab_projects).to receive(:push_branches) + .with('downstream-remote', timeout, true, ['master']) + .and_return(true) + + is_expected.to be_truthy + end + + it 'raises an error if the command fails' do + allow(gitlab_projects).to receive(:output) { 'error' } + expect(gitlab_projects).to receive(:push_branches) + .with('downstream-remote', timeout, true, ['master']) + .and_return(false) + + expect { subject }.to raise_error(Gitlab::Git::CommandError, 'error') + end + end + + describe '#delete_remote_branches' do + subject do + repository.delete_remote_branches('downstream-remote', ['master']) + end + + it 'executes the command' do + expect(gitlab_projects).to receive(:delete_remote_branches) + .with('downstream-remote', ['master']) + .and_return(true) + + is_expected.to be_truthy + end + + it 'raises an error if the command fails' do + allow(gitlab_projects).to receive(:output) { 'error' } + expect(gitlab_projects).to receive(:delete_remote_branches) + .with('downstream-remote', ['master']) + .and_return(false) + + expect { subject }.to raise_error(Gitlab::Git::CommandError, 'error') + end + end + + describe '#delete_remote_branches' do + subject do + repository.delete_remote_branches('downstream-remote', ['master']) + end + + it 'executes the command' do + expect(gitlab_projects).to receive(:delete_remote_branches) + .with('downstream-remote', ['master']) + .and_return(true) + + is_expected.to be_truthy + end + + it 'raises an error if the command fails' do + allow(gitlab_projects).to receive(:output) { 'error' } + expect(gitlab_projects).to receive(:delete_remote_branches) + .with('downstream-remote', ['master']) + .and_return(false) + + expect { subject }.to raise_error(Gitlab::Git::CommandError, 'error') + end + end + + describe '#delete_remote_branches' do + subject do + repository.delete_remote_branches('downstream-remote', ['master']) + end + + it 'executes the command' do + expect(gitlab_projects).to receive(:delete_remote_branches) + .with('downstream-remote', ['master']) + .and_return(true) + + is_expected.to be_truthy + end + + it 'raises an error if the command fails' do + allow(gitlab_projects).to receive(:output) { 'error' } + expect(gitlab_projects).to receive(:delete_remote_branches) + .with('downstream-remote', ['master']) + .and_return(false) + + expect { subject }.to raise_error(Gitlab::Git::CommandError, 'error') + end + end + end + def create_remote_branch(repository, remote_name, branch_name, source_branch_name) source_branch = repository.branches.find { |branch| branch.name == source_branch_name } rugged = repository.rugged diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb index 2db560c2cec..4290fbb0087 100644 --- a/spec/lib/gitlab/git_access_spec.rb +++ b/spec/lib/gitlab/git_access_spec.rb @@ -275,7 +275,7 @@ describe Gitlab::GitAccess do describe '#check_command_disabled!' do before do - project.team << [user, :master] + project.add_master(user) end context 'over http' do @@ -404,7 +404,7 @@ describe Gitlab::GitAccess do describe 'reporter user' do before do - project.team << [user, :reporter] + project.add_reporter(user) end context 'pull code' do @@ -417,7 +417,7 @@ describe Gitlab::GitAccess do context 'when member of the project' do before do - project.team << [user, :reporter] + project.add_reporter(user) end context 'pull code' do @@ -497,7 +497,7 @@ describe Gitlab::GitAccess do if role == :admin user.update_attribute(:admin, true) else - project.team << [user, role] + project.add_role(user, role) end aggregate_failures do @@ -658,7 +658,7 @@ describe Gitlab::GitAccess do context 'when project is authorized' do before do - project.team << [user, :reporter] + project.add_reporter(user) end it { expect { push_access_check }.to raise_unauthorized(described_class::ERROR_MESSAGES[:upload]) } diff --git a/spec/lib/gitlab/git_access_wiki_spec.rb b/spec/lib/gitlab/git_access_wiki_spec.rb index 1056074264a..186b2d9279d 100644 --- a/spec/lib/gitlab/git_access_wiki_spec.rb +++ b/spec/lib/gitlab/git_access_wiki_spec.rb @@ -18,7 +18,7 @@ describe Gitlab::GitAccessWiki do context 'when user can :create_wiki' do before do create(:protected_branch, name: 'master', project: project) - project.team << [user, :developer] + project.add_developer(user) end subject { access.check('git-receive-pack', changes) } @@ -41,7 +41,7 @@ describe Gitlab::GitAccessWiki do subject { access.check('git-upload-pack', '_any') } before do - project.team << [user, :developer] + project.add_developer(user) end context 'when wiki feature is enabled' do diff --git a/spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb b/spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb new file mode 100644 index 00000000000..b9641de7eda --- /dev/null +++ b/spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb @@ -0,0 +1,90 @@ +require 'spec_helper' + +describe Gitlab::GitalyClient::ConflictsService do + let(:project) { create(:project, :repository) } + let(:target_project) { create(:project, :repository) } + let(:source_repository) { project.repository.raw } + let(:target_repository) { target_project.repository.raw } + let(:target_gitaly_repository) { target_repository.gitaly_repository } + let(:our_commit_oid) { 'f00' } + let(:their_commit_oid) { 'f44' } + let(:client) do + described_class.new(target_repository, our_commit_oid, their_commit_oid) + end + + describe '#list_conflict_files' do + let(:request) do + Gitaly::ListConflictFilesRequest.new( + repository: target_gitaly_repository, our_commit_oid: our_commit_oid, + their_commit_oid: their_commit_oid + ) + end + let(:our_path) { 'our/path' } + let(:their_path) { 'their/path' } + let(:our_mode) { 0744 } + let(:header) do + double(repository: target_gitaly_repository, commit_oid: our_commit_oid, + our_path: our_path, our_mode: 0744, their_path: their_path) + end + let(:response) do + [ + double(files: [double(header: header), double(content: 'foo', header: nil)]), + double(files: [double(content: 'bar', header: nil)]) + ] + end + let(:file) { subject[0] } + + subject { client.list_conflict_files } + + it 'sends an RPC request' do + expect_any_instance_of(Gitaly::ConflictsService::Stub).to receive(:list_conflict_files) + .with(request, kind_of(Hash)).and_return([]) + + subject + end + + it 'forms a Gitlab::Git::ConflictFile collection from the response' do + allow_any_instance_of(Gitaly::ConflictsService::Stub).to receive(:list_conflict_files) + .with(request, kind_of(Hash)).and_return(response) + + expect(subject.size).to be(1) + expect(file.content).to eq('foobar') + expect(file.their_path).to eq(their_path) + expect(file.our_path).to eq(our_path) + expect(file.our_mode).to be(our_mode) + expect(file.repository).to eq(target_repository) + expect(file.commit_oid).to eq(our_commit_oid) + end + end + + describe '#resolve_conflicts' do + let(:user) { create(:user) } + let(:files) do + [{ old_path: 'some/path', new_path: 'some/path', content: '' }] + end + let(:source_branch) { 'master' } + let(:target_branch) { 'feature' } + let(:commit_message) { 'Solving conflicts' } + let(:resolution) do + Gitlab::Git::Conflict::Resolution.new(user, files, commit_message) + end + + subject do + client.resolve_conflicts(source_repository, resolution, source_branch, target_branch) + end + + it 'sends an RPC request' do + expect_any_instance_of(Gitaly::ConflictsService::Stub).to receive(:resolve_conflicts) + .with(kind_of(Enumerator), kind_of(Hash)).and_return(double(resolution_error: "")) + + subject + end + + it 'raises a relevant exception if resolution_error is present' do + expect_any_instance_of(Gitaly::ConflictsService::Stub).to receive(:resolve_conflicts) + .with(kind_of(Enumerator), kind_of(Hash)).and_return(double(resolution_error: "something happened")) + + expect { subject }.to raise_error(Gitlab::Git::Conflict::Resolver::ResolutionError) + end + end +end diff --git a/spec/lib/gitlab/gitaly_client/remote_service_spec.rb b/spec/lib/gitlab/gitaly_client/remote_service_spec.rb new file mode 100644 index 00000000000..69c6f054016 --- /dev/null +++ b/spec/lib/gitlab/gitaly_client/remote_service_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe Gitlab::GitalyClient::RemoteService do + let(:project) { create(:project) } + let(:storage_name) { project.repository_storage } + let(:relative_path) { project.disk_path + '.git' } + let(:remote_name) { 'my-remote' } + let(:client) { described_class.new(project.repository) } + + describe '#add_remote' do + let(:url) { 'http://my-repo.git' } + let(:mirror_refmap) { :all_refs } + + it 'sends an add_remote message' do + expect_any_instance_of(Gitaly::RemoteService::Stub) + .to receive(:add_remote) + .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash)) + .and_return(double(:add_remote_response)) + + client.add_remote(remote_name, url, mirror_refmap) + end + end + + describe '#remove_remote' do + it 'sends an remove_remote message and returns the result value' do + expect_any_instance_of(Gitaly::RemoteService::Stub) + .to receive(:remove_remote) + .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash)) + .and_return(double(result: true)) + + expect(client.remove_remote(remote_name)).to be(true) + end + end +end diff --git a/spec/lib/gitlab/gitaly_client_spec.rb b/spec/lib/gitlab/gitaly_client_spec.rb index a871ed0df0e..309b7338ef0 100644 --- a/spec/lib/gitlab/gitaly_client_spec.rb +++ b/spec/lib/gitlab/gitaly_client_spec.rb @@ -38,20 +38,6 @@ describe Gitlab::GitalyClient, skip_gitaly_mock: true do end end - describe 'encode' do - [ - [nil, ""], - ["", ""], - [" ", " "], - %w(a1 a1), - ["编码", "\xE7\xBC\x96\xE7\xA0\x81".b] - ].each do |input, result| - it "encodes #{input.inspect} to #{result.inspect}" do - expect(described_class.encode(input)).to eq result - end - end - end - describe 'allow_n_plus_1_calls' do context 'when RequestStore is enabled', :request_store do it 'returns the result of the allow_n_plus_1_calls block' do diff --git a/spec/lib/gitlab/google_code_import/importer_spec.rb b/spec/lib/gitlab/google_code_import/importer_spec.rb index 798ea0bac58..017facd0f5e 100644 --- a/spec/lib/gitlab/google_code_import/importer_spec.rb +++ b/spec/lib/gitlab/google_code_import/importer_spec.rb @@ -15,7 +15,7 @@ describe Gitlab::GoogleCodeImport::Importer do subject { described_class.new(project) } before do - project.team << [project.creator, :master] + project.add_master(project.creator) project.create_import_data(data: import_data) end diff --git a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb index 6243b6ac9f0..6faf3d82981 100644 --- a/spec/lib/gitlab/import_export/project_tree_saver_spec.rb +++ b/spec/lib/gitlab/import_export/project_tree_saver_spec.rb @@ -9,7 +9,7 @@ describe Gitlab::ImportExport::ProjectTreeSaver do let!(:project) { setup_project } before do - project.team << [user, :master] + project.add_master(user) allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) allow_any_instance_of(MergeRequest).to receive(:source_branch_sha).and_return('ABCD') allow_any_instance_of(MergeRequest).to receive(:target_branch_sha).and_return('DCBA') diff --git a/spec/lib/gitlab/import_export/repo_saver_spec.rb b/spec/lib/gitlab/import_export/repo_saver_spec.rb index e6ad516deef..44f972fe530 100644 --- a/spec/lib/gitlab/import_export/repo_saver_spec.rb +++ b/spec/lib/gitlab/import_export/repo_saver_spec.rb @@ -9,7 +9,7 @@ describe Gitlab::ImportExport::RepoSaver do let(:bundler) { described_class.new(project: project, shared: shared) } before do - project.team << [user, :master] + project.add_master(user) allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) end diff --git a/spec/lib/gitlab/import_export/wiki_repo_saver_spec.rb b/spec/lib/gitlab/import_export/wiki_repo_saver_spec.rb index 0e55993c8ef..1d1e7e7f89a 100644 --- a/spec/lib/gitlab/import_export/wiki_repo_saver_spec.rb +++ b/spec/lib/gitlab/import_export/wiki_repo_saver_spec.rb @@ -10,7 +10,7 @@ describe Gitlab::ImportExport::WikiRepoSaver do let!(:project_wiki) { ProjectWiki.new(project, user) } before do - project.team << [user, :master] + project.add_master(user) allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) project_wiki.wiki project_wiki.create_page("index", "test content") diff --git a/spec/lib/gitlab/project_authorizations_spec.rb b/spec/lib/gitlab/project_authorizations_spec.rb index 953cfbb8b88..f3cd6961e94 100644 --- a/spec/lib/gitlab/project_authorizations_spec.rb +++ b/spec/lib/gitlab/project_authorizations_spec.rb @@ -15,7 +15,7 @@ describe Gitlab::ProjectAuthorizations do end before do - other_project.team << [user, :reporter] + other_project.add_reporter(user) group.add_developer(user) end diff --git a/spec/lib/gitlab/project_search_results_spec.rb b/spec/lib/gitlab/project_search_results_spec.rb index a424f0f5cfe..17937726f2c 100644 --- a/spec/lib/gitlab/project_search_results_spec.rb +++ b/spec/lib/gitlab/project_search_results_spec.rb @@ -179,7 +179,7 @@ describe Gitlab::ProjectSearchResults do end it 'does not list project confidential issues for project members with guest role' do - project.team << [member, :guest] + project.add_guest(member) results = described_class.new(member, project, query) issues = results.objects('issues') @@ -211,7 +211,7 @@ describe Gitlab::ProjectSearchResults do end it 'lists project confidential issues for project members' do - project.team << [member, :developer] + project.add_developer(member) results = described_class.new(member, project, query) issues = results.objects('issues') @@ -290,12 +290,12 @@ describe Gitlab::ProjectSearchResults do let!(:private_project) { create(:project, :private, :repository, creator: creator, namespace: creator.namespace) } let(:team_master) do user = create(:user, username: 'private-project-master') - private_project.team << [user, :master] + private_project.add_master(user) user end let(:team_reporter) do user = create(:user, username: 'private-project-reporter') - private_project.team << [user, :reporter] + private_project.add_reporter(user) user end diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb index 8ec3f55e6de..4139d1c650c 100644 --- a/spec/lib/gitlab/reference_extractor_spec.rb +++ b/spec/lib/gitlab/reference_extractor_spec.rb @@ -4,7 +4,7 @@ describe Gitlab::ReferenceExtractor do let(:project) { create(:project) } before do - project.team << [project.creator, :developer] + project.add_developer(project.creator) end subject { described_class.new(project, project.creator) } @@ -14,8 +14,8 @@ describe Gitlab::ReferenceExtractor do @u_bar = create(:user, username: 'bar') @u_offteam = create(:user, username: 'offteam') - project.team << [@u_foo, :reporter] - project.team << [@u_bar, :guest] + project.add_guest(@u_foo) + project.add_guest(@u_bar) subject.analyze('@foo, @baduser, @bar, and @offteam') expect(subject.users).to match_array([@u_foo, @u_bar, @u_offteam]) @@ -26,8 +26,8 @@ describe Gitlab::ReferenceExtractor do @u_bar = create(:user, username: 'bar') @u_offteam = create(:user, username: 'offteam') - project.team << [@u_foo, :reporter] - project.team << [@u_bar, :guest] + project.add_reporter(@u_foo) + project.add_reporter(@u_bar) subject.analyze(%Q{ Inline code: `@foo` @@ -228,7 +228,7 @@ describe Gitlab::ReferenceExtractor do let(:issue) { create(:issue, project: other_project) } before do - other_project.team << [project.creator, :developer] + other_project.add_developer(project.creator) end it 'handles project issue references' do @@ -246,7 +246,7 @@ describe Gitlab::ReferenceExtractor do let(:text) { "Ref. #{issue.to_reference} and #{label.to_reference}" } before do - project.team << [project.creator, :developer] + project.add_developer(project.creator) subject.analyze(text) end diff --git a/spec/lib/gitlab/search_results_spec.rb b/spec/lib/gitlab/search_results_spec.rb index a958baab44f..b5a9ac570e6 100644 --- a/spec/lib/gitlab/search_results_spec.rb +++ b/spec/lib/gitlab/search_results_spec.rb @@ -16,7 +16,7 @@ describe Gitlab::SearchResults do context 'as a user with access' do before do - project.team << [user, :developer] + project.add_developer(user) end describe '#projects_count' do @@ -52,15 +52,36 @@ describe Gitlab::SearchResults do expect(results.objects('merge_requests')).to include merge_request_2 end - it 'includes project filter by default' do - expect(results).to receive(:project_ids_relation).and_call_original - results.objects('merge_requests') + describe '#merge_requests' do + it 'includes project filter by default' do + expect(results).to receive(:project_ids_relation).and_call_original + + results.objects('merge_requests') + end + + it 'it skips project filter if default project context is used' do + allow(results).to receive(:default_project_filter).and_return(true) + + expect(results).not_to receive(:project_ids_relation) + + results.objects('merge_requests') + end end - it 'it skips project filter if default is used' do - allow(results).to receive(:default_project_filter).and_return(true) - expect(results).not_to receive(:project_ids_relation) - results.objects('merge_requests') + describe '#issues' do + it 'includes project filter by default' do + expect(results).to receive(:project_ids_relation).and_call_original + + results.objects('issues') + end + + it 'it skips project filter if default project context is used' do + allow(results).to receive(:default_project_filter).and_return(true) + + expect(results).not_to receive(:project_ids_relation) + + results.objects('issues') + end end end @@ -104,8 +125,8 @@ describe Gitlab::SearchResults do end it 'does not list confidential issues for project members with guest role' do - project_1.team << [member, :guest] - project_2.team << [member, :guest] + project_1.add_guest(member) + project_2.add_guest(member) results = described_class.new(member, limit_projects, query) issues = results.objects('issues') @@ -146,8 +167,8 @@ describe Gitlab::SearchResults do end it 'lists confidential issues for project members' do - project_1.team << [member, :developer] - project_2.team << [member, :developer] + project_1.add_developer(member) + project_2.add_developer(member) results = described_class.new(member, limit_projects, query) issues = results.objects('issues') diff --git a/spec/lib/gitlab/shell_spec.rb b/spec/lib/gitlab/shell_spec.rb index dd779b04741..81d9e6a8f82 100644 --- a/spec/lib/gitlab/shell_spec.rb +++ b/spec/lib/gitlab/shell_spec.rb @@ -347,62 +347,6 @@ describe Gitlab::Shell do end.to raise_error(Gitlab::Shell::Error, "error") end end - - describe '#push_remote_branches' do - subject(:result) do - gitlab_shell.push_remote_branches( - project.repository_storage_path, - project.disk_path, - 'downstream-remote', - ['master'] - ) - end - - it 'executes the command' do - expect(gitlab_projects).to receive(:push_branches) - .with('downstream-remote', timeout, true, ['master']) - .and_return(true) - - is_expected.to be_truthy - end - - it 'fails to execute the command' do - allow(gitlab_projects).to receive(:output) { 'error' } - expect(gitlab_projects).to receive(:push_branches) - .with('downstream-remote', timeout, true, ['master']) - .and_return(false) - - expect { result }.to raise_error(Gitlab::Shell::Error, 'error') - end - end - - describe '#delete_remote_branches' do - subject(:result) do - gitlab_shell.delete_remote_branches( - project.repository_storage_path, - project.disk_path, - 'downstream-remote', - ['master'] - ) - end - - it 'executes the command' do - expect(gitlab_projects).to receive(:delete_remote_branches) - .with('downstream-remote', ['master']) - .and_return(true) - - is_expected.to be_truthy - end - - it 'fails to execute the command' do - allow(gitlab_projects).to receive(:output) { 'error' } - expect(gitlab_projects).to receive(:delete_remote_branches) - .with('downstream-remote', ['master']) - .and_return(false) - - expect { result }.to raise_error(Gitlab::Shell::Error, 'error') - end - end end describe 'namespace actions' do diff --git a/spec/lib/gitlab/slash_commands/issue_new_spec.rb b/spec/lib/gitlab/slash_commands/issue_new_spec.rb index 75ae58d0582..3b077c58c50 100644 --- a/spec/lib/gitlab/slash_commands/issue_new_spec.rb +++ b/spec/lib/gitlab/slash_commands/issue_new_spec.rb @@ -7,7 +7,7 @@ describe Gitlab::SlashCommands::IssueNew do let(:regex_match) { described_class.match("issue create bird is the word") } before do - project.team << [user, :master] + project.add_master(user) end subject do diff --git a/spec/lib/gitlab/slash_commands/issue_search_spec.rb b/spec/lib/gitlab/slash_commands/issue_search_spec.rb index 51f59216413..e41e5254dde 100644 --- a/spec/lib/gitlab/slash_commands/issue_search_spec.rb +++ b/spec/lib/gitlab/slash_commands/issue_search_spec.rb @@ -21,7 +21,7 @@ describe Gitlab::SlashCommands::IssueSearch do context 'the user has access' do before do - project.team << [user, :master] + project.add_master(user) end it 'returns all results' do diff --git a/spec/lib/gitlab/slash_commands/issue_show_spec.rb b/spec/lib/gitlab/slash_commands/issue_show_spec.rb index 08c380ca8f1..e5834d5a2ee 100644 --- a/spec/lib/gitlab/slash_commands/issue_show_spec.rb +++ b/spec/lib/gitlab/slash_commands/issue_show_spec.rb @@ -8,7 +8,7 @@ describe Gitlab::SlashCommands::IssueShow do let(:regex_match) { described_class.match("issue show #{issue.iid}") } before do - project.team << [user, :master] + project.add_master(user) end subject do diff --git a/spec/lib/gitlab/user_access_spec.rb b/spec/lib/gitlab/user_access_spec.rb index cd97416bcc9..7280acb6c82 100644 --- a/spec/lib/gitlab/user_access_spec.rb +++ b/spec/lib/gitlab/user_access_spec.rb @@ -8,19 +8,19 @@ describe Gitlab::UserAccess do describe '#can_push_to_branch?' do describe 'push to none protected branch' do it 'returns true if user is a master' do - project.team << [user, :master] + project.add_master(user) expect(access.can_push_to_branch?('random_branch')).to be_truthy end it 'returns true if user is a developer' do - project.team << [user, :developer] + project.add_developer(user) expect(access.can_push_to_branch?('random_branch')).to be_truthy end it 'returns false if user is a reporter' do - project.team << [user, :reporter] + project.add_reporter(user) expect(access.can_push_to_branch?('random_branch')).to be_falsey end @@ -31,34 +31,34 @@ describe Gitlab::UserAccess do let(:project_access) { described_class.new(user, project: empty_project) } it 'returns true if user is master' do - empty_project.team << [user, :master] + empty_project.add_master(user) expect(project_access.can_push_to_branch?('master')).to be_truthy end it 'returns false if user is developer and project is fully protected' do - empty_project.team << [user, :developer] + empty_project.add_developer(user) stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_FULL) expect(project_access.can_push_to_branch?('master')).to be_falsey end it 'returns false if user is developer and it is not allowed to push new commits but can merge into branch' do - empty_project.team << [user, :developer] + empty_project.add_developer(user) stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_MERGE) expect(project_access.can_push_to_branch?('master')).to be_falsey end it 'returns true if user is developer and project is unprotected' do - empty_project.team << [user, :developer] + empty_project.add_developer(user) stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_NONE) expect(project_access.can_push_to_branch?('master')).to be_truthy end it 'returns true if user is developer and project grants developers permission' do - empty_project.team << [user, :developer] + empty_project.add_developer(user) stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_PUSH) expect(project_access.can_push_to_branch?('master')).to be_truthy @@ -70,25 +70,25 @@ describe Gitlab::UserAccess do let(:not_existing_branch) { create :protected_branch, :developers_can_merge, project: project } it 'returns true if user is a master' do - project.team << [user, :master] + project.add_master(user) expect(access.can_push_to_branch?(branch.name)).to be_truthy end it 'returns false if user is a developer' do - project.team << [user, :developer] + project.add_developer(user) expect(access.can_push_to_branch?(branch.name)).to be_falsey end it 'returns false if user is a reporter' do - project.team << [user, :reporter] + project.add_reporter(user) expect(access.can_push_to_branch?(branch.name)).to be_falsey end it 'returns false if branch does not exist' do - project.team << [user, :developer] + project.add_developer(user) expect(access.can_push_to_branch?(not_existing_branch.name)).to be_falsey end @@ -100,19 +100,19 @@ describe Gitlab::UserAccess do end it 'returns true if user is a master' do - project.team << [user, :master] + project.add_master(user) expect(access.can_push_to_branch?(@branch.name)).to be_truthy end it 'returns true if user is a developer' do - project.team << [user, :developer] + project.add_developer(user) expect(access.can_push_to_branch?(@branch.name)).to be_truthy end it 'returns false if user is a reporter' do - project.team << [user, :reporter] + project.add_reporter(user) expect(access.can_push_to_branch?(@branch.name)).to be_falsey end @@ -124,19 +124,19 @@ describe Gitlab::UserAccess do end it 'returns true if user is a master' do - project.team << [user, :master] + project.add_master(user) expect(access.can_merge_to_branch?(@branch.name)).to be_truthy end it 'returns true if user is a developer' do - project.team << [user, :developer] + project.add_developer(user) expect(access.can_merge_to_branch?(@branch.name)).to be_truthy end it 'returns false if user is a reporter' do - project.team << [user, :reporter] + project.add_reporter(user) expect(access.can_merge_to_branch?(@branch.name)).to be_falsey end diff --git a/spec/lib/gitlab/visibility_level_spec.rb b/spec/lib/gitlab/visibility_level_spec.rb index 48a67773de9..d85dac630b4 100644 --- a/spec/lib/gitlab/visibility_level_spec.rb +++ b/spec/lib/gitlab/visibility_level_spec.rb @@ -49,4 +49,31 @@ describe Gitlab::VisibilityLevel do .to eq([Gitlab::VisibilityLevel::PUBLIC]) end end + + describe '.allowed_levels' do + it 'only includes the levels that arent restricted' do + stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::INTERNAL]) + + expect(described_class.allowed_levels) + .to contain_exactly(described_class::PRIVATE, described_class::PUBLIC) + end + end + + describe '.closest_allowed_level' do + it 'picks INTERNAL instead of PUBLIC if public is restricted' do + stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC]) + + expect(described_class.closest_allowed_level(described_class::PUBLIC)) + .to eq(described_class::INTERNAL) + end + + it 'picks PRIVATE if nothing is available' do + stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC, + Gitlab::VisibilityLevel::INTERNAL, + Gitlab::VisibilityLevel::PRIVATE]) + + expect(described_class.closest_allowed_level(described_class::PUBLIC)) + .to eq(described_class::PRIVATE) + end + end end diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index 4d0a3942996..cbc8c67da61 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -417,7 +417,7 @@ describe Notify do context 'for a project in a user namespace' do let(:project) do create(:project, :public, :access_requestable) do |project| - project.team << [project.owner, :master, project.owner] + project.add_master(project.owner, current_user: project.owner) end end @@ -520,7 +520,7 @@ describe Notify do end describe 'project invitation' do - let(:master) { create(:user).tap { |u| project.team << [u, :master] } } + let(:master) { create(:user).tap { |u| project.add_master(u) } } let(:project_member) { invite_to_project(project, inviter: master) } subject { described_class.member_invited_email('project', project_member.id, project_member.invite_token) } @@ -540,7 +540,7 @@ describe Notify do describe 'project invitation accepted' do let(:invited_user) { create(:user, name: 'invited user') } - let(:master) { create(:user).tap { |u| project.team << [u, :master] } } + let(:master) { create(:user).tap { |u| project.add_master(u) } } let(:project_member) do invitee = invite_to_project(project, inviter: master) invitee.accept_invite!(invited_user) @@ -563,7 +563,7 @@ describe Notify do end describe 'project invitation declined' do - let(:master) { create(:user).tap { |u| project.team << [u, :master] } } + let(:master) { create(:user).tap { |u| project.add_master(u) } } let(:project_member) do invitee = invite_to_project(project, inviter: master) invitee.decline_invite! diff --git a/spec/migrations/clean_up_for_members_spec.rb b/spec/migrations/clean_up_for_members_spec.rb new file mode 100644 index 00000000000..0258860d169 --- /dev/null +++ b/spec/migrations/clean_up_for_members_spec.rb @@ -0,0 +1,78 @@ +require 'spec_helper' +require Rails.root.join('db', 'migrate', '20171216111734_clean_up_for_members.rb') + +describe CleanUpForMembers, :migration do + let(:migration) { described_class.new } + let!(:group_member) { create_group_member } + let!(:unbinded_group_member) { create_group_member } + let!(:invited_group_member) { create_group_member(true) } + let!(:not_valid_group_member) { create_group_member } + let!(:project_member) { create_project_member } + let!(:invited_project_member) { create_project_member(true) } + let!(:unbinded_project_member) { create_project_member } + let!(:not_valid_project_member) { create_project_member } + + it 'removes members without proper user_id' do + unbinded_group_member.update_column(:user_id, nil) + not_valid_group_member.update_column(:user_id, 9999) + unbinded_project_member.update_column(:user_id, nil) + not_valid_project_member.update_column(:user_id, 9999) + + migrate! + + expect(Member.all).not_to include(unbinded_group_member, not_valid_group_member, unbinded_project_member, not_valid_project_member) + expect(Member.all).to include(group_member, invited_group_member, project_member, invited_project_member) + end + + def create_group_member(invited = false) + fill_member(GroupMember.new(group: create_group), invited) + end + + def create_project_member(invited = false) + fill_member(ProjectMember.new(project: create_project), invited) + end + + def fill_member(member_object, invited) + member_object.tap do |m| + m.access_level = 40 + m.notification_level = 3 + + if invited + m.user_id = nil + m.invite_token = 'xxx' + m.invite_email = 'email@email.com' + else + m.user_id = create_user.id + end + + m.save + end + + member_object + end + + def create_group + name = FFaker::Lorem.characters(10) + + Group.create(name: name, path: name.downcase.gsub(/\s/, '_')) + end + + def create_project + name = FFaker::Lorem.characters(10) + creator = create_user + + Project.create(name: name, + path: name.downcase.gsub(/\s/, '_'), + namespace: creator.namespace, + creator: creator) + end + + def create_user + User.create(email: FFaker::Internet.email, + password: '12345678', + name: FFaker::Name.name, + username: FFaker::Internet.user_name, + confirmed_at: Time.now, + confirmation_token: nil) + end +end diff --git a/spec/migrations/delete_conflicting_redirect_routes_spec.rb b/spec/migrations/delete_conflicting_redirect_routes_spec.rb index 1df2477da51..8a191bd7139 100644 --- a/spec/migrations/delete_conflicting_redirect_routes_spec.rb +++ b/spec/migrations/delete_conflicting_redirect_routes_spec.rb @@ -10,9 +10,6 @@ describe DeleteConflictingRedirectRoutes, :migration, :sidekiq do end before do - stub_const("DeleteConflictingRedirectRoutes::BATCH_SIZE", 2) - stub_const("Gitlab::Database::MigrationHelpers::BACKGROUND_MIGRATION_JOB_BUFFER_SIZE", 2) - routes.create!(id: 1, source_id: 1, source_type: 'Namespace', path: 'foo1') routes.create!(id: 2, source_id: 2, source_type: 'Namespace', path: 'foo2') routes.create!(id: 3, source_id: 3, source_type: 'Namespace', path: 'foo3') @@ -32,27 +29,14 @@ describe DeleteConflictingRedirectRoutes, :migration, :sidekiq do redirect_routes.create!(source_id: 1, source_type: 'Namespace', path: 'foo5') end - it 'correctly schedules background migrations' do + # No-op. See https://gitlab.com/gitlab-com/infrastructure/issues/3460#note_53223252 + it 'NO-OP: does not schedule any background migrations' do Sidekiq::Testing.fake! do Timecop.freeze do migrate! - expect(BackgroundMigrationWorker.jobs[0]['args']).to eq([described_class::MIGRATION, [1, 2]]) - expect(BackgroundMigrationWorker.jobs[0]['at']).to eq(12.seconds.from_now.to_f) - expect(BackgroundMigrationWorker.jobs[1]['args']).to eq([described_class::MIGRATION, [3, 4]]) - expect(BackgroundMigrationWorker.jobs[1]['at']).to eq(24.seconds.from_now.to_f) - expect(BackgroundMigrationWorker.jobs[2]['args']).to eq([described_class::MIGRATION, [5, 5]]) - expect(BackgroundMigrationWorker.jobs[2]['at']).to eq(36.seconds.from_now.to_f) - expect(BackgroundMigrationWorker.jobs.size).to eq 3 + expect(BackgroundMigrationWorker.jobs.size).to eq 0 end end end - - it 'schedules background migrations' do - Sidekiq::Testing.inline! do - expect do - migrate! - end.to change { redirect_routes.count }.from(8).to(3) - end - end end diff --git a/spec/migrations/issues_moved_to_id_foreign_key_spec.rb b/spec/migrations/issues_moved_to_id_foreign_key_spec.rb new file mode 100644 index 00000000000..d2eef81f396 --- /dev/null +++ b/spec/migrations/issues_moved_to_id_foreign_key_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' +require Rails.root.join('db', 'migrate', '20171106151218_issues_moved_to_id_foreign_key.rb') + +# The schema version has to be far enough in advance to have the +# only_mirror_protected_branches column in the projects table to create a +# project via FactoryBot. +describe IssuesMovedToIdForeignKey, :migration, schema: 20171114150259 do + let!(:issue_first) { create(:issue, moved_to_id: issue_second.id) } + let!(:issue_second) { create(:issue, moved_to_id: issue_third.id) } + let!(:issue_third) { create(:issue) } + + subject { described_class.new } + + it 'removes the orphaned moved_to_id' do + subject.down + + issue_third.update_attributes(moved_to_id: 100000) + + subject.up + + expect(issue_first.reload.moved_to_id).to eq(issue_second.id) + expect(issue_second.reload.moved_to_id).to eq(issue_third.id) + expect(issue_third.reload.moved_to_id).to be_nil + end +end diff --git a/spec/migrations/schedule_populate_merge_request_metrics_with_events_data_spec.rb b/spec/migrations/schedule_populate_merge_request_metrics_with_events_data_spec.rb new file mode 100644 index 00000000000..97e089c5cb8 --- /dev/null +++ b/spec/migrations/schedule_populate_merge_request_metrics_with_events_data_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' +require Rails.root.join('db', 'post_migrate', '20171128214150_schedule_populate_merge_request_metrics_with_events_data.rb') + +describe SchedulePopulateMergeRequestMetricsWithEventsData, :migration, :sidekiq do + let!(:mrs) { create_list(:merge_request, 3) } + + it 'correctly schedules background migrations' do + stub_const("#{described_class.name}::BATCH_SIZE", 2) + + Sidekiq::Testing.fake! do + Timecop.freeze do + migrate! + + expect(described_class::MIGRATION) + .to be_scheduled_migration(10.minutes, mrs.first.id, mrs.second.id) + + expect(described_class::MIGRATION) + .to be_scheduled_migration(20.minutes, mrs.third.id, mrs.third.id) + + expect(BackgroundMigrationWorker.jobs.size).to eq(2) + end + end + end +end diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 71aa51e1857..38fb98d4f50 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -34,19 +34,19 @@ describe Ability do end it 'returns false for a guest user' do - project.team << [user, :guest] + project.add_guest(user) expect(described_class.can_edit_note?(user, note)).to be_falsy end it 'returns false for a developer' do - project.team << [user, :developer] + project.add_developer(user) expect(described_class.can_edit_note?(user, note)).to be_falsy end it 'returns true for a master' do - project.team << [user, :master] + project.add_master(user) expect(described_class.can_edit_note?(user, note)).to be_truthy end diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index a1f63a2534b..7bef798a782 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -1440,7 +1440,7 @@ describe Ci::Pipeline, :mailer do end before do - project.team << [pipeline.user, Gitlab::Access::DEVELOPER] + project.add_developer(pipeline.user) pipeline.user.global_notification_setting .update(level: 'custom', failed_pipeline: true, success_pipeline: true) diff --git a/spec/models/ci/trigger_spec.rb b/spec/models/ci/trigger_spec.rb index bd9c837402f..d4b72205203 100644 --- a/spec/models/ci/trigger_spec.rb +++ b/spec/models/ci/trigger_spec.rb @@ -69,7 +69,7 @@ describe Ci::Trigger do context 'and is member of the project' do before do - project.team << [owner, :developer] + project.add_developer(owner) end it { is_expected.to eq(true) } diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb index cd955a5eb69..4f02dc33cd8 100644 --- a/spec/models/commit_spec.rb +++ b/spec/models/commit_spec.rb @@ -193,8 +193,8 @@ eos let(:commiter) { create :user } before do - project.team << [commiter, :developer] - other_project.team << [commiter, :developer] + project.add_developer(commiter) + other_project.add_developer(commiter) end it 'detects issues that this commit is marked as closing' do diff --git a/spec/models/concerns/mentionable_spec.rb b/spec/models/concerns/mentionable_spec.rb index 8b545aec7f5..c73ea6aa94c 100644 --- a/spec/models/concerns/mentionable_spec.rb +++ b/spec/models/concerns/mentionable_spec.rb @@ -62,7 +62,7 @@ describe Issue, "Mentionable" do context 'when the current user can see the issue' do before do - private_project.team << [user, Gitlab::Access::DEVELOPER] + private_project.add_developer(user) end it 'includes the reference' do @@ -107,7 +107,7 @@ describe Issue, "Mentionable" do let(:issues) { create_list(:issue, 2, project: project, author: author) } before do - project.team << [author, Gitlab::Access::DEVELOPER] + project.add_developer(author) end context 'before changes are persisted' do diff --git a/spec/models/concerns/milestoneish_spec.rb b/spec/models/concerns/milestoneish_spec.rb index 673c609f534..87bf731340f 100644 --- a/spec/models/concerns/milestoneish_spec.rb +++ b/spec/models/concerns/milestoneish_spec.rb @@ -24,8 +24,8 @@ describe Milestone, 'Milestoneish' do let(:label_3) { create(:label, title: 'label_3', project: project) } before do - project.team << [member, :developer] - project.team << [guest, :guest] + project.add_developer(member) + project.add_guest(guest) end describe '#sorted_issues' do diff --git a/spec/models/concerns/resolvable_discussion_spec.rb b/spec/models/concerns/resolvable_discussion_spec.rb index 1616c2ea985..2a2ef5a304d 100644 --- a/spec/models/concerns/resolvable_discussion_spec.rb +++ b/spec/models/concerns/resolvable_discussion_spec.rb @@ -190,7 +190,7 @@ describe Discussion, ResolvableDiscussion do context "when the signed in user can push to the project" do before do - subject.project.team << [current_user, :master] + subject.project.add_master(current_user) end it "returns true" do diff --git a/spec/models/diff_discussion_spec.rb b/spec/models/diff_discussion_spec.rb index fa02434b0fd..50b19000799 100644 --- a/spec/models/diff_discussion_spec.rb +++ b/spec/models/diff_discussion_spec.rb @@ -47,8 +47,20 @@ describe DiffDiscussion do diff_note.save! end - it 'returns the diff ID for the version to show' do - expect(subject.merge_request_version_params).to eq(diff_id: merge_request_diff1.id) + context 'when commit_id is not present' do + it 'returns the diff ID for the version to show' do + expect(subject.merge_request_version_params).to eq(diff_id: merge_request_diff1.id) + end + end + + context 'when commit_id is present' do + before do + diff_note.update_attribute(:commit_id, 'commit_123') + end + + it 'includes the commit_id in the result' do + expect(subject.merge_request_version_params).to eq(diff_id: merge_request_diff1.id, commit_id: 'commit_123') + end end end @@ -70,8 +82,20 @@ describe DiffDiscussion do diff_note.save! end - it 'returns the diff ID and start sha of the versions to compare' do - expect(subject.merge_request_version_params).to eq(diff_id: merge_request_diff3.id, start_sha: merge_request_diff1.head_commit_sha) + context 'when commit_id is not present' do + it 'returns the diff ID and start sha of the versions to compare' do + expect(subject.merge_request_version_params).to eq(diff_id: merge_request_diff3.id, start_sha: merge_request_diff1.head_commit_sha) + end + end + + context 'when commit_id is present' do + before do + diff_note.update_attribute(:commit_id, 'commit_123') + end + + it 'includes the commit_id in the result' do + expect(subject.merge_request_version_params).to eq(diff_id: merge_request_diff3.id, start_sha: merge_request_diff1.head_commit_sha, commit_id: 'commit_123') + end end end @@ -83,8 +107,20 @@ describe DiffDiscussion do diff_note.save! end - it 'returns nil' do - expect(subject.merge_request_version_params).to be_nil + context 'when commit_id is not present' do + it 'returns empty hash' do + expect(subject.merge_request_version_params).to eq(nil) + end + end + + context 'when commit_id is present' do + before do + diff_note.update_attribute(:commit_id, 'commit_123') + end + + it 'returns the commit_id' do + expect(subject.merge_request_version_params).to eq(commit_id: 'commit_123') + end end end end diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index aa7a8342a4c..67f49348acb 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -125,8 +125,8 @@ describe Event do let(:event) { described_class.new(project: project, target: target, author_id: author.id) } before do - project.team << [member, :developer] - project.team << [guest, :guest] + project.add_developer(member) + project.add_guest(guest) end context 'commit note event' do @@ -347,6 +347,22 @@ describe Event do end end + describe '#target' do + it 'eager loads the author of an event target' do + create(:closed_issue_event) + + events = described_class.preload(:target).all.to_a + count = ActiveRecord::QueryRecorder + .new { events.first.target.author }.count + + # This expectation exists to make sure the test doesn't pass when the + # author is for some reason not loaded at all. + expect(events.first.target.author).to be_an_instance_of(User) + + expect(count).to be_zero + end + end + def create_push_event(project, user) event = create(:push_event, project: project, author: user) diff --git a/spec/models/generic_commit_status_spec.rb b/spec/models/generic_commit_status_spec.rb index 7f1909710d8..673049d1cc4 100644 --- a/spec/models/generic_commit_status_spec.rb +++ b/spec/models/generic_commit_status_spec.rb @@ -43,7 +43,7 @@ describe GenericCommitStatus do context 'when user has ability to see datails' do before do - project.team << [user, :developer] + project.add_developer(user) end it 'details path points to an external URL' do diff --git a/spec/models/hooks/system_hook_spec.rb b/spec/models/hooks/system_hook_spec.rb index 431e3db9f00..0e965f541d8 100644 --- a/spec/models/hooks/system_hook_spec.rb +++ b/spec/models/hooks/system_hook_spec.rb @@ -62,7 +62,7 @@ describe SystemHook do end it "project_create hook" do - project.team << [user, :master] + project.add_master(user) expect(WebMock).to have_requested(:post, system_hook.url).with( body: /user_add_to_team/, @@ -71,7 +71,7 @@ describe SystemHook do end it "project_destroy hook" do - project.team << [user, :master] + project.add_master(user) project.project_members.destroy_all expect(WebMock).to have_requested(:post, system_hook.url).with( diff --git a/spec/models/issue_collection_spec.rb b/spec/models/issue_collection_spec.rb index 34d98a3c975..580a98193af 100644 --- a/spec/models/issue_collection_spec.rb +++ b/spec/models/issue_collection_spec.rb @@ -42,7 +42,7 @@ describe IssueCollection do context 'using a user that has reporter access to the project' do it 'returns the issues of the project' do - project.team << [user, :reporter] + project.add_reporter(user) expect(collection.updatable_by_user(user)).to eq([issue1, issue2]) end diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index 0ea287d007a..5ced000cdb6 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -23,6 +23,32 @@ describe Issue do it { is_expected.to have_db_index(:deleted_at) } end + describe 'callbacks' do + describe '#ensure_metrics' do + it 'creates metrics after saving' do + issue = create(:issue) + + expect(issue.metrics).to be_persisted + expect(Issue::Metrics.count).to eq(1) + end + + it 'does not create duplicate metrics for an issue' do + issue = create(:issue) + + issue.close! + + expect(issue.metrics).to be_persisted + expect(Issue::Metrics.count).to eq(1) + end + + it 'records current metrics' do + expect_any_instance_of(Issue::Metrics).to receive(:record!) + + create(:issue) + end + end + end + describe '#order_by_position_and_priority' do let(:project) { create :project } let(:p1) { create(:label, title: 'P1', project: project, priority: 1) } @@ -238,7 +264,7 @@ describe Issue do let(:issue) { create(:issue, project: project) } before do - project.team << [user, :reporter] + project.add_reporter(user) end it { is_expected.to eq true } @@ -254,7 +280,7 @@ describe Issue do context 'destination project allowed' do before do - to_project.team << [user, :reporter] + to_project.add_reporter(user) end it { is_expected.to eq true } @@ -262,7 +288,7 @@ describe Issue do context 'destination project not allowed' do before do - to_project.team << [user, :guest] + to_project.add_guest(user) end it { is_expected.to eq false } @@ -550,7 +576,7 @@ describe Issue do context 'when the user is the project owner' do before do - project.team << [user, :master] + project.add_master(user) end it 'returns true for a regular issue' do @@ -574,7 +600,7 @@ describe Issue do context 'using a public project' do before do - project.team << [user, Gitlab::Access::DEVELOPER] + project.add_developer(user) end it 'returns true for a regular issue' do @@ -594,7 +620,7 @@ describe Issue do let(:project) { create(:project, :internal) } before do - project.team << [user, Gitlab::Access::DEVELOPER] + project.add_developer(user) end it 'returns true for a regular issue' do @@ -614,7 +640,7 @@ describe Issue do let(:project) { create(:project, :private) } before do - project.team << [user, Gitlab::Access::DEVELOPER] + project.add_developer(user) end it 'returns true for a regular issue' do diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index 0a017c068ad..6aa0e7f49c3 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -62,12 +62,12 @@ describe Member do @owner_user = create(:user).tap { |u| group.add_owner(u) } @owner = group.members.find_by(user_id: @owner_user.id) - @master_user = create(:user).tap { |u| project.team << [u, :master] } + @master_user = create(:user).tap { |u| project.add_master(u) } @master = project.members.find_by(user_id: @master_user.id) @blocked_user = create(:user).tap do |u| - project.team << [u, :master] - project.team << [u, :developer] + project.add_master(u) + project.add_developer(u) u.block! end @@ -527,7 +527,7 @@ describe Member do it "refreshes user's authorized projects" do project = create(:project, :private) user = create(:user) - member = project.team << [user, :reporter] + member = project.add_reporter(user) member.destroy diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb index fa3e80ba062..3e46fa36375 100644 --- a/spec/models/members/project_member_spec.rb +++ b/spec/models/members/project_member_spec.rb @@ -88,8 +88,8 @@ describe ProjectMember do @user_1 = create :user @user_2 = create :user - @project_1.team << [@user_1, :developer] - @project_2.team << [@user_2, :reporter] + @project_1.add_developer(@user_1) + @project_2.add_reporter(@user_2) @status = @project_2.team.import(@project_1) end @@ -136,8 +136,8 @@ describe ProjectMember do @user_1 = create :user @user_2 = create :user - @project_1.team << [@user_1, :developer] - @project_2.team << [@user_2, :reporter] + @project_1.add_developer(@user_1) + @project_2.add_reporter(@user_2) described_class.truncate_teams([@project_1.id, @project_2.id]) end diff --git a/spec/models/merge_request/metrics_spec.rb b/spec/models/merge_request/metrics_spec.rb index 9353d5c3c8a..02ff7839739 100644 --- a/spec/models/merge_request/metrics_spec.rb +++ b/spec/models/merge_request/metrics_spec.rb @@ -1,16 +1,11 @@ require 'spec_helper' describe MergeRequest::Metrics do - subject { create(:merge_request) } + subject { described_class.new } - describe "when recording the default set of metrics on merge request save" do - it "records the merge time" do - time = Time.now - Timecop.freeze(time) { subject.mark_as_merged } - metrics = subject.metrics - - expect(metrics).to be_present - expect(metrics.merged_at).to be_like_time(time) - end + describe 'associations' do + it { is_expected.to belong_to(:merge_request) } + it { is_expected.to belong_to(:latest_closed_by).class_name('User') } + it { is_expected.to belong_to(:merged_by).class_name('User') } end end diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index bb63abd167b..d8ebd46faab 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -65,6 +65,25 @@ describe MergeRequest do end end + describe 'callbacks' do + describe '#ensure_merge_request_metrics' do + it 'creates metrics after saving' do + merge_request = create(:merge_request) + + expect(merge_request.metrics).to be_persisted + expect(MergeRequest::Metrics.count).to eq(1) + end + + it 'does not duplicate metrics for a merge request' do + merge_request = create(:merge_request) + + merge_request.mark_as_merged! + + expect(MergeRequest::Metrics.count).to eq(1) + end + end + end + describe 'respond to' do it { is_expected.to respond_to(:unchecked?) } it { is_expected.to respond_to(:can_be_merged?) } @@ -195,7 +214,7 @@ describe MergeRequest do describe '#cache_merge_request_closes_issues!' do before do - subject.project.team << [subject.author, :developer] + subject.project.add_developer(subject.author) subject.target_branch = subject.project.default_branch end @@ -481,7 +500,7 @@ describe MergeRequest do let(:commit2) { double('commit2', safe_message: "Fixes #{issue1.to_reference}") } before do - subject.project.team << [subject.author, :developer] + subject.project.add_developer(subject.author) allow(subject).to receive(:commits).and_return([commit0, commit1, commit2]) end @@ -509,7 +528,7 @@ describe MergeRequest do let(:commit) { double('commit', safe_message: "Fixes #{closing_issue.to_reference}") } it 'detects issues mentioned in description but not closed' do - subject.project.team << [subject.author, :developer] + subject.project.add_developer(subject.author) subject.description = "Is related to #{mentioned_issue.to_reference} and #{closing_issue.to_reference}" allow(subject).to receive(:commits).and_return([commit]) @@ -521,7 +540,7 @@ describe MergeRequest do context 'when the project has an external issue tracker' do before do - subject.project.team << [subject.author, :developer] + subject.project.add_developer(subject.author) commit = double(:commit, safe_message: 'Fixes TEST-3') create(:jira_service, project: subject.project) @@ -660,7 +679,7 @@ describe MergeRequest do it 'includes its closed issues in the body' do issue = create(:issue, project: subject.project) - subject.project.team << [subject.author, :developer] + subject.project.add_developer(subject.author) subject.description = "This issue Closes #{issue.to_reference}" allow(subject.project).to receive(:default_branch) @@ -1688,7 +1707,7 @@ describe MergeRequest do let(:mr_sha) { merge_request.diff_head_sha } before do - project.team << [developer, :developer] + project.add_developer(developer) end context 'when autocomplete_precheck is set to true' do diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index b7c6286fd83..0678cae9b93 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -203,7 +203,7 @@ describe Namespace do context 'with subgroups' do let(:parent) { create(:group, name: 'parent', path: 'parent') } let(:child) { create(:group, name: 'child', path: 'child', parent: parent) } - let!(:project) { create(:project_empty_repo, path: 'the-project', namespace: child) } + let!(:project) { create(:project_empty_repo, path: 'the-project', namespace: child, skip_disk_validation: true) } let(:uploads_dir) { File.join(CarrierWave.root, FileUploader.base_dir) } let(:pages_dir) { File.join(TestEnv.pages_path) } @@ -240,6 +240,20 @@ describe Namespace do end end end + + it 'updates project full path in .git/config for each project inside namespace' do + parent = create(:group, name: 'mygroup', path: 'mygroup') + subgroup = create(:group, name: 'mysubgroup', path: 'mysubgroup', parent: parent) + project_in_parent_group = create(:project, :repository, namespace: parent, name: 'foo1') + hashed_project_in_subgroup = create(:project, :repository, :hashed, namespace: subgroup, name: 'foo2') + legacy_project_in_subgroup = create(:project, :repository, namespace: subgroup, name: 'foo3') + + parent.update(path: 'mygroup_new') + + expect(project_in_parent_group.repo.config['gitlab.fullpath']).to eq "mygroup_new/#{project_in_parent_group.path}" + expect(hashed_project_in_subgroup.repo.config['gitlab.fullpath']).to eq "mygroup_new/mysubgroup/#{hashed_project_in_subgroup.path}" + expect(legacy_project_in_subgroup.repo.config['gitlab.fullpath']).to eq "mygroup_new/mysubgroup/#{legacy_project_in_subgroup.path}" + end end describe '#rm_dir', 'callback' do diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index cefbf60b28c..3d030927036 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -195,7 +195,7 @@ describe Note do describe "cross_reference_not_visible_for?" do let(:private_user) { create(:user) } - let(:private_project) { create(:project, namespace: private_user.namespace) { |p| p.team << [private_user, :master] } } + let(:private_project) { create(:project, namespace: private_user.namespace) { |p| p.add_master(private_user) } } let(:private_issue) { create(:issue, project: private_project) } let(:ext_proj) { create(:project, :public) } diff --git a/spec/models/project_feature_spec.rb b/spec/models/project_feature_spec.rb index de3e86b627f..63c6fbda3f2 100644 --- a/spec/models/project_feature_spec.rb +++ b/spec/models/project_feature_spec.rb @@ -37,7 +37,7 @@ describe ProjectFeature do end it "returns true when user is a team member" do - project.team << [user, :developer] + project.add_developer(user) features.each do |feature| project.project_feature.update_attribute("#{feature}_access_level".to_sym, ProjectFeature::PRIVATE) diff --git a/spec/models/project_services/kubernetes_service_spec.rb b/spec/models/project_services/kubernetes_service_spec.rb index f037ee77a94..6980ba335b8 100644 --- a/spec/models/project_services/kubernetes_service_spec.rb +++ b/spec/models/project_services/kubernetes_service_spec.rb @@ -52,12 +52,75 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do context 'when service is inactive' do before do + subject.project = project subject.active = false end it { is_expected.not_to validate_presence_of(:api_url) } it { is_expected.not_to validate_presence_of(:token) } end + + context 'with a deprecated service' do + let(:kubernetes_service) { create(:kubernetes_service) } + + before do + kubernetes_service.update_attribute(:active, false) + kubernetes_service.properties[:namespace] = "foo" + end + + it 'should not update attributes' do + expect(kubernetes_service.save).to be_falsy + end + + it 'should include an error with a deprecation message' do + kubernetes_service.valid? + expect(kubernetes_service.errors[:base].first).to match(/Kubernetes service integration has been deprecated/) + end + end + + context 'with a non-deprecated service' do + let(:kubernetes_service) { create(:kubernetes_service) } + + it 'should update attributes' do + kubernetes_service.properties[:namespace] = 'foo' + expect(kubernetes_service.save).to be_truthy + end + end + + context 'with an active and deprecated service' do + let(:kubernetes_service) { create(:kubernetes_service) } + + before do + kubernetes_service.active = false + kubernetes_service.properties[:namespace] = 'foo' + kubernetes_service.save + end + + it 'should deactive the service' do + expect(kubernetes_service.active?).to be_falsy + end + + it 'should not include a deprecation message as error' do + expect(kubernetes_service.errors.messages.count).to eq(0) + end + + it 'should update attributes' do + expect(kubernetes_service.properties[:namespace]).to eq("foo") + end + end + + context 'with a template service' do + let(:kubernetes_service) { create(:kubernetes_service, template: true, active: false) } + + before do + kubernetes_service.properties[:namespace] = 'foo' + end + + it 'should update attributes' do + expect(kubernetes_service.save).to be_truthy + expect(kubernetes_service.properties[:namespace]).to eq('foo') + end + end end describe '#initialize_properties' do @@ -318,4 +381,42 @@ describe KubernetesService, :use_clean_rails_memory_store_caching do it { is_expected.to eq(pods: []) } end end + + describe "#deprecated?" do + let(:kubernetes_service) { create(:kubernetes_service) } + + context 'with an active kubernetes service' do + it 'should return false' do + expect(kubernetes_service.deprecated?).to be_falsy + end + end + + context 'with a inactive kubernetes service' do + it 'should return true' do + kubernetes_service.update_attribute(:active, false) + expect(kubernetes_service.deprecated?).to be_truthy + end + end + end + + describe "#deprecation_message" do + let(:kubernetes_service) { create(:kubernetes_service) } + + it 'should indicate the service is deprecated' do + expect(kubernetes_service.deprecation_message).to match(/Kubernetes service integration has been deprecated/) + end + + context 'if the services is active' do + it 'should return a message' do + expect(kubernetes_service.deprecation_message).to match(/Your cluster information on this page is still editable/) + end + end + + context 'if the service is not active' do + it 'should return a message' do + kubernetes_service.update_attribute(:active, false) + expect(kubernetes_service.deprecation_message).to match(/Fields on this page are now uneditable/) + end + end + end end diff --git a/spec/models/project_services/pipelines_email_service_spec.rb b/spec/models/project_services/pipelines_email_service_spec.rb index be07ca2d945..75ae2207910 100644 --- a/spec/models/project_services/pipelines_email_service_spec.rb +++ b/spec/models/project_services/pipelines_email_service_spec.rb @@ -37,7 +37,7 @@ describe PipelinesEmailService, :mailer do let(:user) { create(:user) } before do - project.team << [user, :developer] + project.add_developer(user) end it 'builds test data' do diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index cbeac2f05d3..cea22bbd184 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -93,7 +93,7 @@ describe Project do let(:developer) { create(:user) } before do project.request_access(requester) - project.team << [developer, :developer] + project.add_developer(developer) end it_behaves_like 'members and requesters associations' do @@ -520,7 +520,7 @@ describe Project do let(:user) { create(:user) } before do - project.team << [user, :developer] + project.add_developer(user) end context 'with default issues tracker' do @@ -1435,35 +1435,35 @@ describe Project do let(:user) { create(:user) } it 'returns false when default_branch_protection is in full protection and user is developer' do - project.team << [user, :developer] + project.add_developer(user) stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_FULL) expect(project.user_can_push_to_empty_repo?(user)).to be_falsey end it 'returns false when default_branch_protection only lets devs merge and user is dev' do - project.team << [user, :developer] + project.add_developer(user) stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_MERGE) expect(project.user_can_push_to_empty_repo?(user)).to be_falsey end it 'returns true when default_branch_protection lets devs push and user is developer' do - project.team << [user, :developer] + project.add_developer(user) stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_PUSH) expect(project.user_can_push_to_empty_repo?(user)).to be_truthy end it 'returns true when default_branch_protection is unprotected and user is developer' do - project.team << [user, :developer] + project.add_developer(user) stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_NONE) expect(project.user_can_push_to_empty_repo?(user)).to be_truthy end it 'returns true when user is master' do - project.team << [user, :master] + project.add_master(user) expect(project.user_can_push_to_empty_repo?(user)).to be_truthy end @@ -2626,6 +2626,14 @@ describe Project do project.rename_repo end end + + it 'updates project full path in .git/config' do + allow(project_storage).to receive(:rename_repo).and_return(true) + + project.rename_repo + + expect(project.repo.config['gitlab.fullpath']).to eq(project.full_path) + end end describe '#pages_path' do @@ -2668,14 +2676,12 @@ describe Project do end context 'hashed storage' do - let(:project) { create(:project, :repository) } + let(:project) { create(:project, :repository, skip_disk_validation: true) } let(:gitlab_shell) { Gitlab::Shell.new } - let(:hash) { '6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b' } + let(:hash) { Digest::SHA2.hexdigest(project.id.to_s) } before do stub_application_setting(hashed_storage_enabled: true) - allow(Digest::SHA2).to receive(:hexdigest) { hash } - allow(project).to receive(:gitlab_shell).and_return(gitlab_shell) end describe '#legacy_storage?' do @@ -2698,13 +2704,13 @@ describe Project do describe '#base_dir' do it 'returns base_dir based on hash of project id' do - expect(project.base_dir).to eq('@hashed/6b/86') + expect(project.base_dir).to eq("@hashed/#{hash[0..1]}/#{hash[2..3]}") end end describe '#disk_path' do it 'returns disk_path based on hash of project id' do - hashed_path = '@hashed/6b/86/6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b' + hashed_path = "@hashed/#{hash[0..1]}/#{hash[2..3]}/#{hash}" expect(project.disk_path).to eq(hashed_path) end @@ -2712,7 +2718,9 @@ describe Project do describe '#ensure_storage_path_exists' do it 'delegates to gitlab_shell to ensure namespace is created' do - expect(gitlab_shell).to receive(:add_namespace).with(project.repository_storage_path, '@hashed/6b/86') + allow(project).to receive(:gitlab_shell).and_return(gitlab_shell) + + expect(gitlab_shell).to receive(:add_namespace).with(project.repository_storage_path, "@hashed/#{hash[0..1]}/#{hash[2..3]}") project.ensure_storage_path_exists end @@ -2772,7 +2780,7 @@ describe Project do end context 'when not rolled out' do - let(:project) { create(:project, :repository, storage_version: 1) } + let(:project) { create(:project, :repository, storage_version: 1, skip_disk_validation: true) } it 'moves pages folder to new location' do expect_any_instance_of(Gitlab::UploadsTransfer).to receive(:rename_project) @@ -2781,6 +2789,12 @@ describe Project do end end end + + it 'updates project full path in .git/config' do + project.rename_repo + + expect(project.repo.config['gitlab.fullpath']).to eq(project.full_path) + end end describe '#pages_path' do @@ -3141,4 +3155,26 @@ describe Project do it { is_expected.to eq(platform_kubernetes) } end end + + describe '#write_repository_config' do + set(:project) { create(:project, :repository) } + + it 'writes full path in .git/config when key is missing' do + project.write_repository_config + + expect(project.repo.config['gitlab.fullpath']).to eq project.full_path + end + + it 'updates full path in .git/config when key is present' do + project.write_repository_config(gl_full_path: 'old/path') + + expect { project.write_repository_config }.to change { project.repo.config['gitlab.fullpath'] }.from('old/path').to(project.full_path) + end + + it 'does not raise an error with an empty repository' do + project = create(:project_empty_repo) + + expect { project.write_repository_config }.not_to raise_error + end + end end diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb index 314824b32da..e07c522800a 100644 --- a/spec/models/project_team_spec.rb +++ b/spec/models/project_team_spec.rb @@ -291,8 +291,8 @@ describe ProjectTeam do group.add_master(master) group.add_developer(developer) - members_project.team << [developer, :developer] - members_project.team << [master, :master] + members_project.add_developer(developer) + members_project.add_master(master) create(:project_group_link, project: shared_project, group: group) end diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb index 0f2f906c667..540615de117 100644 --- a/spec/models/service_spec.rb +++ b/spec/models/service_spec.rb @@ -254,4 +254,22 @@ describe Service do end end end + + describe "#deprecated?" do + let(:project) { create(:project, :repository) } + + it 'should return false by default' do + service = create(:service, project: project) + expect(service.deprecated?).to be_falsy + end + end + + describe "#deprecation_message" do + let(:project) { create(:project, :repository) } + + it 'should be empty by default' do + service = create(:service, project: project) + expect(service.deprecation_message).to be_nil + end + end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index e58e7588df0..8d0eaf565a7 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -22,7 +22,9 @@ describe User do describe 'associations' do it { is_expected.to have_one(:namespace) } it { is_expected.to have_many(:snippets).dependent(:destroy) } - it { is_expected.to have_many(:project_members).dependent(:destroy) } + it { is_expected.to have_many(:members) } + it { is_expected.to have_many(:project_members) } + it { is_expected.to have_many(:group_members) } it { is_expected.to have_many(:groups) } it { is_expected.to have_many(:keys).dependent(:destroy) } it { is_expected.to have_many(:deploy_keys).dependent(:destroy) } @@ -134,6 +136,16 @@ describe User do end end + it 'has a DB-level NOT NULL constraint on projects_limit' do + user = create(:user) + + expect(user.persisted?).to eq(true) + + expect do + user.update_columns(projects_limit: nil) + end.to raise_error(ActiveRecord::StatementInvalid) + end + it { is_expected.to validate_presence_of(:projects_limit) } it { is_expected.to validate_numericality_of(:projects_limit) } it { is_expected.to allow_value(0).for(:projects_limit) } @@ -760,7 +772,7 @@ describe User do before do # add user to project - project.team << [user, :master] + project.add_master(user) # create invite to projet create(:project_member, :developer, project: project, invite_token: '1234', invite_email: 'inviteduser1@example.com') @@ -805,6 +817,13 @@ describe User do expect(user.can_create_group).to be_falsey expect(user.theme_id).to eq(1) end + + it 'does not undo projects_limit setting if it matches old DB default of 10' do + # If the real default project limit is 10 then this test is worthless + expect(Gitlab.config.gitlab.default_projects_limit).not_to eq(10) + user = described_class.new(projects_limit: 10) + expect(user.projects_limit).to eq(10) + end end context 'when current_application_settings.user_default_external is true' do @@ -1448,8 +1467,8 @@ describe User do let!(:merge_event) { create(:event, :created, project: project3, target: merge_request, author: subject) } before do - project1.team << [subject, :master] - project2.team << [subject, :master] + project1.add_master(subject) + project2.add_master(subject) end it "includes IDs for projects the user has pushed to" do @@ -1548,7 +1567,7 @@ describe User do user = create(:user) project = create(:project, :private) - project.team << [user, Gitlab::Access::MASTER] + project.add_master(user) expect(user.authorized_projects(Gitlab::Access::REPORTER)) .to contain_exactly(project) @@ -1567,7 +1586,7 @@ describe User do user2 = create(:user) project = create(:project, :private, namespace: user1.namespace) - project.team << [user2, Gitlab::Access::DEVELOPER] + project.add_developer(user2) expect(user2.authorized_projects).to include(project) end @@ -1612,7 +1631,7 @@ describe User do user2 = create(:user) project = create(:project, :private, namespace: user1.namespace) - project.team << [user2, Gitlab::Access::DEVELOPER] + project.add_developer(user2) expect(user2.authorized_projects).to include(project) @@ -1702,7 +1721,7 @@ describe User do shared_examples :member do context 'when the user is a master' do before do - add_user(Gitlab::Access::MASTER) + add_user(:master) end it 'loads' do @@ -1712,7 +1731,7 @@ describe User do context 'when the user is a developer' do before do - add_user(Gitlab::Access::DEVELOPER) + add_user(:developer) end it 'does not load' do @@ -1736,7 +1755,7 @@ describe User do let(:project) { create(:project) } def add_user(access) - project.team << [user, access] + project.add_role(user, access) end it_behaves_like :member @@ -1749,8 +1768,8 @@ describe User do let(:user) { create(:user) } before do - project1.team << [user, :reporter] - project2.team << [user, :guest] + project1.add_reporter(user) + project2.add_guest(user) end it 'returns the projects when using a single project ID' do @@ -1892,8 +1911,8 @@ describe User do let(:user) { create(:user) } before do - project1.team << [user, :reporter] - project2.team << [user, :guest] + project1.add_reporter(user) + project2.add_guest(user) user.project_authorizations.delete_all user.refresh_authorized_projects diff --git a/spec/policies/ci/build_policy_spec.rb b/spec/policies/ci/build_policy_spec.rb index 298a9d16425..41cf2ef7225 100644 --- a/spec/policies/ci/build_policy_spec.rb +++ b/spec/policies/ci/build_policy_spec.rb @@ -57,7 +57,7 @@ describe Ci::BuildPolicy do context 'team member is a guest' do before do - project.team << [user, :guest] + project.add_guest(user) end context 'when public builds are enabled' do @@ -77,7 +77,7 @@ describe Ci::BuildPolicy do context 'team member is a reporter' do before do - project.team << [user, :reporter] + project.add_reporter(user) end context 'when public builds are enabled' do diff --git a/spec/policies/ci/trigger_policy_spec.rb b/spec/policies/ci/trigger_policy_spec.rb index be40dbb2aa9..14630748c90 100644 --- a/spec/policies/ci/trigger_policy_spec.rb +++ b/spec/policies/ci/trigger_policy_spec.rb @@ -45,7 +45,7 @@ describe Ci::TriggerPolicy do context 'when user is master of the project' do before do - project.team << [user, :master] + project.add_master(user) end it_behaves_like 'allows to admin and manage trigger' @@ -53,7 +53,7 @@ describe Ci::TriggerPolicy do context 'when user is developer of the project' do before do - project.team << [user, :developer] + project.add_developer(user) end it_behaves_like 'disallows to admin and manage trigger' @@ -69,7 +69,7 @@ describe Ci::TriggerPolicy do context 'when user is master of the project' do before do - project.team << [user, :master] + project.add_master(user) end it_behaves_like 'allows to admin and manage trigger' @@ -81,7 +81,7 @@ describe Ci::TriggerPolicy do context 'when user is master of the project' do before do - project.team << [user, :master] + project.add_master(user) end it_behaves_like 'allows to manage trigger' @@ -89,7 +89,7 @@ describe Ci::TriggerPolicy do context 'when user is developer of the project' do before do - project.team << [user, :developer] + project.add_developer(user) end it_behaves_like 'disallows to admin and manage trigger' diff --git a/spec/policies/issue_policy_spec.rb b/spec/policies/issue_policy_spec.rb index be4c24c727c..a4af9361ea6 100644 --- a/spec/policies/issue_policy_spec.rb +++ b/spec/policies/issue_policy_spec.rb @@ -19,10 +19,10 @@ describe IssuePolicy do let(:issue_no_assignee) { create(:issue, project: project) } before do - project.team << [guest, :guest] - project.team << [author, :guest] - project.team << [assignee, :guest] - project.team << [reporter, :reporter] + project.add_guest(guest) + project.add_guest(author) + project.add_guest(assignee) + project.add_reporter(reporter) group.add_reporter(reporter_from_group_link) @@ -114,8 +114,8 @@ describe IssuePolicy do let(:issue_no_assignee) { create(:issue, project: project) } before do - project.team << [guest, :guest] - project.team << [reporter, :reporter] + project.add_guest(guest) + project.add_reporter(reporter) group.add_reporter(reporter_from_group_link) diff --git a/spec/policies/project_snippet_policy_spec.rb b/spec/policies/project_snippet_policy_spec.rb index f0bf46c480a..cdba1b09fc1 100644 --- a/spec/policies/project_snippet_policy_spec.rb +++ b/spec/policies/project_snippet_policy_spec.rb @@ -87,7 +87,7 @@ describe ProjectSnippetPolicy do subject { abilities(external_user, :internal) } before do - project.team << [external_user, :developer] + project.add_developer(external_user) end it do @@ -131,7 +131,7 @@ describe ProjectSnippetPolicy do subject { abilities(regular_user, :private) } before do - project.team << [regular_user, :developer] + project.add_developer(regular_user) end it do @@ -144,7 +144,7 @@ describe ProjectSnippetPolicy do subject { abilities(external_user, :private) } before do - project.team << [external_user, :developer] + project.add_developer(external_user) end it do diff --git a/spec/presenters/merge_request_presenter_spec.rb b/spec/presenters/merge_request_presenter_spec.rb index f325d1776e4..969c4753f33 100644 --- a/spec/presenters/merge_request_presenter_spec.rb +++ b/spec/presenters/merge_request_presenter_spec.rb @@ -116,7 +116,7 @@ describe MergeRequestPresenter do end before do - project.team << [user, :developer] + project.add_developer(user) allow(resource.project).to receive(:default_branch) .and_return(resource.target_branch) @@ -270,7 +270,7 @@ describe MergeRequestPresenter do context 'when can create issue and issues enabled' do it 'returns path' do allow(project).to receive(:issues_enabled?) { true } - project.team << [user, :master] + project.add_master(user) is_expected .to eq("/#{resource.project.full_path}/issues/new?merge_request_to_resolve_discussions_of=#{resource.iid}") @@ -288,7 +288,7 @@ describe MergeRequestPresenter do context 'when issues disabled' do it 'returns nil' do allow(project).to receive(:issues_enabled?) { false } - project.team << [user, :master] + project.add_master(user) is_expected.to be_nil end @@ -307,7 +307,7 @@ describe MergeRequestPresenter do context 'when merge request enabled and has permission' do it 'has remove_wip_path' do allow(project).to receive(:merge_requests_enabled?) { true } - project.team << [user, :master] + project.add_master(user) is_expected .to eq("/#{resource.project.full_path}/merge_requests/#{resource.iid}/remove_wip") diff --git a/spec/requests/api/access_requests_spec.rb b/spec/requests/api/access_requests_spec.rb index 35ca3635a9d..24389f28b21 100644 --- a/spec/requests/api/access_requests_spec.rb +++ b/spec/requests/api/access_requests_spec.rb @@ -8,8 +8,8 @@ describe API::AccessRequests do set(:project) do create(:project, :public, :access_requestable, creator_id: master.id, namespace: master.namespace) do |project| - project.team << [developer, :developer] - project.team << [master, :master] + project.add_developer(developer) + project.add_master(master) project.request_access(access_requester) end end diff --git a/spec/requests/api/award_emoji_spec.rb b/spec/requests/api/award_emoji_spec.rb index eaf12f71421..5adfb33677f 100644 --- a/spec/requests/api/award_emoji_spec.rb +++ b/spec/requests/api/award_emoji_spec.rb @@ -10,7 +10,7 @@ describe API::AwardEmoji do set(:note) { create(:note, project: project, noteable: issue) } before do - project.team << [user, :master] + project.add_master(user) end describe "GET /projects/:id/awardable/:awardable_id/award_emoji" do diff --git a/spec/requests/api/boards_spec.rb b/spec/requests/api/boards_spec.rb index 546a1697e56..f65af69dc7f 100644 --- a/spec/requests/api/boards_spec.rb +++ b/spec/requests/api/boards_spec.rb @@ -33,8 +33,8 @@ describe API::Boards do end before do - project.team << [user, :reporter] - project.team << [guest, :guest] + project.add_reporter(user) + project.add_guest(guest) end describe "GET /projects/:id/boards" do diff --git a/spec/requests/api/deployments_spec.rb b/spec/requests/api/deployments_spec.rb index c7977e624ff..6732c99e329 100644 --- a/spec/requests/api/deployments_spec.rb +++ b/spec/requests/api/deployments_spec.rb @@ -7,7 +7,7 @@ describe API::Deployments do let!(:deployment) { create(:deployment) } before do - project.team << [user, :master] + project.add_master(user) end describe 'GET /projects/:id/deployments' do diff --git a/spec/requests/api/environments_spec.rb b/spec/requests/api/environments_spec.rb index 3665cfd7241..53d48a91007 100644 --- a/spec/requests/api/environments_spec.rb +++ b/spec/requests/api/environments_spec.rb @@ -7,7 +7,7 @@ describe API::Environments do let!(:environment) { create(:environment, project: project) } before do - project.team << [user, :master] + project.add_master(user) end describe 'GET /projects/:id/environments' do diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb index 5d8338a3fb7..d8fdfd6dee1 100644 --- a/spec/requests/api/files_spec.rb +++ b/spec/requests/api/files_spec.rb @@ -14,7 +14,7 @@ describe API::Files do let(:author_name) { 'John Doe' } before do - project.team << [user, :developer] + project.add_developer(user) end def route(file_path = nil) diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb index 6330c140246..3c0b4728dc2 100644 --- a/spec/requests/api/groups_spec.rb +++ b/spec/requests/api/groups_spec.rb @@ -417,7 +417,7 @@ describe API::Groups do end it "only returns projects to which user has access" do - project3.team << [user3, :developer] + project3.add_developer(user3) get api("/groups/#{group1.id}/projects", user3) diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb index 3c31980b273..7b25047ea8f 100644 --- a/spec/requests/api/internal_spec.rb +++ b/spec/requests/api/internal_spec.rb @@ -147,7 +147,7 @@ describe API::Internal do describe "POST /internal/lfs_authenticate" do before do - project.team << [user, :developer] + project.add_developer(user) end context 'user key' do @@ -199,7 +199,7 @@ describe API::Internal do end before do - project.team << [user, :developer] + project.add_developer(user) end context 'with env passed as a JSON' do @@ -359,7 +359,7 @@ describe API::Internal do context "access denied" do before do - project.team << [user, :guest] + project.add_guest(user) end context "git pull" do @@ -413,7 +413,7 @@ describe API::Internal do context "archived project" do before do - project.team << [user, :developer] + project.add_developer(user) project.archive! end @@ -527,7 +527,7 @@ describe API::Internal do context 'web actions are always allowed' do it 'allows WEB push' do stub_application_setting(enabled_git_access_protocol: 'ssh') - project.team << [user, :developer] + project.add_developer(user) push(key, project, 'web') expect(response.status).to eq(200) @@ -540,7 +540,7 @@ describe API::Internal do let!(:repository) { project.repository } before do - project.team << [user, :developer] + project.add_developer(user) project.path = 'new_path' project.save! end @@ -566,7 +566,7 @@ describe API::Internal do let(:changes) { URI.escape("#{Gitlab::Git::BLANK_SHA} 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/new_branch") } before do - project.team << [user, :developer] + project.add_developer(user) end it 'returns link to create new merge request' do @@ -701,7 +701,7 @@ describe API::Internal do end before do - project.team << [user, :developer] + project.add_developer(user) allow(described_class).to receive(:identify).and_return(user) allow_any_instance_of(Gitlab::Identifier).to receive(:identify).and_return(user) end @@ -784,6 +784,16 @@ describe API::Internal do expect(json_response["redirected_message"]).to eq(project_moved.redirect_message) end end + + context 'with an orphaned write deploy key' do + it 'does not try to notify that project moved' do + allow_any_instance_of(Gitlab::Identifier).to receive(:identify).and_return(nil) + + post api("/internal/post_receive"), valid_params + + expect(response).to have_gitlab_http_status(200) + end + end end describe 'POST /internal/pre_receive' do diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index 3f5070a1fd2..00d9c795619 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -58,8 +58,8 @@ describe API::Issues, :mailer do let(:no_milestone_title) { URI.escape(Milestone::None.title) } before(:all) do - project.team << [user, :reporter] - project.team << [guest, :guest] + project.add_reporter(user) + project.add_guest(guest) end describe "GET /issues" do @@ -344,7 +344,7 @@ describe API::Issues, :mailer do let!(:group_note) { create(:note_on_issue, author: user, project: group_project, noteable: group_issue) } before do - group_project.team << [user, :reporter] + group_project.add_reporter(user) end let(:base_url) { "/groups/#{group.id}/issues" } @@ -967,7 +967,7 @@ describe API::Issues, :mailer do let(:project) { merge_request.source_project } before do - project.team << [user, :master] + project.add_master(user) end context 'resolving all discussions in a merge request' do diff --git a/spec/requests/api/jobs_spec.rb b/spec/requests/api/jobs_spec.rb index e38cedc7042..805496e4a54 100644 --- a/spec/requests/api/jobs_spec.rb +++ b/spec/requests/api/jobs_spec.rb @@ -503,7 +503,7 @@ describe API::Jobs do let(:role) { :master } before do - project.team << [user, role] + project.add_role(user, role) post api("/projects/#{project.id}/jobs/#{job.id}/erase", user) end diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb index 3498e5bc8d9..34cbf75f4c1 100644 --- a/spec/requests/api/labels_spec.rb +++ b/spec/requests/api/labels_spec.rb @@ -7,7 +7,7 @@ describe API::Labels do let!(:priority_label) { create(:label, title: 'bug', project: project, priority: 3) } before do - project.team << [user, :master] + project.add_master(user) end describe 'GET /projects/:id/labels' do diff --git a/spec/requests/api/members_spec.rb b/spec/requests/api/members_spec.rb index 3349e396ab8..5d4f81e07a6 100644 --- a/spec/requests/api/members_spec.rb +++ b/spec/requests/api/members_spec.rb @@ -8,8 +8,8 @@ describe API::Members do let(:project) do create(:project, :public, :access_requestable, creator_id: master.id, namespace: master.namespace) do |project| - project.team << [developer, :developer] - project.team << [master, :master] + project.add_developer(developer) + project.add_master(master) project.request_access(access_requester) end end diff --git a/spec/requests/api/merge_request_diffs_spec.rb b/spec/requests/api/merge_request_diffs_spec.rb index bf4c8443b23..cb647aee70f 100644 --- a/spec/requests/api/merge_request_diffs_spec.rb +++ b/spec/requests/api/merge_request_diffs_spec.rb @@ -8,7 +8,7 @@ describe API::MergeRequestDiffs, 'MergeRequestDiffs' do before do merge_request.merge_request_diffs.create(head_commit_sha: '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9') merge_request.merge_request_diffs.create(head_commit_sha: '5937ac0a7beb003549fc5fd26fc247adbce4a52e') - project.team << [user, :master] + project.add_master(user) end describe 'GET /projects/:id/merge_requests/:merge_request_iid/versions' do diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index 60dbd74d59d..ef3f610740d 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -25,7 +25,7 @@ describe API::MergeRequests do let!(:upvote) { create(:award_emoji, :upvote, awardable: merge_request) } before do - project.team << [user, :reporter] + project.add_reporter(user) end describe 'GET /merge_requests' do @@ -730,7 +730,7 @@ describe API::MergeRequests do let(:developer) { create(:user) } before do - project.team << [developer, :developer] + project.add_developer(developer) end it "denies the deletion of the merge request" do @@ -808,7 +808,7 @@ describe API::MergeRequests do it "returns 401 if user has no permissions to merge" do user2 = create(:user) - project.team << [user2, :reporter] + project.add_reporter(user2) put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user2) expect(response).to have_gitlab_http_status(401) expect(json_response['message']).to eq('401 Unauthorized') @@ -997,7 +997,7 @@ describe API::MergeRequests do project = create(:project, :private) merge_request = create(:merge_request, :simple, source_project: project) guest = create(:user) - project.team << [guest, :guest] + project.add_guest(guest) get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/closes_issues", guest) @@ -1045,7 +1045,7 @@ describe API::MergeRequests do it 'returns 403 if user has no access to read code' do guest = create(:user) - project.team << [guest, :guest] + project.add_guest(guest) post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/subscribe", guest) @@ -1081,7 +1081,7 @@ describe API::MergeRequests do it 'returns 403 if user has no access to read code' do guest = create(:user) - project.team << [guest, :guest] + project.add_guest(guest) post api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/unsubscribe", guest) diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb index 3bfb4c5506f..981c9c27325 100644 --- a/spec/requests/api/notes_spec.rb +++ b/spec/requests/api/notes_spec.rb @@ -14,7 +14,7 @@ describe API::Notes do let(:private_user) { create(:user) } let(:private_project) do create(:project, namespace: private_user.namespace) - .tap { |p| p.team << [private_user, :master] } + .tap { |p| p.add_master(private_user) } end let(:private_issue) { create(:issue, project: private_project) } @@ -29,7 +29,7 @@ describe API::Notes do end before do - project.team << [user, :reporter] + project.add_reporter(user) end describe "GET /projects/:id/noteable/:noteable_id/notes" do @@ -464,7 +464,7 @@ describe API::Notes do describe "POST /projects/:id/noteable/:noteable_id/notes to test observer on create" do it "creates an activity event when an issue note is created" do - expect(Event).to receive(:create) + expect(Event).to receive(:create!) post api("/projects/#{project.id}/issues/#{issue.iid}/notes", user), body: 'hi!' end diff --git a/spec/requests/api/pipelines_spec.rb b/spec/requests/api/pipelines_spec.rb index e4dcc9252fa..0736329f9fd 100644 --- a/spec/requests/api/pipelines_spec.rb +++ b/spec/requests/api/pipelines_spec.rb @@ -11,7 +11,7 @@ describe API::Pipelines do end before do - project.team << [user, :master] + project.add_master(user) end describe 'GET /projects/:id/pipelines ' do @@ -424,7 +424,7 @@ describe API::Pipelines do let!(:reporter) { create(:user) } before do - project.team << [reporter, :reporter] + project.add_reporter(reporter) end it 'rejects the action' do diff --git a/spec/requests/api/project_hooks_spec.rb b/spec/requests/api/project_hooks_spec.rb index f31344a6238..1fd082ecc38 100644 --- a/spec/requests/api/project_hooks_spec.rb +++ b/spec/requests/api/project_hooks_spec.rb @@ -13,8 +13,8 @@ describe API::ProjectHooks, 'ProjectHooks' do end before do - project.team << [user, :master] - project.team << [user3, :developer] + project.add_master(user) + project.add_developer(user3) end describe "GET /projects/:id/hooks" do @@ -206,7 +206,7 @@ describe API::ProjectHooks, 'ProjectHooks' do it "returns a 404 if a user attempts to delete project hooks he/she does not own" do test_user = create(:user) other_project = create(:project) - other_project.team << [test_user, :master] + other_project.add_master(test_user) delete api("/projects/#{other_project.id}/hooks/#{hook.id}", test_user) expect(response).to have_gitlab_http_status(404) diff --git a/spec/requests/api/project_milestones_spec.rb b/spec/requests/api/project_milestones_spec.rb index 72e1574b55f..08ea7314bb3 100644 --- a/spec/requests/api/project_milestones_spec.rb +++ b/spec/requests/api/project_milestones_spec.rb @@ -7,7 +7,7 @@ describe API::ProjectMilestones do let!(:milestone) { create(:milestone, project: project, title: 'version2', description: 'open milestone') } before do - project.team << [user, :developer] + project.add_developer(user) end it_behaves_like 'group and project milestones', "/projects/:id/milestones" do @@ -16,7 +16,7 @@ describe API::ProjectMilestones do describe 'PUT /projects/:id/milestones/:milestone_id to test observer on close' do it 'creates an activity event when an milestone is closed' do - expect(Event).to receive(:create) + expect(Event).to receive(:create!) put api("/projects/#{project.id}/milestones/#{milestone.id}", user), state_event: 'close' diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index a41345da05b..de1763015fa 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -908,7 +908,7 @@ describe API::Projects do describe 'permissions' do context 'all projects' do before do - project.team << [user, :master] + project.add_master(user) end it 'contains permission information' do @@ -923,7 +923,7 @@ describe API::Projects do context 'personal project' do it 'sets project access and returns 200' do - project.team << [user, :master] + project.add_master(user) get api("/projects/#{project.id}", user) expect(response).to have_gitlab_http_status(200) @@ -1539,7 +1539,7 @@ describe API::Projects do context 'user without archiving rights to the project' do before do - project.team << [user3, :developer] + project.add_developer(user3) end it 'rejects the action' do @@ -1575,7 +1575,7 @@ describe API::Projects do context 'user without archiving rights to the project' do before do - project.team << [user3, :developer] + project.add_developer(user3) end it 'rejects the action' do @@ -1650,7 +1650,7 @@ describe API::Projects do it 'does not remove a project if not an owner' do user3 = create(:user) - project.team << [user3, :developer] + project.add_developer(user3) delete api("/projects/#{project.id}", user3) expect(response).to have_gitlab_http_status(403) end diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb index ba697e2b305..26d56c04862 100644 --- a/spec/requests/api/services_spec.rb +++ b/spec/requests/api/services_spec.rb @@ -53,6 +53,10 @@ describe API::Services do describe "DELETE /projects/:id/services/#{service.dasherize}" do include_context service + before do + initialize_service(service) + end + it "deletes #{service}" do delete api("/projects/#{project.id}/services/#{dashed_service}", user) @@ -67,9 +71,7 @@ describe API::Services do # inject some properties into the service before do - service_object = project.find_or_initialize_service(service) - service_object.properties = service_attrs - service_object.save + initialize_service(service) end it 'returns authentication error when unauthenticated' do @@ -92,7 +94,7 @@ describe API::Services do end it "returns error when authenticated but not a project owner" do - project.team << [user2, :developer] + project.add_developer(user2) get api("/projects/#{project.id}/services/#{dashed_service}", user2) expect(response).to have_gitlab_http_status(403) diff --git a/spec/requests/api/todos_spec.rb b/spec/requests/api/todos_spec.rb index c6063a2e089..fb3a33cadff 100644 --- a/spec/requests/api/todos_spec.rb +++ b/spec/requests/api/todos_spec.rb @@ -13,8 +13,8 @@ describe API::Todos do let!(:done) { create(:todo, :done, project: project_1, author: author_1, user: john_doe) } before do - project_1.team << [john_doe, :developer] - project_2.team << [john_doe, :developer] + project_1.add_developer(john_doe) + project_2.add_developer(john_doe) end describe 'GET /todos' do @@ -191,7 +191,7 @@ describe API::Todos do it 'returns an error if the issuable is not accessible' do guest = create(:user) - project_1.team << [guest, :guest] + project_1.add_guest(guest) post api("/projects/#{project_1.id}/#{issuable_type}/#{issuable.iid}/todo", guest) diff --git a/spec/requests/api/v3/award_emoji_spec.rb b/spec/requests/api/v3/award_emoji_spec.rb index 0cd8b70007f..6dc430676b0 100644 --- a/spec/requests/api/v3/award_emoji_spec.rb +++ b/spec/requests/api/v3/award_emoji_spec.rb @@ -9,7 +9,7 @@ describe API::V3::AwardEmoji do let!(:downvote) { create(:award_emoji, :downvote, awardable: merge_request, user: user) } set(:note) { create(:note, project: project, noteable: issue) } - before { project.team << [user, :master] } + before { project.add_master(user) } describe "GET /projects/:id/awardable/:awardable_id/award_emoji" do context 'on an issue' do diff --git a/spec/requests/api/v3/boards_spec.rb b/spec/requests/api/v3/boards_spec.rb index 14409d25544..dde4f096193 100644 --- a/spec/requests/api/v3/boards_spec.rb +++ b/spec/requests/api/v3/boards_spec.rb @@ -27,8 +27,8 @@ describe API::V3::Boards do end before do - project.team << [user, :reporter] - project.team << [guest, :guest] + project.add_reporter(user) + project.add_guest(guest) end describe "GET /projects/:id/boards" do diff --git a/spec/requests/api/v3/commits_spec.rb b/spec/requests/api/v3/commits_spec.rb index d31c94ddd2c..8b115e01f47 100644 --- a/spec/requests/api/v3/commits_spec.rb +++ b/spec/requests/api/v3/commits_spec.rb @@ -9,11 +9,11 @@ describe API::V3::Commits do let!(:note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'a comment on a commit') } let!(:another_note) { create(:note_on_commit, author: user, project: project, commit_id: project.repository.commit.id, note: 'another comment on a commit') } - before { project.team << [user, :reporter] } + before { project.add_reporter(user) } describe "List repository commits" do context "authorized user" do - before { project.team << [user2, :reporter] } + before { project.add_reporter(user2) } it "returns project commits" do commit = project.repository.commit @@ -415,7 +415,7 @@ describe API::V3::Commits do describe "Get the diff of a commit" do context "authorized user" do - before { project.team << [user2, :reporter] } + before { project.add_reporter(user2) } it "returns the diff of the selected commit" do get v3_api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}/diff", user) @@ -487,7 +487,7 @@ describe API::V3::Commits do end it 'returns 400 if you are not allowed to push to the target branch' do - project.team << [user2, :developer] + project.add_developer(user2) protected_branch = create(:protected_branch, project: project, name: 'feature') post v3_api("/projects/#{project.id}/repository/commits/#{master_pickable_commit.id}/cherry_pick", user2), branch: protected_branch.name diff --git a/spec/requests/api/v3/deployments_spec.rb b/spec/requests/api/v3/deployments_spec.rb index 90eabda4dac..ac86fbea498 100644 --- a/spec/requests/api/v3/deployments_spec.rb +++ b/spec/requests/api/v3/deployments_spec.rb @@ -7,7 +7,7 @@ describe API::V3::Deployments do let!(:deployment) { create(:deployment) } before do - project.team << [user, :master] + project.add_master(user) end shared_examples 'a paginated resources' do diff --git a/spec/requests/api/v3/environments_spec.rb b/spec/requests/api/v3/environments_spec.rb index 937250b5219..68be5256b64 100644 --- a/spec/requests/api/v3/environments_spec.rb +++ b/spec/requests/api/v3/environments_spec.rb @@ -7,7 +7,7 @@ describe API::V3::Environments do let!(:environment) { create(:environment, project: project) } before do - project.team << [user, :master] + project.add_master(user) end shared_examples 'a paginated resources' do diff --git a/spec/requests/api/v3/files_spec.rb b/spec/requests/api/v3/files_spec.rb index 5500c1cf770..26a3d8870a0 100644 --- a/spec/requests/api/v3/files_spec.rb +++ b/spec/requests/api/v3/files_spec.rb @@ -27,7 +27,7 @@ describe API::V3::Files do let(:author_email) { 'user@example.org' } let(:author_name) { 'John Doe' } - before { project.team << [user, :developer] } + before { project.add_developer(user) } describe "GET /projects/:id/repository/files" do let(:route) { "/projects/#{project.id}/repository/files" } diff --git a/spec/requests/api/v3/groups_spec.rb b/spec/requests/api/v3/groups_spec.rb index 498cb42fad1..a1cdf583de3 100644 --- a/spec/requests/api/v3/groups_spec.rb +++ b/spec/requests/api/v3/groups_spec.rb @@ -330,7 +330,7 @@ describe API::V3::Groups do end it "only returns projects to which user has access" do - project3.team << [user3, :developer] + project3.add_developer(user3) get v3_api("/groups/#{group1.id}/projects", user3) diff --git a/spec/requests/api/v3/issues_spec.rb b/spec/requests/api/v3/issues_spec.rb index 39a47a62f16..0dd6d673625 100644 --- a/spec/requests/api/v3/issues_spec.rb +++ b/spec/requests/api/v3/issues_spec.rb @@ -50,8 +50,8 @@ describe API::V3::Issues, :mailer do let(:no_milestone_title) { URI.escape(Milestone::None.title) } before do - project.team << [user, :reporter] - project.team << [guest, :guest] + project.add_reporter(user) + project.add_guest(guest) end describe "GET /issues" do @@ -278,7 +278,7 @@ describe API::V3::Issues, :mailer do let!(:group_note) { create(:note_on_issue, author: user, project: group_project, noteable: group_issue) } before do - group_project.team << [user, :reporter] + group_project.add_reporter(user) end let(:base_url) { "/groups/#{group.id}/issues" } @@ -827,7 +827,7 @@ describe API::V3::Issues, :mailer do let(:merge_request) { discussion.noteable } let(:project) { merge_request.source_project } before do - project.team << [user, :master] + project.add_master(user) post v3_api("/projects/#{project.id}/issues", user), title: 'New Issue', merge_request_for_resolving_discussions: merge_request.iid diff --git a/spec/requests/api/v3/labels_spec.rb b/spec/requests/api/v3/labels_spec.rb index 1d31213d5ca..cdab4d2bd73 100644 --- a/spec/requests/api/v3/labels_spec.rb +++ b/spec/requests/api/v3/labels_spec.rb @@ -7,7 +7,7 @@ describe API::V3::Labels do let!(:priority_label) { create(:label, title: 'bug', project: project, priority: 3) } before do - project.team << [user, :master] + project.add_master(user) end describe 'GET /projects/:id/labels' do diff --git a/spec/requests/api/v3/members_spec.rb b/spec/requests/api/v3/members_spec.rb index 68be3d24c26..b91782ae511 100644 --- a/spec/requests/api/v3/members_spec.rb +++ b/spec/requests/api/v3/members_spec.rb @@ -8,8 +8,8 @@ describe API::V3::Members do let(:project) do create(:project, :public, :access_requestable, creator_id: master.id, namespace: master.namespace) do |project| - project.team << [developer, :developer] - project.team << [master, :master] + project.add_developer(developer) + project.add_master(master) project.request_access(access_requester) end end diff --git a/spec/requests/api/v3/merge_request_diffs_spec.rb b/spec/requests/api/v3/merge_request_diffs_spec.rb index e613036a88d..547c066fadc 100644 --- a/spec/requests/api/v3/merge_request_diffs_spec.rb +++ b/spec/requests/api/v3/merge_request_diffs_spec.rb @@ -8,7 +8,7 @@ describe API::V3::MergeRequestDiffs, 'MergeRequestDiffs' do before do merge_request.merge_request_diffs.create(head_commit_sha: '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9') merge_request.merge_request_diffs.create(head_commit_sha: '5937ac0a7beb003549fc5fd26fc247adbce4a52e') - project.team << [user, :master] + project.add_master(user) end describe 'GET /projects/:id/merge_requests/:merge_request_id/versions' do diff --git a/spec/requests/api/v3/merge_requests_spec.rb b/spec/requests/api/v3/merge_requests_spec.rb index 2e2b9449429..b8b7d9d1c40 100644 --- a/spec/requests/api/v3/merge_requests_spec.rb +++ b/spec/requests/api/v3/merge_requests_spec.rb @@ -14,7 +14,7 @@ describe API::MergeRequests do let(:milestone) { create(:milestone, title: '1.0.0', project: project) } before do - project.team << [user, :reporter] + project.add_reporter(user) end describe "GET /projects/:id/merge_requests" do @@ -396,7 +396,7 @@ describe API::MergeRequests do let(:developer) { create(:user) } before do - project.team << [developer, :developer] + project.add_developer(developer) end it "denies the deletion of the merge request" do @@ -458,7 +458,7 @@ describe API::MergeRequests do it "returns 401 if user has no permissions to merge" do user2 = create(:user) - project.team << [user2, :reporter] + project.add_reporter(user2) put v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user2) expect(response).to have_gitlab_http_status(401) expect(json_response['message']).to eq('401 Unauthorized') @@ -645,7 +645,7 @@ describe API::MergeRequests do project = create(:project, :private, :repository) merge_request = create(:merge_request, :simple, source_project: project) guest = create(:user) - project.team << [guest, :guest] + project.add_guest(guest) get v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/closes_issues", guest) @@ -675,7 +675,7 @@ describe API::MergeRequests do it 'returns 403 if user has no access to read code' do guest = create(:user) - project.team << [guest, :guest] + project.add_guest(guest) post v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", guest) @@ -705,7 +705,7 @@ describe API::MergeRequests do it 'returns 403 if user has no access to read code' do guest = create(:user) - project.team << [guest, :guest] + project.add_guest(guest) delete v3_api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", guest) diff --git a/spec/requests/api/v3/milestones_spec.rb b/spec/requests/api/v3/milestones_spec.rb index e82f35598a6..6021600e09c 100644 --- a/spec/requests/api/v3/milestones_spec.rb +++ b/spec/requests/api/v3/milestones_spec.rb @@ -6,7 +6,7 @@ describe API::V3::Milestones do let!(:closed_milestone) { create(:closed_milestone, project: project) } let!(:milestone) { create(:milestone, project: project) } - before { project.team << [user, :developer] } + before { project.add_developer(user) } describe 'GET /projects/:id/milestones' do it 'returns project milestones' do @@ -161,7 +161,7 @@ describe API::V3::Milestones do describe 'PUT /projects/:id/milestones/:milestone_id to test observer on close' do it 'creates an activity event when an milestone is closed' do - expect(Event).to receive(:create) + expect(Event).to receive(:create!) put v3_api("/projects/#{project.id}/milestones/#{milestone.id}", user), state_event: 'close' @@ -200,7 +200,7 @@ describe API::V3::Milestones do let(:confidential_issue) { create(:issue, confidential: true, project: public_project) } before do - public_project.team << [user, :developer] + public_project.add_developer(user) milestone.issues << issue << confidential_issue end @@ -215,7 +215,7 @@ describe API::V3::Milestones do it 'does not return confidential issues to team members with guest role' do member = create(:user) - project.team << [member, :guest] + project.add_guest(member) get v3_api("/projects/#{public_project.id}/milestones/#{milestone.id}/issues", member) diff --git a/spec/requests/api/v3/notes_spec.rb b/spec/requests/api/v3/notes_spec.rb index d3455a4bba4..5532795ab02 100644 --- a/spec/requests/api/v3/notes_spec.rb +++ b/spec/requests/api/v3/notes_spec.rb @@ -14,7 +14,7 @@ describe API::V3::Notes do let(:private_user) { create(:user) } let(:private_project) do create(:project, namespace: private_user.namespace) - .tap { |p| p.team << [private_user, :master] } + .tap { |p| p.add_master(private_user) } end let(:private_issue) { create(:issue, project: private_project) } @@ -28,7 +28,7 @@ describe API::V3::Notes do system: true end - before { project.team << [user, :reporter] } + before { project.add_reporter(user) } describe "GET /projects/:id/noteable/:noteable_id/notes" do context "when noteable is an Issue" do @@ -302,7 +302,7 @@ describe API::V3::Notes do describe "POST /projects/:id/noteable/:noteable_id/notes to test observer on create" do it "creates an activity event when an issue note is created" do - expect(Event).to receive(:create) + expect(Event).to receive(:create!) post v3_api("/projects/#{project.id}/issues/#{issue.id}/notes", user), body: 'hi!' end diff --git a/spec/requests/api/v3/pipelines_spec.rb b/spec/requests/api/v3/pipelines_spec.rb index 1c7d9fe32bb..ea943f22c41 100644 --- a/spec/requests/api/v3/pipelines_spec.rb +++ b/spec/requests/api/v3/pipelines_spec.rb @@ -10,7 +10,7 @@ describe API::V3::Pipelines do ref: project.default_branch) end - before { project.team << [user, :master] } + before { project.add_master(user) } shared_examples 'a paginated resources' do before do @@ -188,7 +188,7 @@ describe API::V3::Pipelines do context 'user without proper access rights' do let!(:reporter) { create(:user) } - before { project.team << [reporter, :reporter] } + before { project.add_reporter(reporter) } it 'rejects the action' do post v3_api("/projects/#{project.id}/pipelines/#{pipeline.id}/cancel", reporter) diff --git a/spec/requests/api/v3/project_hooks_spec.rb b/spec/requests/api/v3/project_hooks_spec.rb index 00f59744a31..248ae97f875 100644 --- a/spec/requests/api/v3/project_hooks_spec.rb +++ b/spec/requests/api/v3/project_hooks_spec.rb @@ -13,8 +13,8 @@ describe API::ProjectHooks, 'ProjectHooks' do end before do - project.team << [user, :master] - project.team << [user3, :developer] + project.add_master(user) + project.add_developer(user3) end describe "GET /projects/:id/hooks" do @@ -205,7 +205,7 @@ describe API::ProjectHooks, 'ProjectHooks' do it "returns a 404 if a user attempts to delete project hooks he/she does not own" do test_user = create(:user) other_project = create(:project) - other_project.team << [test_user, :master] + other_project.add_master(test_user) delete v3_api("/projects/#{other_project.id}/hooks/#{hook.id}", test_user) expect(response).to have_gitlab_http_status(404) diff --git a/spec/requests/api/v3/projects_spec.rb b/spec/requests/api/v3/projects_spec.rb index 27288b98d1c..13e465e0b2d 100644 --- a/spec/requests/api/v3/projects_spec.rb +++ b/spec/requests/api/v3/projects_spec.rb @@ -753,7 +753,7 @@ describe API::V3::Projects do describe 'permissions' do context 'all projects' do - before { project.team << [user, :master] } + before { project.add_master(user) } it 'contains permission information' do get v3_api("/projects", user) @@ -767,7 +767,7 @@ describe API::V3::Projects do context 'personal project' do it 'sets project access and returns 200' do - project.team << [user, :master] + project.add_master(user) get v3_api("/projects/#{project.id}", user) expect(response).to have_gitlab_http_status(200) @@ -1362,7 +1362,7 @@ describe API::V3::Projects do context 'user without archiving rights to the project' do before do - project.team << [user3, :developer] + project.add_developer(user3) end it 'rejects the action' do @@ -1398,7 +1398,7 @@ describe API::V3::Projects do context 'user without archiving rights to the project' do before do - project.team << [user3, :developer] + project.add_developer(user3) end it 'rejects the action' do @@ -1466,7 +1466,7 @@ describe API::V3::Projects do it 'does not remove a project if not an owner' do user3 = create(:user) - project.team << [user3, :developer] + project.add_developer(user3) delete v3_api("/projects/#{project.id}", user3) expect(response).to have_gitlab_http_status(403) end diff --git a/spec/requests/api/v3/services_spec.rb b/spec/requests/api/v3/services_spec.rb index 8f212ab6be6..c69a7d58ca6 100644 --- a/spec/requests/api/v3/services_spec.rb +++ b/spec/requests/api/v3/services_spec.rb @@ -10,6 +10,10 @@ describe API::V3::Services do describe "DELETE /projects/:id/services/#{service.dasherize}" do include_context service + before do + initialize_service(service) + end + it "deletes #{service}" do delete v3_api("/projects/#{project.id}/services/#{dashed_service}", user) diff --git a/spec/requests/api/v3/todos_spec.rb b/spec/requests/api/v3/todos_spec.rb index 8f5c3fbf8dd..53fd962272a 100644 --- a/spec/requests/api/v3/todos_spec.rb +++ b/spec/requests/api/v3/todos_spec.rb @@ -12,8 +12,8 @@ describe API::V3::Todos do let!(:done) { create(:todo, :done, project: project_1, author: author_1, user: john_doe) } before do - project_1.team << [john_doe, :developer] - project_2.team << [john_doe, :developer] + project_1.add_developer(john_doe) + project_2.add_developer(john_doe) end describe 'DELETE /todos/:id' do diff --git a/spec/requests/api/wikis_spec.rb b/spec/requests/api/wikis_spec.rb index 65bd001e491..fb0806ff9f1 100644 --- a/spec/requests/api/wikis_spec.rb +++ b/spec/requests/api/wikis_spec.rb @@ -12,6 +12,8 @@ require 'spec_helper' describe API::Wikis do let(:user) { create(:user) } + let(:group) { create(:group).tap { |g| g.add_owner(user) } } + let(:project_wiki) { create(:project_wiki, project: project, user: user) } let(:payload) { { content: 'content', format: 'rdoc', title: 'title' } } let(:expected_keys_with_content) { %w(content format slug title) } let(:expected_keys_without_content) { %w(format slug title) } @@ -19,8 +21,8 @@ describe API::Wikis do shared_examples_for 'returns list of wiki pages' do context 'when wiki has pages' do let!(:pages) do - [create(:wiki_page, wiki: project.wiki, attrs: { title: 'page1', content: 'content of page1' }), - create(:wiki_page, wiki: project.wiki, attrs: { title: 'page2', content: 'content of page2' })] + [create(:wiki_page, wiki: project_wiki, attrs: { title: 'page1', content: 'content of page1' }), + create(:wiki_page, wiki: project_wiki, attrs: { title: 'page2', content: 'content of page2' })] end it 'returns the list of wiki pages without content' do @@ -445,7 +447,7 @@ describe API::Wikis do end describe 'PUT /projects/:id/wikis/:slug' do - let(:page) { create(:wiki_page, wiki: project.wiki) } + let(:page) { create(:wiki_page, wiki: project_wiki) } let(:payload) { { title: 'new title', content: 'new content' } } let(:url) { "/projects/#{project.id}/wikis/#{page.slug}" } @@ -568,10 +570,20 @@ describe API::Wikis do end end end + + context 'when wiki belongs to a group project' do + let(:project) { create(:project, namespace: group) } + + before do + put(api(url, user), payload) + end + + include_examples 'updates wiki page' + end end describe 'DELETE /projects/:id/wikis/:slug' do - let(:page) { create(:wiki_page, wiki: project.wiki) } + let(:page) { create(:wiki_page, wiki: project_wiki) } let(:url) { "/projects/#{project.id}/wikis/#{page.slug}" } context 'when wiki is disabled' do @@ -675,5 +687,15 @@ describe API::Wikis do end end end + + context 'when wiki belongs to a group project' do + let(:project) { create(:project, namespace: group) } + + before do + delete(api(url, user)) + end + + include_examples '204 No Content' + end end end diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb index fa02fffc82a..27bd22d6bca 100644 --- a/spec/requests/git_http_spec.rb +++ b/spec/requests/git_http_spec.rb @@ -149,7 +149,7 @@ describe 'Git HTTP requests' do context 'and as a developer on the team' do before do - project.team << [user, :developer] + project.add_developer(user) end context 'but the repo is disabled' do @@ -182,7 +182,7 @@ describe 'Git HTTP requests' do context 'when authenticated' do context 'and as a developer on the team' do before do - project.team << [user, :developer] + project.add_developer(user) end context 'but the repo is disabled' do @@ -240,7 +240,7 @@ describe 'Git HTTP requests' do context 'as a developer on the team' do before do - project.team << [user, :developer] + project.add_developer(user) end it_behaves_like 'pulls are allowed' @@ -365,13 +365,13 @@ describe 'Git HTTP requests' do context "when the user has access to the project" do before do - project.team << [user, :master] + project.add_master(user) end context "when the user is blocked" do it "rejects pulls with 401 Unauthorized" do user.block - project.team << [user, :master] + project.add_master(user) download(path, env) do |response| expect(response).to have_gitlab_http_status(:unauthorized) @@ -434,7 +434,7 @@ describe 'Git HTTP requests' do let(:path) { "#{project.full_path}.git" } before do - project.team << [user, :master] + project.add_master(user) end context 'when username and password are provided' do @@ -612,7 +612,7 @@ describe 'Git HTTP requests' do context 'and build created by' do before do build.update(user: user) - project.team << [user, :reporter] + project.add_reporter(user) end shared_examples 'can download code only' do @@ -795,7 +795,7 @@ describe 'Git HTTP requests' do context 'and the user is on the team' do before do - project.team << [user, :master] + project.add_master(user) end it "responds with status 200" do diff --git a/spec/requests/lfs_http_spec.rb b/spec/requests/lfs_http_spec.rb index c597623bc4d..5e59bb0d585 100644 --- a/spec/requests/lfs_http_spec.rb +++ b/spec/requests/lfs_http_spec.rb @@ -63,7 +63,7 @@ describe 'Git LFS API and storage' do context 'with LFS disabled globally' do before do - project.team << [user, :master] + project.add_master(user) allow(Gitlab.config.lfs).to receive(:enabled).and_return(false) end @@ -106,7 +106,7 @@ describe 'Git LFS API and storage' do context 'with LFS enabled globally' do before do - project.team << [user, :master] + project.add_master(user) enable_lfs end @@ -234,7 +234,7 @@ describe 'Git LFS API and storage' do context 'and does have project access' do let(:update_permissions) do - project.team << [user, :master] + project.add_master(user) project.lfs_objects << lfs_object end @@ -259,7 +259,7 @@ describe 'Git LFS API and storage' do context 'when user allowed' do let(:update_permissions) do - project.team << [user, :master] + project.add_master(user) project.lfs_objects << lfs_object end @@ -295,7 +295,7 @@ describe 'Git LFS API and storage' do let(:pipeline) { create(:ci_empty_pipeline, project: project) } let(:update_permissions) do - project.team << [user, :reporter] + project.add_reporter(user) project.lfs_objects << lfs_object end @@ -517,7 +517,7 @@ describe 'Git LFS API and storage' do let(:authorization) { authorize_user } let(:update_user_permissions) do - project.team << [user, role] + project.add_role(user, role) end it_behaves_like 'an authorized requests' do @@ -553,7 +553,7 @@ describe 'Git LFS API and storage' do let(:pipeline) { create(:ci_empty_pipeline, project: project) } let(:update_user_permissions) do - project.team << [user, :reporter] + project.add_reporter(user) end it_behaves_like 'an authorized requests' @@ -673,7 +673,7 @@ describe 'Git LFS API and storage' do let(:authorization) { authorize_user } let(:update_user_permissions) do - project.team << [user, :developer] + project.add_developer(user) end context 'when pushing an lfs object that already exists' do @@ -795,7 +795,7 @@ describe 'Git LFS API and storage' do context 'when user is not authenticated' do context 'when user has push access' do let(:update_user_permissions) do - project.team << [user, :master] + project.add_master(user) end it 'responds with status 401' do @@ -840,7 +840,7 @@ describe 'Git LFS API and storage' do before do allow(Gitlab::Database).to receive(:read_only?) { true } - project.team << [user, :master] + project.add_master(user) enable_lfs end @@ -935,7 +935,7 @@ describe 'Git LFS API and storage' do describe 'when user has push access to the project' do before do - project.team << [user, :developer] + project.add_developer(user) end context 'and the request bypassed workhorse' do @@ -993,7 +993,7 @@ describe 'Git LFS API and storage' do describe 'and user does not have push access' do before do - project.team << [user, :reporter] + project.add_reporter(user) end it_behaves_like 'forbidden' @@ -1010,7 +1010,7 @@ describe 'Git LFS API and storage' do let(:build) { create(:ci_build, :running, pipeline: pipeline, user: user) } before do - project.team << [user, :developer] + project.add_developer(user) put_authorize end @@ -1062,7 +1062,7 @@ describe 'Git LFS API and storage' do describe 'when user has push access to the project' do before do - project.team << [user, :developer] + project.add_developer(user) end context 'and request is sent by gitlab-workhorse to authorize the request' do @@ -1149,7 +1149,7 @@ describe 'Git LFS API and storage' do let(:authorization) { authorize_user } before do - second_project.team << [user, :master] + second_project.add_master(user) upstream_project.lfs_objects << lfs_object end diff --git a/spec/requests/projects/cycle_analytics_events_spec.rb b/spec/requests/projects/cycle_analytics_events_spec.rb index 286d8a884a4..98f70e2101b 100644 --- a/spec/requests/projects/cycle_analytics_events_spec.rb +++ b/spec/requests/projects/cycle_analytics_events_spec.rb @@ -7,7 +7,7 @@ describe 'cycle analytics events' do describe 'GET /:namespace/:project/cycle_analytics/events/issues' do before do - project.team << [user, :developer] + project.add_developer(user) 3.times do |count| Timecop.freeze(Time.now + count.days) do diff --git a/spec/serializers/event_entity_spec.rb b/spec/serializers/event_entity_spec.rb deleted file mode 100644 index bb54597c967..00000000000 --- a/spec/serializers/event_entity_spec.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'spec_helper' - -describe EventEntity do - subject { described_class.represent(create(:event)).as_json } - - it 'exposes author' do - expect(subject).to include(:author) - end - - it 'exposes core elements of event' do - expect(subject).to include(:updated_at) - end -end diff --git a/spec/serializers/merge_request_widget_entity_spec.rb b/spec/serializers/merge_request_widget_entity_spec.rb index a5924a8589c..e25552eb0d8 100644 --- a/spec/serializers/merge_request_widget_entity_spec.rb +++ b/spec/serializers/merge_request_widget_entity_spec.rb @@ -35,6 +35,81 @@ describe MergeRequestWidgetEntity do end end + describe 'metrics' do + context 'when metrics record exists with merged data' do + before do + resource.mark_as_merged! + resource.metrics.update!(merged_by: user) + end + + it 'matches merge request metrics schema' do + expect(subject[:metrics].with_indifferent_access) + .to match_schema('entities/merge_request_metrics') + end + + it 'returns values from metrics record' do + expect(subject.dig(:metrics, :merged_by, :id)) + .to eq(resource.metrics.merged_by_id) + end + end + + context 'when metrics record exists with closed data' do + before do + resource.close! + resource.metrics.update!(latest_closed_by: user) + end + + it 'matches merge request metrics schema' do + expect(subject[:metrics].with_indifferent_access) + .to match_schema('entities/merge_request_metrics') + end + + it 'returns values from metrics record' do + expect(subject.dig(:metrics, :closed_by, :id)) + .to eq(resource.metrics.latest_closed_by_id) + end + end + + context 'when metrics does not exists' do + before do + resource.mark_as_merged! + resource.metrics.destroy! + resource.reload + end + + context 'when events exists' do + let!(:closed_event) { create(:event, :closed, project: project, target: resource) } + let!(:merge_event) { create(:event, :merged, project: project, target: resource) } + + it 'matches merge request metrics schema' do + expect(subject[:metrics].with_indifferent_access) + .to match_schema('entities/merge_request_metrics') + end + + it 'returns values from events record' do + expect(subject.dig(:metrics, :merged_by, :id)) + .to eq(merge_event.author_id) + + expect(subject.dig(:metrics, :closed_by, :id)) + .to eq(closed_event.author_id) + + expect(subject.dig(:metrics, :merged_at).to_s) + .to eq(merge_event.updated_at.to_s) + + expect(subject.dig(:metrics, :closed_at).to_s) + .to eq(closed_event.updated_at.to_s) + end + end + + context 'when events does not exists' do + it 'matches merge request metrics schema' do + expect(subject[:metrics].with_indifferent_access) + .to match_schema('entities/merge_request_metrics') + end + end + end + end + it 'has email_patches_path' do expect(subject[:email_patches_path]) .to eq("/#{resource.project.full_path}/merge_requests/#{resource.iid}.patch") diff --git a/spec/services/boards/issues/create_service_spec.rb b/spec/services/boards/issues/create_service_spec.rb index 1a56164dba4..f0179e35652 100644 --- a/spec/services/boards/issues/create_service_spec.rb +++ b/spec/services/boards/issues/create_service_spec.rb @@ -11,7 +11,7 @@ describe Boards::Issues::CreateService do subject(:service) { described_class.new(board.parent, project, user, board_id: board.id, list_id: list.id, title: 'New issue') } before do - project.team << [user, :developer] + project.add_developer(user) end it 'delegates the create proceedings to Issues::CreateService' do diff --git a/spec/services/boards/issues/list_service_spec.rb b/spec/services/boards/issues/list_service_spec.rb index 01ee3856c99..ff5733b7064 100644 --- a/spec/services/boards/issues/list_service_spec.rb +++ b/spec/services/boards/issues/list_service_spec.rb @@ -34,7 +34,7 @@ describe Boards::Issues::ListService do let!(:closed_issue5) { create(:labeled_issue, :closed, project: project, labels: [development]) } before do - project.team << [user, :developer] + project.add_developer(user) end it 'delegates search to IssuesFinder' do diff --git a/spec/services/boards/issues/move_service_spec.rb b/spec/services/boards/issues/move_service_spec.rb index 464ff9f94b3..280e411683e 100644 --- a/spec/services/boards/issues/move_service_spec.rb +++ b/spec/services/boards/issues/move_service_spec.rb @@ -15,7 +15,7 @@ describe Boards::Issues::MoveService do let!(:closed) { create(:closed_list, board: board1) } before do - project.team << [user, :developer] + project.add_developer(user) end context 'when moving an issue between lists' do diff --git a/spec/services/boards/lists/create_service_spec.rb b/spec/services/boards/lists/create_service_spec.rb index 7d0b396cd06..d5322e1bb21 100644 --- a/spec/services/boards/lists/create_service_spec.rb +++ b/spec/services/boards/lists/create_service_spec.rb @@ -10,7 +10,7 @@ describe Boards::Lists::CreateService do subject(:service) { described_class.new(project, user, label_id: label.id) } before do - project.team << [user, :developer] + project.add_developer(user) end context 'when board lists is empty' do diff --git a/spec/services/boards/lists/generate_service_spec.rb b/spec/services/boards/lists/generate_service_spec.rb index 592f25059ac..82dbd1ee744 100644 --- a/spec/services/boards/lists/generate_service_spec.rb +++ b/spec/services/boards/lists/generate_service_spec.rb @@ -9,7 +9,7 @@ describe Boards::Lists::GenerateService do subject(:service) { described_class.new(project, user) } before do - project.team << [user, :developer] + project.add_developer(user) end context 'when board lists is empty' do diff --git a/spec/services/ci/stop_environments_service_spec.rb b/spec/services/ci/stop_environments_service_spec.rb index e2a9ed27e87..3fc4e499b0c 100644 --- a/spec/services/ci/stop_environments_service_spec.rb +++ b/spec/services/ci/stop_environments_service_spec.rb @@ -15,7 +15,7 @@ describe Ci::StopEnvironmentsService do context 'when user has permission to stop environment' do before do - project.team << [user, :developer] + project.add_developer(user) end context 'when environment is associated with removed branch' do @@ -57,7 +57,7 @@ describe Ci::StopEnvironmentsService do context 'when user does not have permission to stop environment' do context 'when user has no access to manage deployments' do before do - project.team << [user, :guest] + project.add_guest(user) end it 'does not stop environment' do @@ -86,7 +86,7 @@ describe Ci::StopEnvironmentsService do context 'when user has permission to stop environments' do before do - project.team << [user, :master] + project.add_master(user) end it 'does not stop environment' do diff --git a/spec/services/create_deployment_service_spec.rb b/spec/services/create_deployment_service_spec.rb index 08267d6e6a0..b9bfbb11511 100644 --- a/spec/services/create_deployment_service_spec.rb +++ b/spec/services/create_deployment_service_spec.rb @@ -266,7 +266,7 @@ describe CreateDeploymentService do context "while updating the 'first_deployed_to_production_at' time" do before do - merge_request.mark_as_merged + merge_request.metrics.update!(merged_at: Time.now) end context "for merge requests merged before the current deploy" do diff --git a/spec/services/delete_branch_service_spec.rb b/spec/services/delete_branch_service_spec.rb index 19855c9bee2..9c9fba030e7 100644 --- a/spec/services/delete_branch_service_spec.rb +++ b/spec/services/delete_branch_service_spec.rb @@ -9,7 +9,7 @@ describe DeleteBranchService do describe '#execute' do context 'when user has access to push to repository' do before do - project.team << [user, :developer] + project.add_developer(user) end it 'removes the branch' do diff --git a/spec/services/discussions/resolve_service_spec.rb b/spec/services/discussions/resolve_service_spec.rb index ab8df7b74cd..3895a0b3aea 100644 --- a/spec/services/discussions/resolve_service_spec.rb +++ b/spec/services/discussions/resolve_service_spec.rb @@ -9,7 +9,7 @@ describe Discussions::ResolveService do let(:service) { described_class.new(discussion.noteable.project, user, merge_request: merge_request) } before do - project.team << [user, :master] + project.add_master(user) end it "doesn't resolve discussions the user can't resolve" do diff --git a/spec/services/files/delete_service_spec.rb b/spec/services/files/delete_service_spec.rb index e9f8f0efe6b..ace5f293097 100644 --- a/spec/services/files/delete_service_spec.rb +++ b/spec/services/files/delete_service_spec.rb @@ -37,7 +37,7 @@ describe Files::DeleteService do end before do - project.team << [user, :master] + project.add_master(user) end describe "#execute" do diff --git a/spec/services/files/multi_service_spec.rb b/spec/services/files/multi_service_spec.rb index 085a28d267f..2b79609930c 100644 --- a/spec/services/files/multi_service_spec.rb +++ b/spec/services/files/multi_service_spec.rb @@ -36,7 +36,7 @@ describe Files::MultiService do end before do - project.team << [user, :master] + project.add_master(user) end describe '#execute' do diff --git a/spec/services/files/update_service_spec.rb b/spec/services/files/update_service_spec.rb index 2b4f8cd42ee..43b0c9a63a9 100644 --- a/spec/services/files/update_service_spec.rb +++ b/spec/services/files/update_service_spec.rb @@ -24,7 +24,7 @@ describe Files::UpdateService do end before do - project.team << [user, :master] + project.add_master(user) end describe "#execute" do diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb index cc3d4e7da49..26fdf8d4b24 100644 --- a/spec/services/git_push_service_spec.rb +++ b/spec/services/git_push_service_spec.rb @@ -11,7 +11,7 @@ describe GitPushService, services: true do let(:ref) { 'refs/heads/master' } before do - project.team << [user, :master] + project.add_master(user) end describe 'Push branches' do @@ -266,8 +266,8 @@ describe GitPushService, services: true do let(:commit) { project.commit } before do - project.team << [commit_author, :developer] - project.team << [user, :developer] + project.add_developer(commit_author) + project.add_developer(user) allow(commit).to receive_messages( safe_message: "this commit \n mentions #{issue.to_reference}", @@ -323,8 +323,8 @@ describe GitPushService, services: true do let(:commit_time) { Time.now } before do - project.team << [commit_author, :developer] - project.team << [user, :developer] + project.add_developer(commit_author) + project.add_developer(user) allow(commit).to receive_messages( safe_message: "this commit \n mentions #{issue.to_reference}", @@ -376,7 +376,7 @@ describe GitPushService, services: true do allow_any_instance_of(ProcessCommitWorker).to receive(:build_commit) .and_return(closing_commit) - project.team << [commit_author, :master] + project.add_master(commit_author) end context "to default branches" do diff --git a/spec/services/git_tag_push_service_spec.rb b/spec/services/git_tag_push_service_spec.rb index 05695aa8188..33405d7a7ec 100644 --- a/spec/services/git_tag_push_service_spec.rb +++ b/spec/services/git_tag_push_service_spec.rb @@ -35,7 +35,7 @@ describe GitTagPushService do before do stub_ci_pipeline_to_return_yaml_file - project.team << [user, :developer] + project.add_developer(user) end it "creates a new pipeline" do diff --git a/spec/services/issuable/bulk_update_service_spec.rb b/spec/services/issuable/bulk_update_service_spec.rb index bdaab88d673..53c85f73cde 100644 --- a/spec/services/issuable/bulk_update_service_spec.rb +++ b/spec/services/issuable/bulk_update_service_spec.rb @@ -54,7 +54,7 @@ describe Issuable::BulkUpdateService do context 'when the new assignee ID is a valid user' do it 'succeeds' do new_assignee = create(:user) - project.team << [new_assignee, :developer] + project.add_developer(new_assignee) result = bulk_update(merge_request, assignee_id: new_assignee.id) @@ -64,7 +64,7 @@ describe Issuable::BulkUpdateService do it 'updates the assignee to the user ID passed' do assignee = create(:user) - project.team << [assignee, :developer] + project.add_developer(assignee) expect { bulk_update(merge_request, assignee_id: assignee.id) } .to change { merge_request.reload.assignee }.from(user).to(assignee) @@ -92,7 +92,7 @@ describe Issuable::BulkUpdateService do context 'when the new assignee ID is a valid user' do it 'succeeds' do new_assignee = create(:user) - project.team << [new_assignee, :developer] + project.add_developer(new_assignee) result = bulk_update(issue, assignee_ids: [new_assignee.id]) @@ -102,7 +102,7 @@ describe Issuable::BulkUpdateService do it 'updates the assignee to the user ID passed' do assignee = create(:user) - project.team << [assignee, :developer] + project.add_developer(assignee) expect { bulk_update(issue, assignee_ids: [assignee.id]) } .to change { issue.reload.assignees.first }.from(user).to(assignee) end diff --git a/spec/services/issues/build_service_spec.rb b/spec/services/issues/build_service_spec.rb index 03f76bd428d..248e7d5a389 100644 --- a/spec/services/issues/build_service_spec.rb +++ b/spec/services/issues/build_service_spec.rb @@ -5,7 +5,7 @@ describe Issues::BuildService do let(:user) { create(:user) } before do - project.team << [user, :developer] + project.add_developer(user) end context 'for a single discussion' do diff --git a/spec/services/issues/close_service_spec.rb b/spec/services/issues/close_service_spec.rb index 5c27e8fd561..8897a64a138 100644 --- a/spec/services/issues/close_service_spec.rb +++ b/spec/services/issues/close_service_spec.rb @@ -9,9 +9,9 @@ describe Issues::CloseService do let!(:todo) { create(:todo, :assigned, user: user, project: project, target: issue, author: user2) } before do - project.team << [user, :master] - project.team << [user2, :developer] - project.team << [guest, :guest] + project.add_master(user) + project.add_developer(user2) + project.add_guest(guest) end describe '#execute' do diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb index d86da244520..79bcdc41fb0 100644 --- a/spec/services/issues/create_service_spec.rb +++ b/spec/services/issues/create_service_spec.rb @@ -13,8 +13,8 @@ describe Issues::CreateService do let(:labels) { create_pair(:label, project: project) } before do - project.team << [user, :master] - project.team << [assignee, :master] + project.add_master(user) + project.add_master(assignee) end let(:opts) do @@ -43,7 +43,7 @@ describe Issues::CreateService do let(:guest) { create(:user) } before do - project.team << [guest, :guest] + project.add_guest(guest) end it 'filters out params that cannot be set without the :admin_issue permission' do @@ -130,7 +130,7 @@ describe Issues::CreateService do end it 'invalidates open issues counter for assignees when issue is assigned' do - project.team << [assignee, :master] + project.add_master(assignee) described_class.new(project, user, opts).execute @@ -160,7 +160,7 @@ describe Issues::CreateService do context 'issue create service' do context 'assignees' do before do - project.team << [user, :master] + project.add_master(user) end it 'removes assignee when user id is invalid' do @@ -180,7 +180,7 @@ describe Issues::CreateService do end it 'saves assignee when user id is valid' do - project.team << [assignee, :master] + project.add_master(assignee) opts = { title: 'Title', description: 'Description', assignee_ids: [assignee.id] } issue = described_class.new(project, user, opts).execute @@ -224,8 +224,8 @@ describe Issues::CreateService do end before do - project.team << [user, :master] - project.team << [assignee, :master] + project.add_master(user) + project.add_master(assignee) end it 'assigns and sets milestone to issuable from command' do @@ -242,7 +242,7 @@ describe Issues::CreateService do let(:project) { merge_request.source_project } before do - project.team << [user, :master] + project.add_master(user) end describe 'for a single discussion' do diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb index 2cad695d7c4..53ea88332fb 100644 --- a/spec/services/issues/move_service_spec.rb +++ b/spec/services/issues/move_service_spec.rb @@ -20,8 +20,8 @@ describe Issues::MoveService do shared_context 'user can move issue' do before do - old_project.team << [user, :reporter] - new_project.team << [user, :reporter] + old_project.add_reporter(user) + new_project.add_reporter(user) labels = Array.new(2) { |x| "label%d" % (x + 1) } @@ -313,7 +313,7 @@ describe Issues::MoveService do context 'user is reporter only in new project' do before do - new_project.team << [user, :reporter] + new_project.add_reporter(user) end it { expect { move }.to raise_error(StandardError, /permissions/) } @@ -321,7 +321,7 @@ describe Issues::MoveService do context 'user is reporter only in old project' do before do - old_project.team << [user, :reporter] + old_project.add_reporter(user) end it { expect { move }.to raise_error(StandardError, /permissions/) } @@ -329,8 +329,8 @@ describe Issues::MoveService do context 'user is reporter in one project and guest in another' do before do - new_project.team << [user, :guest] - old_project.team << [user, :reporter] + new_project.add_guest(user) + old_project.add_reporter(user) end it { expect { move }.to raise_error(StandardError, /permissions/) } @@ -358,8 +358,8 @@ describe Issues::MoveService do context 'movable issue with no assigned labels' do before do - old_project.team << [user, :reporter] - new_project.team << [user, :reporter] + old_project.add_reporter(user) + new_project.add_reporter(user) labels = Array.new(2) { |x| "label%d" % (x + 1) } diff --git a/spec/services/issues/reopen_service_spec.rb b/spec/services/issues/reopen_service_spec.rb index 48fc98b3b2f..42e5d544f4c 100644 --- a/spec/services/issues/reopen_service_spec.rb +++ b/spec/services/issues/reopen_service_spec.rb @@ -8,7 +8,7 @@ describe Issues::ReopenService do context 'when user is not authorized to reopen issue' do before do guest = create(:user) - project.team << [guest, :guest] + project.add_guest(guest) perform_enqueued_jobs do described_class.new(project, guest).execute(issue) @@ -24,7 +24,7 @@ describe Issues::ReopenService do let(:user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) end it 'invalidates counter cache for assignees' do diff --git a/spec/services/issues/resolve_discussions_spec.rb b/spec/services/issues/resolve_discussions_spec.rb index 67a86c50fc1..13accc6ae1b 100644 --- a/spec/services/issues/resolve_discussions_spec.rb +++ b/spec/services/issues/resolve_discussions_spec.rb @@ -14,7 +14,7 @@ describe Issues::ResolveDiscussions do let(:user) { create(:user) } before do - project.team << [user, :developer] + project.add_developer(user) end describe "for resolving discussions" do diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index f07b81e842a..1cb6f2e097f 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -17,9 +17,9 @@ describe Issues::UpdateService, :mailer do end before do - project.team << [user, :master] - project.team << [user2, :developer] - project.team << [user3, :developer] + project.add_master(user) + project.add_developer(user2) + project.add_developer(user3) end describe 'execute' do @@ -99,7 +99,7 @@ describe Issues::UpdateService, :mailer do context 'when current user cannot admin issues in the project' do let(:guest) { create(:user) } before do - project.team << [guest, :guest] + project.add_guest(guest) end it 'filters out params that cannot be set without the :admin_issue permission' do @@ -318,7 +318,7 @@ describe Issues::UpdateService, :mailer do let!(:subscriber) do create(:user).tap do |u| label.toggle_subscription(u, project) - project.team << [u, :developer] + project.add_developer(u) end end @@ -556,7 +556,7 @@ describe Issues::UpdateService, :mailer do context 'valid project' do before do - target_project.team << [user, :master] + target_project.add_master(user) end it 'calls the move service with the proper issue and project' do diff --git a/spec/services/labels/find_or_create_service_spec.rb b/spec/services/labels/find_or_create_service_spec.rb index a781fbc7f7d..78aa5d442e7 100644 --- a/spec/services/labels/find_or_create_service_spec.rb +++ b/spec/services/labels/find_or_create_service_spec.rb @@ -17,7 +17,7 @@ describe Labels::FindOrCreateService do let(:user) { create(:user) } subject(:service) { described_class.new(user, project, params) } before do - project.team << [user, :developer] + project.add_developer(user) end context 'when label does not exist at group level' do diff --git a/spec/services/members/approve_access_request_service_spec.rb b/spec/services/members/approve_access_request_service_spec.rb index 302c488d6c6..b3018169a1c 100644 --- a/spec/services/members/approve_access_request_service_spec.rb +++ b/spec/services/members/approve_access_request_service_spec.rb @@ -123,7 +123,7 @@ describe Members::ApproveAccessRequestService do context 'when current user can approve access request to the project' do before do - project.team << [user, :master] + project.add_master(user) group.add_owner(user) end diff --git a/spec/services/members/authorized_destroy_service_spec.rb b/spec/services/members/authorized_destroy_service_spec.rb index d4ef31c0c74..757c45708b9 100644 --- a/spec/services/members/authorized_destroy_service_spec.rb +++ b/spec/services/members/authorized_destroy_service_spec.rb @@ -13,7 +13,7 @@ describe Members::AuthorizedDestroyService do context 'Invited users' do # Regression spec for issue: https://gitlab.com/gitlab-org/gitlab-ce/issues/32504 it 'destroys invited project member' do - project.team << [member_user, :developer] + project.add_developer(member_user) member = create :project_member, :invited, project: project @@ -52,7 +52,7 @@ describe Members::AuthorizedDestroyService do context 'Project member' do it "unassigns issues and merge requests" do - project.team << [member_user, :developer] + project.add_developer(member_user) create :issue, project: project, assignees: [member_user] create :merge_request, target_project: project, source_project: project, assignee: member_user diff --git a/spec/services/members/create_service_spec.rb b/spec/services/members/create_service_spec.rb index 2a793e0eb4d..6bd4718e780 100644 --- a/spec/services/members/create_service_spec.rb +++ b/spec/services/members/create_service_spec.rb @@ -6,7 +6,7 @@ describe Members::CreateService do let(:project_user) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) end it 'adds user to members' do diff --git a/spec/services/members/destroy_service_spec.rb b/spec/services/members/destroy_service_spec.rb index 72f5e27180d..91152df3ad9 100644 --- a/spec/services/members/destroy_service_spec.rb +++ b/spec/services/members/destroy_service_spec.rb @@ -71,7 +71,7 @@ describe Members::DestroyService do context 'when a member is found' do before do - project.team << [member_user, :developer] + project.add_developer(member_user) group.add_developer(member_user) end let(:params) { { user_id: member_user.id } } @@ -88,7 +88,7 @@ describe Members::DestroyService do context 'when current user can destroy the given member' do before do - project.team << [user, :master] + project.add_master(user) group.add_owner(user) end diff --git a/spec/services/merge_requests/assign_issues_service_spec.rb b/spec/services/merge_requests/assign_issues_service_spec.rb index fcbe0e5985f..bda6383a346 100644 --- a/spec/services/merge_requests/assign_issues_service_spec.rb +++ b/spec/services/merge_requests/assign_issues_service_spec.rb @@ -8,7 +8,7 @@ describe MergeRequests::AssignIssuesService do let(:service) { described_class.new(project, user, merge_request: merge_request) } before do - project.team << [user, :developer] + project.add_developer(user) end it 'finds unassigned issues fixed in merge request' do diff --git a/spec/services/merge_requests/build_service_spec.rb b/spec/services/merge_requests/build_service_spec.rb index b5c92e681fb..a9605c6e4c6 100644 --- a/spec/services/merge_requests/build_service_spec.rb +++ b/spec/services/merge_requests/build_service_spec.rb @@ -28,7 +28,7 @@ describe MergeRequests::BuildService do end before do - project.team << [user, :guest] + project.add_guest(user) end def stub_compare diff --git a/spec/services/merge_requests/close_service_spec.rb b/spec/services/merge_requests/close_service_spec.rb index b3886987316..4d12de3ecce 100644 --- a/spec/services/merge_requests/close_service_spec.rb +++ b/spec/services/merge_requests/close_service_spec.rb @@ -9,9 +9,9 @@ describe MergeRequests::CloseService do let!(:todo) { create(:todo, :assigned, user: user, project: project, target: merge_request, author: user2) } before do - project.team << [user, :master] - project.team << [user2, :developer] - project.team << [guest, :guest] + project.add_master(user) + project.add_developer(user2) + project.add_guest(guest) end describe '#execute' do @@ -52,6 +52,19 @@ describe MergeRequests::CloseService do end end + it 'updates metrics' do + metrics = merge_request.metrics + metrics_service = double(MergeRequestMetricsService) + allow(MergeRequestMetricsService) + .to receive(:new) + .with(metrics) + .and_return(metrics_service) + + expect(metrics_service).to receive(:close) + + described_class.new(project, user, {}).execute(merge_request) + end + it 'refreshes the number of open merge requests for a valid MR', :use_clean_rails_memory_store_caching do service = described_class.new(project, user, {}) diff --git a/spec/services/merge_requests/conflicts/list_service_spec.rb b/spec/services/merge_requests/conflicts/list_service_spec.rb index 0b32c51a16f..6cadcd438c3 100644 --- a/spec/services/merge_requests/conflicts/list_service_spec.rb +++ b/spec/services/merge_requests/conflicts/list_service_spec.rb @@ -32,14 +32,6 @@ describe MergeRequests::Conflicts::ListService do expect(conflicts_service(merge_request).can_be_resolved_in_ui?).to be_falsey end - it 'returns a falsey value when the MR has a missing ref after a force push' do - merge_request = create_merge_request('conflict-resolvable') - service = conflicts_service(merge_request) - allow_any_instance_of(Rugged::Repository).to receive(:merge_commits).and_raise(Rugged::OdbError) - - expect(service.can_be_resolved_in_ui?).to be_falsey - end - it 'returns a falsey value when the MR does not support new diff notes' do merge_request = create_merge_request('conflict-resolvable') merge_request.merge_request_diff.update_attributes(start_commit_sha: nil) @@ -76,5 +68,23 @@ describe MergeRequests::Conflicts::ListService do expect(conflicts_service(merge_request).can_be_resolved_in_ui?).to be_truthy end + + it 'returns a falsey value when the MR has a missing ref after a force push' do + merge_request = create_merge_request('conflict-resolvable') + service = conflicts_service(merge_request) + allow_any_instance_of(Gitlab::GitalyClient::ConflictsService).to receive(:list_conflict_files).and_raise(GRPC::Unknown) + + expect(service.can_be_resolved_in_ui?).to be_falsey + end + + context 'with gitaly disabled', :skip_gitaly_mock do + it 'returns a falsey value when the MR has a missing ref after a force push' do + merge_request = create_merge_request('conflict-resolvable') + service = conflicts_service(merge_request) + allow_any_instance_of(Rugged::Repository).to receive(:merge_commits).and_raise(Rugged::OdbError) + + expect(service.can_be_resolved_in_ui?).to be_falsey + end + end end end diff --git a/spec/services/merge_requests/conflicts/resolve_service_spec.rb b/spec/services/merge_requests/conflicts/resolve_service_spec.rb index e28d8d7ae5c..cff09237005 100644 --- a/spec/services/merge_requests/conflicts/resolve_service_spec.rb +++ b/spec/services/merge_requests/conflicts/resolve_service_spec.rb @@ -111,15 +111,6 @@ describe MergeRequests::Conflicts::ResolveService do described_class.new(merge_request_from_fork).execute(user, params) end - it 'gets conflicts from the source project' do - # REFACTOR NOTE: We used to test that `project.repository.rugged` wasn't - # used in this case, but since the refactor, for simplification, - # we always use that repository for read only operations. - expect(forked_project.repository.rugged).to receive(:merge_commits).and_call_original - - subject - end - it 'creates a commit with the message' do subject @@ -132,6 +123,17 @@ describe MergeRequests::Conflicts::ResolveService do expect(merge_request_from_fork.source_branch_head.parents.map(&:id)) .to eq(['404fa3fc7c2c9b5dacff102f353bdf55b1be2813', target_head]) end + + context 'when gitaly is disabled', :skip_gitaly_mock do + it 'gets conflicts from the source project' do + # REFACTOR NOTE: We used to test that `project.repository.rugged` wasn't + # used in this case, but since the refactor, for simplification, + # we always use that repository for read only operations. + expect(forked_project.repository.rugged).to receive(:merge_commits).and_call_original + + subject + end + end end end diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb index a047f891ab2..dd8c803a2f7 100644 --- a/spec/services/merge_requests/create_service_spec.rb +++ b/spec/services/merge_requests/create_service_spec.rb @@ -21,8 +21,8 @@ describe MergeRequests::CreateService do let(:merge_request) { service.execute } before do - project.team << [user, :master] - project.team << [assignee, :developer] + project.add_master(user) + project.add_developer(assignee) allow(service).to receive(:execute_hooks) end @@ -148,8 +148,8 @@ describe MergeRequests::CreateService do end before do - project.team << [user, :master] - project.team << [assignee, :master] + project.add_master(user) + project.add_master(assignee) end it 'assigns and sets milestone to issuable from command' do @@ -165,7 +165,7 @@ describe MergeRequests::CreateService do let(:assignee) { create(:user) } before do - project.team << [user, :master] + project.add_master(user) end it 'removes assignee_id when user id is invalid' do @@ -185,7 +185,7 @@ describe MergeRequests::CreateService do end it 'saves assignee when user id is valid' do - project.team << [assignee, :master] + project.add_master(assignee) opts = { title: 'Title', description: 'Description', assignee_id: assignee.id } merge_request = described_class.new(project, user, opts).execute @@ -205,7 +205,7 @@ describe MergeRequests::CreateService do end it 'invalidates open merge request counter for assignees when merge request is assigned' do - project.team << [assignee, :master] + project.add_master(assignee) described_class.new(project, user, opts).execute @@ -249,8 +249,8 @@ describe MergeRequests::CreateService do end before do - project.team << [user, :master] - project.team << [assignee, :developer] + project.add_master(user) + project.add_developer(assignee) end it 'creates a `MergeRequestsClosingIssues` record for each issue' do diff --git a/spec/services/merge_requests/ff_merge_service_spec.rb b/spec/services/merge_requests/ff_merge_service_spec.rb index aaabf3ed2b0..aa90feeef89 100644 --- a/spec/services/merge_requests/ff_merge_service_spec.rb +++ b/spec/services/merge_requests/ff_merge_service_spec.rb @@ -12,8 +12,8 @@ describe MergeRequests::FfMergeService do let(:project) { merge_request.project } before do - project.team << [user, :master] - project.team << [user2, :developer] + project.add_master(user) + project.add_developer(user2) end describe '#execute' do diff --git a/spec/services/merge_requests/post_merge_service_spec.rb b/spec/services/merge_requests/post_merge_service_spec.rb index d2bd05d921f..70957431942 100644 --- a/spec/services/merge_requests/post_merge_service_spec.rb +++ b/spec/services/merge_requests/post_merge_service_spec.rb @@ -6,7 +6,7 @@ describe MergeRequests::PostMergeService do let(:project) { merge_request.project } before do - project.team << [user, :master] + project.add_master(user) end describe '#execute' do @@ -22,5 +22,18 @@ describe MergeRequests::PostMergeService do expect { service.execute(merge_request) } .to change { project.open_merge_requests_count }.from(1).to(0) end + + it 'updates metrics' do + metrics = merge_request.metrics + metrics_service = double(MergeRequestMetricsService) + allow(MergeRequestMetricsService) + .to receive(:new) + .with(metrics) + .and_return(metrics_service) + + expect(metrics_service).to receive(:merge) + + described_class.new(project, user, {}).execute(merge_request) + end end end diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb index 61ec4709c59..7a01d3dd698 100644 --- a/spec/services/merge_requests/refresh_service_spec.rb +++ b/spec/services/merge_requests/refresh_service_spec.rb @@ -300,8 +300,8 @@ describe MergeRequests::RefreshService do let(:commit) { project.commit } before do - project.team << [commit_author, :developer] - project.team << [user, :developer] + project.add_developer(commit_author) + project.add_developer(user) allow(commit).to receive_messages( safe_message: "Closes #{issue.to_reference}", diff --git a/spec/services/merge_requests/reopen_service_spec.rb b/spec/services/merge_requests/reopen_service_spec.rb index fa652611c6b..a44d63e5f9f 100644 --- a/spec/services/merge_requests/reopen_service_spec.rb +++ b/spec/services/merge_requests/reopen_service_spec.rb @@ -8,9 +8,9 @@ describe MergeRequests::ReopenService do let(:project) { merge_request.project } before do - project.team << [user, :master] - project.team << [user2, :developer] - project.team << [guest, :guest] + project.add_master(user) + project.add_developer(user2) + project.add_guest(guest) end describe '#execute' do @@ -47,6 +47,19 @@ describe MergeRequests::ReopenService do end end + it 'updates metrics' do + metrics = merge_request.metrics + service = double(MergeRequestMetricsService) + allow(MergeRequestMetricsService) + .to receive(:new) + .with(metrics) + .and_return(service) + + expect(service).to receive(:reopen) + + described_class.new(project, user, {}).execute(merge_request) + end + it 'refreshes the number of open merge requests for a valid MR' do service = described_class.new(project, user, {}) diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb index 7a66b809550..2238da2d14d 100644 --- a/spec/services/merge_requests/update_service_spec.rb +++ b/spec/services/merge_requests/update_service_spec.rb @@ -16,9 +16,9 @@ describe MergeRequests::UpdateService, :mailer do end before do - project.team << [user, :master] - project.team << [user2, :developer] - project.team << [user3, :developer] + project.add_master(user) + project.add_developer(user2) + project.add_developer(user3) end describe 'execute' do @@ -356,8 +356,8 @@ describe MergeRequests::UpdateService, :mailer do let!(:subscriber) { create(:user) { |u| label.toggle_subscription(u, project) } } before do - project.team << [non_subscriber, :developer] - project.team << [subscriber, :developer] + project.add_developer(non_subscriber) + project.add_developer(subscriber) end it 'sends notifications for subscribers of newly added labels' do diff --git a/spec/services/milestones/close_service_spec.rb b/spec/services/milestones/close_service_spec.rb index 2bdf224804d..adad73f7e11 100644 --- a/spec/services/milestones/close_service_spec.rb +++ b/spec/services/milestones/close_service_spec.rb @@ -6,7 +6,7 @@ describe Milestones::CloseService do let(:milestone) { create(:milestone, title: "Milestone v1.2", project: project) } before do - project.team << [user, :master] + project.add_master(user) end describe '#execute' do diff --git a/spec/services/milestones/create_service_spec.rb b/spec/services/milestones/create_service_spec.rb index 8837b91051d..f2a18c7295a 100644 --- a/spec/services/milestones/create_service_spec.rb +++ b/spec/services/milestones/create_service_spec.rb @@ -7,7 +7,7 @@ describe Milestones::CreateService do describe '#execute' do context "valid params" do before do - project.team << [user, :master] + project.add_master(user) opts = { title: 'v2.1.9', diff --git a/spec/services/milestones/destroy_service_spec.rb b/spec/services/milestones/destroy_service_spec.rb index af35e17bfa7..9703780b0e9 100644 --- a/spec/services/milestones/destroy_service_spec.rb +++ b/spec/services/milestones/destroy_service_spec.rb @@ -8,7 +8,7 @@ describe Milestones::DestroyService do let!(:merge_request) { create(:merge_request, source_project: project, milestone: milestone) } before do - project.team << [user, :master] + project.add_master(user) end def service diff --git a/spec/services/notes/create_service_spec.rb b/spec/services/notes/create_service_spec.rb index 661d26946e7..0ae26e87154 100644 --- a/spec/services/notes/create_service_spec.rb +++ b/spec/services/notes/create_service_spec.rb @@ -10,7 +10,7 @@ describe Notes::CreateService do describe '#execute' do before do - project.team << [user, :master] + project.add_master(user) end context "valid params" do diff --git a/spec/services/notes/post_process_service_spec.rb b/spec/services/notes/post_process_service_spec.rb index a2b3638059f..6ef5e93cb20 100644 --- a/spec/services/notes/post_process_service_spec.rb +++ b/spec/services/notes/post_process_service_spec.rb @@ -7,7 +7,7 @@ describe Notes::PostProcessService do describe '#execute' do before do - project.team << [user, :master] + project.add_master(user) note_opts = { note: 'Awesome comment', noteable_type: 'Issue', diff --git a/spec/services/notes/quick_actions_service_spec.rb b/spec/services/notes/quick_actions_service_spec.rb index 0280a19098b..5eafe56c99d 100644 --- a/spec/services/notes/quick_actions_service_spec.rb +++ b/spec/services/notes/quick_actions_service_spec.rb @@ -3,11 +3,11 @@ require 'spec_helper' describe Notes::QuickActionsService do shared_context 'note on noteable' do let(:project) { create(:project) } - let(:master) { create(:user).tap { |u| project.team << [u, :master] } } + let(:master) { create(:user).tap { |u| project.add_master(u) } } let(:assignee) { create(:user) } before do - project.team << [assignee, :master] + project.add_master(assignee) end end @@ -226,7 +226,7 @@ describe Notes::QuickActionsService do context 'CE restriction for issue assignees' do describe '/assign' do let(:project) { create(:project) } - let(:master) { create(:user).tap { |u| project.team << [u, :master] } } + let(:master) { create(:user).tap { |u| project.add_master(u) } } let(:assignee) { create(:user) } let(:master) { create(:user) } let(:service) { described_class.new(project, master) } @@ -237,8 +237,8 @@ describe Notes::QuickActionsService do end before do - project.team << [master, :master] - project.team << [assignee, :master] + project.add_master(master) + project.add_master(assignee) end it 'adds only one assignee from the list' do diff --git a/spec/services/notes/update_service_spec.rb b/spec/services/notes/update_service_spec.rb index 3210539f3ee..65b1d613998 100644 --- a/spec/services/notes/update_service_spec.rb +++ b/spec/services/notes/update_service_spec.rb @@ -9,9 +9,9 @@ describe Notes::UpdateService do let(:note) { create(:note, project: project, noteable: issue, author: user, note: "Old note #{user2.to_reference}") } before do - project.team << [user, :master] - project.team << [user2, :developer] - project.team << [user3, :developer] + project.add_master(user) + project.add_developer(user2) + project.add_developer(user3) end describe '#execute' do diff --git a/spec/services/projects/autocomplete_service_spec.rb b/spec/services/projects/autocomplete_service_spec.rb index 426593be428..7a8c54673f7 100644 --- a/spec/services/projects/autocomplete_service_spec.rb +++ b/spec/services/projects/autocomplete_service_spec.rb @@ -34,7 +34,7 @@ describe Projects::AutocompleteService do end it 'does not list project confidential issues for project members with guest role' do - project.team << [member, :guest] + project.add_guest(member) autocomplete = described_class.new(project, non_member) issues = autocomplete.issues.map(&:iid) @@ -66,7 +66,7 @@ describe Projects::AutocompleteService do end it 'lists project confidential issues for project members' do - project.team << [member, :developer] + project.add_developer(member) autocomplete = described_class.new(project, member) issues = autocomplete.issues.map(&:iid) diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb index dc89fdebce7..1833078f37c 100644 --- a/spec/services/projects/create_service_spec.rb +++ b/spec/services/projects/create_service_spec.rb @@ -252,6 +252,12 @@ describe Projects::CreateService, '#execute' do end end + it 'writes project full path to .git/config' do + project = create_project(user, opts) + + expect(project.repo.config['gitlab.fullpath']).to eq project.full_path + end + def create_project(user, opts) Projects::CreateService.new(user, opts).execute end diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb index 4057caca2ac..409d5de8d43 100644 --- a/spec/services/projects/fork_service_spec.rb +++ b/spec/services/projects/fork_service_spec.rb @@ -139,10 +139,10 @@ describe Projects::ForkService do stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::INTERNAL]) end - it "creates fork with highest allowed level" do + it "creates fork with lowest level" do forked_project = fork_project(@from_project, @to_user) - expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PUBLIC) + expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) end end @@ -209,6 +209,19 @@ describe Projects::ForkService do expect(to_project.errors[:path]).to eq(['has already been taken']) end end + + context 'when the namespace has a lower visibility level than the project' do + it 'creates the project with the lower visibility level' do + public_project = create(:project, :public) + private_group = create(:group, :private) + group_owner = create(:user) + private_group.add_owner(group_owner) + + forked_project = fork_project(public_project, group_owner, namespace: private_group) + + expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE) + end + end end end diff --git a/spec/services/projects/hashed_storage/migrate_repository_service_spec.rb b/spec/services/projects/hashed_storage/migrate_repository_service_spec.rb index 3a3e47fd9c0..ded864beb1d 100644 --- a/spec/services/projects/hashed_storage/migrate_repository_service_spec.rb +++ b/spec/services/projects/hashed_storage/migrate_repository_service_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe Projects::HashedStorage::MigrateRepositoryService do let(:gitlab_shell) { Gitlab::Shell.new } - let(:project) { create(:project, :empty_repo, :wiki_repo) } + let(:project) { create(:project, :repository, :wiki_repo) } let(:service) { described_class.new(project) } let(:legacy_storage) { Storage::LegacyProject.new(project) } let(:hashed_storage) { Storage::HashedProject.new(project) } @@ -33,6 +33,12 @@ describe Projects::HashedStorage::MigrateRepositoryService do service.execute end + + it 'writes project full path to .git/config' do + service.execute + + expect(project.repo.config['gitlab.fullpath']).to eq project.full_path + end end context 'when one move fails' do diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb index 2b1337bee7e..7377c748698 100644 --- a/spec/services/projects/transfer_service_spec.rb +++ b/spec/services/projects/transfer_service_spec.rb @@ -54,6 +54,12 @@ describe Projects::TransferService do expect(project.disk_path).not_to eq(old_path) expect(project.disk_path).to start_with(group.path) end + + it 'updates project full path in .git/config' do + transfer_project(project, user, group) + + expect(project.repo.config['gitlab.fullpath']).to eq "#{group.full_path}/#{project.path}" + end end context 'when transfer fails' do @@ -86,6 +92,12 @@ describe Projects::TransferService do expect(original_path).to eq current_path end + it 'rolls back project full path in .git/config' do + attempt_project_transfer + + expect(project.repo.config['gitlab.fullpath']).to eq project.full_path + end + it "doesn't send move notifications" do expect_any_instance_of(NotificationService).not_to receive(:project_was_moved) diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb index d887f70efae..fc6aa713d6f 100644 --- a/spec/services/projects/update_service_spec.rb +++ b/spec/services/projects/update_service_spec.rb @@ -61,7 +61,7 @@ describe Projects::UpdateService do end end - context 'When project visibility is higher than parent group' do + context 'when project visibility is higher than parent group' do let(:group) { create(:group, visibility_level: Gitlab::VisibilityLevel::INTERNAL) } before do diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb index eb46480fa54..ae160d104f1 100644 --- a/spec/services/quick_actions/interpret_service_spec.rb +++ b/spec/services/quick_actions/interpret_service_spec.rb @@ -12,7 +12,7 @@ describe QuickActions::InterpretService do let(:service) { described_class.new(project, developer) } before do - project.team << [developer, :developer] + project.add_developer(developer) end describe '#execute' do @@ -440,7 +440,7 @@ describe QuickActions::InterpretService do let(:content) { "/assign @#{developer.username} @#{developer2.username}" } before do - project.team << [developer2, :developer] + project.add_developer(developer2) end context 'Issue' do diff --git a/spec/services/search/snippet_service_spec.rb b/spec/services/search/snippet_service_spec.rb index eae9bd4f5cf..bc7885b03d9 100644 --- a/spec/services/search/snippet_service_spec.rb +++ b/spec/services/search/snippet_service_spec.rb @@ -33,7 +33,7 @@ describe Search::SnippetService do it 'returns public, internal snippets and project private snippets for project members' do member = create(:user) - project.team << [member, :developer] + project.add_developer(member) search = described_class.new(member, search: 'password') results = search.execute diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb index 9025589ae0b..4e640a82dfc 100644 --- a/spec/services/system_note_service_spec.rb +++ b/spec/services/system_note_service_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' describe SystemNoteService do include Gitlab::Routing + include RepoHelpers set(:group) { create(:group) } set(:project) { create(:project, :repository, group: group) } @@ -1070,17 +1071,32 @@ describe SystemNoteService do let(:action) { 'outdated' } end - it 'creates a new note in the discussion' do - # we need to completely rebuild the merge request object, or the `@discussions` on the merge request are not reloaded. - expect { subject }.to change { reloaded_merge_request.discussions.first.notes.size }.by(1) + context 'when the change_position is valid for the discussion' do + it 'creates a new note in the discussion' do + # we need to completely rebuild the merge request object, or the `@discussions` on the merge request are not reloaded. + expect { subject }.to change { reloaded_merge_request.discussions.first.notes.size }.by(1) + end + + it 'links to the diff in the system note' do + expect(subject.note).to include('version 1') + + diff_id = merge_request.merge_request_diff.id + line_code = change_position.line_code(project.repository) + expect(subject.note).to include(diffs_project_merge_request_url(project, merge_request, diff_id: diff_id, anchor: line_code)) + end end - it 'links to the diff in the system note' do - expect(subject.note).to include('version 1') + context 'when the change_position is invalid for the discussion' do + let(:change_position) { project.commit(sample_commit.id) } - diff_id = merge_request.merge_request_diff.id - line_code = change_position.line_code(project.repository) - expect(subject.note).to include(diffs_project_merge_request_url(project, merge_request, diff_id: diff_id, anchor: line_code)) + it 'creates a new note in the discussion' do + # we need to completely rebuild the merge request object, or the `@discussions` on the merge request are not reloaded. + expect { subject }.to change { reloaded_merge_request.discussions.first.notes.size }.by(1) + end + + it 'does not create a link' do + expect(subject.note).to eq('changed this line in version 1 of the diff') + end end end diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb index 88013acae0a..5e6c24f5730 100644 --- a/spec/services/todo_service_spec.rb +++ b/spec/services/todo_service_spec.rb @@ -17,11 +17,11 @@ describe TodoService do let(:service) { described_class.new } before do - project.team << [guest, :guest] - project.team << [author, :developer] - project.team << [member, :developer] - project.team << [john_doe, :developer] - project.team << [skipped, :developer] + project.add_guest(guest) + project.add_developer(author) + project.add_developer(member) + project.add_developer(john_doe) + project.add_developer(skipped) end describe 'Issues' do diff --git a/spec/services/update_merge_request_metrics_service_spec.rb b/spec/services/update_merge_request_metrics_service_spec.rb new file mode 100644 index 00000000000..b5fb999381d --- /dev/null +++ b/spec/services/update_merge_request_metrics_service_spec.rb @@ -0,0 +1,42 @@ +require 'rails_helper' + +describe MergeRequestMetricsService do + let(:metrics) { create(:merge_request).metrics } + + describe '#merge' do + it 'updates metrics' do + user = create(:user) + service = described_class.new(metrics) + event = double(Event, author_id: user.id, created_at: Time.now) + + service.merge(event) + + expect(metrics.merged_by).to eq(user) + expect(metrics.merged_at).to eq(event.created_at) + end + end + + describe '#close' do + it 'updates metrics' do + user = create(:user) + service = described_class.new(metrics) + event = double(Event, author_id: user.id, created_at: Time.now) + + service.close(event) + + expect(metrics.latest_closed_by).to eq(user) + expect(metrics.latest_closed_at).to eq(event.created_at) + end + end + + describe '#reopen' do + it 'updates metrics' do + service = described_class.new(metrics) + + service.reopen + + expect(metrics.latest_closed_by).to be_nil + expect(metrics.latest_closed_at).to be_nil + end + end +end diff --git a/spec/services/users/destroy_service_spec.rb b/spec/services/users/destroy_service_spec.rb index 58a5bede3de..aeba9cd60bc 100644 --- a/spec/services/users/destroy_service_spec.rb +++ b/spec/services/users/destroy_service_spec.rb @@ -188,5 +188,22 @@ describe Users::DestroyService do end end end + + describe "calls the before/after callbacks" do + it 'of project_members' do + expect_any_instance_of(ProjectMember).to receive(:run_callbacks).with(:destroy).once + + service.execute(user) + end + + it 'of group_members' do + group_member = create(:group_member) + group_member.group.group_members.create(user: user, access_level: 40) + + expect_any_instance_of(GroupMember).to receive(:run_callbacks).with(:destroy).once + + service.execute(user) + end + end end end diff --git a/spec/support/api/milestones_shared_examples.rb b/spec/support/api/milestones_shared_examples.rb index d9080b02541..0388f110d71 100644 --- a/spec/support/api/milestones_shared_examples.rb +++ b/spec/support/api/milestones_shared_examples.rb @@ -258,7 +258,7 @@ shared_examples_for 'group and project milestones' do |route_definition| # Add public project to the group in context setup_for_group if context_group - public_project.team << [user, :developer] + public_project.add_developer(user) milestone.issues << issue << confidential_issue end @@ -275,7 +275,7 @@ shared_examples_for 'group and project milestones' do |route_definition| it 'does not return confidential issues to team members with guest role' do member = create(:user) - public_project.team << [member, :guest] + public_project.add_guest(member) get api(issues_route, member) diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index 935b170a0f6..5189c57b7db 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -33,6 +33,9 @@ Capybara.register_driver :chrome do |app| options.add_argument("disable-gpu") end + # Disable /dev/shm use in CI. See https://gitlab.com/gitlab-org/gitlab-ee/issues/4252 + options.add_argument("disable-dev-shm-usage") if ENV['CI'] || ENV['CI_SERVER'] + Capybara::Selenium::Driver.new( app, browser: :chrome, diff --git a/spec/support/cookie_helper.rb b/spec/support/cookie_helper.rb index 224619c899c..d72925e1838 100644 --- a/spec/support/cookie_helper.rb +++ b/spec/support/cookie_helper.rb @@ -8,6 +8,10 @@ module CookieHelper page.driver.browser.manage.add_cookie(name: name, value: value, **options) end + def get_cookie(name) + page.driver.browser.manage.cookie_named(name) + end + private def on_a_page? diff --git a/spec/support/features/issuable_slash_commands_shared_examples.rb b/spec/support/features/issuable_slash_commands_shared_examples.rb index 08e21ee2537..2c20821ac3f 100644 --- a/spec/support/features/issuable_slash_commands_shared_examples.rb +++ b/spec/support/features/issuable_slash_commands_shared_examples.rb @@ -19,7 +19,7 @@ shared_examples 'issuable record that supports quick actions in its description let(:new_url_opts) { {} } before do - project.team << [master, :master] + project.add_master(master) gitlab_sign_in(master) end diff --git a/spec/support/markdown_feature.rb b/spec/support/markdown_feature.rb index a0d854d3641..39e94ad53de 100644 --- a/spec/support/markdown_feature.rb +++ b/spec/support/markdown_feature.rb @@ -24,7 +24,7 @@ class MarkdownFeature def project @project ||= create(:project, :repository, group: group).tap do |project| - project.team << [user, :master] + project.add_master(user) end end @@ -85,7 +85,7 @@ class MarkdownFeature @xproject ||= begin group = create(:group, :nested) create(:project, :repository, namespace: group) do |project| - project.team << [user, :developer] + project.add_developer(user) end end end diff --git a/spec/support/mentionable_shared_examples.rb b/spec/support/mentionable_shared_examples.rb index 3ac201f1fb1..1685decbe94 100644 --- a/spec/support/mentionable_shared_examples.rb +++ b/spec/support/mentionable_shared_examples.rb @@ -53,7 +53,7 @@ shared_context 'mentionable context' do set_mentionable_text.call(ref_string) - project.team << [author, :developer] + project.add_developer(author) end end diff --git a/spec/support/reference_parser_shared_examples.rb b/spec/support/reference_parser_shared_examples.rb index bd83cb88058..baf8bcc04b8 100644 --- a/spec/support/reference_parser_shared_examples.rb +++ b/spec/support/reference_parser_shared_examples.rb @@ -26,7 +26,7 @@ RSpec.shared_examples "referenced feature visibility" do |*related_features| end it "creates reference for member" do - project.team << [user, :developer] + project.add_developer(user) expect(subject.nodes_visible_to_user(user, [link])).to eq([link]) end diff --git a/spec/support/services/issuable_create_service_slash_commands_shared_examples.rb b/spec/support/services/issuable_create_service_slash_commands_shared_examples.rb index 9399745f900..7b064162726 100644 --- a/spec/support/services/issuable_create_service_slash_commands_shared_examples.rb +++ b/spec/support/services/issuable_create_service_slash_commands_shared_examples.rb @@ -3,7 +3,7 @@ shared_examples 'new issuable record that supports quick actions' do let!(:project) { create(:project, :repository) } - let(:user) { create(:user).tap { |u| project.team << [u, :master] } } + let(:user) { create(:user).tap { |u| project.add_master(u) } } let(:assignee) { create(:user) } let!(:milestone) { create(:milestone, project: project) } let!(:labels) { create_list(:label, 3, project: project) } @@ -12,7 +12,7 @@ shared_examples 'new issuable record that supports quick actions' do let(:issuable) { described_class.new(project, user, params).execute } before do - project.team << [assignee, :master] + project.add_master(assignee) end context 'with labels in command only' do diff --git a/spec/support/services_shared_context.rb b/spec/support/services_shared_context.rb index 7457484a932..3f1fd169b72 100644 --- a/spec/support/services_shared_context.rb +++ b/spec/support/services_shared_context.rb @@ -29,5 +29,13 @@ Service.available_services_names.each do |service| end end end + + def initialize_service(service) + service_item = project.find_or_initialize_service(service) + service_item.properties = service_attrs + service_item.active = true if service == "kubernetes" + service_item.save + service_item + end end end diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb index ffc051a3fff..1d99746b09f 100644 --- a/spec/support/test_env.rb +++ b/spec/support/test_env.rb @@ -215,7 +215,7 @@ module TestEnv end def copy_repo(project, bare_repo:, refs:) - target_repo_path = File.expand_path(project.repository_storage_path + "/#{project.full_path}.git") + target_repo_path = File.expand_path(project.repository_storage_path + "/#{project.disk_path}.git") FileUtils.mkdir_p(target_repo_path) FileUtils.cp_r("#{File.expand_path(bare_repo)}/.", target_repo_path) FileUtils.chmod_R 0755, target_repo_path diff --git a/spec/support/updating_mentions_shared_examples.rb b/spec/support/updating_mentions_shared_examples.rb index 565d3203e4f..5e3f19ba19e 100644 --- a/spec/support/updating_mentions_shared_examples.rb +++ b/spec/support/updating_mentions_shared_examples.rb @@ -3,7 +3,7 @@ RSpec.shared_examples 'updating mentions' do |service_class| let(:service_class) { service_class } before do - project.team << [mentioned_user, :developer] + project.add_developer(mentioned_user) end def update_mentionable(opts) diff --git a/spec/views/projects/imports/new.html.haml_spec.rb b/spec/views/projects/imports/new.html.haml_spec.rb index 9b293065797..ec435ec3b32 100644 --- a/spec/views/projects/imports/new.html.haml_spec.rb +++ b/spec/views/projects/imports/new.html.haml_spec.rb @@ -8,7 +8,7 @@ describe "projects/imports/new.html.haml" do before do sign_in(user) - project.team << [user, :master] + project.add_master(user) end it "escapes HTML in import errors" do diff --git a/spec/views/shared/notes/_form.html.haml_spec.rb b/spec/views/shared/notes/_form.html.haml_spec.rb index cae6bee2776..50980718e66 100644 --- a/spec/views/shared/notes/_form.html.haml_spec.rb +++ b/spec/views/shared/notes/_form.html.haml_spec.rb @@ -7,7 +7,7 @@ describe 'shared/notes/_form' do let(:project) { create(:project, :repository) } before do - project.team << [user, :master] + project.add_master(user) assign(:project, project) assign(:note, note) diff --git a/spec/workers/merge_worker_spec.rb b/spec/workers/merge_worker_spec.rb index 303193bab9b..c861a56497e 100644 --- a/spec/workers/merge_worker_spec.rb +++ b/spec/workers/merge_worker_spec.rb @@ -8,7 +8,7 @@ describe MergeWorker do let!(:author) { merge_request.author } before do - source_project.team << [author, :master] + source_project.add_master(author) source_project.repository.expire_branches_cache end |