Commit fd60f374 authored by Gabriel Mazetto's avatar Gabriel Mazetto

Merge branch '9-5-stable' into security-9-5

parents b01f5e85 9031bb47
...@@ -13,6 +13,9 @@ ...@@ -13,6 +13,9 @@
img { img {
/*max-width: 100%;*/ /*max-width: 100%;*/
margin: 0 0 8px; margin: 0 0 8px;
}
img.lazy {
min-width: 200px; min-width: 200px;
min-height: 100px; min-height: 100px;
background-color: $gray-lightest; background-color: $gray-lightest;
......
...@@ -70,8 +70,7 @@ $new-sidebar-collapsed-width: 50px; ...@@ -70,8 +70,7 @@ $new-sidebar-collapsed-width: 50px;
background-color: $white-light; background-color: $white-light;
} }
.project-title, .sidebar-context-title {
.group-title {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
...@@ -110,7 +109,7 @@ $new-sidebar-collapsed-width: 50px; ...@@ -110,7 +109,7 @@ $new-sidebar-collapsed-width: 50px;
} }
.badge, .badge,
.project-title { .sidebar-context-title {
display: none; display: none;
} }
......
...@@ -286,6 +286,9 @@ ...@@ -286,6 +286,9 @@
.gpg-status-box { .gpg-status-box {
padding: 2px 10px;
margin-right: $gl-padding;
&:empty { &:empty {
display: none; display: none;
} }
...@@ -314,7 +317,6 @@ ...@@ -314,7 +317,6 @@
&.valid { &.valid {
svg { svg {
border: 1px solid $brand-success; border: 1px solid $brand-success;
fill: $brand-success; fill: $brand-success;
} }
} }
...@@ -322,7 +324,6 @@ ...@@ -322,7 +324,6 @@
&.invalid { &.invalid {
svg { svg {
border: 1px solid $common-gray-light; border: 1px solid $common-gray-light;
fill: $common-gray-light; fill: $common-gray-light;
} }
} }
......
...@@ -4,7 +4,6 @@ class Projects::ServicesController < Projects::ApplicationController ...@@ -4,7 +4,6 @@ class Projects::ServicesController < Projects::ApplicationController
# Authorize # Authorize
before_action :authorize_admin_project! before_action :authorize_admin_project!
before_action :service, only: [:edit, :update, :test] before_action :service, only: [:edit, :update, :test]
before_action :update_service, only: [:update, :test]
respond_to :html respond_to :html
...@@ -14,6 +13,8 @@ class Projects::ServicesController < Projects::ApplicationController ...@@ -14,6 +13,8 @@ class Projects::ServicesController < Projects::ApplicationController
end end
def update def update
@service.attributes = service_params[:service]
if @service.save(context: :manual_change) if @service.save(context: :manual_change)
redirect_to(project_settings_integrations_path(@project), notice: success_message) redirect_to(project_settings_integrations_path(@project), notice: success_message)
else else
...@@ -24,7 +25,7 @@ class Projects::ServicesController < Projects::ApplicationController ...@@ -24,7 +25,7 @@ class Projects::ServicesController < Projects::ApplicationController
def test def test
message = {} message = {}
if @service.can_test? if @service.can_test? && @service.update_attributes(service_params[:service])
data = @service.test_data(project, current_user) data = @service.test_data(project, current_user)
outcome = @service.test(data) outcome = @service.test(data)
...@@ -50,10 +51,6 @@ class Projects::ServicesController < Projects::ApplicationController ...@@ -50,10 +51,6 @@ class Projects::ServicesController < Projects::ApplicationController
end end
end end
def update_service
@service.assign_attributes(service_params[:service])
end
def service def service
@service ||= @project.find_or_initialize_service(params[:id]) @service ||= @project.find_or_initialize_service(params[:id])
end end
......
...@@ -12,11 +12,18 @@ module AvatarsHelper ...@@ -12,11 +12,18 @@ module AvatarsHelper
avatar_size = options[:size] || 16 avatar_size = options[:size] || 16
user_name = options[:user].try(:name) || options[:user_name] user_name = options[:user].try(:name) || options[:user_name]
avatar_url = options[:url] || avatar_icon(options[:user] || options[:user_email], avatar_size) avatar_url = options[:url] || avatar_icon(options[:user] || options[:user_email], avatar_size)
data_attributes = { container: 'body' } has_tooltip = options[:has_tooltip].nil? ? true : options[:has_tooltip]
data_attributes = {}
css_class = %W[avatar s#{avatar_size}].push(*options[:css_class])
if has_tooltip
css_class.push('has-tooltip')
data_attributes = { container: 'body' }
end
image_tag( image_tag(
avatar_url, avatar_url,
class: %W[avatar has-tooltip s#{avatar_size}].push(*options[:css_class]), class: css_class,
alt: "#{user_name}'s avatar", alt: "#{user_name}'s avatar",
title: user_name, title: user_name,
data: data_attributes, data: data_attributes,
......
...@@ -114,7 +114,7 @@ module CommitsHelper ...@@ -114,7 +114,7 @@ module CommitsHelper
end end
def commit_signature_badge_classes(additional_classes) def commit_signature_badge_classes(additional_classes)
%w(btn status-box gpg-status-box) + Array(additional_classes) %w(btn gpg-status-box) + Array(additional_classes)
end end
protected protected
......
...@@ -181,6 +181,7 @@ module EventsHelper ...@@ -181,6 +181,7 @@ module EventsHelper
end end
def event_commit_title(message) def event_commit_title(message)
message ||= ''
(message.split("\n").first || "").truncate(70) (message.split("\n").first || "").truncate(70)
rescue rescue
"--broken encoding" "--broken encoding"
......
...@@ -406,7 +406,7 @@ class Event < ActiveRecord::Base ...@@ -406,7 +406,7 @@ class Event < ActiveRecord::Base
def body? def body?
if push? if push?
push_with_commits? || rm_ref? push_with_commits?
elsif note? elsif note?
true true
else else
......
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
%i %i
at at
= event.created_at.to_s(:short) = event.created_at.to_s(:short)
%blockquote= markdown(escape_once(event.commit_title), pipeline: :atom, project: event.project, author: event.author) - unless event.rm_ref?
- if event.commits_count > 1 %blockquote= markdown(escape_once(event.commit_title), pipeline: :atom, project: event.project, author: event.author)
%p - if event.commits_count > 1
%i %p
\... and %i
= pluralize(event.commits_count - 1, "more commit") \... and
= pluralize(event.commits_count - 1, "more commit")
...@@ -41,7 +41,3 @@ ...@@ -41,7 +41,3 @@
%li.commits-stat %li.commits-stat
= link_to create_mr_path(project.default_branch, event.ref_name, project) do = link_to create_mr_path(project.default_branch, event.ref_name, project) do
Create Merge Request Create Merge Request
- elsif event.rm_ref?
.event-body
%ul.well-list.event_commits
= render "events/commit", project: project, event: event
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
= link_to admin_root_path, title: 'Admin Overview' do = link_to admin_root_path, title: 'Admin Overview' do
.avatar-container.s40.settings-avatar .avatar-container.s40.settings-avatar
= icon('wrench') = icon('wrench')
.project-title Admin Area .sidebar-context-title Admin Area
%ul.sidebar-top-level-items %ul.sidebar-top-level-items
= nav_link(controller: %w(dashboard admin projects users groups jobs runners cohorts), html_options: {class: 'home'}) do = nav_link(controller: %w(dashboard admin projects users groups jobs runners cohorts), html_options: {class: 'home'}) do
= link_to admin_root_path, title: 'Overview', class: 'shortcuts-tree' do = link_to admin_root_path, title: 'Overview', class: 'shortcuts-tree' do
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
= link_to group_path(@group), title: @group.name do = link_to group_path(@group), title: @group.name do
.avatar-container.s40.group-avatar .avatar-container.s40.group-avatar
= image_tag group_icon(@group), class: "avatar s40 avatar-tile" = image_tag group_icon(@group), class: "avatar s40 avatar-tile"
.group-title .sidebar-context-title
= @group.name = @group.name
%ul.sidebar-top-level-items %ul.sidebar-top-level-items
= nav_link(path: ['groups#show', 'groups#activity', 'groups#subgroups'], html_options: { class: 'home' }) do = nav_link(path: ['groups#show', 'groups#activity', 'groups#subgroups'], html_options: { class: 'home' }) do
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
= link_to profile_path, title: 'Profile Settings' do = link_to profile_path, title: 'Profile Settings' do
.avatar-container.s40.settings-avatar .avatar-container.s40.settings-avatar
= icon('user') = icon('user')
.project-title User Settings .sidebar-context-title User Settings
%ul.sidebar-top-level-items %ul.sidebar-top-level-items
= nav_link(path: 'profiles#show', html_options: {class: 'home'}) do = nav_link(path: 'profiles#show', html_options: {class: 'home'}) do
= link_to profile_path, title: 'Profile Settings' do = link_to profile_path, title: 'Profile Settings' do
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
= link_to project_path(@project), title: @project.name do = link_to project_path(@project), title: @project.name do
.avatar-container.s40.project-avatar .avatar-container.s40.project-avatar
= project_icon(@project, alt: @project.name, class: 'avatar s40 avatar-tile') = project_icon(@project, alt: @project.name, class: 'avatar s40 avatar-tile')
.project-title .sidebar-context-title
= @project.name = @project.name
%ul.sidebar-top-level-items %ul.sidebar-top-level-items
= nav_link(path: ['projects#show', 'projects#activity', 'cycle_analytics#show'], html_options: { class: 'home' }) do = nav_link(path: ['projects#show', 'projects#activity', 'cycle_analytics#show'], html_options: { class: 'home' }) do
......
.project-templates-buttons.import-buttons{ data: { toggle: "buttons" } } .project-templates-buttons.import-buttons{ data: { toggle: "buttons" } }
.btn.blank-option.active .btn.blank-option.active
%input{ type: "radio", autocomplete: "off", name: "project_templates", id: "blank", checked: "true" } %input{ type: "radio", autocomplete: "off", name: "project[template_name]", id: "blank", checked: "true", value: "" }
= icon('file-o', class: 'btn-template-icon') = icon('file-o', class: 'btn-template-icon')
Blank Blank
- Gitlab::ProjectTemplate.all.each do |template| - Gitlab::ProjectTemplate.all.each do |template|
......
...@@ -37,14 +37,14 @@ ...@@ -37,14 +37,14 @@
.commit-actions.hidden-xs .commit-actions.hidden-xs
- if commit.status(ref)
= render_commit_status(commit, ref: ref)
- if request.xhr? - if request.xhr?
= render partial: 'projects/commit/signature', object: commit.signature = render partial: 'projects/commit/signature', object: commit.signature
- else - else
= render partial: 'projects/commit/ajax_signature', locals: { commit: commit } = render partial: 'projects/commit/ajax_signature', locals: { commit: commit }
- if commit.status(ref)
= render_commit_status(commit, ref: ref)
= link_to commit.short_id, project_commit_path(project, commit), class: "commit-sha btn btn-transparent" = link_to commit.short_id, project_commit_path(project, commit), class: "commit-sha btn btn-transparent"
= clipboard_button(text: commit.id, title: _("Copy commit SHA to clipboard")) = clipboard_button(text: commit.id, title: _("Copy commit SHA to clipboard"))
= link_to_browse_code(project, commit) = link_to_browse_code(project, commit)
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
%li.filter-dropdown-item{ class: ('js-current-user' if user == current_user) } %li.filter-dropdown-item{ class: ('js-current-user' if user == current_user) }
%button.btn.btn-link.dropdown-user{ type: :button } %button.btn.btn-link.dropdown-user{ type: :button }
.avatar-container.s40 .avatar-container.s40
= user_avatar_without_link(user: user, lazy: avatar[:lazy], url: avatar[:url], size: 40).gsub('/images/{{avatar_url}}','{{avatar_url}}').html_safe = user_avatar_without_link(user: user, lazy: avatar[:lazy], url: avatar[:url], size: 40, has_tooltip: false).gsub('/images/{{avatar_url}}','{{avatar_url}}').html_safe
.dropdown-user-details .dropdown-user-details
%span %span
= user.name = user.name
......
---
title: Fix signing in using LDAP when attribute mapping uses simple strings instead
of arrays
merge_request:
author:
type: fixed
---
title: Show un-highlighted text diffs when we do not have references to the correct
blobs
merge_request:
author:
type: fixed
---
title: Fix display of push events for removed refs
merge_request:
author:
type: fixed
---
title: Testing of some integrations were broken due to missing ServiceHook record.
merge_request:
author:
type: fixed
---
title: Fix new project form not resetting the template value
merge_request:
author:
type: fixed
...@@ -186,7 +186,10 @@ module Gitlab ...@@ -186,7 +186,10 @@ module Gitlab
end end
def content_changed? def content_changed?
old_blob && new_blob && old_blob.id != new_blob.id return blobs_changed? if diff_refs
return false if new_file? || deleted_file? || renamed_file?
text? && diff_lines.any?
end end
def different_type? def different_type?
...@@ -225,6 +228,10 @@ module Gitlab ...@@ -225,6 +228,10 @@ module Gitlab
private private
def blobs_changed?
old_blob && new_blob && old_blob.id != new_blob.id
end
def simple_viewer_class def simple_viewer_class
return DiffViewer::NotDiffable unless diffable? return DiffViewer::NotDiffable unless diffable?
...@@ -250,6 +257,8 @@ module Gitlab ...@@ -250,6 +257,8 @@ module Gitlab
DiffViewer::Renamed DiffViewer::Renamed
elsif mode_changed? elsif mode_changed?
DiffViewer::ModeChanged DiffViewer::ModeChanged
else
DiffViewer::NoPreview
end end
end end
......
...@@ -159,8 +159,8 @@ module Gitlab ...@@ -159,8 +159,8 @@ module Gitlab
def raw_blame(revision, path) def raw_blame(revision, path)
request = Gitaly::RawBlameRequest.new( request = Gitaly::RawBlameRequest.new(
repository: @gitaly_repo, repository: @gitaly_repo,
revision: revision, revision: GitalyClient.encode(revision),
path: path path: GitalyClient.encode(path)
) )
response = GitalyClient.call(@repository.storage, :commit_service, :raw_blame, request) response = GitalyClient.call(@repository.storage, :commit_service, :raw_blame, request)
......
...@@ -73,7 +73,7 @@ module Gitlab ...@@ -73,7 +73,7 @@ module Gitlab
private private
def user_options(field, value, limit) def user_options(field, value, limit)
options = { attributes: user_attributes } options = { attributes: Gitlab::LDAP::Person.ldap_attributes(config).compact.uniq }
options[:size] = limit if limit options[:size] = limit if limit
if field.to_sym == :dn if field.to_sym == :dn
...@@ -99,10 +99,6 @@ module Gitlab ...@@ -99,10 +99,6 @@ module Gitlab
filter filter
end end
end end
def user_attributes
%W(#{config.uid} cn dn) + config.attributes['username'] + config.attributes['email']
end
end end
end end
end end
...@@ -21,6 +21,15 @@ module Gitlab ...@@ -21,6 +21,15 @@ module Gitlab
adapter.dn_matches_filter?(dn, AD_USER_DISABLED) adapter.dn_matches_filter?(dn, AD_USER_DISABLED)
end end
def self.ldap_attributes(config)
[
'dn', # Used in `dn`
config.uid, # Used in `uid`
*config.attributes['name'], # Used in `name`
*config.attributes['email'] # Used in `email`
]
end
def initialize(entry, provider) def initialize(entry, provider)
Rails.logger.debug { "Instantiating #{self.class.name} with LDIF:\n#{entry.to_ldif}" } Rails.logger.debug { "Instantiating #{self.class.name} with LDIF:\n#{entry.to_ldif}" }
@entry = entry @entry = entry
......
...@@ -10,9 +10,6 @@ describe Projects::ServicesController do ...@@ -10,9 +10,6 @@ describe Projects::ServicesController do
before do before do
sign_in(user) sign_in(user)
project.team << [user, :master] project.team << [user, :master]
controller.instance_variable_set(:@project, project)
controller.instance_variable_set(:@service, service)
end end
describe '#test' do describe '#test' do
...@@ -20,7 +17,7 @@ describe Projects::ServicesController do ...@@ -20,7 +17,7 @@ describe Projects::ServicesController do
it 'renders 404' do it 'renders 404' do
allow_any_instance_of(Service).to receive(:can_test?).and_return(false) allow_any_instance_of(Service).to receive(:can_test?).and_return(false)
put :test, namespace_id: project.namespace.id, project_id: project.id, id: service.id put :test, namespace_id: project.namespace, project_id: project, id: service.to_param
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
end end
...@@ -36,7 +33,7 @@ describe Projects::ServicesController do ...@@ -36,7 +33,7 @@ describe Projects::ServicesController do
it 'returns success' do it 'returns success' do
allow_any_instance_of(MicrosoftTeams::Notifier).to receive(:ping).and_return(true) allow_any_instance_of(MicrosoftTeams::Notifier).to receive(:ping).and_return(true)
put :test, namespace_id: project.namespace.id, project_id: project.id, id: service.id put :test, namespace_id: project.namespace, project_id: project, id: service.to_param
expect(response.status).to eq(200) expect(response.status).to eq(200)
end end
...@@ -45,7 +42,7 @@ describe Projects::ServicesController do ...@@ -45,7 +42,7 @@ describe Projects::ServicesController do
it 'returns success' do it 'returns success' do
expect(HipChat::Client).to receive(:new).with('hipchat_token_p', anything).and_return(hipchat_client) expect(HipChat::Client).to receive(:new).with('hipchat_token_p', anything).and_return(hipchat_client)
put :test, namespace_id: project.namespace.id, project_id: project.id, id: service.id, service: service_params put :test, namespace_id: project.namespace, project_id: project, id: service.to_param, service: service_params
expect(response.status).to eq(200) expect(response.status).to eq(200)
end end
...@@ -54,17 +51,42 @@ describe Projects::ServicesController do ...@@ -54,17 +51,42 @@ describe Projects::ServicesController do
it 'returns success' do it 'returns success' do
expect(HipChat::Client).to receive(:new).with('hipchat_token_p', anything).and_return(hipchat_client) expect(HipChat::Client).to receive(:new).with('hipchat_token_p', anything).and_return(hipchat_client)
put :test, namespace_id: project.namespace.id, project_id: project.id, id: service.id, service: service_params put :test, namespace_id: project.namespace, project_id: project, id: service.to_param, service: service_params
expect(response.status).to eq(200) expect(response.status).to eq(200)
end end
context 'when service is configured for the first time' do
before do
allow_any_instance_of(ServiceHook).to receive(:execute).and_return(true)
end
it 'persist the object' do
do_put
expect(BuildkiteService.first).to be_present
end
it 'creates the ServiceHook object' do
do_put
expect(BuildkiteService.first.service_hook).to be_present
end
def do_put
put :test, namespace_id: project.namespace,
project_id: project,
id: 'buildkite',
service: { 'active' => '1', 'push_events' => '1', token: 'token', 'project_url' => 'http://test.com' }
end
end
end end
context 'failure' do context 'failure' do
it 'returns success status code and the error message' do it 'returns success status code and the error message' do
expect(HipChat::Client).to receive(:new).with('hipchat_token_p', anything).and_raise('Bad test') expect(HipChat::Client).to receive(:new).with('hipchat_token_p', anything).and_raise('Bad test')
put :test, namespace_id: project.namespace.id, project_id: project.id, id: service.id, service: service_params put :test, namespace_id: project.namespace, project_id: project, id: service.to_param, service: service_params
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(JSON.parse(response.body)) expect(JSON.parse(response.body))
...@@ -77,7 +99,7 @@ describe Projects::ServicesController do ...@@ -77,7 +99,7 @@ describe Projects::ServicesController do
context 'when param `active` is set to true' do context 'when param `active` is set to true' do
it 'activates the service and redirects to integrations paths' do it 'activates the service and redirects to integrations paths' do
put :update, put :update,
namespace_id: project.namespace.id, project_id: project.id, id: service.id, service: { active: true } namespace_id: project.namespace, project_id: project, id: service.to_param, service: { active: true }
expect(response).to redirect_to(project_settings_integrations_path(project)) expect(response).to redirect_to(project_settings_integrations_path(project))
expect(flash[:notice]).to eq 'HipChat activated.' expect(flash[:notice]).to eq 'HipChat activated.'
...@@ -87,7 +109,7 @@ describe Projects::ServicesController do ...@@ -87,7 +109,7 @@ describe Projects::ServicesController do
context 'when param `active` is set to false' do context 'when param `active` is set to false' do
it 'does not activate the service but saves the settings' do it 'does not activate the service but saves the settings' do
put :update, put :update,
namespace_id: project.namespace.id, project_id: project.id, id: service.id, service: { active: false } namespace_id: project.namespace, project_id: project, id: service.to_param, service: { active: false }
expect(flash[:notice]).to eq 'HipChat settings saved, but not activated.' expect(flash[:notice]).to eq 'HipChat settings saved, but not activated.'
end end
......
...@@ -28,7 +28,7 @@ describe AvatarsHelper do ...@@ -28,7 +28,7 @@ describe AvatarsHelper do
it 'displays user avatar' do it 'displays user avatar' do
is_expected.to eq image_tag( is_expected.to eq image_tag(
LazyImageTagHelper.placeholder_image, LazyImageTagHelper.placeholder_image,
class: 'avatar has-tooltip s16 lazy', class: 'avatar s16 has-tooltip lazy',
alt: "#{user.name}'s avatar", alt: "#{user.name}'s avatar",
title: user.name, title: user.name,
data: { container: 'body', src: avatar_icon(user, 16) } data: { container: 'body', src: avatar_icon(user, 16) }
...@@ -41,7 +41,7 @@ describe AvatarsHelper do ...@@ -41,7 +41,7 @@ describe AvatarsHelper do
it 'uses provided css_class' do it 'uses provided css_class' do
is_expected.to eq image_tag( is_expected.to eq image_tag(
LazyImageTagHelper.placeholder_image, LazyImageTagHelper.placeholder_image,
class: "avatar has-tooltip s16 #{options[:css_class]} lazy", class: "avatar s16 #{options[:css_class]} has-tooltip lazy",
alt: "#{user.name}'s avatar", alt: "#{user.name}'s avatar",
title: user.name, title: user.name,
data: { container: 'body', src: avatar_icon(user, 16) } data: { container: 'body', src: avatar_icon(user, 16) }
...@@ -55,7 +55,7 @@ describe AvatarsHelper do ...@@ -55,7 +55,7 @@ describe AvatarsHelper do
it 'uses provided size' do it 'uses provided size' do
is_expected.to eq image_tag( is_expected.to eq image_tag(
LazyImageTagHelper.placeholder_image, LazyImageTagHelper.placeholder_image,
class: "avatar has-tooltip s#{options[:size]} lazy", class: "avatar s#{options[:size]} has-tooltip lazy",
alt: "#{user.name}'s avatar", alt: "#{user.name}'s avatar",
title: user.name, title: user.name,
data: { container: 'body', src: avatar_icon(user, options[:size]) } data: { container: 'body', src: avatar_icon(user, options[:size]) }
...@@ -69,7 +69,7 @@ describe AvatarsHelper do ...@@ -69,7 +69,7 @@ describe AvatarsHelper do
it 'uses provided url' do it 'uses provided url' do
is_expected.to eq image_tag( is_expected.to eq image_tag(
LazyImageTagHelper.placeholder_image, LazyImageTagHelper.placeholder_image,
class: 'avatar has-tooltip s16 lazy', class: 'avatar s16 has-tooltip lazy',
alt: "#{user.name}'s avatar", alt: "#{user.name}'s avatar",
title: user.name, title: user.name,
data: { container: 'body', src: options[:url] } data: { container: 'body', src: options[:url] }
...@@ -77,6 +77,36 @@ describe AvatarsHelper do ...@@ -77,6 +77,36 @@ describe AvatarsHelper do
end end
end end
context 'with has_tooltip parameter' do
context 'with has_tooltip set to true' do
let(:options) { { user: user, has_tooltip: true } }
it 'adds has-tooltip' do
is_expected.to eq image_tag(
LazyImageTagHelper.placeholder_image,
class: 'avatar s16 has-tooltip lazy',
alt: "#{user.name}'s avatar",
title: user.name,
data: { container: 'body', src: avatar_icon(user, 16) }
)
end
end
context 'with has_tooltip set to false' do
let(:options) { { user: user, has_tooltip: false } }
it 'does not add has-tooltip or data container' do
is_expected.to eq image_tag(
LazyImageTagHelper.placeholder_image,
class: 'avatar s16 lazy',
alt: "#{user.name}'s avatar",
title: user.name,
data: { src: avatar_icon(user, 16) }
)
end
end
end
context 'with user_name parameter' do context 'with user_name parameter' do
let(:options) { { user_name: 'Tinky Winky', user_email: 'no@f.un' } } let(:options) { { user_name: 'Tinky Winky', user_email: 'no@f.un' } }
...@@ -86,7 +116,7 @@ describe AvatarsHelper do ...@@ -86,7 +116,7 @@ describe AvatarsHelper do
it 'prefers user parameter' do it 'prefers user parameter' do
is_expected.to eq image_tag( is_expected.to eq image_tag(
LazyImageTagHelper.placeholder_image, LazyImageTagHelper.placeholder_image,
class: 'avatar has-tooltip s16 lazy', class: 'avatar s16 has-tooltip lazy',
alt: "#{user.name}'s avatar", alt: "#{user.name}'s avatar",
title: user.name, title: user.name,
data: { container: 'body', src: avatar_icon(user, 16) } data: { container: 'body', src: avatar_icon(user, 16) }
...@@ -97,7 +127,7 @@ describe AvatarsHelper do ...@@ -97,7 +127,7 @@ describe AvatarsHelper do
it 'uses user_name and user_email parameter if user is not present' do it 'uses user_name and user_email parameter if user is not present' do
is_expected.to eq image_tag( is_expected.to eq image_tag(
LazyImageTagHelper.placeholder_image, LazyImageTagHelper.placeholder_image,
class: 'avatar has-tooltip s16 lazy', class: 'avatar s16 has-tooltip lazy',
alt: "#{options[:user_name]}'s avatar", alt: "#{options[:user_name]}'s avatar",
title: options[:user_name], title: options[:user_name],
data: { container: 'body', src: avatar_icon(options[:user_email], 16) } data: { container: 'body', src: avatar_icon(options[:user_email], 16) }
......
...@@ -106,5 +106,9 @@ describe EventsHelper do ...@@ -106,5 +106,9 @@ describe EventsHelper do
it "handles empty strings" do it "handles empty strings" do
expect(helper.event_commit_title("")).to eq("") expect(helper.event_commit_title("")).to eq("")
end end
it 'handles nil values' do
expect(helper.event_commit_title(nil)).to eq('')
end
end end
end end
...@@ -15,6 +15,17 @@ describe Gitlab::Diff::File do ...@@ -15,6 +15,17 @@ describe Gitlab::Diff::File do
it { expect(diff_lines.first).to be_kind_of(Gitlab::Diff::Line) } it { expect(diff_lines.first).to be_kind_of(Gitlab::Diff::Line) }
end end
describe '#highlighted_diff_lines' do
it 'highlights the diff and memoises the result' do
expect(Gitlab::Diff::Highlight).to receive(:new)
.with(diff_file, repository: project.repository)
.once
.and_call_original
diff_file.highlighted_diff_lines
end
end
describe '#mode_changed?' do describe '#mode_changed?' do
it { expect(diff_file.mode_changed?).to be_falsey } it { expect(diff_file.mode_changed?).to be_falsey }
end end
...@@ -122,8 +133,20 @@ describe Gitlab::Diff::File do ...@@ -122,8 +133,20 @@ describe Gitlab::Diff::File do
let(:commit) { project.commit('2f63565e7aac07bcdadb654e253078b727143ec4') } let(:commit) { project.commit('2f63565e7aac07bcdadb654e253078b727143ec4') }
let(:diff_file) { commit.diffs.diff_file_with_new_path('files/images/6049019_460s.jpg') } let(:diff_file) { commit.diffs.diff_file_with_new_path('files/images/6049019_460s.jpg') }
it 'returns true' do context 'when the blobs are different' do
expect(diff_file.content_changed?).to be_truthy it 'returns true' do
expect(diff_file.content_changed?).to be_truthy
end
end
context 'when there are no diff refs' do
before do
allow(diff_file).to receive(:diff_refs).and_return(nil)
end
it 'returns false' do
expect(diff_file.content_changed?).to be_falsey
end
end end
end end
...@@ -131,8 +154,20 @@ describe Gitlab::Diff::File do ...@@ -131,8 +154,20 @@ describe Gitlab::Diff::File do
let(:commit) { project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') } let(:commit) { project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') }
let(:diff_file) { commit.diffs.diff_file_with_new_path('files/ruby/popen.rb') } let(:diff_file) { commit.diffs.diff_file_with_new_path('files/ruby/popen.rb') }
it 'returns true' do context 'when the blobs are different' do
expect(diff_file.content_changed?).to be_truthy it 'returns true' do
expect(diff_file.content_changed?).to be_truthy
end
end
context 'when there are no diff refs' do
before do
allow(diff_file).to receive(:diff_refs).and_return(nil)
end
it 'returns true' do
expect(diff_file.content_changed?).to be_truthy
end
end end
end end
end end
...@@ -270,6 +305,21 @@ describe Gitlab::Diff::File do ...@@ -270,6 +305,21 @@ describe Gitlab::Diff::File do
expect(diff_file.simple_viewer).to be_a(DiffViewer::ModeChanged) expect(diff_file.simple_viewer).to be_a(DiffViewer::ModeChanged)
end end
end end
context 'when no other conditions apply' do
before do
allow(diff_file).to receive(:content_changed?).and_return(false)
allow(diff_file).to receive(:new_file?).and_return(false)
allow(diff_file).to receive(:deleted_file?).and_return(false)
allow(diff_file).to receive(:renamed_file?).and_return(false)
allow(diff_file).to receive(:mode_changed?).and_return(false)
allow(diff_file).to receive(:raw_text?).and_return(false)
end
it 'returns a No Preview viewer' do
expect(diff_file.simple_viewer).to be_a(DiffViewer::NoPreview)
end
end
end end
describe '#rich_viewer' do describe '#rich_viewer' do
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::Git::Storage::ForkedStorageCheck, skip_database_cleaner: true do describe Gitlab::Git::Storage::ForkedStorageCheck, broken_storage: true, skip_database_cleaner: true do
let(:existing_path) do let(:existing_path) do
existing_path = TestEnv.repos_path existing_path = TestEnv.repos_path
FileUtils.mkdir_p(existing_path) FileUtils.mkdir_p(existing_path)
......
...@@ -16,7 +16,7 @@ describe Gitlab::LDAP::Adapter do ...@@ -16,7 +16,7 @@ describe Gitlab::LDAP::Adapter do
expect(adapter).to receive(:ldap_search) do |arg| expect(adapter).to receive(:ldap_search) do |arg|
expect(arg[:filter].to_s).to eq('(uid=johndoe)') expect(arg[:filter].to_s).to eq('(uid=johndoe)')
expect(arg[:base]).to eq('dc=example,dc=com') expect(arg[:base]).to eq('dc=example,dc=com')
expect(arg[:attributes]).to match(%w{uid cn dn uid userid sAMAccountName mail email userPrincipalName}) expect(arg[:attributes]).to match(%w{dn uid cn mail email userPrincipalName})
end.and_return({}) end.and_return({})
adapter.users('uid', 'johndoe') adapter.users('uid', 'johndoe')
...@@ -26,7 +26,7 @@ describe Gitlab::LDAP::Adapter do ...@@ -26,7 +26,7 @@ describe Gitlab::LDAP::Adapter do
expect(adapter).to receive(:ldap_search).with( expect(adapter).to receive(:ldap_search).with(
base: 'uid=johndoe,ou=users,dc=example,dc=com', base: 'uid=johndoe,ou=users,dc=example,dc=com',
scope: Net::LDAP::SearchScope_BaseObject, scope: Net::LDAP::SearchScope_BaseObject,
attributes: %w{uid cn dn uid userid sAMAccountName mail email userPrincipalName}, attributes: %w{dn uid cn mail email userPrincipalName},
filter: nil filter: nil
).and_return({}) ).and_return({})
...@@ -63,7 +63,7 @@ describe Gitlab::LDAP::Adapter do ...@@ -63,7 +63,7 @@ describe Gitlab::LDAP::Adapter do
it 'uses the right uid attribute when non-default' do it 'uses the right uid attribute when non-default' do
stub_ldap_config(uid: 'sAMAccountName') stub_ldap_config(uid: 'sAMAccountName')
expect(adapter).to receive(:ldap_search).with( expect(adapter).to receive(:ldap_search).with(
hash_including(attributes: %w{sAMAccountName cn dn uid userid sAMAccountName mail email userPrincipalName}) hash_including(attributes: %w{dn sAMAccountName cn mail email userPrincipalName})
).and_return({}) ).and_return({})
adapter.users('sAMAccountName', 'johndoe') adapter.users('sAMAccountName', 'johndoe')
......
...@@ -304,6 +304,50 @@ describe Event do ...@@ -304,6 +304,50 @@ describe Event do
end end
end end
describe '#body?' do
let(:push_event) do
event = build(:push_event)
allow(event).to receive(:push?).and_return(true)
event
end
it 'returns true for a push event with commits' do
allow(push_event).to receive(:push_with_commits?).and_return(true)
expect(push_event).to be_body
end
it 'returns false for a push event without a valid commit range' do
allow(push_event).to receive(:push_with_commits?).and_return(false)
expect(push_event).not_to be_body
end
it 'returns true for a Note event' do
event = build(:event)
allow(event).to receive(:note?).and_return(true)
expect(event).to be_body
end
it 'returns true if the target responds to #title' do
event = build(:event)
allow(event).to receive(:target).and_return(double(:target, title: 'foo'))
expect(event).to be_body
end
it 'returns false for a regular event without a target' do
event = build(:event)
expect(event).not_to be_body
end
end
def create_push_event(project, user) def create_push_event(project, user)
event = create(:push_event, project: project, author: user) event = create(:push_event, project: project, author: user)
......
...@@ -97,9 +97,15 @@ RSpec.configure do |config| ...@@ -97,9 +97,15 @@ RSpec.configure do |config|
reset_delivered_emails! reset_delivered_emails!
end end
if ENV['CI'] # Stub the `ForkedStorageCheck.storage_available?` method unless
config.around(:each) do |ex| # `:broken_storage` metadata is defined
ex.run_with_retry retry: 2 #
# This check can be slow and is unnecessary in a test environment where we
# know the storage is available, because we create it at runtime
config.before(:example) do |example|
unless example.metadata[:broken_storage]
allow(Gitlab::Git::Storage::ForkedStorageCheck)
.to receive(:storage_available?).and_return(true)
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment