Skip to content
Snippets Groups Projects
Commit add80eb9 authored by Valery Sizov's avatar Valery Sizov
Browse files
parents 681e714c 327f7ae8
No related branches found
No related tags found
No related merge requests found
Showing
with 669 additions and 53 deletions
Loading
Loading
@@ -358,4 +358,25 @@ describe Issue, "Issuable" do
expect(Issue.with_label([bug.title, enhancement.title])).to match_array([issue2])
end
end
describe '#assignee_or_author?' do
let(:user) { build(:user, id: 1) }
let(:issue) { build(:issue) }
it 'returns true for a user that is assigned to an issue' do
issue.assignee = user
expect(issue.assignee_or_author?(user)).to eq(true)
end
it 'returns true for a user that is the author of an issue' do
issue.author = user
expect(issue.assignee_or_author?(user)).to eq(true)
end
it 'returns false for a user that is not the assignee or author' do
expect(issue.assignee_or_author?(user)).to eq(false)
end
end
end
require 'spec_helper'
 
describe ExternalIssue, models: true do
let(:project) { double('project', to_reference: 'namespace1/project1') }
let(:project) { double('project', id: 1, to_reference: 'namespace1/project1') }
let(:issue) { described_class.new('EXT-1234', project) }
 
describe 'modules' do
Loading
Loading
@@ -36,4 +36,10 @@ describe ExternalIssue, models: true do
end
end
end
describe '#project_id' do
it 'returns the ID of the project' do
expect(issue.project_id).to eq(project.id)
end
end
end
require 'spec_helper'
describe IssueCollection do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:issue1) { create(:issue, project: project) }
let(:issue2) { create(:issue, project: project) }
let(:collection) { described_class.new([issue1, issue2]) }
describe '#collection' do
it 'returns the issues in the same order as the input Array' do
expect(collection.collection).to eq([issue1, issue2])
end
end
describe '#updatable_by_user' do
context 'using an admin user' do
it 'returns all issues' do
user = create(:admin)
expect(collection.updatable_by_user(user)).to eq([issue1, issue2])
end
end
context 'using a user that has no access to the project' do
it 'returns no issues when the user is not an assignee or author' do
expect(collection.updatable_by_user(user)).to be_empty
end
it 'returns the issues the user is assigned to' do
issue1.assignee = user
expect(collection.updatable_by_user(user)).to eq([issue1])
end
it 'returns the issues for which the user is the author' do
issue1.author = user
expect(collection.updatable_by_user(user)).to eq([issue1])
end
end
context 'using a user that has reporter access to the project' do
it 'returns the issues of the project' do
project.team << [user, :reporter]
expect(collection.updatable_by_user(user)).to eq([issue1, issue2])
end
end
context 'using a user that is the owner of a project' do
it 'returns the issues of the project' do
expect(collection.updatable_by_user(project.namespace.owner)).
to eq([issue1, issue2])
end
end
end
describe '#visible_to' do
it 'is an alias for updatable_by_user' do
updatable_by_user = described_class.instance_method(:updatable_by_user)
visible_to = described_class.instance_method(:visible_to)
expect(visible_to).to eq(updatable_by_user)
end
end
end
Loading
Loading
@@ -304,7 +304,7 @@ describe Project, models: true do
end
end
 
xdescribe "#new_issue_address" do
describe "#new_issue_address" do
let(:project) { create(:empty_project, path: "somewhere") }
let(:user) { create(:user) }
 
Loading
Loading
@@ -314,8 +314,7 @@ describe Project, models: true do
end
 
it 'returns the address to create a new issue' do
token = user.authentication_token
address = "p+#{project.namespace.path}/#{project.path}+#{token}@gl.ab"
address = "p+#{project.path_with_namespace}+#{user.incoming_email_token}@gl.ab"
 
expect(project.new_issue_address(user)).to eq(address)
end
Loading
Loading
Loading
Loading
@@ -362,6 +362,19 @@ describe Repository, models: true do
expect(results.first).not_to start_with('fatal:')
end
 
it 'properly handles when query is not present' do
results = repository.search_files('', 'master')
expect(results).to match_array([])
end
it 'properly handles query when repo is empty' do
repository = create(:empty_project).repository
results = repository.search_files('test', 'master')
expect(results).to match_array([])
end
describe 'result' do
subject { results.first }
 
Loading
Loading
Loading
Loading
@@ -1240,4 +1240,40 @@ describe User, models: true do
expect(user.viewable_starred_projects).not_to include(private_project)
end
end
describe '#projects_with_reporter_access_limited_to' do
let(:project1) { create(:project) }
let(:project2) { create(:project) }
let(:user) { create(:user) }
before do
project1.team << [user, :reporter]
project2.team << [user, :guest]
end
it 'returns the projects when using a single project ID' do
projects = user.projects_with_reporter_access_limited_to(project1.id)
expect(projects).to eq([project1])
end
it 'returns the projects when using an Array of project IDs' do
projects = user.projects_with_reporter_access_limited_to([project1.id])
expect(projects).to eq([project1])
end
it 'returns the projects when using an ActiveRecord relation' do
projects = user.
projects_with_reporter_access_limited_to(Project.select(:id))
expect(projects).to eq([project1])
end
it 'does not return projects you do not have reporter access to' do
projects = user.projects_with_reporter_access_limited_to(project2.id)
expect(projects).to be_empty
end
end
end
require 'spec_helper'
describe IssuePolicy, models: true do
let(:user) { create(:user) }
describe '#rules' do
context 'using a regular issue' do
let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project) }
let(:policies) { described_class.abilities(user, issue).to_set }
context 'with a regular user' do
it 'includes the read_issue permission' do
expect(policies).to include(:read_issue)
end
it 'does not include the admin_issue permission' do
expect(policies).not_to include(:admin_issue)
end
it 'does not include the update_issue permission' do
expect(policies).not_to include(:update_issue)
end
end
context 'with a user that is a project reporter' do
before do
project.team << [user, :reporter]
end
it 'includes the read_issue permission' do
expect(policies).to include(:read_issue)
end
it 'includes the admin_issue permission' do
expect(policies).to include(:admin_issue)
end
it 'includes the update_issue permission' do
expect(policies).to include(:update_issue)
end
end
context 'with a user that is a project guest' do
before do
project.team << [user, :guest]
end
it 'includes the read_issue permission' do
expect(policies).to include(:read_issue)
end
it 'does not include the admin_issue permission' do
expect(policies).not_to include(:admin_issue)
end
it 'does not include the update_issue permission' do
expect(policies).not_to include(:update_issue)
end
end
end
context 'using a confidential issue' do
let(:issue) { create(:issue, :confidential) }
context 'with a regular user' do
let(:policies) { described_class.abilities(user, issue).to_set }
it 'does not include the read_issue permission' do
expect(policies).not_to include(:read_issue)
end
it 'does not include the admin_issue permission' do
expect(policies).not_to include(:admin_issue)
end
it 'does not include the update_issue permission' do
expect(policies).not_to include(:update_issue)
end
end
context 'with a user that is a project member' do
let(:policies) { described_class.abilities(user, issue).to_set }
before do
issue.project.team << [user, :reporter]
end
it 'includes the read_issue permission' do
expect(policies).to include(:read_issue)
end
it 'includes the admin_issue permission' do
expect(policies).to include(:admin_issue)
end
it 'includes the update_issue permission' do
expect(policies).to include(:update_issue)
end
end
context 'without a user' do
let(:policies) { described_class.abilities(nil, issue).to_set }
it 'does not include the read_issue permission' do
expect(policies).not_to include(:read_issue)
end
it 'does not include the admin_issue permission' do
expect(policies).not_to include(:admin_issue)
end
it 'does not include the update_issue permission' do
expect(policies).not_to include(:update_issue)
end
end
end
end
end
Loading
Loading
@@ -6,6 +6,7 @@ describe API::API, api: true do
let(:user) { create(:user) }
let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
let!(:label1) { create(:label, title: 'label1', project: project) }
let!(:priority_label) { create(:label, title: 'bug', project: project, priority: 3) }
 
before do
project.team << [user, :master]
Loading
Loading
@@ -16,13 +17,27 @@ describe API::API, api: true do
group = create(:group)
group_label = create(:group_label, group: group)
project.update(group: group)
expected_keys = [
'id', 'name', 'color', 'description',
'open_issues_count', 'closed_issues_count', 'open_merge_requests_count',
'subscribed', 'priority'
]
 
get api("/projects/#{project.id}/labels", user)
 
expect(response).to have_http_status(200)
expect(json_response).to be_an Array
expect(json_response.size).to eq(2)
expect(json_response.map { |l| l['name'] }).to match_array([group_label.name, label1.name])
expect(json_response.size).to eq(3)
expect(json_response.first.keys).to match_array expected_keys
expect(json_response.map { |l| l['name'] }).to match_array([group_label.name, priority_label.name, label1.name])
expect(json_response.last['name']).to eq(label1.name)
expect(json_response.last['color']).to be_present
expect(json_response.last['description']).to be_nil
expect(json_response.last['open_issues_count']).to eq(0)
expect(json_response.last['closed_issues_count']).to eq(0)
expect(json_response.last['open_merge_requests_count']).to eq(0)
expect(json_response.last['priority']).to be_nil
expect(json_response.last['subscribed']).to be_falsey
end
end
 
Loading
Loading
@@ -31,21 +46,39 @@ describe API::API, api: true do
post api("/projects/#{project.id}/labels", user),
name: 'Foo',
color: '#FFAABB',
description: 'test'
description: 'test',
priority: 2
expect(response).to have_http_status(201)
expect(json_response['name']).to eq('Foo')
expect(json_response['color']).to eq('#FFAABB')
expect(json_response['description']).to eq('test')
expect(json_response['priority']).to eq(2)
end
 
it 'returns created label when only required params' do
post api("/projects/#{project.id}/labels", user),
name: 'Foo & Bar',
color: '#FFAABB'
expect(response.status).to eq(201)
expect(json_response['name']).to eq('Foo & Bar')
expect(json_response['color']).to eq('#FFAABB')
expect(json_response['description']).to be_nil
expect(json_response['priority']).to be_nil
end
it 'creates a prioritized label' do
post api("/projects/#{project.id}/labels", user),
name: 'Foo & Bar',
color: '#FFAABB',
priority: 3
expect(response.status).to eq(201)
expect(json_response['name']).to eq('Foo & Bar')
expect(json_response['color']).to eq('#FFAABB')
expect(json_response['description']).to be_nil
expect(json_response['priority']).to eq(3)
end
 
it 'returns a 400 bad request if name not given' do
Loading
Loading
@@ -95,6 +128,15 @@ describe API::API, api: true do
expect(json_response['message']).to eq('Label already exists')
end
 
it 'returns 400 for invalid priority' do
post api("/projects/#{project.id}/labels", user),
name: 'Foo',
color: '#FFAAFFFF',
priority: 'foo'
expect(response).to have_http_status(400)
end
it 'returns 409 if label already exists in project' do
post api("/projects/#{project.id}/labels", user),
name: 'label1',
Loading
Loading
@@ -155,11 +197,43 @@ describe API::API, api: true do
 
it 'returns 200 if description is changed' do
put api("/projects/#{project.id}/labels", user),
name: 'label1',
name: 'bug',
description: 'test'
expect(response).to have_http_status(200)
expect(json_response['name']).to eq(label1.name)
expect(json_response['name']).to eq(priority_label.name)
expect(json_response['description']).to eq('test')
expect(json_response['priority']).to eq(3)
end
it 'returns 200 if priority is changed' do
put api("/projects/#{project.id}/labels", user),
name: 'bug',
priority: 10
expect(response.status).to eq(200)
expect(json_response['name']).to eq(priority_label.name)
expect(json_response['priority']).to eq(10)
end
it 'returns 200 if a priority is added' do
put api("/projects/#{project.id}/labels", user),
name: 'label1',
priority: 3
expect(response.status).to eq(200)
expect(json_response['name']).to eq(label1.name)
expect(json_response['priority']).to eq(3)
end
it 'returns 200 if the priority is removed' do
put api("/projects/#{project.id}/labels", user),
name: priority_label.name,
priority: nil
expect(response.status).to eq(200)
expect(json_response['name']).to eq(priority_label.name)
expect(json_response['priority']).to be_nil
end
 
it 'returns 404 if label does not exist' do
Loading
Loading
@@ -178,7 +252,7 @@ describe API::API, api: true do
it 'returns 400 if no new parameters given' do
put api("/projects/#{project.id}/labels", user), name: 'label1'
expect(response).to have_http_status(400)
expect(json_response['error']).to eq('new_name, color, description are missing, '\
expect(json_response['error']).to eq('new_name, color, description, priority are missing, '\
'at least one parameter must be provided')
end
 
Loading
Loading
@@ -206,6 +280,14 @@ describe API::API, api: true do
expect(response).to have_http_status(400)
expect(json_response['message']['color']).to eq(['must be a valid color code'])
end
it 'returns 400 for invalid priority' do
post api("/projects/#{project.id}/labels", user),
name: 'Foo',
priority: 'foo'
expect(response).to have_http_status(400)
end
end
 
describe "POST /projects/:id/labels/:label_id/subscription" do
Loading
Loading
Loading
Loading
@@ -52,6 +52,12 @@ describe API::API, api: true do
expect(response).to have_http_status(400)
end
 
it "responds with 400 if url is invalid" do
post api("/hooks", admin), url: 'hp://mep.mep'
expect(response).to have_http_status(400)
end
it "does not create new hook without url" do
expect do
post api("/hooks", admin)
Loading
Loading
Loading
Loading
@@ -266,13 +266,13 @@ describe "Groups", "routing" do
end
 
it "also display group#show on the short path" do
allow(Group).to receive(:find_by_path).and_return(true)
allow(Group).to receive(:find_by).and_return(true)
 
expect(get('/1')).to route_to('groups#show', id: '1')
end
 
it "also display group#show with dot in the path" do
allow(Group).to receive(:find_by_path).and_return(true)
allow(Group).to receive(:find_by).and_return(true)
 
expect(get('/group.with.dot')).to route_to('groups#show', id: 'group.with.dot')
end
Loading
Loading
Loading
Loading
@@ -326,6 +326,9 @@ describe GitPushService, services: true do
author_email: commit_author.email
)
 
allow_any_instance_of(ProcessCommitWorker).to receive(:find_commit).
and_return(commit)
allow(project.repository).to receive(:commits_between).and_return([commit])
end
 
Loading
Loading
@@ -381,6 +384,9 @@ describe GitPushService, services: true do
committed_date: commit_time
)
 
allow_any_instance_of(ProcessCommitWorker).to receive(:find_commit).
and_return(commit)
allow(project.repository).to receive(:commits_between).and_return([commit])
end
 
Loading
Loading
@@ -417,6 +423,9 @@ describe GitPushService, services: true do
allow(project.repository).to receive(:commits_between).
and_return([closing_commit])
 
allow_any_instance_of(ProcessCommitWorker).to receive(:find_commit).
and_return(closing_commit)
project.team << [commit_author, :master]
end
 
Loading
Loading
@@ -562,9 +571,16 @@ describe GitPushService, services: true do
let(:housekeeping) { Projects::HousekeepingService.new(project) }
 
before do
# Flush any raw Redis data stored by the housekeeping code.
Gitlab::Redis.with { |conn| conn.flushall }
allow(Projects::HousekeepingService).to receive(:new).and_return(housekeeping)
end
 
after do
Gitlab::Redis.with { |conn| conn.flushall }
end
it 'does not perform housekeeping when not needed' do
expect(housekeeping).not_to receive(:execute)
 
Loading
Loading
Loading
Loading
@@ -15,10 +15,39 @@ describe Issues::CloseService, services: true do
end
 
describe '#execute' do
let(:service) { described_class.new(project, user) }
it 'checks if the user is authorized to update the issue' do
expect(service).to receive(:can?).with(user, :update_issue, issue).
and_call_original
service.execute(issue)
end
it 'does not close the issue when the user is not authorized to do so' do
allow(service).to receive(:can?).with(user, :update_issue, issue).
and_return(false)
expect(service).not_to receive(:close_issue)
expect(service.execute(issue)).to eq(issue)
end
it 'closes the issue when the user is authorized to do so' do
allow(service).to receive(:can?).with(user, :update_issue, issue).
and_return(true)
expect(service).to receive(:close_issue).
with(issue, commit: nil, notifications: true, system_note: true)
service.execute(issue)
end
end
describe '#close_issue' do
context "valid params" do
before do
perform_enqueued_jobs do
described_class.new(project, user).execute(issue)
described_class.new(project, user).close_issue(issue)
end
end
 
Loading
Loading
@@ -41,24 +70,12 @@ describe Issues::CloseService, services: true do
end
end
 
context 'current user is not authorized to close issue' do
before do
perform_enqueued_jobs do
described_class.new(project, guest).execute(issue)
end
end
it 'does not close the issue' do
expect(issue).to be_open
end
end
context 'when issue is not confidential' do
it 'executes issue hooks' do
expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :issue_hooks)
expect(project).to receive(:execute_services).with(an_instance_of(Hash), :issue_hooks)
 
described_class.new(project, user).execute(issue)
described_class.new(project, user).close_issue(issue)
end
end
 
Loading
Loading
@@ -69,14 +86,14 @@ describe Issues::CloseService, services: true do
expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :confidential_issue_hooks)
expect(project).to receive(:execute_services).with(an_instance_of(Hash), :confidential_issue_hooks)
 
described_class.new(project, user).execute(issue)
described_class.new(project, user).close_issue(issue)
end
end
 
context 'external issue tracker' do
before do
allow(project).to receive(:default_issues_tracker?).and_return(false)
described_class.new(project, user).execute(issue)
described_class.new(project, user).close_issue(issue)
end
 
it { expect(issue).to be_valid }
Loading
Loading
Loading
Loading
@@ -14,8 +14,10 @@ describe Projects::HousekeepingService do
 
describe '#execute' do
it 'enqueues a sidekiq job' do
expect(subject).to receive(:try_obtain_lease).and_return(true)
expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id)
expect(subject).to receive(:try_obtain_lease).and_return(:the_uuid)
expect(subject).to receive(:lease_key).and_return(:the_lease_key)
expect(subject).to receive(:task).and_return(:the_task)
expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :the_task, :the_lease_key, :the_uuid)
 
subject.execute
expect(project.reload.pushes_since_gc).to eq(0)
Loading
Loading
@@ -58,4 +60,26 @@ describe Projects::HousekeepingService do
end.to change { project.pushes_since_gc }.from(0).to(1)
end
end
it 'uses all three kinds of housekeeping we offer' do
allow(subject).to receive(:try_obtain_lease).and_return(:the_uuid)
allow(subject).to receive(:lease_key).and_return(:the_lease_key)
# At push 200
expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :gc, :the_lease_key, :the_uuid).
exactly(1).times
# At push 50, 100, 150
expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :full_repack, :the_lease_key, :the_uuid).
exactly(3).times
# At push 10, 20, ... (except those above)
expect(GitGarbageCollectWorker).to receive(:perform_async).with(project.id, :incremental_repack, :the_lease_key, :the_uuid).
exactly(16).times
201.times do
subject.increment!
subject.execute if subject.needed?
end
expect(project.pushes_since_gc).to eq(1)
end
end
Loading
Loading
@@ -29,7 +29,7 @@ RSpec.configure do |config|
config.include Devise::Test::ControllerHelpers, type: :controller
config.include Warden::Test::Helpers, type: :request
config.include LoginHelpers, type: :feature
config.include SearchHelpers, type: :feature
config.include SearchHelpers, type: :feature
config.include StubConfiguration
config.include EmailHelpers
config.include TestEnv
Loading
Loading
Loading
Loading
@@ -205,20 +205,18 @@ module TestEnv
end
 
def set_repo_refs(repo_path, branch_sha)
instructions = branch_sha.map {|branch, sha| "update refs/heads/#{branch}\x00#{sha}\x00" }.join("\x00") << "\x00"
update_refs = %W(#{Gitlab.config.git.bin_path} update-ref --stdin -z)
reset = proc do
IO.popen(update_refs, "w") {|io| io.write(instructions) }
$?.success?
end
Dir.chdir(repo_path) do
branch_sha.each do |branch, sha|
# Try to reset without fetching to avoid using the network.
reset = %W(#{Gitlab.config.git.bin_path} update-ref refs/heads/#{branch} #{sha})
unless system(*reset)
if system(*%W(#{Gitlab.config.git.bin_path} fetch origin))
unless system(*reset)
raise 'The fetched test seed '\
'does not contain the required revision.'
end
else
raise 'Could not fetch test seed repository.'
end
end
# Try to reset without fetching to avoid using the network.
unless reset.call
raise 'Could not fetch test seed repository.' unless system(*%W(#{Gitlab.config.git.bin_path} fetch origin))
raise 'The fetched test seed does not contain the required revision.' unless reset.call
end
end
end
Loading
Loading
require 'fileutils'
require 'spec_helper'
 
describe GitGarbageCollectWorker do
Loading
Loading
@@ -6,16 +8,12 @@ describe GitGarbageCollectWorker do
 
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)
it "flushes ref caches when the task is 'gc'" do
expect(subject).to receive(:command).with(:gc).and_return([:the, :command])
expect(Gitlab::Popen).to receive(:popen).
with([:the, :command], project.repository.path_to_repo).and_return(["", 0])
expect_any_instance_of(Repository).to receive(:after_create_branch).and_call_original
expect_any_instance_of(Repository).to receive(:branch_names).and_call_original
expect_any_instance_of(Repository).to receive(:branch_count).and_call_original
Loading
Loading
@@ -23,5 +21,110 @@ describe GitGarbageCollectWorker do
 
subject.perform(project.id)
end
shared_examples 'gc tasks' do
before { allow(subject).to receive(:bitmaps_enabled?).and_return(bitmaps_enabled) }
it 'incremental repack adds a new packfile' do
create_objects(project)
before_packs = packs(project)
expect(before_packs.count).to be >= 1
subject.perform(project.id, 'incremental_repack')
after_packs = packs(project)
# Exactly one new pack should have been created
expect(after_packs.count).to eq(before_packs.count + 1)
# Previously existing packs are still around
expect(before_packs & after_packs).to eq(before_packs)
end
it 'full repack consolidates into 1 packfile' do
create_objects(project)
subject.perform(project.id, 'incremental_repack')
before_packs = packs(project)
expect(before_packs.count).to be >= 2
subject.perform(project.id, 'full_repack')
after_packs = packs(project)
expect(after_packs.count).to eq(1)
# Previously existing packs should be gone now
expect(after_packs - before_packs).to eq(after_packs)
expect(File.exist?(bitmap_path(after_packs.first))).to eq(bitmaps_enabled)
end
it 'gc consolidates into 1 packfile and updates packed-refs' do
create_objects(project)
before_packs = packs(project)
before_packed_refs = packed_refs(project)
expect(before_packs.count).to be >= 1
subject.perform(project.id, 'gc')
after_packed_refs = packed_refs(project)
after_packs = packs(project)
expect(after_packs.count).to eq(1)
# Previously existing packs should be gone now
expect(after_packs - before_packs).to eq(after_packs)
# The packed-refs file should have been updated during 'git gc'
expect(before_packed_refs).not_to eq(after_packed_refs)
expect(File.exist?(bitmap_path(after_packs.first))).to eq(bitmaps_enabled)
end
end
context 'with bitmaps enabled' do
let(:bitmaps_enabled) { true }
include_examples 'gc tasks'
end
context 'with bitmaps disabled' do
let(:bitmaps_enabled) { false }
include_examples 'gc tasks'
end
end
# Create a new commit on a random new branch
def create_objects(project)
rugged = project.repository.rugged
old_commit = rugged.branches.first.target
new_commit_sha = Rugged::Commit.create(
rugged,
message: "hello world #{SecureRandom.hex(6)}",
author: Gitlab::Git::committer_hash(email: 'foo@bar', name: 'baz'),
committer: Gitlab::Git::committer_hash(email: 'foo@bar', name: 'baz'),
tree: old_commit.tree,
parents: [old_commit],
)
project.repository.update_ref!(
"refs/heads/#{SecureRandom.hex(6)}",
new_commit_sha,
Gitlab::Git::BLANK_SHA
)
end
def packs(project)
Dir["#{project.repository.path_to_repo}/objects/pack/*.pack"]
end
def packed_refs(project)
path = "#{project.repository.path_to_repo}/packed-refs"
FileUtils.touch(path)
File.read(path)
end
def bitmap_path(pack)
pack.sub(/\.pack\z/, '.bitmap')
end
end
require 'spec_helper'
describe ProcessCommitWorker do
let(:worker) { described_class.new }
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
let(:issue) { create(:issue, project: project, author: user) }
let(:commit) { project.commit }
describe '#perform' do
it 'does not process the commit when the project does not exist' do
expect(worker).not_to receive(:close_issues)
worker.perform(-1, user.id, commit.id)
end
it 'does not process the commit when the user does not exist' do
expect(worker).not_to receive(:close_issues)
worker.perform(project.id, -1, commit.id)
end
it 'does not process the commit when the commit no longer exists' do
expect(worker).not_to receive(:close_issues)
worker.perform(project.id, user.id, 'this-should-does-not-exist')
end
it 'processes the commit message' do
expect(worker).to receive(:process_commit_message).and_call_original
worker.perform(project.id, user.id, commit.id)
end
it 'updates the issue metrics' do
expect(worker).to receive(:update_issue_metrics).and_call_original
worker.perform(project.id, user.id, commit.id)
end
end
describe '#process_commit_message' do
context 'when pushing to the default branch' do
it 'closes issues that should be closed per the commit message' do
allow(commit).to receive(:safe_message).
and_return("Closes #{issue.to_reference}")
expect(worker).to receive(:close_issues).
with(project, user, user, commit, [issue])
worker.process_commit_message(project, commit, user, user, true)
end
end
context 'when pushing to a non-default branch' do
it 'does not close any issues' do
allow(commit).to receive(:safe_message).
and_return("Closes #{issue.to_reference}")
expect(worker).not_to receive(:close_issues)
worker.process_commit_message(project, commit, user, user, false)
end
end
it 'creates cross references' do
expect(commit).to receive(:create_cross_references!)
worker.process_commit_message(project, commit, user, user)
end
end
describe '#close_issues' do
context 'when the user can update the issues' do
it 'closes the issues' do
worker.close_issues(project, user, user, commit, [issue])
issue.reload
expect(issue.closed?).to eq(true)
end
end
context 'when the user can not update the issues' do
it 'does not close the issues' do
other_user = create(:user)
worker.close_issues(project, other_user, other_user, commit, [issue])
issue.reload
expect(issue.closed?).to eq(false)
end
end
end
describe '#update_issue_metrics' do
it 'updates any existing issue metrics' do
allow(commit).to receive(:safe_message).
and_return("Closes #{issue.to_reference}")
worker.update_issue_metrics(commit, user)
metric = Issue::Metrics.first
expect(metric.first_mentioned_in_commit_at).to eq(commit.committed_date)
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