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
Boxiang Sun
gitlab-ce
Commits
1ba2ef4f
Commit
1ba2ef4f
authored
Aug 15, 2016
by
Douwe Maan
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into mc-ui
parents
882f97e4
931eadaa
Changes
95
Hide whitespace changes
Inline
Side-by-side
Showing
95 changed files
with
1634 additions
and
350 deletions
+1634
-350
.gitlab-ci.yml
.gitlab-ci.yml
+1
-0
CHANGELOG
CHANGELOG
+9
-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/dashboard/todos_controller.rb
app/controllers/dashboard/todos_controller.rb
+2
-2
app/controllers/projects/badges_controller.rb
app/controllers/projects/badges_controller.rb
+15
-2
app/controllers/projects/blob_controller.rb
app/controllers/projects/blob_controller.rb
+12
-2
app/controllers/projects/pipelines_settings_controller.rb
app/controllers/projects/pipelines_settings_controller.rb
+7
-1
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/sorting_helper.rb
app/helpers/sorting_helper.rb
+7
-1
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/project_services/pivotaltracker_service.rb
app/models/project_services/pivotaltracker_service.rb
+27
-4
app/models/project_wiki.rb
app/models/project_wiki.rb
+4
-0
app/models/user.rb
app/models/user.rb
+2
-2
app/services/files/base_service.rb
app/services/files/base_service.rb
+1
-0
app/services/files/update_service.rb
app/services/files/update_service.rb
+23
-0
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/blob/edit.html.haml
app/views/projects/blob/edit.html.haml
+7
-2
app/views/projects/merge_requests/widget/_heading.html.haml
app/views/projects/merge_requests/widget/_heading.html.haml
+13
-0
app/views/projects/pipelines_settings/_badge.html.haml
app/views/projects/pipelines_settings/_badge.html.haml
+27
-0
app/views/projects/pipelines_settings/show.html.haml
app/views/projects/pipelines_settings/show.html.haml
+1
-24
app/views/shared/projects/_project.html.haml
app/views/shared/projects/_project.html.haml
+2
-0
config/routes.rb
config/routes.rb
+4
-1
db/fixtures/development/14_builds.rb
db/fixtures/development/14_builds.rb
+29
-30
db/schema.rb
db/schema.rb
+1
-1
doc/api/services.md
doc/api/services.md
+2
-2
doc/ci/pipelines.md
doc/ci/pipelines.md
+35
-0
doc/ci/quick_start/README.md
doc/ci/quick_start/README.md
+2
-10
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/badge/base.rb
lib/gitlab/badge/base.rb
+21
-0
lib/gitlab/badge/build.rb
lib/gitlab/badge/build.rb
+0
-30
lib/gitlab/badge/build/metadata.rb
lib/gitlab/badge/build/metadata.rb
+7
-15
lib/gitlab/badge/build/status.rb
lib/gitlab/badge/build/status.rb
+37
-0
lib/gitlab/badge/build/template.rb
lib/gitlab/badge/build/template.rb
+8
-24
lib/gitlab/badge/coverage/metadata.rb
lib/gitlab/badge/coverage/metadata.rb
+30
-0
lib/gitlab/badge/coverage/report.rb
lib/gitlab/badge/coverage/report.rb
+56
-0
lib/gitlab/badge/coverage/template.rb
lib/gitlab/badge/coverage/template.rb
+52
-0
lib/gitlab/badge/metadata.rb
lib/gitlab/badge/metadata.rb
+36
-0
lib/gitlab/badge/template.rb
lib/gitlab/badge/template.rb
+49
-0
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
+3
-2
spec/controllers/groups_controller_spec.rb
spec/controllers/groups_controller_spec.rb
+3
-2
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/badges/coverage_spec.rb
spec/features/projects/badges/coverage_spec.rb
+73
-0
spec/features/projects/badges/list_spec.rb
spec/features/projects/badges/list_spec.rb
+32
-14
spec/features/projects/files/editing_a_file_spec.rb
spec/features/projects/files/editing_a_file_spec.rb
+34
-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/badge/build/metadata_spec.rb
spec/lib/gitlab/badge/build/metadata_spec.rb
+13
-23
spec/lib/gitlab/badge/build/status_spec.rb
spec/lib/gitlab/badge/build/status_spec.rb
+13
-25
spec/lib/gitlab/badge/build/template_spec.rb
spec/lib/gitlab/badge/build/template_spec.rb
+14
-8
spec/lib/gitlab/badge/coverage/metadata_spec.rb
spec/lib/gitlab/badge/coverage/metadata_spec.rb
+30
-0
spec/lib/gitlab/badge/coverage/report_spec.rb
spec/lib/gitlab/badge/coverage/report_spec.rb
+93
-0
spec/lib/gitlab/badge/coverage/template_spec.rb
spec/lib/gitlab/badge/coverage/template_spec.rb
+130
-0
spec/lib/gitlab/badge/shared/metadata.rb
spec/lib/gitlab/badge/shared/metadata.rb
+21
-0
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/irker_service_spec.rb
spec/models/project_services/irker_service_spec.rb
+4
-3
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/services/files/update_service_spec.rb
spec/services/files/update_service_spec.rb
+84
-0
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
No files found.
.gitlab-ci.yml
View file @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
Please view this file on the master branch, on stable branches it's out of date.
v 8.11.0 (unreleased)
- Add test coverage report badge. !5708
- 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 +34,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 +58,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
...
...
@@ -107,6 +112,9 @@ 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
- Ensure file editing in UI does not overwrite commited changes without warning user
v 8.10.5
- Add a data migration to fix some missing timestamps in the members table. !5670
...
...
@@ -271,6 +279,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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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/dashboard/todos_controller.rb
View file @
1ba2ef4f
...
...
@@ -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/projects/badges_controller.rb
View file @
1ba2ef4f
...
...
@@ -4,11 +4,24 @@ class Projects::BadgesController < Projects::ApplicationController
before_action
:no_cache_headers
,
except:
[
:index
]
def
build
badge
=
Gitlab
::
Badge
::
Build
.
new
(
project
,
params
[
:ref
])
build_status
=
Gitlab
::
Badge
::
Build
::
Status
.
new
(
project
,
params
[
:ref
])
render_badge
build_status
end
def
coverage
coverage_report
=
Gitlab
::
Badge
::
Coverage
::
Report
.
new
(
project
,
params
[
:ref
],
params
[
:job
])
render_badge
coverage_report
end
private
def
render_badge
(
badge
)
respond_to
do
|
format
|
format
.
html
{
render_404
}
format
.
svg
do
render
'badge'
,
locals:
{
badge:
badge
.
template
}
end
...
...
app/controllers/projects/blob_controller.rb
View file @
1ba2ef4f
...
...
@@ -17,6 +17,7 @@ class Projects::BlobController < Projects::ApplicationController
before_action
:require_branch_head
,
only:
[
:edit
,
:update
]
before_action
:editor_variables
,
except:
[
:show
,
:preview
,
:diff
]
before_action
:validate_diff_params
,
only: :diff
before_action
:set_last_commit_sha
,
only:
[
:edit
,
:update
]
def
new
commit
unless
@repository
.
empty?
...
...
@@ -33,7 +34,6 @@ class Projects::BlobController < Projects::ApplicationController
end
def
edit
@last_commit
=
Gitlab
::
Git
::
Commit
.
last_for_path
(
@repository
,
@ref
,
@path
).
sha
blob
.
load_all_data!
(
@repository
)
end
...
...
@@ -55,6 +55,10 @@ class Projects::BlobController < Projects::ApplicationController
create_commit
(
Files
::
UpdateService
,
success_path:
after_edit_path
,
failure_view: :edit
,
failure_path:
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
@id
))
rescue
Files
::
UpdateService
::
FileChangedError
@conflict
=
true
render
:edit
end
def
preview
...
...
@@ -152,7 +156,8 @@ class Projects::BlobController < Projects::ApplicationController
file_path:
@file_path
,
commit_message:
params
[
:commit_message
],
file_content:
params
[
:content
],
file_content_encoding:
params
[
:encoding
]
file_content_encoding:
params
[
:encoding
],
last_commit_sha:
params
[
:last_commit_sha
]
}
end
...
...
@@ -161,4 +166,9 @@ class Projects::BlobController < Projects::ApplicationController
render
nothing:
true
end
end
def
set_last_commit_sha
@last_commit_sha
=
Gitlab
::
Git
::
Commit
.
last_for_path
(
@repository
,
@ref
,
@path
).
sha
end
end
app/controllers/projects/pipelines_settings_controller.rb
View file @
1ba2ef4f
...
...
@@ -3,7 +3,13 @@ class Projects::PipelinesSettingsController < Projects::ApplicationController
def
show
@ref
=
params
[
:ref
]
||
@project
.
default_branch
||
'master'
@build_badge
=
Gitlab
::
Badge
::
Build
.
new
(
@project
,
@ref
).
metadata
@badges
=
[
Gitlab
::
Badge
::
Build
::
Status
,
Gitlab
::
Badge
::
Coverage
::
Report
]
@badges
.
map!
do
|
badge
|
badge
.
new
(
@project
,
@ref
).
metadata
end
end
def
update
...
...
app/finders/projects_finder.rb
View file @
1ba2ef4f
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 @
1ba2ef4f
...
...
@@ -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/sorting_helper.rb
View file @
1ba2ef4f
...
...
@@ -20,13 +20,19 @@ module SortingHelper
end
def
projects_sort_options_hash
{
options
=
{
sort_value_name
=>
sort_title_name
,
sort_value_recently_updated
=>
sort_title_recently_updated
,
sort_value_oldest_updated
=>
sort_title_oldest_updated
,
sort_value_recently_created
=>
sort_title_recently_created
,
sort_value_oldest_created
=>
sort_title_oldest_created
,
}
if
current_controller?
(
'admin/projects'
)
options
.
merge!
(
sort_value_largest_repo
=>
sort_title_largest_repo
)
end
options
end
def
sort_title_priority
...
...
app/helpers/todos_helper.rb
View file @
1ba2ef4f
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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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/project_services/pivotaltracker_service.rb
View file @
1ba2ef4f
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/project_wiki.rb
View file @
1ba2ef4f
...
...
@@ -56,6 +56,10 @@ class ProjectWiki
end
end
def
repository_exists?
!!
repository
.
exists?
end
def
empty?
pages
.
empty?
end
...
...
app/models/user.rb
View file @
1ba2ef4f
...
...
@@ -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/files/base_service.rb
View file @
1ba2ef4f
...
...
@@ -15,6 +15,7 @@ module Files
else
params
[
:file_content
]
end
@last_commit_sha
=
params
[
:last_commit_sha
]
# Validate parameters
validate
...
...
app/services/files/update_service.rb
View file @
1ba2ef4f
...
...
@@ -2,11 +2,34 @@ require_relative "base_service"
module
Files
class
UpdateService
<
Files
::
BaseService
class
FileChangedError
<
StandardError
;
end
def
commit
repository
.
update_file
(
current_user
,
@file_path
,
@file_content
,
branch:
@target_branch
,
previous_path:
@previous_path
,
message:
@commit_message
)
end
private
def
validate
super
if
file_has_changed?
raise
FileChangedError
.
new
(
"You are attempting to update a file that has changed since you started editing it."
)
end
end
def
file_has_changed?
return
false
unless
@last_commit_sha
&&
last_commit
@last_commit_sha
!=
last_commit
.
sha
end
def
last_commit
@last_commit
||=
Gitlab
::
Git
::
Commit
.
last_for_path
(
@source_project
.
repository
,
@source_branch
,
@file_path
)
end
end
end
app/services/merge_requests/get_urls_service.rb
View file @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
.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/blob/edit.html.haml
View file @
1ba2ef4f
-
page_title
"Edit"
,
@blob
.
path
,
@ref
-
if
@conflict
.alert.alert-danger
Someone edited the file the same time you did. Please check out
=
link_to
"the file"
,
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
tree_join
(
@target_branch
,
@file_path
)),
target:
"_blank"
and make sure your changes will not unintentionally remove theirs.
.file-editor
%ul
.nav-links.no-bottom.js-edit-mode
%li
.active
...
...
@@ -13,8 +19,7 @@
=
form_tag
(
namespace_project_update_blob_path
(
@project
.
namespace
,
@project
,
@id
),
method: :put
,
class:
'form-horizontal js-quick-submit js-requires-input js-edit-blob-form'
)
do
=
render
'projects/blob/editor'
,
ref:
@ref
,
path:
@path
,
blob_data:
@blob
.
data
=
render
'shared/new_commit_form'
,
placeholder:
"Update
#{
@blob
.
name
}
"
=
hidden_field_tag
'last_commit'
,
@last_commit
=
hidden_field_tag
'last_commit_sha'
,
@last_commit_sha
=
hidden_field_tag
'content'
,
''
,
id:
"file-content"
=
hidden_field_tag
'from_merge_request_id'
,
params
[
:from_merge_request_id
]
=
render
'projects/commit_button'
,
ref:
@ref
,
cancel_path:
namespace_project_blob_path
(
@project
.
namespace
,
@project
,
@id
)
...
...
app/views/projects/merge_requests/widget/_heading.html.haml
View file @
1ba2ef4f
...
...
@@ -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/projects/pipelines_settings/_badge.html.haml
0 → 100644
View file @
1ba2ef4f
.row
{
class:
badge
.
title
.
gsub
(
' '
,
'-'
)
}
.col-lg-3.profile-settings-sidebar
%h4
.prepend-top-0
=
badge
.
title
.
capitalize
.col-lg-9
.prepend-top-10
.panel.panel-default
.panel-heading
%b
=
badge
.
title
.
capitalize
·
=
badge
.
to_html
.pull-right
=
render
'shared/ref_switcher'
,
destination:
'badges'
,
align_right:
true
.panel-body
.row
.col-md-2.text-center
Markdown
.col-md-10.code.js-syntax-highlight
=
highlight
(
'.md'
,
badge
.
to_markdown
)
.row
%hr
.row
.col-md-2.text-center
HTML
.col-md-10.code.js-syntax-highlight
=
highlight
(
'.html'
,
badge
.
to_html
)
app/views/projects/pipelines_settings/show.html.haml
View file @
1ba2ef4f
...
...
@@ -77,27 +77,4 @@
%hr
.row.prepend-top-default
.col-lg-3.profile-settings-sidebar
%h4
.prepend-top-0
Builds Badge
.col-lg-9
.prepend-top-10
.panel.panel-default
.panel-heading
%b
Builds badge
·
=
@build_badge
.
to_html
.pull-right
=
render
'shared/ref_switcher'
,
destination:
'badges'
,
align_right:
true
.panel-body
.row
.col-md-2.text-center
Markdown
.col-md-10.code.js-syntax-highlight
=
highlight
(
'.md'
,
@build_badge
.
to_markdown
)
.row
%hr
.row
.col-md-2.text-center
HTML
.col-md-10.code.js-syntax-highlight
=
highlight
(
'.html'
,
@build_badge
.
to_html
)
=
render
partial:
'badge'
,
collection:
@badges
app/views/shared/projects/_project.html.haml
View file @
1ba2ef4f
...
...
@@ -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
)
...
...
config/routes.rb
View file @
1ba2ef4f
...
...
@@ -871,7 +871,10 @@ Rails.application.routes.draw do
resources
:badges
,
only:
[
:index
]
do
collection
do
scope
'*ref'
,
constraints:
{
ref:
Gitlab
::
Regex
.
git_reference_regex
}
do
get
:build
,
constraints:
{
format:
/svg/
}
constraints
format:
/svg/
do
get
:build
get
:coverage
end
end
end
end
...
...
db/fixtures/development/14_builds.rb
View file @
1ba2ef4f
class
Gitlab::Seeder::Builds
STAGES
=
%w[build notify_build test notify_test deploy notify_deploy]
BUILDS
=
[
{
name:
'build:linux'
,
stage:
'build'
,
status: :success
},
{
name:
'build:osx'
,
stage:
'build'
,
status: :success
},
{
name:
'slack post build'
,
stage:
'notify_build'
,
status: :success
},
{
name:
'rspec:linux'
,
stage:
'test'
,
status: :success
},
{
name:
'rspec:windows'
,
stage:
'test'
,
status: :success
},
{
name:
'rspec:windows'
,
stage:
'test'
,
status: :success
},
{
name:
'rspec:osx'
,
stage:
'test'
,
status_event: :success
},
{
name:
'spinach:linux'
,
stage:
'test'
,
status: :pending
},
{
name:
'spinach:osx'
,
stage:
'test'
,
status: :canceled
},
{
name:
'cucumber:linux'
,
stage:
'test'
,
status: :running
},
{
name:
'cucumber:osx'
,
stage:
'test'
,
status: :failed
},
{
name:
'slack post test'
,
stage:
'notify_test'
,
status: :success
},
{
name:
'staging'
,
stage:
'deploy'
,
environment:
'staging'
,
status: :success
},
{
name:
'production'
,
stage:
'deploy'
,
environment:
'production'
,
when:
'manual'
,
status: :success
},
]
def
initialize
(
project
)
@project
=
project
...
...
@@ -8,25 +24,7 @@ class Gitlab::Seeder::Builds
def
seed!
pipelines
.
each
do
|
pipeline
|
begin
build_create!
(
pipeline
,
name:
'build:linux'
,
stage:
'build'
,
status_event: :success
)
build_create!
(
pipeline
,
name:
'build:osx'
,
stage:
'build'
,
status_event: :success
)
build_create!
(
pipeline
,
name:
'slack post build'
,
stage:
'notify_build'
,
status_event: :success
)
build_create!
(
pipeline
,
name:
'rspec:linux'
,
stage:
'test'
,
status_event: :success
)
build_create!
(
pipeline
,
name:
'rspec:windows'
,
stage:
'test'
,
status_event: :success
)
build_create!
(
pipeline
,
name:
'rspec:windows'
,
stage:
'test'
,
status_event: :success
)
build_create!
(
pipeline
,
name:
'rspec:osx'
,
stage:
'test'
,
status_event: :success
)
build_create!
(
pipeline
,
name:
'spinach:linux'
,
stage:
'test'
,
status: :pending
)
build_create!
(
pipeline
,
name:
'spinach:osx'
,
stage:
'test'
,
status_event: :cancel
)
build_create!
(
pipeline
,
name:
'cucumber:linux'
,
stage:
'test'
,
status_event: :run
)
build_create!
(
pipeline
,
name:
'cucumber:osx'
,
stage:
'test'
,
status_event: :drop
)
build_create!
(
pipeline
,
name:
'slack post test'
,
stage:
'notify_test'
,
status_event: :success
)
build_create!
(
pipeline
,
name:
'staging'
,
stage:
'deploy'
,
environment:
'staging'
,
status_event: :success
)
build_create!
(
pipeline
,
name:
'production'
,
stage:
'deploy'
,
environment:
'production'
,
when:
'manual'
,
status: :success
)
BUILDS
.
each
{
|
opts
|
build_create!
(
pipeline
,
opts
)
}
commit_status_create!
(
pipeline
,
name:
'jenkins'
,
status: :success
)
print
'.'
...
...
@@ -48,21 +46,22 @@ class Gitlab::Seeder::Builds
def
build_create!
(
pipeline
,
opts
=
{})
attributes
=
build_attributes_for
(
pipeline
,
opts
)
build
=
Ci
::
Build
.
create!
(
attributes
)
if
opts
[
:name
].
start_with?
(
'build'
)
artifacts_cache_file
(
artifacts_archive_path
)
do
|
file
|
build
.
artifacts_file
=
file
end
Ci
::
Build
.
create!
(
attributes
)
do
|
build
|
if
opts
[
:name
].
start_with?
(
'build'
)
artifacts_cache_file
(
artifacts_archive_path
)
do
|
file
|
build
.
artifacts_file
=
file
end
artifacts_cache_file
(
artifacts_metadata_path
)
do
|
file
|
build
.
artifacts_metadata
=
file
artifacts_cache_file
(
artifacts_metadata_path
)
do
|
file
|
build
.
artifacts_metadata
=
file
end
end
end
if
%w(running success failed)
.
include?
(
build
.
status
)
# We need to set build trace after saving a build (id required)
build
.
trace
=
FFaker
::
Lorem
.
paragraphs
(
6
).
join
(
"
\n\n
"
)
if
%w(running success failed)
.
include?
(
build
.
status
)
# We need to set build trace after saving a build (id required)
build
.
trace
=
FFaker
::
Lorem
.
paragraphs
(
6
).
join
(
"
\n\n
"
)
end
end
end
...
...
db/schema.rb
View file @
1ba2ef4f
...
...
@@ -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
...
...
doc/api/services.md
View file @
1ba2ef4f
...
...
@@ -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
```
doc/ci/pipelines.md
View file @
1ba2ef4f
...
...
@@ -32,6 +32,41 @@ project.
Clicking on a pipeline will show the builds that were run for that pipeline.
## Badges
There are build status and test coverage report badges available.
Go to pipeline settings to see available badges and code you can use to embed
badges in the
`README.md`
or your website.
### Build status badge
You can access a build status badge image using following link:
```
http://example.gitlab.com/namespace/project/badges/branch/build.svg
```
### Test coverage report badge
GitLab makes it possible to define the regular expression for coverage report,
that each build log will be matched against. This means that each build in the
pipeline can have the test coverage percentage value defined.
You can access test coverage badge using following link:
```
http://example.gitlab.com/namespace/project/badges/branch/coverage.svg
```
If you would like to get the coverage report from the specific job, you can add
a
`job=coverage_job_name`
parameter to the URL. For example, it is possible to
use following Markdown code to embed the est coverage report into
`README.md`
:
```
markdown
![
coverage
](
http://gitlab.com/gitlab-org/gitlab-ce/badges/master/coverage.svg?job=coverage
)
```
[
builds
]:
#builds
[
jobs
]:
yaml/README.md#jobs
[
stages
]:
yaml/README.md#stages
...
...
doc/ci/quick_start/README.md
View file @
1ba2ef4f
...
...
@@ -218,21 +218,13 @@ project's settings.
For more information read the
[
Builds emails service documentation
](
../../project_services/builds_emails.md
)
.
## Builds badge
You can access a builds badge image using following link:
```
http://example.gitlab.com/namespace/project/badges/branch/build.svg
```
Awesome! You started using CI in GitLab!
## Examples
Visit the
[
examples README
][
examples
]
to see a list of examples using GitLab
CI with various languages.
Awesome! You started using CI in GitLab!
[
runner-install
]:
https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/tree/master#install-gitlab-runner
[
blog-ci
]:
https://about.gitlab.com/2015/05/06/why-were-replacing-gitlab-ci-jobs-with-gitlab-ci-dot-yml/
[
examples
]:
../examples/README.md
...
...
features/steps/dashboard/dashboard.rb
View file @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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/badge/base.rb
0 → 100644
View file @
1ba2ef4f
module
Gitlab
module
Badge
class
Base
def
entity
raise
NotImplementedError
end
def
status
raise
NotImplementedError
end
def
metadata
raise
NotImplementedError
end
def
template
raise
NotImplementedError
end
end
end
end
lib/gitlab/badge/build.rb
deleted
100644 → 0
View file @
882f97e4
module
Gitlab
module
Badge
##
# Build badge
#
class
Build
delegate
:key_text
,
:value_text
,
to: :template
def
initialize
(
project
,
ref
)
@project
=
project
@ref
=
ref
@sha
=
@project
.
commit
(
@ref
).
try
(
:sha
)
end
def
status
@project
.
pipelines
.
where
(
sha:
@sha
,
ref:
@ref
)
.
status
||
'unknown'
end
def
metadata
@metadata
||=
Build
::
Metadata
.
new
(
@project
,
@ref
)
end
def
template
@template
||=
Build
::
Template
.
new
(
status
)
end
end
end
end
lib/gitlab/badge/build/metadata.rb
View file @
1ba2ef4f
module
Gitlab
module
Badge
class
Build
module
Build
##
# Class that describes build badge metadata
#
class
Metadata
include
Gitlab
::
Application
.
routes
.
url_helpers
include
ActionView
::
Helpers
::
AssetTagHelper
include
ActionView
::
Helpers
::
UrlHelper
def
initialize
(
project
,
ref
)
@project
=
project
@ref
=
ref
end
def
to_html
link_to
(
image_tag
(
image_url
,
alt:
'build status'
),
link_url
)
class
Metadata
<
Badge
::
Metadata
def
initialize
(
badge
)
@project
=
badge
.
project
@ref
=
badge
.
ref
end
def
t
o_markdown
"[![build status](
#{
image_url
}
)](
#{
link_url
}
)"
def
t
itle
'build status'
end
def
image_url
...
...
lib/gitlab/badge/build/status.rb
0 → 100644
View file @
1ba2ef4f
module
Gitlab
module
Badge
module
Build
##
# Build status badge
#
class
Status
<
Badge
::
Base
attr_reader
:project
,
:ref
def
initialize
(
project
,
ref
)
@project
=
project
@ref
=
ref
@sha
=
@project
.
commit
(
@ref
).
try
(
:sha
)
end
def
entity
'build'
end
def
status
@project
.
pipelines
.
where
(
sha:
@sha
,
ref:
@ref
)
.
status
||
'unknown'
end
def
metadata
@metadata
||=
Build
::
Metadata
.
new
(
self
)
end
def
template
@template
||=
Build
::
Template
.
new
(
self
)
end
end
end
end
end
lib/gitlab/badge/build/template.rb
View file @
1ba2ef4f
module
Gitlab
module
Badge
class
Build
module
Build
##
# Class that represents a build badge template.
#
# Template object will be passed to badge.svg.erb template.
#
class
Template
class
Template
<
Badge
::
Template
STATUS_COLOR
=
{
success:
'#4c1'
,
failed:
'#e05d44'
,
...
...
@@ -17,16 +17,17 @@ module Gitlab
unknown:
'#9f9f9f'
}
def
initialize
(
status
)
@status
=
status
def
initialize
(
badge
)
@entity
=
badge
.
entity
@status
=
badge
.
status
end
def
key_text
'build'
@entity
.
to_s
end
def
value_text
@status
@status
.
to_s
end
def
key_width
...
...
@@ -37,25 +38,8 @@ module Gitlab
54
end
def
key_color
'#555'
end
def
value_color
STATUS_COLOR
[
@status
.
to_sym
]
||
STATUS_COLOR
[
:unknown
]
end
def
key_text_anchor
key_width
/
2
end
def
value_text_anchor
key_width
+
(
value_width
/
2
)
end
def
width
key_width
+
value_width
STATUS_COLOR
[
@status
.
to_sym
]
||
STATUS_COLOR
[
:unknown
]
end
end
end
...
...
lib/gitlab/badge/coverage/metadata.rb
0 → 100644
View file @
1ba2ef4f
module
Gitlab
module
Badge
module
Coverage
##
# Class that describes coverage badge metadata
#
class
Metadata
<
Badge
::
Metadata
def
initialize
(
badge
)
@project
=
badge
.
project
@ref
=
badge
.
ref
@job
=
badge
.
job
end
def
title
'coverage report'
end
def
image_url
coverage_namespace_project_badges_url
(
@project
.
namespace
,
@project
,
@ref
,
format: :svg
)
end
def
link_url
namespace_project_commits_url
(
@project
.
namespace
,
@project
,
id:
@ref
)
end
end
end
end
end
lib/gitlab/badge/coverage/report.rb
0 → 100644
View file @
1ba2ef4f
module
Gitlab
module
Badge
module
Coverage
##
# Test coverage report badge
#
class
Report
<
Badge
::
Base
attr_reader
:project
,
:ref
,
:job
def
initialize
(
project
,
ref
,
job
=
nil
)
@project
=
project
@ref
=
ref
@job
=
job
@pipeline
=
@project
.
pipelines
.
where
(
ref:
@ref
)
.
where
(
sha:
@project
.
commit
(
@ref
).
try
(
:sha
))
.
first
end
def
entity
'coverage'
end
def
status
@coverage
||=
raw_coverage
return
unless
@coverage
@coverage
.
to_i
end
def
metadata
@metadata
||=
Coverage
::
Metadata
.
new
(
self
)
end
def
template
@template
||=
Coverage
::
Template
.
new
(
self
)
end
private
def
raw_coverage
return
unless
@pipeline
if
@job
.
blank?
@pipeline
.
coverage
else
@pipeline
.
builds
.
find_by
(
name:
@job
)
.
try
(
:coverage
)
end
end
end
end
end
end
lib/gitlab/badge/coverage/template.rb
0 → 100644
View file @
1ba2ef4f
module
Gitlab
module
Badge
module
Coverage
##
# Class that represents a coverage badge template.
#
# Template object will be passed to badge.svg.erb template.
#
class
Template
<
Badge
::
Template
STATUS_COLOR
=
{
good:
'#4c1'
,
acceptable:
'#a3c51c'
,
medium:
'#dfb317'
,
low:
'#e05d44'
,
unknown:
'#9f9f9f'
}
def
initialize
(
badge
)
@entity
=
badge
.
entity
@status
=
badge
.
status
end
def
key_text
@entity
.
to_s
end
def
value_text
@status
?
"
#{
@status
}
%"
:
'unknown'
end
def
key_width
62
end
def
value_width
@status
?
36
:
58
end
def
value_color
case
@status
when
95
..
100
then
STATUS_COLOR
[
:good
]
when
90
..
95
then
STATUS_COLOR
[
:acceptable
]
when
75
..
90
then
STATUS_COLOR
[
:medium
]
when
0
..
75
then
STATUS_COLOR
[
:low
]
else
STATUS_COLOR
[
:unknown
]
end
end
end
end
end
end
lib/gitlab/badge/metadata.rb
0 → 100644
View file @
1ba2ef4f
module
Gitlab
module
Badge
##
# Abstract class for badge metadata
#
class
Metadata
include
Gitlab
::
Application
.
routes
.
url_helpers
include
ActionView
::
Helpers
::
AssetTagHelper
include
ActionView
::
Helpers
::
UrlHelper
def
initialize
(
badge
)
@badge
=
badge
end
def
to_html
link_to
(
image_tag
(
image_url
,
alt:
title
),
link_url
)
end
def
to_markdown
"[![
#{
title
}
](
#{
image_url
}
)](
#{
link_url
}
)"
end
def
title
raise
NotImplementedError
end
def
image_url
raise
NotImplementedError
end
def
link_url
raise
NotImplementedError
end
end
end
end
lib/gitlab/badge/template.rb
0 → 100644
View file @
1ba2ef4f
module
Gitlab
module
Badge
##
# Abstract template class for badges
#
class
Template
def
initialize
(
badge
)
@entity
=
badge
.
entity
@status
=
badge
.
status
end
def
key_text
raise
NotImplementedError
end
def
value_text
raise
NotImplementedError
end
def
key_width
raise
NotImplementedError
end
def
value_width
raise
NotImplementedError
end
def
value_color
raise
NotImplementedError
end
def
key_color
'#555'
end
def
key_text_anchor
key_width
/
2
end
def
value_text_anchor
key_width
+
(
value_width
/
2
)
end
def
width
key_width
+
value_width
end
end
end
end
lib/gitlab/checks/change_access.rb
View file @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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
View file @
1ba2ef4f
...
...
@@ -7,12 +7,13 @@ describe Admin::GroupsController do
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
)
Sidekiq
::
Testing
.
fake!
do
expect
{
delete
:destroy
,
id:
project
.
group
.
path
}.
to
change
(
GroupDestroyWorker
.
jobs
,
:size
).
by
(
1
)
end
end
it
'redirects to the admin group path'
do
...
...
spec/controllers/groups_controller_spec.rb
View file @
1ba2ef4f
...
...
@@ -89,12 +89,13 @@ describe GroupsController do
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
)
Sidekiq
::
Testing
.
fake!
do
expect
{
delete
:destroy
,
id:
group
.
path
}.
to
change
(
GroupDestroyWorker
.
jobs
,
:size
).
by
(
1
)
end
end
it
'redirects to the root path'
do
...
...
spec/features/issuables/default_sort_order_spec.rb
View file @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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/badges/coverage_spec.rb
0 → 100644
View file @
1ba2ef4f
require
'spec_helper'
feature
'test coverage badge'
do
given!
(
:user
)
{
create
(
:user
)
}
given!
(
:project
)
{
create
(
:project
,
:private
)
}
given!
(
:pipeline
)
do
create
(
:ci_pipeline
,
project:
project
,
ref:
'master'
,
sha:
project
.
commit
.
id
)
end
context
'when user has access to view badge'
do
background
do
project
.
team
<<
[
user
,
:developer
]
login_as
(
user
)
end
scenario
'user requests coverage badge image for pipeline'
do
create_job
(
coverage:
100
,
name:
'test:1'
)
create_job
(
coverage:
90
,
name:
'test:2'
)
show_test_coverage_badge
expect_coverage_badge
(
'95%'
)
end
scenario
'user requests coverage badge for specific job'
do
create_job
(
coverage:
50
,
name:
'test:1'
)
create_job
(
coverage:
50
,
name:
'test:2'
)
create_job
(
coverage:
85
,
name:
'coverage'
)
show_test_coverage_badge
(
job:
'coverage'
)
expect_coverage_badge
(
'85%'
)
end
scenario
'user requests coverage badge for pipeline without coverage'
do
create_job
(
coverage:
nil
,
name:
'test'
)
show_test_coverage_badge
expect_coverage_badge
(
'unknown'
)
end
end
context
'when user does not have access to view badge'
do
background
{
login_as
(
user
)
}
scenario
'user requests test coverage badge image'
do
show_test_coverage_badge
expect
(
page
).
to
have_http_status
(
404
)
end
end
def
create_job
(
coverage
:,
name
:)
create
(
:ci_build
,
name:
name
,
coverage:
coverage
,
pipeline:
pipeline
)
end
def
show_test_coverage_badge
(
job:
nil
)
visit
coverage_namespace_project_badges_path
(
project
.
namespace
,
project
,
ref: :master
,
job:
job
,
format: :svg
)
end
def
expect_coverage_badge
(
coverage
)
svg
=
Nokogiri
::
XML
.
parse
(
page
.
body
)
expect
(
page
.
response_headers
[
'Content-Type'
]).
to
include
(
'image/svg+xml'
)
expect
(
svg
.
at
(
%Q{text:contains("
#{
coverage
}
")}
)).
to
be_truthy
end
end
spec/features/projects/badges/list_spec.rb
View file @
1ba2ef4f
...
...
@@ -9,25 +9,43 @@ feature 'list of badges' do
visit
namespace_project_pipelines_settings_path
(
project
.
namespace
,
project
)
end
scenario
'user displays list of badges'
do
expect
(
page
).
to
have_content
'build status'
expect
(
page
).
to
have_content
'Markdown'
expect
(
page
).
to
have_content
'HTML'
expect
(
page
).
to
have_css
(
'.highlight'
,
count:
2
)
expect
(
page
).
to
have_xpath
(
"//img[@alt='build status']"
)
page
.
within
(
'.highlight'
,
match: :first
)
do
expect
(
page
).
to
have_content
'badges/master/build.svg'
scenario
'user wants to see build status badge'
do
page
.
within
(
'.build-status'
)
do
expect
(
page
).
to
have_content
'build status'
expect
(
page
).
to
have_content
'Markdown'
expect
(
page
).
to
have_content
'HTML'
expect
(
page
).
to
have_css
(
'.highlight'
,
count:
2
)
expect
(
page
).
to
have_xpath
(
"//img[@alt='build status']"
)
page
.
within
(
'.highlight'
,
match: :first
)
do
expect
(
page
).
to
have_content
'badges/master/build.svg'
end
end
end
scenario
'user changes current ref on badges list page'
,
js:
true
do
first
(
'.js-project-refs-dropdown'
).
click
scenario
'user wants to see coverage report badge'
do
page
.
within
(
'.coverage-report'
)
do
expect
(
page
).
to
have_content
'coverage report'
expect
(
page
).
to
have_content
'Markdown'
expect
(
page
).
to
have_content
'HTML'
expect
(
page
).
to
have_css
(
'.highlight'
,
count:
2
)
expect
(
page
).
to
have_xpath
(
"//img[@alt='coverage report']"
)
page
.
within
'.project-refs-form'
do
click_link
'improve/awesome'
page
.
within
(
'.highlight'
,
match: :first
)
do
expect
(
page
).
to
have_content
'badges/master/coverage.svg'
end
end
end
scenario
'user changes current ref of build status badge'
,
js:
true
do
page
.
within
(
'.build-status'
)
do
first
(
'.js-project-refs-dropdown'
).
click
expect
(
page
).
to
have_content
'badges/improve/awesome/build.svg'
page
.
within
'.project-refs-form'
do
click_link
'improve/awesome'
end
expect
(
page
).
to
have_content
'badges/improve/awesome/build.svg'
end
end
end
spec/features/projects/files/editing_a_file_spec.rb
0 → 100644
View file @
1ba2ef4f
require
'spec_helper'
feature
'User wants to edit a file'
,
feature:
true
do
include
WaitForAjax
let
(
:project
)
{
create
(
:project
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:commit_params
)
do
{
source_branch:
project
.
default_branch
,
target_branch:
project
.
default_branch
,
commit_message:
"Committing First Update"
,
file_path:
".gitignore"
,
file_content:
"First Update"
,
last_commit_sha:
Gitlab
::
Git
::
Commit
.
last_for_path
(
project
.
repository
,
project
.
default_branch
,
".gitignore"
).
sha
}
end
background
do
project
.
team
<<
[
user
,
:master
]
login_as
user
visit
namespace_project_edit_blob_path
(
project
.
namespace
,
project
,
File
.
join
(
project
.
default_branch
,
'.gitignore'
))
end
scenario
'file has been updated since the user opened the edit page'
do
Files
::
UpdateService
.
new
(
project
,
user
,
commit_params
).
execute
click_button
'Commit Changes'
expect
(
page
).
to
have_content
'Someone edited the file the same time you did.'
end
end
spec/features/projects/files/project_owner_creates_license_file_spec.rb
View file @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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/badge/build/metadata_spec.rb
View file @
1ba2ef4f
require
'spec_helper'
require
'lib/gitlab/badge/shared/metadata'
describe
Gitlab
::
Badge
::
Build
::
Metadata
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:branch
)
{
'master'
}
let
(
:badge
)
{
described_class
.
new
(
project
,
branch
)
}
let
(
:badge
)
{
double
(
project:
create
(
:project
),
ref:
'feature'
)
}
let
(
:metadata
)
{
described_class
.
new
(
badge
)
}
describe
'#to_html'
do
let
(
:html
)
{
Nokogiri
::
HTML
.
parse
(
badge
.
to_html
)
}
let
(
:a_href
)
{
html
.
at
(
'a'
)
}
it_behaves_like
'badge metadata'
it
'points to link'
do
expect
(
a_href
[
:href
]).
to
eq
badge
.
link_url
end
it
'contains clickable image'
do
expect
(
a_href
.
children
.
first
.
name
).
to
eq
'img'
describe
'#title'
do
it
'returns build status title'
do
expect
(
metadata
.
title
).
to
eq
'build status'
end
end
describe
'#to_markdown'
do
subject
{
badge
.
to_markdown
}
it
{
is_expected
.
to
include
badge
.
image_url
}
it
{
is_expected
.
to
include
badge
.
link_url
}
end
describe
'#image_url'
do
subject
{
badge
.
image_url
}
it
{
is_expected
.
to
include
"badges/
#{
branch
}
/build.svg"
}
it
'returns valid url'
do
expect
(
metadata
.
image_url
).
to
include
'badges/feature/build.svg'
end
end
describe
'#link_url'
do
subject
{
badge
.
link_url
}
it
{
is_expected
.
to
include
"commits/
#{
branch
}
"
}
it
'returns valid link'
do
expect
(
metadata
.
link_url
).
to
include
'commits/feature'
end
end
end
spec/lib/gitlab/badge/build_spec.rb
→
spec/lib/gitlab/badge/build
/status
_spec.rb
View file @
1ba2ef4f
require
'spec_helper'
describe
Gitlab
::
Badge
::
Build
do
describe
Gitlab
::
Badge
::
Build
::
Status
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:sha
)
{
project
.
commit
.
sha
}
let
(
:branch
)
{
'master'
}
let
(
:badge
)
{
described_class
.
new
(
project
,
branch
)
}
describe
'#entity'
do
it
'always says build'
do
expect
(
badge
.
entity
).
to
eq
'build'
end
end
describe
'#template'
do
it
'returns badge template'
do
expect
(
badge
.
template
.
key_text
).
to
eq
'build'
end
end
describe
'#metadata'
do
it
'returns badge metadata'
do
expect
(
badge
.
metadata
.
image_url
)
...
...
@@ -13,12 +25,6 @@ describe Gitlab::Badge::Build do
end
end
describe
'#key_text'
do
it
'always says build'
do
expect
(
badge
.
key_text
).
to
eq
'build'
end
end
context
'build exists'
do
let!
(
:build
)
{
create_build
(
project
,
sha
,
branch
)
}
...
...
@@ -30,12 +36,6 @@ describe Gitlab::Badge::Build do
expect
(
badge
.
status
).
to
eq
'success'
end
end
describe
'#value_text'
do
it
'returns correct value text'
do
expect
(
badge
.
value_text
).
to
eq
'success'
end
end
end
context
'build failed'
do
...
...
@@ -46,12 +46,6 @@ describe Gitlab::Badge::Build do
expect
(
badge
.
status
).
to
eq
'failed'
end
end
describe
'#value_text'
do
it
'has correct value text'
do
expect
(
badge
.
value_text
).
to
eq
'failed'
end
end
end
context
'when outdated pipeline for given ref exists'
do
...
...
@@ -87,12 +81,6 @@ describe Gitlab::Badge::Build do
expect
(
badge
.
status
).
to
eq
'unknown'
end
end
describe
'#value_text'
do
it
'has correct value text'
do
expect
(
badge
.
value_text
).
to
eq
'unknown'
end
end
end
def
create_build
(
project
,
sha
,
branch
)
...
...
spec/lib/gitlab/badge/build/template_spec.rb
View file @
1ba2ef4f
require
'spec_helper'
describe
Gitlab
::
Badge
::
Build
::
Template
do
let
(
:
status
)
{
'success'
}
let
(
:template
)
{
described_class
.
new
(
status
)
}
let
(
:
badge
)
{
double
(
entity:
'build'
,
status:
'success'
)
}
let
(
:template
)
{
described_class
.
new
(
badge
)
}
describe
'#key_text'
do
it
'is always says build'
do
...
...
@@ -34,15 +34,15 @@ describe Gitlab::Badge::Build::Template do
describe
'#value_color'
do
context
'when status is success'
do
let
(
:status
)
{
'success'
}
it
'has expected color'
do
expect
(
template
.
value_color
).
to
eq
'#4c1'
end
end
context
'when status is failed'
do
let
(
:status
)
{
'failed'
}
before
do
allow
(
badge
).
to
receive
(
:status
).
and_return
(
'failed'
)
end
it
'has expected color'
do
expect
(
template
.
value_color
).
to
eq
'#e05d44'
...
...
@@ -50,7 +50,9 @@ describe Gitlab::Badge::Build::Template do
end
context
'when status is running'
do
let
(
:status
)
{
'running'
}
before
do
allow
(
badge
).
to
receive
(
:status
).
and_return
(
'running'
)
end
it
'has expected color'
do
expect
(
template
.
value_color
).
to
eq
'#dfb317'
...
...
@@ -58,7 +60,9 @@ describe Gitlab::Badge::Build::Template do
end
context
'when status is unknown'
do
let
(
:status
)
{
'unknown'
}
before
do
allow
(
badge
).
to
receive
(
:status
).
and_return
(
'unknown'
)
end
it
'has expected color'
do
expect
(
template
.
value_color
).
to
eq
'#9f9f9f'
...
...
@@ -66,7 +70,9 @@ describe Gitlab::Badge::Build::Template do
end
context
'when status does not match any known statuses'
do
let
(
:status
)
{
'invalid status'
}
before
do
allow
(
badge
).
to
receive
(
:status
).
and_return
(
'invalid'
)
end
it
'has expected color'
do
expect
(
template
.
value_color
).
to
eq
'#9f9f9f'
...
...
spec/lib/gitlab/badge/coverage/metadata_spec.rb
0 → 100644
View file @
1ba2ef4f
require
'spec_helper'
require
'lib/gitlab/badge/shared/metadata'
describe
Gitlab
::
Badge
::
Coverage
::
Metadata
do
let
(
:badge
)
do
double
(
project:
create
(
:project
),
ref:
'feature'
,
job:
'test'
)
end
let
(
:metadata
)
{
described_class
.
new
(
badge
)
}
it_behaves_like
'badge metadata'
describe
'#title'
do
it
'returns coverage report title'
do
expect
(
metadata
.
title
).
to
eq
'coverage report'
end
end
describe
'#image_url'
do
it
'returns valid url'
do
expect
(
metadata
.
image_url
).
to
include
'badges/feature/coverage.svg'
end
end
describe
'#link_url'
do
it
'returns valid link'
do
expect
(
metadata
.
link_url
).
to
include
'commits/feature'
end
end
end
spec/lib/gitlab/badge/coverage/report_spec.rb
0 → 100644
View file @
1ba2ef4f
require
'spec_helper'
describe
Gitlab
::
Badge
::
Coverage
::
Report
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:job_name
)
{
nil
}
let
(
:badge
)
do
described_class
.
new
(
project
,
'master'
,
job_name
)
end
describe
'#entity'
do
it
'describes a coverage'
do
expect
(
badge
.
entity
).
to
eq
'coverage'
end
end
describe
'#metadata'
do
it
'returns correct metadata'
do
expect
(
badge
.
metadata
.
image_url
).
to
include
'coverage.svg'
end
end
describe
'#template'
do
it
'returns correct template'
do
expect
(
badge
.
template
.
key_text
).
to
eq
'coverage'
end
end
shared_examples
'unknown coverage report'
do
context
'particular job specified'
do
let
(
:job_name
)
{
''
}
it
'returns nil'
do
expect
(
badge
.
status
).
to
be_nil
end
end
context
'particular job not specified'
do
let
(
:job_name
)
{
nil
}
it
'returns nil'
do
expect
(
badge
.
status
).
to
be_nil
end
end
end
context
'pipeline exists'
do
let!
(
:pipeline
)
do
create
(
:ci_pipeline
,
project:
project
,
sha:
project
.
commit
.
id
,
ref:
'master'
)
end
context
'builds exist'
do
before
do
create
(
:ci_build
,
name:
'first'
,
pipeline:
pipeline
,
coverage:
40
)
create
(
:ci_build
,
pipeline:
pipeline
,
coverage:
60
)
end
context
'particular job specified'
do
let
(
:job_name
)
{
'first'
}
it
'returns coverage for the particular job'
do
expect
(
badge
.
status
).
to
eq
40
end
end
context
'particular job not specified'
do
let
(
:job_name
)
{
''
}
it
'returns arithemetic mean for the pipeline'
do
expect
(
badge
.
status
).
to
eq
50
end
end
end
context
'builds do not exist'
do
it_behaves_like
'unknown coverage report'
context
'particular job specified'
do
let
(
:job_name
)
{
'nonexistent'
}
it
'retruns nil'
do
expect
(
badge
.
status
).
to
be_nil
end
end
end
end
context
'pipeline does not exist'
do
it_behaves_like
'unknown coverage report'
end
end
spec/lib/gitlab/badge/coverage/template_spec.rb
0 → 100644
View file @
1ba2ef4f
require
'spec_helper'
describe
Gitlab
::
Badge
::
Coverage
::
Template
do
let
(
:badge
)
{
double
(
entity:
'coverage'
,
status:
90
)
}
let
(
:template
)
{
described_class
.
new
(
badge
)
}
describe
'#key_text'
do
it
'is always says coverage'
do
expect
(
template
.
key_text
).
to
eq
'coverage'
end
end
describe
'#value_text'
do
context
'when coverage is known'
do
it
'returns coverage percentage'
do
expect
(
template
.
value_text
).
to
eq
'90%'
end
end
context
'when coverage is unknown'
do
before
do
allow
(
badge
).
to
receive
(
:status
).
and_return
(
nil
)
end
it
'returns string that says coverage is unknown'
do
expect
(
template
.
value_text
).
to
eq
'unknown'
end
end
end
describe
'#key_width'
do
it
'has a fixed key width'
do
expect
(
template
.
key_width
).
to
eq
62
end
end
describe
'#value_width'
do
context
'when coverage is known'
do
it
'is narrower when coverage is known'
do
expect
(
template
.
value_width
).
to
eq
36
end
end
context
'when coverage is unknown'
do
before
do
allow
(
badge
).
to
receive
(
:status
).
and_return
(
nil
)
end
it
'is wider when coverage is unknown to fit text'
do
expect
(
template
.
value_width
).
to
eq
58
end
end
end
describe
'#key_color'
do
it
'always has the same color'
do
expect
(
template
.
key_color
).
to
eq
'#555'
end
end
describe
'#value_color'
do
context
'when coverage is good'
do
before
do
allow
(
badge
).
to
receive
(
:status
).
and_return
(
98
)
end
it
'is green'
do
expect
(
template
.
value_color
).
to
eq
'#4c1'
end
end
context
'when coverage is acceptable'
do
before
do
allow
(
badge
).
to
receive
(
:status
).
and_return
(
90
)
end
it
'is green-orange'
do
expect
(
template
.
value_color
).
to
eq
'#a3c51c'
end
end
context
'when coverage is medium'
do
before
do
allow
(
badge
).
to
receive
(
:status
).
and_return
(
75
)
end
it
'is orange-yellow'
do
expect
(
template
.
value_color
).
to
eq
'#dfb317'
end
end
context
'when coverage is low'
do
before
do
allow
(
badge
).
to
receive
(
:status
).
and_return
(
50
)
end
it
'is red'
do
expect
(
template
.
value_color
).
to
eq
'#e05d44'
end
end
context
'when coverage is unknown'
do
before
do
allow
(
badge
).
to
receive
(
:status
).
and_return
(
nil
)
end
it
'is grey'
do
expect
(
template
.
value_color
).
to
eq
'#9f9f9f'
end
end
end
describe
'#width'
do
context
'when coverage is known'
do
it
'returns the key width plus value width'
do
expect
(
template
.
width
).
to
eq
98
end
end
context
'when coverage is unknown'
do
before
do
allow
(
badge
).
to
receive
(
:status
).
and_return
(
nil
)
end
it
'returns key width plus wider value width'
do
expect
(
template
.
width
).
to
eq
120
end
end
end
end
spec/lib/gitlab/badge/shared/metadata.rb
0 → 100644
View file @
1ba2ef4f
shared_examples
'badge metadata'
do
describe
'#to_html'
do
let
(
:html
)
{
Nokogiri
::
HTML
.
parse
(
metadata
.
to_html
)
}
let
(
:a_href
)
{
html
.
at
(
'a'
)
}
it
'points to link'
do
expect
(
a_href
[
:href
]).
to
eq
metadata
.
link_url
end
it
'contains clickable image'
do
expect
(
a_href
.
children
.
first
.
name
).
to
eq
'img'
end
end
describe
'#to_markdown'
do
subject
{
metadata
.
to_markdown
}
it
{
is_expected
.
to
include
metadata
.
image_url
}
it
{
is_expected
.
to
include
metadata
.
link_url
}
end
end
spec/lib/gitlab/checks/change_access_spec.rb
0 → 100644
View file @
1ba2ef4f
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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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/irker_service_spec.rb
View file @
1ba2ef4f
...
...
@@ -52,19 +52,20 @@ describe IrkerService, models: true do
let
(
:colorize_messages
)
{
'1'
}
before
do
@irker_server
=
TCPServer
.
new
'localhost'
,
0
allow
(
irker
).
to
receive_messages
(
active:
true
,
project:
project
,
project_id:
project
.
id
,
service_hook:
true
,
server_host:
'localhost'
,
server_port:
6659
,
server_host:
@irker_server
.
addr
[
2
]
,
server_port:
@irker_server
.
addr
[
1
]
,
default_irc_uri:
'irc://chat.freenode.net/'
,
recipients:
recipients
,
colorize_messages:
colorize_messages
)
irker
.
valid?
@irker_server
=
TCPServer
.
new
'localhost'
,
6659
end
after
do
...
...
spec/models/project_services/pivotaltracker_service_spec.rb
View file @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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/services/files/update_service_spec.rb
0 → 100644
View file @
1ba2ef4f
require
"spec_helper"
describe
Files
::
UpdateService
do
subject
{
described_class
.
new
(
project
,
user
,
commit_params
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:file_path
)
{
'files/ruby/popen.rb'
}
let
(
:new_contents
)
{
"New Content"
}
let
(
:commit_params
)
do
{
file_path:
file_path
,
commit_message:
"Update File"
,
file_content:
new_contents
,
file_content_encoding:
"text"
,
last_commit_sha:
last_commit_sha
,
source_project:
project
,
source_branch:
project
.
default_branch
,
target_branch:
project
.
default_branch
,
}
end
before
do
project
.
team
<<
[
user
,
:master
]
end
describe
"#execute"
do
context
"when the file's last commit sha does not match the supplied last_commit_sha"
do
let
(
:last_commit_sha
)
{
"foo"
}
it
"returns a hash with the correct error message and a :error status "
do
expect
{
subject
.
execute
}.
to
raise_error
(
Files
::
UpdateService
::
FileChangedError
,
"You are attempting to update a file that has changed since you started editing it."
)
end
end
context
"when the file's last commit sha does match the supplied last_commit_sha"
do
let
(
:last_commit_sha
)
{
Gitlab
::
Git
::
Commit
.
last_for_path
(
project
.
repository
,
project
.
default_branch
,
file_path
).
sha
}
it
"returns a hash with the :success status "
do
results
=
subject
.
execute
expect
(
results
).
to
match
({
status: :success
})
end
it
"updates the file with the new contents"
do
subject
.
execute
results
=
project
.
repository
.
blob_at_branch
(
project
.
default_branch
,
file_path
)
expect
(
results
.
data
).
to
eq
(
new_contents
)
end
end
context
"when the last_commit_sha is not supplied"
do
let
(
:commit_params
)
do
{
file_path:
file_path
,
commit_message:
"Update File"
,
file_content:
new_contents
,
file_content_encoding:
"text"
,
source_project:
project
,
source_branch:
project
.
default_branch
,
target_branch:
project
.
default_branch
,
}
end
it
"returns a hash with the :success status "
do
results
=
subject
.
execute
expect
(
results
).
to
match
({
status: :success
})
end
it
"updates the file with the new contents"
do
subject
.
execute
results
=
project
.
repository
.
blob_at_branch
(
project
.
default_branch
,
file_path
)
expect
(
results
.
data
).
to
eq
(
new_contents
)
end
end
end
end
spec/services/merge_requests/get_urls_service_spec.rb
View file @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
...
...
@@ -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 @
1ba2ef4f
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
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