diff options
Diffstat (limited to 'spec/services')
-rw-r--r-- | spec/services/create_snippet_service_spec.rb | 2 | ||||
-rw-r--r-- | spec/services/git_push_service_spec.rb | 13 | ||||
-rw-r--r-- | spec/services/groups/create_service_spec.rb | 20 | ||||
-rw-r--r-- | spec/services/groups/update_service_spec.rb | 52 | ||||
-rw-r--r-- | spec/services/issues/move_service_spec.rb | 213 | ||||
-rw-r--r-- | spec/services/projects/autocomplete_service_spec.rb | 79 | ||||
-rw-r--r-- | spec/services/projects/housekeeping_service_spec.rb | 4 | ||||
-rw-r--r-- | spec/services/system_note_service_spec.rb | 53 | ||||
-rw-r--r-- | spec/services/todo_service_spec.rb | 9 | ||||
-rw-r--r-- | spec/services/update_snippet_service_spec.rb | 2 |
10 files changed, 438 insertions, 9 deletions
diff --git a/spec/services/create_snippet_service_spec.rb b/spec/services/create_snippet_service_spec.rb index c800dea04fa..7a850066bf8 100644 --- a/spec/services/create_snippet_service_spec.rb +++ b/spec/services/create_snippet_service_spec.rb @@ -23,7 +23,7 @@ describe CreateSnippetService, services: true do snippet = create_snippet(nil, @user, @opts) expect(snippet.errors.messages).to have_key(:visibility_level) expect(snippet.errors.messages[:visibility_level].first).to( - match('Public visibility has been restricted') + match('has been restricted') ) end diff --git a/spec/services/git_push_service_spec.rb b/spec/services/git_push_service_spec.rb index 145bc937560..8490a729e51 100644 --- a/spec/services/git_push_service_spec.rb +++ b/spec/services/git_push_service_spec.rb @@ -29,7 +29,8 @@ describe GitPushService, services: true do it { is_expected.to be_truthy } it 'flushes general cached data' do - expect(project.repository).to receive(:expire_cache).with('master') + expect(project.repository).to receive(:expire_cache). + with('master', newrev) subject end @@ -46,7 +47,8 @@ describe GitPushService, services: true do it { is_expected.to be_truthy } it 'flushes general cached data' do - expect(project.repository).to receive(:expire_cache).with('master') + expect(project.repository).to receive(:expire_cache). + with('master', newrev) subject end @@ -65,7 +67,8 @@ describe GitPushService, services: true do end it 'flushes general cached data' do - expect(project.repository).to receive(:expire_cache).with('master') + expect(project.repository).to receive(:expire_cache). + with('master', newrev) subject end @@ -212,12 +215,16 @@ describe GitPushService, services: true do let(:commit) { project.commit } before do + project.team << [commit_author, :developer] + project.team << [user, :developer] + allow(commit).to receive_messages( safe_message: "this commit \n mentions #{issue.to_reference}", references: [issue], author_name: commit_author.name, author_email: commit_author.email ) + allow(project.repository).to receive(:commits_between).and_return([commit]) end diff --git a/spec/services/groups/create_service_spec.rb b/spec/services/groups/create_service_spec.rb new file mode 100644 index 00000000000..6aefb48a4e8 --- /dev/null +++ b/spec/services/groups/create_service_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe Groups::CreateService, services: true do + let!(:user) { create(:user) } + let!(:group_params) { { path: "group_path", visibility_level: Gitlab::VisibilityLevel::PUBLIC } } + + describe "execute" do + let!(:service) { described_class.new(user, group_params ) } + subject { service.execute } + + context "create groups without restricted visibility level" do + it { is_expected.to be_persisted } + end + + context "cannot create group with restricted visibility level" do + before { allow(current_application_settings).to receive(:restricted_visibility_levels).and_return([Gitlab::VisibilityLevel::PUBLIC]) } + it { is_expected.to_not be_persisted } + end + end +end diff --git a/spec/services/groups/update_service_spec.rb b/spec/services/groups/update_service_spec.rb new file mode 100644 index 00000000000..9c2331144a0 --- /dev/null +++ b/spec/services/groups/update_service_spec.rb @@ -0,0 +1,52 @@ +require 'spec_helper' + +describe Groups::UpdateService, services: true do + let!(:user) { create(:user) } + let!(:private_group) { create(:group, :private) } + let!(:internal_group) { create(:group, :internal) } + let!(:public_group) { create(:group, :public) } + + describe "#execute" do + context "project visibility_level validation" do + context "public group with public projects" do + let!(:service) { described_class.new(public_group, user, visibility_level: Gitlab::VisibilityLevel::INTERNAL ) } + + before do + public_group.add_user(user, Gitlab::Access::MASTER) + create(:project, :public, group: public_group) + end + + it "does not change permission level" do + service.execute + expect(public_group.errors.count).to eq(1) + end + end + + context "internal group with internal project" do + let!(:service) { described_class.new(internal_group, user, visibility_level: Gitlab::VisibilityLevel::PRIVATE ) } + + before do + internal_group.add_user(user, Gitlab::Access::MASTER) + create(:project, :internal, group: internal_group) + end + + it "does not change permission level" do + service.execute + expect(internal_group.errors.count).to eq(1) + end + end + end + end + + context "unauthorized visibility_level validation" do + let!(:service) { described_class.new(internal_group, user, visibility_level: 99 ) } + before do + internal_group.add_user(user, Gitlab::Access::MASTER) + end + + it "does not change permission level" do + service.execute + expect(internal_group.errors.count).to eq(1) + end + end +end diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb new file mode 100644 index 00000000000..14cc20e529a --- /dev/null +++ b/spec/services/issues/move_service_spec.rb @@ -0,0 +1,213 @@ +require 'spec_helper' + +describe Issues::MoveService, services: true do + let(:user) { create(:user) } + let(:author) { create(:user) } + let(:title) { 'Some issue' } + let(:description) { 'Some issue description' } + let(:old_project) { create(:project) } + let(:new_project) { create(:project) } + + let(:old_issue) do + create(:issue, title: title, description: description, + project: old_project, author: author) + end + + let(:move_service) do + described_class.new(old_project, user) + end + + shared_context 'user can move issue' do + before do + old_project.team << [user, :reporter] + new_project.team << [user, :reporter] + end + end + + describe '#execute' do + shared_context 'issue move executed' do + let!(:new_issue) { move_service.execute(old_issue, new_project) } + end + + context 'issue movable' do + include_context 'user can move issue' + + context 'generic issue' do + include_context 'issue move executed' + + it 'creates a new issue in a new project' do + expect(new_issue.project).to eq new_project + end + + it 'rewrites issue title' do + expect(new_issue.title).to eq title + end + + it 'rewrites issue description' do + expect(new_issue.description).to eq description + end + + it 'adds system note to old issue at the end' do + expect(old_issue.notes.last.note).to match /^Moved to/ + end + + it 'adds system note to new issue at the end' do + expect(new_issue.notes.last.note).to match /^Moved from/ + end + + it 'closes old issue' do + expect(old_issue.closed?).to be true + end + + it 'persists new issue' do + expect(new_issue.persisted?).to be true + end + + it 'persists all changes' do + expect(old_issue.changed?).to be false + expect(new_issue.changed?).to be false + end + + it 'preserves author' do + expect(new_issue.author).to eq author + end + + it 'removes data that is invalid in new context' do + expect(new_issue.milestone).to be_nil + expect(new_issue.labels).to be_empty + end + + it 'creates a new internal id for issue' do + expect(new_issue.iid).to be 1 + end + + it 'marks issue as moved' do + expect(old_issue.moved?).to eq true + expect(old_issue.moved_to).to eq new_issue + end + end + + context 'issue with notes' do + context 'notes without references' do + let(:notes_params) do + [{ system: false, note: 'Some comment 1' }, + { system: true, note: 'Some system note' }, + { system: false, note: 'Some comment 2' }] + end + + let(:notes_contents) { notes_params.map { |n| n[:note] } } + + before do + note_params = { noteable: old_issue, project: old_project, author: author } + notes_params.each do |note| + create(:note, note_params.merge(note)) + end + end + + include_context 'issue move executed' + + let(:all_notes) { new_issue.notes.order('id ASC') } + let(:system_notes) { all_notes.system } + let(:user_notes) { all_notes.user } + + it 'rewrites existing notes in valid order' do + expect(all_notes.pluck(:note).first(3)).to eq notes_contents + end + + it 'adds a system note about move after rewritten notes' do + expect(system_notes.last.note).to match /^Moved from/ + end + + it 'preserves orignal author of comment' do + expect(user_notes.pluck(:author_id)).to all(eq(author.id)) + end + + it 'preserves time when note has been created at' do + expect(old_issue.notes.first.created_at) + .to eq new_issue.notes.first.created_at + end + end + + context 'notes with references' do + before do + create(:merge_request, source_project: old_project) + create(:note, noteable: old_issue, project: old_project, author: author, + note: 'Note with reference to merge request !1') + end + + include_context 'issue move executed' + let(:new_note) { new_issue.notes.first } + + it 'rewrites references using a cross reference to old project' do + expect(new_note.note) + .to eq "Note with reference to merge request #{old_project.to_reference}!1" + end + end + end + + describe 'rewritting references' do + include_context 'issue move executed' + + context 'issue reference' do + let(:another_issue) { create(:issue, project: old_project) } + let(:description) { "Some description #{another_issue.to_reference}" } + + it 'rewrites referenced issues creating cross project reference' do + expect(new_issue.description) + .to eq "Some description #{old_project.to_reference}#{another_issue.to_reference}" + end + end + end + + context 'moving to same project' do + let(:new_project) { old_project } + + it 'raises error' do + expect { move_service.execute(old_issue, new_project) } + .to raise_error(StandardError, /Cannot move issue/) + end + end + end + + describe 'move permissions' do + let(:move) { move_service.execute(old_issue, new_project) } + + context 'user is reporter in both projects' do + include_context 'user can move issue' + it { expect { move }.to_not raise_error } + end + + context 'user is reporter only in new project' do + before { new_project.team << [user, :reporter] } + it { expect { move }.to raise_error(StandardError, /permissions/) } + end + + context 'user is reporter only in old project' do + before { old_project.team << [user, :reporter] } + it { expect { move }.to raise_error(StandardError, /permissions/) } + end + + context 'user is reporter in one project and guest in another' do + before do + new_project.team << [user, :guest] + old_project.team << [user, :reporter] + end + + it { expect { move }.to raise_error(StandardError, /permissions/) } + end + + context 'issue has already been moved' do + include_context 'user can move issue' + + let(:moved_to_issue) { create(:issue) } + + let(:old_issue) do + create(:issue, project: old_project, author: author, + moved_to: moved_to_issue) + end + + it { expect { move }.to raise_error(StandardError, /permissions/) } + end + end + end +end diff --git a/spec/services/projects/autocomplete_service_spec.rb b/spec/services/projects/autocomplete_service_spec.rb new file mode 100644 index 00000000000..6108c26a78b --- /dev/null +++ b/spec/services/projects/autocomplete_service_spec.rb @@ -0,0 +1,79 @@ +require 'spec_helper' + +describe Projects::AutocompleteService, services: true do + describe '#issues' do + describe 'confidential issues' do + let(:author) { create(:user) } + let(:assignee) { create(:user) } + let(:non_member) { create(:user) } + let(:member) { create(:user) } + let(:admin) { create(:admin) } + let(:project) { create(:empty_project, :public) } + let!(:issue) { create(:issue, project: project, title: 'Issue 1') } + let!(:security_issue_1) { create(:issue, :confidential, project: project, title: 'Security issue 1', author: author) } + let!(:security_issue_2) { create(:issue, :confidential, title: 'Security issue 2', project: project, assignee: assignee) } + + it 'should not list project confidential issues for guests' do + autocomplete = described_class.new(project, nil) + issues = autocomplete.issues.map(&:iid) + + expect(issues).to include issue.iid + expect(issues).not_to include security_issue_1.iid + expect(issues).not_to include security_issue_2.iid + expect(issues.count).to eq 1 + end + + it 'should not list project confidential issues for non project members' do + autocomplete = described_class.new(project, non_member) + issues = autocomplete.issues.map(&:iid) + + expect(issues).to include issue.iid + expect(issues).not_to include security_issue_1.iid + expect(issues).not_to include security_issue_2.iid + expect(issues.count).to eq 1 + end + + it 'should list project confidential issues for author' do + autocomplete = described_class.new(project, author) + issues = autocomplete.issues.map(&:iid) + + expect(issues).to include issue.iid + expect(issues).to include security_issue_1.iid + expect(issues).not_to include security_issue_2.iid + expect(issues.count).to eq 2 + end + + it 'should list project confidential issues for assignee' do + autocomplete = described_class.new(project, assignee) + issues = autocomplete.issues.map(&:iid) + + expect(issues).to include issue.iid + expect(issues).not_to include security_issue_1.iid + expect(issues).to include security_issue_2.iid + expect(issues.count).to eq 2 + end + + it 'should list project confidential issues for project members' do + project.team << [member, :developer] + + autocomplete = described_class.new(project, member) + issues = autocomplete.issues.map(&:iid) + + expect(issues).to include issue.iid + expect(issues).to include security_issue_1.iid + expect(issues).to include security_issue_2.iid + expect(issues.count).to eq 3 + end + + it 'should list all project issues for admin' do + autocomplete = described_class.new(project, admin) + issues = autocomplete.issues.map(&:iid) + + expect(issues).to include issue.iid + expect(issues).to include security_issue_1.iid + expect(issues).to include security_issue_2.iid + expect(issues.count).to eq 3 + end + end + end +end diff --git a/spec/services/projects/housekeeping_service_spec.rb b/spec/services/projects/housekeeping_service_spec.rb index 93bf1b81fbe..4c5ced7e746 100644 --- a/spec/services/projects/housekeeping_service_spec.rb +++ b/spec/services/projects/housekeeping_service_spec.rb @@ -12,7 +12,7 @@ describe Projects::HousekeepingService do it 'enqueues a sidekiq job' do expect(subject).to receive(:try_obtain_lease).and_return(true) - expect(GitlabShellWorker).to receive(:perform_async).with(:gc, project.path_with_namespace) + expect(GitlabShellOneShotWorker).to receive(:perform_async).with(:gc, project.path_with_namespace) subject.execute expect(project.pushes_since_gc).to eq(0) @@ -20,7 +20,7 @@ describe Projects::HousekeepingService do it 'does not enqueue a job when no lease can be obtained' do expect(subject).to receive(:try_obtain_lease).and_return(false) - expect(GitlabShellWorker).not_to receive(:perform_async) + expect(GitlabShellOneShotWorker).not_to receive(:perform_async) expect { subject.execute }.to raise_error(Projects::HousekeepingService::LeaseTaken) expect(project.pushes_since_gc).to eq(0) diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb index 8e6292014d4..240eae10052 100644 --- a/spec/services/system_note_service_spec.rb +++ b/spec/services/system_note_service_spec.rb @@ -453,6 +453,59 @@ describe SystemNoteService, services: true do end end + describe '.noteable_moved' do + let(:new_project) { create(:project) } + let(:new_noteable) { create(:issue, project: new_project) } + + subject do + described_class.noteable_moved(noteable, project, new_noteable, author, direction: direction) + end + + shared_examples 'cross project mentionable' do + include GitlabMarkdownHelper + + it 'should contain cross reference to new noteable' do + expect(subject.note).to include cross_project_reference(new_project, new_noteable) + end + + it 'should mention referenced noteable' do + expect(subject.note).to include new_noteable.to_reference + end + + it 'should mention referenced project' do + expect(subject.note).to include new_project.to_reference + end + end + + context 'moved to' do + let(:direction) { :to } + + it_behaves_like 'cross project mentionable' + + it 'should notify about noteable being moved to' do + expect(subject.note).to match /Moved to/ + end + end + + context 'moved from' do + let(:direction) { :from } + + it_behaves_like 'cross project mentionable' + + it 'should notify about noteable being moved from' do + expect(subject.note).to match /Moved from/ + end + end + + context 'invalid direction' do + let(:direction) { :invalid } + + it 'should raise error' do + expect { subject }.to raise_error StandardError, /Invalid direction/ + end + end + end + include JiraServiceHelper describe 'JIRA integration' do diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb index 96420acb31d..b4728807b8b 100644 --- a/spec/services/todo_service_spec.rb +++ b/spec/services/todo_service_spec.rb @@ -148,8 +148,13 @@ describe TodoService, services: true do should_not_create_todo(user: stranger, target: issue, author: john_doe, action: Todo::MENTIONED, note: note) end - it 'does not create todo when leaving a note on commit' do - should_not_create_any_todo { service.new_note(note_on_commit, john_doe) } + it 'creates a todo for each valid mentioned user when leaving a note on commit' do + service.new_note(note_on_commit, john_doe) + + should_create_todo(user: michael, target_id: nil, target_type: 'Commit', commit_id: note_on_commit.commit_id, author: john_doe, action: Todo::MENTIONED, note: note_on_commit) + should_create_todo(user: author, target_id: nil, target_type: 'Commit', commit_id: note_on_commit.commit_id, author: john_doe, action: Todo::MENTIONED, note: note_on_commit) + should_not_create_todo(user: john_doe, target_id: nil, target_type: 'Commit', commit_id: note_on_commit.commit_id, author: john_doe, action: Todo::MENTIONED, note: note_on_commit) + should_not_create_todo(user: stranger, target_id: nil, target_type: 'Commit', commit_id: note_on_commit.commit_id, author: john_doe, action: Todo::MENTIONED, note: note_on_commit) end it 'does not create todo when leaving a note on snippet' do diff --git a/spec/services/update_snippet_service_spec.rb b/spec/services/update_snippet_service_spec.rb index 48d114896d0..37c2e861362 100644 --- a/spec/services/update_snippet_service_spec.rb +++ b/spec/services/update_snippet_service_spec.rb @@ -25,7 +25,7 @@ describe UpdateSnippetService, services: true do update_snippet(@project, @user, @snippet, @opts) expect(@snippet.errors.messages).to have_key(:visibility_level) expect(@snippet.errors.messages[:visibility_level].first).to( - match('Public visibility has been restricted') + match('has been restricted') ) expect(@snippet.visibility_level).to eq(old_visibility) end |