Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
gitlab-ce
Commits
35f9f79b
Commit
35f9f79b
authored
Aug 15, 2016
by
Ruben Davila
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into 8-11-stable
parents
69ed2c96
06e3bb9f
Changes
71
Hide whitespace changes
Inline
Side-by-side
Showing
71 changed files
with
794 additions
and
165 deletions
+794
-165
.gitlab-ci.yml
.gitlab-ci.yml
+1
-0
CHANGELOG
CHANGELOG
+8
-0
app/assets/javascripts/issuable.js
app/assets/javascripts/issuable.js
+4
-7
app/assets/stylesheets/pages/merge_requests.scss
app/assets/stylesheets/pages/merge_requests.scss
+4
-1
app/controllers/admin/groups_controller.rb
app/controllers/admin/groups_controller.rb
+2
-2
app/controllers/dashboard/todos_controller.rb
app/controllers/dashboard/todos_controller.rb
+2
-2
app/controllers/groups_controller.rb
app/controllers/groups_controller.rb
+2
-2
app/finders/projects_finder.rb
app/finders/projects_finder.rb
+2
-1
app/finders/todos_finder.rb
app/finders/todos_finder.rb
+9
-11
app/helpers/todos_helper.rb
app/helpers/todos_helper.rb
+2
-2
app/models/blob.rb
app/models/blob.rb
+7
-0
app/models/deployment.rb
app/models/deployment.rb
+6
-0
app/models/environment.rb
app/models/environment.rb
+6
-0
app/models/merge_request.rb
app/models/merge_request.rb
+8
-0
app/models/namespace.rb
app/models/namespace.rb
+2
-0
app/models/project_services/pivotaltracker_service.rb
app/models/project_services/pivotaltracker_service.rb
+27
-4
app/models/user.rb
app/models/user.rb
+2
-2
app/services/delete_user_service.rb
app/services/delete_user_service.rb
+6
-1
app/services/destroy_group_service.rb
app/services/destroy_group_service.rb
+13
-3
app/services/merge_requests/get_urls_service.rb
app/services/merge_requests/get_urls_service.rb
+12
-1
app/services/todo_service.rb
app/services/todo_service.rb
+2
-1
app/views/projects/blob/_image.html.haml
app/views/projects/blob/_image.html.haml
+11
-5
app/views/projects/merge_requests/widget/_heading.html.haml
app/views/projects/merge_requests/widget/_heading.html.haml
+13
-0
app/views/shared/projects/_project.html.haml
app/views/shared/projects/_project.html.haml
+2
-0
app/workers/group_destroy_worker.rb
app/workers/group_destroy_worker.rb
+17
-0
db/migrate/20140407135544_fix_namespaces.rb
db/migrate/20140407135544_fix_namespaces.rb
+8
-2
db/migrate/20160805041956_add_deleted_at_to_namespaces.rb
db/migrate/20160805041956_add_deleted_at_to_namespaces.rb
+12
-0
db/schema.rb
db/schema.rb
+3
-1
doc/api/services.md
doc/api/services.md
+2
-2
features/steps/dashboard/dashboard.rb
features/steps/dashboard/dashboard.rb
+1
-0
features/steps/dashboard/event_filters.rb
features/steps/dashboard/event_filters.rb
+10
-3
features/steps/dashboard/issues.rb
features/steps/dashboard/issues.rb
+5
-0
features/steps/dashboard/merge_requests.rb
features/steps/dashboard/merge_requests.rb
+5
-0
features/steps/dashboard/new_project.rb
features/steps/dashboard/new_project.rb
+2
-0
features/steps/project/builds/artifacts.rb
features/steps/project/builds/artifacts.rb
+1
-0
features/steps/project/forked_merge_requests.rb
features/steps/project/forked_merge_requests.rb
+3
-0
features/steps/project/issues/issues.rb
features/steps/project/issues/issues.rb
+2
-0
features/steps/project/merge_requests.rb
features/steps/project/merge_requests.rb
+2
-0
features/steps/project/source/browse_files.rb
features/steps/project/source/browse_files.rb
+2
-0
features/steps/project/wiki.rb
features/steps/project/wiki.rb
+2
-0
features/steps/shared/issuable.rb
features/steps/shared/issuable.rb
+1
-3
features/support/wait_for_ajax.rb
features/support/wait_for_ajax.rb
+11
-0
lib/api/todos.rb
lib/api/todos.rb
+3
-5
lib/banzai/filter/sanitization_filter.rb
lib/banzai/filter/sanitization_filter.rb
+3
-1
lib/gitlab/checks/change_access.rb
lib/gitlab/checks/change_access.rb
+1
-1
scripts/prepare_build.sh
scripts/prepare_build.sh
+4
-3
spec/controllers/admin/groups_controller_spec.rb
spec/controllers/admin/groups_controller_spec.rb
+24
-0
spec/controllers/groups_controller_spec.rb
spec/controllers/groups_controller_spec.rb
+29
-0
spec/features/issuables/default_sort_order_spec.rb
spec/features/issuables/default_sort_order_spec.rb
+7
-7
spec/features/issues/filter_issues_spec.rb
spec/features/issues/filter_issues_spec.rb
+1
-1
spec/features/merge_requests/create_new_mr_spec.rb
spec/features/merge_requests/create_new_mr_spec.rb
+2
-0
spec/features/profiles/preferences_spec.rb
spec/features/profiles/preferences_spec.rb
+4
-0
spec/features/projects/files/project_owner_creates_license_file_spec.rb
...projects/files/project_owner_creates_license_file_spec.rb
+1
-0
spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
...sees_link_to_create_license_file_in_empty_project_spec.rb
+1
-0
spec/features/u2f_spec.rb
spec/features/u2f_spec.rb
+20
-12
spec/features/variables_spec.rb
spec/features/variables_spec.rb
+1
-0
spec/finders/projects_finder_spec.rb
spec/finders/projects_finder_spec.rb
+18
-55
spec/lib/gitlab/checks/change_access_spec.rb
spec/lib/gitlab/checks/change_access_spec.rb
+99
-0
spec/models/blob_spec.rb
spec/models/blob_spec.rb
+22
-0
spec/models/deployment_spec.rb
spec/models/deployment_spec.rb
+24
-0
spec/models/environment_spec.rb
spec/models/environment_spec.rb
+33
-0
spec/models/merge_request_spec.rb
spec/models/merge_request_spec.rb
+15
-0
spec/models/project_services/pivotaltracker_service_spec.rb
spec/models/project_services/pivotaltracker_service_spec.rb
+71
-0
spec/requests/api/todos_spec.rb
spec/requests/api/todos_spec.rb
+12
-0
spec/requests/api/users_spec.rb
spec/requests/api/users_spec.rb
+2
-0
spec/services/delete_user_service_spec.rb
spec/services/delete_user_service_spec.rb
+4
-2
spec/services/destroy_group_service_spec.rb
spec/services/destroy_group_service_spec.rb
+36
-22
spec/services/merge_requests/get_urls_service_spec.rb
spec/services/merge_requests/get_urls_service_spec.rb
+34
-0
spec/services/todo_service_spec.rb
spec/services/todo_service_spec.rb
+36
-0
spec/views/projects/merge_requests/_heading.html.haml_spec.rb
.../views/projects/merge_requests/_heading.html.haml_spec.rb
+26
-0
spec/workers/group_destroy_worker_spec.rb
spec/workers/group_destroy_worker_spec.rb
+19
-0
No files found.
.gitlab-ci.yml
View file @
35f9f79b
...
...
@@ -15,6 +15,7 @@ variables:
USE_DB
:
"
true"
USE_BUNDLE_INSTALL
:
"
true"
GIT_DEPTH
:
"
20"
PHANTOMJS_VERSION
:
"
2.1.1"
before_script
:
-
source ./scripts/prepare_build.sh
...
...
CHANGELOG
View file @
35f9f79b
...
...
@@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date.
v 8.11.0 (unreleased)
- Remove the http_parser.rb dependency by removing the tinder gem. !5758 (tbalthazar)
- Ability to specify branches for Pivotal Tracker integration (Egor Lynko)
- Fix don't pass a local variable called `i` to a partial. !20510 (herminiotorres)
- Fix rename `add_users_into_project` and `projects_ids`. !20512 (herminiotorres)
- Fix the title of the toggle dropdown button. !5515 (herminiotorres)
...
...
@@ -32,12 +33,14 @@ v 8.11.0 (unreleased)
- Add "No one can push" as an option for protected branches. !5081
- Improve performance of AutolinkFilter#text_parse by using XPath
- Add experimental Redis Sentinel support !1877
- Rendering of SVGs as blobs is now limited to SVGs with a size smaller or equal to 2MB
- Fix branches page dropdown sort initial state (ClemMakesApps)
- Environments have an url to link to
- Various redundant database indexes have been removed
- Update `timeago` plugin to use multiple string/locale settings
- Remove unused images (ClemMakesApps)
- Limit git rev-list output count to one in forced push check
- Show deployment status on merge requests with external URLs
- Clean up unused routes (Josef Strzibny)
- Fix issue on empty project to allow developers to only push to protected branches if given permission
- Add green outline to New Branch button. !5447 (winniehell)
...
...
@@ -54,6 +57,7 @@ v 8.11.0 (unreleased)
- Optimize checking if a user has read access to a list of issues !5370
- Store all DB secrets in secrets.yml, under descriptive names !5274
- Nokogiri's various parsing methods are now instrumented
- Add archived badge to project list !5798
- Add simple identifier to public SSH keys (muteor)
- Admin page now references docs instead of a specific file !5600 (AnAverageHuman)
- Add a way to send an email and create an issue based on private personal token. Find the email address from issues page. !3363
...
...
@@ -93,6 +97,7 @@ v 8.11.0 (unreleased)
- Bump gitlab_git to lazy load compare commits
- Reduce number of queries made for merge_requests/:id/diffs
- Sensible state specific default sort order for issues and merge requests !5453 (tomb0y)
- Fix bug where destroying a namespace would not always destroy projects
- Fix RequestProfiler::Middleware error when code is reloaded in development
- Catch what warden might throw when profiling requests to re-throw it
- Avoid commit lookup on diff_helper passing existing local variable to the helper method
...
...
@@ -106,6 +111,8 @@ v 8.11.0 (unreleased)
- Sort folders with submodules in Files view !5521
- Each `File::exists?` replaced to `File::exist?` because of deprecate since ruby version 2.2.0
- Add auto-completition in pipeline (Katarzyna Kobierska Ula Budziszewska)
- Fix a memory leak caused by Banzai::Filter::SanitizationFilter
- Speed up todos queries by limiting the projects set we join with
v 8.10.5
- Add a data migration to fix some missing timestamps in the members table. !5670
...
...
@@ -270,6 +277,7 @@ v 8.10.0
- Fix new snippet style bug (elliotec)
- Instrument Rinku usage
- Be explicit to define merge request discussion variables
- Use cache for todos counter calling TodoService
- Metrics for Rouge::Plugins::Redcarpet and Rouge::Formatters::HTMLGitlab
- RailsCache metris now includes fetch_hit/fetch_miss and read_hit/read_miss info.
- Allow [ci skip] to be in any case and allow [skip ci]. !4785 (simon_w)
...
...
app/assets/javascripts/issuable.js
View file @
35f9f79b
...
...
@@ -5,13 +5,10 @@
this
.
Issuable
=
{
init
:
function
()
{
if
(
!
issuable_created
)
{
issuable_created
=
true
;
Issuable
.
initTemplates
();
Issuable
.
initSearch
();
Issuable
.
initChecks
();
return
Issuable
.
initLabelFilterRemove
();
}
Issuable
.
initTemplates
();
Issuable
.
initSearch
();
Issuable
.
initChecks
();
return
Issuable
.
initLabelFilterRemove
();
},
initTemplates
:
function
()
{
return
Issuable
.
labelRow
=
_
.
template
(
'
<% _.each(labels, function(label){ %> <span class="label-row btn-group" role="group" aria-label="<%- label.title %>" style="color: <%- label.text_color %>;"> <a href="#" class="btn btn-transparent has-tooltip" style="background-color: <%- label.color %>;" title="<%- label.description %>" data-container="body"> <%- label.title %> </a> <button type="button" class="btn btn-transparent label-remove js-label-filter-remove" style="background-color: <%- label.color %>;" data-label="<%- label.title %>"> <i class="fa fa-times"></i> </button> </span> <% }); %>
'
);
...
...
app/assets/stylesheets/pages/merge_requests.scss
View file @
35f9f79b
...
...
@@ -69,6 +69,10 @@
&
.ci-success
{
color
:
$gl-success
;
a
.environment
{
color
:
inherit
;
}
}
&
.ci-success_with_warnings
{
...
...
@@ -126,7 +130,6 @@
&
.has-conflicts
.fa-exclamation-triangle
{
color
:
$gl-warning
;
}
}
p
:last-child
{
...
...
app/controllers/admin/groups_controller.rb
View file @
35f9f79b
...
...
@@ -48,9 +48,9 @@ class Admin::GroupsController < Admin::ApplicationController
end
def
destroy
DestroyGroupService
.
new
(
@group
,
current_user
).
execute
DestroyGroupService
.
new
(
@group
,
current_user
).
async_
execute
redirect_to
admin_groups_path
,
notice:
'Group was successfully deleted.'
redirect_to
admin_groups_path
,
alert:
"Group '
#{
@group
.
name
}
' was scheduled for deletion."
end
private
...
...
app/controllers/dashboard/todos_controller.rb
View file @
35f9f79b
...
...
@@ -37,8 +37,8 @@ class Dashboard::TodosController < Dashboard::ApplicationController
def
todos_counts
{
count:
TodosFinder
.
new
(
current_user
,
state: :pending
).
execute
.
count
,
done_count:
TodosFinder
.
new
(
current_user
,
state: :done
).
execute
.
count
count:
current_user
.
todos_pending_
count
,
done_count:
current_user
.
todos_done_
count
}
end
end
app/controllers/groups_controller.rb
View file @
35f9f79b
...
...
@@ -87,9 +87,9 @@ class GroupsController < Groups::ApplicationController
end
def
destroy
DestroyGroupService
.
new
(
@group
,
current_user
).
execute
DestroyGroupService
.
new
(
@group
,
current_user
).
async_
execute
redirect_to
root_path
,
alert:
"Group '
#{
@group
.
name
}
' was s
uccessfully deleted
."
redirect_to
root_path
,
alert:
"Group '
#{
@group
.
name
}
' was s
cheduled for deletion
."
end
protected
...
...
app/finders/projects_finder.rb
View file @
35f9f79b
class
ProjectsFinder
<
UnionFinder
def
execute
(
current_user
=
nil
,
options
=
{}
)
def
execute
(
current_user
=
nil
,
project_ids_relation
=
nil
)
segments
=
all_projects
(
current_user
)
segments
.
map!
{
|
s
|
s
.
where
(
id:
project_ids_relation
)
}
if
project_ids_relation
find_union
(
segments
,
Project
)
end
...
...
app/finders/todos_finder.rb
View file @
35f9f79b
...
...
@@ -27,9 +27,11 @@ class TodosFinder
items
=
by_action_id
(
items
)
items
=
by_action
(
items
)
items
=
by_author
(
items
)
items
=
by_project
(
items
)
items
=
by_state
(
items
)
items
=
by_type
(
items
)
# Filtering by project HAS TO be the last because we use
# the project IDs yielded by the todos query thus far
items
=
by_project
(
items
)
items
.
reorder
(
id: :desc
)
end
...
...
@@ -91,14 +93,9 @@ class TodosFinder
@project
end
def
projects
return
@projects
if
defined?
(
@projects
)
if
project?
@projects
=
project
else
@projects
=
ProjectsFinder
.
new
.
execute
(
current_user
)
end
def
projects
(
items
)
item_project_ids
=
items
.
reorder
(
nil
).
select
(
:project_id
)
ProjectsFinder
.
new
.
execute
(
current_user
,
item_project_ids
)
end
def
type?
...
...
@@ -136,8 +133,9 @@ class TodosFinder
def
by_project
(
items
)
if
project?
items
=
items
.
where
(
project:
project
)
elsif
projects
items
=
items
.
merge
(
projects
).
joins
(
:project
)
else
item_projects
=
projects
(
items
)
items
=
items
.
merge
(
item_projects
).
joins
(
:project
)
end
items
...
...
app/helpers/todos_helper.rb
View file @
35f9f79b
module
TodosHelper
def
todos_pending_count
@todos_pending_count
||=
TodosFinder
.
new
(
current_user
,
state: :pending
).
execute
.
count
@todos_pending_count
||=
current_user
.
todos_pending_
count
end
def
todos_done_count
@todos_done_count
||=
TodosFinder
.
new
(
current_user
,
state: :done
).
execute
.
count
@todos_done_count
||=
current_user
.
todos_done_
count
end
def
todo_action_name
(
todo
)
...
...
app/models/blob.rb
View file @
35f9f79b
...
...
@@ -3,6 +3,9 @@ class Blob < SimpleDelegator
CACHE_TIME
=
60
# Cache raw blobs referred to by a (mutable) ref for 1 minute
CACHE_TIME_IMMUTABLE
=
3600
# Cache blobs referred to by an immutable reference for 1 hour
# The maximum size of an SVG that can be displayed.
MAXIMUM_SVG_SIZE
=
2
.
megabytes
# Wrap a Gitlab::Git::Blob object, or return nil when given nil
#
# This method prevents the decorated object from evaluating to "truthy" when
...
...
@@ -31,6 +34,10 @@ class Blob < SimpleDelegator
text?
&&
language
&&
language
.
name
==
'SVG'
end
def
size_within_svg_limits?
size
<=
MAXIMUM_SVG_SIZE
end
def
video?
UploaderHelper
::
VIDEO_EXT
.
include?
(
extname
.
downcase
.
delete
(
'.'
))
end
...
...
app/models/deployment.rb
View file @
35f9f79b
...
...
@@ -36,4 +36,10 @@ class Deployment < ActiveRecord::Base
def
manual_actions
deployable
.
try
(
:other_actions
)
end
def
includes_commit?
(
commit
)
return
false
unless
commit
project
.
repository
.
is_ancestor?
(
commit
.
id
,
sha
)
end
end
app/models/environment.rb
View file @
35f9f79b
...
...
@@ -25,4 +25,10 @@ class Environment < ActiveRecord::Base
def
nullify_external_url
self
.
external_url
=
nil
if
self
.
external_url
.
blank?
end
def
includes_commit?
(
commit
)
return
false
unless
last_deployment
last_deployment
.
includes_commit?
(
commit
)
end
end
app/models/merge_request.rb
View file @
35f9f79b
...
...
@@ -591,6 +591,14 @@ class MergeRequest < ActiveRecord::Base
!
pipeline
||
pipeline
.
success?
end
def
environments
return
unless
diff_head_commit
target_project
.
environments
.
select
do
|
environment
|
environment
.
includes_commit?
(
diff_head_commit
)
end
end
def
state_human_name
if
merged?
"Merged"
...
...
app/models/namespace.rb
View file @
35f9f79b
class
Namespace
<
ActiveRecord
::
Base
acts_as_paranoid
include
Sortable
include
Gitlab
::
ShellAdapter
...
...
app/models/project_services/pivotaltracker_service.rb
View file @
35f9f79b
class
PivotaltrackerService
<
Service
include
HTTParty
prop_accessor
:token
API_ENDPOINT
=
'https://www.pivotaltracker.com/services/v5/source_commits'
prop_accessor
:token
,
:restrict_to_branch
validates
:token
,
presence:
true
,
if: :activated?
def
title
...
...
@@ -18,7 +20,17 @@ class PivotaltrackerService < Service
def
fields
[
{
type:
'text'
,
name:
'token'
,
placeholder:
''
}
{
type:
'text'
,
name:
'token'
,
placeholder:
'Pivotal Tracker API token.'
},
{
type:
'text'
,
name:
'restrict_to_branch'
,
placeholder:
'Comma-separated list of branches which will be '
\
'automatically inspected. Leave blank to include all branches.'
}
]
end
...
...
@@ -28,8 +40,8 @@ class PivotaltrackerService < Service
def
execute
(
data
)
return
unless
supported_events
.
include?
(
data
[
:object_kind
])
return
unless
allowed_branch?
(
data
[
:ref
])
url
=
'https://www.pivotaltracker.com/services/v5/source_commits'
data
[
:commits
].
each
do
|
commit
|
message
=
{
'source_commit'
=>
{
...
...
@@ -40,7 +52,7 @@ class PivotaltrackerService < Service
}
}
PivotaltrackerService
.
post
(
url
,
API_ENDPOINT
,
body:
message
.
to_json
,
headers:
{
'Content-Type'
=>
'application/json'
,
...
...
@@ -49,4 +61,15 @@ class PivotaltrackerService < Service
)
end
end
private
def
allowed_branch?
(
ref
)
return
true
unless
ref
.
present?
&&
restrict_to_branch
.
present?
branch
=
Gitlab
::
Git
.
ref_name
(
ref
)
allowed_branches
=
restrict_to_branch
.
split
(
','
).
map
(
&
:strip
)
branch
.
present?
&&
allowed_branches
.
include?
(
branch
)
end
end
app/models/user.rb
View file @
35f9f79b
...
...
@@ -809,13 +809,13 @@ class User < ActiveRecord::Base
def
todos_done_count
(
force:
false
)
Rails
.
cache
.
fetch
([
'users'
,
id
,
'todos_done_count'
],
force:
force
)
do
todos
.
don
e
.
count
TodosFinder
.
new
(
self
,
state: :done
).
execut
e
.
count
end
end
def
todos_pending_count
(
force:
false
)
Rails
.
cache
.
fetch
([
'users'
,
id
,
'todos_pending_count'
],
force:
force
)
do
todos
.
pending
.
count
TodosFinder
.
new
(
self
,
state: :pending
).
execute
.
count
end
end
...
...
app/services/delete_user_service.rb
View file @
35f9f79b
...
...
@@ -21,6 +21,11 @@ class DeleteUserService
::
Projects
::
DestroyService
.
new
(
project
,
current_user
,
skip_repo:
true
).
async_execute
end
user
.
destroy
# Destroy the namespace after destroying the user since certain methods may depend on the namespace existing
namespace
=
user
.
namespace
user_data
=
user
.
destroy
namespace
.
really_destroy!
user_data
end
end
app/services/destroy_group_service.rb
View file @
35f9f79b
...
...
@@ -5,13 +5,23 @@ class DestroyGroupService
@group
,
@current_user
=
group
,
user
end
def
async_execute
group
.
transaction
do
# Soft delete via paranoia gem
group
.
destroy
job_id
=
GroupDestroyWorker
.
perform_async
(
group
.
id
,
current_user
.
id
)
Rails
.
logger
.
info
(
"User
#{
current_user
.
id
}
scheduled a deletion of group ID
#{
group
.
id
}
with job ID
#{
job_id
}
"
)
end
end
def
execute
group
.
projects
.
each
do
|
project
|
# Execute the destruction of the models immediately to ensure atomic cleanup.
# Skip repository removal because we remove directory with namespace
# that contain all th
is
repositories
::
Projects
::
DestroyService
.
new
(
project
,
current_user
,
skip_repo:
true
).
async_
execute
# that contain all th
ese
repositories
::
Projects
::
DestroyService
.
new
(
project
,
current_user
,
skip_repo:
true
).
execute
end
group
.
destroy
group
.
really_destroy!
end
end
app/services/merge_requests/get_urls_service.rb
View file @
35f9f79b
...
...
@@ -30,10 +30,21 @@ module MergeRequests
end
def
get_branches
(
changes
)
return
[]
if
project
.
empty_repo?
return
[]
unless
project
.
merge_requests_enabled
changes_list
=
Gitlab
::
ChangesList
.
new
(
changes
)
changes_list
.
map
do
|
change
|
next
unless
Gitlab
::
Git
.
branch_ref?
(
change
[
:ref
])
Gitlab
::
Git
.
branch_name
(
change
[
:ref
])
# Deleted branch
next
if
Gitlab
::
Git
.
blank_ref?
(
change
[
:newrev
])
# Default branch
branch_name
=
Gitlab
::
Git
.
branch_name
(
change
[
:ref
])
next
if
branch_name
==
project
.
default_branch
branch_name
end
.
compact
end
...
...
app/services/todo_service.rb
View file @
35f9f79b
...
...
@@ -144,8 +144,9 @@ class TodoService
def
mark_todos_as_done
(
todos
,
current_user
)
todos
=
current_user
.
todos
.
where
(
id:
todos
.
map
(
&
:id
))
unless
todos
.
respond_to?
(
:update_all
)
todos
.
update_all
(
state: :done
)
marked_todos
=
todos
.
update_all
(
state: :done
)
current_user
.
update_todos_count_cache
marked_todos
end
# When user marks an issue as todo
...
...
app/views/projects/blob/_image.html.haml
View file @
35f9f79b
.file-content.image_file
-
if
blob
.
svg?
-
# We need to scrub SVG but we cannot do so in the RawController: it would
-
# be wrong/strange if RawController modified the data.
-
blob
.
load_all_data!
(
@repository
)
-
blob
=
sanitize_svg
(
blob
)
%img
{
src:
"data:#{blob.mime_type};base64,#{Base64.encode64(blob.data)}"
}
-
if
blob
.
size_within_svg_limits?
-
# We need to scrub SVG but we cannot do so in the RawController: it would
-
# be wrong/strange if RawController modified the data.
-
blob
.
load_all_data!
(
@repository
)
-
blob
=
sanitize_svg
(
blob
)
%img
{
src:
"data:#{blob.mime_type};base64,#{Base64.encode64(blob.data)}"
}
-
else
.nothing-here-block
The SVG could not be displayed as it is too large, you can
#{
link_to
(
'view the raw file'
,
namespace_project_raw_path
(
@project
.
namespace
,
@project
,
@id
),
target:
'_blank'
)
}
instead.
-
else
%img
{
src:
namespace_project_raw_path
(
@project
.
namespace
,
@project
,
tree_join
(
@commit
.
id
,
blob
.
path
))}
app/views/projects/merge_requests/widget/_heading.html.haml
View file @
35f9f79b
...
...
@@ -42,3 +42,16 @@
.ci_widget.ci-error
{
style:
"display:none"
}
=
icon
(
"times-circle"
)
Could not connect to the CI server. Please check your settings and try again.
-
@merge_request
.
environments
.
each
do
|
environment
|
.mr-widget-heading
.ci_widget.ci-success
=
ci_icon_for_status
(
"success"
)
%span
.hidden-sm
Deployed to
=
succeed
'.'
do
=
link_to
environment
.
name
,
namespace_project_environment_path
(
@project
.
namespace
,
@project
,
environment
),
class:
'environment'
-
external_url
=
environment
.
external_url
-
if
external_url
=
link_to
external_url
,
target:
'_blank'
do
=
icon
(
'external-link'
,
text:
"View on
#{
external_url
.
gsub
(
/\A.*?:\/\//
,
''
)
}
"
,
right:
true
)
app/views/shared/projects/_project.html.haml
View file @
35f9f79b
...
...
@@ -12,6 +12,8 @@
%li
.project-row
{
class:
css_class
}
=
cache
(
cache_key
)
do
.controls
-
if
project
.
archived
%span
.label.label-warning
archived
-
if
project
.
commit
.
try
(
:status
)
%span
=
render_commit_status
(
project
.
commit
)
...
...
app/workers/group_destroy_worker.rb
0 → 100644
View file @
35f9f79b
class
GroupDestroyWorker
include
Sidekiq
::
Worker
sidekiq_options
queue: :default
def
perform
(
group_id
,
user_id
)
begin
group
=
Group
.
with_deleted
.
find
(
group_id
)
rescue
ActiveRecord
::
RecordNotFound
return
end
user
=
User
.
find
(
user_id
)
DestroyGroupService
.
new
(
group
,
user
).
execute
end
end
db/migrate/20140407135544_fix_namespaces.rb
View file @
35f9f79b
# rubocop:disable all
class
FixNamespaces
<
ActiveRecord
::
Migration
DOWNTIME
=
false
def
up
Namespace
.
where
(
'name <> path and type is null'
).
each
do
|
namespace
|
namespace
.
update_attribute
(
:name
,
namespace
.
path
)
namespaces
=
exec_query
(
'SELECT id, path FROM namespaces WHERE name <> path and type is null'
)
namespaces
.
each
do
|
row
|
id
=
row
[
'id'
]
path
=
row
[
'path'
]
exec_query
(
"UPDATE namespaces SET name = '
#{
path
}
' WHERE id =
#{
id
}
"
)
end
end
...
...
db/migrate/20160805041956_add_deleted_at_to_namespaces.rb
0 → 100644
View file @
35f9f79b
class
AddDeletedAtToNamespaces
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
disable_ddl_transaction!
def
change
add_column
:namespaces
,
:deleted_at
,
:datetime
add_concurrent_index
:namespaces
,
:deleted_at
end
end
db/schema.rb
View file @
35f9f79b
...
...
@@ -589,12 +589,12 @@ ActiveRecord::Schema.define(version: 20160810142633) do
t
.
datetime
"locked_at"
t
.
integer
"updated_by_id"
t
.
string
"merge_error"
t
.
text
"merge_params"
t
.
boolean
"merge_when_build_succeeds"
,
default:
false
,
null:
false
t
.
integer
"merge_user_id"
t
.
string
"merge_commit_sha"
t
.
datetime
"deleted_at"
t
.
string
"in_progress_merge_commit_sha"
t
.
text
"merge_params"
end
add_index
"merge_requests"
,
[
"assignee_id"
],
name:
"index_merge_requests_on_assignee_id"
,
using: :btree
...
...
@@ -640,9 +640,11 @@ ActiveRecord::Schema.define(version: 20160810142633) do
t
.
boolean
"share_with_group_lock"
,
default:
false
t
.
integer
"visibility_level"
,
default:
20
,
null:
false
t
.
boolean
"request_access_enabled"
,
default:
true
,
null:
false
t
.
datetime
"deleted_at"
end
add_index
"namespaces"
,
[
"created_at"
],
name:
"index_namespaces_on_created_at"
,
using: :btree
add_index
"namespaces"
,
[
"deleted_at"
],
name:
"index_namespaces_on_deleted_at"
,
using: :btree
add_index
"namespaces"
,
[
"name"
],
name:
"index_namespaces_on_name"
,
unique:
true
,
using: :btree
add_index
"namespaces"
,
[
"name"
],
name:
"index_namespaces_on_name_trigram"
,
using: :gin
,
opclasses:
{
"name"
=>
"gin_trgm_ops"
}
add_index
"namespaces"
,
[
"owner_id"
],
name:
"index_namespaces_on_owner_id"
,
using: :btree
...
...
doc/api/services.md
View file @
35f9f79b
...
...
@@ -355,7 +355,7 @@ PUT /projects/:id/services/gemnasium
Parameters:
-
`api_key`
(
**required**
) - Your personal API KEY on gemnasium.com
-
`api_key`
(
**required**
) - Your personal API KEY on gemnasium.com
-
`token`
(
**required**
) - The project's slug on gemnasium.com
### Delete Gemnasium service
...
...
@@ -503,6 +503,7 @@ PUT /projects/:id/services/pivotaltracker
Parameters:
-
`token`
(
**required**
)
-
`restrict_to_branch`
(optional) - Comma-separated list of branches which will be automatically inspected. Leave blank to include all branches.
### Delete PivotalTracker service
...
...
@@ -661,4 +662,3 @@ Get JetBrains TeamCity CI service settings for a project.
```
GET /projects/:id/services/teamcity
```
features/steps/dashboard/dashboard.rb
View file @
35f9f79b
...
...
@@ -26,6 +26,7 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps
end
step
'I see prefilled new Merge Request page'
do
expect
(
page
).
to
have_selector
(
'.merge-request-form'
)
expect
(
current_path
).
to
eq
new_namespace_project_merge_request_path
(
@project
.
namespace
,
@project
)
expect
(
find
(
"#merge_request_target_project_id"
).
value
).
to
eq
@project
.
id
.
to_s
expect
(
find
(
"input#merge_request_source_branch"
).
value
).
to
eq
"fix"
...
...
features/steps/dashboard/event_filters.rb
View file @
35f9f79b
class
Spinach::Features::EventFilters
<
Spinach
::
FeatureSteps
include
WaitForAjax
include
SharedAuthentication
include
SharedPaths
include
SharedProject
...
...
@@ -72,14 +73,20 @@ class Spinach::Features::EventFilters < Spinach::FeatureSteps
end
When
'I click "push" event filter'
do
click_link
(
"push_event_filter"
)
wait_for_ajax
click_link
(
"Push events"
)
wait_for_ajax
end
When
'I click "team" event filter'
do
click_link
(
"team_event_filter"
)
wait_for_ajax
click_link
(
"Team"
)
wait_for_ajax
end
When
'I click "merge" event filter'
do
click_link
(
"merged_event_filter"
)
wait_for_ajax
click_link
(
"Merge events"
)
wait_for_ajax
end
end
features/steps/dashboard/issues.rb
View file @
35f9f79b
...
...
@@ -43,9 +43,14 @@ class Spinach::Features::DashboardIssues < Spinach::FeatureSteps
step
'I click "All" link'
do
find
(
".js-author-search"
).
click
expect
(
page
).
to
have_selector
(
".dropdown-menu-author li a"
)
find
(
".dropdown-menu-author li a"
,
match: :first
).
click
expect
(
page
).
not_to
have_selector
(
".dropdown-menu-author li a"
)
find
(
".js-assignee-search"
).
click
expect
(
page
).
to
have_selector
(
".dropdown-menu-assignee li a"
)
find
(
".dropdown-menu-assignee li a"
,
match: :first
).
click
expect
(
page
).
not_to
have_selector
(
".dropdown-menu-assignee li a"
)
end
def
should_see
(
issue
)
...
...
features/steps/dashboard/merge_requests.rb
View file @
35f9f79b
...
...
@@ -47,9 +47,14 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps
step
'I click "All" link'
do
find
(
".js-author-search"
).
click
expect
(
page
).
to
have_selector
(
".dropdown-menu-author li a"
)
find
(
".dropdown-menu-author li a"
,
match: :first
).
click
expect
(
page
).
not_to
have_selector
(
".dropdown-menu-author li a"
)
find
(
".js-assignee-search"
).
click
expect
(
page
).
to
have_selector
(
".dropdown-menu-assignee li a"
)
find
(
".dropdown-menu-assignee li a"
,
match: :first
).
click
expect
(
page
).
not_to
have_selector
(
".dropdown-menu-assignee li a"
)
end
def
should_see
(
merge_request
)
...
...
features/steps/dashboard/new_project.rb
View file @
35f9f79b
...
...
@@ -29,6 +29,7 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps
end
step
'I am redirected to the GitHub import page'
do
expect
(
page
).
to
have_content
(
'Import Projects from GitHub'
)
expect
(
current_path
).
to
eq
new_import_github_path
end
...
...
@@ -47,6 +48,7 @@ class Spinach::Features::NewProject < Spinach::FeatureSteps
end
step
'I redirected to Google Code import page'
do
expect
(
page
).
to
have_content
(
'Import projects from Google Code'
)
expect
(
current_path
).
to
eq
new_import_google_code_path
end
end
features/steps/project/builds/artifacts.rb
View file @
35f9f79b
...
...
@@ -10,6 +10,7 @@ class Spinach::Features::ProjectBuildsArtifacts < Spinach::FeatureSteps
step
'I click artifacts browse button'
do
click_link
'Browse'
expect
(
page
).
not_to
have_selector
(
'.build-sidebar'
)
end
step
'I should see content of artifacts archive'
do
...
...
features/steps/project/forked_merge_requests.rb
View file @
35f9f79b
...
...
@@ -34,6 +34,9 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps
end
step
'I fill out a "Merge Request On Forked Project" merge request'
do
expect
(
page
).
to
have_content
(
'Source branch'
)
expect
(
page
).
to
have_content
(
'Target branch'
)
first
(
'.js-source-project'
).
click
first
(
'.dropdown-source-project a'
,
text:
@forked_project
.
path_with_namespace
)
...
...
features/steps/project/issues/issues.rb
View file @
35f9f79b
...
...
@@ -354,6 +354,8 @@ class Spinach::Features::ProjectIssues < Spinach::FeatureSteps
end
def
filter_issue
(
text
)
sleep
1
fill_in
'issue_search'
,
with:
text
sleep
1
end
end
features/steps/project/merge_requests.rb
View file @
35f9f79b
...
...
@@ -489,10 +489,12 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
end
step
'I fill in merge request search with "Fe"'
do
sleep
1
fill_in
'issue_search'
,
with:
"Fe"
end
step
'I click the "Target branch" dropdown'
do
expect
(
page
).
to
have_content
(
'Target branch'
)
first
(
'.target_branch'
).
click
end
...
...
features/steps/project/source/browse_files.rb
View file @
35f9f79b
...
...
@@ -69,6 +69,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
end
step
'I edit code'
do
expect
(
page
).
to
have_selector
(
'.file-editor'
)
set_new_content
end
...
...
@@ -131,6 +132,7 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
step
'I click on "New file" link in repo'
do
find
(
'.add-to-tree'
).
click
click_link
'New file'
expect
(
page
).
to
have_selector
(
'.file-editor'
)
end
step
'I click on "Upload file" link in repo'
do
...
...
features/steps/project/wiki.rb
View file @
35f9f79b
...
...
@@ -142,7 +142,9 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps
end
step
'I edit the Wiki page with a path'
do
expect
(
page
).
to
have_content
(
'three'
)
click_on
'three'
expect
(
find
(
'.nav-text'
)).
to
have_content
(
'Three'
)
click_on
'Edit'
end
...
...
features/steps/shared/issuable.rb
View file @
35f9f79b
...
...
@@ -133,9 +133,7 @@ module SharedIssuable
end
step
'The list should be sorted by "Oldest updated"'
do
page
.
within
(
'.content div.dropdown.inline.prepend-left-10'
)
do
expect
(
page
.
find
(
'button.dropdown-toggle.btn'
)).
to
have_content
(
'Oldest updated'
)
end
expect
(
find
(
'.issues-filters'
)).
to
have_content
(
'Oldest updated'
)
end
step
'I click link "Next" in the sidebar'
do
...
...
features/support/wait_for_ajax.rb
0 → 100644
View file @
35f9f79b
module
WaitForAjax
def
wait_for_ajax
Timeout
.
timeout
(
Capybara
.
default_max_wait_time
)
do
loop
until
finished_all_ajax_requests?
end
end
def
finished_all_ajax_requests?
page
.
evaluate_script
(
'jQuery.active'
).
zero?
end
end
lib/api/todos.rb
View file @
35f9f79b
...
...
@@ -61,9 +61,9 @@ module API
#
delete
':id'
do
todo
=
current_user
.
todos
.
find
(
params
[
:id
])
todo
.
done
TodoService
.
new
.
mark_todos_as_done
([
todo
],
current_user
)
present
todo
,
with:
Entities
::
Todo
,
current_user:
current_user
present
todo
.
reload
,
with:
Entities
::
Todo
,
current_user:
current_user
end
# Mark all todos as done
...
...
@@ -73,9 +73,7 @@ module API
#
delete
do
todos
=
find_todos
todos
.
each
(
&
:done
)
todos
.
length
TodoService
.
new
.
mark_todos_as_done
(
todos
,
current_user
)
end
end
end
...
...
lib/banzai/filter/sanitization_filter.rb
View file @
35f9f79b
...
...
@@ -7,7 +7,7 @@ module Banzai
UNSAFE_PROTOCOLS
=
%w(data javascript vbscript)
.
freeze
def
whitelist
whitelist
=
super
whitelist
=
super
.
dup
customize_whitelist
(
whitelist
)
...
...
@@ -42,6 +42,8 @@ module Banzai
# Allow any protocol in `a` elements...
whitelist
[
:protocols
].
delete
(
'a'
)
whitelist
[
:transformers
]
=
whitelist
[
:transformers
].
dup
# ...but then remove links with unsafe protocols
whitelist
[
:transformers
].
push
(
remove_unsafe_links
)
...
...
lib/gitlab/checks/change_access.rb
View file @
35f9f79b
...
...
@@ -11,7 +11,7 @@ module Gitlab
end
def
exec
error
=
p
rotected_branch_checks
||
tag_checks
||
pus
h_checks
error
=
p
ush_checks
||
tag_checks
||
protected_branc
h_checks
if
error
GitAccessStatus
.
new
(
false
,
error
)
...
...
scripts/prepare_build.sh
View file @
35f9f79b
...
...
@@ -20,10 +20,11 @@ if [ -f /.dockerenv ] || [ -f ./dockerinit ]; then
# Install phantomjs package
pushd
vendor/apt
if
[
!
-e
phantomjs_1.9.8-0jessie_amd64.deb
]
;
then
wget
-q
https://gitlab.com/axil/phantomjs-debian/raw/master/phantomjs_1.9.8-0jessie_amd64.deb
PHANTOMJS_FILE
=
"phantomjs-
$PHANTOMJS_VERSION
-linux-x86_64"
if
[
!
-d
"
$PHANTOMJS_FILE
"
]
;
then
curl
-q
-L
"https://s3.amazonaws.com/gitlab-build-helpers/
$PHANTOMJS_FILE
.tar.bz2"
|
tar
jx
fi
dpkg
-i
phantomjs_1.9.8-0jessie_amd64.deb
cp
"
$PHANTOMJS_FILE
/bin/phantomjs"
"/usr/bin/"
popd
# Try to install packages
...
...
spec/controllers/admin/groups_controller_spec.rb
0 → 100644
View file @
35f9f79b
require
'spec_helper'
describe
Admin
::
GroupsController
do
let
(
:group
)
{
create
(
:group
)
}
let
(
:project
)
{
create
(
:project
,
namespace:
group
)
}
let
(
:admin
)
{
create
(
:admin
)
}
before
do
sign_in
(
admin
)
Sidekiq
::
Testing
.
fake!
end
describe
'DELETE #destroy'
do
it
'schedules a group destroy'
do
expect
{
delete
:destroy
,
id:
project
.
group
.
path
}.
to
change
(
GroupDestroyWorker
.
jobs
,
:size
).
by
(
1
)
end
it
'redirects to the admin group path'
do
delete
:destroy
,
id:
project
.
group
.
path
expect
(
response
).
to
redirect_to
(
admin_groups_path
)
end
end
end
spec/controllers/groups_controller_spec.rb
View file @
35f9f79b
...
...
@@ -75,4 +75,33 @@ describe GroupsController do
end
end
end
describe
'DELETE #destroy'
do
context
'as another user'
do
it
'returns 404'
do
sign_in
(
create
(
:user
))
delete
:destroy
,
id:
group
.
path
expect
(
response
.
status
).
to
eq
(
404
)
end
end
context
'as the group owner'
do
before
do
Sidekiq
::
Testing
.
fake!
sign_in
(
user
)
end
it
'schedules a group destroy'
do
expect
{
delete
:destroy
,
id:
group
.
path
}.
to
change
(
GroupDestroyWorker
.
jobs
,
:size
).
by
(
1
)
end
it
'redirects to the root path'
do
delete
:destroy
,
id:
group
.
path
expect
(
response
).
to
redirect_to
(
root_path
)
end
end
end
end
spec/features/issuables/default_sort_order_spec.rb
View file @
35f9f79b
...
...
@@ -55,7 +55,7 @@ describe 'Projects > Issuables > Default sort order', feature: true do
it
'is "last updated"'
do
visit_merge_requests_with_state
(
project
,
'merged'
)
expect
(
selected_sort_order
).
to
eq
(
'l
ast updated'
)
expect
(
find
(
'.issues-other-filters'
)).
to
have_content
(
'L
ast updated'
)
expect
(
first_merge_request
).
to
include
(
last_updated_issuable
.
title
)
expect
(
last_merge_request
).
to
include
(
first_updated_issuable
.
title
)
end
...
...
@@ -67,7 +67,7 @@ describe 'Projects > Issuables > Default sort order', feature: true do
it
'is "last updated"'
do
visit_merge_requests_with_state
(
project
,
'closed'
)
expect
(
selected_sort_order
).
to
eq
(
'l
ast updated'
)
expect
(
find
(
'.issues-other-filters'
)).
to
have_content
(
'L
ast updated'
)
expect
(
first_merge_request
).
to
include
(
last_updated_issuable
.
title
)
expect
(
last_merge_request
).
to
include
(
first_updated_issuable
.
title
)
end
...
...
@@ -79,7 +79,7 @@ describe 'Projects > Issuables > Default sort order', feature: true do
it
'is "last created"'
do
visit_merge_requests_with_state
(
project
,
'all'
)
expect
(
selected_sort_order
).
to
eq
(
'l
ast created'
)
expect
(
find
(
'.issues-other-filters'
)).
to
have_content
(
'L
ast created'
)
expect
(
first_merge_request
).
to
include
(
last_created_issuable
.
title
)
expect
(
last_merge_request
).
to
include
(
first_created_issuable
.
title
)
end
...
...
@@ -108,7 +108,7 @@ describe 'Projects > Issuables > Default sort order', feature: true do
it
'is "last created"'
do
visit_issues
project
expect
(
selected_sort_order
).
to
eq
(
'l
ast created'
)
expect
(
find
(
'.issues-other-filters'
)).
to
have_content
(
'L
ast created'
)
expect
(
first_issue
).
to
include
(
last_created_issuable
.
title
)
expect
(
last_issue
).
to
include
(
first_created_issuable
.
title
)
end
...
...
@@ -120,7 +120,7 @@ describe 'Projects > Issuables > Default sort order', feature: true do
it
'is "last created"'
do
visit_issues_with_state
(
project
,
'open'
)
expect
(
selected_sort_order
).
to
eq
(
'l
ast created'
)
expect
(
find
(
'.issues-other-filters'
)).
to
have_content
(
'L
ast created'
)
expect
(
first_issue
).
to
include
(
last_created_issuable
.
title
)
expect
(
last_issue
).
to
include
(
first_created_issuable
.
title
)
end
...
...
@@ -132,7 +132,7 @@ describe 'Projects > Issuables > Default sort order', feature: true do
it
'is "last updated"'
do
visit_issues_with_state
(
project
,
'closed'
)
expect
(
selected_sort_order
).
to
eq
(
'l
ast updated'
)
expect
(
find
(
'.issues-other-filters'
)).
to
have_content
(
'L
ast updated'
)
expect
(
first_issue
).
to
include
(
last_updated_issuable
.
title
)
expect
(
last_issue
).
to
include
(
first_updated_issuable
.
title
)
end
...
...
@@ -144,7 +144,7 @@ describe 'Projects > Issuables > Default sort order', feature: true do
it
'is "last created"'
do
visit_issues_with_state
(
project
,
'all'
)
expect
(
selected_sort_order
).
to
eq
(
'l
ast created'
)
expect
(
find
(
'.issues-other-filters'
)).
to
have_content
(
'L
ast created'
)
expect
(
first_issue
).
to
include
(
last_created_issuable
.
title
)
expect
(
last_issue
).
to
include
(
first_created_issuable
.
title
)
end
...
...
spec/features/issues/filter_issues_spec.rb
View file @
35f9f79b
...
...
@@ -117,7 +117,7 @@ describe 'Filter issues', feature: true do
find
(
'.dropdown-menu-user-link'
,
text:
user
.
username
).
click
wait_for_ajax
expect
(
page
).
not_to
have_selector
(
'.issues-list .issue'
)
find
(
'.js-label-select'
).
click
...
...
spec/features/merge_requests/create_new_mr_spec.rb
View file @
35f9f79b
...
...
@@ -13,6 +13,8 @@ feature 'Create New Merge Request', feature: true, js: true do
it
'generates a diff for an orphaned branch'
do
click_link
'New Merge Request'
expect
(
page
).
to
have_content
(
'Source branch'
)
expect
(
page
).
to
have_content
(
'Target branch'
)
first
(
'.js-source-branch'
).
click
first
(
'.dropdown-source-branch .dropdown-content a'
,
text:
'orphaned-branch'
).
click
...
...
spec/features/profiles/preferences_spec.rb
View file @
35f9f79b
...
...
@@ -68,10 +68,14 @@ describe 'Profile > Preferences', feature: true do
allowing_for_delay
do
find
(
'#logo'
).
click
expect
(
page
).
to
have_content
(
"You don't have starred projects yet"
)
expect
(
page
.
current_path
).
to
eq
starred_dashboard_projects_path
end
click_link
'Your Projects'
expect
(
page
).
not_to
have_content
(
"You don't have starred projects yet"
)
expect
(
page
.
current_path
).
to
eq
dashboard_projects_path
end
end
...
...
spec/features/projects/files/project_owner_creates_license_file_spec.rb
View file @
35f9f79b
...
...
@@ -39,6 +39,7 @@ feature 'project owner creates a license file', feature: true, js: true do
scenario
'project master creates a license file from the "Add license" link'
do
click_link
'Add License'
expect
(
page
).
to
have_content
(
'New File'
)
expect
(
current_path
).
to
eq
(
namespace_project_new_blob_path
(
project
.
namespace
,
project
,
'master'
))
expect
(
find
(
'#file_name'
).
value
).
to
eq
(
'LICENSE'
)
...
...
spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
View file @
35f9f79b
...
...
@@ -14,6 +14,7 @@ feature 'project owner sees a link to create a license file in empty project', f
visit
namespace_project_path
(
project
.
namespace
,
project
)
click_link
'Create empty bare repository'
click_on
'LICENSE'
expect
(
page
).
to
have_content
(
'New File'
)
expect
(
current_path
).
to
eq
(
namespace_project_new_blob_path
(
project
.
namespace
,
project
,
'master'
))
...
...
spec/features/u2f_spec.rb
View file @
35f9f79b
require
'spec_helper'
feature
'Using U2F (Universal 2nd Factor) Devices for Authentication'
,
feature:
true
,
js:
true
do
include
WaitForAjax
before
{
allow_any_instance_of
(
U2fHelper
).
to
receive
(
:inject_u2f_api?
).
and_return
(
true
)
}
def
manage_two_factor_authentication
click_on
'Manage Two-Factor Authentication'
expect
(
page
).
to
have_content
(
"Setup New U2F Device"
)
wait_for_ajax
end
def
register_u2f_device
(
u2f_device
=
nil
)
u2f_device
||=
FakeU2fDevice
.
new
(
page
)
u2f_device
.
respond_to_u2f_registration
...
...
@@ -34,7 +42,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
describe
'when 2FA via OTP is enabled'
do
it
'allows registering a new device'
do
visit
profile_account_path
click_on
'Manage Two-Factor Authentication'
manage_two_factor_authentication
expect
(
page
.
body
).
to
match
(
"You've already enabled two-factor authentication using mobile"
)
register_u2f_device
...
...
@@ -46,15 +54,15 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
visit
profile_account_path
# First device
click_on
'Manage Two-Factor Authentication'
manage_two_factor_authentication
register_u2f_device
expect
(
page
.
body
).
to
match
(
'Your U2F device was registered'
)
# Second device
click_on
'Manage Two-Factor Authentication'
manage_two_factor_authentication
register_u2f_device
expect
(
page
.
body
).
to
match
(
'Your U2F device was registered'
)
click_on
'Manage Two-Factor Authentication'
manage_two_factor_authentication
expect
(
page
.
body
).
to
match
(
'You have 2 U2F devices registered'
)
end
end
...
...
@@ -62,7 +70,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
it
'allows the same device to be registered for multiple users'
do
# First user
visit
profile_account_path
click_on
'Manage Two-Factor Authentication'
manage_two_factor_authentication
u2f_device
=
register_u2f_device
expect
(
page
.
body
).
to
match
(
'Your U2F device was registered'
)
logout
...
...
@@ -71,7 +79,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
user
=
login_as
(
:user
)
user
.
update_attribute
(
:otp_required_for_login
,
true
)
visit
profile_account_path
click_on
'Manage Two-Factor Authentication'
manage_two_factor_authentication
register_u2f_device
(
u2f_device
)
expect
(
page
.
body
).
to
match
(
'Your U2F device was registered'
)
...
...
@@ -81,7 +89,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
context
"when there are form errors"
do
it
"doesn't register the device if there are errors"
do
visit
profile_account_path
click_on
'Manage Two-Factor Authentication'
manage_two_factor_authentication
# Have the "u2f device" respond with bad data
page
.
execute_script
(
"u2f.register = function(_,_,_,callback) { callback('bad response'); };"
)
...
...
@@ -96,7 +104,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
it
"allows retrying registration"
do
visit
profile_account_path
click_on
'Manage Two-Factor Authentication'
manage_two_factor_authentication
# Failed registration
page
.
execute_script
(
"u2f.register = function(_,_,_,callback) { callback('bad response'); };"
)
...
...
@@ -122,7 +130,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
login_as
(
user
)
user
.
update_attribute
(
:otp_required_for_login
,
true
)
visit
profile_account_path
click_on
'Manage Two-Factor Authentication'
manage_two_factor_authentication
@u2f_device
=
register_u2f_device
logout
end
...
...
@@ -161,7 +169,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
current_user
=
login_as
(
:user
)
current_user
.
update_attribute
(
:otp_required_for_login
,
true
)
visit
profile_account_path
click_on
'Manage Two-Factor Authentication'
manage_two_factor_authentication
register_u2f_device
logout
...
...
@@ -182,7 +190,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
current_user
=
login_as
(
:user
)
current_user
.
update_attribute
(
:otp_required_for_login
,
true
)
visit
profile_account_path
click_on
'Manage Two-Factor Authentication'
manage_two_factor_authentication
register_u2f_device
(
@u2f_device
)
logout
...
...
@@ -248,7 +256,7 @@ feature 'Using U2F (Universal 2nd Factor) Devices for Authentication', feature:
user
=
login_as
(
:user
)
user
.
update_attribute
(
:otp_required_for_login
,
true
)
visit
profile_account_path
click_on
'Manage Two-Factor Authentication'
manage_two_factor_authentication
expect
(
page
).
to
have_content
(
"Your U2F device needs to be set up."
)
register_u2f_device
end
...
...
spec/features/variables_spec.rb
View file @
35f9f79b
...
...
@@ -42,6 +42,7 @@ describe 'Project variables', js: true do
find
(
'.btn-variable-edit'
).
click
end
expect
(
page
).
to
have_content
(
'Update variable'
)
fill_in
(
'variable_key'
,
with:
'key'
)
fill_in
(
'variable_value'
,
with:
'key value'
)
click_button
(
'Save variable'
)
...
...
spec/finders/projects_finder_spec.rb
View file @
35f9f79b
...
...
@@ -23,73 +23,36 @@ describe ProjectsFinder do
let
(
:finder
)
{
described_class
.
new
}
describe
'without a group'
do
describe
'without a user'
do
subject
{
finder
.
execute
}
describe
'without a user'
do
subject
{
finder
.
execute
}
it
{
is_expected
.
to
eq
([
public_project
])
}
end
describe
'with a user'
do
subject
{
finder
.
execute
(
user
)
}
describe
'without private projects'
do
it
{
is_expected
.
to
eq
([
public_project
,
internal_project
])
}
end
describe
'with private projects'
do
before
do
private_project
.
team
.
add_user
(
user
,
Gitlab
::
Access
::
MASTER
)
end
it
do
is_expected
.
to
eq
([
public_project
,
internal_project
,
private_project
])
end
end
end
it
{
is_expected
.
to
eq
([
public_project
])
}
end
describe
'with a group'
do
describe
'without a user'
do
subject
{
finder
.
execute
(
nil
,
group:
group
)
}
describe
'with a user'
do
subject
{
finder
.
execute
(
user
)
}
it
{
is_expected
.
to
eq
([
public_project
])
}
describe
'without private projects'
do
it
{
is_expected
.
to
eq
([
public_project
,
internal_project
])
}
end
describe
'with a user'
do
subject
{
finder
.
execute
(
user
,
group:
group
)
}
describe
'without shared projects'
do
it
{
is_expected
.
to
eq
([
public_project
,
internal_project
])
}
describe
'with private projects'
do
before
do
private_project
.
team
.
add_user
(
user
,
Gitlab
::
Access
::
MASTER
)
end
describe
'with shared projects and group membership'
do
before
do
group
.
add_user
(
user
,
Gitlab
::
Access
::
DEVELOPER
)
shared_project
.
project_group_links
.
create
(
group_access:
Gitlab
::
Access
::
MASTER
,
group:
group
)
end
it
do
is_expected
.
to
eq
([
shared_project
,
public_project
,
internal_project
])
end
it
do
is_expected
.
to
eq
([
public_project
,
internal_project
,
private_project
])
end
end
end
describe
'with shared projects and project membership'
do
before
do
shared_project
.
team
.
add_user
(
user
,
Gitlab
::
Access
::
DEVELOPER
)
describe
'with project_ids_relation'
do
let
(
:project_ids_relation
)
{
Project
.
where
(
id:
internal_project
.
id
)
}
shared_project
.
project_group_links
.
create
(
group_access:
Gitlab
::
Access
::
MASTER
,
group:
group
)
end
subject
{
finder
.
execute
(
user
,
project_ids_relation
)
}
it
do
is_expected
.
to
eq
([
shared_project
,
public_project
,
internal_project
])
end
end
end
it
{
is_expected
.
to
eq
([
internal_project
])
}
end
end
end
spec/lib/gitlab/checks/change_access_spec.rb
0 → 100644
View file @
35f9f79b
require
'spec_helper'
describe
Gitlab
::
Checks
::
ChangeAccess
,
lib:
true
do
describe
'#exec'
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:user_access
)
{
Gitlab
::
UserAccess
.
new
(
user
,
project:
project
)
}
let
(
:changes
)
do
{
oldrev:
'be93687618e4b132087f430a4d8fc3a609c9b77c'
,
newrev:
'54fcc214b94e78d7a41a9a8fe6d87a5e59500e51'
,
ref:
'refs/heads/master'
}
end
subject
{
described_class
.
new
(
changes
,
project:
project
,
user_access:
user_access
).
exec
}
before
{
allow
(
user_access
).
to
receive
(
:can_do_action?
).
with
(
:push_code
).
and_return
(
true
)
}
context
'without failed checks'
do
it
"doesn't return any error"
do
expect
(
subject
.
status
).
to
be
(
true
)
end
end
context
'when the user is not allowed to push code'
do
it
'returns an error'
do
expect
(
user_access
).
to
receive
(
:can_do_action?
).
with
(
:push_code
).
and_return
(
false
)
expect
(
subject
.
status
).
to
be
(
false
)
expect
(
subject
.
message
).
to
eq
(
'You are not allowed to push code to this project.'
)
end
end
context
'tags check'
do
let
(
:changes
)
do
{
oldrev:
'be93687618e4b132087f430a4d8fc3a609c9b77c'
,
newrev:
'54fcc214b94e78d7a41a9a8fe6d87a5e59500e51'
,
ref:
'refs/tags/v1.0.0'
}
end
it
'returns an error if the user is not allowed to update tags'
do
expect
(
user_access
).
to
receive
(
:can_do_action?
).
with
(
:admin_project
).
and_return
(
false
)
expect
(
subject
.
status
).
to
be
(
false
)
expect
(
subject
.
message
).
to
eq
(
'You are not allowed to change existing tags on this project.'
)
end
end
context
'protected branches check'
do
before
do
allow
(
project
).
to
receive
(
:protected_branch?
).
with
(
'master'
).
and_return
(
true
)
end
it
'returns an error if the user is not allowed to do forced pushes to protected branches'
do
expect
(
Gitlab
::
Checks
::
ForcePush
).
to
receive
(
:force_push?
).
and_return
(
true
)
expect
(
user_access
).
to
receive
(
:can_do_action?
).
with
(
:force_push_code_to_protected_branches
).
and_return
(
false
)
expect
(
subject
.
status
).
to
be
(
false
)
expect
(
subject
.
message
).
to
eq
(
'You are not allowed to force push code to a protected branch on this project.'
)
end
it
'returns an error if the user is not allowed to merge to protected branches'
do
expect_any_instance_of
(
Gitlab
::
Checks
::
MatchingMergeRequest
).
to
receive
(
:match?
).
and_return
(
true
)
expect
(
user_access
).
to
receive
(
:can_merge_to_branch?
).
and_return
(
false
)
expect
(
user_access
).
to
receive
(
:can_push_to_branch?
).
and_return
(
false
)
expect
(
subject
.
status
).
to
be
(
false
)
expect
(
subject
.
message
).
to
eq
(
'You are not allowed to merge code into protected branches on this project.'
)
end
it
'returns an error if the user is not allowed to push to protected branches'
do
expect
(
user_access
).
to
receive
(
:can_push_to_branch?
).
and_return
(
false
)
expect
(
subject
.
status
).
to
be
(
false
)
expect
(
subject
.
message
).
to
eq
(
'You are not allowed to push code to protected branches on this project.'
)
end
context
'branch deletion'
do
let
(
:changes
)
do
{
oldrev:
'be93687618e4b132087f430a4d8fc3a609c9b77c'
,
newrev:
'0000000000000000000000000000000000000000'
,
ref:
'refs/heads/master'
}
end
it
'returns an error if the user is not allowed to delete protected branches'
do
expect
(
user_access
).
to
receive
(
:can_do_action?
).
with
(
:remove_protected_branches
).
and_return
(
false
)
expect
(
subject
.
status
).
to
be
(
false
)
expect
(
subject
.
message
).
to
eq
(
'You are not allowed to delete protected branches from this project.'
)
end
end
end
end
end
spec/models/blob_spec.rb
View file @
35f9f79b
...
...
@@ -94,4 +94,26 @@ describe Blob do
expect
(
blob
.
to_partial_path
).
to
eq
'download'
end
end
describe
'#size_within_svg_limits?'
do
let
(
:blob
)
{
described_class
.
decorate
(
double
(
:blob
))
}
it
'returns true when the blob size is smaller than the SVG limit'
do
expect
(
blob
).
to
receive
(
:size
).
and_return
(
42
)
expect
(
blob
.
size_within_svg_limits?
).
to
eq
(
true
)
end
it
'returns true when the blob size is equal to the SVG limit'
do
expect
(
blob
).
to
receive
(
:size
).
and_return
(
Blob
::
MAXIMUM_SVG_SIZE
)
expect
(
blob
.
size_within_svg_limits?
).
to
eq
(
true
)
end
it
'returns false when the blob size is larger than the SVG limit'
do
expect
(
blob
).
to
receive
(
:size
).
and_return
(
1
.
terabyte
)
expect
(
blob
.
size_within_svg_limits?
).
to
eq
(
false
)
end
end
end
spec/models/deployment_spec.rb
View file @
35f9f79b
...
...
@@ -15,4 +15,28 @@ describe Deployment, models: true do
it
{
is_expected
.
to
validate_presence_of
(
:ref
)
}
it
{
is_expected
.
to
validate_presence_of
(
:sha
)
}
describe
'#includes_commit?'
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:environment
)
{
create
(
:environment
,
project:
project
)
}
let
(
:deployment
)
do
create
(
:deployment
,
environment:
environment
,
sha:
project
.
commit
.
id
)
end
context
'when there is no project commit'
do
it
'returns false'
do
commit
=
project
.
commit
(
'feature'
)
expect
(
deployment
.
includes_commit?
(
commit
)).
to
be
false
end
end
context
'when they share the same tree branch'
do
it
'returns true'
do
commit
=
project
.
commit
expect
(
deployment
.
includes_commit?
(
commit
)).
to
be
true
end
end
end
end
spec/models/environment_spec.rb
View file @
35f9f79b
...
...
@@ -30,4 +30,37 @@ describe Environment, models: true do
expect
(
env
.
external_url
).
to
be_nil
end
end
describe
'#includes_commit?'
do
context
'without a last deployment'
do
it
"returns false"
do
expect
(
environment
.
includes_commit?
(
'HEAD'
)).
to
be
false
end
end
context
'with a last deployment'
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:environment
)
{
create
(
:environment
,
project:
project
)
}
let!
(
:deployment
)
do
create
(
:deployment
,
environment:
environment
,
sha:
project
.
commit
(
'master'
).
id
)
end
context
'in the same branch'
do
it
'returns true'
do
expect
(
environment
.
includes_commit?
(
RepoHelpers
.
sample_commit
)).
to
be
true
end
end
context
'not in the same branch'
do
before
do
deployment
.
update
(
sha:
project
.
commit
(
'feature'
).
id
)
end
it
'returns false'
do
expect
(
environment
.
includes_commit?
(
RepoHelpers
.
sample_commit
)).
to
be
false
end
end
end
end
end
spec/models/merge_request_spec.rb
View file @
35f9f79b
...
...
@@ -674,6 +674,21 @@ describe MergeRequest, models: true do
end
end
describe
"#environments"
do
let
(
:project
)
{
create
(
:project
)
}
let!
(
:environment
)
{
create
(
:environment
,
project:
project
)
}
let!
(
:environment1
)
{
create
(
:environment
,
project:
project
)
}
let!
(
:environment2
)
{
create
(
:environment
,
project:
project
)
}
let
(
:merge_request
)
{
create
(
:merge_request
,
source_project:
project
)
}
it
'selects deployed environments'
do
create
(
:deployment
,
environment:
environment
,
sha:
project
.
commit
(
'master'
).
id
)
create
(
:deployment
,
environment:
environment1
,
sha:
project
.
commit
(
'feature'
).
id
)
expect
(
merge_request
.
environments
).
to
eq
[
environment
]
end
end
describe
"#reload_diff"
do
let
(
:note
)
{
create
(
:diff_note_on_merge_request
,
project:
subject
.
project
,
noteable:
subject
)
}
...
...
spec/models/project_services/pivotaltracker_service_spec.rb
View file @
35f9f79b
...
...
@@ -39,4 +39,75 @@ describe PivotaltrackerService, models: true do
it
{
is_expected
.
not_to
validate_presence_of
(
:token
)
}
end
end
describe
'Execute'
do
let
(
:service
)
do
PivotaltrackerService
.
new
.
tap
do
|
service
|
service
.
token
=
'secret_api_token'
end
end
let
(
:url
)
{
PivotaltrackerService
::
API_ENDPOINT
}
def
push_data
(
branch:
'master'
)
{
object_kind:
'push'
,
ref:
"refs/heads/
#{
branch
}
"
,
commits:
[
{
id:
'21c12ea'
,
author:
{
name:
'Some User'
},
url:
'https://example.com/commit'
,
message:
'commit message'
,
}
]
}
end
before
do
WebMock
.
stub_request
(
:post
,
url
)
end
it
'should post correct message'
do
service
.
execute
(
push_data
)
expect
(
WebMock
).
to
have_requested
(
:post
,
url
).
with
(
body:
{
'source_commit'
=>
{
'commit_id'
=>
'21c12ea'
,
'author'
=>
'Some User'
,
'url'
=>
'https://example.com/commit'
,
'message'
=>
'commit message'
}
},
headers:
{
'Content-Type'
=>
'application/json'
,
'X-TrackerToken'
=>
'secret_api_token'
}
).
once
end
context
'when allowed branches is specified'
do
let
(
:service
)
do
super
().
tap
do
|
service
|
service
.
restrict_to_branch
=
'master,v10'
end
end
it
'should post message if branch is in the list'
do
service
.
execute
(
push_data
(
branch:
'master'
))
service
.
execute
(
push_data
(
branch:
'v10'
))
expect
(
WebMock
).
to
have_requested
(
:post
,
url
).
twice
end
it
'should not post message if branch is not in the list'
do
service
.
execute
(
push_data
(
branch:
'mas'
))
service
.
execute
(
push_data
(
branch:
'v11'
))
expect
(
WebMock
).
not_to
have_requested
(
:post
,
url
)
end
end
end
end
spec/requests/api/todos_spec.rb
View file @
35f9f79b
...
...
@@ -117,6 +117,12 @@ describe API::Todos, api: true do
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
pending_1
.
reload
).
to
be_done
end
it
'updates todos cache'
do
expect_any_instance_of
(
User
).
to
receive
(
:update_todos_count_cache
).
and_call_original
delete
api
(
"/todos/
#{
pending_1
.
id
}
"
,
john_doe
)
end
end
end
...
...
@@ -139,6 +145,12 @@ describe API::Todos, api: true do
expect
(
pending_2
.
reload
).
to
be_done
expect
(
pending_3
.
reload
).
to
be_done
end
it
'updates todos cache'
do
expect_any_instance_of
(
User
).
to
receive
(
:update_todos_count_cache
).
and_call_original
delete
api
(
"/todos"
,
john_doe
)
end
end
end
...
...
spec/requests/api/users_spec.rb
View file @
35f9f79b
...
...
@@ -564,12 +564,14 @@ describe API::API, api: true do
end
describe
"DELETE /users/:id"
do
let!
(
:namespace
)
{
user
.
namespace
}
before
{
admin
}
it
"deletes user"
do
delete
api
(
"/users/
#{
user
.
id
}
"
,
admin
)
expect
(
response
).
to
have_http_status
(
200
)
expect
{
User
.
find
(
user
.
id
)
}.
to
raise_error
ActiveRecord
::
RecordNotFound
expect
{
Namespace
.
find
(
namespace
.
id
)
}.
to
raise_error
ActiveRecord
::
RecordNotFound
expect
(
json_response
[
'email'
]).
to
eq
(
user
.
email
)
end
...
...
spec/services/delete_user_service_spec.rb
View file @
35f9f79b
...
...
@@ -9,9 +9,11 @@ describe DeleteUserService, services: true do
context
'no options are given'
do
it
'deletes the user'
do
DeleteUserService
.
new
(
current_user
).
execute
(
user
)
user_data
=
DeleteUserService
.
new
(
current_user
).
execute
(
user
)
expect
{
User
.
find
(
user
.
id
)
}.
to
raise_error
(
ActiveRecord
::
RecordNotFound
)
expect
{
user_data
[
'email'
].
to
eq
(
user
.
email
)
}
expect
{
User
.
find
(
user
.
id
)
}.
to
raise_error
(
ActiveRecord
::
RecordNotFound
)
expect
{
Namespace
.
with_deleted
.
find
(
user
.
namespace
.
id
)
}.
to
raise_error
(
ActiveRecord
::
RecordNotFound
)
end
it
'will delete the project in the near future'
do
...
...
spec/services/destroy_group_service_spec.rb
View file @
35f9f79b
...
...
@@ -7,38 +7,52 @@ describe DestroyGroupService, services: true do
let!
(
:gitlab_shell
)
{
Gitlab
::
Shell
.
new
}
let!
(
:remove_path
)
{
group
.
path
+
"+
#{
group
.
id
}
+deleted"
}
context
'database records'
do
before
do
destroy_group
(
group
,
user
)
shared_examples
'group destruction'
do
|
async
|
context
'database records'
do
before
do
destroy_group
(
group
,
user
,
async
)
end
it
{
expect
(
Group
.
all
).
not_to
include
(
group
)
}
it
{
expect
(
Project
.
all
).
not_to
include
(
project
)
}
end
it
{
expect
(
Group
.
all
).
not_to
include
(
group
)
}
it
{
expect
(
Project
.
all
).
not_to
include
(
project
)
}
end
context
'file system'
do
context
'Sidekiq inline'
do
before
do
# Run sidekiq immediatly to check that renamed dir will be removed
Sidekiq
::
Testing
.
inline!
{
destroy_group
(
group
,
user
,
async
)
}
end
context
'file system'
do
context
'Sidekiq inline'
do
before
do
# Run sidekiq immediatly to check that renamed dir will be removed
Sidekiq
::
Testing
.
inline!
{
destroy_group
(
group
,
user
)
}
it
{
expect
(
gitlab_shell
.
exists?
(
project
.
repository_storage_path
,
group
.
path
)).
to
be_falsey
}
it
{
expect
(
gitlab_shell
.
exists?
(
project
.
repository_storage_path
,
remove_path
)).
to
be_falsey
}
end
it
{
expect
(
gitlab_shell
.
exists?
(
project
.
repository_storage_path
,
group
.
path
)).
to
be_falsey
}
it
{
expect
(
gitlab_shell
.
exists?
(
project
.
repository_storage_path
,
remove_path
)).
to
be_falsey
}
end
context
'Sidekiq fake'
do
before
do
# Dont run sidekiq to check if renamed repository exists
Sidekiq
::
Testing
.
fake!
{
destroy_group
(
group
,
user
,
async
)
}
end
context
'Sidekiq fake'
do
before
do
# Dont run sidekiq to check if renamed repository exists
Sidekiq
::
Testing
.
fake!
{
destroy_group
(
group
,
user
)
}
it
{
expect
(
gitlab_shell
.
exists?
(
project
.
repository_storage_path
,
group
.
path
)).
to
be_falsey
}
it
{
expect
(
gitlab_shell
.
exists?
(
project
.
repository_storage_path
,
remove_path
)).
to
be_truthy
}
end
end
it
{
expect
(
gitlab_shell
.
exists?
(
project
.
repository_storage_path
,
group
.
path
)).
to
be_falsey
}
it
{
expect
(
gitlab_shell
.
exists?
(
project
.
repository_storage_path
,
remove_path
)).
to
be_truthy
}
def
destroy_group
(
group
,
user
,
async
)
if
async
DestroyGroupService
.
new
(
group
,
user
).
async_execute
else
DestroyGroupService
.
new
(
group
,
user
).
execute
end
end
end
def
destroy_group
(
group
,
user
)
DestroyGroupService
.
new
(
group
,
user
).
execute
describe
'asynchronous delete'
do
it_behaves_like
'group destruction'
,
true
end
describe
'synchronous delete'
do
it_behaves_like
'group destruction'
,
false
end
end
spec/services/merge_requests/get_urls_service_spec.rb
View file @
35f9f79b
...
...
@@ -7,7 +7,9 @@ describe MergeRequests::GetUrlsService do
let
(
:new_merge_request_url
)
{
"http://localhost/
#{
project
.
namespace
.
name
}
/
#{
project
.
path
}
/merge_requests/new?merge_request%5Bsource_branch%5D=
#{
source_branch
}
"
}
let
(
:show_merge_request_url
)
{
"http://localhost/
#{
project
.
namespace
.
name
}
/
#{
project
.
path
}
/merge_requests/
#{
merge_request
.
iid
}
"
}
let
(
:new_branch_changes
)
{
"
#{
Gitlab
::
Git
::
BLANK_SHA
}
570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/
#{
source_branch
}
"
}
let
(
:deleted_branch_changes
)
{
"d14d6c0abdd253381df51a723d58691b2ee1ab08
#{
Gitlab
::
Git
::
BLANK_SHA
}
refs/heads/
#{
source_branch
}
"
}
let
(
:existing_branch_changes
)
{
"d14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/
#{
source_branch
}
"
}
let
(
:default_branch_changes
)
{
"d14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master"
}
describe
"#execute"
do
shared_examples
'new_merge_request_link'
do
...
...
@@ -32,6 +34,28 @@ describe MergeRequests::GetUrlsService do
end
end
shared_examples
'no_merge_request_url'
do
it
'returns no URL'
do
result
=
service
.
execute
(
changes
)
expect
(
result
).
to
be_empty
end
end
context
'pushing to default branch'
do
let
(
:changes
)
{
default_branch_changes
}
it_behaves_like
'no_merge_request_url'
end
context
'pushing to project with MRs disabled'
do
let
(
:changes
)
{
new_branch_changes
}
before
do
project
.
merge_requests_enabled
=
false
end
it_behaves_like
'no_merge_request_url'
end
context
'pushing one completely new branch'
do
let
(
:changes
)
{
new_branch_changes
}
it_behaves_like
'new_merge_request_link'
...
...
@@ -42,6 +66,11 @@ describe MergeRequests::GetUrlsService do
it_behaves_like
'new_merge_request_link'
end
context
'pushing to deleted branch'
do
let
(
:changes
)
{
deleted_branch_changes
}
it_behaves_like
'no_merge_request_url'
end
context
'pushing to existing branch and merge request opened'
do
let!
(
:merge_request
)
{
create
(
:merge_request
,
source_project:
project
,
source_branch:
source_branch
)
}
let
(
:changes
)
{
existing_branch_changes
}
...
...
@@ -61,6 +90,11 @@ describe MergeRequests::GetUrlsService do
let
(
:changes
)
{
existing_branch_changes
}
# Source project is now the forked one
let
(
:service
)
{
MergeRequests
::
GetUrlsService
.
new
(
forked_project
)
}
before
do
allow
(
forked_project
).
to
receive
(
:empty_repo?
).
and_return
(
false
)
end
it_behaves_like
'show_merge_request_url'
end
...
...
spec/services/todo_service_spec.rb
View file @
35f9f79b
...
...
@@ -472,6 +472,42 @@ describe TodoService, services: true do
expect
(
john_doe
.
todos_pending_count
).
to
eq
(
1
)
end
describe
'#mark_todos_as_done'
do
let
(
:issue
)
{
create
(
:issue
,
project:
project
,
author:
author
,
assignee:
john_doe
)
}
it
'marks a relation of todos as done'
do
create
(
:todo
,
:mentioned
,
user:
john_doe
,
target:
issue
,
project:
project
)
todos
=
TodosFinder
.
new
(
john_doe
,
{}).
execute
expect
{
TodoService
.
new
.
mark_todos_as_done
(
todos
,
john_doe
)
}
.
to
change
{
john_doe
.
todos
.
done
.
count
}.
from
(
0
).
to
(
1
)
end
it
'marks an array of todos as done'
do
todo
=
create
(
:todo
,
:mentioned
,
user:
john_doe
,
target:
issue
,
project:
project
)
expect
{
TodoService
.
new
.
mark_todos_as_done
([
todo
],
john_doe
)
}
.
to
change
{
todo
.
reload
.
state
}.
from
(
'pending'
).
to
(
'done'
)
end
it
'returns the number of updated todos'
do
# Needed on API
todo
=
create
(
:todo
,
:mentioned
,
user:
john_doe
,
target:
issue
,
project:
project
)
expect
(
TodoService
.
new
.
mark_todos_as_done
([
todo
],
john_doe
)).
to
eq
(
1
)
end
it
'caches the number of todos of a user'
,
:caching
do
create
(
:todo
,
:mentioned
,
user:
john_doe
,
target:
issue
,
project:
project
)
todo
=
create
(
:todo
,
:mentioned
,
user:
john_doe
,
target:
issue
,
project:
project
)
TodoService
.
new
.
mark_todos_as_done
([
todo
],
john_doe
)
expect_any_instance_of
(
TodosFinder
).
not_to
receive
(
:execute
)
expect
(
john_doe
.
todos_done_count
).
to
eq
(
1
)
expect
(
john_doe
.
todos_pending_count
).
to
eq
(
1
)
end
end
def
should_create_todo
(
attributes
=
{})
attributes
.
reverse_merge!
(
project:
project
,
...
...
spec/views/projects/merge_requests/_heading.html.haml_spec.rb
0 → 100644
View file @
35f9f79b
require
'spec_helper'
describe
'projects/merge_requests/widget/_heading'
do
include
Devise
::
TestHelpers
context
'when released to an environment'
do
let
(
:project
)
{
merge_request
.
target_project
}
let
(
:merge_request
)
{
create
(
:merge_request
,
:merged
)
}
let
(
:environment
)
{
create
(
:environment
,
project:
project
)
}
let!
(
:deployment
)
do
create
(
:deployment
,
environment:
environment
,
sha:
project
.
commit
(
'master'
).
id
)
end
before
do
assign
(
:merge_request
,
merge_request
)
assign
(
:project
,
project
)
render
end
it
'displays that the environment is deployed'
do
expect
(
rendered
).
to
match
(
"Deployed to"
)
expect
(
rendered
).
to
match
(
"
#{
environment
.
name
}
"
)
end
end
end
spec/workers/group_destroy_worker_spec.rb
0 → 100644
View file @
35f9f79b
require
'spec_helper'
describe
GroupDestroyWorker
do
let
(
:group
)
{
create
(
:group
)
}
let
(
:user
)
{
create
(
:admin
)
}
let!
(
:project
)
{
create
(
:project
,
namespace:
group
)
}
subject
{
GroupDestroyWorker
.
new
}
describe
"#perform"
do
it
"deletes the project"
do
subject
.
perform
(
group
.
id
,
user
.
id
)
expect
(
Group
.
all
).
not_to
include
(
group
)
expect
(
Project
.
all
).
not_to
include
(
project
)
expect
(
Dir
.
exist?
(
project
.
path
)).
to
be_falsey
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment