Skip to content
Snippets Groups Projects
Commit 3d7194f0 authored by Izaak Alpert's avatar Izaak Alpert Committed by Izaak Alpert
Browse files

Merge Request on forked projects

The good:

 - You can do a merge request for a forked commit and it will merge properly (i.e. it does work).
 - Push events take into account merge requests on forked projects
 - Tests around merge_actions now present, spinach, and other rspec tests
 - Satellites now clean themselves up rather then recreate

The questionable:

 - Events only know about target projects
 - Project's merge requests only hold on to MR's where they are the target
 - All operations performed in the satellite

The bad:

  -  Duplication between project's repositories and satellites (e.g. commits_between)

(for reference: http://feedback.gitlab.com/forums/176466-general/suggestions/3456722-merge-requests-between-projects-repos)

Fixes:

Make test repos/satellites only create when needed
-Spinach/Rspec now only initialize test directory, and setup stubs (things that are relatively cheap)
-project_with_code, source_project_with_code, and target_project_with_code now create/destroy their repos individually
-fixed remote removal
-How to merge renders properly
-Update emails to show project/branches
-Edit MR doesn't set target branch
-Fix some failures on editing/creating merge requests, added a test
-Added back a test around merge request observer
-Clean up project_transfer_spec, Remove duplicate enable/disable observers
-Ensure satellite lock files are cleaned up, Attempted to add some testing around these as well
-Signifant speed ups for tests
-Update formatting ordering in notes_on_merge_requests
-Remove wiki schema update
Fixes for search/search results
-Search results was using by_project for a list of projects, updated this to use in_projects
-updated search results to reference the correct (target) project
-udpated search results to print both sides of the merge request

Change-Id: I19407990a0950945cc95d62089cbcc6262dab1a8
parent fd033671
No related branches found
No related tags found
1 merge request!4184Merge Request on forked projects
Showing
with 582 additions and 106 deletions
Loading
Loading
@@ -51,9 +51,10 @@ module API
#
# Parameters:
#
# id (required) - The ID of a project
# id (required) - The ID of a project - this will be the source of the merge request
# source_branch (required) - The source branch
# target_branch (required) - The target branch
# target_project - The target project of the merge request defaults to the :id of the project
# assignee_id - Assignee user ID
# title (required) - Title of MR
#
Loading
Loading
@@ -63,11 +64,15 @@ module API
post ":id/merge_requests" do
authorize! :write_merge_request, user_project
required_attributes! [:source_branch, :target_branch, :title]
attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title]
attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id]
merge_request = user_project.merge_requests.new(attrs)
merge_request.author = current_user
merge_request.source_project = user_project
if !attrs[:target_project_id].nil? && user_project.forked? && user_project.forked_from_project.id.to_s == attrs[:target_project_id]
merge_request.target_project = Project.find_by_id(attrs[:target_project_id])
elsif attrs[:target_project].nil?
merge_request.target_project = user_project
end
if merge_request.save
merge_request.reload_code
present merge_request, with: Entities::MergeRequest
Loading
Loading
module Gitlab
module Satellite
class Action
DEFAULT_OPTIONS = { git_timeout: 30.seconds }
DEFAULT_OPTIONS = { git_timeout: 30.seconds}
 
attr_accessor :options, :project, :user
 
Loading
Loading
@@ -34,16 +34,19 @@ module Gitlab
Gitlab::ShellEnv.reset_env
end
 
# * Clears the satellite
# * Updates the satellite from Gitolite
# * Recreates the satellite
# * Sets up Git variables for the user
#
# Note: use this within #in_locked_and_timed_satellite
def prepare_satellite!(repo)
project.satellite.clear_and_update!
 
repo.git.config({}, "user.name", user.name)
repo.git.config({}, "user.email", user.email)
repo.config['user.name']=user.name
repo.config['user.email']=user.email
end
def default_options(options = {})
{raise: true, timeout: true}.merge(options)
end
end
end
Loading
Loading
Loading
Loading
@@ -5,37 +5,37 @@ module Gitlab
attr_accessor :merge_request
 
def initialize(user, merge_request)
super user, merge_request.project
super user, merge_request.target_project
@merge_request = merge_request
end
 
# Checks if a merge request can be executed without user interaction
def can_be_merged?
in_locked_and_timed_satellite do |merge_repo|
prepare_satellite!(merge_repo)
merge_in_satellite!(merge_repo)
end
end
 
# Merges the source branch into the target branch in the satellite and
# pushes it back to Gitolite.
# It also removes the source branch if requested in the merge request.
# pushes it back to the repository.
# It also removes the source branch if requested in the merge request (and this is permitted by the merge request).
#
# Returns false if the merge produced conflicts
# Returns false if pushing from the satellite to Gitolite failed or was rejected
# Returns false if pushing from the satellite to the repository failed or was rejected
# Returns true otherwise
def merge!
in_locked_and_timed_satellite do |merge_repo|
prepare_satellite!(merge_repo)
if merge_in_satellite!(merge_repo)
# push merge back to Gitolite
# will raise CommandFailed when push fails
merge_repo.git.push({raise: true, timeout: true}, :origin, merge_request.target_branch)
merge_repo.git.push(default_options, :origin, merge_request.target_branch)
# remove source branch
if merge_request.should_remove_source_branch && !project.root_ref?(merge_request.source_branch)
# will raise CommandFailed when push fails
merge_repo.git.push({raise: true, timeout: true}, :origin, ":#{merge_request.source_branch}")
merge_repo.git.push(default_options, :origin, ":#{merge_request.source_branch}")
end
# merge, push and branch removal successful
true
end
Loading
Loading
@@ -45,6 +45,82 @@ module Gitlab
false
end
 
# Get a raw diff of the source to the target
def diff_in_satellite
in_locked_and_timed_satellite do |merge_repo|
prepare_satellite!(merge_repo)
update_satellite_source_and_target!(merge_repo)
if merge_request.for_fork?
diff = merge_repo.git.native(:diff, default_options, "origin/#{merge_request.target_branch}", "source/#{merge_request.source_branch}")
else
diff = merge_repo.git.native(:diff, default_options, "#{merge_request.target_branch}", "#{merge_request.source_branch}")
end
return diff
end
rescue Grit::Git::CommandFailed => ex
Gitlab::GitLogger.error(ex.message)
false
end
# Only show what is new in the source branch compared to the target branch, not the other way around.
# The line below with merge_base is equivalent to diff with three dots (git diff branch1...branch2)
# From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B"
def diffs_between_satellite
in_locked_and_timed_satellite do |merge_repo|
prepare_satellite!(merge_repo)
update_satellite_source_and_target!(merge_repo)
if merge_request.for_fork?
common_commit = merge_repo.git.native(:merge_base, default_options, ["origin/#{merge_request.target_branch}", "source/#{merge_request.source_branch}"]).strip
diffs = merge_repo.diff(default_options, common_commit, "source/#{merge_request.source_branch}")
else
common_commit = merge_repo.git.native(:merge_base, default_options, ["#{merge_request.target_branch}", "#{merge_request.source_branch}"]).strip
diffs = merge_repo.diff(default_options, common_commit, "#{merge_request.source_branch}")
end
return diffs
end
rescue Grit::Git::CommandFailed => ex
Gitlab::GitLogger.error(ex.message)
false
end
# Get commit as an email patch
def format_patch
in_locked_and_timed_satellite do |merge_repo|
prepare_satellite!(merge_repo)
update_satellite_source_and_target!(merge_repo)
if (merge_request.for_fork?)
patch = merge_repo.git.format_patch(default_options({stdout: true}), "origin/#{merge_request.target_branch}...source/#{merge_request.source_branch}")
else
patch = merge_repo.git.format_patch(default_options({stdout: true}), "#{merge_request.target_branch}...#{merge_request.source_branch}")
end
return patch
end
rescue Grit::Git::CommandFailed => ex
Gitlab::GitLogger.error(ex.message)
false
end
# Retrieve an array of commits between the source and the target
def commits_between
in_locked_and_timed_satellite do |merge_repo|
prepare_satellite!(merge_repo)
update_satellite_source_and_target!(merge_repo)
if (merge_request.for_fork?)
commits = merge_repo.commits_between("origin/#{merge_request.target_branch}", "source/#{merge_request.source_branch}")
else
commits = merge_repo.commits_between("#{merge_request.target_branch}", "#{merge_request.source_branch}")
end
return commits
end
rescue Grit::Git::CommandFailed => ex
Gitlab::GitLogger.error(ex.message)
false
end
private
 
# Merges the source_branch into the target_branch in the satellite.
Loading
Loading
@@ -54,18 +130,38 @@ module Gitlab
# Returns false if the merge produced conflicts
# Returns true otherwise
def merge_in_satellite!(repo)
prepare_satellite!(repo)
# create target branch in satellite at the corresponding commit from Gitolite
repo.git.checkout({raise: true, timeout: true, b: true}, merge_request.target_branch, "origin/#{merge_request.target_branch}")
update_satellite_source_and_target!(repo)
 
# merge the source branch from Gitolite into the satellite
# merge the source branch into the satellite
# will raise CommandFailed when merge fails
repo.git.pull({raise: true, timeout: true, no_ff: true}, :origin, merge_request.source_branch)
if merge_request.for_fork?
repo.git.pull(default_options({no_ff: true}), 'source', merge_request.source_branch)
else
repo.git.pull(default_options({no_ff: true}), 'origin', merge_request.source_branch)
end
rescue Grit::Git::CommandFailed => ex
Gitlab::GitLogger.error(ex.message)
false
end
# Assumes a satellite exists that is a fresh clone of the projects repo, prepares satellite for merges, diffs etc
def update_satellite_source_and_target!(repo)
if merge_request.for_fork?
repo.remote_add('source', merge_request.source_project.repository.path_to_repo)
repo.remote_fetch('source')
repo.git.checkout(default_options({b: true}), merge_request.target_branch, "origin/#{merge_request.target_branch}")
else
# We can't trust the input here being branch names, we can't always check it out because it could be a relative ref i.e. HEAD~3
# we could actually remove the if true, because it should never ever happen (as long as the satellite has been prepared)
repo.git.checkout(default_options, "#{merge_request.source_branch}")
repo.git.checkout(default_options, "#{merge_request.target_branch}")
end
rescue Grit::Git::CommandFailed => ex
Gitlab::GitLogger.error(ex.message)
false
end
end
end
end
module Gitlab
class SatelliteNotExistError < StandardError; end
class SatelliteNotExistError < StandardError;
end
 
module Satellite
class Satellite
Loading
Loading
@@ -21,11 +22,14 @@ module Gitlab
raise SatelliteNotExistError.new("Satellite doesn't exist")
end
 
def clear_and_update!
raise_no_satellite unless exists?
File.exists? path
@repo = nil
clear_working_dir!
delete_heads!
remove_remotes!
update_from_source!
end
 
Loading
Loading
@@ -55,14 +59,16 @@ module Gitlab
raise_no_satellite unless exists?
 
File.open(lock_file, "w+") do |f|
f.flock(File::LOCK_EX)
Dir.chdir(path) do
return yield
begin
f.flock File::LOCK_EX
Dir.chdir(path) { return yield }
ensure
f.flock File::LOCK_UN
end
end
end
 
def lock_file
create_locks_dir unless File.exists?(lock_files_dir)
File.join(lock_files_dir, "satellite_#{project.id}.lock")
Loading
Loading
@@ -100,20 +106,35 @@ module Gitlab
if heads.include? PARKING_BRANCH
repo.git.checkout({}, PARKING_BRANCH)
else
repo.git.checkout({b: true}, PARKING_BRANCH)
repo.git.checkout(default_options({b: true}), PARKING_BRANCH)
end
 
# remove the parking branch from the list of heads ...
heads.delete(PARKING_BRANCH)
# ... and delete all others
heads.each { |head| repo.git.branch({D: true}, head) }
heads.each { |head| repo.git.branch(default_options({D: true}), head) }
end
# Deletes all remotes except origin
#
# This ensures we have no remote name clashes or issues updating branches when
# working with the satellite.
def remove_remotes!
remotes = repo.git.remote.split(' ')
remotes.delete('origin')
remotes.each { |name| repo.git.remote(default_options,'rm', name)}
end
 
# Updates the satellite from Gitolite
#
# Note: this will only update remote branches (i.e. origin/*)
def update_from_source!
repo.git.fetch({timeout: true}, :origin)
repo.git.fetch(default_options, :origin)
end
def default_options(options = {})
{raise: true, timeout: true}.merge(options)
end
 
# Create directory for stroing
Loading
Loading
require 'spec_helper'
describe FilterContext do
let(:user) { create :user }
let(:user2) { create :user }
let(:project1) { create(:project, creator_id: user.id) }
let(:project2) { create(:project, creator_id: user.id) }
let(:merge_request1) { create(:merge_request, author_id: user.id, source_project: project1, target_project: project2) }
let(:merge_request2) { create(:merge_request, author_id: user.id, source_project: project2, target_project: project1) }
let(:merge_request3) { create(:merge_request, author_id: user.id, source_project: project2, target_project: project2) }
let(:merge_request4) { create(:merge_request, author_id: user2.id, source_project: project2, target_project: project2) }
let(:issue1) { create(:issue, assignee_id: user.id, project: project1) }
let(:issue2) { create(:issue, assignee_id: user.id, project: project2) }
let(:issue3) { create(:issue, assignee_id: user2.id, project: project2) }
describe 'merge requests' do
before :each do
merge_request1
merge_request2
merge_request3
merge_request4
end
it 'should by default filter properly' do
merge_requests = user.cared_merge_requests
params ={}
merge_requests = FilterContext.new(merge_requests, params).execute
merge_requests.size.should == 3
end
it 'should apply blocks passed in on creation to the filters' do
merge_requests = user.cared_merge_requests
params = {:project_id => project1.id}
merge_requests = FilterContext.new(merge_requests, params).execute
merge_requests.size.should == 2
end
end
describe 'issues' do
before :each do
issue1
issue2
issue3
end
it 'should by default filter projects properly' do
issues = user.assigned_issues
params = {}
issues = FilterContext.new(issues, params).execute
issues.size.should == 2
end
it 'should apply blocks passed in on creation to the filters' do
issues = user.assigned_issues
params = {:project_id => project1.id}
issues = FilterContext.new(issues, params).execute
issues.size.should == 1
end
end
end
\ No newline at end of file
Loading
Loading
@@ -2,12 +2,11 @@ require 'spec_helper'
 
describe Projects::CommitController do
let(:project) { create(:project_with_code) }
let(:user) { create(:user) }
let(:commit) { project.repository.last_commit_for("master") }
let(:user) { create(:user) }
let(:commit) { project.repository.last_commit_for("master") }
 
before do
sign_in(user)
project.team << [user, :master]
end
 
Loading
Loading
Loading
Loading
@@ -2,7 +2,7 @@ require 'spec_helper'
 
describe Projects::CommitsController do
let(:project) { create(:project_with_code) }
let(:user) { create(:user) }
let(:user) { create(:user) }
 
before do
sign_in(user)
Loading
Loading
Loading
Loading
@@ -3,7 +3,7 @@ require 'spec_helper'
describe Projects::MergeRequestsController do
let(:project) { create(:project_with_code) }
let(:user) { create(:user) }
let(:merge_request) { create(:merge_request_with_diffs, project: project, target_branch: "bcf03b5d~3", source_branch: "bcf03b5d") }
let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project, target_branch: "bcf03b5d~3", source_branch: "bcf03b5d") }
 
before do
sign_in(user)
Loading
Loading
@@ -28,7 +28,7 @@ describe Projects::MergeRequestsController do
it "should render it" do
get :show, project_id: project.code, id: merge_request.id, format: format
 
expect(response.body).to eq(merge_request.send(:"to_#{format}"))
expect(response.body).to eq((merge_request.send(:"to_#{format}",user)).to_s)
end
 
it "should not escape Html" do
Loading
Loading
<<<<<<< HEAD
include ActionDispatch::TestProcess
=======
require Rails.root.join('spec', 'support', 'test_env.rb')
>>>>>>> Merge Request on forked projects
 
FactoryGirl.define do
sequence :sentence, aliases: [:title, :content] do
Loading
Loading
@@ -29,8 +33,19 @@ FactoryGirl.define do
sequence(:name) { |n| "project#{n}" }
path { name.downcase.gsub(/\s/, '_') }
creator
trait :source do
sequence(:name) { |n| "source project#{n}" }
end
trait :target do
sequence(:name) { |n| "target project#{n}" }
end
factory :source_project, traits: [:source]
factory :target_project, traits: [:target]
end
 
factory :redmine_project, parent: :project do
issues_tracker { "redmine" }
issues_tracker_id { "project_name_in_redmine" }
Loading
Loading
@@ -39,14 +54,24 @@ FactoryGirl.define do
factory :project_with_code, parent: :project do
path { 'gitlabhq' }
 
trait :source_path do
path { 'source_gitlabhq' }
end
trait :target_path do
path { 'target_gitlabhq' }
end
factory :source_project_with_code, traits: [:source, :source_path]
factory :target_project_with_code, traits: [:target, :target_path]
after :create do |project|
repos_path = Rails.root.join('tmp', 'test-git-base-path')
seed_repo = Rails.root.join('tmp', 'repositories', 'gitlabhq')
target_repo = File.join(repos_path, project.path_with_namespace + '.git')
system("ln -s #{seed_repo} #{target_repo}")
TestEnv.clear_repo_dir(project.namespace, project.path)
TestEnv.create_repo(project.namespace, project.path)
end
end
 
factory :group do
sequence(:name) { |n| "group#{n}" }
path { name.downcase.gsub(/\s/, '_') }
Loading
Loading
@@ -86,7 +111,8 @@ FactoryGirl.define do
factory :merge_request do
title
author
project factory: :project_with_code
source_project factory: :source_project_with_code
target_project factory: :target_project_with_code
source_branch "master"
target_branch "stable"
 
Loading
Loading
@@ -96,13 +122,13 @@ FactoryGirl.define do
source_branch "stable" # pretend bcf03b5d
st_commits do
[
project.repository.commit('bcf03b5d').to_hash,
project.repository.commit('bcf03b5d~1').to_hash,
project.repository.commit('bcf03b5d~2').to_hash
source_project.repository.commit('bcf03b5d').to_hash,
source_project.repository.commit('bcf03b5d~1').to_hash,
source_project.repository.commit('bcf03b5d~2').to_hash
]
end
st_diffs do
project.repo.diff("bcf03b5d~3", "bcf03b5d")
source_project.repo.diff("bcf03b5d~3", "bcf03b5d")
end
end
 
Loading
Loading
@@ -133,7 +159,7 @@ FactoryGirl.define do
 
trait :on_commit do
project factory: :project_with_code
commit_id "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
commit_id "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
noteable_type "Commit"
end
 
Loading
Loading
@@ -143,12 +169,12 @@ FactoryGirl.define do
 
trait :on_merge_request do
project factory: :project_with_code
noteable_id 1
noteable_id 1
noteable_type "MergeRequest"
end
 
trait :on_issue do
noteable_id 1
noteable_id 1
noteable_type "Issue"
end
 
Loading
Loading
Loading
Loading
@@ -5,8 +5,10 @@ INVALID_FACTORIES = [
:invalid_key,
]
 
FactoryGirl.factories.map(&:name).each do |factory_name|
next if INVALID_FACTORIES.include?(factory_name)
describe "#{factory_name} factory" do
it 'should be valid' do
build(factory_name).should be_valid
Loading
Loading
Loading
Loading
@@ -3,11 +3,11 @@ require 'spec_helper'
describe "GitLab Flavored Markdown" do
let(:project) { create(:project_with_code) }
let(:issue) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, project: project) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:fred) do
u = create(:user, name: "fred")
project.team << [u, :master]
u
u = create(:user, name: "fred")
project.team << [u, :master]
u
end
 
before do
Loading
Loading
@@ -83,9 +83,7 @@ describe "GitLab Flavored Markdown" do
 
describe "for merge requests" do
before do
@merge_request = create(:merge_request,
project: project,
title: "fix ##{issue.id}")
@merge_request = create(:merge_request, source_project: project, target_project: project, title: "fix ##{issue.id}")
end
 
it "should render title in merge_requests#index" do
Loading
Loading
Loading
Loading
@@ -2,8 +2,8 @@ require 'spec_helper'
 
describe "On a merge request", js: true do
let!(:project) { create(:project_with_code) }
let!(:merge_request) { create(:merge_request, project: project) }
let!(:note) { create(:note_on_merge_request_with_attachment, project: project) }
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let!(:note) { create(:note_on_merge_request_with_attachment, source_project: project, target_project: project) }
 
before do
login_as :user
Loading
Loading
@@ -62,7 +62,7 @@ describe "On a merge request", js: true do
 
it 'should be added and form reset' do
should have_content("This is awsome!")
within(".js-main-target-form") { should have_no_field("note[note]", with: "This is awesome!") }
within(".js-main-target-form") { should have_no_field("note[note]", with: "This is awesome!") }
within(".js-main-target-form") { should have_css(".js-note-preview", visible: false) }
within(".js-main-target-form") { should have_css(".js-note-text", visible: true) }
end
Loading
Loading
@@ -135,8 +135,8 @@ describe "On a merge request", js: true do
end
 
describe "On a merge request diff", js: true, focus: true do
let!(:project) { create(:project_with_code) }
let!(:merge_request) { create(:merge_request_with_diffs, project: project) }
let!(:project) { create(:source_project_with_code) }
let!(:merge_request) { create(:merge_request_with_diffs, source_project: project, target_project: project) }
 
before do
login_as :user
Loading
Loading
@@ -144,6 +144,7 @@ describe "On a merge request diff", js: true, focus: true do
visit diffs_project_merge_request_path(project, merge_request)
end
 
subject { page }
 
describe "when adding a note" do
Loading
Loading
@@ -205,13 +206,13 @@ describe "On a merge request diff", js: true, focus: true do
 
# TODO: fix
#it 'should check if previews were rendered separately' do
#within("tr[id='4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185'] + .js-temp-notes-holder") do
#should have_css(".js-note-preview", text: "One comment on line 185")
#end
#within("tr[id='4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185'] + .js-temp-notes-holder") do
#should have_css(".js-note-preview", text: "One comment on line 185")
#end
 
#within("tr[id='342e16cbbd482ac2047dc679b2749d248cc1428f_18_17'] + .js-temp-notes-holder") do
#should have_css(".js-note-preview", text: "Another comment on line 17")
#end
#within("tr[id='342e16cbbd482ac2047dc679b2749d248cc1428f_18_17'] + .js-temp-notes-holder") do
#should have_css(".js-note-preview", text: "Another comment on line 17")
#end
#end
end
 
Loading
Loading
@@ -238,39 +239,38 @@ describe "On a merge request diff", js: true, focus: true do
 
# TODO: fix
#it "should remove last note of a discussion" do
#within("tr[id='342e16cbbd482ac2047dc679b2749d248cc1428f_18_17'] + .notes-holder") do
#find(".js-note-delete").click
#end
#should_not have_css(".note_holder")
# within("tr[id='342e16cbbd482ac2047dc679b2749d248cc1428f_18_17'] + .notes-holder") do
# find(".js-note-delete").click
# end
# should_not have_css(".note_holder")
#end
end
end
 
# TODO: fix
#describe "when replying to a note" do
#before do
## create first note
#find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_184_184"]').click
#before do
## create first note
# find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_184_184"]').click
 
#within(".js-temp-notes-holder") do
#fill_in "note[note]", with: "One comment on line 184"
#click_button("Add Comment")
#end
# within(".js-temp-notes-holder") do
# fill_in "note[note]", with: "One comment on line 184"
# click_button("Add Comment")
#end
 
#within(".js-temp-notes-holder") do
#find(".js-discussion-reply-button").click
#fill_in "note[note]", with: "An additional comment in reply"
#click_button("Add Comment")
#end
#end
#it 'should be inserted and form removed from reply' do
#should have_content("An additional comment in reply")
#within(".notes_holder") { should have_css(".note", count: 2) }
#within(".notes_holder") { should have_no_css("form") }
#within(".notes_holder") { should have_link("Reply") }
#end
# within(".js-temp-notes-holder") do
# find(".js-discussion-reply-button").click
# fill_in "note[note]", with: "An additional comment in reply"
# click_button("Add Comment")
# end
#end
#it 'should be inserted and form removed from reply' do
# should have_content("An additional comment in reply")
# within(".notes_holder") { should have_css(".note", count: 2) }
# within(".notes_holder") { should have_no_css("form") }
# within(".notes_holder") { should have_link("Reply") }
# end
#end
end
 
Loading
Loading
Loading
Loading
@@ -2,6 +2,7 @@ require 'spec_helper'
 
describe "Profile account page" do
before(:each) { enable_observers }
after(:each) {disable_observers}
let(:user) { create(:user) }
 
before do
Loading
Loading
Loading
Loading
@@ -2,6 +2,7 @@ require 'spec_helper'
 
describe "Projects" do
before(:each) { enable_observers }
after(:each) {disable_observers}
before { login_as :user }
 
describe "DELETE /projects/:id" do
Loading
Loading
Loading
Loading
@@ -14,13 +14,14 @@ describe "Application access" do
end
 
describe "Project" do
let(:project) { create(:project_with_code) }
let(:project) { create(:project_with_code) }
 
let(:master) { create(:user) }
let(:guest) { create(:user) }
let(:master) { create(:user) }
let(:guest) { create(:user) }
let(:reporter) { create(:user) }
 
before do
# full access
project.team << [master, :master]
 
Loading
Loading
@@ -108,7 +109,7 @@ describe "Application access" do
describe "GET /project_code/blob" do
before do
commit = project.repository.commit
path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob)}.first.name
path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob) }.first.name
@blob_path = project_blob_path(project, File.join(commit.id, path))
end
 
Loading
Loading
@@ -232,13 +233,13 @@ describe "Application access" do
 
 
describe "PublicProject" do
let(:project) { create(:project_with_code) }
let(:project) { create(:project_with_code) }
 
let(:master) { create(:user) }
let(:guest) { create(:user) }
let(:master) { create(:user) }
let(:guest) { create(:user) }
let(:reporter) { create(:user) }
 
let(:admin) { create(:user) }
let(:admin) { create(:user) }
 
before do
# public project
Loading
Loading
@@ -339,7 +340,7 @@ describe "Application access" do
describe "GET /project_code/blob" do
before do
commit = project.repository.commit
path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob)}.first.name
path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob) }.first.name
@blob_path = project_blob_path(project, File.join(commit.id, path))
end
 
Loading
Loading
Loading
Loading
@@ -9,7 +9,7 @@ describe GitlabMarkdownHelper do
let(:user) { create(:user, username: 'gfm') }
let(:commit) { project.repository.commit }
let(:issue) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, project: project) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:snippet) { create(:project_snippet, project: project) }
let(:member) { project.users_projects.where(user_id: user).first }
 
Loading
Loading
require 'spec_helper'
describe 'Gitlab::Satellite::Action' do
let(:project) { create(:project_with_code) }
let(:user) { create(:user) }
describe '#prepare_satellite!' do
it 'create a repository with a parking branch and one remote: origin' do
repo = project.satellite.repo
#now lets dirty it up
starting_remote_count = repo.git.list_remotes.size
starting_remote_count.should >= 1
#kind of hookey way to add a second remote
origin_uri = repo.git.remote({v: true}).split(" ")[1]
begin
repo.git.remote({raise: true}, 'add', 'another-remote', origin_uri)
repo.git.branch({raise: true}, 'a-new-branch')
repo.heads.size.should > (starting_remote_count)
repo.git.remote().split(" ").size.should > (starting_remote_count)
rescue
end
repo.git.config({}, "user.name", "#{user.name} -- foo")
repo.git.config({}, "user.email", "#{user.email} -- foo")
repo.config['user.name'].should =="#{user.name} -- foo"
repo.config['user.email'].should =="#{user.email} -- foo"
#These must happen in the context of the satellite directory...
satellite_action = Gitlab::Satellite::Action.new(user, project)
project.satellite.lock {
#Now clean it up, use send to get around prepare_satellite! being protected
satellite_action.send(:prepare_satellite!, repo)
}
#verify it's clean
heads = repo.heads.map(&:name)
heads.size.should == 1
heads.include?(Gitlab::Satellite::Satellite::PARKING_BRANCH).should == true
remotes = repo.git.remote().split(' ')
remotes.size.should == 1
remotes.include?('origin').should == true
repo.config['user.name'].should ==user.name
repo.config['user.email'].should ==user.email
end
end
describe '#in_locked_and_timed_satellite' do
it 'should make use of a lockfile' do
repo = project.satellite.repo
called = false
#set assumptions
File.rm(project.satellite.lock_file) unless !File.exists? project.satellite.lock_file
File.exists?(project.satellite.lock_file).should be_false
satellite_action = Gitlab::Satellite::Action.new(user, project)
satellite_action.send(:in_locked_and_timed_satellite) do |sat_repo|
repo.should == sat_repo
(File.exists? project.satellite.lock_file).should be_true
called = true
end
called.should be_true
end
it 'should be able to use the satellite after locking' do
pending "can't test this, doesn't seem to be a way to the the flock status on a file, throwing piles of processes at it seems lousy too"
repo = project.satellite.repo
first_call = false
(File.exists? project.satellite.lock_file).should be_false
test_file = ->(called) {
File.exists?(project.satellite.lock_file).should be_true
called.should be_true
File.readlines.should == "some test code"
File.truncate(project.satellite.lock, 0)
File.readlines.should == ""
}
write_file = ->(called, checker) {
if (File.exists?(project.satellite.lock_file))
file = File.open(project.satellite.lock, '+w')
file.write("some test code")
file.close
checker.call(called)
end
}
satellite_action = Gitlab::Satellite::Action.new(user, project)
satellite_action.send(:in_locked_and_timed_satellite) do |sat_repo|
write_file.call(first_call, test_file)
first_call = true
repo.should == sat_repo
(File.exists? project.satellite.lock_file).should be_true
end
first_call.should be_true
puts File.stat(project.satellite.lock_file).inspect
second_call = false
satellite_action.send(:in_locked_and_timed_satellite) do |sat_repo|
write_file.call(second_call, test_file)
second_call = true
repo.should == sat_repo
(File.exists? project.satellite.lock_file).should be_true
end
second_call.should be_true
(File.exists? project.satellite.lock_file).should be_true
end
end
end
require 'spec_helper'
describe 'Gitlab::Satellite::MergeAction' do
before(:each) do
# TestEnv.init(mailer: false, init_repos: true, repos: true)
@master = ['master', 'bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a']
@one_after_stable = ['stable', '6ea87c47f0f8a24ae031c3fff17bc913889ecd00'] #this commit sha is one after stable
@wiki_branch = ['wiki', '635d3e09b72232b6e92a38de6cc184147e5bcb41'] #this is the commit sha where the wiki branch goes off from master
@conflicting_metior = ['metior', '313d96e42b313a0af5ab50fa233bf43e27118b3f'] #this branch conflicts with the wiki branch
#these commits are quite close together, itended to make string diffs/format patches small
@close_commit1 = ['2_3_notes_fix', '8470d70da67355c9c009e4401746b1d5410af2e3']
@close_commit2 = ['scss_refactoring', 'f0f14c8eaba69ebddd766498a9d0b0e79becd633']
end
let(:project) { create(:project_with_code) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:merge_request_fork) { create(:merge_request) }
describe '#commits_between' do
context 'on fork' do
it 'should get proper commits between' do
merge_request_fork.target_branch = @one_after_stable[0]
merge_request_fork.source_branch = @master[0]
commits = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).commits_between
commits.first.id.should == @one_after_stable[1]
commits.last.id.should == @master[1]
merge_request_fork.target_branch = @wiki_branch[0]
merge_request_fork.source_branch = @master[0]
commits = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).commits_between
commits.first.id.should == @wiki_branch[1]
commits.last.id.should == @master[1]
end
end
context 'between branches' do
it 'should get proper commits between' do
merge_request.target_branch = @one_after_stable[0]
merge_request.source_branch = @master[0]
commits = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).commits_between
commits.first.id.should == @one_after_stable[1]
commits.last.id.should == @master[1]
merge_request.target_branch = @wiki_branch[0]
merge_request.source_branch = @master[0]
commits = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).commits_between
commits.first.id.should == @wiki_branch[1]
commits.last.id.should == @master[1]
end
end
end
describe '#format_patch' do
context 'on fork' do
it 'should build a format patch' do
merge_request_fork.target_branch = @close_commit1[0]
merge_request_fork.source_branch = @close_commit2[0]
patch = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).format_patch
(patch.include? "From #{@close_commit2[1]}").should be_true
(patch.include? "From #{@close_commit1[1]}").should be_true
end
end
context 'between branches' do
it 'should build a format patch' do
merge_request.target_branch = @close_commit1[0]
merge_request.source_branch = @close_commit2[0]
patch = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).format_patch
(patch.include? "From #{@close_commit2[1]}").should be_true
(patch.include? "From #{@close_commit1[1]}").should be_true
end
end
end
describe '#diffs_between_satellite tested against diff_in_satellite' do
context 'on fork' do
it 'should get proper diffs' do
merge_request_fork.target_branch = @close_commit1[0]
merge_request_fork.source_branch = @master[0]
diffs = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).diffs_between_satellite
merge_request_fork.target_branch = @close_commit1[0]
merge_request_fork.source_branch = @master[0]
diff = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request_fork).diffs_between_satellite
diffs.each {|a_diff| (diff.include? a_diff.diff).should be_true}
end
end
context 'between branches' do
it 'should get proper diffs' do
merge_request.target_branch = @close_commit1[0]
merge_request.source_branch = @wiki_branch[0]
diffs = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).diffs_between_satellite
merge_request.target_branch = @close_commit1[0]
merge_request.source_branch = @master[0]
diff = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).diffs_between_satellite
diffs.each {|a_diff| (diff.include? a_diff.diff).should be_true}
end
end
end
describe '#can_be_merged?' do
context 'on fork' do
it 'return true or false depending on if something is mergable' do
merge_request_fork.target_branch = @one_after_stable[0]
merge_request_fork.source_branch = @master[0]
Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).can_be_merged?.should be_true
merge_request_fork.target_branch = @conflicting_metior[0]
merge_request_fork.source_branch = @wiki_branch[0]
Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).can_be_merged?.should be_false
end
end
context 'between branches' do
it 'return true or false depending on if something is mergable' do
merge_request.target_branch = @one_after_stable[0]
merge_request.source_branch = @master[0]
Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).can_be_merged?.should be_true
merge_request.target_branch = @conflicting_metior[0]
merge_request.source_branch = @wiki_branch[0]
Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).can_be_merged?.should be_false
end
end
end
end
\ No newline at end of file
Loading
Loading
@@ -167,7 +167,7 @@ describe Notify do
end
 
context 'for merge requests' do
let(:merge_request) { create(:merge_request, assignee: assignee, project: project) }
let(:merge_request) { create(:merge_request, assignee: assignee, source_project: project, target_project: project) }
 
describe 'that are new' do
subject { Notify.new_merge_request_email(merge_request.assignee_id, merge_request.id) }
Loading
Loading
@@ -311,7 +311,7 @@ describe Notify do
end
 
describe 'on a merge request' do
let(:merge_request) { create(:merge_request, project: project) }
let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
let(:note_on_merge_request_path) { project_merge_request_path(project, merge_request, anchor: "note_#{note.id}") }
before(:each) { note.stub(:noteable).and_return(merge_request) }
 
Loading
Loading
Loading
Loading
@@ -3,7 +3,6 @@ require 'spec_helper'
describe Commit do
let(:commit) { create(:project_with_code).repository.commit }
 
describe '#title' do
it "returns no_commit_message when safe_message is blank" do
commit.stub(:safe_message).and_return('')
Loading
Loading
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