Commit ac4a09e9 authored by Sebastian Ziebell's avatar Sebastian Ziebell

Merge branch 'master' into fixes/api

parents 9ee6c58a 135418dc
language: ruby language: ruby
env: env:
- DB=postgresql
- DB=mysql - DB=mysql
before_install: before_install:
- sudo apt-get install libicu-dev -y - sudo apt-get install libicu-dev -y
......
v 5.0.0 v 5.0.0
- Replaced gitolite with gitlab-shell - Replaced gitolite with gitlab-shell
- Removed gitolite-related libraries
- State machine added
- Setup gitlab as git user
- Internal API
- Show team tab for empty projects
- Import repository feature
- Updated rails
- Use lambda for scopes
- Redesign admin area -> users
- Redesign admin area -> user
- Secure link to file attachments
- Add validations for Group and Team names
- Restyle team page for project
- Update capybara, rspec-rails, poltergeist to recent versions
v 4.2.0 v 4.2.0
- Teams - Teams
- User show page. Via /u/username - User show page. Via /u/username
- Show help contents on pages for better navigation - Show help contents on pages for better navigation
- Async gitolite calls
- added satellites logs
- can_create_group, can_create_team booleans for User
- Process web hooks async
- GFM: Fix images escaped inside links
- Network graph improved
- Switchable branches for network graph
- API: Groups
- Fixed project download
v 4.1.0 v 4.1.0
- Optional Sign-Up - Optional Sign-Up
......
...@@ -22,7 +22,7 @@ gem 'omniauth-twitter' ...@@ -22,7 +22,7 @@ gem 'omniauth-twitter'
gem 'omniauth-github' gem 'omniauth-github'
# GITLAB patched libs # GITLAB patched libs
gem "grit", git: "https://github.com/gitlabhq/grit.git", ref: '7f35cb98ff17d534a07e3ce6ec3d580f67402837' gem "grit", git: "https://github.com/gitlabhq/grit.git", ref: '9e98418ce2d654485b967003726aa2706a10060b'
gem 'grack', git: "https://github.com/gitlabhq/grack.git", ref: 'ba46f3b0845c6a09d488ae6abdce6ede37e227e8' gem 'grack', git: "https://github.com/gitlabhq/grack.git", ref: 'ba46f3b0845c6a09d488ae6abdce6ede37e227e8'
gem 'grit_ext', git: "https://github.com/gitlabhq/grit_ext.git", ref: '8e6afc2da821354774aa4d1ee8a1aa2082f84a3e' gem 'grit_ext', git: "https://github.com/gitlabhq/grit_ext.git", ref: '8e6afc2da821354774aa4d1ee8a1aa2082f84a3e'
...@@ -81,8 +81,8 @@ gem "draper", "~> 0.18.0" ...@@ -81,8 +81,8 @@ gem "draper", "~> 0.18.0"
# Background jobs # Background jobs
gem 'slim' gem 'slim'
gem 'sinatra', :require => nil gem 'sinatra', require: nil
gem 'sidekiq', '2.6.4' gem 'sidekiq', '2.7.3'
# HTTP requests # HTTP requests
gem "httparty" gem "httparty"
...@@ -134,12 +134,12 @@ end ...@@ -134,12 +134,12 @@ end
group :development, :test do group :development, :test do
gem 'rails-dev-tweaks' gem 'rails-dev-tweaks'
gem 'spinach-rails' gem 'spinach-rails', '0.2.0'
gem "rspec-rails" gem "rspec-rails", '2.12.2'
gem "capybara" gem "capybara", '2.0.2'
gem "pry" gem "pry"
gem "awesome_print" gem "awesome_print"
gem "database_cleaner", ref: "f89c34300e114be99532f14c115b2799a3380ac6", git: "https://github.com/bmabey/database_cleaner.git" gem "database_cleaner", ref: "9f898fc50d87a5d51760f9dcf374bf5ffda21baf", git: "https://github.com/bmabey/database_cleaner.git"
gem "launchy" gem "launchy"
gem 'factory_girl_rails' gem 'factory_girl_rails'
...@@ -153,7 +153,7 @@ group :development, :test do ...@@ -153,7 +153,7 @@ group :development, :test do
gem 'rb-inotify', require: linux_only('rb-inotify') gem 'rb-inotify', require: linux_only('rb-inotify')
# PhantomJS driver for Capybara # PhantomJS driver for Capybara
gem 'poltergeist', git: 'https://github.com/jonleighton/poltergeist.git', ref: '5c2e092001074a8cf09f332d3714e9ba150bc8ca' gem 'poltergeist', '1.1.0'
end end
group :test do group :test do
......
GIT GIT
remote: https://github.com/bmabey/database_cleaner.git remote: https://github.com/bmabey/database_cleaner.git
revision: f89c34300e114be99532f14c115b2799a3380ac6 revision: 9f898fc50d87a5d51760f9dcf374bf5ffda21baf
ref: f89c34300e114be99532f14c115b2799a3380ac6 ref: 9f898fc50d87a5d51760f9dcf374bf5ffda21baf
specs: specs:
database_cleaner (0.9.1) database_cleaner (0.9.1)
...@@ -23,8 +23,8 @@ GIT ...@@ -23,8 +23,8 @@ GIT
GIT GIT
remote: https://github.com/gitlabhq/grit.git remote: https://github.com/gitlabhq/grit.git
revision: 7f35cb98ff17d534a07e3ce6ec3d580f67402837 revision: 9e98418ce2d654485b967003726aa2706a10060b
ref: 7f35cb98ff17d534a07e3ce6ec3d580f67402837 ref: 9e98418ce2d654485b967003726aa2706a10060b
specs: specs:
grit (2.5.0) grit (2.5.0)
diff-lcs (~> 1.1) diff-lcs (~> 1.1)
...@@ -54,18 +54,6 @@ GIT ...@@ -54,18 +54,6 @@ GIT
specs: specs:
raphael-rails (2.1.0) raphael-rails (2.1.0)
GIT
remote: https://github.com/jonleighton/poltergeist.git
revision: 5c2e092001074a8cf09f332d3714e9ba150bc8ca
ref: 5c2e092001074a8cf09f332d3714e9ba150bc8ca
specs:
poltergeist (1.0.2)
capybara (~> 1.1)
childprocess (~> 0.3)
faye-websocket (~> 0.4, >= 0.4.4)
http_parser.rb (~> 0.5.3)
multi_json (~> 1.0)
GEM GEM
remote: http://rubygems.org/ remote: http://rubygems.org/
specs: specs:
...@@ -110,13 +98,13 @@ GEM ...@@ -110,13 +98,13 @@ GEM
bootstrap-sass (2.2.1.1) bootstrap-sass (2.2.1.1)
sass (~> 3.2) sass (~> 3.2)
builder (3.0.4) builder (3.0.4)
capybara (1.1.3) capybara (2.0.2)
mime-types (>= 1.16) mime-types (>= 1.16)
nokogiri (>= 1.3.3) nokogiri (>= 1.3.3)
rack (>= 1.0.0) rack (>= 1.0.0)
rack-test (>= 0.5.4) rack-test (>= 0.5.4)
selenium-webdriver (~> 2.0) selenium-webdriver (~> 2.0)
xpath (~> 0.1.4) xpath (~> 1.0.0)
carrierwave (0.7.1) carrierwave (0.7.1)
activemodel (>= 3.2.0) activemodel (>= 3.2.0)
activesupport (>= 3.2.0) activesupport (>= 3.2.0)
...@@ -124,8 +112,8 @@ GEM ...@@ -124,8 +112,8 @@ GEM
facter (>= 1.6.12) facter (>= 1.6.12)
timers (>= 1.0.0) timers (>= 1.0.0)
charlock_holmes (0.6.9) charlock_holmes (0.6.9)
childprocess (0.3.6) childprocess (0.3.8)
ffi (~> 1.0, >= 1.0.6) ffi (~> 1.0, >= 1.0.11)
chosen-rails (0.9.8) chosen-rails (0.9.8)
railties (~> 3.0) railties (~> 3.0)
thor (~> 0.14) thor (~> 0.14)
...@@ -169,10 +157,10 @@ GEM ...@@ -169,10 +157,10 @@ GEM
railties (>= 3.0.0) railties (>= 3.0.0)
faraday (0.8.4) faraday (0.8.4)
multipart-post (~> 1.1) multipart-post (~> 1.1)
faye-websocket (0.4.6) faye-websocket (0.4.7)
eventmachine (>= 0.12.0) eventmachine (>= 0.12.0)
ffaker (1.15.0) ffaker (1.15.0)
ffi (1.1.5) ffi (1.4.0)
font-awesome-sass-rails (3.0.0.1) font-awesome-sass-rails (3.0.0.1)
railties (>= 3.1.1) railties (>= 3.1.1)
sass-rails (>= 3.1.1) sass-rails (>= 3.1.1)
...@@ -249,8 +237,6 @@ GEM ...@@ -249,8 +237,6 @@ GEM
letter_opener (1.0.0) letter_opener (1.0.0)
launchy (>= 2.0.4) launchy (>= 2.0.4)
libv8 (3.3.10.4) libv8 (3.3.10.4)
libwebsocket (0.1.6)
websocket
listen (0.5.3) listen (0.5.3)
lumberjack (1.0.2) lumberjack (1.0.2)
mail (2.4.4) mail (2.4.4)
...@@ -261,12 +247,12 @@ GEM ...@@ -261,12 +247,12 @@ GEM
mime-types (1.21) mime-types (1.21)
modernizr (2.6.2) modernizr (2.6.2)
sprockets (~> 2.0) sprockets (~> 2.0)
multi_json (1.5.1) multi_json (1.6.1)
multi_xml (0.5.1) multi_xml (0.5.1)
multipart-post (1.1.5) multipart-post (1.1.5)
mysql2 (0.3.11) mysql2 (0.3.11)
net-ldap (0.2.2) net-ldap (0.2.2)
nokogiri (1.5.5) nokogiri (1.5.6)
oauth (0.4.7) oauth (0.4.7)
oauth2 (0.8.0) oauth2 (0.8.0)
faraday (~> 0.8) faraday (~> 0.8)
...@@ -294,6 +280,10 @@ GEM ...@@ -294,6 +280,10 @@ GEM
omniauth-oauth (~> 1.0) omniauth-oauth (~> 1.0)
orm_adapter (0.4.0) orm_adapter (0.4.0)
pg (0.14.1) pg (0.14.1)
poltergeist (1.1.0)
capybara (~> 2.0, >= 2.0.1)
faye-websocket (~> 0.4, >= 0.4.4)
http_parser.rb (~> 0.5.3)
polyglot (0.3.3) polyglot (0.3.3)
posix-spawn (0.3.6) posix-spawn (0.3.6)
progressbar (0.12.0) progressbar (0.12.0)
...@@ -364,7 +354,7 @@ GEM ...@@ -364,7 +354,7 @@ GEM
rspec-expectations (2.12.0) rspec-expectations (2.12.0)
diff-lcs (~> 1.1.3) diff-lcs (~> 1.1.3)
rspec-mocks (2.12.0) rspec-mocks (2.12.0)
rspec-rails (2.12.0) rspec-rails (2.12.2)
actionpack (>= 3.0) actionpack (>= 3.0)
activesupport (>= 3.0) activesupport (>= 3.0)
railties (>= 3.0) railties (>= 3.0)
...@@ -384,16 +374,16 @@ GEM ...@@ -384,16 +374,16 @@ GEM
seed-fu (2.2.0) seed-fu (2.2.0)
activerecord (~> 3.1) activerecord (~> 3.1)
activesupport (~> 3.1) activesupport (~> 3.1)
selenium-webdriver (2.26.0) selenium-webdriver (2.30.0)
childprocess (>= 0.2.5) childprocess (>= 0.2.5)
libwebsocket (~> 0.1.3)
multi_json (~> 1.0) multi_json (~> 1.0)
rubyzip rubyzip
websocket (~> 1.0.4)
settingslogic (2.0.8) settingslogic (2.0.8)
sexp_processor (4.1.3) sexp_processor (4.1.3)
shoulda-matchers (1.3.0) shoulda-matchers (1.3.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
sidekiq (2.6.4) sidekiq (2.7.3)
celluloid (~> 0.12.0) celluloid (~> 0.12.0)
connection_pool (~> 1.0) connection_pool (~> 1.0)
multi_json (~> 1) multi_json (~> 1)
...@@ -412,11 +402,11 @@ GEM ...@@ -412,11 +402,11 @@ GEM
temple (~> 0.5.5) temple (~> 0.5.5)
tilt (~> 1.3.3) tilt (~> 1.3.3)
slop (3.3.3) slop (3.3.3)
spinach (0.5.2) spinach (0.7.0)
colorize colorize
gherkin-ruby (~> 0.2.0) gherkin-ruby (~> 0.2.0)
spinach-rails (0.1.8) spinach-rails (0.2.0)
capybara (~> 1) capybara (~> 2.0.0)
railties (>= 3) railties (>= 3)
spinach (>= 0.4) spinach (>= 0.4)
sprockets (2.2.2) sprockets (2.2.2)
...@@ -436,7 +426,7 @@ GEM ...@@ -436,7 +426,7 @@ GEM
rack (>= 1.0.0) rack (>= 1.0.0)
thor (0.17.0) thor (0.17.0)
tilt (1.3.3) tilt (1.3.3)
timers (1.0.2) timers (1.1.0)
treetop (1.4.12) treetop (1.4.12)
polyglot polyglot
polyglot (>= 0.3.1) polyglot (>= 0.3.1)
...@@ -455,8 +445,8 @@ GEM ...@@ -455,8 +445,8 @@ GEM
webmock (1.9.0) webmock (1.9.0)
addressable (>= 2.2.7) addressable (>= 2.2.7)
crack (>= 0.1.7) crack (>= 0.1.7)
websocket (1.0.2) websocket (1.0.7)
xpath (0.1.4) xpath (1.0.0)
nokogiri (~> 1.3) nokogiri (~> 1.3)
yajl-ruby (1.1.0) yajl-ruby (1.1.0)
...@@ -470,7 +460,7 @@ DEPENDENCIES ...@@ -470,7 +460,7 @@ DEPENDENCIES
better_errors better_errors
binding_of_caller binding_of_caller
bootstrap-sass (= 2.2.1.1) bootstrap-sass (= 2.2.1.1)
capybara capybara (= 2.0.2)
carrierwave (~> 0.7.1) carrierwave (~> 0.7.1)
chosen-rails (= 0.9.8) chosen-rails (= 0.9.8)
coffee-rails (~> 3.2.2) coffee-rails (~> 3.2.2)
...@@ -512,7 +502,7 @@ DEPENDENCIES ...@@ -512,7 +502,7 @@ DEPENDENCIES
omniauth-google-oauth2 omniauth-google-oauth2
omniauth-twitter omniauth-twitter
pg pg
poltergeist! poltergeist (= 1.1.0)
pry pry
pygments.rb! pygments.rb!
quiet_assets (~> 1.0.1) quiet_assets (~> 1.0.1)
...@@ -524,18 +514,18 @@ DEPENDENCIES ...@@ -524,18 +514,18 @@ DEPENDENCIES
rb-fsevent rb-fsevent
rb-inotify rb-inotify
redcarpet (~> 2.2.2) redcarpet (~> 2.2.2)
rspec-rails rspec-rails (= 2.12.2)
sass-rails (~> 3.2.5) sass-rails (~> 3.2.5)
sdoc sdoc
seed-fu seed-fu
settingslogic settingslogic
shoulda-matchers (= 1.3.0) shoulda-matchers (= 1.3.0)
sidekiq (= 2.6.4) sidekiq (= 2.7.3)
simplecov simplecov
sinatra sinatra
six six
slim slim
spinach-rails spinach-rails (= 0.2.0)
stamp stamp
state_machine state_machine
test_after_commit test_after_commit
......
...@@ -31,7 +31,7 @@ class MergeRequest ...@@ -31,7 +31,7 @@ class MergeRequest
if this.$('.automerge_widget').length and @opts.check_enable if this.$('.automerge_widget').length and @opts.check_enable
$.get @opts.url_to_automerge_check, (data) => $.get @opts.url_to_automerge_check, (data) =>
this.showState( data.state ) this.showState( data.merge_status )
, 'json' , 'json'
if @opts.ci_enable if @opts.ci_enable
......
...@@ -24,6 +24,14 @@ ...@@ -24,6 +24,14 @@
background-image: -o-linear-gradient($from, $to); background-image: -o-linear-gradient($from, $to);
} }
@mixin transition($transition) {
-webkit-transition: $transition;
-moz-transition: $transition;
-ms-transition: $transition;
-o-transition: $transition;
transition: $transition;
}
/** /**
* Prefilled mixins * Prefilled mixins
* Mixins with fixed values * Mixins with fixed values
......
...@@ -90,6 +90,7 @@ header { ...@@ -90,6 +90,7 @@ header {
@include border-radius(3px); @include border-radius(3px);
border: 1px solid #c6c6c6; border: 1px solid #c6c6c6;
box-shadow: none; box-shadow: none;
@include transition(all 0.15s ease-in 0s);
&:focus { &:focus {
@extend .span3; @extend .span3;
} }
......
...@@ -14,7 +14,7 @@ class MergeRequestsLoadContext < BaseContext ...@@ -14,7 +14,7 @@ class MergeRequestsLoadContext < BaseContext
end end
merge_requests = merge_requests.page(params[:page]).per(20) merge_requests = merge_requests.page(params[:page]).per(20)
merge_requests = merge_requests.includes(:author, :project).order("state, created_at desc") merge_requests = merge_requests.includes(:author, :project).order("created_at desc")
# Filter by specific assignee_id (or lack thereof)? # Filter by specific assignee_id (or lack thereof)?
if params[:assignee_id].present? if params[:assignee_id].present?
......
class TestHookContext < BaseContext class TestHookContext < BaseContext
def execute def execute
hook = project.hooks.find(params[:id]) hook = project.hooks.find(params[:id])
commits = project.repository.commits(project.default_branch, nil, 3) data = GitPushService.new.sample_data(project, current_user)
data = project.post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{project.default_branch}", current_user)
hook.execute(data) hook.execute(data)
end end
end end
require 'gitlab/satellite/satellite'
class MergeRequestsController < ProjectResourceController class MergeRequestsController < ProjectResourceController
before_filter :module_enabled before_filter :module_enabled
before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status] before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status]
...@@ -73,7 +75,7 @@ class MergeRequestsController < ProjectResourceController ...@@ -73,7 +75,7 @@ class MergeRequestsController < ProjectResourceController
if @merge_request.unchecked? if @merge_request.unchecked?
@merge_request.check_if_can_be_merged @merge_request.check_if_can_be_merged
end end
render json: {merge_status: @merge_request.human_merge_status} render json: {merge_status: @merge_request.merge_status_name}
rescue Gitlab::SatelliteNotExistError rescue Gitlab::SatelliteNotExistError
render json: {merge_status: :no_satellite} render json: {merge_status: :no_satellite}
end end
......
class ProfilesController < ApplicationController class ProfilesController < ApplicationController
include ActionView::Helpers::SanitizeHelper
before_filter :user before_filter :user
layout 'profile' layout 'profile'
...@@ -12,7 +14,7 @@ class ProfilesController < ApplicationController ...@@ -12,7 +14,7 @@ class ProfilesController < ApplicationController
end end
def update def update
if @user.update_attributes(params[:user]) if @user.update_attributes(user_attributes)
flash[:notice] = "Profile was successfully updated" flash[:notice] = "Profile was successfully updated"
else else
flash[:alert] = "Failed to update profile" flash[:alert] = "Failed to update profile"
...@@ -65,4 +67,17 @@ class ProfilesController < ApplicationController ...@@ -65,4 +67,17 @@ class ProfilesController < ApplicationController
def user def user
@user = current_user @user = current_user
end end
def user_attributes
user_attributes = params[:user]
# Sanitize user input because we dont have strict
# validation for this fields
%w(name skype linkedin twitter bio).each do |attr|
value = user_attributes[attr]
user_attributes[attr] = sanitize(value) if value.present?
end
user_attributes
end
end end
...@@ -72,7 +72,7 @@ module ApplicationHelper ...@@ -72,7 +72,7 @@ module ApplicationHelper
end end
def search_autocomplete_source def search_autocomplete_source
projects = current_user.authorized_projects.map { |p| { label: "project: #{p.name_with_namespace}", url: project_path(p) } } projects = current_user.authorized_projects.map { |p| { label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) } }
groups = current_user.authorized_groups.map { |group| { label: "group: #{simple_sanitize(group.name)}", url: group_path(group) } } groups = current_user.authorized_groups.map { |group| { label: "group: #{simple_sanitize(group.name)}", url: group_path(group) } }
teams = current_user.authorized_teams.map { |team| { label: "team: #{simple_sanitize(team.name)}", url: team_path(team) } } teams = current_user.authorized_teams.map { |team| { label: "team: #{simple_sanitize(team.name)}", url: team_path(team) } }
...@@ -98,15 +98,15 @@ module ApplicationHelper ...@@ -98,15 +98,15 @@ module ApplicationHelper
project_nav = [] project_nav = []
if @project && @project.repository && @project.repository.root_ref if @project && @project.repository && @project.repository.root_ref
project_nav = [ project_nav = [
{ label: "#{@project.name_with_namespace} - Issues", url: project_issues_path(@project) }, { label: "#{simple_sanitize(@project.name_with_namespace)} - Issues", url: project_issues_path(@project) },
{ label: "#{@project.name_with_namespace} - Commits", url: project_commits_path(@project, @ref || @project.repository.root_ref) }, { label: "#{simple_sanitize(@project.name_with_namespace)} - Commits", url: project_commits_path(@project, @ref || @project.repository.root_ref) },
{ label: "#{@project.name_with_namespace} - Merge Requests", url: project_merge_requests_path(@project) }, { label: "#{simple_sanitize(@project.name_with_namespace)} - Merge Requests", url: project_merge_requests_path(@project) },
{ label: "#{@project.name_with_namespace} - Milestones", url: project_milestones_path(@project) }, { label: "#{simple_sanitize(@project.name_with_namespace)} - Milestones", url: project_milestones_path(@project) },
{ label: "#{@project.name_with_namespace} - Snippets", url: project_snippets_path(@project) }, { label: "#{simple_sanitize(@project.name_with_namespace)} - Snippets", url: project_snippets_path(@project) },
{ label: "#{@project.name_with_namespace} - Team", url: project_team_index_path(@project) }, { label: "#{simple_sanitize(@project.name_with_namespace)} - Team", url: project_team_index_path(@project) },
{ label: "#{@project.name_with_namespace} - Tree", url: project_tree_path(@project, @ref || @project.repository.root_ref) }, { label: "#{simple_sanitize(@project.name_with_namespace)} - Tree", url: project_tree_path(@project, @ref || @project.repository.root_ref) },
{ label: "#{@project.name_with_namespace} - Wall", url: wall_project_path(@project) }, { label: "#{simple_sanitize(@project.name_with_namespace)} - Wall", url: wall_project_path(@project) },
{ label: "#{@project.name_with_namespace} - Wiki", url: project_wikis_path(@project) }, { label: "#{simple_sanitize(@project.name_with_namespace)} - Wiki", url: project_wikis_path(@project) },
] ]
end end
......
...@@ -57,6 +57,31 @@ module CommitsHelper ...@@ -57,6 +57,31 @@ module CommitsHelper
end end
end end
def each_diff_line_near(diff, index, expected_line_code)
max_number_of_lines = 16
prev_match_line = nil
prev_lines = []
each_diff_line(diff, index) do |full_line, type, line_code, line_new, line_old|
line = [full_line, type, line_code, line_new, line_old]
if line_code != expected_line_code
if type == "match"
prev_lines.clear
prev_match_line = line
else
prev_lines.push(line)
prev_lines.shift if prev_lines.length >= max_number_of_lines
end
else
yield(prev_match_line) if !prev_match_line.nil?
prev_lines.each { |ln| yield(ln) }
yield(line)
break
end
end
end
def image_diff_class(diff) def image_diff_class(diff)
if diff.deleted_file if diff.deleted_file
"deleted" "deleted"
......
...@@ -21,7 +21,6 @@ class Key < ActiveRecord::Base ...@@ -21,7 +21,6 @@ class Key < ActiveRecord::Base
attr_accessible :key, :title attr_accessible :key, :title
before_validation :strip_white_space before_validation :strip_white_space
before_save :set_identifier
validates :title, presence: true, length: { within: 0..255 } validates :title, presence: true, length: { within: 0..255 }
validates :key, presence: true, length: { within: 0..5000 }, format: { :with => /ssh-.{3} / }, uniqueness: true validates :key, presence: true, length: { within: 0..5000 }, format: { :with => /ssh-.{3} / }, uniqueness: true
...@@ -48,14 +47,6 @@ class Key < ActiveRecord::Base ...@@ -48,14 +47,6 @@ class Key < ActiveRecord::Base
errors.add(:key, "can't be fingerprinted") if $?.exitstatus != 0 errors.add(:key, "can't be fingerprinted") if $?.exitstatus != 0
end end
def set_identifier
if is_deploy_key
self.identifier = "deploy_#{Digest::MD5.hexdigest(key)}"
else
self.identifier = "#{user.identifier}_#{Time.now.to_i}"
end
end
def is_deploy_key def is_deploy_key
!!project_id !!project_id
end end
......
...@@ -24,6 +24,8 @@ require Rails.root.join("lib/static_model") ...@@ -24,6 +24,8 @@ require Rails.root.join("lib/static_model")
class MergeRequest < ActiveRecord::Base class MergeRequest < ActiveRecord::Base
include Issuable include Issuable
BROKEN_DIFF = "--broken-diff"
attr_accessible :title, :assignee_id, :target_branch, :source_branch, :milestone_id, attr_accessible :title, :assignee_id, :target_branch, :source_branch, :milestone_id,
:author_id_of_changes, :state_event :author_id_of_changes, :state_event
...@@ -51,11 +53,25 @@ class MergeRequest < ActiveRecord::Base ...@@ -51,11 +53,25 @@ class MergeRequest < ActiveRecord::Base
state :merged state :merged
end end
BROKEN_DIFF = "--broken-diff" state_machine :merge_status, initial: :unchecked do
event :mark_as_unchecked do
transition [:can_be_merged, :cannot_be_merged] => :unchecked
end
event :mark_as_mergeable do
transition unchecked: :can_be_merged
end
event :mark_as_unmergeable do
transition unchecked: :cannot_be_merged
end
UNCHECKED = 1 state :unchecked
CAN_BE_MERGED = 2
CANNOT_BE_MERGED = 3 state :can_be_merged
state :cannot_be_merged
end
serialize :st_commits serialize :st_commits
serialize :st_diffs serialize :st_diffs
...@@ -65,33 +81,13 @@ class MergeRequest < ActiveRecord::Base ...@@ -65,33 +81,13 @@ class MergeRequest < ActiveRecord::Base
validate :validate_branches validate :validate_branches
scope :merged, -> { with_state(:merged) } scope :merged, -> { with_state(:merged) }
scope :by_branch, ->(branch_name) { where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name) }
scope :cared, ->(user) { where('assignee_id = :user OR author_id = :user', user: user.id) }
scope :by_milestone, ->(milestone) { where(milestone_id: milestone) }
class << self # Closed scope for merge request should return
def find_all_by_branch(branch_name) # both merged and closed mr's
where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name) scope :closed, -> { with_states(:closed, :merged) }
end
def cared(user)
where('assignee_id = :user OR author_id = :user', user: user.id)
end
def find_all_by_branch(branch_name)
where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name)
end
def find_all_by_milestone(milestone)
where("milestone_id = :milestone_id", milestone_id: milestone)
end
end
def human_merge_status
merge_statuses = {
CAN_BE_MERGED => "can_be_merged",
CANNOT_BE_MERGED => "cannot_be_merged",
UNCHECKED => "unchecked"
}
merge_statuses[self.merge_status]
end
def validate_branches def validate_branches
if target_branch == source_branch if target_branch == source_branch
...@@ -104,26 +100,12 @@ class MergeRequest < ActiveRecord::Base ...@@ -104,26 +100,12 @@ class MergeRequest < ActiveRecord::Base
self.reloaded_diffs self.reloaded_diffs
end end
def unchecked?
merge_status == UNCHECKED
end
def mark_as_unchecked
self.merge_status = UNCHECKED
self.save
end
def can_be_merged?
merge_status == CAN_BE_MERGED
end
def check_if_can_be_merged def check_if_can_be_merged
self.merge_status = if Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged? if Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged?
CAN_BE_MERGED mark_as_mergeable
else else
CANNOT_BE_MERGED mark_as_unmergeable
end end
self.save
end end
def diffs def diffs
...@@ -178,11 +160,6 @@ class MergeRequest < ActiveRecord::Base ...@@ -178,11 +160,6 @@ class MergeRequest < ActiveRecord::Base
commits.any? && opened? commits.any? && opened?
end end
def mark_as_unmergable
self.merge_status = CANNOT_BE_MERGED
self.save
end
def reloaded_commits def reloaded_commits
if opened? && unmerged_commits.any? if opened? && unmerged_commits.any?
self.st_commits = unmerged_commits self.st_commits = unmerged_commits
...@@ -217,7 +194,7 @@ class MergeRequest < ActiveRecord::Base ...@@ -217,7 +194,7 @@ class MergeRequest < ActiveRecord::Base
true true
end end
rescue rescue
self.mark_as_unmergable mark_as_unmergeable
false false
end end
......
...@@ -247,32 +247,6 @@ class Project < ActiveRecord::Base ...@@ -247,32 +247,6 @@ class Project < ActiveRecord::Base
users_projects.find_by_user_id(user_id) users_projects.find_by_user_id(user_id)
end end
def transfer(new_namespace)
Project.transaction do
old_namespace = namespace
self.namespace = new_namespace
old_dir = old_namespace.try(:path) || ''
new_dir = new_namespace.try(:path) || ''
old_repo = if old_dir.present?
File.join(old_dir, self.path)
else
self.path
end
if Project.where(path: self.path, namespace_id: new_namespace.try(:id)).present?
raise TransferError.new("Project with same path in target namespace already exists")
end
Gitlab::ProjectMover.new(self, old_dir, new_dir).execute
save!
end
rescue Gitlab::ProjectMover::ProjectMoveError => ex
raise Project::TransferError.new(ex.message)
end
def name_with_namespace def name_with_namespace
@name_with_namespace ||= begin @name_with_namespace ||= begin
if namespace if namespace
...@@ -295,51 +269,8 @@ class Project < ActiveRecord::Base ...@@ -295,51 +269,8 @@ class Project < ActiveRecord::Base
end end
end end
# This method will be called after each post receive and only if the provided def transfer(new_namespace)
# user is present in GitLab. ProjectTransferService.new.transfer(self, new_namespace)
#
# All callbacks for post receive should be placed here.
def trigger_post_receive(oldrev, newrev, ref, user)
data = post_receive_data(oldrev, newrev, ref, user)
# Create satellite
self.satellite.create unless self.satellite.exists?
# Create push event
self.observe_push(data)
if push_to_branch? ref, oldrev
# Close merged MR
self.update_merge_requests(oldrev, newrev, ref, user)
# Execute web hooks
self.execute_hooks(data.dup)
# Execute project services
self.execute_services(data.dup)
end
# Discover the default branch, but only if it hasn't already been set to
# something else
if repository && default_branch.nil?
update_attributes(default_branch: self.repository.discover_default_branch)
end
end
def push_to_branch? ref, oldrev
ref_parts = ref.split('/')
# Return if this is not a push to a branch (e.g. new commits)
!(ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000")
end
def observe_push(data)
Event.create(
project: self,
action: Event::PUSHED,
data: data,
author_id: data[:user_id]
)
end end
def execute_hooks(data) def execute_hooks(data)
...@@ -354,68 +285,12 @@ class Project < ActiveRecord::Base ...@@ -354,68 +285,12 @@ class Project < ActiveRecord::Base
end end
end end
# Produce a hash of post-receive data def discover_default_branch
# # Discover the default branch, but only if it hasn't already been set to
# data = { # something else
# before: String, if repository && default_branch.nil?
# after: String, update_attributes(default_branch: self.repository.discover_default_branch)
# ref: String, end
# user_id: String,
# user_name: String,
# repository: {
# name: String,
# url: String,
# description: String,
# homepage: String,
# },
# commits: Array,
# total_commits_count: Fixnum
# }
#
def post_receive_data(oldrev, newrev, ref, user)
push_commits = repository.commits_between(oldrev, newrev)
# Total commits count
push_commits_count = push_commits.size
# Get latest 20 commits ASC
push_commits_limited = push_commits.last(20)
# Hash to be passed as post_receive_data
data = {
before: oldrev,
after: newrev,
ref: ref,
user_id: user.id,
user_name: user.name,
repository: {
name: name,
url: url_to_repo,
description: description,
homepage: web_url,
},
commits: [],
total_commits_count: push_commits_count
}
# For perfomance purposes maximum 20 latest commits
# will be passed as post receive hook data.
#
push_commits_limited.each do |commit|
data[:commits] << {
id: commit.id,
message: commit.safe_message,
timestamp: commit.date.xmlschema,
url: "#{Gitlab.config.gitlab.url}/#{path_with_namespace}/commit/#{commit.id}",
author: {
name: commit.author_name,
email: commit.author_email
}
}
end
data
end end
def update_merge_requests(oldrev, newrev, ref, user) def update_merge_requests(oldrev, newrev, ref, user)
...@@ -424,7 +299,7 @@ class Project < ActiveRecord::Base ...@@ -424,7 +299,7 @@ class Project < ActiveRecord::Base
c_ids = self.repository.commits_between(oldrev, newrev).map(&:id) c_ids = self.repository.commits_between(oldrev, newrev).map(&:id)
# Update code for merge requests # Update code for merge requests
mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all mrs = self.merge_requests.opened.by_branch(branch_name).all
mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked } mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }
# Close merge requests # Close merge requests
...@@ -446,6 +321,10 @@ class Project < ActiveRecord::Base ...@@ -446,6 +321,10 @@ class Project < ActiveRecord::Base
!repository || repository.empty? !repository || repository.empty?
end end
def ensure_satellite_exists
self.satellite.create unless self.satellite.exists?
end
def satellite def satellite
@satellite ||= Gitlab::Satellite::Satellite.new(self) @satellite ||= Gitlab::Satellite::Satellite.new(self)
end end
......
...@@ -66,28 +66,6 @@ class ProjectTeam ...@@ -66,28 +66,6 @@ class ProjectTeam
members.masters.map(&:user) members.masters.map(&:user)
end end
def repository_readers
repository_members[UsersProject::REPORTER]
end
def repository_writers
repository_members[UsersProject::DEVELOPER]
end
def repository_masters
repository_members[UsersProject::MASTER]
end
def repository_members
keys = Hash.new {|h,k| h[k] = [] }
UsersProject.select("keys.identifier, project_access").
joins(user: :keys).where(project_id: project.id).
each {|row| keys[row.project_access] << [row.identifier] }
keys[UsersProject::REPORTER] += project.deploy_keys.pluck(:identifier)
keys
end
def import(source_project) def import(source_project)
target_project = project target_project = project
......
...@@ -12,13 +12,4 @@ ...@@ -12,13 +12,4 @@
# #
class SystemHook < WebHook class SystemHook < WebHook
def self.all_hooks_fire(data)
SystemHook.all.each do |sh|
sh.async_execute data
end
end
def async_execute(data)
Sidekiq::Client.enqueue(SystemHookWorker, id, data)
end
end end
...@@ -70,6 +70,7 @@ class User < ActiveRecord::Base ...@@ -70,6 +70,7 @@ class User < ActiveRecord::Base
has_many :team_projects, through: :user_team_project_relationships has_many :team_projects, through: :user_team_project_relationships
validates :name, presence: true validates :name, presence: true
validates :email, presence: true, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ }
validates :bio, length: { within: 0..255 } validates :bio, length: { within: 0..255 }
validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider} validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider}
validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0} validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0}
...@@ -215,17 +216,6 @@ class User < ActiveRecord::Base ...@@ -215,17 +216,6 @@ class User < ActiveRecord::Base
UsersProject.where(project_id: authorized_projects.map(&:id), user_id: self.id) UsersProject.where(project_id: authorized_projects.map(&:id), user_id: self.id)
end end
# Returns a string for use as a Gitolite user identifier
#
# Note that Gitolite 2.x requires the following pattern for users:
#
# ^@?[0-9a-zA-Z][0-9a-zA-Z._\@+-]*$
def identifier
# Replace non-word chars with underscores, then make sure it starts with
# valid chars
email.gsub(/\W/, '_').gsub(/\A([\W\_])+/, '')
end
def is_admin? def is_admin?
admin admin
end end
......
...@@ -28,10 +28,14 @@ class WebHook < ActiveRecord::Base ...@@ -28,10 +28,14 @@ class WebHook < ActiveRecord::Base
WebHook.post(url, body: data.to_json, headers: { "Content-Type" => "application/json" }) WebHook.post(url, body: data.to_json, headers: { "Content-Type" => "application/json" })
else else
post_url = url.gsub("#{parsed_url.userinfo}@", "") post_url = url.gsub("#{parsed_url.userinfo}@", "")
auth = {
username: URI.decode(parsed_url.user),
password: URI.decode(parsed_url.password),
}
WebHook.post(post_url, WebHook.post(post_url,
body: data.to_json, body: data.to_json,
headers: {"Content-Type" => "application/json"}, headers: {"Content-Type" => "application/json"},
basic_auth: {username: parsed_url.user, password: parsed_url.password}) basic_auth: auth)
end end
end end
......
class NoteObserver < ActiveRecord::Observer class NoteObserver < ActiveRecord::Observer
def after_create(note) def after_create(note)
send_notify_mails(note) send_notify_mails(note)
end end
......
...@@ -2,66 +2,10 @@ class SystemHookObserver < ActiveRecord::Observer ...@@ -2,66 +2,10 @@ class SystemHookObserver < ActiveRecord::Observer
observe :user, :project, :users_project observe :user, :project, :users_project
def after_create(model) def after_create(model)
if model.kind_of? Project SystemHooksService.execute_hooks_for(model, :create)
SystemHook.all_hooks_fire({
event_name: "project_create",
name: model.name,
path: model.path,
project_id: model.id,
owner_name: model.owner.name,
owner_email: model.owner.email,
created_at: model.created_at
})
elsif model.kind_of? User
SystemHook.all_hooks_fire({
event_name: "user_create",
name: model.name,
email: model.email,
created_at: model.created_at
})
elsif model.kind_of? UsersProject
SystemHook.all_hooks_fire({
event_name: "user_add_to_team",
project_name: model.project.name,
project_path: model.project.path,
project_id: model.project_id,
user_name: model.user.name,
user_email: model.user.email,
project_access: model.repo_access_human,
created_at: model.created_at
})
end
end end
def after_destroy(model) def after_destroy(model)
if model.kind_of? Project SystemHooksService.execute_hooks_for(model, :destroy)
SystemHook.all_hooks_fire({
event_name: "project_destroy",
name: model.name,
path: model.path,
project_id: model.id,
owner_name: model.owner.name,
owner_email: model.owner.email,
})
elsif model.kind_of? User
SystemHook.all_hooks_fire({
event_name: "user_destroy",
name: model.name,
email: model.email
})
elsif model.kind_of? UsersProject
SystemHook.all_hooks_fire({
event_name: "user_remove_from_team",
project_name: model.project.name,
project_path: model.project.path,
project_id: model.project_id,
user_name: model.user.name,
user_email: model.user.email,
project_access: model.repo_access_human
})
end
end end
end end
class GitPushService
attr_accessor :project, :user, :push_data
# This method will be called after each git update
# and only if the provided user and project is present in GitLab.
#
# All callbacks for post receive action should be placed here.
#
# Now this method do next:
# 1. Ensure project satellite exists
# 2. Update merge requests
# 3. Execute project web hooks
# 4. Execute project services
# 5. Create Push Event
#
def execute(project, user, oldrev, newrev, ref)
@project, @user = project, user
# Collect data for this git push
@push_data = post_receive_data(oldrev, newrev, ref)
project.ensure_satellite_exists
project.discover_default_branch
if push_to_branch?(ref, oldrev)
project.update_merge_requests(oldrev, newrev, ref, @user)
project.execute_hooks(@push_data.dup)
project.execute_services(@push_data.dup)
end
create_push_event
end
# This method provide a sample data
# generated with post_receive_data method
# for given project
#
def sample_data(project, user)
@project, @user = project, user
commits = project.repository.commits(project.default_branch, nil, 3)
post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{project.default_branch}")
end
protected
def create_push_event
Event.create(
project: project,
action: Event::PUSHED,
data: push_data,
author_id: push_data[:user_id]
)
end
# Produce a hash of post-receive data
#
# data = {
# before: String,
# after: String,
# ref: String,
# user_id: String,
# user_name: String,
# repository: {
# name: String,
# url: String,
# description: String,
# homepage: String,
# },
# commits: Array,
# total_commits_count: Fixnum
# }
#
def post_receive_data(oldrev, newrev, ref)
push_commits = project.repository.commits_between(oldrev, newrev)
# Total commits count
push_commits_count = push_commits.size
# Get latest 20 commits ASC
push_commits_limited = push_commits.last(20)
# Hash to be passed as post_receive_data
data = {
before: oldrev,
after: newrev,
ref: ref,
user_id: user.id,
user_name: user.name,
repository: {
name: project.name,
url: project.url_to_repo,
description: project.description,
homepage: project.web_url,
},
commits: [],
total_commits_count: push_commits_count
}
# For perfomance purposes maximum 20 latest commits
# will be passed as post receive hook data.
#
push_commits_limited.each do |commit|
data[:commits] << {
id: commit.id,
message: commit.safe_message,
timestamp: commit.date.xmlschema,
url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/commit/#{commit.id}",
author: {
name: commit.author_name,
email: commit.author_email
}
}
end
data
end
def push_to_branch? ref, oldrev
ref_parts = ref.split('/')
# Return if this is not a push to a branch (e.g. new commits)
!(ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000")
end
end
# ProjectTransferService class
#
# Used for transfer project to another namespace
#
class ProjectTransferService
attr_accessor :project
def transfer(project, new_namespace)
Project.transaction do
old_namespace = project.namespace
project.namespace = new_namespace
old_dir = old_namespace.try(:path) || ''
new_dir = new_namespace.try(:path) || ''
old_repo = if old_dir.present?
File.join(old_dir, project.path)
else
project.path
end
if Project.where(path: project.path, namespace_id: new_namespace.try(:id)).present?
raise TransferError.new("Project with same path in target namespace already exists")
end
Gitlab::ProjectMover.new(project, old_dir, new_dir).execute
save!
end
rescue Gitlab::ProjectMover::ProjectMoveError => ex
raise Project::TransferError.new(ex.message)
end
end
class SystemHooksService
def self.execute_hooks_for(model, event)
execute_hooks(build_event_data(model, event))
end
private
def self.execute_hooks(data)
SystemHook.all.each do |sh|
async_execute_hook sh, data
end
end
def self.async_execute_hook(hook, data)
Sidekiq::Client.enqueue(SystemHookWorker, hook.id, data)
end
def self.build_event_data(model, event)
data = {
event_name: build_event_name(model, event),
created_at: model.created_at
}
case model
when Project
data.merge!({
name: model.name,
path: model.path,
project_id: model.id,
owner_name: model.owner.name,
owner_email: model.owner.email
})
when User
data.merge!({
name: model.name,
email: model.email
})
when UsersProject
data.merge!({
project_name: model.project.name,
project_path: model.project.path,
project_id: model.project_id,
user_name: model.user.name,
user_email: model.user.email,
project_access: model.repo_access_human
})
end
end
def self.build_event_name(model, event)
case model
when UsersProject
return "user_add_to_team" if event == :create
return "user_remove_from_team" if event == :destroy
else
"#{model.class.name.downcase}_#{event.to_s}"
end
end
end
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
= link_to_project project = link_to_project project
%ul.well-list.issues_table %ul.well-list.issues_table
- group[1].each do |issue| - group[1].each do |issue|
= render(partial: 'issues/show', locals: {issue: issue}) = render issue
%hr %hr
= paginate @issues, theme: "gitlab" = paginate @issues, theme: "gitlab"
- else - else
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
= link_to_project project = link_to_project project
%ul.well-list.issues_table %ul.well-list.issues_table
- group[1].each do |issue| - group[1].each do |issue|
= render(partial: 'issues/show', locals: {issue: issue}) = render issue
%hr %hr
= paginate @issues, theme: "gitlab" = paginate @issues, theme: "gitlab"
- else - else
......
- @issues.each do |issue| = render @issues
= render(partial: 'issues/show', locals: {issue: issue})
- if @issues.present? - if @issues.present?
%li.bottom %li.bottom
......
...@@ -6,12 +6,12 @@ ...@@ -6,12 +6,12 @@
= @issue.created_at.stamp("Aug 21, 2011") = @issue.created_at.stamp("Aug 21, 2011")
%span.pull-right %span.pull-right
- if can?(current_user, :admin_project, @project) || @issue.author == current_user - if can?(current_user, :modify_issue, @issue)
- if @issue.closed? - if @issue.closed?
= link_to 'Reopen', project_issue_path(@project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn grouped reopen_issue" = link_to 'Reopen', project_issue_path(@project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn grouped reopen_issue"
- else - else
= link_to 'Close', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn grouped close_issue", title: "Close Issue" = link_to 'Close', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn grouped close_issue", title: "Close Issue"
- if can?(current_user, :admin_project, @project) || @issue.author == current_user
= link_to edit_project_issue_path(@project, @issue), class: "btn grouped" do = link_to edit_project_issue_path(@project, @issue), class: "btn grouped" do
%i.icon-edit %i.icon-edit
Edit Edit
...@@ -55,5 +55,11 @@ ...@@ -55,5 +55,11 @@
= preserve do = preserve do
= markdown @issue.description = markdown @issue.description
- content_for :note_actions do
- if can?(current_user, :modify_issue, @issue)
- if @issue.closed?
= link_to 'Reopen Issue', project_issue_path(@project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn grouped reopen_issue"
- else
= link_to 'Close Issue', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn grouped close_issue", title: "Close Issue"
.voting_notes#notes= render "notes/notes_with_form" .voting_notes#notes= render "notes/notes_with_form"
...@@ -29,10 +29,10 @@ ...@@ -29,10 +29,10 @@
$(function(){ $(function(){
merge_request = new MergeRequest({ merge_request = new MergeRequest({
url_to_automerge_check: "#{automerge_check_project_merge_request_path(@project, @merge_request)}", url_to_automerge_check: "#{automerge_check_project_merge_request_path(@project, @merge_request)}",
check_enable: #{@merge_request.merge_status == MergeRequest::UNCHECKED ? "true" : "false"}, check_enable: #{@merge_request.unchecked? ? "true" : "false"},
url_to_ci_check: "#{ci_status_project_merge_request_path(@project, @merge_request)}", url_to_ci_check: "#{ci_status_project_merge_request_path(@project, @merge_request)}",
ci_enable: #{@project.gitlab_ci? ? "true" : "false"}, ci_enable: #{@project.gitlab_ci? ? "true" : "false"},
current_status: "#{@merge_request.human_merge_status}", current_status: "#{@merge_request.merge_status_name}",
action: "#{controller.action_name}" action: "#{controller.action_name}"
}); });
}); });
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
%br/ %br/
.content .content
%table %table
- each_diff_line(diff, note.diff_file_index) do |line, type, line_code, line_new, line_old| - each_diff_line_near(diff, note.diff_file_index, note.line_code) do |line, type, line_code, line_new, line_old|
%tr.line_holder{ id: line_code } %tr.line_holder{ id: line_code }
- if type == "match" - if type == "match"
%td.old_line= "..." %td.old_line= "..."
...@@ -22,4 +22,3 @@ ...@@ -22,4 +22,3 @@
- if line_code == note.line_code - if line_code == note.line_code
= render "notes/diff_notes_with_reply", notes: discussion_notes = render "notes/diff_notes_with_reply", notes: discussion_notes
- break # cut off diff after notes
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
.note-form-actions .note-form-actions
.buttons .buttons
= f.submit 'Add Comment', class: "btn comment-btn grouped js-comment-button" = f.submit 'Add Comment', class: "btn comment-btn grouped js-comment-button"
= yield(:note_actions)
%a.btn.grouped.js-close-discussion-note-form Cancel %a.btn.grouped.js-close-discussion-note-form Cancel
.note-form-option .note-form-option
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
%fieldset %fieldset.update-token
%legend %legend
Private token Private token
%span.cred.pull-right %span.cred.pull-right
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
%span You don`t have one yet. Click generate to fix it. %span You don`t have one yet. Click generate to fix it.
= f.submit 'Generate', class: "btn success btn-build-token" = f.submit 'Generate', class: "btn success btn-build-token"
%fieldset %fieldset.update-password
%legend Password %legend Password
= form_for @user, url: update_password_profile_path, method: :put do |f| = form_for @user, url: update_password_profile_path, method: :put do |f|
.padded .padded
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
= @snippet.title = @snippet.title
%small= @snippet.file_name %small= @snippet.file_name
- if can?(current_user, :admin_snippet, @project) || @snippet.author == current_user - if can?(current_user, :admin_snippet, @project) || @snippet.author == current_user
= link_to "Edit", edit_project_snippet_path(@project, @snippet), class: "btn btn-small pull-right" = link_to "Edit", edit_project_snippet_path(@project, @snippet), class: "btn btn-small pull-right", title: 'Edit Snippet'
%br %br
%div= render 'blob' %div= render 'blob'
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
= link_to_project @project = link_to_project @project
%ul.well-list.issues_table %ul.well-list.issues_table
- group[1].each do |issue| - group[1].each do |issue|
= render(partial: 'issues/show', locals: {issue: issue}) = render issue
%hr %hr
= paginate @issues, theme: "gitlab" = paginate @issues, theme: "gitlab"
- else - else
......
...@@ -26,5 +26,5 @@ ...@@ -26,5 +26,5 @@
- elsif user.blocked - elsif user.blocked
%span.btn.disabled.blocked Blocked %span.btn.disabled.blocked Blocked
- elsif allow_admin - elsif allow_admin
= link_to team_member_path(@team, user), confirm: remove_from_user_team_message(@team, user), method: :delete, class: "btn-tiny btn btn-remove" do = link_to team_member_path(@team, user), confirm: remove_from_user_team_message(@team, user), method: :delete, class: "btn-tiny btn btn-remove", title: "Remove from team" do
%i.icon-minus.icon-white %i.icon-minus.icon-white
...@@ -42,6 +42,6 @@ class PostReceive ...@@ -42,6 +42,6 @@ class PostReceive
return false return false
end end
project.trigger_post_receive(oldrev, newrev, ref, user) GitPushService.new.execute(project, user, oldrev, newrev, ref)
end end
end end
class ConvertClosedToStateInMergeRequest < ActiveRecord::Migration class ConvertClosedToStateInMergeRequest < ActiveRecord::Migration
def up def up
MergeRequest.transaction do MergeRequest.transaction do
MergeRequest.where("closed = 1 AND merged = 1").update_all("state = 'merged'") MergeRequest.where(closed: true, merged: true).update_all("state = 'merged'")
MergeRequest.where("closed = 1 AND merged = 0").update_all("state = 'closed'") MergeRequest.where(closed: true, merged: true).update_all("state = 'closed'")
MergeRequest.where("closed = 0").update_all("state = 'opened'") MergeRequest.where(closed: false).update_all("state = 'opened'")
end end
end end
def down def down
MergeRequest.transaction do MergeRequest.transaction do
MergeRequest.where(state: :closed).update_all("closed = 1") MergeRequest.where(state: :closed).update_all(closed: true)
MergeRequest.where(state: :merged).update_all("closed = 1, merged = 1") MergeRequest.where(state: :merged).update_all(closed: true, merged: true)
end end
end end
end end
class AddNewMergeStatusToMergeRequest < ActiveRecord::Migration
def change
add_column :merge_requests, :new_merge_status, :string
end
end
class ConvertMergeStatusInMergeRequest < ActiveRecord::Migration
def up
MergeRequest.transaction do
MergeRequest.where(merge_status: 1).update_all("new_merge_status = 'unchecked'")
MergeRequest.where(merge_status: 2).update_all("new_merge_status = 'can_be_merged'")
MergeRequest.where(merge_status: 3).update_all("new_merge_status = 'cannot_be_merged'")
end
end
def down
MergeRequest.transaction do
MergeRequest.where(new_merge_status: :unchecked).update_all("merge_status = 1")
MergeRequest.where(new_merge_status: :can_be_merged).update_all("merge_status = 2")
MergeRequest.where(new_merge_status: :cannot_be_merged).update_all("merge_status = 3")
end
end
end
class RemoveMergeStatusFromMergeRequest < ActiveRecord::Migration
def up
remove_column :merge_requests, :merge_status
end
def down
add_column :merge_requests, :merge_status, :integer
end
end
class RenameNewMergeStatusToMergeStatusInMilestone < ActiveRecord::Migration
def change
rename_column :merge_requests, :new_merge_status, :merge_status
end
end
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# #
# It's strongly recommended to check this file into your version control system. # It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20130218141554) do ActiveRecord::Schema.define(:version => 20130220133245) do
create_table "events", :force => true do |t| create_table "events", :force => true do |t|
t.string "target_type" t.string "target_type"
...@@ -78,9 +78,9 @@ ActiveRecord::Schema.define(:version => 20130218141554) do ...@@ -78,9 +78,9 @@ ActiveRecord::Schema.define(:version => 20130218141554) do
t.datetime "updated_at", :null => false t.datetime "updated_at", :null => false
t.text "st_commits", :limit => 2147483647 t.text "st_commits", :limit => 2147483647
t.text "st_diffs", :limit => 2147483647 t.text "st_diffs", :limit => 2147483647
t.integer "merge_status", :default => 1, :null => false
t.integer "milestone_id" t.integer "milestone_id"
t.string "state" t.string "state"
t.string "merge_status"
end end
add_index "merge_requests", ["assignee_id"], :name => "index_merge_requests_on_assignee_id" add_index "merge_requests", ["assignee_id"], :name => "index_merge_requests_on_assignee_id"
......
...@@ -31,7 +31,6 @@ Dumping database tables: ...@@ -31,7 +31,6 @@ Dumping database tables:
- Dumping table wikis... [DONE] - Dumping table wikis... [DONE]
Dumping repositories: Dumping repositories:
- Dumping repository abcd... [DONE] - Dumping repository abcd... [DONE]
- Dumping repository gitolite-admin.git... [DONE]
Creating backup archive: $TIMESTAMP_gitlab_backup.tar [DONE] Creating backup archive: $TIMESTAMP_gitlab_backup.tar [DONE]
Deleting tmp directories...[DONE] Deleting tmp directories...[DONE]
Deleting old backups... [SKIPPING] Deleting old backups... [SKIPPING]
...@@ -77,6 +76,5 @@ Restoring database tables: ...@@ -77,6 +76,5 @@ Restoring database tables:
- Loading fixture wikis...[SKIPPING] - Loading fixture wikis...[SKIPPING]
Restoring repositories: Restoring repositories:
- Restoring repository abcd... [DONE] - Restoring repository abcd... [DONE]
- Restoring repository gitolite-admin.git... [DONE]
Deleting tmp directories...[DONE] Deleting tmp directories...[DONE]
``` ```
### Remove grabage from gitolite config and filesystem. Important! Data loss! ### Remove grabage from filesystem. Important! Data loss!
Remove projects from gitolite config if they dont exist in GitLab database
```
bundle exec rake gitlab:cleanup:config RAILS_ENV=production
```
Remove namespaces(dirs) from /home/git/repositories if they dont exist in GitLab database Remove namespaces(dirs) from /home/git/repositories if they dont exist in GitLab database
......
...@@ -17,12 +17,12 @@ bundle exec rake gitlab:enable_namespaces RAILS_ENV=production ...@@ -17,12 +17,12 @@ bundle exec rake gitlab:enable_namespaces RAILS_ENV=production
``` ```
### Enable auto merge ### Rebuild project satellites
This command will enable the auto merge feature. After this you will be able to **merge a merge request** via GitLab and use the **online editor**. This command will build missing satellites for projects. After this you will be able to **merge a merge request** via GitLab and use the **online editor**.
``` ```
bundle exec rake gitlab:enable_automerge RAILS_ENV=production bundle exec rake gitlab:satellites:create RAILS_ENV=production
``` ```
Example output: Example output:
......
...@@ -31,12 +31,10 @@ SSH Clone URL: git@localhost:some-project.git ...@@ -31,12 +31,10 @@ SSH Clone URL: git@localhost:some-project.git
Using LDAP: no Using LDAP: no
Using Omniauth: no Using Omniauth: no
Gitolite information GitLab Shell
Version: v3.04-4-g4524f01 Version: 1.0.4
Admin URI: git@localhost:gitolite-admin
Admin Key: gitlab
Repositories: /home/git/repositories/ Repositories: /home/git/repositories/
Hooks: /home/git/.gitolite/hooks/ Hooks: /home/git/gitlab-shell/hooks/
Git: /usr/bin/git Git: /usr/bin/git
``` ```
...@@ -46,8 +44,8 @@ Git: /usr/bin/git ...@@ -46,8 +44,8 @@ Git: /usr/bin/git
Runs the following rake tasks: Runs the following rake tasks:
* gitlab:env:check * gitlab:env:check
* gitlab:gitolite:check * gitlab:gitlab_shell:check
* gitlab:resque:check * gitlab:sidekiq:check
* gitlab:app:check * gitlab:app:check
It will check that each component was setup according to the installation guide and suggest fixes for issues found. It will check that each component was setup according to the installation guide and suggest fixes for issues found.
...@@ -74,16 +72,12 @@ Checking Environment ... Finished ...@@ -74,16 +72,12 @@ Checking Environment ... Finished
Checking Gitolite ... Checking Gitolite ...
Using recommended version ... yes Using recommended version ... yes
Repo umask is 0007 in .gitolite.rc? ... yes
Allow all Git config keys in .gitolite.rc ... yes
Config directory exists? ... yes Config directory exists? ... yes
Config directory owned by git:git? ... yes Config directory owned by git:git? ... yes
Config directory access is drwxr-x---? ... yes Config directory access is drwxr-x---? ... yes
Repo base directory exists? ... yes Repo base directory exists? ... yes
Repo base owned by git:git? ... yes Repo base owned by git:git? ... yes
Repo base access is drwxrws---? ... yes Repo base access is drwxrws---? ... yes
Can clone gitolite-admin? ... yes
Can commit to gitolite-admin? ... yes
post-receive hook exists? ... yes post-receive hook exists? ... yes
post-receive hook up-to-date? ... yes post-receive hook up-to-date? ... yes
post-receive hooks in repos are links: ... post-receive hooks in repos are links: ...
...@@ -135,24 +129,6 @@ If necessary, remove the `tmp/repo_satellites` directory and rerun the command b ...@@ -135,24 +129,6 @@ If necessary, remove the `tmp/repo_satellites` directory and rerun the command b
bundle exec rake gitlab:satellites:create RAILS_ENV=production bundle exec rake gitlab:satellites:create RAILS_ENV=production
``` ```
### Rebuild each key at gitolite config
This will send all users ssh public keys to gitolite and grant them access (based on their permission) to their projects.
```
bundle exec rake gitlab:gitolite:update_keys RAILS_ENV=production
```
### Rebuild each project at gitolite config
This makes sure that all projects are present in gitolite and can be accessed.
```
bundle exec rake gitlab:gitolite:update_repos RAILS_ENV=production
```
### Import bare repositories into GitLab project instance ### Import bare repositories into GitLab project instance
Notes: Notes:
......
...@@ -12,7 +12,7 @@ Feature: Project Browse files ...@@ -12,7 +12,7 @@ Feature: Project Browse files
Then I should see files from repository for "8470d70" Then I should see files from repository for "8470d70"
Scenario: I browse file content Scenario: I browse file content
Given I click on "Gemfile" file in repo Given I click on "Gemfile.lock" file in repo
Then I should see it content Then I should see it content
Scenario: I browse raw file Scenario: I browse raw file
...@@ -22,6 +22,6 @@ Feature: Project Browse files ...@@ -22,6 +22,6 @@ Feature: Project Browse files
@javascript @javascript
Scenario: I can edit file Scenario: I can edit file
Given I click on "Gemfile" file in repo Given I click on "Gemfile.lock" file in repo
And I click button "edit" And I click button "edit"
Then I can edit code Then I can edit code
...@@ -5,6 +5,6 @@ Feature: Project Browse git repo ...@@ -5,6 +5,6 @@ Feature: Project Browse git repo
Given I visit project source page Given I visit project source page
Scenario: I blame file Scenario: I blame file
Given I click on "Gemfile" file in repo Given I click on "Gemfile.lock" file in repo
And I click blame button And I click blame button
Then I should see git file blame Then I should see git file blame
...@@ -9,7 +9,7 @@ class AdminTeams < Spinach::FeatureSteps ...@@ -9,7 +9,7 @@ class AdminTeams < Spinach::FeatureSteps
end end
And 'Create gitlab user "John"' do And 'Create gitlab user "John"' do
@user = create(:user, :name => "John") @user = create(:user, name: "John")
end end
And 'I click new team link' do And 'I click new team link' do
...@@ -50,8 +50,8 @@ class AdminTeams < Spinach::FeatureSteps ...@@ -50,8 +50,8 @@ class AdminTeams < Spinach::FeatureSteps
When 'I select user "John" from user list as "Developer"' do When 'I select user "John" from user list as "Developer"' do
@user ||= User.find_by_name("John") @user ||= User.find_by_name("John")
within "#team_members" do within "#team_members" do
select @user.name, :from => "user_ids" select "#{@user.name} (#{@user.email})", from: "user_ids"
select "Developer", :from => "default_project_access" select "Developer", from: "default_project_access"
end end
end end
...@@ -89,8 +89,8 @@ class AdminTeams < Spinach::FeatureSteps ...@@ -89,8 +89,8 @@ class AdminTeams < Spinach::FeatureSteps
When 'I select project "Shop" with max access "Reporter"' do When 'I select project "Shop" with max access "Reporter"' do
@project ||= Project.find_by_name("Shop") @project ||= Project.find_by_name("Shop")
within "#assign_projects" do within "#assign_projects" do
select @project.name, :from => "project_ids" select @project.name, from: "project_ids"
select "Reporter", :from => "greatest_project_access" select "Reporter", from: "greatest_project_access"
end end
end end
...@@ -127,8 +127,8 @@ class AdminTeams < Spinach::FeatureSteps ...@@ -127,8 +127,8 @@ class AdminTeams < Spinach::FeatureSteps
When 'I select user "Jimm" ub team members list as "Master"' do When 'I select user "Jimm" ub team members list as "Master"' do
user = User.find_by_name("Jimm") user = User.find_by_name("Jimm")
within "#team_members" do within "#team_members" do
select user.name, :from => "user_ids" select "#{user.name} (#{user.email})", from: "user_ids"
select "Developer", :from => "default_project_access" select "Developer", from: "default_project_access"
end end
end end
......
...@@ -23,16 +23,20 @@ class Profile < Spinach::FeatureSteps ...@@ -23,16 +23,20 @@ class Profile < Spinach::FeatureSteps
end end
Then 'I change my password' do Then 'I change my password' do
within '.update-password' do
fill_in "user_password", :with => "222333" fill_in "user_password", :with => "222333"
fill_in "user_password_confirmation", :with => "222333" fill_in "user_password_confirmation", :with => "222333"
click_button "Save" click_button "Save"
end end
end
When 'I unsuccessfully change my password' do When 'I unsuccessfully change my password' do
within '.update-password' do
fill_in "user_password", with: "password" fill_in "user_password", with: "password"
fill_in "user_password_confirmation", with: "confirmation" fill_in "user_password_confirmation", with: "confirmation"
click_button "Save" click_button "Save"
end end
end
Then "I should see a password error message" do Then "I should see a password error message" do
page.should have_content "Password doesn't match confirmation" page.should have_content "Password doesn't match confirmation"
...@@ -43,9 +47,11 @@ class Profile < Spinach::FeatureSteps ...@@ -43,9 +47,11 @@ class Profile < Spinach::FeatureSteps
end end
Then 'I reset my token' do Then 'I reset my token' do
within '.update-token' do
@old_token = @user.private_token @old_token = @user.private_token
click_button "Reset" click_button "Reset"
end end
end
And 'I should see new token' do And 'I should see new token' do
find("#token").value.should_not == @old_token find("#token").value.should_not == @old_token
......
...@@ -16,12 +16,12 @@ class ProjectBrowseFiles < Spinach::FeatureSteps ...@@ -16,12 +16,12 @@ class ProjectBrowseFiles < Spinach::FeatureSteps
page.should have_content "Gemfile" page.should have_content "Gemfile"
end end
Given 'I click on "Gemfile" file in repo' do Given 'I click on "Gemfile.lock" file in repo' do
click_link "Gemfile" click_link "Gemfile.lock"
end end
Then 'I should see it content' do Then 'I should see it content' do
page.should have_content "rubygems.org" page.should have_content "DEPENDENCIES"
end end
And 'I click link "raw"' do And 'I click link "raw"' do
......
...@@ -3,8 +3,8 @@ class ProjectBrowseGitRepo < Spinach::FeatureSteps ...@@ -3,8 +3,8 @@ class ProjectBrowseGitRepo < Spinach::FeatureSteps
include SharedProject include SharedProject
include SharedPaths include SharedPaths
Given 'I click on "Gemfile" file in repo' do Given 'I click on "Gemfile.lock" file in repo' do
click_link "Gemfile" click_link "Gemfile.lock"
end end
And 'I click blame button' do And 'I click blame button' do
...@@ -12,7 +12,7 @@ class ProjectBrowseGitRepo < Spinach::FeatureSteps ...@@ -12,7 +12,7 @@ class ProjectBrowseGitRepo < Spinach::FeatureSteps
end end
Then 'I should see git file blame' do Then 'I should see git file blame' do
page.should have_content "rubygems.org" page.should have_content "DEPENDENCIES"
page.should have_content "Dmitriy Zaporozhets" page.should have_content "Dmitriy Zaporozhets"
page.should have_content "Moving to rails 3.2" page.should have_content "Moving to rails 3.2"
end end
......
...@@ -53,7 +53,7 @@ class ProjectTeamManagement < Spinach::FeatureSteps ...@@ -53,7 +53,7 @@ class ProjectTeamManagement < Spinach::FeatureSteps
end end
Given 'I click link "Sam"' do Given 'I click link "Sam"' do
click_link "Sam" first(:link, "Sam").click
end end
Then 'I should see "Sam" team profile' do Then 'I should see "Sam" team profile' do
......
...@@ -22,7 +22,7 @@ module SharedDiffNote ...@@ -22,7 +22,7 @@ module SharedDiffNote
Given 'I leave a diff comment like "Typo, please fix"' do Given 'I leave a diff comment like "Typo, please fix"' do
find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click") find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click")
within(".file") do within(".file form[rel$='586fb7c4e1add2d4d24e27566ed7064680098646_29_14']") do
fill_in "note[note]", with: "Typo, please fix" fill_in "note[note]", with: "Typo, please fix"
#click_button("Add Comment") #click_button("Add Comment")
find(".js-comment-button").trigger("click") find(".js-comment-button").trigger("click")
...@@ -32,7 +32,7 @@ module SharedDiffNote ...@@ -32,7 +32,7 @@ module SharedDiffNote
Given 'I preview a diff comment text like "Should fix it :smile:"' do Given 'I preview a diff comment text like "Should fix it :smile:"' do
find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click") find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click")
within(".file") do within(".file form[rel$='586fb7c4e1add2d4d24e27566ed7064680098646_29_14']") do
fill_in "note[note]", with: "Should fix it :smile:" fill_in "note[note]", with: "Should fix it :smile:"
find(".js-note-preview-button").trigger("click") find(".js-note-preview-button").trigger("click")
end end
...@@ -40,7 +40,7 @@ module SharedDiffNote ...@@ -40,7 +40,7 @@ module SharedDiffNote
Given 'I preview another diff comment text like "DRY this up"' do Given 'I preview another diff comment text like "DRY this up"' do
find("#586fb7c4e1add2d4d24e27566ed7064680098646_57_41.line_holder .js-add-diff-note-button").trigger("click") find("#586fb7c4e1add2d4d24e27566ed7064680098646_57_41.line_holder .js-add-diff-note-button").trigger("click")
within(".file") do within(".file form[rel$='586fb7c4e1add2d4d24e27566ed7064680098646_57_41']") do
fill_in "note[note]", with: "DRY this up" fill_in "note[note]", with: "DRY this up"
find(".js-note-preview-button").trigger("click") find(".js-note-preview-button").trigger("click")
end end
......
...@@ -173,12 +173,10 @@ module SharedPaths ...@@ -173,12 +173,10 @@ module SharedPaths
# ---------------------------------------- # ----------------------------------------
And 'I visit project "Shop" page' do And 'I visit project "Shop" page' do
project = Project.find_by_name("Shop")
visit project_path(project) visit project_path(project)
end end
When 'I visit edit project "Shop" page' do When 'I visit edit project "Shop" page' do
project = Project.find_by_name("Shop")
visit edit_project_path(project) visit edit_project_path(project)
end end
...@@ -219,7 +217,7 @@ module SharedPaths ...@@ -219,7 +217,7 @@ module SharedPaths
end end
And 'I visit project "Shop" issues page' do And 'I visit project "Shop" issues page' do
visit project_issues_path(Project.find_by_name("Shop")) visit project_issues_path(project)
end end
Given 'I visit issue page "Release 0.4"' do Given 'I visit issue page "Release 0.4"' do
...@@ -228,7 +226,7 @@ module SharedPaths ...@@ -228,7 +226,7 @@ module SharedPaths
end end
Given 'I visit project "Shop" labels page' do Given 'I visit project "Shop" labels page' do
visit project_labels_path(Project.find_by_name("Shop")) visit project_labels_path(project)
end end
Given 'I visit merge request page "Bug NS-04"' do Given 'I visit merge request page "Bug NS-04"' do
...@@ -242,20 +240,18 @@ module SharedPaths ...@@ -242,20 +240,18 @@ module SharedPaths
end end
And 'I visit project "Shop" merge requests page' do And 'I visit project "Shop" merge requests page' do
visit project_merge_requests_path(Project.find_by_name("Shop")) visit project_merge_requests_path(project)
end end
Given 'I visit project "Shop" milestones page' do Given 'I visit project "Shop" milestones page' do
@project = Project.find_by_name("Shop") visit project_milestones_path(project)
visit project_milestones_path(@project)
end end
Then 'I visit project "Shop" team page' do Then 'I visit project "Shop" team page' do
visit project_team_index_path(Project.find_by_name("Shop")) visit project_team_index_path(project)
end end
Then 'I visit project "Shop" wall page' do Then 'I visit project "Shop" wall page' do
project = Project.find_by_name("Shop")
visit wall_project_path(project) visit wall_project_path(project)
end end
...@@ -266,4 +262,8 @@ module SharedPaths ...@@ -266,4 +262,8 @@ module SharedPaths
def root_ref def root_ref
@project.repository.root_ref @project.repository.root_ref
end end
def project
project = Project.find_by_name!("Shop")
end
end end
...@@ -177,8 +177,8 @@ class Userteams < Spinach::FeatureSteps ...@@ -177,8 +177,8 @@ class Userteams < Spinach::FeatureSteps
And 'I select user "John" from list with role "Reporter"' do And 'I select user "John" from list with role "Reporter"' do
user = User.find_by_name("John") user = User.find_by_name("John")
within "#team_members" do within "#team_members" do
select user.name, :from => "user_ids" select "#{user.name} (#{user.email})", from: "user_ids"
select "Reporter", :from => "default_project_access" select "Reporter", from: "default_project_access"
end end
click_button "Add" click_button "Add"
end end
...@@ -213,8 +213,8 @@ class Userteams < Spinach::FeatureSteps ...@@ -213,8 +213,8 @@ class Userteams < Spinach::FeatureSteps
When 'I submit form with selected project and max access' do When 'I submit form with selected project and max access' do
within "#assign_projects" do within "#assign_projects" do
select @project.name_with_namespace, :from => "project_ids" select @project.name_with_namespace, from: "project_ids"
select "Reporter", :from => "greatest_project_access" select "Reporter", from: "greatest_project_access"
end end
click_button "Add" click_button "Add"
end end
......
...@@ -5,6 +5,12 @@ module Gitlab ...@@ -5,6 +5,12 @@ module Gitlab
# #
# Check if ssh key has access to project code # Check if ssh key has access to project code
# #
# Params:
# key_id - SSH Key id
# project - project path with namespace
# action - git action (git-upload-pack or git-receive-pack)
# ref - branch name
#
get "/allowed" do get "/allowed" do
key = Key.find(params[:key_id]) key = Key.find(params[:key_id])
project = Project.find_with_namespace(params[:project]) project = Project.find_with_namespace(params[:project])
......
...@@ -255,7 +255,6 @@ namespace :gitlab do ...@@ -255,7 +255,6 @@ namespace :gitlab do
warn_user_is_not_gitlab warn_user_is_not_gitlab
start_checking "Environment" start_checking "Environment"
check_issue_1059_shell_profile_error
check_gitlab_git_config check_gitlab_git_config
check_python2_exists check_python2_exists
check_python2_version check_python2_version
...@@ -294,30 +293,6 @@ namespace :gitlab do ...@@ -294,30 +293,6 @@ namespace :gitlab do
end end
end end
# see https://github.com/gitlabhq/gitlabhq/issues/1059
def check_issue_1059_shell_profile_error
gitlab_shell_ssh_user = Gitlab.config.gitlab_shell.ssh_user
print "Has no \"-e\" in ~#{gitlab_shell_ssh_user}/.profile ... "
profile_file = File.join(gitlab_shell_user_home, ".profile")
unless File.read(profile_file) =~ /^-e PATH/
puts "yes".green
else
puts "no".red
try_fixing_it(
"Open #{profile_file}",
"Find the line starting with \"-e PATH\"",
"Remove \"-e \" so the line starts with PATH"
)
for_more_information(
see_installation_guide_section("Gitlab Shell"),
"https://github.com/gitlabhq/gitlabhq/issues/1059"
)
fix_and_rerun
end
end
def check_python2_exists def check_python2_exists
print "Has python2? ... " print "Has python2? ... "
......
...@@ -82,7 +82,6 @@ describe "Admin::Users" do ...@@ -82,7 +82,6 @@ describe "Admin::Users" do
it "should have user info" do it "should have user info" do
page.should have_content(@user.email) page.should have_content(@user.email)
page.should have_content(@user.name) page.should have_content(@user.name)
page.should have_content(@user.projects_limit)
end end
end end
......
...@@ -169,32 +169,40 @@ describe "Gitlab Flavored Markdown" do ...@@ -169,32 +169,40 @@ describe "Gitlab Flavored Markdown" do
describe "for notes" do describe "for notes" do
it "should render in commits#show", js: true do it "should render in commits#show", js: true do
visit project_commit_path(project, commit) visit project_commit_path(project, commit)
within ".new_note.js-main-target-form" do
fill_in "note_note", with: "see ##{issue.id}" fill_in "note_note", with: "see ##{issue.id}"
click_button "Add Comment" click_button "Add Comment"
end
page.should have_link("##{issue.id}") page.should have_link("##{issue.id}")
end end
it "should render in issue#show", js: true do it "should render in issue#show", js: true do
visit project_issue_path(project, issue) visit project_issue_path(project, issue)
within ".new_note.js-main-target-form" do
fill_in "note_note", with: "see ##{issue.id}" fill_in "note_note", with: "see ##{issue.id}"
click_button "Add Comment" click_button "Add Comment"
end
page.should have_link("##{issue.id}") page.should have_link("##{issue.id}")
end end
it "should render in merge_request#show", js: true do it "should render in merge_request#show", js: true do
visit project_merge_request_path(project, merge_request) visit project_merge_request_path(project, merge_request)
within ".new_note.js-main-target-form" do
fill_in "note_note", with: "see ##{issue.id}" fill_in "note_note", with: "see ##{issue.id}"
click_button "Add Comment" click_button "Add Comment"
end
page.should have_link("##{issue.id}") page.should have_link("##{issue.id}")
end end
it "should render in projects#wall", js: true do it "should render in projects#wall", js: true do
visit wall_project_path(project) visit wall_project_path(project)
within ".new_note.js-main-target-form" do
fill_in "note_note", with: "see ##{issue.id}" fill_in "note_note", with: "see ##{issue.id}"
click_button "Add Comment" click_button "Add Comment"
end
page.should have_link("##{issue.id}") page.should have_link("##{issue.id}")
end end
......
...@@ -18,7 +18,7 @@ describe "On a merge request", js: true do ...@@ -18,7 +18,7 @@ describe "On a merge request", js: true do
it { should have_css(".js-main-target-form", visible: true, count: 1) } it { should have_css(".js-main-target-form", visible: true, count: 1) }
# button initalization # button initalization
it { within(".js-main-target-form") { should have_button("Add Comment") } } it { find(".js-main-target-form input[type=submit]").value.should == "Add Comment" }
it { within(".js-main-target-form") { should_not have_link("Cancel") } } it { within(".js-main-target-form") { should_not have_link("Cancel") } }
# notifiactions # notifiactions
...@@ -67,7 +67,7 @@ describe "On a merge request", js: true do ...@@ -67,7 +67,7 @@ describe "On a merge request", js: true do
end end
# note added # note added
it { within(".js-main-target-form") { should have_content("This is awsome!") } } it { should have_content("This is awsome!") }
# reset form # reset form
it { within(".js-main-target-form") { should have_no_field("note[note]", with: "This is awesome!") } } it { within(".js-main-target-form") { should have_no_field("note[note]", with: "This is awesome!") } }
...@@ -97,8 +97,10 @@ describe "On a merge request diff", js: true, focus: true do ...@@ -97,8 +97,10 @@ describe "On a merge request diff", js: true, focus: true do
visit diffs_project_merge_request_path(project, merge_request) visit diffs_project_merge_request_path(project, merge_request)
within '.diffs-tab' do
click_link("Diff") click_link("Diff")
end end
end
subject { page } subject { page }
...@@ -134,7 +136,9 @@ describe "On a merge request diff", js: true, focus: true do ...@@ -134,7 +136,9 @@ describe "On a merge request diff", js: true, focus: true do
end end
it "should be removed when canceled" do it "should be removed when canceled" do
within(".file form[rel$='4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185']") do
find(".js-close-discussion-note-form").trigger("click") find(".js-close-discussion-note-form").trigger("click")
end
should have_no_css(".js-temp-notes-holder") should have_no_css(".js-temp-notes-holder")
end end
......
...@@ -17,7 +17,7 @@ describe "On the project wall", js: true do ...@@ -17,7 +17,7 @@ describe "On the project wall", js: true do
it { should have_css(".js-main-target-form", visible: true, count: 1) } it { should have_css(".js-main-target-form", visible: true, count: 1) }
# button initalization # button initalization
it { within(".js-main-target-form") { should have_button("Add Comment") } } it { find(".js-main-target-form input[type=submit]").value.should == "Add Comment" }
it { within(".js-main-target-form") { should_not have_link("Cancel") } } it { within(".js-main-target-form") { should_not have_link("Cancel") } }
# notifiactions # notifiactions
...@@ -66,7 +66,7 @@ describe "On the project wall", js: true do ...@@ -66,7 +66,7 @@ describe "On the project wall", js: true do
end end
# note added # note added
it { within(".js-main-target-form") { should have_content("This is awsome!") } } it { should have_content("This is awsome!") }
# reset form # reset form
it { within(".js-main-target-form") { should have_no_field("note[note]", with: "This is awesome!") } } it { within(".js-main-target-form") { should have_no_field("note[note]", with: "This is awesome!") } }
......
...@@ -6,9 +6,12 @@ describe "Search" do ...@@ -6,9 +6,12 @@ describe "Search" do
@project = create(:project) @project = create(:project)
@project.team << [@user, :reporter] @project.team << [@user, :reporter]
visit search_path visit search_path
within '.search-holder' do
fill_in "search", with: @project.name[0..3] fill_in "search", with: @project.name[0..3]
click_button "Search" click_button "Search"
end end
end
it "should show project in search results" do it "should show project in search results" do
page.should have_content @project.name page.should have_content @project.name
......
...@@ -72,7 +72,7 @@ describe "Snippets" do ...@@ -72,7 +72,7 @@ describe "Snippets" do
author: @user, author: @user,
project: project) project: project)
visit project_snippet_path(project, @snippet) visit project_snippet_path(project, @snippet)
click_link "Edit" click_link "Edit Snippet"
end end
it "should open edit page" do it "should open edit page" do
......
require 'spec_helper'
describe 'Users' do
describe "GET /users/sign_up" do
before do
Gitlab.config.gitlab.stub(:signup_enabled).and_return(true)
end
it "should create a new user account" do
visit new_user_registration_path
fill_in "user_name", with: "Name Surname"
fill_in "user_username", with: "Great"
fill_in "user_email", with: "name@mail.com"
fill_in "user_password", with: "password1234"
fill_in "user_password_confirmation", with: "password1234"
expect { click_button "Sign up" }.to change {User.count}.by(1)
end
end
end
require 'spec_helper'
describe 'Gitlab::Popen', no_db: true do
let (:path) { Rails.root.join('tmp').to_s }
before do
@klass = Class.new(Object)
@klass.send(:include, Gitlab::Popen)
end
context 'zero status' do
before do
@output, @status = @klass.new.popen('ls', path)
end
it { @status.should be_zero }
it { @output.should include('cache') }
end
context 'non-zero status' do
before do
@output, @status = @klass.new.popen('cat NOTHING', path)
end
it { @status.should == 1 }
it { @output.should include('No such file or directory') }
end
end
...@@ -32,6 +32,12 @@ describe MergeRequest do ...@@ -32,6 +32,12 @@ describe MergeRequest do
it { should_not allow_mass_assignment_of(:project_id) } it { should_not allow_mass_assignment_of(:project_id) }
end end
describe "Respond to" do
it { should respond_to(:unchecked?) }
it { should respond_to(:can_be_merged?) }
it { should respond_to(:cannot_be_merged?) }
end
describe 'modules' do describe 'modules' do
it { should include_module(Issuable) } it { should include_module(Issuable) }
end end
......
require 'spec_helper'
describe Project, "Hooks" do
let(:project) { create(:project) }
before do
@key = create(:key, user: project.owner)
@user = @key.user
@key_id = @key.identifier
end
describe "Post Receive Event" do
it "should create push event" do
oldrev, newrev, ref = '00000000000000000000000000000000', 'newrev', 'refs/heads/master'
data = project.post_receive_data(oldrev, newrev, ref, @user)
project.observe_push(data)
event = Event.last
event.should_not be_nil
event.project.should == project
event.action.should == Event::PUSHED
event.data.should == data
end
end
describe "Project hooks" do
context "with no web hooks" do
it "raises no errors" do
lambda {
project.execute_hooks({})
}.should_not raise_error
end
end
context "with web hooks" do
before do
@project_hook = create(:project_hook)
@project_hook_2 = create(:project_hook)
project.hooks << [@project_hook, @project_hook_2]
stub_request(:post, @project_hook.url)
stub_request(:post, @project_hook_2.url)
end
it "executes multiple web hook" do
@project_hook.should_receive(:async_execute).once
@project_hook_2.should_receive(:async_execute).once
project.trigger_post_receive('oldrev', 'newrev', 'refs/heads/master', @user)
end
end
context "does not execute web hooks" do
before do
@project_hook = create(:project_hook)
project.hooks << [@project_hook]
end
it "when pushing a branch for the first time" do
@project_hook.should_not_receive(:execute)
project.trigger_post_receive('00000000000000000000000000000000', 'newrev', 'refs/heads/master', @user)
end
it "when pushing tags" do
@project_hook.should_not_receive(:execute)
project.trigger_post_receive('oldrev', 'newrev', 'refs/tags/v1.0.0', @user)
end
end
context "when pushing new branches" do
end
context "when gathering commit data" do
before do
@oldrev, @newrev, @ref = project.repository.fresh_commits(2).last.sha,
project.repository.fresh_commits(2).first.sha, 'refs/heads/master'
@commit = project.repository.fresh_commits(2).first
# Fill nil/empty attributes
project.description = "This is a description"
@data = project.post_receive_data(@oldrev, @newrev, @ref, @user)
end
subject { @data }
it { should include(before: @oldrev) }
it { should include(after: @newrev) }
it { should include(ref: @ref) }
it { should include(user_id: project.owner.id) }
it { should include(user_name: project.owner.name) }
context "with repository data" do
subject { @data[:repository] }
it { should include(name: project.name) }
it { should include(url: project.url_to_repo) }
it { should include(description: project.description) }
it { should include(homepage: project.web_url) }
end
context "with commits" do
subject { @data[:commits] }
it { should be_an(Array) }
it { should have(1).element }
context "the commit" do
subject { @data[:commits].first }
it { should include(id: @commit.id) }
it { should include(message: @commit.safe_message) }
it { should include(timestamp: @commit.date.xmlschema) }
it { should include(url: "#{Gitlab.config.gitlab.url}/#{project.code}/commit/#{@commit.id}") }
context "with a author" do
subject { @data[:commits].first[:author] }
it { should include(name: @commit.author_name) }
it { should include(email: @commit.author_email) }
end
end
end
end
end
end
...@@ -72,11 +72,8 @@ describe Project do ...@@ -72,11 +72,8 @@ describe Project do
it { should respond_to(:url_to_repo) } it { should respond_to(:url_to_repo) }
it { should respond_to(:repo_exists?) } it { should respond_to(:repo_exists?) }
it { should respond_to(:satellite) } it { should respond_to(:satellite) }
it { should respond_to(:observe_push) }
it { should respond_to(:update_merge_requests) } it { should respond_to(:update_merge_requests) }
it { should respond_to(:execute_hooks) } it { should respond_to(:execute_hooks) }
it { should respond_to(:post_receive_data) }
it { should respond_to(:trigger_post_receive) }
it { should respond_to(:transfer) } it { should respond_to(:transfer) }
it { should respond_to(:name_with_namespace) } it { should respond_to(:name_with_namespace) }
it { should respond_to(:namespace_owner) } it { should respond_to(:namespace_owner) }
......
...@@ -10,9 +10,6 @@ describe ProjectTeam do ...@@ -10,9 +10,6 @@ describe ProjectTeam do
it { should respond_to(:masters) } it { should respond_to(:masters) }
it { should respond_to(:reporters) } it { should respond_to(:reporters) }
it { should respond_to(:guests) } it { should respond_to(:guests) }
it { should respond_to(:repository_writers) }
it { should respond_to(:repository_masters) }
it { should respond_to(:repository_readers) }
end end
end end
...@@ -69,28 +69,10 @@ describe User do ...@@ -69,28 +69,10 @@ describe User do
describe "Respond to" do describe "Respond to" do
it { should respond_to(:is_admin?) } it { should respond_to(:is_admin?) }
it { should respond_to(:identifier) }
it { should respond_to(:name) } it { should respond_to(:name) }
it { should respond_to(:private_token) } it { should respond_to(:private_token) }
end end
describe '#identifier' do
it "should return valid identifier" do
user = build(:user, email: "test@mail.com")
user.identifier.should == "test_mail_com"
end
it "should return identifier without + sign" do
user = build(:user, email: "test+foo@mail.com")
user.identifier.should == "test_foo_mail_com"
end
it "should conform to Gitolite's required identifier pattern" do
user = build(:user, email: "_test@example.com")
user.identifier.should == 'test_example_com'
end
end
describe '#generate_password' do describe '#generate_password' do
it "should execute callback when force_random_password specified" do it "should execute callback when force_random_password specified" do
user = build(:user, force_random_password: true) user = build(:user, force_random_password: true)
......
require 'spec_helper'
describe Gitlab::API do
include ApiHelpers
let(:user) { create(:user) }
let(:key) { create(:key, user: user) }
let(:project) { create(:project) }
describe "GET /internal/check", no_db: true do
it do
get api("/internal/check")
response.status.should == 200
json_response['api_version'].should == Gitlab::API.version
end
end
describe "GET /internal/discover" do
it do
get(api("/internal/discover"), key_id: key.id)
response.status.should == 200
json_response['email'].should == user.email
end
end
describe "GET /internal/allowed" do
context "access granted" do
before do
project.team << [user, :developer]
end
context "git pull" do
it do
get(
api("/internal/allowed"),
ref: 'master',
key_id: key.id,
project: project.path_with_namespace,
action: 'git-upload-pack'
)
response.status.should == 200
response.body.should == 'true'
end
end
context "git push" do
it do
get(
api("/internal/allowed"),
ref: 'master',
key_id: key.id,
project: project.path_with_namespace,
action: 'git-receive-pack'
)
response.status.should == 200
response.body.should == 'true'
end
end
end
context "access denied" do
before do
project.team << [user, :guest]
end
context "git pull" do
it do
get(
api("/internal/allowed"),
ref: 'master',
key_id: key.id,
project: project.path_with_namespace,
action: 'git-upload-pack'
)
response.status.should == 200
response.body.should == 'false'
end
end
context "git push" do
it do
get(
api("/internal/allowed"),
ref: 'master',
key_id: key.id,
project: project.path_with_namespace,
action: 'git-receive-pack'
)
response.status.should == 200
response.body.should == 'false'
end
end
end
end
end
...@@ -97,32 +97,27 @@ describe Gitlab::API do ...@@ -97,32 +97,27 @@ describe Gitlab::API do
end end
describe "GET /users/sign_up" do describe "GET /users/sign_up" do
context 'enabled' do
before do before do
Gitlab.config.gitlab.stub(:signup_enabled).and_return(false) Gitlab.config.gitlab.stub(:signup_enabled).and_return(true)
end end
it "should redirect to sign in page if signup is disabled" do
it "should return sign up page if signup is enabled" do
get "/users/sign_up" get "/users/sign_up"
response.status.should == 302 response.status.should == 200
response.should redirect_to(new_user_session_path)
end end
end end
describe "GET /users/sign_up" do context 'disabled' do
before do before do
Gitlab.config.gitlab.stub(:signup_enabled).and_return(true) Gitlab.config.gitlab.stub(:signup_enabled).and_return(false)
end end
it "should return sign up page if signup is enabled" do
it "should redirect to sign in page if signup is disabled" do
get "/users/sign_up" get "/users/sign_up"
response.status.should == 200 response.status.should == 302
response.should redirect_to(new_user_session_path)
end end
it "should create a new user account" do
visit new_user_registration_path
fill_in "user_name", with: "Name Surname"
fill_in "user_username", with: "Great"
fill_in "user_email", with: "name@mail.com"
fill_in "user_password", with: "password1234"
fill_in "user_password_confirmation", with: "password1234"
expect { click_button "Sign up" }.to change {User.count}.by(1)
end end
end end
......
require 'spec_helper'
describe GitPushService do
let (:user) { create :user }
let (:project) { create :project }
let (:service) { GitPushService.new }
before do
@oldrev = 'b98a310def241a6fd9c9a9a3e7934c48e498fe81'
@newrev = 'b19a04f53caeebf4fe5ec2327cb83e9253dc91bb'
@ref = 'refs/heads/master'
end
describe "Git Push Data" do
before do
service.execute(project, user, @oldrev, @newrev, @ref)
@push_data = service.push_data
@commit = project.repository.commit(@newrev)
end
subject { @push_data }
it { should include(before: @oldrev) }
it { should include(after: @newrev) }
it { should include(ref: @ref) }
it { should include(user_id: user.id) }
it { should include(user_name: user.name) }
context "with repository data" do
subject { @push_data[:repository] }
it { should include(name: project.name) }
it { should include(url: project.url_to_repo) }
it { should include(description: project.description) }
it { should include(homepage: project.web_url) }
end
context "with commits" do
subject { @push_data[:commits] }
it { should be_an(Array) }
it { should have(1).element }
context "the commit" do
subject { @push_data[:commits].first }
it { should include(id: @commit.id) }
it { should include(message: @commit.safe_message) }
it { should include(timestamp: @commit.date.xmlschema) }
it { should include(url: "#{Gitlab.config.gitlab.url}/#{project.code}/commit/#{@commit.id}") }
context "with a author" do
subject { @push_data[:commits].first[:author] }
it { should include(name: @commit.author_name) }
it { should include(email: @commit.author_email) }
end
end
end
end
describe "Push Event" do
before do
service.execute(project, user, @oldrev, @newrev, @ref)
@event = Event.last
end
it { @event.should_not be_nil }
it { @event.project.should == project }
it { @event.action.should == Event::PUSHED }
it { @event.data.should == service.push_data }
end
describe "Web Hooks" do
context "with web hooks" do
before do
@project_hook = create(:project_hook)
@project_hook_2 = create(:project_hook)
project.hooks << [@project_hook, @project_hook_2]
stub_request(:post, @project_hook.url)
stub_request(:post, @project_hook_2.url)
end
it "executes multiple web hook" do
@project_hook.should_receive(:async_execute).once
@project_hook_2.should_receive(:async_execute).once
service.execute(project, user, @oldrev, @newrev, @ref)
end
end
context "does not execute web hooks" do
before do
@project_hook = create(:project_hook)
project.hooks << [@project_hook]
end
it "when pushing a branch for the first time" do
@project_hook.should_not_receive(:execute)
service.execute(project, user, '00000000000000000000000000000000', 'newrev', 'refs/heads/master')
end
it "when pushing tags" do
@project_hook.should_not_receive(:execute)
service.execute(project, user, 'newrev', 'newrev', 'refs/tags/v1.0.0')
end
end
end
end
require 'spec_helper'
describe SystemHooksService do
let (:user) { create :user }
let (:project) { create :project }
let (:users_project) { create :users_project }
context 'it should build event data' do
it 'should build event data for user' do
SystemHooksService.build_event_data(user, :create).should include(:event_name, :name, :created_at, :email)
end
it 'should build event data for project' do
SystemHooksService.build_event_data(project, :create).should include(:event_name, :name, :created_at, :path, :project_id, :owner_name, :owner_email)
end
it 'should build event data for users project' do
SystemHooksService.build_event_data(users_project, :create).should include(:event_name, :created_at, :project_name, :project_path, :project_id, :user_name, :user_email, :project_access)
end
end
context 'it should build event names' do
it 'should build event names for user' do
SystemHooksService.build_event_name(user, :create).should eq "user_create"
SystemHooksService.build_event_name(user, :destroy).should eq "user_destroy"
end
it 'should build event names for project' do
SystemHooksService.build_event_name(project, :create).should eq "project_create"
SystemHooksService.build_event_name(project, :destroy).should eq "project_destroy"
end
it 'should build event names for users project' do
SystemHooksService.build_event_name(users_project, :create).should eq "user_add_to_team"
SystemHooksService.build_event_name(users_project, :destroy).should eq "user_remove_from_team"
end
end
end
...@@ -10,19 +10,19 @@ require 'capybara/rspec' ...@@ -10,19 +10,19 @@ require 'capybara/rspec'
require 'webmock/rspec' require 'webmock/rspec'
require 'email_spec' require 'email_spec'
require 'sidekiq/testing/inline' require 'sidekiq/testing/inline'
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist
# Requires supporting ruby files with custom matchers and macros, etc, # Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories. # in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist
WebMock.disable_net_connect!(allow_localhost: true) WebMock.disable_net_connect!(allow_localhost: true)
RSpec.configure do |config| RSpec.configure do |config|
config.mock_with :rspec config.mock_with :rspec
config.include LoginHelpers, type: :feature
config.include LoginHelpers, type: :request config.include LoginHelpers, type: :request
config.include FactoryGirl::Syntax::Methods config.include FactoryGirl::Syntax::Methods
config.include Devise::TestHelpers, type: :controller config.include Devise::TestHelpers, type: :controller
......
...@@ -9,10 +9,14 @@ RSpec.configure do |config| ...@@ -9,10 +9,14 @@ RSpec.configure do |config|
DatabaseCleaner.strategy = :transaction DatabaseCleaner.strategy = :transaction
end end
unless example.metadata[:no_db]
DatabaseCleaner.start DatabaseCleaner.start
end end
end
config.after do config.after do
unless example.metadata[:no_db]
DatabaseCleaner.clean DatabaseCleaner.clean
end end
end
end end
require "repository" require "repository"
require "project" require "project"
require "merge_request"
require "shell" require "shell"
# Stubs out all Git repository access done by models so that specs can run # Stubs out all Git repository access done by models so that specs can run
...@@ -32,6 +33,12 @@ class Project ...@@ -32,6 +33,12 @@ class Project
end end
end end
class MergeRequest
def check_if_can_be_merged
true
end
end
class GitLabTestRepo < Repository class GitLabTestRepo < Repository
def repo def repo
@repo ||= Grit::Repo.new(Rails.root.join('tmp', 'repositories', 'gitlabhq')) @repo ||= Grit::Repo.new(Rails.root.join('tmp', 'repositories', 'gitlabhq'))
......
...@@ -21,7 +21,6 @@ describe PostReceive do ...@@ -21,7 +21,6 @@ describe PostReceive do
it "does not run if the author is not in the project" do it "does not run if the author is not in the project" do
Key.stub(find_by_id: nil) Key.stub(find_by_id: nil)
project.should_not_receive(:observe_push)
project.should_not_receive(:execute_hooks) project.should_not_receive(:execute_hooks)
PostReceive.new.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id).should be_false PostReceive.new.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id).should be_false
...@@ -32,7 +31,6 @@ describe PostReceive do ...@@ -32,7 +31,6 @@ describe PostReceive do
project.should_receive(:execute_hooks) project.should_receive(:execute_hooks)
project.should_receive(:execute_services) project.should_receive(:execute_services)
project.should_receive(:update_merge_requests) project.should_receive(:update_merge_requests)
project.should_receive(:observe_push)
PostReceive.new.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id) PostReceive.new.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id)
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment