diff options
Diffstat (limited to 'spec')
26 files changed, 307 insertions, 117 deletions
diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb index 7c9d522273b..df2714f91ff 100644 --- a/spec/features/cycle_analytics_spec.rb +++ b/spec/features/cycle_analytics_spec.rb @@ -6,7 +6,7 @@ feature 'Cycle Analytics', feature: true, js: true do let(:project) { create(:project, :repository) } let(:issue) { create(:issue, project: project, created_at: 2.days.ago) } let(:milestone) { create(:milestone, project: project) } - let(:mr) { create_merge_request_closing_issue(issue) } + let(:mr) { create_merge_request_closing_issue(issue, commit_message: "References #{issue.to_reference}") } let(:pipeline) { create(:ci_empty_pipeline, status: 'created', project: project, ref: mr.source_branch, sha: mr.source_branch_sha) } context 'as an allowed user' do @@ -32,7 +32,6 @@ feature 'Cycle Analytics', feature: true, js: true do before do project.team << [user, :master] - allow_any_instance_of(Gitlab::ReferenceExtractor).to receive(:issues).and_return([issue]) create_cycle deploy_master diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb index 8e0306ce83b..7668ce5f8be 100644 --- a/spec/features/projects/branches_spec.rb +++ b/spec/features/projects/branches_spec.rb @@ -4,7 +4,13 @@ describe 'Branches', feature: true do let(:project) { create(:project, :public) } let(:repository) { project.repository } - context 'logged in' do + def set_protected_branch_name(branch_name) + find(".js-protected-branch-select").click + find(".dropdown-input-field").set(branch_name) + click_on("Create wildcard #{branch_name}") + end + + context 'logged in as developer' do before do login_as :user project.team << [@user, :developer] @@ -38,6 +44,83 @@ describe 'Branches', feature: true do expect(find('.all-branches')).to have_selector('li', count: 1) end end + + describe 'Delete unprotected branch' do + it 'removes branch after confirmation', js: true do + visit namespace_project_branches_path(project.namespace, project) + + fill_in 'branch-search', with: 'fix' + + find('#branch-search').native.send_keys(:enter) + + expect(page).to have_content('fix') + expect(find('.all-branches')).to have_selector('li', count: 1) + find('.js-branch-fix .btn-remove').trigger(:click) + + expect(page).not_to have_content('fix') + expect(find('.all-branches')).to have_selector('li', count: 0) + end + end + + describe 'Delete protected branch' do + before do + project.add_user(@user, :master) + visit namespace_project_protected_branches_path(project.namespace, project) + set_protected_branch_name('fix') + click_on "Protect" + + within(".protected-branches-list") { expect(page).to have_content('fix') } + expect(ProtectedBranch.count).to eq(1) + project.add_user(@user, :developer) + end + + it 'does not allow devleoper to removes protected branch', js: true do + visit namespace_project_branches_path(project.namespace, project) + + fill_in 'branch-search', with: 'fix' + find('#branch-search').native.send_keys(:enter) + + expect(page).to have_css('.btn-remove.disabled') + end + end + end + + context 'logged in as master' do + before do + login_as :user + project.team << [@user, :master] + end + + describe 'Delete protected branch' do + before do + visit namespace_project_protected_branches_path(project.namespace, project) + set_protected_branch_name('fix') + click_on "Protect" + + within(".protected-branches-list") { expect(page).to have_content('fix') } + expect(ProtectedBranch.count).to eq(1) + end + + it 'removes branch after modal confirmation', js: true do + visit namespace_project_branches_path(project.namespace, project) + + fill_in 'branch-search', with: 'fix' + find('#branch-search').native.send_keys(:enter) + + expect(page).to have_content('fix') + expect(find('.all-branches')).to have_selector('li', count: 1) + page.find('[data-target="#modal-delete-branch"]').trigger(:click) + + expect(page).to have_css('.js-delete-branch[disabled]') + fill_in 'delete_branch_input', with: 'fix' + click_link 'Delete protected branch' + + fill_in 'branch-search', with: 'fix' + find('#branch-search').native.send_keys(:enter) + + expect(page).to have_content('No branches to show') + end + end end context 'logged out' do diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb index 957baac02eb..698eb46573f 100644 --- a/spec/features/snippets/notes_on_personal_snippets_spec.rb +++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb @@ -78,9 +78,11 @@ describe 'Comments on personal snippets', :js, feature: true do end page.within("#notes-list li#note_#{snippet_notes[0].id}") do + edited_text = find('.edited-text') + expect(page).to have_css('.note_edited_ago') expect(page).to have_content('new content') - expect(find('.note_edited_ago').text).to match(/less than a minute ago/) + expect(edited_text).to have_selector('.note_edited_ago') end end end diff --git a/spec/javascripts/behaviors/bind_in_out_spec.js b/spec/javascripts/behaviors/bind_in_out_spec.js index dd9ab33289f..5ff66167718 100644 --- a/spec/javascripts/behaviors/bind_in_out_spec.js +++ b/spec/javascripts/behaviors/bind_in_out_spec.js @@ -2,7 +2,7 @@ import BindInOut from '~/behaviors/bind_in_out'; import ClassSpecHelper from '../helpers/class_spec_helper'; describe('BindInOut', function () { - describe('.constructor', function () { + describe('constructor', function () { beforeEach(function () { this.in = {}; this.out = {}; @@ -53,7 +53,7 @@ describe('BindInOut', function () { }); }); - describe('.addEvents', function () { + describe('addEvents', function () { beforeEach(function () { this.in = jasmine.createSpyObj('in', ['addEventListener']); @@ -79,7 +79,7 @@ describe('BindInOut', function () { }); }); - describe('.updateOut', function () { + describe('updateOut', function () { beforeEach(function () { this.in = { value: 'the-value' }; this.out = { textContent: 'not-the-value' }; @@ -98,7 +98,7 @@ describe('BindInOut', function () { }); }); - describe('.removeEvents', function () { + describe('removeEvents', function () { beforeEach(function () { this.in = jasmine.createSpyObj('in', ['removeEventListener']); this.updateOut = () => {}; @@ -122,7 +122,7 @@ describe('BindInOut', function () { }); }); - describe('.initAll', function () { + describe('initAll', function () { beforeEach(function () { this.ins = [0, 1, 2]; this.instances = []; @@ -153,7 +153,7 @@ describe('BindInOut', function () { }); }); - describe('.init', function () { + describe('init', function () { beforeEach(function () { spyOn(BindInOut.prototype, 'addEvents').and.callFake(function () { return this; }); spyOn(BindInOut.prototype, 'updateOut').and.callFake(function () { return this; }); diff --git a/spec/javascripts/blob/target_branch_dropdown_spec.js b/spec/javascripts/blob/target_branch_dropdown_spec.js index 4fb79663c51..bb436978a0f 100644 --- a/spec/javascripts/blob/target_branch_dropdown_spec.js +++ b/spec/javascripts/blob/target_branch_dropdown_spec.js @@ -63,7 +63,7 @@ describe('TargetBranchDropdown', () => { expect('change.branch').toHaveBeenTriggeredOn(dropdown.$dropdown); }); - describe('#dropdownData', () => { + describe('dropdownData', () => { it('cache the refs', () => { const refs = dropdown.cachedRefs; dropdown.cachedRefs = null; @@ -88,7 +88,7 @@ describe('TargetBranchDropdown', () => { }); }); - describe('#setNewBranch', () => { + describe('setNewBranch', () => { it('adds the new branch and select it', () => { const branchName = 'new_branch'; diff --git a/spec/javascripts/gl_form_spec.js b/spec/javascripts/gl_form_spec.js index 71d6e2a7e22..5ed18d0a76b 100644 --- a/spec/javascripts/gl_form_spec.js +++ b/spec/javascripts/gl_form_spec.js @@ -32,7 +32,7 @@ describe('GLForm', () => { }); }); - describe('.setupAutosize', () => { + describe('setupAutosize', () => { beforeEach((done) => { this.glForm.setupAutosize(); setTimeout(() => { @@ -59,7 +59,7 @@ describe('GLForm', () => { }); }); - describe('.setHeightData', () => { + describe('setHeightData', () => { beforeEach(() => { spyOn($.prototype, 'data'); spyOn($.prototype, 'outerHeight').and.returnValue(200); @@ -75,7 +75,7 @@ describe('GLForm', () => { }); }); - describe('.destroyAutosize', () => { + describe('destroyAutosize', () => { describe('when called', () => { beforeEach(() => { spyOn($.prototype, 'data'); diff --git a/spec/javascripts/helpers/class_spec_helper_spec.js b/spec/javascripts/helpers/class_spec_helper_spec.js index 0a61e561640..a1cfc8ba820 100644 --- a/spec/javascripts/helpers/class_spec_helper_spec.js +++ b/spec/javascripts/helpers/class_spec_helper_spec.js @@ -3,7 +3,7 @@ require('./class_spec_helper'); describe('ClassSpecHelper', () => { - describe('.itShouldBeAStaticMethod', function () { + describe('itShouldBeAStaticMethod', function () { beforeEach(() => { class TestClass { instanceMethod() { this.prop = 'val'; } diff --git a/spec/javascripts/line_highlighter_spec.js b/spec/javascripts/line_highlighter_spec.js index a1fd2d38968..b1b08989028 100644 --- a/spec/javascripts/line_highlighter_spec.js +++ b/spec/javascripts/line_highlighter_spec.js @@ -58,7 +58,7 @@ require('~/line_highlighter'); return expect(func).not.toThrow(); }); }); - describe('#clickHandler', function() { + describe('clickHandler', function() { it('handles clicking on a child icon element', function() { var spy; spy = spyOn(this["class"], 'setHash').and.callThrough(); @@ -176,7 +176,7 @@ require('~/line_highlighter'); }); }); }); - describe('#hashToRange', function() { + describe('hashToRange', function() { beforeEach(function() { return this.subject = this["class"].hashToRange; }); @@ -190,7 +190,7 @@ require('~/line_highlighter'); return expect(this.subject('#foo')).toEqual([null, null]); }); }); - describe('#highlightLine', function() { + describe('highlightLine', function() { beforeEach(function() { return this.subject = this["class"].highlightLine; }); @@ -203,7 +203,7 @@ require('~/line_highlighter'); return expect($('#LC13')).toHaveClass(this.css); }); }); - return describe('#setHash', function() { + return describe('setHash', function() { beforeEach(function() { return this.subject = this["class"].setHash; }); diff --git a/spec/javascripts/merge_request_tabs_spec.js b/spec/javascripts/merge_request_tabs_spec.js index e437333d522..254a41db160 100644 --- a/spec/javascripts/merge_request_tabs_spec.js +++ b/spec/javascripts/merge_request_tabs_spec.js @@ -47,7 +47,7 @@ require('vendor/jquery.scrollTo'); this.class.destroyPipelinesView(); }); - describe('#activateTab', function () { + describe('activateTab', function () { beforeEach(function () { spyOn($, 'ajax').and.callFake(function () {}); loadFixtures('merge_requests/merge_request_with_task_list.html.raw'); @@ -71,7 +71,7 @@ require('vendor/jquery.scrollTo'); }); }); - describe('#opensInNewTab', function () { + describe('opensInNewTab', function () { var tabUrl; var windowTarget = '_blank'; @@ -152,7 +152,7 @@ require('vendor/jquery.scrollTo'); }); }); - describe('#setCurrentAction', function () { + describe('setCurrentAction', function () { beforeEach(function () { spyOn($, 'ajax').and.callFake(function () {}); this.subject = this.class.setCurrentAction; @@ -221,7 +221,7 @@ require('vendor/jquery.scrollTo'); }); }); - describe('#tabShown', () => { + describe('tabShown', () => { beforeEach(function () { spyOn($, 'ajax').and.callFake(function (options) { options.success({ html: '' }); @@ -281,7 +281,7 @@ require('vendor/jquery.scrollTo'); }); }); - describe('#loadDiff', function () { + describe('loadDiff', function () { it('requires an absolute pathname', function () { spyOn($, 'ajax').and.callFake(function (options) { expect(options.url).toEqual('/foo/bar/merge_requests/1/diffs.json'); diff --git a/spec/javascripts/shortcuts_issuable_spec.js b/spec/javascripts/shortcuts_issuable_spec.js index 9e19dabd0e3..757b8d595a4 100644 --- a/spec/javascripts/shortcuts_issuable_spec.js +++ b/spec/javascripts/shortcuts_issuable_spec.js @@ -13,7 +13,7 @@ require('~/shortcuts_issuable'); document.querySelector('.js-new-note-form').classList.add('js-main-target-form'); this.shortcut = new ShortcutsIssuable(); }); - describe('#replyWithSelectedText', function() { + describe('replyWithSelectedText', function() { var stubSelection; // Stub window.gl.utils.getSelectedFragment to return a node with the provided HTML. stubSelection = function(html) { diff --git a/spec/javascripts/test_bundle.js b/spec/javascripts/test_bundle.js index 07dc51a7815..92428fd501c 100644 --- a/spec/javascripts/test_bundle.js +++ b/spec/javascripts/test_bundle.js @@ -1,8 +1,8 @@ // enable test fixtures require('jasmine-jquery'); -jasmine.getFixtures().fixturesPath = 'base/spec/javascripts/fixtures'; -jasmine.getJSONFixtures().fixturesPath = 'base/spec/javascripts/fixtures'; +jasmine.getFixtures().fixturesPath = '/base/spec/javascripts/fixtures'; +jasmine.getJSONFixtures().fixturesPath = '/base/spec/javascripts/fixtures'; // include common libraries require('~/commons/index.js'); diff --git a/spec/javascripts/version_check_image_spec.js b/spec/javascripts/version_check_image_spec.js index 464c1fce210..83ffeca253a 100644 --- a/spec/javascripts/version_check_image_spec.js +++ b/spec/javascripts/version_check_image_spec.js @@ -3,7 +3,7 @@ const VersionCheckImage = require('~/version_check_image'); require('jquery'); describe('VersionCheckImage', function () { - describe('.bindErrorEvent', function () { + describe('bindErrorEvent', function () { ClassSpecHelper.itShouldBeAStaticMethod(VersionCheckImage, 'bindErrorEvent'); beforeEach(function () { diff --git a/spec/javascripts/visibility_select_spec.js b/spec/javascripts/visibility_select_spec.js index 9727c03c91e..b26ed41f27a 100644 --- a/spec/javascripts/visibility_select_spec.js +++ b/spec/javascripts/visibility_select_spec.js @@ -22,7 +22,7 @@ require('~/visibility_select'); spyOn(Element.prototype, 'querySelector').and.callFake(selector => mockElements[selector]); }); - describe('#constructor', function () { + describe('constructor', function () { beforeEach(function () { this.visibilitySelect = new VisibilitySelect(mockElements.container); }); @@ -48,7 +48,7 @@ require('~/visibility_select'); }); }); - describe('#init', function () { + describe('init', function () { describe('if there is a select', function () { beforeEach(function () { this.visibilitySelect = new VisibilitySelect(mockElements.container); @@ -85,7 +85,7 @@ require('~/visibility_select'); }); }); - describe('#updateHelpText', function () { + describe('updateHelpText', function () { beforeEach(function () { this.visibilitySelect = new VisibilitySelect(mockElements.container); this.visibilitySelect.init(); diff --git a/spec/lib/gitlab/checks/change_access_spec.rb b/spec/lib/gitlab/checks/change_access_spec.rb index 959ae02c222..8d81ed5856e 100644 --- a/spec/lib/gitlab/checks/change_access_spec.rb +++ b/spec/lib/gitlab/checks/change_access_spec.rb @@ -96,40 +96,77 @@ describe Gitlab::Checks::ChangeAccess, lib: true do end end - context 'protected branches check' do - before do - allow(ProtectedBranch).to receive(:protected?).with(project, 'master').and_return(true) - end - - it 'returns an error if the user is not allowed to do forced pushes to protected branches' do - expect(Gitlab::Checks::ForcePush).to receive(:force_push?).and_return(true) + context 'branches check' do + context 'trying to delete the default branch' do + let(:newrev) { '0000000000000000000000000000000000000000' } + let(:ref) { 'refs/heads/master' } - expect(subject.status).to be(false) - expect(subject.message).to eq('You are not allowed to force push code to a protected branch on this project.') + it 'returns an error' do + expect(subject.status).to be(false) + expect(subject.message).to eq('The default branch of a project cannot be deleted.') + end end - it 'returns an error if the user is not allowed to merge to protected branches' do - expect_any_instance_of(Gitlab::Checks::MatchingMergeRequest).to receive(:match?).and_return(true) - expect(user_access).to receive(:can_merge_to_branch?).and_return(false) - expect(user_access).to receive(:can_push_to_branch?).and_return(false) + context 'protected branches check' do + before do + allow(ProtectedBranch).to receive(:protected?).with(project, 'master').and_return(true) + allow(ProtectedBranch).to receive(:protected?).with(project, 'feature').and_return(true) + end - expect(subject.status).to be(false) - expect(subject.message).to eq('You are not allowed to merge code into protected branches on this project.') - end + it 'returns an error if the user is not allowed to do forced pushes to protected branches' do + expect(Gitlab::Checks::ForcePush).to receive(:force_push?).and_return(true) - it 'returns an error if the user is not allowed to push to protected branches' do - expect(user_access).to receive(:can_push_to_branch?).and_return(false) + expect(subject.status).to be(false) + expect(subject.message).to eq('You are not allowed to force push code to a protected branch on this project.') + end - expect(subject.status).to be(false) - expect(subject.message).to eq('You are not allowed to push code to protected branches on this project.') - end + it 'returns an error if the user is not allowed to merge to protected branches' do + expect_any_instance_of(Gitlab::Checks::MatchingMergeRequest).to receive(:match?).and_return(true) + expect(user_access).to receive(:can_merge_to_branch?).and_return(false) + expect(user_access).to receive(:can_push_to_branch?).and_return(false) - context 'branch deletion' do - let(:newrev) { '0000000000000000000000000000000000000000' } + expect(subject.status).to be(false) + expect(subject.message).to eq('You are not allowed to merge code into protected branches on this project.') + end + + it 'returns an error if the user is not allowed to push to protected branches' do + expect(user_access).to receive(:can_push_to_branch?).and_return(false) - it 'returns an error if the user is not allowed to delete protected branches' do expect(subject.status).to be(false) - expect(subject.message).to eq('You are not allowed to delete protected branches from this project.') + expect(subject.message).to eq('You are not allowed to push code to protected branches on this project.') + end + + context 'branch deletion' do + let(:newrev) { '0000000000000000000000000000000000000000' } + let(:ref) { 'refs/heads/feature' } + + context 'if the user is not allowed to delete protected branches' do + it 'returns an error' do + expect(subject.status).to be(false) + expect(subject.message).to eq('You are not allowed to delete protected branches from this project. Only a project master or owner can delete a protected branch.') + end + end + + context 'if the user is allowed to delete protected branches' do + before do + project.add_master(user) + end + + context 'through the web interface' do + let(:protocol) { 'web' } + + it 'allows branch deletion' do + expect(subject.status).to be(true) + end + end + + context 'over SSH or HTTP' do + it 'returns an error' do + expect(subject.status).to be(false) + expect(subject.message).to eq('You can only delete protected branches using the web interface.') + end + end + end end end end diff --git a/spec/lib/gitlab/cycle_analytics/events_spec.rb b/spec/lib/gitlab/cycle_analytics/events_spec.rb index 9d2ba481919..0d56bdd0ebd 100644 --- a/spec/lib/gitlab/cycle_analytics/events_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/events_spec.rb @@ -11,8 +11,6 @@ describe 'cycle analytics events' do end before do - allow_any_instance_of(Gitlab::ReferenceExtractor).to receive(:issues).and_return([context]) - setup(context) end @@ -332,7 +330,7 @@ describe 'cycle analytics events' do def setup(context) milestone = create(:milestone, project: project) context.update(milestone: milestone) - mr = create_merge_request_closing_issue(context) + mr = create_merge_request_closing_issue(context, commit_message: "References #{context.to_reference}") ProcessCommitWorker.new.perform(project.id, user.id, mr.commits.last.to_hash) end diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb index d8b72615fab..25769977f24 100644 --- a/spec/lib/gitlab/git_access_spec.rb +++ b/spec/lib/gitlab/git_access_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Gitlab::GitAccess, lib: true do - let(:access) { Gitlab::GitAccess.new(actor, project, 'web', authentication_abilities: authentication_abilities) } + let(:access) { Gitlab::GitAccess.new(actor, project, 'ssh', authentication_abilities: authentication_abilities) } let(:project) { create(:project, :repository) } let(:user) { create(:user) } let(:actor) { user } diff --git a/spec/lib/gitlab/user_access_spec.rb b/spec/lib/gitlab/user_access_spec.rb index 2b27ff66c09..0d87cf25dbb 100644 --- a/spec/lib/gitlab/user_access_spec.rb +++ b/spec/lib/gitlab/user_access_spec.rb @@ -5,7 +5,7 @@ describe Gitlab::UserAccess, lib: true do let(:project) { create(:project) } let(:user) { create(:user) } - describe 'can_push_to_branch?' do + describe '#can_push_to_branch?' do describe 'push to none protected branch' do it 'returns true if user is a master' do project.team << [user, :master] @@ -143,7 +143,7 @@ describe Gitlab::UserAccess, lib: true do end end - describe 'can_create_tag?' do + describe '#can_create_tag?' do describe 'push to none protected tag' do it 'returns true if user is a master' do project.add_user(user, :master) @@ -211,4 +211,48 @@ describe Gitlab::UserAccess, lib: true do end end end + + describe '#can_delete_branch?' do + describe 'delete unprotected branch' do + it 'returns true if user is a master' do + project.add_user(user, :master) + + expect(access.can_delete_branch?('random_branch')).to be_truthy + end + + it 'returns true if user is a developer' do + project.add_user(user, :developer) + + expect(access.can_delete_branch?('random_branch')).to be_truthy + end + + it 'returns false if user is a reporter' do + project.add_user(user, :reporter) + + expect(access.can_delete_branch?('random_branch')).to be_falsey + end + end + + describe 'delete protected branch' do + let(:branch) { create(:protected_branch, project: project, name: "test") } + + it 'returns true if user is a master' do + project.add_user(user, :master) + + expect(access.can_delete_branch?(branch.name)).to be_truthy + end + + it 'returns false if user is a developer' do + project.add_user(user, :developer) + + expect(access.can_delete_branch?(branch.name)).to be_falsey + end + + it 'returns false if user is a reporter' do + project.add_user(user, :reporter) + + expect(access.can_delete_branch?(branch.name)).to be_falsey + end + end + end end diff --git a/spec/models/concerns/mentionable_spec.rb b/spec/models/concerns/mentionable_spec.rb index 2092576e981..e382c7120de 100644 --- a/spec/models/concerns/mentionable_spec.rb +++ b/spec/models/concerns/mentionable_spec.rb @@ -163,3 +163,52 @@ describe Issue, "Mentionable" do end end end + +describe Commit, 'Mentionable' do + let(:project) { create(:project, :public, :repository) } + let(:commit) { project.commit } + + describe '#matches_cross_reference_regex?' do + it "is false when message doesn't reference anything" do + allow(commit.raw).to receive(:message).and_return "WIP: Do something" + + expect(commit.matches_cross_reference_regex?).to be false + end + + it 'is true if issue #number mentioned in title' do + allow(commit.raw).to receive(:message).and_return "#1" + + expect(commit.matches_cross_reference_regex?).to be true + end + + it 'is true if references an MR' do + allow(commit.raw).to receive(:message).and_return "See merge request !12" + + expect(commit.matches_cross_reference_regex?).to be true + end + + it 'is true if references a commit' do + allow(commit.raw).to receive(:message).and_return "a1b2c3d4" + + expect(commit.matches_cross_reference_regex?).to be true + end + + it 'is true if issue referenced by url' do + issue = create(:issue, project: project) + + allow(commit.raw).to receive(:message).and_return Gitlab::UrlBuilder.build(issue) + + expect(commit.matches_cross_reference_regex?).to be true + end + + context 'with external issue tracker' do + let(:project) { create(:jira_project) } + + it 'is true if external issues referenced' do + allow(commit.raw).to receive(:message).and_return 'JIRA-123' + + expect(commit.matches_cross_reference_regex?).to be true + end + end + end +end diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index 064847ee3dc..0d3af1f4499 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -43,7 +43,7 @@ describe ProjectPolicy, models: true do let(:master_permissions) do %i[ - push_code_to_protected_branches update_project_snippet update_environment + delete_protected_branch update_project_snippet update_environment update_deployment admin_milestone admin_project_snippet admin_project_member admin_note admin_wiki admin_project admin_commit_status admin_build admin_container_image diff --git a/spec/requests/api/branches_spec.rb b/spec/requests/api/branches_spec.rb index 7eaa89837c8..c64499fc8c0 100644 --- a/spec/requests/api/branches_spec.rb +++ b/spec/requests/api/branches_spec.rb @@ -406,19 +406,6 @@ describe API::Branches do delete api("/projects/#{project.id}/repository/branches/foobar", user) expect(response).to have_http_status(404) end - - it "removes protected branch" do - create(:protected_branch, project: project, name: branch_name) - delete api("/projects/#{project.id}/repository/branches/#{branch_name}", user) - expect(response).to have_http_status(405) - expect(json_response['message']).to eq('Protected branch cant be removed') - end - - it "does not remove HEAD branch" do - delete api("/projects/#{project.id}/repository/branches/master", user) - expect(response).to have_http_status(405) - expect(json_response['message']).to eq('Cannot remove HEAD branch') - end end describe "DELETE /projects/:id/repository/merged_branches" do diff --git a/spec/requests/api/v3/branches_spec.rb b/spec/requests/api/v3/branches_spec.rb index 72f8fbe71fb..c88f7788697 100644 --- a/spec/requests/api/v3/branches_spec.rb +++ b/spec/requests/api/v3/branches_spec.rb @@ -47,19 +47,6 @@ describe API::V3::Branches do delete v3_api("/projects/#{project.id}/repository/branches/foobar", user) expect(response).to have_http_status(404) end - - it "removes protected branch" do - create(:protected_branch, project: project, name: branch_name) - delete v3_api("/projects/#{project.id}/repository/branches/#{branch_name}", user) - expect(response).to have_http_status(405) - expect(json_response['message']).to eq('Protected branch cant be removed') - end - - it "does not remove HEAD branch" do - delete v3_api("/projects/#{project.id}/repository/branches/master", user) - expect(response).to have_http_status(405) - expect(json_response['message']).to eq('Cannot remove HEAD branch') - end end describe "DELETE /projects/:id/repository/merged_branches" do diff --git a/spec/requests/projects/cycle_analytics_events_spec.rb b/spec/requests/projects/cycle_analytics_events_spec.rb index 33940f70b1c..c5a45949841 100644 --- a/spec/requests/projects/cycle_analytics_events_spec.rb +++ b/spec/requests/projects/cycle_analytics_events_spec.rb @@ -9,8 +9,6 @@ describe 'cycle analytics events', api: true do before do project.team << [user, :developer] - allow_any_instance_of(Gitlab::ReferenceExtractor).to receive(:issues).and_return([issue]) - 3.times do |count| Timecop.freeze(Time.now + count.days) do create_cycle @@ -121,7 +119,7 @@ describe 'cycle analytics events', api: true do def create_cycle milestone = create(:milestone, project: project) issue.update(milestone: milestone) - mr = create_merge_request_closing_issue(issue) + mr = create_merge_request_closing_issue(issue, commit_message: "References #{issue.to_reference}") pipeline = create(:ci_empty_pipeline, status: 'created', project: project, ref: mr.source_branch, sha: mr.source_branch_sha) pipeline.run diff --git a/spec/services/delete_merged_branches_service_spec.rb b/spec/services/delete_merged_branches_service_spec.rb index 7b921f606f8..cae74df9c90 100644 --- a/spec/services/delete_merged_branches_service_spec.rb +++ b/spec/services/delete_merged_branches_service_spec.rb @@ -6,33 +6,22 @@ describe DeleteMergedBranchesService, services: true do let(:project) { create(:project, :repository) } context '#execute' do - context 'unprotected branches' do - before do - service.execute - end + it 'deletes a branch that was merged' do + service.execute - it 'deletes a branch that was merged' do - expect(project.repository.branch_names).not_to include('improve/awesome') - end + expect(project.repository.branch_names).not_to include('improve/awesome') + end - it 'keeps branch that is unmerged' do - expect(project.repository.branch_names).to include('feature') - end + it 'keeps branch that is unmerged' do + service.execute - it 'keeps "master"' do - expect(project.repository.branch_names).to include('master') - end + expect(project.repository.branch_names).to include('feature') end - context 'protected branches' do - before do - create(:protected_branch, name: 'improve/awesome', project: project) - service.execute - end + it 'keeps "master"' do + service.execute - it 'keeps protected branch' do - expect(project.repository.branch_names).to include('improve/awesome') - end + expect(project.repository.branch_names).to include('master') end context 'user without rights' do diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb index 0477cac6677..8c2415b4e07 100644 --- a/spec/services/git_push_service_spec.rb +++ b/spec/services/git_push_service_spec.rb @@ -622,12 +622,21 @@ describe GitPushService, services: true do it 'only schedules a limited number of commits' do allow(service).to receive(:push_commits). - and_return(Array.new(1000, double(:commit, to_hash: {}))) + and_return(Array.new(1000, double(:commit, to_hash: {}, matches_cross_reference_regex?: true))) expect(ProcessCommitWorker).to receive(:perform_async).exactly(100).times service.process_commit_messages end + + it "skips commits which don't include cross-references" do + allow(service).to receive(:push_commits). + and_return([double(:commit, to_hash: {}, matches_cross_reference_regex?: false)]) + + expect(ProcessCommitWorker).not_to receive(:perform_async) + + service.process_commit_messages + end end def execute_service(project, user, oldrev, newrev, ref) diff --git a/spec/support/cycle_analytics_helpers.rb b/spec/support/cycle_analytics_helpers.rb index 8ad042f5e3b..66545127a44 100644 --- a/spec/support/cycle_analytics_helpers.rb +++ b/spec/support/cycle_analytics_helpers.rb @@ -20,7 +20,7 @@ module CycleAnalyticsHelpers ref: 'refs/heads/master').execute end - def create_merge_request_closing_issue(issue, message: nil, source_branch: nil) + def create_merge_request_closing_issue(issue, message: nil, source_branch: nil, commit_message: 'commit message') if !source_branch || project.repository.commit(source_branch).blank? source_branch = generate(:branch) project.repository.add_branch(user, source_branch, 'master') @@ -30,7 +30,7 @@ module CycleAnalyticsHelpers user, generate(:branch), 'content', - message: 'commit message', + message: commit_message, branch_name: source_branch) project.repository.commit(sha) diff --git a/spec/workers/process_commit_worker_spec.rb b/spec/workers/process_commit_worker_spec.rb index 9afe2e610b9..6295856b461 100644 --- a/spec/workers/process_commit_worker_spec.rb +++ b/spec/workers/process_commit_worker_spec.rb @@ -20,6 +20,14 @@ describe ProcessCommitWorker do worker.perform(project.id, -1, commit.to_hash) end + it 'does not process the commit when no issues are referenced' do + allow(worker).to receive(:build_commit).and_return(double(matches_cross_reference_regex?: false)) + + expect(worker).not_to receive(:process_commit_message) + + worker.perform(project.id, user.id, commit.to_hash) + end + it 'processes the commit message' do expect(worker).to receive(:process_commit_message).and_call_original |