Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorRémy Coutable <remy@rymai.me>2016-07-13 14:35:08 +0300
committerRémy Coutable <remy@rymai.me>2016-07-13 14:35:08 +0300
commitcb4a5880ea4e9b6f004ab39eae7b3b608d448737 (patch)
treef79f2eb18d51d879019d8b013e3377fa18fd464e /spec
parent4d0a6f17262dc5956868ca664841fb1f5a7ba458 (diff)
parent9ca633eb4c62231e4ddff5466c723cf8e2bdb25d (diff)
Merge remote-tracking branch 'origin/master' into 8-10-stable
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/commit_controller_spec.rb246
-rw-r--r--spec/controllers/help_controller_spec.rb13
-rw-r--r--spec/controllers/projects/commit_controller_spec.rb289
-rw-r--r--spec/controllers/projects/compare_controller_spec.rb69
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb244
-rw-r--r--spec/controllers/projects/todo_controller_spec.rb78
-rw-r--r--spec/factories/todos.rb4
-rw-r--r--spec/features/expand_collapse_diffs_spec.rb207
-rw-r--r--spec/features/help_pages_spec.rb2
-rw-r--r--spec/features/issues_spec.rb11
-rw-r--r--spec/features/login_spec.rb43
-rw-r--r--spec/features/merge_requests/diffs_spec.rb25
-rw-r--r--spec/features/merge_requests/edit_mr_spec.rb11
-rw-r--r--spec/features/notes_on_merge_requests_spec.rb25
-rw-r--r--spec/features/projects/labels/update_prioritization_spec.rb2
-rw-r--r--spec/finders/notes_finder_spec.rb2
-rw-r--r--spec/helpers/diff_helper_spec.rb19
-rw-r--r--spec/javascripts/fixtures/issues_show.html.haml2
-rw-r--r--spec/lib/banzai/object_renderer_spec.rb44
-rw-r--r--spec/lib/banzai/redactor_spec.rb24
-rw-r--r--spec/lib/ci/gitlab_ci_yaml_processor_spec.rb4
-rw-r--r--spec/lib/gitlab/build_data_builder_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/file_spec.rb4
-rw-r--r--spec/lib/gitlab/diff/inline_diff_spec.rb28
-rw-r--r--spec/lib/gitlab/diff/parser_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/position_tracer_spec.rb3
-rw-r--r--spec/lib/gitlab/git_access_spec.rb247
-rw-r--r--spec/lib/gitlab/github_import/client_spec.rb7
-rw-r--r--spec/lib/gitlab/import_export/project.json13
-rw-r--r--spec/lib/gitlab/import_export/project_tree_restorer_spec.rb18
-rw-r--r--spec/lib/gitlab/ldap/access_spec.rb2
-rw-r--r--spec/lib/gitlab/ldap/user_spec.rb2
-rw-r--r--spec/lib/gitlab/user_access_spec.rb88
-rw-r--r--spec/models/ci/pipeline_spec.rb10
-rw-r--r--spec/models/ci/variable_spec.rb2
-rw-r--r--spec/models/commit_status_spec.rb14
-rw-r--r--spec/models/concerns/mentionable_spec.rb2
-rw-r--r--spec/models/forked_project_link_spec.rb2
-rw-r--r--spec/models/generic_commit_status_spec.rb10
-rw-r--r--spec/models/global_milestone_spec.rb6
-rw-r--r--spec/models/group_spec.rb10
-rw-r--r--spec/models/members/project_member_spec.rb4
-rw-r--r--spec/models/merge_request_diff_spec.rb47
-rw-r--r--spec/models/merge_request_spec.rb25
-rw-r--r--spec/models/milestone_spec.rb10
-rw-r--r--spec/models/namespace_spec.rb8
-rw-r--r--spec/models/note_spec.rb14
-rw-r--r--spec/models/project_security_spec.rb2
-rw-r--r--spec/models/project_services/buildkite_service_spec.rb6
-rw-r--r--spec/models/project_spec.rb24
-rw-r--r--spec/models/repository_spec.rb29
-rw-r--r--spec/models/service_spec.rb6
-rw-r--r--spec/models/user_spec.rb12
-rw-r--r--spec/requests/api/api_helpers_spec.rb4
-rw-r--r--spec/requests/api/merge_requests_spec.rb4
-rw-r--r--spec/routing/routing_spec.rb22
-rw-r--r--spec/services/ci/create_trigger_request_service_spec.rb2
-rw-r--r--spec/services/ci/image_for_build_service_spec.rb2
-rw-r--r--spec/services/ci/register_build_service_spec.rb2
-rw-r--r--spec/services/create_commit_builds_service_spec.rb2
-rw-r--r--spec/services/event_create_service_spec.rb20
-rw-r--r--spec/services/git_push_service_spec.rb14
-rw-r--r--spec/services/issues/close_service_spec.rb2
-rw-r--r--spec/services/merge_requests/close_service_spec.rb2
-rw-r--r--spec/services/merge_requests/create_service_spec.rb2
-rw-r--r--spec/services/merge_requests/merge_service_spec.rb2
-rw-r--r--spec/services/merge_requests/refresh_service_spec.rb5
-rw-r--r--spec/services/merge_requests/reopen_service_spec.rb2
-rw-r--r--spec/services/milestones/close_service_spec.rb2
-rw-r--r--spec/services/milestones/create_service_spec.rb2
-rw-r--r--spec/services/notes/create_service_spec.rb2
-rw-r--r--spec/services/notes/post_process_service_spec.rb2
-rw-r--r--spec/services/notification_service_spec.rb26
-rw-r--r--spec/services/projects/housekeeping_service_spec.rb44
-rw-r--r--spec/services/test_hook_service_spec.rb2
-rw-r--r--spec/spec_helper.rb1
-rw-r--r--spec/support/capybara_helpers.rb8
-rw-r--r--spec/support/login_helpers.rb34
-rw-r--r--spec/support/omni_auth.rb1
-rw-r--r--spec/support/relative_url.rb8
-rw-r--r--spec/support/test_env.rb27
-rw-r--r--spec/workers/git_garbage_collect_worker_spec.rb24
82 files changed, 1586 insertions, 707 deletions
diff --git a/spec/controllers/commit_controller_spec.rb b/spec/controllers/commit_controller_spec.rb
deleted file mode 100644
index a3a3309e15e..00000000000
--- a/spec/controllers/commit_controller_spec.rb
+++ /dev/null
@@ -1,246 +0,0 @@
-require 'spec_helper'
-
-describe Projects::CommitController do
- let(:project) { create(:project) }
- let(:user) { create(:user) }
- let(:commit) { project.commit("master") }
- let(:master_pickable_sha) { '7d3b0f7cff5f37573aea97cebfd5692ea1689924' }
- let(:master_pickable_commit) { project.commit(master_pickable_sha) }
-
- before do
- sign_in(user)
- project.team << [user, :master]
- end
-
- describe "#show" do
- shared_examples "export as" do |format|
- it "should generally work" do
- get(:show,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- id: commit.id,
- format: format)
-
- expect(response).to be_success
- end
-
- it "should generate it" do
- expect_any_instance_of(Commit).to receive(:"to_#{format}")
-
- get(:show,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- id: commit.id, format: format)
- end
-
- it "should render it" do
- get(:show,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- id: commit.id, format: format)
-
- expect(response.body).to eq(commit.send(:"to_#{format}"))
- end
-
- it "should not escape Html" do
- allow_any_instance_of(Commit).to receive(:"to_#{format}").
- and_return('HTML entities &<>" ')
-
- get(:show,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- id: commit.id, format: format)
-
- expect(response.body).not_to include('&amp;')
- expect(response.body).not_to include('&gt;')
- expect(response.body).not_to include('&lt;')
- expect(response.body).not_to include('&quot;')
- end
- end
-
- describe "as diff" do
- include_examples "export as", :diff
- let(:format) { :diff }
-
- it "should really only be a git diff" do
- get(:show,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- id: commit.id,
- format: format)
-
- expect(response.body).to start_with("diff --git")
- end
-
- it "should really only be a git diff without whitespace changes" do
- get(:show,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- id: '66eceea0db202bb39c4e445e8ca28689645366c5',
- # id: commit.id,
- format: format,
- w: 1)
-
- expect(response.body).to start_with("diff --git")
- # without whitespace option, there are more than 2 diff_splits
- diff_splits = assigns(:diffs).first.diff.split("\n")
- expect(diff_splits.length).to be <= 2
- end
- end
-
- describe "as patch" do
- include_examples "export as", :patch
- let(:format) { :patch }
-
- it "should really be a git email patch" do
- get(:show,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- id: commit.id,
- format: format)
-
- expect(response.body).to start_with("From #{commit.id}")
- end
-
- it "should contain a git diff" do
- get(:show,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- id: commit.id,
- format: format)
-
- expect(response.body).to match(/^diff --git/)
- end
- end
-
- context 'commit that removes a submodule' do
- render_views
-
- let(:fork_project) { create(:forked_project_with_submodules) }
- let(:commit) { fork_project.commit('remove-submodule') }
-
- before do
- fork_project.team << [user, :master]
- end
-
- it 'renders it' do
- get(:show,
- namespace_id: fork_project.namespace.to_param,
- project_id: fork_project.to_param,
- id: commit.id)
-
- expect(response).to be_success
- end
- end
- end
-
- describe "#branches" do
- it "contains branch and tags information" do
- get(:branches,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- id: commit.id)
-
- expect(assigns(:branches)).to include("master", "feature_conflict")
- expect(assigns(:tags)).to include("v1.1.0")
- end
- end
-
- describe '#revert' do
- context 'when target branch is not provided' do
- it 'should render the 404 page' do
- post(:revert,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- id: commit.id)
-
- expect(response).not_to be_success
- expect(response).to have_http_status(404)
- end
- end
-
- context 'when the revert was successful' do
- it 'should redirect to the commits page' do
- post(:revert,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- target_branch: 'master',
- id: commit.id)
-
- expect(response).to redirect_to namespace_project_commits_path(project.namespace, project, 'master')
- expect(flash[:notice]).to eq('The commit has been successfully reverted.')
- end
- end
-
- context 'when the revert failed' do
- before do
- post(:revert,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- target_branch: 'master',
- id: commit.id)
- end
-
- it 'should redirect to the commit page' do
- # Reverting a commit that has been already reverted.
- post(:revert,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- target_branch: 'master',
- id: commit.id)
-
- expect(response).to redirect_to namespace_project_commit_path(project.namespace, project, commit.id)
- expect(flash[:alert]).to match('Sorry, we cannot revert this commit automatically.')
- end
- end
- end
-
- describe '#cherry_pick' do
- context 'when target branch is not provided' do
- it 'should render the 404 page' do
- post(:cherry_pick,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- id: master_pickable_commit.id)
-
- expect(response).not_to be_success
- expect(response).to have_http_status(404)
- end
- end
-
- context 'when the cherry-pick was successful' do
- it 'should redirect to the commits page' do
- post(:cherry_pick,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- target_branch: 'master',
- id: master_pickable_commit.id)
-
- expect(response).to redirect_to namespace_project_commits_path(project.namespace, project, 'master')
- expect(flash[:notice]).to eq('The commit has been successfully cherry-picked.')
- end
- end
-
- context 'when the cherry_pick failed' do
- before do
- post(:cherry_pick,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- target_branch: 'master',
- id: master_pickable_commit.id)
- end
-
- it 'should redirect to the commit page' do
- # Cherry-picking a commit that has been already cherry-picked.
- post(:cherry_pick,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- target_branch: 'master',
- id: master_pickable_commit.id)
-
- expect(response).to redirect_to namespace_project_commit_path(project.namespace, project, master_pickable_commit.id)
- expect(flash[:alert]).to match('Sorry, we cannot cherry-pick this commit automatically.')
- end
- end
- end
-end
diff --git a/spec/controllers/help_controller_spec.rb b/spec/controllers/help_controller_spec.rb
index 1f7fd517342..267d511c2db 100644
--- a/spec/controllers/help_controller_spec.rb
+++ b/spec/controllers/help_controller_spec.rb
@@ -11,7 +11,7 @@ describe HelpController do
context 'for Markdown formats' do
context 'when requested file exists' do
before do
- get :show, category: 'ssh', file: 'README', format: :md
+ get :show, path: 'ssh/README', format: :md
end
it 'assigns to @markdown' do
@@ -26,7 +26,7 @@ describe HelpController do
context 'when requested file is missing' do
it 'renders not found' do
- get :show, category: 'foo', file: 'bar', format: :md
+ get :show, path: 'foo/bar', format: :md
expect(response).to be_not_found
end
end
@@ -36,8 +36,7 @@ describe HelpController do
context 'when requested file exists' do
it 'renders the raw file' do
get :show,
- category: 'workflow/protected_branches',
- file: 'protected_branches1',
+ path: 'workflow/protected_branches/protected_branches1',
format: :png
expect(response).to be_success
expect(response.content_type).to eq 'image/png'
@@ -48,8 +47,7 @@ describe HelpController do
context 'when requested file is missing' do
it 'renders not found' do
get :show,
- category: 'foo',
- file: 'bar',
+ path: 'foo/bar',
format: :png
expect(response).to be_not_found
end
@@ -59,8 +57,7 @@ describe HelpController do
context 'for other formats' do
it 'always renders not found' do
get :show,
- category: 'ssh',
- file: 'README',
+ path: 'ssh/README',
format: :foo
expect(response).to be_not_found
end
diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb
index 6e3db10e451..3001d32e719 100644
--- a/spec/controllers/projects/commit_controller_spec.rb
+++ b/spec/controllers/projects/commit_controller_spec.rb
@@ -1,9 +1,29 @@
-require 'rails_helper'
+require 'spec_helper'
describe Projects::CommitController do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+ let(:commit) { project.commit("master") }
+ let(:master_pickable_sha) { '7d3b0f7cff5f37573aea97cebfd5692ea1689924' }
+ let(:master_pickable_commit) { project.commit(master_pickable_sha) }
+
+ before do
+ sign_in(user)
+ project.team << [user, :master]
+ end
+
describe 'GET show' do
render_views
+ def go(extra_params = {})
+ params = {
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param
+ }
+
+ get :show, params.merge(extra_params)
+ end
+
let(:project) { create(:project) }
before do
@@ -15,7 +35,7 @@ describe Projects::CommitController do
context 'with valid id' do
it 'responds with 200' do
- go id: project.commit.id
+ go(id: commit.id)
expect(response).to be_ok
end
@@ -23,27 +43,274 @@ describe Projects::CommitController do
context 'with invalid id' do
it 'responds with 404' do
- go id: project.commit.id.reverse
+ go(id: commit.id.reverse)
expect(response).to be_not_found
end
end
it 'handles binary files' do
- get(:show,
+ go(id: TestEnv::BRANCH_SHA['binary-encoding'], format: 'html')
+
+ expect(response).to be_success
+ end
+
+ shared_examples "export as" do |format|
+ it "should generally work" do
+ go(id: commit.id, format: format)
+
+ expect(response).to be_success
+ end
+
+ it "should generate it" do
+ expect_any_instance_of(Commit).to receive(:"to_#{format}")
+
+ go(id: commit.id, format: format)
+ end
+
+ it "should render it" do
+ go(id: commit.id, format: format)
+
+ expect(response.body).to eq(commit.send(:"to_#{format}"))
+ end
+
+ it "should not escape Html" do
+ allow_any_instance_of(Commit).to receive(:"to_#{format}").
+ and_return('HTML entities &<>" ')
+
+ go(id: commit.id, format: format)
+
+ expect(response.body).not_to include('&amp;')
+ expect(response.body).not_to include('&gt;')
+ expect(response.body).not_to include('&lt;')
+ expect(response.body).not_to include('&quot;')
+ end
+ end
+
+ describe "as diff" do
+ include_examples "export as", :diff
+ let(:format) { :diff }
+
+ it "should really only be a git diff" do
+ go(id: commit.id, format: format)
+
+ expect(response.body).to start_with("diff --git")
+ end
+
+ it "should really only be a git diff without whitespace changes" do
+ go(id: '66eceea0db202bb39c4e445e8ca28689645366c5', format: format, w: 1)
+
+ expect(response.body).to start_with("diff --git")
+ # without whitespace option, there are more than 2 diff_splits
+ diff_splits = assigns(:diffs).first.diff.split("\n")
+ expect(diff_splits.length).to be <= 2
+ end
+ end
+
+ describe "as patch" do
+ include_examples "export as", :patch
+ let(:format) { :patch }
+
+ it "should really be a git email patch" do
+ go(id: commit.id, format: format)
+
+ expect(response.body).to start_with("From #{commit.id}")
+ end
+
+ it "should contain a git diff" do
+ go(id: commit.id, format: format)
+
+ expect(response.body).to match(/^diff --git/)
+ end
+ end
+
+ context 'commit that removes a submodule' do
+ render_views
+
+ let(:fork_project) { create(:forked_project_with_submodules, visibility_level: 20) }
+ let(:commit) { fork_project.commit('remove-submodule') }
+
+ it 'renders it' do
+ get(:show,
+ namespace_id: fork_project.namespace.to_param,
+ project_id: fork_project.to_param,
+ id: commit.id)
+
+ expect(response).to be_success
+ end
+ end
+ end
+
+ describe "GET branches" do
+ it "contains branch and tags information" do
+ get(:branches,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
- id: TestEnv::BRANCH_SHA['binary-encoding'],
- format: "html")
+ id: commit.id)
- expect(response).to be_success
+ expect(assigns(:branches)).to include("master", "feature_conflict")
+ expect(assigns(:tags)).to include("v1.1.0")
+ end
+ end
+
+ describe 'POST revert' do
+ context 'when target branch is not provided' do
+ it 'should render the 404 page' do
+ post(:revert,
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ id: commit.id)
+
+ expect(response).not_to be_success
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ context 'when the revert was successful' do
+ it 'should redirect to the commits page' do
+ post(:revert,
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ target_branch: 'master',
+ id: commit.id)
+
+ expect(response).to redirect_to namespace_project_commits_path(project.namespace, project, 'master')
+ expect(flash[:notice]).to eq('The commit has been successfully reverted.')
+ end
+ end
+
+ context 'when the revert failed' do
+ before do
+ post(:revert,
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ target_branch: 'master',
+ id: commit.id)
+ end
+
+ it 'should redirect to the commit page' do
+ # Reverting a commit that has been already reverted.
+ post(:revert,
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ target_branch: 'master',
+ id: commit.id)
+
+ expect(response).to redirect_to namespace_project_commit_path(project.namespace, project, commit.id)
+ expect(flash[:alert]).to match('Sorry, we cannot revert this commit automatically.')
+ end
+ end
+ end
+
+ describe 'POST cherry_pick' do
+ context 'when target branch is not provided' do
+ it 'should render the 404 page' do
+ post(:cherry_pick,
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ id: master_pickable_commit.id)
+
+ expect(response).not_to be_success
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ context 'when the cherry-pick was successful' do
+ it 'should redirect to the commits page' do
+ post(:cherry_pick,
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ target_branch: 'master',
+ id: master_pickable_commit.id)
+
+ expect(response).to redirect_to namespace_project_commits_path(project.namespace, project, 'master')
+ expect(flash[:notice]).to eq('The commit has been successfully cherry-picked.')
+ end
end
- def go(id:)
- get :show,
+ context 'when the cherry_pick failed' do
+ before do
+ post(:cherry_pick,
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ target_branch: 'master',
+ id: master_pickable_commit.id)
+ end
+
+ it 'should redirect to the commit page' do
+ # Cherry-picking a commit that has been already cherry-picked.
+ post(:cherry_pick,
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ target_branch: 'master',
+ id: master_pickable_commit.id)
+
+ expect(response).to redirect_to namespace_project_commit_path(project.namespace, project, master_pickable_commit.id)
+ expect(flash[:alert]).to match('Sorry, we cannot cherry-pick this commit automatically.')
+ end
+ end
+ end
+
+ describe 'GET diff_for_path' do
+ def diff_for_path(extra_params = {})
+ params = {
namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- id: id
+ project_id: project.to_param
+ }
+
+ get :diff_for_path, params.merge(extra_params)
+ end
+
+ let(:existing_path) { '.gitmodules' }
+
+ context 'when the commit exists' do
+ context 'when the user has access to the project' do
+ context 'when the path exists in the diff' do
+ it 'enables diff notes' do
+ diff_for_path(id: commit.id, old_path: existing_path, new_path: existing_path)
+
+ expect(assigns(:diff_notes_disabled)).to be_falsey
+ expect(assigns(:comments_target)).to eq(noteable_type: 'Commit',
+ commit_id: commit.id)
+ end
+
+ it 'only renders the diffs for the path given' do
+ expect(controller).to receive(:render_diff_for_path).and_wrap_original do |meth, diffs, diff_refs, project|
+ expect(diffs.map(&:new_path)).to contain_exactly(existing_path)
+ meth.call(diffs, diff_refs, project)
+ end
+
+ diff_for_path(id: commit.id, old_path: existing_path, new_path: existing_path)
+ end
+ end
+
+ context 'when the path does not exist in the diff' do
+ before { diff_for_path(id: commit.id, old_path: existing_path.succ, new_path: existing_path.succ) }
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ context 'when the user does not have access to the project' do
+ before do
+ project.team.truncate
+ diff_for_path(id: commit.id, old_path: existing_path, new_path: existing_path)
+ end
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ context 'when the commit does not exist' do
+ before { diff_for_path(id: commit.id.succ, old_path: existing_path, new_path: existing_path) }
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
end
end
end
diff --git a/spec/controllers/projects/compare_controller_spec.rb b/spec/controllers/projects/compare_controller_spec.rb
index 4018dac95a2..4058d5e2453 100644
--- a/spec/controllers/projects/compare_controller_spec.rb
+++ b/spec/controllers/projects/compare_controller_spec.rb
@@ -64,4 +64,73 @@ describe Projects::CompareController do
expect(assigns(:commits)).to eq(nil)
end
end
+
+ describe 'GET diff_for_path' do
+ def diff_for_path(extra_params = {})
+ params = {
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param
+ }
+
+ get :diff_for_path, params.merge(extra_params)
+ end
+
+ let(:existing_path) { 'files/ruby/feature.rb' }
+
+ context 'when the from and to refs exist' do
+ context 'when the user has access to the project' do
+ context 'when the path exists in the diff' do
+ it 'disables diff notes' do
+ diff_for_path(from: ref_from, to: ref_to, old_path: existing_path, new_path: existing_path)
+
+ expect(assigns(:diff_notes_disabled)).to be_truthy
+ end
+
+ it 'only renders the diffs for the path given' do
+ expect(controller).to receive(:render_diff_for_path).and_wrap_original do |meth, diffs, diff_refs, project|
+ expect(diffs.map(&:new_path)).to contain_exactly(existing_path)
+ meth.call(diffs, diff_refs, project)
+ end
+
+ diff_for_path(from: ref_from, to: ref_to, old_path: existing_path, new_path: existing_path)
+ end
+ end
+
+ context 'when the path does not exist in the diff' do
+ before { diff_for_path(from: ref_from, to: ref_to, old_path: existing_path.succ, new_path: existing_path.succ) }
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ context 'when the user does not have access to the project' do
+ before do
+ project.team.truncate
+ diff_for_path(from: ref_from, to: ref_to, old_path: existing_path, new_path: existing_path)
+ end
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ context 'when the from ref does not exist' do
+ before { diff_for_path(from: ref_from.succ, to: ref_to, old_path: existing_path, new_path: existing_path) }
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ context 'when the to ref does not exist' do
+ before { diff_for_path(from: ref_from, to: ref_to.succ, old_path: existing_path, new_path: existing_path) }
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
end
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index c4b57e77804..210085e3b1a 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -10,7 +10,7 @@ describe Projects::MergeRequestsController do
project.team << [user, :master]
end
- describe '#new' do
+ describe 'GET new' do
context 'merge request that removes a submodule' do
render_views
@@ -34,7 +34,7 @@ describe Projects::MergeRequestsController do
end
end
- describe "#show" do
+ describe "GET show" do
shared_examples "export merge as" do |format|
it "should generally work" do
get(:show,
@@ -108,7 +108,7 @@ describe Projects::MergeRequestsController do
end
end
- describe 'GET #index' do
+ describe 'GET index' do
def get_merge_requests
get :index,
namespace_id: project.namespace.to_param,
@@ -140,7 +140,7 @@ describe Projects::MergeRequestsController do
end
end
- describe 'PUT #update' do
+ describe 'PUT update' do
context 'there is no source project' do
let(:project) { create(:project) }
let(:fork_project) { create(:forked_project_with_submodules) }
@@ -168,7 +168,7 @@ describe Projects::MergeRequestsController do
end
end
- describe 'POST #merge' do
+ describe 'POST merge' do
let(:base_params) do
{
namespace_id: project.namespace.path,
@@ -266,7 +266,7 @@ describe Projects::MergeRequestsController do
end
end
- describe "DELETE #destroy" do
+ describe "DELETE destroy" do
it "denies access to users unless they're admin or project owner" do
delete :destroy, namespace_id: project.namespace.path, project_id: project.path, id: merge_request.iid
@@ -290,96 +290,210 @@ describe Projects::MergeRequestsController do
end
describe 'GET diffs' do
- def go(format: 'html')
- get :diffs,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- id: merge_request.iid,
- format: format
+ def go(extra_params = {})
+ params = {
+ namespace_id: project.namespace.to_param,
+ project_id: project.to_param,
+ id: merge_request.iid
+ }
+
+ get :diffs, params.merge(extra_params)
end
- context 'as html' do
- it 'renders the diff template' do
- go
+ context 'with default params' do
+ context 'as html' do
+ before { go(format: 'html') }
- expect(response).to render_template('diffs')
+ it 'renders the diff template' do
+ expect(response).to render_template('diffs')
+ end
end
- end
- context 'as json' do
- it 'renders the diffs template to a string' do
- go format: 'json'
+ context 'as json' do
+ before { go(format: 'json') }
- expect(response).to render_template('projects/merge_requests/show/_diffs')
- expect(JSON.parse(response.body)).to have_key('html')
+ it 'renders the diffs template to a string' do
+ expect(response).to render_template('projects/merge_requests/show/_diffs')
+ expect(JSON.parse(response.body)).to have_key('html')
+ end
end
- end
-
- context 'with forked projects with submodules' do
- render_views
- let(:project) { create(:project) }
- let(:fork_project) { create(:forked_project_with_submodules) }
- let(:merge_request) { create(:merge_request_with_diffs, source_project: fork_project, source_branch: 'add-submodule-version-bump', target_branch: 'master', target_project: project) }
+ context 'with forked projects with submodules' do
+ render_views
- before do
- fork_project.build_forked_project_link(forked_to_project_id: fork_project.id, forked_from_project_id: project.id)
- fork_project.save
- merge_request.reload
- end
+ let(:project) { create(:project) }
+ let(:fork_project) { create(:forked_project_with_submodules) }
+ let(:merge_request) { create(:merge_request_with_diffs, source_project: fork_project, source_branch: 'add-submodule-version-bump', target_branch: 'master', target_project: project) }
- it 'renders' do
- go format: 'json'
+ before do
+ fork_project.build_forked_project_link(forked_to_project_id: fork_project.id, forked_from_project_id: project.id)
+ fork_project.save
+ merge_request.reload
+ go(format: 'json')
+ end
- expect(response).to be_success
- expect(response.body).to have_content('Subproject commit')
+ it 'renders' do
+ expect(response).to be_success
+ expect(response.body).to have_content('Subproject commit')
+ end
end
end
- end
- describe 'GET diffs with ignore_whitespace_change' do
- def go(format: 'html')
- get :diffs,
- namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- id: merge_request.iid,
- format: format,
- w: 1
- end
+ context 'with ignore_whitespace_change' do
+ context 'as html' do
+ before { go(format: 'html', w: 1) }
- context 'as html' do
- it 'renders the diff template' do
- go
+ it 'renders the diff template' do
+ expect(response).to render_template('diffs')
+ end
+ end
+
+ context 'as json' do
+ before { go(format: 'json', w: 1) }
- expect(response).to render_template('diffs')
+ it 'renders the diffs template to a string' do
+ expect(response).to render_template('projects/merge_requests/show/_diffs')
+ expect(JSON.parse(response.body)).to have_key('html')
+ end
end
end
- context 'as json' do
- it 'renders the diffs template to a string' do
- go format: 'json'
+ context 'with view' do
+ before { go(view: 'parallel') }
- expect(response).to render_template('projects/merge_requests/show/_diffs')
- expect(JSON.parse(response.body)).to have_key('html')
+ it 'saves the preferred diff view in a cookie' do
+ expect(response.cookies['diff_view']).to eq('parallel')
end
end
end
- describe 'GET diffs with view' do
- def go(extra_params = {})
+ describe 'GET diff_for_path' do
+ def diff_for_path(extra_params = {})
params = {
namespace_id: project.namespace.to_param,
- project_id: project.to_param,
- id: merge_request.iid
+ project_id: project.to_param
}
- get :diffs, params.merge(extra_params)
+ get :diff_for_path, params.merge(extra_params)
end
- it 'saves the preferred diff view in a cookie' do
- go view: 'parallel'
+ context 'when an ID param is passed' do
+ let(:existing_path) { 'files/ruby/popen.rb' }
- expect(response.cookies['diff_view']).to eq('parallel')
+ context 'when the merge request exists' do
+ context 'when the user can view the merge request' do
+ context 'when the path exists in the diff' do
+ it 'enables diff notes' do
+ diff_for_path(id: merge_request.iid, old_path: existing_path, new_path: existing_path)
+
+ expect(assigns(:diff_notes_disabled)).to be_falsey
+ expect(assigns(:comments_target)).to eq(noteable_type: 'MergeRequest',
+ noteable_id: merge_request.id)
+ end
+
+ it 'only renders the diffs for the path given' do
+ expect(controller).to receive(:render_diff_for_path).and_wrap_original do |meth, diffs, diff_refs, project|
+ expect(diffs.map(&:new_path)).to contain_exactly(existing_path)
+ meth.call(diffs, diff_refs, project)
+ end
+
+ diff_for_path(id: merge_request.iid, old_path: existing_path, new_path: existing_path)
+ end
+ end
+
+ context 'when the path does not exist in the diff' do
+ before { diff_for_path(id: merge_request.iid, old_path: 'files/ruby/nopen.rb', new_path: 'files/ruby/nopen.rb') }
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ context 'when the user cannot view the merge request' do
+ before do
+ project.team.truncate
+ diff_for_path(id: merge_request.iid, old_path: existing_path, new_path: existing_path)
+ end
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ context 'when the merge request does not exist' do
+ before { diff_for_path(id: merge_request.iid.succ, old_path: existing_path, new_path: existing_path) }
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ context 'when the merge request belongs to a different project' do
+ let(:other_project) { create(:empty_project) }
+
+ before do
+ other_project.team << [user, :master]
+ diff_for_path(id: merge_request.iid, old_path: existing_path, new_path: existing_path, project_id: other_project.to_param)
+ end
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ context 'when source and target params are passed' do
+ let(:existing_path) { 'files/ruby/feature.rb' }
+
+ context 'when both branches are in the same project' do
+ it 'disables diff notes' do
+ diff_for_path(old_path: existing_path, new_path: existing_path, merge_request: { source_branch: 'feature', target_branch: 'master' })
+
+ expect(assigns(:diff_notes_disabled)).to be_truthy
+ end
+
+ it 'only renders the diffs for the path given' do
+ expect(controller).to receive(:render_diff_for_path).and_wrap_original do |meth, diffs, diff_refs, project|
+ expect(diffs.map(&:new_path)).to contain_exactly(existing_path)
+ meth.call(diffs, diff_refs, project)
+ end
+
+ diff_for_path(old_path: existing_path, new_path: existing_path, merge_request: { source_branch: 'feature', target_branch: 'master' })
+ end
+ end
+
+ context 'when the source branch is in a different project to the target' do
+ let(:other_project) { create(:project) }
+
+ before { other_project.team << [user, :master] }
+
+ context 'when the path exists in the diff' do
+ it 'disables diff notes' do
+ diff_for_path(old_path: existing_path, new_path: existing_path, merge_request: { source_project: other_project, source_branch: 'feature', target_branch: 'master' })
+
+ expect(assigns(:diff_notes_disabled)).to be_truthy
+ end
+
+ it 'only renders the diffs for the path given' do
+ expect(controller).to receive(:render_diff_for_path).and_wrap_original do |meth, diffs, diff_refs, project|
+ expect(diffs.map(&:new_path)).to contain_exactly(existing_path)
+ meth.call(diffs, diff_refs, project)
+ end
+
+ diff_for_path(old_path: existing_path, new_path: existing_path, merge_request: { source_project: other_project, source_branch: 'feature', target_branch: 'master' })
+ end
+ end
+
+ context 'when the path does not exist in the diff' do
+ before { diff_for_path(old_path: 'files/ruby/nopen.rb', new_path: 'files/ruby/nopen.rb', merge_request: { source_project: other_project, source_branch: 'feature', target_branch: 'master' }) }
+
+ it 'returns a 404' do
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
end
end
diff --git a/spec/controllers/projects/todo_controller_spec.rb b/spec/controllers/projects/todo_controller_spec.rb
index 5a8bba28594..936320a3709 100644
--- a/spec/controllers/projects/todo_controller_spec.rb
+++ b/spec/controllers/projects/todo_controller_spec.rb
@@ -1,6 +1,8 @@
require('spec_helper')
describe Projects::TodosController do
+ include ApiHelpers
+
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
@@ -8,43 +10,51 @@ describe Projects::TodosController do
context 'Issues' do
describe 'POST create' do
+ def go
+ post :create,
+ namespace_id: project.namespace.path,
+ project_id: project.path,
+ issuable_id: issue.id,
+ issuable_type: 'issue',
+ format: 'html'
+ end
+
context 'when authorized' do
before do
sign_in(user)
project.team << [user, :developer]
end
- it 'should create todo for issue' do
+ it 'creates todo for issue' do
expect do
- post(:create, namespace_id: project.namespace.path,
- project_id: project.path,
- issuable_id: issue.id,
- issuable_type: 'issue')
+ go
end.to change { user.todos.count }.by(1)
expect(response).to have_http_status(200)
end
+
+ it 'returns todo path and pending count' do
+ go
+
+ expect(response).to have_http_status(200)
+ expect(json_response['count']).to eq 1
+ expect(json_response['delete_path']).to match(/\/dashboard\/todos\/\d{1}/)
+ end
end
context 'when not authorized' do
- it 'should not create todo for issue that user has no access to' do
+ it 'does not create todo for issue that user has no access to' do
sign_in(user)
expect do
- post(:create, namespace_id: project.namespace.path,
- project_id: project.path,
- issuable_id: issue.id,
- issuable_type: 'issue')
+ go
end.to change { user.todos.count }.by(0)
expect(response).to have_http_status(404)
end
- it 'should not create todo for issue when user not logged in' do
+ it 'does not create todo for issue when user not logged in' do
expect do
- post(:create, namespace_id: project.namespace.path,
- project_id: project.path,
- issuable_id: issue.id,
- issuable_type: 'issue')
+ go
end.to change { user.todos.count }.by(0)
expect(response).to have_http_status(302)
@@ -55,43 +65,51 @@ describe Projects::TodosController do
context 'Merge Requests' do
describe 'POST create' do
+ def go
+ post :create,
+ namespace_id: project.namespace.path,
+ project_id: project.path,
+ issuable_id: merge_request.id,
+ issuable_type: 'merge_request',
+ format: 'html'
+ end
+
context 'when authorized' do
before do
sign_in(user)
project.team << [user, :developer]
end
- it 'should create todo for merge request' do
+ it 'creates todo for merge request' do
expect do
- post(:create, namespace_id: project.namespace.path,
- project_id: project.path,
- issuable_id: merge_request.id,
- issuable_type: 'merge_request')
+ go
end.to change { user.todos.count }.by(1)
expect(response).to have_http_status(200)
end
+
+ it 'returns todo path and pending count' do
+ go
+
+ expect(response).to have_http_status(200)
+ expect(json_response['count']).to eq 1
+ expect(json_response['delete_path']).to match(/\/dashboard\/todos\/\d{1}/)
+ end
end
context 'when not authorized' do
- it 'should not create todo for merge request user has no access to' do
+ it 'does not create todo for merge request user has no access to' do
sign_in(user)
expect do
- post(:create, namespace_id: project.namespace.path,
- project_id: project.path,
- issuable_id: merge_request.id,
- issuable_type: 'merge_request')
+ go
end.to change { user.todos.count }.by(0)
expect(response).to have_http_status(404)
end
- it 'should not create todo for merge request user has no access to' do
+ it 'does not create todo for merge request user has no access to' do
expect do
- post(:create, namespace_id: project.namespace.path,
- project_id: project.path,
- issuable_id: merge_request.id,
- issuable_type: 'merge_request')
+ go
end.to change { user.todos.count }.by(0)
expect(response).to have_http_status(302)
diff --git a/spec/factories/todos.rb b/spec/factories/todos.rb
index 7fc20cd5555..866e663f026 100644
--- a/spec/factories/todos.rb
+++ b/spec/factories/todos.rb
@@ -23,6 +23,10 @@ FactoryGirl.define do
action { Todo::BUILD_FAILED }
end
+ trait :approval_required do
+ action { Todo::APPROVAL_REQUIRED }
+ end
+
trait :done do
state :done
end
diff --git a/spec/features/expand_collapse_diffs_spec.rb b/spec/features/expand_collapse_diffs_spec.rb
new file mode 100644
index 00000000000..78bc888f2a6
--- /dev/null
+++ b/spec/features/expand_collapse_diffs_spec.rb
@@ -0,0 +1,207 @@
+require 'spec_helper'
+
+feature 'Expand and collapse diffs', js: true, feature: true do
+ include WaitForAjax
+
+ before do
+ login_as :admin
+ project = create(:project)
+ branch = 'expand-collapse-diffs'
+
+ # Ensure that undiffable.md is in .gitattributes
+ project.repository.copy_gitattributes(branch)
+ visit namespace_project_commit_path(project.namespace, project, project.commit(branch))
+ execute_script('window.ajaxUris = []; $(document).ajaxSend(function(event, xhr, settings) { ajaxUris.push(settings.url) });')
+ end
+
+ def file_container(filename)
+ find("[data-blob-diff-path*='#{filename}']")
+ end
+
+ # Use define_method instead of let (which is memoized) so that this just works across a
+ # reload.
+ #
+ files = [
+ 'small_diff.md', 'large_diff.md', 'large_diff_renamed.md', 'undiffable.md',
+ 'too_large.md', 'too_large_image.jpg'
+ ]
+
+ files.each do |file|
+ define_method(file.split('.').first) { file_container(file) }
+ end
+
+ context 'visiting a commit with collapsed diffs' do
+ it 'shows small diffs immediately' do
+ expect(small_diff).to have_selector('.code')
+ expect(small_diff).not_to have_selector('.nothing-here-block')
+ end
+
+ it 'collapses large diffs by default' do
+ expect(large_diff).not_to have_selector('.code')
+ expect(large_diff).to have_selector('.nothing-here-block')
+ end
+
+ it 'collapses large diffs for renamed files by default' do
+ expect(large_diff_renamed).not_to have_selector('.code')
+ expect(large_diff_renamed).to have_selector('.nothing-here-block')
+ expect(large_diff_renamed).to have_selector('.file-title .deletion')
+ expect(large_diff_renamed).to have_selector('.file-title .addition')
+ end
+
+ it 'shows non-renderable diffs as such immediately, regardless of their size' do
+ expect(undiffable).not_to have_selector('.code')
+ expect(undiffable).to have_selector('.nothing-here-block')
+ expect(undiffable).to have_content('gitattributes')
+ end
+
+ it 'does not allow diffs that are larger than the maximum size to be expanded' do
+ expect(too_large).not_to have_selector('.code')
+ expect(too_large).to have_selector('.nothing-here-block')
+ expect(too_large).to have_content('too large')
+ end
+
+ it 'shows image diffs immediately, regardless of their size' do
+ expect(too_large_image).not_to have_selector('.nothing-here-block')
+ expect(too_large_image).to have_selector('.image')
+ end
+
+ context 'expanding a diff for a renamed file' do
+ before do
+ large_diff_renamed.find('.nothing-here-block').click
+ wait_for_ajax
+ end
+
+ it 'shows the old content' do
+ old_line = large_diff_renamed.find('.line_content.old')
+
+ expect(old_line).to have_content('two copies')
+ end
+
+ it 'shows the new content' do
+ new_line = large_diff_renamed.find('.line_content.new', match: :prefer_exact)
+
+ expect(new_line).to have_content('three copies')
+ end
+ end
+
+ context 'expanding a large diff' do
+ before do
+ click_link('large_diff.md')
+ wait_for_ajax
+ end
+
+ it 'makes a request to get the content' do
+ ajax_uris = evaluate_script('ajaxUris')
+
+ expect(ajax_uris).not_to be_empty
+ expect(ajax_uris.first).to include('large_diff.md')
+ end
+
+ it 'shows the diff content' do
+ expect(large_diff).to have_selector('.code')
+ expect(large_diff).not_to have_selector('.nothing-here-block')
+ end
+
+ context 'adding a comment to the expanded diff' do
+ let(:comment_text) { 'A comment' }
+
+ before do
+ large_diff.find('.diff-line-num', match: :prefer_exact).hover
+ large_diff.find('.add-diff-note').click
+ large_diff.find('.note-textarea').send_keys comment_text
+ large_diff.find_button('Comment').click
+ wait_for_ajax
+ end
+
+ it 'adds the comment' do
+ expect(large_diff.find('.notes')).to have_content comment_text
+ end
+
+ context 'reloading the page' do
+ before { refresh }
+
+ it 'collapses the large diff by default' do
+ expect(large_diff).not_to have_selector('.code')
+ expect(large_diff).to have_selector('.nothing-here-block')
+ end
+
+ context 'expanding the diff' do
+ before do
+ click_link('large_diff.md')
+ wait_for_ajax
+ end
+
+ it 'shows the diff content' do
+ expect(large_diff).to have_selector('.code')
+ expect(large_diff).not_to have_selector('.nothing-here-block')
+ end
+
+ it 'shows the diff comment' do
+ expect(large_diff.find('.notes')).to have_content comment_text
+ end
+ end
+ end
+ end
+ end
+
+ context 'collapsing an expanded diff' do
+ before { click_link('small_diff.md') }
+
+ it 'hides the diff content' do
+ expect(small_diff).not_to have_selector('.code')
+ expect(small_diff).to have_selector('.nothing-here-block')
+ end
+
+ context 're-expanding the same diff' do
+ before { click_link('small_diff.md') }
+
+ it 'shows the diff content' do
+ expect(small_diff).to have_selector('.code')
+ expect(small_diff).not_to have_selector('.nothing-here-block')
+ end
+
+ it 'does not make a new HTTP request' do
+ expect(evaluate_script('ajaxUris')).not_to include(a_string_matching('small_diff.md'))
+ end
+ end
+ end
+ end
+
+ context 'expanding all diffs' do
+ before do
+ click_link('Expand all')
+ wait_for_ajax
+ execute_script('window.ajaxUris = []; $(document).ajaxSend(function(event, xhr, settings) { ajaxUris.push(settings.url) });')
+ end
+
+ it 'reloads the page with all diffs expanded' do
+ expect(small_diff).to have_selector('.code')
+ expect(small_diff).not_to have_selector('.nothing-here-block')
+
+ expect(large_diff).to have_selector('.code')
+ expect(large_diff).not_to have_selector('.nothing-here-block')
+ end
+
+ context 'collapsing an expanded diff' do
+ before { click_link('small_diff.md') }
+
+ it 'hides the diff content' do
+ expect(small_diff).not_to have_selector('.code')
+ expect(small_diff).to have_selector('.nothing-here-block')
+ end
+
+ context 're-expanding the same diff' do
+ before { click_link('small_diff.md') }
+
+ it 'shows the diff content' do
+ expect(small_diff).to have_selector('.code')
+ expect(small_diff).not_to have_selector('.nothing-here-block')
+ end
+
+ it 'does not make a new HTTP request' do
+ expect(evaluate_script('ajaxUris')).not_to include(a_string_matching('small_diff.md'))
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/help_pages_spec.rb b/spec/features/help_pages_spec.rb
index 8c6b669ce78..1e2306d7f59 100644
--- a/spec/features/help_pages_spec.rb
+++ b/spec/features/help_pages_spec.rb
@@ -6,7 +6,7 @@ describe 'Help Pages', feature: true do
login_as :user
end
it 'replace the variable $your_email with the email of the user' do
- visit help_page_path('ssh', 'README')
+ visit help_page_path('ssh/README')
expect(page).to have_content("ssh-keygen -t rsa -C \"#{@user.email}\"")
end
end
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index d51c9abea19..cfe6349a1a1 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -121,6 +121,17 @@ describe 'Issues', feature: true do
expect(page).to have_content date.to_s(:medium)
end
end
+
+ it 'warns about version conflict' do
+ issue.update(title: "New title")
+
+ fill_in 'issue_title', with: 'bug 345'
+ fill_in 'issue_description', with: 'bug description'
+
+ click_button 'Save changes'
+
+ expect(page).to have_content 'Someone edited the issue the same time you did'
+ end
end
end
diff --git a/spec/features/login_spec.rb b/spec/features/login_spec.rb
index 72b5ff231f7..58753ff21f6 100644
--- a/spec/features/login_spec.rb
+++ b/spec/features/login_spec.rb
@@ -28,6 +28,11 @@ feature 'Login', feature: true do
end
describe 'with two-factor authentication' do
+ def enter_code(code)
+ fill_in 'Two-Factor Authentication code', with: code
+ click_button 'Verify code'
+ end
+
context 'with valid username/password' do
let(:user) { create(:user, :two_factor) }
@@ -36,11 +41,6 @@ feature 'Login', feature: true do
expect(page).to have_content('Two-Factor Authentication')
end
- def enter_code(code)
- fill_in 'Two-Factor Authentication code', with: code
- click_button 'Verify code'
- end
-
it 'does not show a "You are already signed in." error message' do
enter_code(user.current_otp)
expect(page).not_to have_content('You are already signed in.')
@@ -108,6 +108,39 @@ feature 'Login', feature: true do
end
end
end
+
+ context 'logging in via OAuth' do
+ def saml_config
+ OpenStruct.new(name: 'saml', label: 'saml', args: {
+ assertion_consumer_service_url: 'https://localhost:3443/users/auth/saml/callback',
+ idp_cert_fingerprint: '26:43:2C:47:AF:F0:6B:D0:07:9C:AD:A3:74:FE:5D:94:5F:4E:9E:52',
+ idp_sso_target_url: 'https://idp.example.com/sso/saml',
+ issuer: 'https://localhost:3443/',
+ name_identifier_format: 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'
+ })
+ end
+
+ def stub_omniauth_config(messages)
+ Rails.application.env_config['devise.mapping'] = Devise.mappings[:user]
+ Rails.application.routes.disable_clear_and_finalize = true
+ Rails.application.routes.draw do
+ post '/users/auth/saml' => 'omniauth_callbacks#saml'
+ end
+ allow(Gitlab::OAuth::Provider).to receive_messages(providers: [:saml], config_for: saml_config)
+ allow(Gitlab.config.omniauth).to receive_messages(messages)
+ allow_any_instance_of(Object).to receive(:user_omniauth_authorize_path).with('saml').and_return('/users/auth/saml')
+ end
+
+ it 'should show 2FA prompt after OAuth login' do
+ stub_omniauth_config(enabled: true, auto_link_saml_user: true, allow_single_sign_on: ['saml'], providers: [saml_config])
+ user = create(:omniauth_user, :two_factor, extern_uid: 'my-uid', provider: 'saml')
+ login_via('saml', user, 'my-uid')
+
+ expect(page).to have_content('Two-Factor Authentication')
+ enter_code(user.current_otp)
+ expect(current_path).to eq root_path
+ end
+ end
end
describe 'without two-factor authentication' do
diff --git a/spec/features/merge_requests/diffs_spec.rb b/spec/features/merge_requests/diffs_spec.rb
new file mode 100644
index 00000000000..c9a0059645d
--- /dev/null
+++ b/spec/features/merge_requests/diffs_spec.rb
@@ -0,0 +1,25 @@
+require 'spec_helper'
+
+feature 'Diffs URL', js: true, feature: true do
+ before do
+ login_as :admin
+ @merge_request = create(:merge_request)
+ @project = @merge_request.source_project
+ end
+
+ context 'when visit with */* as accept header' do
+ before(:each) do
+ page.driver.add_header('Accept', '*/*')
+ end
+
+ it 'renders the notes' do
+ create :note_on_merge_request, project: @project, noteable: @merge_request, note: 'Rebasing with master'
+
+ visit diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)
+
+ # Load notes and diff through AJAX
+ expect(page).to have_css('.note-text', visible: false, text: 'Rebasing with master')
+ expect(page).to have_css('.diffs.tab-pane.active')
+ end
+ end
+end
diff --git a/spec/features/merge_requests/edit_mr_spec.rb b/spec/features/merge_requests/edit_mr_spec.rb
index 9e007ab7635..8ad884492d1 100644
--- a/spec/features/merge_requests/edit_mr_spec.rb
+++ b/spec/features/merge_requests/edit_mr_spec.rb
@@ -17,5 +17,16 @@ feature 'Edit Merge Request', feature: true do
it 'form should have class js-quick-submit' do
expect(page).to have_selector('.js-quick-submit')
end
+
+ it 'warns about version conflict' do
+ merge_request.update(title: "New title")
+
+ fill_in 'merge_request_title', with: 'bug 345'
+ fill_in 'merge_request_description', with: 'bug description'
+
+ click_button 'Save changes'
+
+ expect(page).to have_content 'Someone edited the merge request the same time you did'
+ end
end
end
diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb
index 5174168713c..0b38c413f44 100644
--- a/spec/features/notes_on_merge_requests_spec.rb
+++ b/spec/features/notes_on_merge_requests_spec.rb
@@ -135,6 +135,28 @@ describe 'Comments', feature: true do
end
end
+ describe 'Handles cross-project system notes', js: true, feature: true do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :public) }
+ let(:project2) { create(:project, :private) }
+ let(:issue) { create(:issue, project: project2) }
+ let(:merge_request) { create(:merge_request, source_project: project, source_branch: 'markdown') }
+ let!(:note) { create(:note_on_merge_request, :system, noteable: merge_request, project: project, note: "mentioned in #{issue.to_reference(project)}") }
+
+ it 'shows the system note' do
+ login_as :admin
+ visit namespace_project_merge_request_path(project.namespace, project, merge_request)
+
+ expect(page).to have_css('.system-note')
+ end
+
+ it 'hides redacted system note' do
+ visit namespace_project_merge_request_path(project.namespace, project, merge_request)
+
+ expect(page).not_to have_css('.system-note')
+ end
+ end
+
describe 'On a merge request diff', js: true, feature: true do
let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.source_project }
@@ -231,6 +253,7 @@ describe 'Comments', feature: true do
end
def click_diff_line(data = line_code)
- execute_script("$('button[data-line-code=\"#{data}\"]').click()")
+ find(".line_holder[id='#{data}'] td.line_content").hover
+ find(".line_holder[id='#{data}'] button").trigger('click')
end
end
diff --git a/spec/features/projects/labels/update_prioritization_spec.rb b/spec/features/projects/labels/update_prioritization_spec.rb
index 6a39c302f55..98ba93b4036 100644
--- a/spec/features/projects/labels/update_prioritization_spec.rb
+++ b/spec/features/projects/labels/update_prioritization_spec.rb
@@ -76,7 +76,7 @@ feature 'Prioritize labels', feature: true do
expect(page.all('li').last).to have_content('bug')
end
- visit current_url
+ refresh
wait_for_ajax
page.within('.prioritized-labels') do
diff --git a/spec/finders/notes_finder_spec.rb b/spec/finders/notes_finder_spec.rb
index 1bd354815e4..8db897b1646 100644
--- a/spec/finders/notes_finder_spec.rb
+++ b/spec/finders/notes_finder_spec.rb
@@ -11,7 +11,7 @@ describe NotesFinder do
project.team << [user, :master]
end
- describe :execute do
+ describe '#execute' do
let(:params) { { target_id: commit.id, target_type: 'commit', last_fetched_at: 1.hour.ago.to_i } }
before do
diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb
index e2db33d8345..4b134a48410 100644
--- a/spec/helpers/diff_helper_spec.rb
+++ b/spec/helpers/diff_helper_spec.rb
@@ -31,26 +31,11 @@ describe DiffHelper do
end
end
- describe 'diff_hard_limit_enabled?' do
- it 'should return true if param is provided' do
- allow(controller).to receive(:params) { { force_show_diff: true } }
- expect(diff_hard_limit_enabled?).to be_truthy
- end
-
- it 'should return false if param is not provided' do
- expect(diff_hard_limit_enabled?).to be_falsey
- end
- end
-
describe 'diff_options' do
- it 'should return hard limit for a diff if force diff is true' do
+ it 'should return hard limit for a diff' do
allow(controller).to receive(:params) { { force_show_diff: true } }
expect(diff_options).to include(Commit.max_diff_options)
end
-
- it 'should return safe limit for a diff if force diff is false' do
- expect(diff_options).not_to include(:max_lines, :max_files)
- end
end
describe 'unfold_bottom_class' do
@@ -59,7 +44,7 @@ describe DiffHelper do
end
it 'should return js class when bottom lines should be unfolded' do
- expect(unfold_bottom_class(true)).to eq('js-unfold-bottom')
+ expect(unfold_bottom_class(true)).to include('js-unfold-bottom')
end
end
diff --git a/spec/javascripts/fixtures/issues_show.html.haml b/spec/javascripts/fixtures/issues_show.html.haml
index 470cabeafbb..06c2ab1e823 100644
--- a/spec/javascripts/fixtures/issues_show.html.haml
+++ b/spec/javascripts/fixtures/issues_show.html.haml
@@ -1,7 +1,7 @@
:css
.hidden { display: none !important; }
-.flash-container
+.flash-container.flash-container-page
.flash-alert
.flash-notice
diff --git a/spec/lib/banzai/object_renderer_spec.rb b/spec/lib/banzai/object_renderer_spec.rb
index 44256b32bdc..bcdb95250ca 100644
--- a/spec/lib/banzai/object_renderer_spec.rb
+++ b/spec/lib/banzai/object_renderer_spec.rb
@@ -17,6 +17,7 @@ describe Banzai::ObjectRenderer do
and_call_original
expect(object).to receive(:note_html=).with('<p>hello</p>')
+ expect(object).to receive(:user_visible_reference_count=).with(0)
renderer.render([object], :note)
end
@@ -25,9 +26,10 @@ describe Banzai::ObjectRenderer do
describe '#render_objects' do
it 'renders an Array of objects' do
object = double(:object, note: 'hello')
+
renderer = described_class.new(project, user)
- expect(renderer).to receive(:render_attribute).with(object, :note).
+ expect(renderer).to receive(:render_attributes).with([object], :note).
and_call_original
rendered = renderer.render_objects([object], :note)
@@ -38,7 +40,7 @@ describe Banzai::ObjectRenderer do
end
describe '#redact_documents' do
- it 'redacts a set of documents and returns them as an Array of Strings' do
+ it 'redacts a set of documents and returns them as an Array of Hashes' do
doc = Nokogiri::HTML.fragment('<p>hello</p>')
renderer = described_class.new(project, user)
@@ -48,7 +50,9 @@ describe Banzai::ObjectRenderer do
redacted = renderer.redact_documents([doc])
- expect(redacted).to eq(['<p>hello</p>'])
+ expect(redacted.count).to eq(1)
+ expect(redacted.first[:visible_reference_count]).to eq(0)
+ expect(redacted.first[:document].to_html).to eq('<p>hello</p>')
end
end
@@ -85,14 +89,36 @@ describe Banzai::ObjectRenderer do
end
end
- describe '#render_attribute' do
- it 'renders the attribute of an object' do
- object = double(:doc, note: 'hello')
+ describe '#render_attributes' do
+ it 'renders the attribute of a list of objects' do
+ objects = [double(:doc, note: 'hello'), double(:doc, note: 'bye')]
renderer = described_class.new(project, user, pipeline: :note)
- doc = renderer.render_attribute(object, :note)
- expect(doc).to be_an_instance_of(Nokogiri::HTML::DocumentFragment)
- expect(doc.to_html).to eq('<p>hello</p>')
+ expect(Banzai).to receive(:cache_collection_render).
+ with([
+ { text: 'hello', context: renderer.context_for(objects[0], :note) },
+ { text: 'bye', context: renderer.context_for(objects[1], :note) }
+ ]).
+ and_call_original
+
+ docs = renderer.render_attributes(objects, :note)
+
+ expect(docs[0]).to be_an_instance_of(Nokogiri::HTML::DocumentFragment)
+ expect(docs[0].to_html).to eq('<p>hello</p>')
+
+ expect(docs[1]).to be_an_instance_of(Nokogiri::HTML::DocumentFragment)
+ expect(docs[1].to_html).to eq('<p>bye</p>')
+ end
+
+ it 'returns when no objects to render' do
+ objects = []
+ renderer = described_class.new(project, user, pipeline: :note)
+
+ expect(Banzai).to receive(:cache_collection_render).
+ with([]).
+ and_call_original
+
+ expect(renderer.render_attributes(objects, :note)).to eq([])
end
end
diff --git a/spec/lib/banzai/redactor_spec.rb b/spec/lib/banzai/redactor_spec.rb
index 488f465bcda..254657a881d 100644
--- a/spec/lib/banzai/redactor_spec.rb
+++ b/spec/lib/banzai/redactor_spec.rb
@@ -15,11 +15,31 @@ describe Banzai::Redactor do
expect(redactor).to receive(:nodes_visible_to_user).and_return([])
- expect(redactor.redact([doc1, doc2])).to eq([doc1, doc2])
+ redacted_data = redactor.redact([doc1, doc2])
+ expect(redacted_data.map { |data| data[:document] }).to eq([doc1, doc2])
+ expect(redacted_data.map { |data| data[:visible_reference_count] }).to eq([0, 0])
expect(doc1.to_html).to eq('foo')
expect(doc2.to_html).to eq('bar')
end
+
+ it 'does not redact an Array of documents' do
+ doc1_html = '<a class="gfm" data-reference-type="issue">foo</a>'
+ doc1 = Nokogiri::HTML.fragment(doc1_html)
+
+ doc2_html = '<a class="gfm" data-reference-type="issue">bar</a>'
+ doc2 = Nokogiri::HTML.fragment(doc2_html)
+
+ nodes = redactor.document_nodes([doc1, doc2]).map { |x| x[:nodes] }
+ expect(redactor).to receive(:nodes_visible_to_user).and_return(nodes.flatten)
+
+ redacted_data = redactor.redact([doc1, doc2])
+
+ expect(redacted_data.map { |data| data[:document] }).to eq([doc1, doc2])
+ expect(redacted_data.map { |data| data[:visible_reference_count] }).to eq([1, 1])
+ expect(doc1.to_html).to eq(doc1_html)
+ expect(doc2.to_html).to eq(doc2_html)
+ end
end
describe '#redact_nodes' do
@@ -31,7 +51,7 @@ describe Banzai::Redactor do
with([node]).
and_return(Set.new)
- redactor.redact_nodes([node])
+ redactor.redact_document_nodes([{ document: doc, nodes: [node] }])
expect(doc.to_html).to eq('foo')
end
diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
index bad439bc489..bcbf409c8b0 100644
--- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
+++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb
@@ -31,7 +31,7 @@ module Ci
})
end
- describe :only do
+ describe 'only' do
it "does not return builds if only has another branch" do
config = YAML.dump({
before_script: ["pwd"],
@@ -187,7 +187,7 @@ module Ci
end
end
- describe :except do
+ describe 'except' do
it "returns builds if except has another branch" do
config = YAML.dump({
before_script: ["pwd"],
diff --git a/spec/lib/gitlab/build_data_builder_spec.rb b/spec/lib/gitlab/build_data_builder_spec.rb
index 38be9448794..23ae5cfacc4 100644
--- a/spec/lib/gitlab/build_data_builder_spec.rb
+++ b/spec/lib/gitlab/build_data_builder_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe 'Gitlab::BuildDataBuilder' do
let(:build) { create(:ci_build) }
- describe :build do
+ describe '.build' do
let(:data) do
Gitlab::BuildDataBuilder.build(build)
end
diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb
index 1cb513d5229..0460dcf4658 100644
--- a/spec/lib/gitlab/diff/file_spec.rb
+++ b/spec/lib/gitlab/diff/file_spec.rb
@@ -8,14 +8,14 @@ describe Gitlab::Diff::File, lib: true do
let(:diff) { commit.diffs.first }
let(:diff_file) { Gitlab::Diff::File.new(diff, diff_refs: commit.diff_refs, repository: project.repository) }
- describe :diff_lines do
+ describe '#diff_lines' do
let(:diff_lines) { diff_file.diff_lines }
it { expect(diff_lines.size).to eq(30) }
it { expect(diff_lines.first).to be_kind_of(Gitlab::Diff::Line) }
end
- describe :mode_changed? do
+ describe '#mode_changed?' do
it { expect(diff_file.mode_changed?).to be_falsey }
end
diff --git a/spec/lib/gitlab/diff/inline_diff_spec.rb b/spec/lib/gitlab/diff/inline_diff_spec.rb
index 95a993d26cf..8ca3f73509e 100644
--- a/spec/lib/gitlab/diff/inline_diff_spec.rb
+++ b/spec/lib/gitlab/diff/inline_diff_spec.rb
@@ -3,14 +3,19 @@ require 'spec_helper'
describe Gitlab::Diff::InlineDiff, lib: true do
describe '.for_lines' do
let(:diff) do
- <<eos
- class Test
-- def initialize(test = true)
-+ def initialize(test = false)
- @test = test
- end
- end
-eos
+ <<-EOF.strip_heredoc
+ class Test
+ - def initialize(test = true)
+ + def initialize(test = false)
+ @test = test
+ - if true
+ - @foo = "bar"
+ + unless false
+ + @foo = "baz"
+ end
+ end
+ end
+ EOF
end
let(:subject) { described_class.for_lines(diff.lines) }
@@ -20,8 +25,11 @@ eos
expect(subject[1]).to eq([25..27])
expect(subject[2]).to eq([25..28])
expect(subject[3]).to be_nil
- expect(subject[4]).to be_nil
- expect(subject[5]).to be_nil
+ expect(subject[4]).to eq([5..10])
+ expect(subject[5]).to eq([17..17])
+ expect(subject[6]).to eq([5..15])
+ expect(subject[7]).to eq([17..17])
+ expect(subject[8]).to be_nil
end
end
diff --git a/spec/lib/gitlab/diff/parser_spec.rb b/spec/lib/gitlab/diff/parser_spec.rb
index cdff063a9ed..c3359627652 100644
--- a/spec/lib/gitlab/diff/parser_spec.rb
+++ b/spec/lib/gitlab/diff/parser_spec.rb
@@ -8,7 +8,7 @@ describe Gitlab::Diff::Parser, lib: true do
let(:diff) { commit.diffs.first }
let(:parser) { Gitlab::Diff::Parser.new }
- describe :parse do
+ describe '#parse' do
let(:diff) do
<<eos
--- a/files/ruby/popen.rb
diff --git a/spec/lib/gitlab/diff/position_tracer_spec.rb b/spec/lib/gitlab/diff/position_tracer_spec.rb
index 08312e60f4a..c268f84c759 100644
--- a/spec/lib/gitlab/diff/position_tracer_spec.rb
+++ b/spec/lib/gitlab/diff/position_tracer_spec.rb
@@ -1639,7 +1639,8 @@ describe Gitlab::Diff::PositionTracer, lib: true do
committer: committer
}
- repository.merge(current_user, second_create_file_commit.sha, branch_name, options)
+ merge_request = create(:merge_request, source_branch: second_create_file_commit.sha, target_branch: branch_name, source_project: project)
+ repository.merge(current_user, merge_request, options)
project.commit(branch_name)
end
diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb
index c79ba11f782..db33c7a22bb 100644
--- a/spec/lib/gitlab/git_access_spec.rb
+++ b/spec/lib/gitlab/git_access_spec.rb
@@ -6,67 +6,6 @@ describe Gitlab::GitAccess, lib: true do
let(:user) { create(:user) }
let(:actor) { user }
- 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]
- 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]
- 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]
- expect(access.can_push_to_branch?("random_branch")).to be_falsey
- end
- end
-
- describe 'push to protected branch' do
- before do
- @branch = create :protected_branch, project: project
- end
-
- it "returns true if user is a master" do
- project.team << [user, :master]
- 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]
- 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]
- expect(access.can_push_to_branch?(@branch.name)).to be_falsey
- end
- end
-
- describe 'push to protected branch if allowed for developers' do
- before do
- @branch = create :protected_branch, project: project, developers_can_push: true
- end
-
- it "returns true if user is a master" do
- project.team << [user, :master]
- 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]
- 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]
- expect(access.can_push_to_branch?(@branch.name)).to be_falsey
- end
- end
- end
-
describe '#check with single protocols allowed' do
def disable_protocol(protocol)
settings = ::ApplicationSetting.create_from_defaults
@@ -160,96 +99,46 @@ describe Gitlab::GitAccess, lib: true do
end
describe 'push_access_check' do
- def protect_feature_branch
- create(:protected_branch, name: 'feature', project: project)
- end
+ before { merge_into_protected_branch }
+ let(:unprotected_branch) { FFaker::Internet.user_name }
- def changes
- {
- push_new_branch: "#{Gitlab::Git::BLANK_SHA} 570e7b2ab refs/heads/wow",
+ let(:changes) do
+ { push_new_branch: "#{Gitlab::Git::BLANK_SHA} 570e7b2ab refs/heads/wow",
push_master: '6f6d7e7ed 570e7b2ab refs/heads/master',
push_protected_branch: '6f6d7e7ed 570e7b2ab refs/heads/feature',
push_remove_protected_branch: "570e7b2ab #{Gitlab::Git::BLANK_SHA} "\
'refs/heads/feature',
push_tag: '6f6d7e7ed 570e7b2ab refs/tags/v1.0.0',
push_new_tag: "#{Gitlab::Git::BLANK_SHA} 570e7b2ab refs/tags/v7.8.9",
- push_all: ['6f6d7e7ed 570e7b2ab refs/heads/master', '6f6d7e7ed 570e7b2ab refs/heads/feature']
- }
+ push_all: ['6f6d7e7ed 570e7b2ab refs/heads/master', '6f6d7e7ed 570e7b2ab refs/heads/feature'],
+ merge_into_protected_branch: "0b4bc9a #{merge_into_protected_branch} refs/heads/feature" }
end
- def self.permissions_matrix
- {
- master: {
- push_new_branch: true,
- push_master: true,
- push_protected_branch: true,
- push_remove_protected_branch: false,
- push_tag: true,
- push_new_tag: true,
- push_all: true,
- },
-
- developer: {
- push_new_branch: true,
- push_master: true,
- push_protected_branch: false,
- push_remove_protected_branch: false,
- push_tag: false,
- push_new_tag: true,
- push_all: false,
- },
-
- reporter: {
- push_new_branch: false,
- push_master: false,
- push_protected_branch: false,
- push_remove_protected_branch: false,
- push_tag: false,
- push_new_tag: false,
- push_all: false,
- },
-
- guest: {
- push_new_branch: false,
- push_master: false,
- push_protected_branch: false,
- push_remove_protected_branch: false,
- push_tag: false,
- push_new_tag: false,
- push_all: false,
- }
- }
- end
-
- def self.updated_permissions_matrix
- updated_permissions_matrix = permissions_matrix.dup
- updated_permissions_matrix[:developer][:push_protected_branch] = true
- updated_permissions_matrix[:developer][:push_all] = true
- updated_permissions_matrix
+ def stub_git_hooks
+ # Running the `pre-receive` hook is expensive, and not necessary for this test.
+ allow_any_instance_of(GitHooksService).to receive(:execute).and_yield
end
- permissions_matrix.keys.each do |role|
- describe "#{role} access" do
- before { protect_feature_branch }
- before { project.team << [user, role] }
-
- permissions_matrix[role].each do |action, allowed|
- context action do
- subject { access.push_access_check(changes[action]) }
+ def merge_into_protected_branch
+ @protected_branch_merge_commit ||= begin
+ stub_git_hooks
+ project.repository.add_branch(user, unprotected_branch, 'feature')
+ target_branch = project.repository.lookup('feature')
+ source_branch = project.repository.commit_file(user, FFaker::InternetSE.login_user_name, FFaker::HipsterIpsum.paragraph, FFaker::HipsterIpsum.sentence, unprotected_branch, false)
+ rugged = project.repository.rugged
+ author = { email: "email@example.com", time: Time.now, name: "Example Git User" }
- it { expect(subject.allowed?).to allowed ? be_truthy : be_falsey }
- end
- end
+ merge_index = rugged.merge_commits(target_branch, source_branch)
+ Rugged::Commit.create(rugged, author: author, committer: author, message: "commit message", parents: [target_branch, source_branch], tree: merge_index.write_tree(rugged))
end
end
- context "with enabled developers push to protected branches " do
- updated_permissions_matrix.keys.each do |role|
+ def self.run_permission_checks(permissions_matrix)
+ permissions_matrix.keys.each do |role|
describe "#{role} access" do
- before { create(:protected_branch, name: 'feature', developers_can_push: true, project: project) }
before { project.team << [user, role] }
- updated_permissions_matrix[role].each do |action, allowed|
+ permissions_matrix[role].each do |action, allowed|
context action do
subject { access.push_access_check(changes[action]) }
@@ -259,5 +148,97 @@ describe Gitlab::GitAccess, lib: true do
end
end
end
+
+ permissions_matrix = {
+ master: {
+ push_new_branch: true,
+ push_master: true,
+ push_protected_branch: true,
+ push_remove_protected_branch: false,
+ push_tag: true,
+ push_new_tag: true,
+ push_all: true,
+ merge_into_protected_branch: true
+ },
+
+ developer: {
+ push_new_branch: true,
+ push_master: true,
+ push_protected_branch: false,
+ push_remove_protected_branch: false,
+ push_tag: false,
+ push_new_tag: true,
+ push_all: false,
+ merge_into_protected_branch: false
+ },
+
+ reporter: {
+ push_new_branch: false,
+ push_master: false,
+ push_protected_branch: false,
+ push_remove_protected_branch: false,
+ push_tag: false,
+ push_new_tag: false,
+ push_all: false,
+ merge_into_protected_branch: false
+ },
+
+ guest: {
+ push_new_branch: false,
+ push_master: false,
+ push_protected_branch: false,
+ push_remove_protected_branch: false,
+ push_tag: false,
+ push_new_tag: false,
+ push_all: false,
+ merge_into_protected_branch: false
+ }
+ }
+
+ [['feature', 'exact'], ['feat*', 'wildcard']].each do |protected_branch_name, protected_branch_type|
+ context do
+ before { create(:protected_branch, name: protected_branch_name, project: project) }
+
+ run_permission_checks(permissions_matrix)
+ end
+
+ context "when 'developers can push' is turned on for the #{protected_branch_type} protected branch" do
+ before { create(:protected_branch, name: protected_branch_name, developers_can_push: true, project: project) }
+
+ run_permission_checks(permissions_matrix.deep_merge(developer: { push_protected_branch: true, push_all: true, merge_into_protected_branch: true }))
+ end
+
+ context "when 'developers can merge' is turned on for the #{protected_branch_type} protected branch" do
+ before { create(:protected_branch, name: protected_branch_name, developers_can_merge: true, project: project) }
+
+ context "when a merge request exists for the given source/target branch" do
+ context "when the merge request is in progress" do
+ before do
+ create(:merge_request, source_project: project, source_branch: unprotected_branch, target_branch: 'feature', state: 'locked', in_progress_merge_commit_sha: merge_into_protected_branch)
+ end
+
+ run_permission_checks(permissions_matrix.deep_merge(developer: { merge_into_protected_branch: true }))
+ end
+
+ context "when the merge request is not in progress" do
+ before do
+ create(:merge_request, source_project: project, source_branch: unprotected_branch, target_branch: 'feature', in_progress_merge_commit_sha: nil)
+ end
+
+ run_permission_checks(permissions_matrix.deep_merge(developer: { merge_into_protected_branch: false }))
+ end
+ end
+
+ context "when a merge request does not exist for the given source/target branch" do
+ run_permission_checks(permissions_matrix.deep_merge(developer: { merge_into_protected_branch: false }))
+ end
+ end
+
+ context "when 'developers can merge' and 'developers can push' are turned on for the #{protected_branch_type} protected branch" do
+ before { create(:protected_branch, name: protected_branch_name, developers_can_merge: true, developers_can_push: true, project: project) }
+
+ run_permission_checks(permissions_matrix.deep_merge(developer: { push_protected_branch: true, push_all: true, merge_into_protected_branch: true }))
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/github_import/client_spec.rb b/spec/lib/gitlab/github_import/client_spec.rb
index 3b023a35446..613c47d55f1 100644
--- a/spec/lib/gitlab/github_import/client_spec.rb
+++ b/spec/lib/gitlab/github_import/client_spec.rb
@@ -61,4 +61,11 @@ describe Gitlab::GithubImport::Client, lib: true do
expect(client.api.api_endpoint).to eq 'https://github.company.com/'
end
end
+
+ it 'does not raise error when rate limit is disabled' do
+ stub_request(:get, /api.github.com/)
+ allow(client.api).to receive(:rate_limit!).and_raise(Octokit::NotFound)
+
+ expect { client.issues }.not_to raise_error
+ end
end
diff --git a/spec/lib/gitlab/import_export/project.json b/spec/lib/gitlab/import_export/project.json
index 0b30e8c9b04..7286b0c39c0 100644
--- a/spec/lib/gitlab/import_export/project.json
+++ b/spec/lib/gitlab/import_export/project.json
@@ -4208,7 +4208,18 @@
"name": "User 4"
},
"events": [
-
+ {
+ "id": 529,
+ "target_type": "Note",
+ "target_id": 2521,
+ "title": "test levels",
+ "data": null,
+ "project_id": 4,
+ "created_at": "2016-07-07T14:35:12.128Z",
+ "updated_at": "2016-07-07T14:35:12.128Z",
+ "action": 6,
+ "author_id": 1
+ }
]
},
{
diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
index a72aaa44e82..05ffec8ea0a 100644
--- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
@@ -24,11 +24,27 @@ describe Gitlab::ImportExport::ProjectTreeRestorer, services: true do
expect(Ci::Pipeline.first.notes).not_to be_empty
end
- it 'restores the correct event' do
+ it 'restores the correct event with symbolised data' do
restored_project_json
expect(Event.where.not(data: nil).first.data[:ref]).not_to be_empty
end
+
+ context 'event at forth level of the tree' do
+ let(:event) { Event.where(title: 'test levels').first }
+
+ before do
+ restored_project_json
+ end
+
+ it 'restores the event' do
+ expect(event).not_to be_nil
+ end
+
+ it 'event belongs to note, belongs to merge request, belongs to a project' do
+ expect(event.note.noteable.project).not_to be_nil
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/ldap/access_spec.rb b/spec/lib/gitlab/ldap/access_spec.rb
index f5b66b8156f..acd5394382c 100644
--- a/spec/lib/gitlab/ldap/access_spec.rb
+++ b/spec/lib/gitlab/ldap/access_spec.rb
@@ -4,7 +4,7 @@ describe Gitlab::LDAP::Access, lib: true do
let(:access) { Gitlab::LDAP::Access.new user }
let(:user) { create(:omniauth_user) }
- describe :allowed? do
+ describe '#allowed?' do
subject { access.allowed? }
context 'when the user cannot be found' do
diff --git a/spec/lib/gitlab/ldap/user_spec.rb b/spec/lib/gitlab/ldap/user_spec.rb
index 03199a2523e..949f6e2b19a 100644
--- a/spec/lib/gitlab/ldap/user_spec.rb
+++ b/spec/lib/gitlab/ldap/user_spec.rb
@@ -25,7 +25,7 @@ describe Gitlab::LDAP::User, lib: true do
OmniAuth::AuthHash.new(uid: 'my-uid', provider: 'ldapmain', info: info_upper_case)
end
- describe :changed? do
+ describe '#changed?' do
it "marks existing ldap user as changed" do
create(:omniauth_user, extern_uid: 'my-uid', provider: 'ldapmain')
expect(ldap_user.changed?).to be_truthy
diff --git a/spec/lib/gitlab/user_access_spec.rb b/spec/lib/gitlab/user_access_spec.rb
new file mode 100644
index 00000000000..aa9ec243498
--- /dev/null
+++ b/spec/lib/gitlab/user_access_spec.rb
@@ -0,0 +1,88 @@
+require 'spec_helper'
+
+describe Gitlab::UserAccess, lib: true do
+ let(:access) { Gitlab::UserAccess.new(user, project: project) }
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+
+ 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]
+ 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]
+ 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]
+ expect(access.can_push_to_branch?('random_branch')).to be_falsey
+ end
+ end
+
+ describe 'push to protected branch' do
+ let(:branch) { create :protected_branch, project: project }
+
+ it 'returns true if user is a master' do
+ project.team << [user, :master]
+ 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]
+ 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]
+ expect(access.can_push_to_branch?(branch.name)).to be_falsey
+ end
+ end
+
+ describe 'push to protected branch if allowed for developers' do
+ before do
+ @branch = create :protected_branch, project: project, developers_can_push: true
+ end
+
+ it 'returns true if user is a master' do
+ project.team << [user, :master]
+ 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]
+ 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]
+ expect(access.can_push_to_branch?(@branch.name)).to be_falsey
+ end
+ end
+
+ describe 'merge to protected branch if allowed for developers' do
+ before do
+ @branch = create :protected_branch, project: project, developers_can_merge: true
+ end
+
+ it 'returns true if user is a master' do
+ project.team << [user, :master]
+ 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]
+ 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]
+ expect(access.can_merge_to_branch?(@branch.name)).to be_falsey
+ end
+ end
+
+ end
+end
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 34507cf5083..4e5481f9154 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -15,7 +15,7 @@ describe Ci::Pipeline, models: true do
it { is_expected.to respond_to :git_author_email }
it { is_expected.to respond_to :short_sha }
- describe :valid_commit_sha do
+ describe '#valid_commit_sha' do
context 'commit.sha can not start with 00000000' do
before do
pipeline.sha = '0' * 40
@@ -26,7 +26,7 @@ describe Ci::Pipeline, models: true do
end
end
- describe :short_sha do
+ describe '#short_sha' do
subject { pipeline.short_sha }
it 'has 8 items' do
@@ -35,10 +35,10 @@ describe Ci::Pipeline, models: true do
it { expect(pipeline.sha).to start_with(subject) }
end
- describe :create_next_builds do
+ describe '#create_next_builds' do
end
- describe :retried do
+ describe '#retried' do
subject { pipeline.retried }
before do
@@ -51,7 +51,7 @@ describe Ci::Pipeline, models: true do
end
end
- describe :create_builds do
+ describe '#create_builds' do
let!(:pipeline) { FactoryGirl.create :ci_pipeline, project: project, ref: 'master', tag: false }
def create_builds(trigger_request = nil)
diff --git a/spec/models/ci/variable_spec.rb b/spec/models/ci/variable_spec.rb
index 98f60087cf5..4e7833c3162 100644
--- a/spec/models/ci/variable_spec.rb
+++ b/spec/models/ci/variable_spec.rb
@@ -9,7 +9,7 @@ describe Ci::Variable, models: true do
subject.value = secret_value
end
- describe :value do
+ describe '#value' do
it 'stores the encrypted value' do
expect(subject.encrypted_value).not_to be_nil
end
diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb
index 96397d7c8a9..05f22c7a9eb 100644
--- a/spec/models/commit_status_spec.rb
+++ b/spec/models/commit_status_spec.rb
@@ -24,14 +24,14 @@ describe CommitStatus, models: true do
it { is_expected.to respond_to :running? }
it { is_expected.to respond_to :pending? }
- describe :author do
+ describe '#author' do
subject { commit_status.author }
before { commit_status.author = User.new }
it { is_expected.to eq(commit_status.user) }
end
- describe :started? do
+ describe '#started?' do
subject { commit_status.started? }
context 'without started_at' do
@@ -57,7 +57,7 @@ describe CommitStatus, models: true do
end
end
- describe :active? do
+ describe '#active?' do
subject { commit_status.active? }
%w(pending running).each do |state|
@@ -77,7 +77,7 @@ describe CommitStatus, models: true do
end
end
- describe :complete? do
+ describe '#complete?' do
subject { commit_status.complete? }
%w(success failed canceled).each do |state|
@@ -97,7 +97,7 @@ describe CommitStatus, models: true do
end
end
- describe :duration do
+ describe '#duration' do
subject { commit_status.duration }
it { is_expected.to eq(120.0) }
@@ -122,7 +122,7 @@ describe CommitStatus, models: true do
end
end
- describe :latest do
+ describe '.latest' do
subject { CommitStatus.latest.order(:id) }
before do
@@ -138,7 +138,7 @@ describe CommitStatus, models: true do
end
end
- describe :running_or_pending do
+ describe '.running_or_pending' do
subject { CommitStatus.running_or_pending.order(:id) }
before do
diff --git a/spec/models/concerns/mentionable_spec.rb b/spec/models/concerns/mentionable_spec.rb
index 0344dae8b5d..5e652660e2c 100644
--- a/spec/models/concerns/mentionable_spec.rb
+++ b/spec/models/concerns/mentionable_spec.rb
@@ -7,7 +7,7 @@ describe Mentionable do
nil
end
- describe :references do
+ describe 'references' do
let(:project) { create(:project) }
it 'excludes JIRA references' do
diff --git a/spec/models/forked_project_link_spec.rb b/spec/models/forked_project_link_spec.rb
index fa1a0d4e0c7..f94987dcaff 100644
--- a/spec/models/forked_project_link_spec.rb
+++ b/spec/models/forked_project_link_spec.rb
@@ -18,7 +18,7 @@ describe ForkedProjectLink, "add link on fork" do
end
end
-describe :forked_from_project do
+describe '#forked?' do
let(:forked_project_link) { build(:forked_project_link) }
let(:project_from) { create(:project) }
let(:project_to) { create(:project, forked_project_link: forked_project_link) }
diff --git a/spec/models/generic_commit_status_spec.rb b/spec/models/generic_commit_status_spec.rb
index c4e781dd1dc..615cfe3142b 100644
--- a/spec/models/generic_commit_status_spec.rb
+++ b/spec/models/generic_commit_status_spec.rb
@@ -4,33 +4,33 @@ describe GenericCommitStatus, models: true do
let(:pipeline) { FactoryGirl.create :ci_pipeline }
let(:generic_commit_status) { FactoryGirl.create :generic_commit_status, pipeline: pipeline }
- describe :context do
+ describe '#context' do
subject { generic_commit_status.context }
before { generic_commit_status.context = 'my_context' }
it { is_expected.to eq(generic_commit_status.name) }
end
- describe :tags do
+ describe '#tags' do
subject { generic_commit_status.tags }
it { is_expected.to eq([:external]) }
end
- describe :set_default_values do
+ describe 'set_default_values' do
before do
generic_commit_status.context = nil
generic_commit_status.stage = nil
generic_commit_status.save
end
- describe :context do
+ describe '#context' do
subject { generic_commit_status.context }
it { is_expected.not_to be_nil }
end
- describe :stage do
+ describe '#stage' do
subject { generic_commit_status.stage }
it { is_expected.not_to be_nil }
diff --git a/spec/models/global_milestone_spec.rb b/spec/models/global_milestone_spec.rb
index 197c99cd007..ae77ec5b348 100644
--- a/spec/models/global_milestone_spec.rb
+++ b/spec/models/global_milestone_spec.rb
@@ -14,7 +14,7 @@ describe GlobalMilestone, models: true do
let(:milestone2_project2) { create(:milestone, title: "VD-123", project: project2) }
let(:milestone2_project3) { create(:milestone, title: "VD-123", project: project3) }
- describe :build_collection do
+ describe '.build_collection' do
before do
milestones =
[
@@ -42,7 +42,7 @@ describe GlobalMilestone, models: true do
end
end
- describe :initialize do
+ describe '#initialize' do
before do
milestones =
[
@@ -63,7 +63,7 @@ describe GlobalMilestone, models: true do
end
end
- describe :safe_title do
+ describe '#safe_title' do
let(:milestone) { create(:milestone, title: "git / test", project: project1) }
it 'should strip out slashes and spaces' do
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index a878ff1b227..266c46213a6 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -97,22 +97,22 @@ describe Group, models: true do
end
end
- describe :users do
+ describe '#users' do
it { expect(group.users).to eq(group.owners) }
end
- describe :human_name do
+ describe '#human_name' do
it { expect(group.human_name).to eq(group.name) }
end
- describe :add_users do
+ describe '#add_user' do
let(:user) { create(:user) }
before { group.add_user(user, GroupMember::MASTER) }
it { expect(group.group_members.masters.map(&:user)).to include(user) }
end
- describe :add_users do
+ describe '#add_users' do
let(:user) { create(:user) }
before { group.add_users([user.id], GroupMember::GUEST) }
@@ -124,7 +124,7 @@ describe Group, models: true do
end
end
- describe :avatar_type do
+ describe '#avatar_type' do
let(:user) { create(:user) }
before { group.add_user(user, GroupMember::MASTER) }
diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb
index 4c103462433..ba622dfb9be 100644
--- a/spec/models/members/project_member_spec.rb
+++ b/spec/models/members/project_member_spec.rb
@@ -101,7 +101,7 @@ describe ProjectMember, models: true do
end
end
- describe :add_users_into_projects do
+ describe '.add_users_into_projects' do
before do
@project_1 = create :project
@project_2 = create :project
@@ -123,7 +123,7 @@ describe ProjectMember, models: true do
it { expect(@project_2.users).to include(@user_2) }
end
- describe :truncate_teams do
+ describe '.truncate_teams' do
before do
@project_1 = create :project
@project_2 = create :project
diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb
new file mode 100644
index 00000000000..9a637c94fbe
--- /dev/null
+++ b/spec/models/merge_request_diff_spec.rb
@@ -0,0 +1,47 @@
+require 'spec_helper'
+
+describe MergeRequestDiff, models: true do
+ describe '#diffs' do
+ let(:mr) { create(:merge_request, :with_diffs) }
+ let(:mr_diff) { mr.merge_request_diff }
+
+ context 'when the :ignore_whitespace_change option is set' do
+ it 'creates a new compare object instead of loading from the DB' do
+ expect(mr_diff).not_to receive(:load_diffs)
+ expect(Gitlab::Git::Compare).to receive(:new).and_call_original
+
+ mr_diff.diffs(ignore_whitespace_change: true)
+ end
+ end
+
+ context 'when the raw diffs are empty' do
+ before { mr_diff.update_attributes(st_diffs: '') }
+
+ it 'returns an empty DiffCollection' do
+ expect(mr_diff.diffs).to be_a(Gitlab::Git::DiffCollection)
+ expect(mr_diff.diffs).to be_empty
+ end
+ end
+
+ context 'when the raw diffs exist' do
+ it 'returns the diffs' do
+ expect(mr_diff.diffs).to be_a(Gitlab::Git::DiffCollection)
+ expect(mr_diff.diffs).not_to be_empty
+ end
+
+ context 'when the :paths option is set' do
+ let(:diffs) { mr_diff.diffs(paths: ['files/ruby/popen.rb', 'files/ruby/popen.rb']) }
+
+ it 'only returns diffs that match the (old path, new path) given' do
+ expect(diffs.map(&:new_path)).to contain_exactly('files/ruby/popen.rb')
+ end
+
+ it 'uses the diffs from the DB' do
+ expect(mr_diff).to receive(:load_diffs)
+
+ diffs
+ end
+ end
+ end
+ end
+end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index a4b6ff8f8ad..c8ad7ab3e7f 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -116,6 +116,31 @@ describe MergeRequest, models: true do
end
end
+ describe '#diffs' do
+ let(:merge_request) { build(:merge_request) }
+ let(:options) { { paths: ['a/b', 'b/a', 'c/*'] } }
+
+ context 'when there are MR diffs' do
+ it 'delegates to the MR diffs' do
+ merge_request.merge_request_diff = MergeRequestDiff.new
+
+ expect(merge_request.merge_request_diff).to receive(:diffs).with(options)
+
+ merge_request.diffs(options)
+ end
+ end
+
+ context 'when there are no MR diffs' do
+ it 'delegates to the compare object' do
+ merge_request.compare = double(:compare)
+
+ expect(merge_request.compare).to receive(:diffs).with(options)
+
+ merge_request.diffs(options)
+ end
+ end
+ end
+
describe "#mr_and_commit_notes" do
let!(:merge_request) { create(:merge_request) }
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index 1e18c788b50..d661dc0e59a 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -70,7 +70,7 @@ describe Milestone, models: true do
end
end
- describe :expired? do
+ describe '#expired?' do
context "expired" do
before do
allow(milestone).to receive(:due_date).and_return(Date.today.prev_year)
@@ -88,7 +88,7 @@ describe Milestone, models: true do
end
end
- describe :percent_complete do
+ describe '#percent_complete' do
before do
allow(milestone).to receive_messages(
closed_items_count: 3,
@@ -111,11 +111,11 @@ describe Milestone, models: true do
it { expect(milestone.is_empty?(user)).to be_falsey }
end
- describe :can_be_closed? do
+ describe '#can_be_closed?' do
it { expect(milestone.can_be_closed?).to be_truthy }
end
- describe :total_items_count do
+ describe '#total_items_count' do
before do
create :closed_issue, milestone: milestone
create :merge_request, milestone: milestone
@@ -126,7 +126,7 @@ describe Milestone, models: true do
end
end
- describe :can_be_closed? do
+ describe '#can_be_closed?' do
before do
milestone = create :milestone
create :closed_issue, milestone: milestone
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 5f68cd2b066..a162da0208e 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -18,11 +18,11 @@ describe Namespace, models: true do
it { is_expected.to respond_to(:to_param) }
end
- describe :to_param do
+ describe '#to_param' do
it { expect(namespace.to_param).to eq(namespace.path) }
end
- describe :human_name do
+ describe '#human_name' do
it { expect(namespace.human_name).to eq(namespace.owner_name) }
end
@@ -54,7 +54,7 @@ describe Namespace, models: true do
end
end
- describe :move_dir do
+ describe '#move_dir' do
before do
@namespace = create :namespace
@project = create :project, namespace: @namespace
@@ -98,7 +98,7 @@ describe Namespace, models: true do
end
end
- describe :find_by_path_or_name do
+ describe '.find_by_path_or_name' do
before do
@namespace = create(:namespace, name: 'WoW', path: 'woW')
end
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 6549791f675..7d0697dab42 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -226,6 +226,20 @@ describe Note, models: true do
it "returns false" do
expect(note.cross_reference_not_visible_for?(private_user)).to be_falsy
end
+
+ it "returns false if user visible reference count set" do
+ note.user_visible_reference_count = 1
+
+ expect(note).not_to receive(:reference_mentionables)
+ expect(note.cross_reference_not_visible_for?(ext_issue.author)).to be_falsy
+ end
+
+ it "returns true if ref count is 0" do
+ note.user_visible_reference_count = 0
+
+ expect(note).not_to receive(:reference_mentionables)
+ expect(note.cross_reference_not_visible_for?(ext_issue.author)).to be_truthy
+ end
end
describe 'clear_blank_line_code!' do
diff --git a/spec/models/project_security_spec.rb b/spec/models/project_security_spec.rb
index e12258c0874..2142c7c13ef 100644
--- a/spec/models/project_security_spec.rb
+++ b/spec/models/project_security_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe Project, models: true do
- describe :authorization do
+ describe 'authorization' do
before do
@p1 = create(:project)
diff --git a/spec/models/project_services/buildkite_service_spec.rb b/spec/models/project_services/buildkite_service_spec.rb
index 60364df2015..0866e1532dd 100644
--- a/spec/models/project_services/buildkite_service_spec.rb
+++ b/spec/models/project_services/buildkite_service_spec.rb
@@ -57,7 +57,7 @@ describe BuildkiteService, models: true do
)
end
- describe :webhook_url do
+ describe '#webhook_url' do
it 'returns the webhook url' do
expect(@service.webhook_url).to eq(
'https://webhook.buildkite.com/deliver/secret-sauce-webhook-token'
@@ -65,7 +65,7 @@ describe BuildkiteService, models: true do
end
end
- describe :commit_status_path do
+ describe '#commit_status_path' do
it 'returns the correct status page' do
expect(@service.commit_status_path('2ab7834c')).to eq(
'https://gitlab.buildkite.com/status/secret-sauce-status-token.json?commit=2ab7834c'
@@ -73,7 +73,7 @@ describe BuildkiteService, models: true do
end
end
- describe :build_page do
+ describe '#build_page' do
it 'returns the correct build page' do
expect(@service.build_page('2ab7834c', nil)).to eq(
'https://buildkite.com/account-name/example-project/builds?commit=2ab7834c'
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 5a27ccbab0a..d2269854354 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -296,7 +296,7 @@ describe Project, models: true do
end
end
- describe :update_merge_requests do
+ describe '#update_merge_requests' do
let(:project) { create(:project) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:key) { create(:key, user_id: project.owner.id) }
@@ -345,7 +345,7 @@ describe Project, models: true do
end
end
- describe :to_param do
+ describe '#to_param' do
context 'with namespace' do
before do
@group = create :group, name: 'gitlab'
@@ -356,7 +356,7 @@ describe Project, models: true do
end
end
- describe :repository do
+ describe '#repository' do
let(:project) { create(:project) }
it 'should return valid repo' do
@@ -364,7 +364,7 @@ describe Project, models: true do
end
end
- describe :default_issues_tracker? do
+ describe '#default_issues_tracker?' do
let(:project) { create(:project) }
let(:ext_project) { create(:redmine_project) }
@@ -377,7 +377,7 @@ describe Project, models: true do
end
end
- describe :external_issue_tracker do
+ describe '#external_issue_tracker' do
let(:project) { create(:project) }
let(:ext_project) { create(:redmine_project) }
@@ -418,7 +418,7 @@ describe Project, models: true do
end
end
- describe :cache_has_external_issue_tracker do
+ describe '#cache_has_external_issue_tracker' do
let(:project) { create(:project) }
it 'stores true if there is any external_issue_tracker' do
@@ -440,7 +440,7 @@ describe Project, models: true do
end
end
- describe :open_branches do
+ describe '#open_branches' do
let(:project) { create(:project) }
before do
@@ -517,7 +517,7 @@ describe Project, models: true do
end
end
- describe :avatar_type do
+ describe '#avatar_type' do
let(:project) { create(:project) }
it 'should be true if avatar is image' do
@@ -531,7 +531,7 @@ describe Project, models: true do
end
end
- describe :avatar_url do
+ describe '#avatar_url' do
subject { project.avatar_url }
let(:project) { create(:project) }
@@ -568,7 +568,7 @@ describe Project, models: true do
end
end
- describe :pipeline do
+ describe '#pipeline' do
let(:project) { create :project }
let(:pipeline) { create :ci_pipeline, project: project, ref: 'master' }
@@ -588,7 +588,7 @@ describe Project, models: true do
end
end
- describe :builds_enabled do
+ describe '#builds_enabled' do
let(:project) { create :project }
before { project.builds_enabled = true }
@@ -690,7 +690,7 @@ describe Project, models: true do
end
end
- describe :any_runners do
+ describe '#any_runners' do
let(:project) { create(:empty_project, shared_runners_enabled: shared_runners_enabled) }
let(:specific_runner) { create(:ci_runner) }
let(:shared_runner) { create(:ci_runner, :shared) }
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 24e49c8def3..e14cec589fe 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -4,19 +4,20 @@ describe Repository, models: true do
include RepoHelpers
TestBlob = Struct.new(:name)
- let(:repository) { create(:project).repository }
+ let(:project) { create(:project) }
+ let(:repository) { project.repository }
let(:user) { create(:user) }
let(:commit_options) do
author = repository.user_to_committer(user)
{ message: 'Test message', committer: author, author: author }
end
let(:merge_commit) do
- source_sha = repository.find_branch('feature').target
- merge_commit_sha = repository.merge(user, source_sha, 'master', commit_options)
- repository.commit(merge_commit_sha)
+ merge_request = create(:merge_request, source_branch: 'feature', target_branch: 'master', source_project: project)
+ merge_commit_id = repository.merge(user, merge_request, commit_options)
+ repository.commit(merge_commit_id)
end
- describe :branch_names_contains do
+ describe '#branch_names_contains' do
subject { repository.branch_names_contains(sample_commit.id) }
it { is_expected.to include('master') }
@@ -24,7 +25,7 @@ describe Repository, models: true do
it { is_expected.not_to include('fix') }
end
- describe :tag_names_contains do
+ describe '#tag_names_contains' do
subject { repository.tag_names_contains(sample_commit.id) }
it { is_expected.to include('v1.1.0') }
@@ -72,13 +73,13 @@ describe Repository, models: true do
end
end
- describe :last_commit_for_path do
+ describe '#last_commit_for_path' do
subject { repository.last_commit_for_path(sample_commit.id, '.gitignore').id }
it { is_expected.to eq('c1acaa58bbcbc3eafe538cb8274ba387047b69f8') }
end
- describe :find_commits_by_message do
+ describe '#find_commits_by_message' do
subject { repository.find_commits_by_message('submodule').map{ |k| k.id } }
it { is_expected.to include('5937ac0a7beb003549fc5fd26fc247adbce4a52e') }
@@ -87,7 +88,7 @@ describe Repository, models: true do
it { is_expected.not_to include('913c66a37b4a45b9769037c55c2d238bd0942d2e') }
end
- describe :blob_at do
+ describe '#blob_at' do
context 'blank sha' do
subject { repository.blob_at(Gitlab::Git::BLANK_SHA, '.gitignore') }
@@ -95,7 +96,7 @@ describe Repository, models: true do
end
end
- describe :merged_to_root_ref? do
+ describe '#merged_to_root_ref?' do
context 'merged branch' do
subject { repository.merged_to_root_ref?('improve/awesome') }
@@ -103,7 +104,7 @@ describe Repository, models: true do
end
end
- describe :can_be_merged? do
+ describe '#can_be_merged?' do
context 'mergeable branches' do
subject { repository.can_be_merged?('0b4bc9a49b562e85de7cc9e834518ea6828729b9', 'master') }
@@ -305,7 +306,7 @@ describe Repository, models: true do
end
end
- describe :add_branch do
+ describe '#add_branch' do
context 'when pre hooks were successful' do
it 'should run without errors' do
hook = double(trigger: [true, nil])
@@ -349,7 +350,7 @@ describe Repository, models: true do
end
end
- describe :rm_branch do
+ describe '#rm_branch' do
context 'when pre hooks were successful' do
it 'should run without errors' do
allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([true, nil])
@@ -386,7 +387,7 @@ describe Repository, models: true do
end
end
- describe :commit_with_hooks do
+ describe '#commit_with_hooks' do
context 'when pre hooks were successful' do
before do
expect_any_instance_of(GitHooksService).to receive(:execute).
diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb
index 96bbbec9ea1..67b3783d514 100644
--- a/spec/models/service_spec.rb
+++ b/spec/models/service_spec.rb
@@ -22,11 +22,11 @@ describe Service, models: true do
@testable = @service.can_test?
end
- describe :can_test do
+ describe '#can_test?' do
it { expect(@testable).to eq(true) }
end
- describe :test do
+ describe '#test' do
let(:data) { 'test' }
it 'test runs execute' do
@@ -45,7 +45,7 @@ describe Service, models: true do
@testable = @service.can_test?
end
- describe :can_test do
+ describe '#can_test?' do
it { expect(@testable).to eq(true) }
end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 3984b30ddf8..ff39f187759 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -427,7 +427,7 @@ describe User, models: true do
end
end
- describe :not_in_project do
+ describe '.not_in_project' do
before do
User.delete_all
@user = create :user
@@ -598,7 +598,7 @@ describe User, models: true do
end
end
- describe :avatar_type do
+ describe '#avatar_type' do
let(:user) { create(:user) }
it "should be true if avatar is image" do
@@ -612,7 +612,7 @@ describe User, models: true do
end
end
- describe :requires_ldap_check? do
+ describe '#requires_ldap_check?' do
let(:user) { User.new }
it 'is false when LDAP is disabled' do
@@ -651,7 +651,7 @@ describe User, models: true do
end
context 'ldap synchronized user' do
- describe :ldap_user? do
+ describe '#ldap_user?' do
it 'is true if provider name starts with ldap' do
user = create(:omniauth_user, provider: 'ldapmain')
expect(user.ldap_user?).to be_truthy
@@ -668,7 +668,7 @@ describe User, models: true do
end
end
- describe :ldap_identity do
+ describe '#ldap_identity' do
it 'returns ldap identity' do
user = create :omniauth_user
expect(user.ldap_identity.provider).not_to be_empty
@@ -825,7 +825,7 @@ describe User, models: true do
end
end
- describe :can_be_removed? do
+ describe '#can_be_removed?' do
subject { create(:user) }
context 'no owned groups' do
diff --git a/spec/requests/api/api_helpers_spec.rb b/spec/requests/api/api_helpers_spec.rb
index 83025953889..3d5c19aeff3 100644
--- a/spec/requests/api/api_helpers_spec.rb
+++ b/spec/requests/api/api_helpers_spec.rb
@@ -49,7 +49,7 @@ describe API::Helpers, api: true do
it "should return nil for a user without access" do
env[API::Helpers::PRIVATE_TOKEN_HEADER] = user.private_token
- allow(Gitlab::UserAccess).to receive(:allowed?).and_return(false)
+ allow_any_instance_of(Gitlab::UserAccess).to receive(:allowed?).and_return(false)
expect(current_user).to be_nil
end
@@ -73,7 +73,7 @@ describe API::Helpers, api: true do
it "should return nil for a user without access" do
env[API::Helpers::PRIVATE_TOKEN_HEADER] = personal_access_token.token
- allow(Gitlab::UserAccess).to receive(:allowed?).and_return(false)
+ allow_any_instance_of(Gitlab::UserAccess).to receive(:allowed?).and_return(false)
expect(current_user).to be_nil
end
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 4a1b5600bdf..651b91e9f68 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -138,6 +138,8 @@ describe API::API, api: true do
expect(json_response['work_in_progress']).to be_falsy
expect(json_response['merge_when_build_succeeds']).to be_falsy
expect(json_response['merge_status']).to eq('can_be_merged')
+ expect(json_response['should_close_merge_request']).to be_falsy
+ expect(json_response['force_close_merge_request']).to be_falsy
end
it "should return merge_request" do
@@ -147,6 +149,8 @@ describe API::API, api: true do
expect(json_response['iid']).to eq(merge_request.iid)
expect(json_response['work_in_progress']).to eq(false)
expect(json_response['merge_status']).to eq('can_be_merged')
+ expect(json_response['should_close_merge_request']).to be_falsy
+ expect(json_response['force_close_merge_request']).to be_falsy
end
it 'should return merge_request by iid' do
diff --git a/spec/routing/routing_spec.rb b/spec/routing/routing_spec.rb
index 8a8e131c57b..2c755919456 100644
--- a/spec/routing/routing_spec.rb
+++ b/spec/routing/routing_spec.rb
@@ -98,7 +98,7 @@ describe SnippetsController, "routing" do
end
# help GET /help(.:format) help#index
-# help_page GET /help/:category/:file(.:format) help#show {:category=>/.*/, :file=>/[^\/\.]+/}
+# help_page GET /help/*path(.:format) help#show
# help_shortcuts GET /help/shortcuts(.:format) help#shortcuts
# help_ui GET /help/ui(.:format) help#ui
describe HelpController, "routing" do
@@ -109,23 +109,19 @@ describe HelpController, "routing" do
it 'to #show' do
path = '/help/markdown/markdown.md'
expect(get(path)).to route_to('help#show',
- category: 'markdown',
- file: 'markdown',
+ path: 'markdown/markdown',
format: 'md')
path = '/help/workflow/protected_branches/protected_branches1.png'
expect(get(path)).to route_to('help#show',
- category: 'workflow/protected_branches',
- file: 'protected_branches1',
+ path: 'workflow/protected_branches/protected_branches1',
format: 'png')
- end
-
- it 'to #shortcuts' do
- expect(get('/help/shortcuts')).to route_to('help#shortcuts')
- end
-
- it 'to #ui' do
- expect(get('/help/ui')).to route_to('help#ui')
+ path = '/help/shortcuts'
+ expect(get(path)).to route_to('help#show',
+ path: 'shortcuts')
+ path = '/help/ui'
+ expect(get(path)).to route_to('help#show',
+ path: 'ui')
end
end
diff --git a/spec/services/ci/create_trigger_request_service_spec.rb b/spec/services/ci/create_trigger_request_service_spec.rb
index ae4b7aca820..b72e0bd3dbe 100644
--- a/spec/services/ci/create_trigger_request_service_spec.rb
+++ b/spec/services/ci/create_trigger_request_service_spec.rb
@@ -9,7 +9,7 @@ describe Ci::CreateTriggerRequestService, services: true do
stub_ci_pipeline_to_return_yaml_file
end
- describe :execute do
+ describe '#execute' do
context 'valid params' do
subject { service.execute(project, trigger, 'master') }
diff --git a/spec/services/ci/image_for_build_service_spec.rb b/spec/services/ci/image_for_build_service_spec.rb
index 476a888e394..3a3e3efe709 100644
--- a/spec/services/ci/image_for_build_service_spec.rb
+++ b/spec/services/ci/image_for_build_service_spec.rb
@@ -8,7 +8,7 @@ module Ci
let(:commit) { project.ensure_pipeline(commit_sha, 'master') }
let(:build) { FactoryGirl.create(:ci_build, pipeline: commit) }
- describe :execute do
+ describe '#execute' do
before { build }
context 'branch name' do
diff --git a/spec/services/ci/register_build_service_spec.rb b/spec/services/ci/register_build_service_spec.rb
index f28f2f1438d..026d0ca6534 100644
--- a/spec/services/ci/register_build_service_spec.rb
+++ b/spec/services/ci/register_build_service_spec.rb
@@ -13,7 +13,7 @@ module Ci
specific_runner.assign_to(project)
end
- describe :execute do
+ describe '#execute' do
context 'runner follow tag list' do
it "picks build with the same tag" do
pending_build.tag_list = ["linux"]
diff --git a/spec/services/create_commit_builds_service_spec.rb b/spec/services/create_commit_builds_service_spec.rb
index 309213bd44c..4d09bc5fb12 100644
--- a/spec/services/create_commit_builds_service_spec.rb
+++ b/spec/services/create_commit_builds_service_spec.rb
@@ -9,7 +9,7 @@ describe CreateCommitBuildsService, services: true do
stub_ci_pipeline_to_return_yaml_file
end
- describe :execute do
+ describe '#execute' do
context 'valid params' do
let(:pipeline) do
service.execute(project, user,
diff --git a/spec/services/event_create_service_spec.rb b/spec/services/event_create_service_spec.rb
index f6dc9d4008f..789836f71bb 100644
--- a/spec/services/event_create_service_spec.rb
+++ b/spec/services/event_create_service_spec.rb
@@ -4,7 +4,7 @@ describe EventCreateService, services: true do
let(:service) { EventCreateService.new }
describe 'Issues' do
- describe :open_issue do
+ describe '#open_issue' do
let(:issue) { create(:issue) }
it { expect(service.open_issue(issue, issue.author)).to be_truthy }
@@ -14,7 +14,7 @@ describe EventCreateService, services: true do
end
end
- describe :close_issue do
+ describe '#close_issue' do
let(:issue) { create(:issue) }
it { expect(service.close_issue(issue, issue.author)).to be_truthy }
@@ -24,7 +24,7 @@ describe EventCreateService, services: true do
end
end
- describe :reopen_issue do
+ describe '#reopen_issue' do
let(:issue) { create(:issue) }
it { expect(service.reopen_issue(issue, issue.author)).to be_truthy }
@@ -36,7 +36,7 @@ describe EventCreateService, services: true do
end
describe 'Merge Requests' do
- describe :open_mr do
+ describe '#open_mr' do
let(:merge_request) { create(:merge_request) }
it { expect(service.open_mr(merge_request, merge_request.author)).to be_truthy }
@@ -46,7 +46,7 @@ describe EventCreateService, services: true do
end
end
- describe :close_mr do
+ describe '#close_mr' do
let(:merge_request) { create(:merge_request) }
it { expect(service.close_mr(merge_request, merge_request.author)).to be_truthy }
@@ -56,7 +56,7 @@ describe EventCreateService, services: true do
end
end
- describe :merge_mr do
+ describe '#merge_mr' do
let(:merge_request) { create(:merge_request) }
it { expect(service.merge_mr(merge_request, merge_request.author)).to be_truthy }
@@ -66,7 +66,7 @@ describe EventCreateService, services: true do
end
end
- describe :reopen_mr do
+ describe '#reopen_mr' do
let(:merge_request) { create(:merge_request) }
it { expect(service.reopen_mr(merge_request, merge_request.author)).to be_truthy }
@@ -80,7 +80,7 @@ describe EventCreateService, services: true do
describe 'Milestone' do
let(:user) { create :user }
- describe :open_milestone do
+ describe '#open_milestone' do
let(:milestone) { create(:milestone) }
it { expect(service.open_milestone(milestone, user)).to be_truthy }
@@ -90,7 +90,7 @@ describe EventCreateService, services: true do
end
end
- describe :close_mr do
+ describe '#close_mr' do
let(:milestone) { create(:milestone) }
it { expect(service.close_milestone(milestone, user)).to be_truthy }
@@ -100,7 +100,7 @@ describe EventCreateService, services: true do
end
end
- describe :destroy_mr do
+ describe '#destroy_mr' do
let(:milestone) { create(:milestone) }
it { expect(service.destroy_milestone(milestone, user)).to be_truthy }
diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb
index afabeed4a80..47c0580e0f0 100644
--- a/spec/services/git_push_service_spec.rb
+++ b/spec/services/git_push_service_spec.rb
@@ -224,7 +224,7 @@ describe GitPushService, services: true do
it "when pushing a branch for the first time" do
expect(project).to receive(:execute_hooks)
expect(project.default_branch).to eq("master")
- expect(project.protected_branches).to receive(:create).with({ name: "master", developers_can_push: false })
+ expect(project.protected_branches).to receive(:create).with({ name: "master", developers_can_push: false, developers_can_merge: false })
execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master' )
end
@@ -242,7 +242,17 @@ describe GitPushService, services: true do
expect(project).to receive(:execute_hooks)
expect(project.default_branch).to eq("master")
- expect(project.protected_branches).to receive(:create).with({ name: "master", developers_can_push: true })
+ expect(project.protected_branches).to receive(:create).with({ name: "master", developers_can_push: true, developers_can_merge: false })
+
+ execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master')
+ end
+
+ it "when pushing a branch for the first time with default branch protection set to 'developers can merge'" do
+ stub_application_setting(default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_MERGE)
+
+ expect(project).to receive(:execute_hooks)
+ expect(project.default_branch).to eq("master")
+ expect(project.protected_branches).to receive(:create).with({ name: "master", developers_can_push: false, developers_can_merge: true })
execute_service(project, user, @blankrev, 'newrev', 'refs/heads/master' )
end
diff --git a/spec/services/issues/close_service_spec.rb b/spec/services/issues/close_service_spec.rb
index 62b25709a5d..67a919ba8ee 100644
--- a/spec/services/issues/close_service_spec.rb
+++ b/spec/services/issues/close_service_spec.rb
@@ -12,7 +12,7 @@ describe Issues::CloseService, services: true do
project.team << [user2, :developer]
end
- describe :execute do
+ describe '#execute' do
context "valid params" do
before do
perform_enqueued_jobs do
diff --git a/spec/services/merge_requests/close_service_spec.rb b/spec/services/merge_requests/close_service_spec.rb
index 8443a00e70c..c1db4f3284b 100644
--- a/spec/services/merge_requests/close_service_spec.rb
+++ b/spec/services/merge_requests/close_service_spec.rb
@@ -12,7 +12,7 @@ describe MergeRequests::CloseService, services: true do
project.team << [user2, :developer]
end
- describe :execute do
+ describe '#execute' do
context 'valid params' do
let(:service) { MergeRequests::CloseService.new(project, user, {}) }
diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb
index e433f49872d..d0b55d2d509 100644
--- a/spec/services/merge_requests/create_service_spec.rb
+++ b/spec/services/merge_requests/create_service_spec.rb
@@ -5,7 +5,7 @@ describe MergeRequests::CreateService, services: true do
let(:user) { create(:user) }
let(:assignee) { create(:user) }
- describe :execute do
+ describe '#execute' do
context 'valid params' do
let(:opts) do
{
diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb
index 2f72cd60071..f5bf3c1e367 100644
--- a/spec/services/merge_requests/merge_service_spec.rb
+++ b/spec/services/merge_requests/merge_service_spec.rb
@@ -11,7 +11,7 @@ describe MergeRequests::MergeService, services: true do
project.team << [user2, :developer]
end
- describe :execute do
+ describe '#execute' do
context 'valid params' do
let(:service) { MergeRequests::MergeService.new(project, user, commit_message: 'Awesome message') }
diff --git a/spec/services/merge_requests/refresh_service_spec.rb b/spec/services/merge_requests/refresh_service_spec.rb
index 7d5cb876063..ce643b3f860 100644
--- a/spec/services/merge_requests/refresh_service_spec.rb
+++ b/spec/services/merge_requests/refresh_service_spec.rb
@@ -5,7 +5,7 @@ describe MergeRequests::RefreshService, services: true do
let(:user) { create(:user) }
let(:service) { MergeRequests::RefreshService }
- describe :execute do
+ describe '#execute' do
before do
@user = create(:user)
group = create(:group)
@@ -88,8 +88,7 @@ describe MergeRequests::RefreshService, services: true do
# Merge master -> feature branch
author = { email: 'test@gitlab.com', time: Time.now, name: "Me" }
commit_options = { message: 'Test message', committer: author, author: author }
- master_commit = @project.repository.commit('master')
- @project.repository.merge(@user, master_commit.id, 'feature', commit_options)
+ @project.repository.merge(@user, @merge_request, commit_options)
commit = @project.repository.commit('feature')
service.new(@project, @user).execute(@oldrev, commit.id, 'refs/heads/feature')
reload_mrs
diff --git a/spec/services/merge_requests/reopen_service_spec.rb b/spec/services/merge_requests/reopen_service_spec.rb
index ac0221998f5..88c9c640514 100644
--- a/spec/services/merge_requests/reopen_service_spec.rb
+++ b/spec/services/merge_requests/reopen_service_spec.rb
@@ -11,7 +11,7 @@ describe MergeRequests::ReopenService, services: true do
project.team << [user2, :developer]
end
- describe :execute do
+ describe '#execute' do
context 'valid params' do
let(:service) { MergeRequests::ReopenService.new(project, user, {}) }
diff --git a/spec/services/milestones/close_service_spec.rb b/spec/services/milestones/close_service_spec.rb
index 1cd6eb2ab38..5d400299be0 100644
--- a/spec/services/milestones/close_service_spec.rb
+++ b/spec/services/milestones/close_service_spec.rb
@@ -9,7 +9,7 @@ describe Milestones::CloseService, services: true do
project.team << [user, :master]
end
- describe :execute do
+ describe '#execute' do
before do
Milestones::CloseService.new(project, user, {}).execute(milestone)
end
diff --git a/spec/services/milestones/create_service_spec.rb b/spec/services/milestones/create_service_spec.rb
index c793026e300..6d29edb449a 100644
--- a/spec/services/milestones/create_service_spec.rb
+++ b/spec/services/milestones/create_service_spec.rb
@@ -4,7 +4,7 @@ describe Milestones::CreateService, services: true do
let(:project) { create(:empty_project) }
let(:user) { create(:user) }
- describe :execute do
+ describe '#execute' do
context "valid params" do
before do
project.team << [user, :master]
diff --git a/spec/services/notes/create_service_spec.rb b/spec/services/notes/create_service_spec.rb
index 35f576874b8..32753e84b31 100644
--- a/spec/services/notes/create_service_spec.rb
+++ b/spec/services/notes/create_service_spec.rb
@@ -5,7 +5,7 @@ describe Notes::CreateService, services: true do
let(:issue) { create(:issue, project: project) }
let(:user) { create(:user) }
- describe :execute do
+ describe '#execute' do
context "valid params" do
before do
project.team << [user, :master]
diff --git a/spec/services/notes/post_process_service_spec.rb b/spec/services/notes/post_process_service_spec.rb
index d4c50f824c1..e33a611929b 100644
--- a/spec/services/notes/post_process_service_spec.rb
+++ b/spec/services/notes/post_process_service_spec.rb
@@ -5,7 +5,7 @@ describe Notes::PostProcessService, services: true do
let(:issue) { create(:issue, project: project) }
let(:user) { create(:user) }
- describe :execute do
+ describe '#execute' do
before do
project.team << [user, :master]
note_opts = {
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 54719cbb8d8..9fc93f325f7 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -50,7 +50,7 @@ describe NotificationService, services: true do
update_custom_notification(:new_note, @u_custom_global)
end
- describe :new_note do
+ describe '#new_note' do
it do
add_users_with_subscription(note.project, issue)
@@ -293,6 +293,30 @@ describe NotificationService, services: true do
end
end
end
+
+ context "merge request diff note" do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+ let(:merge_request) { create(:merge_request, source_project: project, assignee: user) }
+ let(:note) { create(:diff_note_on_merge_request, project: project, noteable: merge_request) }
+
+ before do
+ build_team(note.project)
+ project.team << [merge_request.author, :master]
+ project.team << [merge_request.assignee, :master]
+ end
+
+ describe '#new_note' do
+ it "records sent notifications" do
+ # Ensure create SentNotification by noteable = merge_request 6 times, not noteable = note
+ expect(SentNotification).to receive(:record_note).with(note, any_args).exactly(4).times.and_call_original
+
+ notification.new_note(note)
+
+ expect(SentNotification.last.position).to eq(note.position)
+ end
+ end
+ end
end
describe 'Issues' do
diff --git a/spec/services/projects/housekeeping_service_spec.rb b/spec/services/projects/housekeeping_service_spec.rb
index bd4dc6a0f79..ad0d58672b3 100644
--- a/spec/services/projects/housekeeping_service_spec.rb
+++ b/spec/services/projects/housekeeping_service_spec.rb
@@ -12,18 +12,28 @@ describe Projects::HousekeepingService do
it 'enqueues a sidekiq job' do
expect(subject).to receive(:try_obtain_lease).and_return(true)
- expect(GitlabShellOneShotWorker).to receive(:perform_async).with(:gc, project.repository_storage_path, project.path_with_namespace)
+ expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id)
subject.execute
- expect(project.pushes_since_gc).to eq(0)
+ expect(project.reload.pushes_since_gc).to eq(0)
end
- it 'does not enqueue a job when no lease can be obtained' do
- expect(subject).to receive(:try_obtain_lease).and_return(false)
- expect(GitlabShellOneShotWorker).not_to receive(:perform_async)
+ context 'when no lease can be obtained' do
+ before(:each) do
+ expect(subject).to receive(:try_obtain_lease).and_return(false)
+ end
- expect { subject.execute }.to raise_error(Projects::HousekeepingService::LeaseTaken)
- expect(project.pushes_since_gc).to eq(0)
+ it 'does not enqueue a job' do
+ expect(GitGarbageCollectWorker).not_to receive(:perform_async)
+
+ expect { subject.execute }.to raise_error(Projects::HousekeepingService::LeaseTaken)
+ end
+
+ it 'does not reset pushes_since_gc' do
+ expect do
+ expect { subject.execute }.to raise_error(Projects::HousekeepingService::LeaseTaken)
+ end.not_to change { project.pushes_since_gc }.from(3)
+ end
end
end
@@ -39,10 +49,24 @@ describe Projects::HousekeepingService do
end
describe 'increment!' do
+ let(:lease_key) { "project_housekeeping:increment!:#{project.id}" }
+
it 'increments the pushes_since_gc counter' do
- expect(project.pushes_since_gc).to eq(0)
- subject.increment!
- expect(project.pushes_since_gc).to eq(1)
+ lease = double(:lease, try_obtain: true)
+ expect(Gitlab::ExclusiveLease).to receive(:new).with(lease_key, anything).and_return(lease)
+
+ expect do
+ subject.increment!
+ end.to change { project.pushes_since_gc }.from(0).to(1)
+ end
+
+ it 'does not increment when no lease can be obtained' do
+ lease = double(:lease, try_obtain: false)
+ expect(Gitlab::ExclusiveLease).to receive(:new).with(lease_key, anything).and_return(lease)
+
+ expect do
+ subject.increment!
+ end.not_to change { project.pushes_since_gc }
end
end
end
diff --git a/spec/services/test_hook_service_spec.rb b/spec/services/test_hook_service_spec.rb
index f034f251ba4..4f47e89b4b5 100644
--- a/spec/services/test_hook_service_spec.rb
+++ b/spec/services/test_hook_service_spec.rb
@@ -5,7 +5,7 @@ describe TestHookService, services: true do
let(:project) { create :project }
let(:hook) { create :project_hook, project: project }
- describe :execute do
+ describe '#execute' do
it "should execute successfully" do
stub_request(:post, hook.url).to_return(status: 200)
expect(TestHookService.new.execute(hook, user)).to be_truthy
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 606da1b7605..3638dcbb2d3 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -33,7 +33,6 @@ RSpec.configure do |config|
config.include LoginHelpers, type: :request
config.include StubConfiguration
config.include EmailHelpers
- config.include RelativeUrl, type: feature
config.include TestEnv
config.include ActiveJob::TestHelper
config.include StubGitlabCalls
diff --git a/spec/support/capybara_helpers.rb b/spec/support/capybara_helpers.rb
index 9b5c3065eed..b57a3493aff 100644
--- a/spec/support/capybara_helpers.rb
+++ b/spec/support/capybara_helpers.rb
@@ -27,6 +27,14 @@ module CapybaraHelpers
end
end
end
+
+ # Refresh the page. Calling `visit current_url` doesn't seem to work consistently.
+ #
+ def refresh
+ url = current_url
+ visit 'about:blank'
+ visit url
+ end
end
RSpec.configure do |config|
diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb
index ffdf2bb0a8a..e5f76afbfc0 100644
--- a/spec/support/login_helpers.rb
+++ b/spec/support/login_helpers.rb
@@ -37,6 +37,40 @@ module LoginHelpers
Thread.current[:current_user] = user
end
+ def login_via(provider, user, uid)
+ mock_auth_hash(provider, uid, user.email)
+ visit new_user_session_path
+ click_link provider
+ end
+
+ def mock_auth_hash(provider, uid, email)
+ # The mock_auth configuration allows you to set per-provider (or default)
+ # authentication hashes to return during integration testing.
+ OmniAuth.config.mock_auth[provider.to_sym] = OmniAuth::AuthHash.new({
+ provider: provider,
+ uid: uid,
+ info: {
+ name: 'mockuser',
+ email: email,
+ image: 'mock_user_thumbnail_url'
+ },
+ credentials: {
+ token: 'mock_token',
+ secret: 'mock_secret'
+ },
+ extra: {
+ raw_info: {
+ info: {
+ name: 'mockuser',
+ email: email,
+ image: 'mock_user_thumbnail_url'
+ }
+ }
+ }
+ })
+ Rails.application.env_config['omniauth.auth'] = OmniAuth.config.mock_auth[:saml]
+ end
+
# Requires Javascript driver.
def logout
find(".header-user-dropdown-toggle").click
diff --git a/spec/support/omni_auth.rb b/spec/support/omni_auth.rb
new file mode 100644
index 00000000000..0b1af4052ff
--- /dev/null
+++ b/spec/support/omni_auth.rb
@@ -0,0 +1 @@
+OmniAuth.config.test_mode = true
diff --git a/spec/support/relative_url.rb b/spec/support/relative_url.rb
deleted file mode 100644
index 72e3ccce75b..00000000000
--- a/spec/support/relative_url.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-# Fix route helpers in tests (e.g. root_path, ...)
-module RelativeUrl
- extend ActiveSupport::Concern
-
- included do
- default_url_options[:script_name] = Rails.application.config.relative_url_root
- end
-end
diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb
index 6b99b0f24cb..bb6c84262f6 100644
--- a/spec/support/test_env.rb
+++ b/spec/support/test_env.rb
@@ -5,19 +5,20 @@ module TestEnv
# When developing the seed repository, comment out the branch you will modify.
BRANCH_SHA = {
- 'empty-branch' => '7efb185',
- 'flatten-dir' => 'e56497b',
- 'feature' => '0b4bc9a',
- 'feature_conflict' => 'bb5206f',
- 'fix' => '48f0be4',
- 'improve/awesome' => '5937ac0',
- 'markdown' => '0ed8c6c',
- 'lfs' => 'be93687',
- 'master' => '5937ac0',
- "'test'" => 'e56497b',
- 'orphaned-branch' => '45127a9',
- 'binary-encoding' => '7b1cf43',
- 'gitattributes' => '5a62481',
+ 'empty-branch' => '7efb185',
+ 'flatten-dir' => 'e56497b',
+ 'feature' => '0b4bc9a',
+ 'feature_conflict' => 'bb5206f',
+ 'fix' => '48f0be4',
+ 'improve/awesome' => '5937ac0',
+ 'markdown' => '0ed8c6c',
+ 'lfs' => 'be93687',
+ 'master' => '5937ac0',
+ "'test'" => 'e56497b',
+ 'orphaned-branch' => '45127a9',
+ 'binary-encoding' => '7b1cf43',
+ 'gitattributes' => '5a62481',
+ 'expand-collapse-diffs' => '4842455'
}
# gitlab-test-fork is a fork of gitlab-fork, but we don't necessarily
diff --git a/spec/workers/git_garbage_collect_worker_spec.rb b/spec/workers/git_garbage_collect_worker_spec.rb
new file mode 100644
index 00000000000..a9cce8b8b59
--- /dev/null
+++ b/spec/workers/git_garbage_collect_worker_spec.rb
@@ -0,0 +1,24 @@
+require 'spec_helper'
+
+describe GitGarbageCollectWorker do
+ let(:project) { create(:project) }
+ let(:shell) { Gitlab::Shell.new }
+
+ subject { GitGarbageCollectWorker.new }
+
+ before do
+ allow(subject).to receive(:gitlab_shell).and_return(shell)
+ end
+
+ describe "#perform" do
+ it "runs `git gc`" do
+ expect(shell).to receive(:gc).with(
+ project.repository_storage_path,
+ project.path_with_namespace).
+ and_return(true)
+ expect_any_instance_of(Repository).to receive(:after_create_branch)
+
+ subject.perform(project.id)
+ end
+ end
+end