Commit 2016f367 authored by Kamil Trzcinski's avatar Kamil Trzcinski

Merge remote-tracking branch 'origin/master' into cs-warn-on-failure

parents 737e5226 79b02e40
Please view this file on the master branch, on stable branches it's out of date. Please view this file on the master branch, on stable branches it's out of date.
v 8.11.0 (unreleased) v 8.11.0 (unreleased)
- Fix of 'Commits being passed to custom hooks are already reachable when using the UI' - Fix of 'Commits being passed to custom hooks are already reachable when using the UI'
- Limit git rev-list output count to one in forced push check
v 8.10.0 (unreleased) v 8.10.0 (unreleased)
- Fix profile activity heatmap to show correct day name (eanplatter) - Fix profile activity heatmap to show correct day name (eanplatter)
...@@ -35,6 +36,7 @@ v 8.10.0 (unreleased) ...@@ -35,6 +36,7 @@ v 8.10.0 (unreleased)
- Added day name to contribution calendar tooltips - Added day name to contribution calendar tooltips
- Make images fit to the size of the viewport !4810 - Make images fit to the size of the viewport !4810
- Fix check for New Branch button on Issue page !4630 (winniehell) - Fix check for New Branch button on Issue page !4630 (winniehell)
- Fix GFM autocomplete not working on wiki pages
- Fix MR-auto-close text added to description. !4836 - Fix MR-auto-close text added to description. !4836
- Support U2F devices in Firefox. !5177 - Support U2F devices in Firefox. !5177
- Fix issue, preventing users w/o push access to sort tags !5105 (redetection) - Fix issue, preventing users w/o push access to sort tags !5105 (redetection)
......
...@@ -578,7 +578,7 @@ GEM ...@@ -578,7 +578,7 @@ GEM
railties (>= 4.2.0, < 5.1) railties (>= 4.2.0, < 5.1)
rinku (2.0.0) rinku (2.0.0)
rotp (2.1.2) rotp (2.1.2)
rouge (2.0.3) rouge (2.0.5)
rqrcode (0.7.0) rqrcode (0.7.0)
chunky_png chunky_png
rqrcode-rails3 (0.1.7) rqrcode-rails3 (0.1.7)
......
...@@ -49,6 +49,17 @@ ...@@ -49,6 +49,17 @@
border-color: $border-dark; border-color: $border-dark;
color: $color; color: $color;
} }
svg {
path {
fill: $color;
}
use {
stroke: $color;
}
}
} }
@mixin btn-green { @mixin btn-green {
...@@ -173,6 +184,13 @@ ...@@ -173,6 +184,13 @@
.caret { .caret {
margin-left: 5px; margin-left: 5px;
} }
svg {
height: 15px;
width: auto;
position: relative;
top: 2px;
}
} }
.btn-lg { .btn-lg {
......
...@@ -198,6 +198,10 @@ header.header-pinned-nav { ...@@ -198,6 +198,10 @@ header.header-pinned-nav {
.sidebar-collapsed-icon { .sidebar-collapsed-icon {
cursor: pointer; cursor: pointer;
.btn {
background-color: $gray-light;
}
} }
} }
......
...@@ -122,7 +122,8 @@ ...@@ -122,7 +122,8 @@
button { button {
float: right; float: right;
padding: 3px 5px; padding: 1px 5px;
background-color: $gray-light;
} }
} }
......
...@@ -78,6 +78,14 @@ form.edit-issue { ...@@ -78,6 +78,14 @@ form.edit-issue {
} }
} }
.merge-request-ci-status {
svg {
margin-right: 4px;
position: relative;
top: 1px;
}
}
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
.issue-btn-group { .issue-btn-group {
width: 100%; width: 100%;
......
...@@ -60,8 +60,10 @@ ...@@ -60,8 +60,10 @@
.ci_widget { .ci_widget {
border-bottom: 1px solid #eef0f2; border-bottom: 1px solid #eef0f2;
i { svg {
margin-right: 4px; margin-right: 4px;
position: relative;
top: 1px;
} }
&.ci-success { &.ci-success {
...@@ -204,6 +206,16 @@ ...@@ -204,6 +206,16 @@
.merge-request-title { .merge-request-title {
margin-bottom: 2px; margin-bottom: 2px;
.ci-status-link {
svg {
height: 16px;
width: 16px;
position: relative;
top: 3px;
}
}
} }
} }
......
...@@ -49,6 +49,14 @@ ...@@ -49,6 +49,14 @@
.commit-link { .commit-link {
.ci-status {
svg {
top: 1px;
margin-right: 0;
}
}
a:hover { a:hover {
text-decoration: none; text-decoration: none;
} }
...@@ -124,6 +132,15 @@ ...@@ -124,6 +132,15 @@
} }
} }
.stage-cell {
svg {
height: 18px;
width: 18px;
vertical-align: middle;
}
}
.duration, .duration,
.finished-at { .finished-at {
color: $table-text-gray; color: $table-text-gray;
......
...@@ -129,6 +129,17 @@ ...@@ -129,6 +129,17 @@
color: $layout-link-gray; color: $layout-link-gray;
} }
svg {
path {
fill: $layout-link-gray;
}
use {
stroke: $layout-link-gray;
}
}
.fa-caret-down { .fa-caret-down {
margin-left: 3px; margin-left: 3px;
} }
...@@ -486,6 +497,11 @@ pre.light-well { ...@@ -486,6 +497,11 @@ pre.light-well {
> span { > span {
margin-left: 10px; margin-left: 10px;
} }
svg {
position: relative;
top: 2px;
}
} }
} }
......
...@@ -42,6 +42,14 @@ ...@@ -42,6 +42,14 @@
color: $blue-normal; color: $blue-normal;
border-color: $blue-normal; border-color: $blue-normal;
} }
svg {
height: 13px;
width: 13px;
position: relative;
top: 1px;
margin: 0 3px;
}
} }
.ci-status-icon-success { .ci-status-icon-success {
......
.tag-buttons {
line-height: 40px;
.btn:not(.dropdown-toggle) {
margin-left: 10px;
}
}
...@@ -29,20 +29,20 @@ module CiStatusHelper ...@@ -29,20 +29,20 @@ module CiStatusHelper
icon_name = icon_name =
case status case status
when 'success' when 'success'
'check' 'icon_status_success'
when 'success_with_warnings' when 'success_with_warnings'
'exclamation-triangle' 'icon_status_warning'
when 'failed' when 'failed'
'close' 'icon_status_failed'
when 'pending' when 'pending'
'clock-o' 'icon_status_pending'
when 'running' when 'running'
'spinner' 'icon_status_running'
else else
'circle' 'icon_status_cancel'
end end
icon(icon_name + ' fw') custom_icon(icon_name)
end end
def render_commit_status(commit, tooltip_placement: 'auto left', cssclass: '') def render_commit_status(commit, tooltip_placement: 'auto left', cssclass: '')
......
module TimeHelper module TimeHelper
def duration_in_words(finished_at, started_at)
if finished_at && started_at
interval_in_seconds = finished_at.to_i - started_at.to_i
elsif started_at
interval_in_seconds = Time.now.to_i - started_at.to_i
end
time_interval_in_words(interval_in_seconds)
end
def time_interval_in_words(interval_in_seconds) def time_interval_in_words(interval_in_seconds)
minutes = interval_in_seconds / 60 minutes = interval_in_seconds / 60
seconds = interval_in_seconds - minutes * 60 seconds = interval_in_seconds - minutes * 60
...@@ -25,9 +15,19 @@ module TimeHelper ...@@ -25,9 +15,19 @@ module TimeHelper
end end
def duration_in_numbers(finished_at, started_at) def duration_in_numbers(finished_at, started_at)
diff_in_seconds = finished_at.to_i - started_at.to_i interval = interval_in_seconds(started_at, finished_at)
time_format = diff_in_seconds < 1.hour ? "%M:%S" : "%H:%M:%S" time_format = interval < 1.hour ? "%M:%S" : "%H:%M:%S"
Time.at(diff_in_seconds).utc.strftime(time_format) Time.at(interval).utc.strftime(time_format)
end
private
def interval_in_seconds(started_at, finished_at = nil)
if started_at && finished_at
finished_at.to_i - started_at.to_i
elsif started_at
Time.now.to_i - started_at.to_i
end
end end
end end
...@@ -854,7 +854,7 @@ class User < ActiveRecord::Base ...@@ -854,7 +854,7 @@ class User < ActiveRecord::Base
groups.joins(:shared_projects).select(:project_id)] groups.joins(:shared_projects).select(:project_id)]
if min_access_level if min_access_level
scope = { access_level: Gitlab::Access.values.select { |access| access >= min_access_level } } scope = { access_level: Gitlab::Access.all_values.select { |access| access >= min_access_level } }
relations = [relations.shift] + relations.map { |relation| relation.where(members: scope) } relations = [relations.shift] + relations.map { |relation| relation.where(members: scope) }
end end
......
- project = @target_project || @project - project = @target_project || @project
- noteable_class = @noteable.class if @noteable.present?
- if @noteable :javascript
:javascript GitLab.GfmAutoComplete.dataSource = "#{autocomplete_sources_namespace_project_path(project.namespace, project, type: noteable_class, type_id: params[:id])}"
GitLab.GfmAutoComplete.dataSource = "#{autocomplete_sources_namespace_project_path(project.namespace, project, type: @noteable.class, type_id: params[:id])}" GitLab.GfmAutoComplete.cachedData = undefined;
GitLab.GfmAutoComplete.cachedData = undefined; GitLab.GfmAutoComplete.setup();
GitLab.GfmAutoComplete.setup();
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
- if @build.duration - if @build.duration
%p.build-detail-row %p.build-detail-row
%span.build-light-text Duration: %span.build-light-text Duration:
#{duration_in_words(@build.finished_at, @build.started_at)} = time_interval_in_words(@build.duration)
- if @build.finished_at - if @build.finished_at
%p.build-detail-row %p.build-detail-row
%span.build-light-text Finished: %span.build-light-text Finished:
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
- if current_user && can?(current_user, :fork_project, @project) - if current_user && can?(current_user, :fork_project, @project)
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2 - if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn has-tooltip' do = link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn has-tooltip' do
= icon('code-fork fw') = custom_icon('icon_fork')
Fork Fork
%div.count-with-arrow %div.count-with-arrow
%span.arrow %span.arrow
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
= @project.forks_count = @project.forks_count
- else - else
= link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'btn has-tooltip' do = link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'btn has-tooltip' do
= icon('code-fork fw') = custom_icon('icon_fork')
Fork Fork
%div.count-with-arrow %div.count-with-arrow
%span.arrow %span.arrow
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
- stages_status = pipeline.statuses.latest.stages_status - stages_status = pipeline.statuses.latest.stages_status
- stages.each do |stage| - stages.each do |stage|
%td %td.stage-cell
- status = stages_status[stage] - status = stages_status[stage]
- tooltip = "#{stage.titleize}: #{status || 'not found'}" - tooltip = "#{stage.titleize}: #{status || 'not found'}"
- if status - if status
......
...@@ -31,11 +31,11 @@ ...@@ -31,11 +31,11 @@
- if current_user && can?(current_user, :fork_project, @project) - if current_user && can?(current_user, :fork_project, @project)
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2 - if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn btn-new' do = link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn btn-new' do
= icon('code-fork fw') = custom_icon('icon_fork')
Fork Fork
- else - else
= link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'btn btn-new' do = link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'btn btn-new' do
= icon('code-fork fw') = custom_icon('icon_fork')
Fork Fork
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
%td.duration %td.duration
- if generic_commit_status.duration - if generic_commit_status.duration
= icon("clock-o") = icon("clock-o")
#{duration_in_words(generic_commit_status.finished_at, generic_commit_status.started_at)} = time_interval_in_words(generic_commit_status.duration)
%td.timestamp %td.timestamp
- if generic_commit_status.finished_at - if generic_commit_status.finished_at
......
- @no_container = true
- page_title @tag.name, "Tags" - page_title @tag.name, "Tags"
= render "projects/commits/head" = render "projects/commits/head"
.row-content-block %div{ class: container_class }
.pull-right .sub-header-block
- if can?(current_user, :push_code, @project) .pull-right.tag-buttons
= link_to edit_namespace_project_tag_release_path(@project.namespace, @project, @tag.name), class: 'btn-grouped btn has-tooltip', title: 'Edit release notes' do - if can?(current_user, :push_code, @project)
= icon("pencil") = link_to edit_namespace_project_tag_release_path(@project.namespace, @project, @tag.name), class: 'btn has-tooltip', title: 'Edit release notes' do
= link_to namespace_project_tree_path(@project.namespace, @project, @tag.name), class: 'btn btn-grouped has-tooltip', title: 'Browse files' do = icon("pencil")
= icon('files-o') = link_to namespace_project_tree_path(@project.namespace, @project, @tag.name), class: 'btn has-tooltip', title: 'Browse files' do
= link_to namespace_project_commits_path(@project.namespace, @project, @tag.name), class: 'btn btn-grouped has-tooltip', title: 'Browse commits' do = icon('files-o')
= icon('history') = link_to namespace_project_commits_path(@project.namespace, @project, @tag.name), class: 'btn has-tooltip', title: 'Browse commits' do
- if can? current_user, :download_code, @project = icon('history')
= render 'projects/tags/download', ref: @tag.name, project: @project - if can? current_user, :download_code, @project
- if can?(current_user, :admin_project, @project) = render 'projects/tags/download', ref: @tag.name, project: @project
.pull-right - if can?(current_user, :admin_project, @project)
= link_to namespace_project_tag_path(@project.namespace, @project, @tag.name), class: 'btn btn-remove remove-row grouped has-tooltip', title: "Delete tag", method: :delete, data: { confirm: "Deleting the '#{@tag.name}' tag cannot be undone. Are you sure?" } do .pull-right
%i.fa.fa-trash-o = link_to namespace_project_tag_path(@project.namespace, @project, @tag.name), class: 'btn btn-remove remove-row grouped has-tooltip', title: "Delete tag", method: :delete, data: { confirm: "Deleting the '#{@tag.name}' tag cannot be undone. Are you sure?" } do
.title %i.fa.fa-trash-o
%span.item-title= @tag.name .tag-info.append-bottom-10
- if @commit .title
= render 'projects/branches/commit', commit: @commit, project: @project %span.item-title= @tag.name
- else - if @commit
Cant find HEAD commit for this tag = render 'projects/branches/commit', commit: @commit, project: @project
- if @tag.message.present? - else
%pre.body Cant find HEAD commit for this tag
= strip_gpg_signature(@tag.message) - if @tag.message.present?
%pre.body
= strip_gpg_signature(@tag.message)
.append-bottom-default.prepend-top-default .append-bottom-default.prepend-top-default
- if @release.description.present? - if @release.description.present?
.description .description
.wiki .wiki
= preserve do = preserve do
= markdown @release.description = markdown @release.description
- else - else
This tag has no release notes. This tag has no release notes.
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 40 40" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><circle id="a" cx="4" cy="4" r="4"/><mask id="d" width="8" height="8" x="0" y="0" fill="#fff"><use xlink:href="#a"/></mask><circle id="b" cx="20" cy="4" r="4"/><mask id="e" width="8" height="8" x="0" y="0" fill="#fff"><use xlink:href="#b"/></mask><circle id="c" cx="12" cy="30" r="4"/><mask id="f" width="8" height="8" x="0" y="0" fill="#fff"><use xlink:href="#c"/></mask></defs><g fill="none" fill-rule="evenodd" transform="translate(8 3)"><path fill="#7E7E7E" d="M10 19.667c-4.14-1.29-7.389-5.878-7.389-5.878C2.274 13.353 2 12.545 2 12.01V6h4v5.509c0 .276.166.65.367.831 0 0 1.136 1.028 1.746 1.574C9.617 15.261 11.048 16 12.09 16c1.028 0 2.41-.723 3.858-2.048.588-.54 1.84-1.742 1.84-1.742a.784.784 0 0 0 .211-.502V6h4v6.008c0 .548-.259 1.349-.601 1.795 0 0-3.21 4.707-7.399 5.916V27h-4v-7.333z"/><use stroke="#7E7E7E" stroke-width="4" mask="url(#d)" xlink:href="#a"/><use stroke="#7E7E7E" stroke-width="4" mask="url(#e)" xlink:href="#b"/><use stroke="#7E7E7E" stroke-width="4" mask="url(#f)" xlink:href="#c"/></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<circle id="a" cx="7" cy="7" r="7"/>
<mask id="b" width="14" height="14" x="0" y="0" fill="white">
<use xlink:href="#a"/>
</mask>
</defs>
<g fill="none" fill-rule="evenodd">
<use stroke="#5C5C5C" stroke-width="2" mask="url(#b)" xlink:href="#a"/>
<rect width="10" height="1" x="2" y="6.5" fill="#5C5C5C" transform="rotate(45 7 7)" rx=".3"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<circle id="a" cx="7" cy="7" r="7"/>
<mask id="b" width="14" height="14" x="0" y="0" fill="white">
<use xlink:href="#a"/>
</mask>
</defs>
<g fill="none" fill-rule="evenodd">
<use stroke="#D22852" stroke-width="2" mask="url(#b)" xlink:href="#a"/>
<path fill="#D22852" d="M7.5,6.5 L7.5,4.30578971 C7.5,4.12531853 7.36809219,4 7.20537567,4 L6.79462433,4 C6.63904572,4 6.5,4.13690672 6.5,4.30578971 L6.5,6.5 L4.30578971,6.5 C4.12531853,6.5 4,6.63190781 4,6.79462433 L4,7.20537567 C4,7.36095428 4.13690672,7.5 4.30578971,7.5 L6.5,7.5 L6.5,9.69421029 C6.5,9.87468147 6.63190781,10 6.79462433,10 L7.20537567,10 C7.36095428,10 7.5,9.86309328 7.5,9.69421029 L7.5,7.5 L9.69421029,7.5 C9.87468147,7.5 10,7.36809219 10,7.20537567 L10,6.79462433 C10,6.63904572 9.86309328,6.5 9.69421029,6.5 L7.5,6.5 Z" transform="rotate(45 7 7)"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<circle id="a" cx="7" cy="7" r="7"/>
<mask id="b" width="14" height="14" x="0" y="0" fill="white">
<use xlink:href="#a"/>
</mask>
</defs>
<g fill="none" fill-rule="evenodd">
<use stroke="#E75E40" stroke-width="2" mask="url(#b)" xlink:href="#a"/>
<rect width="1" height="4" x="5" y="5" fill="#E75E40" rx=".3"/>
<rect width="1" height="4" x="8" y="5" fill="#E75E40" rx=".3"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<circle id="a" cx="7" cy="7" r="7"/>
<mask id="b" width="14" height="14" x="0" y="0" fill="white">
<use xlink:href="#a"/>
</mask>
</defs>
<g fill="none" fill-rule="evenodd">
<use stroke="#2D9FD8" stroke-width="2" mask="url(#b)" xlink:href="#a"/>
<path fill="#2D9FD8" d="M7,3.00800862 C9.09023405,3.13960661 10.7448145,4.87657932 10.7448145,7 C10.7448145,9.209139 8.95395346,11 6.74481446,11 C5.4560962,11 4.30972054,10.3905589 3.57817301,9.44416214 L7,7 L7,3.00800862 Z"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<circle id="a" cx="7" cy="7" r="7"/>
<mask id="b" width="14" height="14" x="0" y="0" fill="white">
<use xlink:href="#a"/>
</mask>
</defs>
<g fill="none" fill-rule="evenodd">
<use stroke="#31AF64" stroke-width="2" mask="url(#b)" xlink:href="#a"/>
<g fill="#31AF64" transform="rotate(45 -.13 10.953)">
<rect width="1" height="5" x="2" rx=".3"/>
<rect width="3" height="1" y="4" rx=".3"/>
</g>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<circle id="a" cx="7" cy="7" r="7"/>
<mask id="b" width="14" height="14" x="0" y="0" fill="white">
<use xlink:href="#a"/>
</mask>
</defs>
<g fill="none" fill-rule="evenodd">
<g fill="#FF8A24" transform="translate(6 3)">
<rect width="2" height="5" rx=".5"/>
<rect width="2" height="2" y="6" rx=".5"/>
</g>
<use stroke="#FF8A24" stroke-width="2" mask="url(#b)" xlink:href="#a"/>
</g>
</svg>
...@@ -4,14 +4,7 @@ ...@@ -4,14 +4,7 @@
require 'gitlab/current_settings' require 'gitlab/current_settings'
include Gitlab::CurrentSettings include Gitlab::CurrentSettings
# If Sentry is enabled and the Rails app is running in production mode, CSP_REPORT_URI = ''
# this will construct the Report URI for Sentry.
if Rails.env.production? && current_application_settings.sentry_enabled
uri = URI.parse(current_application_settings.sentry_dsn)
CSP_REPORT_URI = "#{uri.scheme}://#{uri.host}/api#{uri.path}/csp-report/?sentry_key=#{uri.user}"
else
CSP_REPORT_URI = ''
end
# Content Security Policy Headers # Content Security Policy Headers
# For more information on CSP see: # For more information on CSP see:
...@@ -71,10 +64,7 @@ SecureHeaders::Configuration.default do |config| ...@@ -71,10 +64,7 @@ SecureHeaders::Configuration.default do |config|
upgrade_insecure_requests: true upgrade_insecure_requests: true
} }
# Reports are sent to Sentry if it's enabled. config.csp[:report_uri] = %W(#{CSP_REPORT_URI})
if current_application_settings.sentry_enabled
config.csp[:report_uri] = %W(#{CSP_REPORT_URI})
end
# Allow Bootstrap Linter in development mode. # Allow Bootstrap Linter in development mode.
if Rails.env.development? if Rails.env.development?
......
...@@ -8,8 +8,8 @@ module Gitlab ...@@ -8,8 +8,8 @@ module Gitlab
if Gitlab::Git.blank_ref?(oldrev) || Gitlab::Git.blank_ref?(newrev) if Gitlab::Git.blank_ref?(oldrev) || Gitlab::Git.blank_ref?(newrev)
false false
else else
missed_refs, _ = Gitlab::Popen.popen(%W(#{Gitlab.config.git.bin_path} --git-dir=#{project.repository.path_to_repo} rev-list #{oldrev} ^#{newrev})) missed_ref, _ = Gitlab::Popen.popen(%W(#{Gitlab.config.git.bin_path} --git-dir=#{project.repository.path_to_repo} rev-list --max-count=1 #{oldrev} ^#{newrev}))
missed_refs.split("\n").size > 0 missed_ref.present?
end end
end end
end end
......
...@@ -7,7 +7,13 @@ describe CiStatusHelper do ...@@ -7,7 +7,13 @@ describe CiStatusHelper do
let(:failed_commit) { double("Ci::Pipeline", status: 'failed') } let(:failed_commit) { double("Ci::Pipeline", status: 'failed') }
describe 'ci_icon_for_status' do describe 'ci_icon_for_status' do
it { expect(helper.ci_icon_for_status(success_commit.status)).to include('fa-check') } it 'renders to correct svg on success' do
it { expect(helper.ci_icon_for_status(failed_commit.status)).to include('fa-close') } expect(helper).to receive(:render).with('shared/icons/icon_status_success.svg', anything)
helper.ci_icon_for_status(success_commit.status)
end
it 'renders the correct svg on failure' do
expect(helper).to receive(:render).with('shared/icons/icon_status_failed.svg', anything)
helper.ci_icon_for_status(failed_commit.status)
end
end end
end end
require 'spec_helper' require 'spec_helper'
describe TimeHelper do describe TimeHelper do
describe "#duration_in_words" do describe "#time_interval_in_words" do
it "returns minutes and seconds" do it "returns minutes and seconds" do
intervals_in_words = { intervals_in_words = {
100 => "1 minute 40 seconds", 100 => "1 minute 40 seconds",
...@@ -11,26 +11,23 @@ describe TimeHelper do ...@@ -11,26 +11,23 @@ describe TimeHelper do
} }
intervals_in_words.each do |interval, expectation| intervals_in_words.each do |interval, expectation|
expect(duration_in_words(Time.now + interval, Time.now)).to eq(expectation) expect(time_interval_in_words(interval)).to eq(expectation)
end end
end end
it "calculates interval from now if there is no finished_at" do
expect(duration_in_words(nil, Time.now - 5)).to eq("5 seconds")
end
end end
describe "#time_interval_in_words" do describe "#duration_in_numbers" do
it "returns minutes and seconds" do it "returns minutes and seconds" do
intervals_in_words = { duration_in_numbers = {
100 => "1 minute 40 seconds", [100, 0] => "01:40",
121 => "2 minutes 1 second", [121, 0] => "02:01",
3721 => "62 minutes 1 second", [3721, 0] => "01:02:01",
0 => "0 seconds" [0, 0] => "00:00",
[nil, Time.now.to_i - 42] => "00:42"
} }
intervals_in_words.each do |interval, expectation| duration_in_numbers.each do |interval, expectation|
expect(time_interval_in_words(interval)).to eq(expectation) expect(duration_in_numbers(*interval)).to eq(expectation)
end end
end end
end end
......
...@@ -887,16 +887,25 @@ describe User, models: true do ...@@ -887,16 +887,25 @@ describe User, models: true do
end end
describe '#authorized_projects' do describe '#authorized_projects' do
let!(:user) { create(:user) } context 'with a minimum access level' do
let!(:private_project) { create(:project, :private) } it 'includes projects for which the user is an owner' do
user = create(:user)
project = create(:empty_project, :private, namespace: user.namespace)
before do expect(user.authorized_projects(Gitlab::Access::REPORTER))
private_project.team << [user, Gitlab::Access::MASTER] .to contain_exactly(project)
end end
subject { user.authorized_projects } it 'includes projects for which the user is a master' do
user = create(:user)
project = create(:empty_project, :private)
project.team << [user, Gitlab::Access::MASTER]
it { is_expected.to eq([private_project]) } expect(user.authorized_projects(Gitlab::Access::REPORTER))
.to contain_exactly(project)
end
end
end end
describe '#ci_authorized_runners' do describe '#ci_authorized_runners' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment