Skip to content
Snippets Groups Projects
Unverified Commit ad8eea38 authored by Yorick Peterse's avatar Yorick Peterse
Browse files

Merge dev.gitlab.org@master into GitLab.com@master

parents 228d752f b0f939a7
No related branches found
No related tags found
No related merge requests found
Showing
with 661 additions and 81 deletions
Loading
Loading
@@ -15,7 +15,7 @@ describe 'User views tags', :feature do
it do
visit project_tags_path(project, format: :atom)
 
expect(page).to have_gitlab_http_status(401)
expect(page.current_path).to eq("/users/sign_in")
end
end
 
Loading
Loading
Loading
Loading
@@ -128,6 +128,89 @@ describe LabelsFinder do
expect(finder.execute).to eq [private_subgroup_label_1]
end
end
context 'when including labels from group projects with limited visibility' do
let(:finder) { described_class.new(user, group_id: group_4.id) }
let(:group_4) { create(:group) }
let(:limited_visibility_project) { create(:project, :public, group: group_4) }
let(:visible_project) { create(:project, :public, group: group_4) }
let!(:group_label_1) { create(:group_label, group: group_4) }
let!(:limited_visibility_label) { create(:label, project: limited_visibility_project) }
let!(:visible_label) { create(:label, project: visible_project) }
shared_examples 'with full visibility' do
it 'returns all projects labels' do
expect(finder.execute).to eq [group_label_1, limited_visibility_label, visible_label]
end
end
shared_examples 'with limited visibility' do
it 'returns only authorized projects labels' do
expect(finder.execute).to eq [group_label_1, visible_label]
end
end
context 'when merge requests and issues are not visible for non members' do
before do
limited_visibility_project.project_feature.update!(
merge_requests_access_level: ProjectFeature::PRIVATE,
issues_access_level: ProjectFeature::PRIVATE
)
end
context 'when user is not a group member' do
it_behaves_like 'with limited visibility'
end
context 'when user is a group member' do
before do
group_4.add_developer(user)
end
it_behaves_like 'with full visibility'
end
end
context 'when merge requests are not visible for non members' do
before do
limited_visibility_project.project_feature.update!(
merge_requests_access_level: ProjectFeature::PRIVATE
)
end
context 'when user is not a group member' do
it_behaves_like 'with full visibility'
end
context 'when user is a group member' do
before do
group_4.add_developer(user)
end
it_behaves_like 'with full visibility'
end
end
context 'when issues are not visible for non members' do
before do
limited_visibility_project.project_feature.update!(
issues_access_level: ProjectFeature::PRIVATE
)
end
context 'when user is not a group member' do
it_behaves_like 'with full visibility'
end
context 'when user is a group member' do
before do
group_4.add_developer(user)
end
it_behaves_like 'with full visibility'
end
end
end
end
 
context 'filtering by project_id' do
Loading
Loading
query allSchemaTypes {
__schema {
types {
fields {
type{
fields {
type {
fields {
type {
fields {
type {
fields {
type {
fields {
type {
fields {
type {
fields {
type {
fields {
type {
fields {
type {
fields {
type {
fields {
type {
fields {
name
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
\ No newline at end of file
{
project(fullPath: "gitlab-org/gitlab-ce") {
group {
projects {
edges {
node {
group {
projects {
edges {
node {
group {
projects {
edges {
node {
group {
projects {
edges {
node {
group {
projects {
edges {
node {
group {
description
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
query allSchemaTypes {
__schema {
types {
fields {
type {
fields {
type {
name
}
}
}
}
}
}
}
Loading
Loading
@@ -3,6 +3,9 @@ import $ from 'jquery';
import ProjectFindFile from '~/project_find_file';
import axios from '~/lib/utils/axios_utils';
import { TEST_HOST } from 'helpers/test_constants';
import sanitize from 'sanitize-html';
jest.mock('sanitize-html', () => jest.fn(val => val));
 
const BLOB_URL_TEMPLATE = `${TEST_HOST}/namespace/project/blob/master`;
const FILE_FIND_URL = `${TEST_HOST}/namespace/project/files/master?format=json`;
Loading
Loading
@@ -38,31 +41,31 @@ describe('ProjectFindFile', () => {
href: el.querySelector('a').href,
}));
 
const files = [
'fileA.txt',
'fileB.txt',
'fi#leC.txt',
'folderA/fileD.txt',
'folder#B/fileE.txt',
'folde?rC/fil#F.txt',
];
beforeEach(() => {
// Create a mock adapter for stubbing axios API requests
mock = new MockAdapter(axios);
 
element = $(TEMPLATE);
mock.onGet(FILE_FIND_URL).replyOnce(200, files);
getProjectFindFileInstance(); // This triggers a load / axios call + subsequent render in the constructor
});
 
afterEach(() => {
// Reset the mock adapter
mock.restore();
sanitize.mockClear();
});
 
it('loads and renders elements from remote server', done => {
const files = [
'fileA.txt',
'fileB.txt',
'fi#leC.txt',
'folderA/fileD.txt',
'folder#B/fileE.txt',
'folde?rC/fil#F.txt',
];
mock.onGet(FILE_FIND_URL).replyOnce(200, files);
getProjectFindFileInstance(); // This triggers a load / axios call + subsequent render in the constructor
setImmediate(() => {
expect(findFiles()).toEqual(
files.map(text => ({
Loading
Loading
@@ -74,4 +77,14 @@ describe('ProjectFindFile', () => {
done();
});
});
it('sanitizes search text', done => {
const searchText = element.find('.file-finder-input').val();
setImmediate(() => {
expect(sanitize).toHaveBeenCalledTimes(1);
expect(sanitize).toHaveBeenCalledWith(searchText);
done();
});
});
});
Loading
Loading
@@ -3,18 +3,18 @@
require 'spec_helper'
 
describe MarkupHelper do
let!(:project) { create(:project, :repository) }
let(:user) { create(:user, username: 'gfm') }
let(:commit) { project.commit }
let(:issue) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:snippet) { create(:project_snippet, project: project) }
before do
# Ensure the generated reference links aren't redacted
set(:project) { create(:project, :repository) }
set(:user) do
user = create(:user, username: 'gfm')
project.add_maintainer(user)
user
end
set(:issue) { create(:issue, project: project) }
set(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
set(:snippet) { create(:project_snippet, project: project) }
let(:commit) { project.commit }
 
before do
# Helper expects a @project instance variable
helper.instance_variable_set(:@project, project)
 
Loading
Loading
@@ -44,8 +44,8 @@ describe MarkupHelper do
 
describe "override default project" do
let(:actual) { issue.to_reference }
let(:second_project) { create(:project, :public) }
let(:second_issue) { create(:issue, project: second_project) }
set(:second_project) { create(:project, :public) }
set(:second_issue) { create(:issue, project: second_project) }
 
it 'links to the issue' do
expected = urls.project_issue_path(second_project, second_issue)
Loading
Loading
@@ -55,7 +55,7 @@ describe MarkupHelper do
 
describe 'uploads' do
let(:text) { "![ImageTest](/uploads/test.png)" }
let(:group) { create(:group) }
set(:group) { create(:group) }
 
subject { helper.markdown(text) }
 
Loading
Loading
@@ -77,7 +77,7 @@ describe MarkupHelper do
end
 
describe "with a group in the context" do
let(:project_in_group) { create(:project, group: group) }
set(:project_in_group) { create(:project, group: group) }
 
before do
helper.instance_variable_set(:@group, group)
Loading
Loading
@@ -235,38 +235,48 @@ describe MarkupHelper do
end
 
describe '#render_wiki_content' do
let(:wiki) { double('WikiPage', path: "file.#{extension}") }
let(:context) do
{
pipeline: :wiki, project: project, project_wiki: wiki,
page_slug: 'nested/page', issuable_state_filter_enabled: true
}
end
before do
@wiki = double('WikiPage')
allow(@wiki).to receive(:content).and_return('wiki content')
allow(@wiki).to receive(:slug).and_return('nested/page')
helper.instance_variable_set(:@project_wiki, @wiki)
expect(wiki).to receive(:content).and_return('wiki content')
expect(wiki).to receive(:slug).and_return('nested/page')
helper.instance_variable_set(:@project_wiki, wiki)
end
 
it "uses Wiki pipeline for markdown files" do
allow(@wiki).to receive(:format).and_return(:markdown)
context 'when file is Markdown' do
let(:extension) { 'md' }
 
expect(helper).to receive(:markdown_unsafe).with('wiki content',
pipeline: :wiki, project: project, project_wiki: @wiki, page_slug: "nested/page",
issuable_state_filter_enabled: true)
it 'renders using #markdown_unsafe helper method' do
expect(helper).to receive(:markdown_unsafe).with('wiki content', context)
 
helper.render_wiki_content(@wiki)
helper.render_wiki_content(wiki)
end
end
 
it "uses Asciidoctor for asciidoc files" do
allow(@wiki).to receive(:format).and_return(:asciidoc)
context 'when file is Asciidoc' do
let(:extension) { 'adoc' }
 
expect(helper).to receive(:asciidoc_unsafe).with('wiki content')
it 'renders using Gitlab::Asciidoc' do
expect(Gitlab::Asciidoc).to receive(:render)
 
helper.render_wiki_content(@wiki)
helper.render_wiki_content(wiki)
end
end
 
it "uses the Gollum renderer for all other file types" do
allow(@wiki).to receive(:format).and_return(:rdoc)
formatted_content_stub = double('formatted_content')
expect(formatted_content_stub).to receive(:html_safe)
allow(@wiki).to receive(:formatted_content).and_return(formatted_content_stub)
context 'any other format' do
let(:extension) { 'foo' }
 
helper.render_wiki_content(@wiki)
it 'renders all other formats using Gitlab::OtherMarkup' do
expect(Gitlab::OtherMarkup).to receive(:render)
helper.render_wiki_content(wiki)
end
end
end
 
Loading
Loading
Loading
Loading
@@ -227,6 +227,14 @@ describe Milestone do
end
end
 
describe '#to_ability_name' do
it 'returns milestone' do
milestone = build(:milestone)
expect(milestone.to_ability_name).to eq('milestone')
end
end
describe '.search' do
let(:milestone) { create(:milestone, title: 'foo', description: 'bar') }
 
Loading
Loading
Loading
Loading
@@ -379,6 +379,63 @@ describe Note do
expect(label_note.cross_reference?).to be_falsy
end
end
context 'when system note metadata is not present' do
let(:note) { build(:note, :system) }
before do
allow(note).to receive(:system_note_metadata).and_return(nil)
end
it 'delegates to the system note service' do
expect(SystemNotes::IssuablesService).to receive(:cross_reference?).with(note.note)
note.cross_reference?
end
end
context 'with a system note' do
let(:issue) { create(:issue, project: create(:project, :repository)) }
let(:note) { create(:system_note, note: "test", noteable: issue, project: issue.project) }
shared_examples 'system_note_metadata includes note action' do
it 'delegates to the cross-reference regex' do
expect(note).to receive(:matches_cross_reference_regex?)
note.cross_reference?
end
end
context 'with :label action' do
let!(:metadata) {create(:system_note_metadata, note: note, action: :label)}
it_behaves_like 'system_note_metadata includes note action'
it { expect(note.cross_reference?).to be_falsy }
context 'with cross reference label note' do
let(:label) { create(:label, project: issue.project)}
let(:note) { create(:system_note, note: "added #{label.to_reference} label", noteable: issue, project: issue.project) }
it { expect(note.cross_reference?).to be_truthy }
end
end
context 'with :milestone action' do
let!(:metadata) {create(:system_note_metadata, note: note, action: :milestone)}
it_behaves_like 'system_note_metadata includes note action'
it { expect(note.cross_reference?).to be_falsy }
context 'with cross reference milestone note' do
let(:milestone) { create(:milestone, project: issue.project)}
let(:note) { create(:system_note, note: "added #{milestone.to_reference} milestone", noteable: issue, project: issue.project) }
it { expect(note.cross_reference?).to be_truthy }
end
end
end
end
 
describe 'clear_blank_line_code!' do
Loading
Loading
@@ -578,24 +635,30 @@ describe Note do
end
 
describe '#to_ability_name' do
it 'returns snippet for a project snippet note' do
expect(build(:note_on_project_snippet).to_ability_name).to eq('project_snippet')
it 'returns note' do
expect(build(:note).to_ability_name).to eq('note')
end
end
describe '#noteable_ability_name' do
it 'returns project_snippet for a project snippet note' do
expect(build(:note_on_project_snippet).noteable_ability_name).to eq('project_snippet')
end
 
it 'returns personal_snippet for a personal snippet note' do
expect(build(:note_on_personal_snippet).to_ability_name).to eq('personal_snippet')
expect(build(:note_on_personal_snippet).noteable_ability_name).to eq('personal_snippet')
end
 
it 'returns merge_request for an MR note' do
expect(build(:note_on_merge_request).to_ability_name).to eq('merge_request')
expect(build(:note_on_merge_request).noteable_ability_name).to eq('merge_request')
end
 
it 'returns issue for an issue note' do
expect(build(:note_on_issue).to_ability_name).to eq('issue')
expect(build(:note_on_issue).noteable_ability_name).to eq('issue')
end
 
it 'returns issue for a commit note' do
expect(build(:note_on_commit).to_ability_name).to eq('commit')
it 'returns commit for a commit note' do
expect(build(:note_on_commit).noteable_ability_name).to eq('commit')
end
end
 
Loading
Loading
Loading
Loading
@@ -3416,7 +3416,7 @@ describe Project do
end
end
 
describe '.ids_with_milestone_available_for' do
describe '.ids_with_issuables_available_for' do
let!(:user) { create(:user) }
 
it 'returns project ids with milestones available for user' do
Loading
Loading
@@ -3426,7 +3426,7 @@ describe Project do
project_4 = create(:project, :public)
project_4.project_feature.update(issues_access_level: ProjectFeature::PRIVATE, merge_requests_access_level: ProjectFeature::PRIVATE )
 
project_ids = described_class.ids_with_milestone_available_for(user).pluck(:id)
project_ids = described_class.ids_with_issuables_available_for(user).pluck(:id)
 
expect(project_ids).to include(project_2.id, project_3.id)
expect(project_ids).not_to include(project_1.id, project_4.id)
Loading
Loading
@@ -4444,6 +4444,14 @@ describe Project do
end
end
 
describe '#to_ability_name' do
it 'returns project' do
project = build(:project_empty_repo)
expect(project.to_ability_name).to eq('project')
end
end
describe '#execute_hooks' do
let(:data) { { ref: 'refs/heads/master', data: 'data' } }
it 'executes active projects hooks with the specified scope' do
Loading
Loading
Loading
Loading
@@ -358,6 +358,23 @@ describe WikiPage do
end
end
 
describe '#path' do
let(:path) { 'mypath.md' }
let(:wiki_page) { instance_double('Gitlab::Git::WikiPage', path: path).as_null_object }
it 'returns the path when persisted' do
page = described_class.new(wiki, wiki_page, true)
expect(page.path).to eq(path)
end
it 'returns nil when not persisted' do
page = described_class.new(wiki, wiki_page, false)
expect(page.path).to be_nil
end
end
describe '#directory' do
context 'when the page is at the root directory' do
it 'returns an empty string' do
Loading
Loading
Loading
Loading
@@ -8,28 +8,42 @@ describe CommitPolicy do
let(:commit) { project.repository.head_commit }
let(:policy) { described_class.new(user, commit) }
 
shared_examples 'can read commit and create a note' do
it 'can read commit' do
expect(policy).to be_allowed(:read_commit)
end
it 'can create a note' do
expect(policy).to be_allowed(:create_note)
end
end
shared_examples 'cannot read commit nor create a note' do
it 'can not read commit' do
expect(policy).to be_disallowed(:read_commit)
end
it 'can not create a note' do
expect(policy).to be_disallowed(:create_note)
end
end
context 'when project is public' do
let(:project) { create(:project, :public, :repository) }
 
it 'can read commit and create a note' do
expect(policy).to be_allowed(:read_commit)
end
it_behaves_like 'can read commit and create a note'
 
context 'when repository access level is private' do
let(:project) { create(:project, :public, :repository, :repository_private) }
 
it 'can not read commit and create a note' do
expect(policy).to be_disallowed(:read_commit)
end
it_behaves_like 'cannot read commit nor create a note'
 
context 'when the user is a project member' do
before do
project.add_developer(user)
end
 
it 'can read commit and create a note' do
expect(policy).to be_allowed(:read_commit)
end
it_behaves_like 'can read commit and create a note'
end
end
end
Loading
Loading
@@ -37,9 +51,7 @@ describe CommitPolicy do
context 'when project is private' do
let(:project) { create(:project, :private, :repository) }
 
it 'can not read commit and create a note' do
expect(policy).to be_disallowed(:read_commit)
end
it_behaves_like 'cannot read commit nor create a note'
 
context 'when the user is a project member' do
before do
Loading
Loading
@@ -50,6 +62,18 @@ describe CommitPolicy do
expect(policy).to be_allowed(:read_commit)
end
end
context 'when the user is a guest' do
before do
project.add_guest(user)
end
it_behaves_like 'cannot read commit nor create a note'
it 'cannot download code' do
expect(policy).to be_disallowed(:download_code)
end
end
end
end
end
Loading
Loading
@@ -356,6 +356,88 @@ describe GroupPolicy do
end
end
 
context 'transfer_projects' do
shared_examples_for 'allowed to transfer projects' do
before do
group.update(project_creation_level: project_creation_level)
end
it { is_expected.to be_allowed(:transfer_projects) }
end
shared_examples_for 'not allowed to transfer projects' do
before do
group.update(project_creation_level: project_creation_level)
end
it { is_expected.to be_disallowed(:transfer_projects) }
end
context 'reporter' do
let(:current_user) { reporter }
it_behaves_like 'not allowed to transfer projects' do
let(:project_creation_level) { ::Gitlab::Access::NO_ONE_PROJECT_ACCESS }
end
it_behaves_like 'not allowed to transfer projects' do
let(:project_creation_level) { ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS }
end
it_behaves_like 'not allowed to transfer projects' do
let(:project_creation_level) { ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS }
end
end
context 'developer' do
let(:current_user) { developer }
it_behaves_like 'not allowed to transfer projects' do
let(:project_creation_level) { ::Gitlab::Access::NO_ONE_PROJECT_ACCESS }
end
it_behaves_like 'not allowed to transfer projects' do
let(:project_creation_level) { ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS }
end
it_behaves_like 'not allowed to transfer projects' do
let(:project_creation_level) { ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS }
end
end
context 'maintainer' do
let(:current_user) { maintainer }
it_behaves_like 'not allowed to transfer projects' do
let(:project_creation_level) { ::Gitlab::Access::NO_ONE_PROJECT_ACCESS }
end
it_behaves_like 'allowed to transfer projects' do
let(:project_creation_level) { ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS }
end
it_behaves_like 'allowed to transfer projects' do
let(:project_creation_level) { ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS }
end
end
context 'owner' do
let(:current_user) { owner }
it_behaves_like 'not allowed to transfer projects' do
let(:project_creation_level) { ::Gitlab::Access::NO_ONE_PROJECT_ACCESS }
end
it_behaves_like 'allowed to transfer projects' do
let(:project_creation_level) { ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS }
end
it_behaves_like 'allowed to transfer projects' do
let(:project_creation_level) { ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS }
end
end
end
context "create_projects" do
context 'when group has no project creation level set' do
before_all do
Loading
Loading
Loading
Loading
@@ -8,7 +8,7 @@ describe NamespacePolicy do
let(:admin) { create(:admin) }
let(:namespace) { create(:namespace, owner: owner) }
 
let(:owner_permissions) { [:create_projects, :admin_namespace, :read_namespace, :read_statistics] }
let(:owner_permissions) { [:create_projects, :admin_namespace, :read_namespace, :read_statistics, :transfer_projects] }
 
subject { described_class.new(current_user, namespace) }
 
Loading
Loading
@@ -33,6 +33,7 @@ describe NamespacePolicy do
let(:owner) { create(:user, projects_limit: 0) }
 
it { is_expected.to be_disallowed(:create_projects) }
it { is_expected.to be_disallowed(:transfer_projects) }
end
end
 
Loading
Loading
Loading
Loading
@@ -15,7 +15,7 @@ describe 'GitlabSchema configurations' do
 
subject
 
expect(graphql_errors.flatten.first['message']).to include('which exceeds max complexity of 1')
expect_graphql_errors_to_include /which exceeds max complexity of 1/
end
end
end
Loading
Loading
@@ -23,12 +23,11 @@ describe 'GitlabSchema configurations' do
describe '#max_depth' do
context 'when query depth is too high' do
it 'shows error' do
errors = { "message" => "Query has depth of 2, which exceeds max depth of 1" }
allow(GitlabSchema).to receive(:max_query_depth).and_return 1
 
subject
 
expect(graphql_errors.flatten).to include(errors)
expect_graphql_errors_to_include /exceeds max depth/
end
end
 
Loading
Loading
@@ -38,7 +37,42 @@ describe 'GitlabSchema configurations' do
 
subject
 
expect(Array.wrap(graphql_errors).compact).to be_empty
expect_graphql_errors_to_be_empty
end
end
end
end
context 'depth, complexity and recursion checking' do
context 'unauthenticated recursive queries' do
context 'a not-quite-recursive-enough introspective query' do
it 'succeeds' do
query = File.read(Rails.root.join('spec/fixtures/api/graphql/small-recursive-introspection.graphql'))
post_graphql(query, current_user: nil)
expect_graphql_errors_to_be_empty
end
end
context 'a deep but simple recursive introspective query' do
it 'fails due to recursion' do
query = File.read(Rails.root.join('spec/fixtures/api/graphql/recursive-introspection.graphql'))
post_graphql(query, current_user: nil)
expect_graphql_errors_to_include [/Recursive query/]
end
end
context 'a deep recursive non-introspective query' do
it 'fails due to recursion, complexity and depth' do
allow(GitlabSchema).to receive(:max_query_complexity).and_return 1
query = File.read(Rails.root.join('spec/fixtures/api/graphql/recursive-query.graphql'))
post_graphql(query, current_user: nil)
expect_graphql_errors_to_include [/Recursive query/, /exceeds max complexity/, /exceeds max depth/]
end
end
end
Loading
Loading
@@ -88,7 +122,7 @@ describe 'GitlabSchema configurations' do
# Expect errors for each query
expect(graphql_errors.size).to eq(3)
graphql_errors.each do |single_query_errors|
expect(single_query_errors.first['message']).to include('which exceeds max complexity of 4')
expect_graphql_errors_to_include(/which exceeds max complexity of 4/)
end
end
end
Loading
Loading
@@ -105,12 +139,12 @@ describe 'GitlabSchema configurations' do
end
 
context 'when IntrospectionQuery' do
it 'is not too complex' do
it 'is not too complex nor recursive' do
query = File.read(Rails.root.join('spec/fixtures/api/graphql/introspection.graphql'))
 
post_graphql(query, current_user: nil)
 
expect(graphql_errors).to be_nil
expect_graphql_errors_to_be_empty
end
end
 
Loading
Loading
Loading
Loading
@@ -1741,6 +1741,38 @@ describe API::MergeRequests do
expect(json_response['state']).to eq('closed')
expect(json_response['force_remove_source_branch']).to be_truthy
end
context 'with a merge request across forks' do
let(:fork_owner) { create(:user) }
let(:source_project) { fork_project(project, fork_owner) }
let(:target_project) { project }
let(:merge_request) do
create(:merge_request,
source_project: source_project,
target_project: target_project,
source_branch: 'fixes',
merge_params: { 'force_remove_source_branch' => false })
end
it 'is true for an authorized user' do
put api("/projects/#{target_project.id}/merge_requests/#{merge_request.iid}", fork_owner), params: { state_event: 'close', remove_source_branch: true }
expect(response).to have_gitlab_http_status(200)
expect(json_response['state']).to eq('closed')
expect(json_response['force_remove_source_branch']).to be true
end
it 'is false for an unauthorized user' do
expect do
put api("/projects/#{target_project.id}/merge_requests/#{merge_request.iid}", target_project.owner), params: { state_event: 'close', remove_source_branch: true }
end.not_to change { merge_request.reload.merge_params }
expect(response).to have_gitlab_http_status(200)
expect(json_response['state']).to eq('closed')
expect(json_response['force_remove_source_branch']).to be false
end
end
end
 
context "to close a MR" do
Loading
Loading
Loading
Loading
@@ -2684,6 +2684,22 @@ describe API::Projects do
expect(response).to have_gitlab_http_status(400)
end
end
context 'when authenticated as developer' do
before do
group.add_developer(user)
end
context 'target namespace allows developers to create projects' do
let(:group) { create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) }
it 'fails transferring the project to the target namespace' do
put api("/projects/#{project.id}/transfer", user), params: { namespace: group.id }
expect(response).to have_gitlab_http_status(400)
end
end
end
end
 
it_behaves_like 'custom attributes endpoints', 'projects' do
Loading
Loading
Loading
Loading
@@ -51,7 +51,7 @@ describe AutoMerge::BaseService do
expect(merge_request.merge_params['commit_message']).to eq("Merge branch 'patch-12' into 'master'")
expect(merge_request.merge_params['sha']).to eq('200fcc9c260f7219eaf0daba87d818f0922c5b18')
expect(merge_request.merge_params['should_remove_source_branch']).to eq(false)
expect(merge_request.merge_params['squash']).to eq(false)
expect(merge_request.squash).to eq(false)
expect(merge_request.merge_params['squash_commit_message']).to eq('Update README.md')
end
end
Loading
Loading
@@ -108,7 +108,6 @@ describe AutoMerge::BaseService do
'commit_message' => "Merge branch 'patch-12' into 'master'",
'sha' => "200fcc9c260f7219eaf0daba87d818f0922c5b18",
'should_remove_source_branch' => false,
'squash' => false,
'squash_commit_message' => "Update README.md"
}
end
Loading
Loading
Loading
Loading
@@ -59,8 +59,9 @@ describe AutoMerge::MergeWhenPipelineSucceedsService do
it 'sets the params, merge_user, and flag' do
expect(merge_request).to be_valid
expect(merge_request.merge_when_pipeline_succeeds).to be_truthy
expect(merge_request.merge_params).to include commit_message: 'Awesome message'
expect(merge_request.merge_params).to include 'commit_message' => 'Awesome message'
expect(merge_request.merge_user).to be user
expect(merge_request.auto_merge_strategy).to eq AutoMergeService::STRATEGY_MERGE_WHEN_PIPELINE_SUCCEEDS
end
 
it 'creates a system note' do
Loading
Loading
@@ -73,7 +74,7 @@ describe AutoMerge::MergeWhenPipelineSucceedsService do
end
 
context 'already approved' do
let(:service) { described_class.new(project, user, new_key: true) }
let(:service) { described_class.new(project, user, should_remove_source_branch: true) }
let(:build) { create(:ci_build, ref: mr_merge_if_green_enabled.source_branch) }
 
before do
Loading
Loading
@@ -90,7 +91,7 @@ describe AutoMerge::MergeWhenPipelineSucceedsService do
expect(SystemNoteService).not_to receive(:merge_when_pipeline_succeeds)
 
service.execute(mr_merge_if_green_enabled)
expect(mr_merge_if_green_enabled.merge_params).to have_key(:new_key)
expect(mr_merge_if_green_enabled.merge_params).to have_key('should_remove_source_branch')
end
end
end
Loading
Loading
require 'spec_helper'
describe MergeRequests::AssignsMergeParams do
it 'raises an error when used from an instance that does not respond to #current_user' do
define_class = -> { Class.new { include MergeRequests::AssignsMergeParams }.new }
expect { define_class.call }.to raise_error %r{can not be included in (.*) without implementing #current_user}
end
describe '#assign_allowed_merge_params' do
let(:merge_request) { build(:merge_request) }
let(:params) do
{ commit_message: 'Commit Message',
'should_remove_source_branch' => true,
unknown_symbol: 'Unknown symbol',
'unknown_string' => 'Unknown String' }
end
subject(:merge_request_service) do
Class.new do
attr_accessor :current_user
include MergeRequests::AssignsMergeParams
def initialize(user)
@current_user = user
end
end
end
it 'only assigns known parameters to the merge request' do
service = merge_request_service.new(merge_request.author)
service.assign_allowed_merge_params(merge_request, params)
expect(merge_request.merge_params).to eq('commit_message' => 'Commit Message', 'should_remove_source_branch' => true)
end
it 'returns a hash without the known merge params' do
service = merge_request_service.new(merge_request.author)
result = service.assign_allowed_merge_params(merge_request, params)
expect(result).to eq({ 'unknown_symbol' => 'Unknown symbol', 'unknown_string' => 'Unknown String' })
end
context 'the force_remove_source_branch param' do
let(:params) { { force_remove_source_branch: true } }
it 'assigns the param if the user is allowed to do that' do
service = merge_request_service.new(merge_request.author)
result = service.assign_allowed_merge_params(merge_request, params)
expect(merge_request.force_remove_source_branch?).to be true
expect(result).to be_empty
end
it 'only removes the param if the user is not allowed to do that' do
service = merge_request_service.new(build(:user))
result = service.assign_allowed_merge_params(merge_request, params)
expect(merge_request.force_remove_source_branch?).to be_falsy
expect(result).to be_empty
end
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment