Commit cdba9047 authored by Stan Hu's avatar Stan Hu

Merge branch 'ce-to-ee-2018-02-28' into 'master'

CE upstream - 2018-02-28 18:24 UTC

Closes gitlab-ce#43580

See merge request gitlab-org/gitlab-ee!4767
parents 499bb3a1 dd2a9692
<!---
Please read this!
Before opening a new issue, make sure to search for keywords in the issues
......@@ -14,10 +15,7 @@ For the Enterprise Edition issue tracker:
- https://gitlab.com/gitlab-org/gitlab-ee/issues?label_name%5B%5D=bug
and verify the issue you're about to submit isn't a duplicate.
Please remove this notice if you're confident your issue isn't a duplicate.
------
--->
### Summary
......
......@@ -21,7 +21,7 @@ export default class LabelsSelect {
}
$els.each(function(i, dropdown) {
var $block, $colorPreview, $dropdown, $form, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, defaultLabel, enableLabelCreateButton, issueURLSplit, issueUpdateURL, labelHTMLTemplate, labelNoneHTMLTemplate, labelUrl, namespacePath, projectPath, saveLabelData, selectedLabel, showAny, showNo, $sidebarLabelTooltip, initialSelected, $toggleText, fieldName, useId, propertyName, showMenuAbove, $container, $dropdownContainer;
var $block, $colorPreview, $dropdown, $form, $loading, $selectbox, $sidebarCollapsedValue, $value, abilityName, defaultLabel, enableLabelCreateButton, issueURLSplit, issueUpdateURL, labelUrl, namespacePath, projectPath, saveLabelData, selectedLabel, showAny, showNo, $sidebarLabelTooltip, initialSelected, $toggleText, fieldName, useId, propertyName, showMenuAbove, $container, $dropdownContainer;
$dropdown = $(dropdown);
$dropdownContainer = $dropdown.closest('.labels-filter');
$toggleText = $dropdown.find('.dropdown-toggle-text');
......@@ -53,13 +53,6 @@ export default class LabelsSelect {
.map(function () {
return this.value;
}).get();
if (issueUpdateURL != null) {
issueURLSplit = issueUpdateURL.split('/');
}
if (issueUpdateURL) {
labelHTMLTemplate = _.template('<% _.each(labels, function(label){ %> <a href="<%- ["",issueURLSplit[1], issueURLSplit[2],""].join("/") %>issues?label_name[]=<%- encodeURIComponent(label.title) %>"> <span class="label has-tooltip color-label" title="<%- label.description %>" style="background-color: <%- label.color %>; color: <%- label.text_color %>;"> <%- label.title %> </span> </a> <% }); %>');
labelNoneHTMLTemplate = '<span class="no-value">None</span>';
}
const handleClick = options.handleClick;
$sidebarLabelTooltip.tooltip();
......@@ -91,14 +84,17 @@ export default class LabelsSelect {
$loading.fadeOut();
$dropdown.trigger('loaded.gl.dropdown');
$selectbox.hide();
data.issueURLSplit = issueURLSplit;
data.issueUpdateURL = issueUpdateURL;
labelCount = 0;
if (data.labels.length) {
template = labelHTMLTemplate(data);
if (data.labels.length && issueUpdateURL) {
template = LabelsSelect.getLabelTemplate({
labels: data.labels,
issueUpdateURL,
});
labelCount = data.labels.length;
}
else {
template = labelNoneHTMLTemplate;
template = '<span class="no-value">None</span>';
}
$value.removeAttr('style').html(template);
$sidebarCollapsedValue.text(labelCount);
......@@ -418,6 +414,26 @@ export default class LabelsSelect {
this.bindEvents();
}
static getLabelTemplate(tplData) {
// We could use ES6 template string here
// and properly indent markup for readability
// but that also introduces unintended white-space
// so best approach is to use traditional way of
// concatenation
// see: http://2ality.com/2016/05/template-literal-whitespace.html#joining-arrays
const tpl = _.template([
'<% _.each(labels, function(label){ %>',
'<a href="<%- issueUpdateURL.slice(0, issueUpdateURL.lastIndexOf("/")) %>?label_name[]=<%- encodeURIComponent(label.title) %>">',
'<span class="label has-tooltip color-label" title="<%- label.description %>" style="background-color: <%- label.color %>; color: <%- label.text_color %>;">',
'<%- label.title %>',
'</span>',
'</a>',
'<% }); %>',
].join(''));
return tpl(tplData);
}
bindEvents() {
return $('body').on('change', '.selected_issue', this.onSelectCheckboxIssue);
}
......
......@@ -103,6 +103,7 @@
.issuable-show-labels {
a {
margin-bottom: 5px;
margin-right: 5px;
display: inline-block;
.color-label {
......@@ -116,6 +117,12 @@
}
&.has-labels {
// this font size is a fix to
// prevent unintended spacing between labels
// which shows up when rendering markup has white-space
// characters present.
// see: https://css-tricks.com/fighting-the-space-between-inline-block-elements/#article-header-id-3
font-size: 0;
margin-bottom: -5px;
}
}
......
......@@ -3,7 +3,7 @@ class Projects::PagesDomainsController < Projects::ApplicationController
before_action :require_pages_enabled!
before_action :authorize_update_pages!, except: [:show]
before_action :domain, only: [:show, :destroy, :verify]
before_action :domain, except: [:new, :create]
def show
end
......@@ -24,8 +24,11 @@ class Projects::PagesDomainsController < Projects::ApplicationController
redirect_to project_pages_domain_path(@project, @domain)
end
def edit
end
def create
@domain = @project.pages_domains.create(pages_domain_params)
@domain = @project.pages_domains.create(create_params)
if @domain.valid?
redirect_to project_pages_domain_path(@project, @domain)
......@@ -34,6 +37,16 @@ class Projects::PagesDomainsController < Projects::ApplicationController
end
end
def update
if @domain.update(update_params)
redirect_to project_pages_path(@project),
status: 302,
notice: 'Domain was updated'
else
render 'edit'
end
end
def destroy
@domain.destroy
......@@ -49,12 +62,12 @@ class Projects::PagesDomainsController < Projects::ApplicationController
private
def pages_domain_params
params.require(:pages_domain).permit(
:certificate,
:key,
:domain
)
def create_params
params.require(:pages_domain).permit(:key, :certificate, :domain)
end
def update_params
params.require(:pages_domain).permit(:key, :certificate)
end
def domain
......
......@@ -50,7 +50,7 @@ module Ci
ref_protected: 1
}
cached_attr_reader :version, :revision, :platform, :architecture, :contacted_at
cached_attr_reader :version, :revision, :platform, :architecture, :contacted_at, :ip_address
# Searches for runners matching the given query.
#
......@@ -158,7 +158,7 @@ module Ci
end
def update_cached_info(values)
values = values&.slice(:version, :revision, :platform, :architecture) || {}
values = values&.slice(:version, :revision, :platform, :architecture, :ip_address) || {}
values[:contacted_at] = Time.now
cache_attributes(values)
......
......@@ -25,6 +25,8 @@ module Projects
return error("Could not set the default branch") unless project.change_head(params[:default_branch])
end
ensure_wiki_exists if enabling_wiki?
if project.update_attributes(params.except(:default_branch))
if project.previous_changes.include?('path')
project.rename_repo
......@@ -62,5 +64,18 @@ module Projects
new_branch && project.repository.exists? &&
new_branch != project.default_branch
end
def enabling_wiki?
return false if @project.wiki_enabled?
params[:project_feature_attributes][:wiki_access_level].to_i > ProjectFeature::DISABLED
end
def ensure_wiki_exists
ProjectWiki.new(project, project.owner).wiki
rescue ProjectWiki::CouldNotCreateWikiError
log_error("Could not create wiki for #{project.full_name}")
Gitlab::Metrics.counter(:wiki_can_not_be_created_total, 'Counts the times we failed to create a wiki')
end
end
end
......@@ -16,6 +16,8 @@
= runner.description
%td
= runner.version
%td
= runner.ip_address
%td
- if runner.shared?
n/a
......
......@@ -60,6 +60,7 @@
%th Runner token
%th Description
%th Version
%th IP Address
%th Projects
%th Jobs
%th Tags
......
= form_for [@project.namespace.becomes(Namespace), @project, @domain], html: { class: 'form-horizontal fieldset-form' } do |f|
- if @domain.errors.any?
#error_explanation
.alert.alert-danger
- @domain.errors.full_messages.each do |msg|
%p= msg
- if @domain.errors.any?
#error_explanation
.alert.alert-danger
- @domain.errors.full_messages.each do |msg|
%p= msg
.form-group
= f.label :domain, class: 'control-label' do
Domain
.col-sm-10
= f.text_field :domain, required: true, autocomplete: 'off', class: 'form-control', disabled: @domain.persisted?
- if Gitlab.config.pages.external_https
.form-group
= f.label :domain, class: 'control-label' do
Domain
= f.label :certificate, class: 'control-label' do
Certificate (PEM)
.col-sm-10
= f.text_field :domain, required: true, autocomplete: 'off', class: 'form-control'
- if Gitlab.config.pages.external_https
.form-group
= f.label :certificate, class: 'control-label' do
Certificate (PEM)
.col-sm-10
= f.text_area :certificate, rows: 5, class: 'form-control'
%span.help-inline Upload a certificate for your domain with all intermediates
.form-group
= f.label :key, class: 'control-label' do
Key (PEM)
.col-sm-10
= f.text_area :key, rows: 5, class: 'form-control'
%span.help-inline Upload a private key for your certificate
- else
.nothing-here-block
Support for custom certificates is disabled.
Ask your system's administrator to enable it.
= f.text_area :certificate, rows: 5, class: 'form-control'
%span.help-inline Upload a certificate for your domain with all intermediates
.form-actions
= f.submit 'Create New Domain', class: "btn btn-save"
.form-group
= f.label :key, class: 'control-label' do
Key (PEM)
.col-sm-10
= f.text_area :key, rows: 5, class: 'form-control'
%span.help-inline Upload a private key for your certificate
- else
.nothing-here-block
Support for custom certificates is disabled.
Ask your system's administrator to enable it.
- add_to_breadcrumbs "Pages", project_pages_path(@project)
- breadcrumb_title @domain.domain
- page_title @domain.domain
%h3.page_title
= @domain.domain
%hr.clearfix
%div
= form_for [@project.namespace.becomes(Namespace), @project, @domain], html: { class: 'form-horizontal fieldset-form' } do |f|
= render 'form', { f: f }
.form-actions
= f.submit 'Save Changes', class: "btn btn-save"
- add_to_breadcrumbs "Pages", project_pages_path(@project)
- page_title 'New Pages Domain'
%h3.page_title
New Pages Domain
%hr.clearfix
%div
= render 'form'
= form_for [@project.namespace.becomes(Namespace), @project, @domain], html: { class: 'form-horizontal fieldset-form' } do |f|
= render 'form', { f: f }
.form-actions
= f.submit 'Create New Domain', class: "btn btn-save"
- add_to_breadcrumbs "Pages", project_pages_path(@project)
- breadcrumb_title @domain.domain
- page_title "#{@domain.domain}", 'Pages Domains'
- verification_enabled = Gitlab::CurrentSettings.pages_domain_verification_enabled?
- if verification_enabled && @domain.unverified?
%p.alert.alert-warning
......@@ -8,6 +11,7 @@
%h3.page-title
Pages Domain
= link_to 'Edit', edit_project_pages_domain_path(@project, @domain), class: 'btn btn-success pull-right'
.table-holder
%table.table
......
......@@ -29,6 +29,11 @@
Token
.col-sm-10
= f.text_field :token, class: 'form-control', readonly: true
.form-group
= label_tag :ip_address, class: 'control-label' do
IP Address
.col-sm-10
= f.text_field :ip_address, class: 'form-control', readonly: true
.form-group
= label_tag :description, class: 'control-label' do
Description
......
......@@ -40,6 +40,9 @@
%tr
%td Version
%td= @runner.version
%tr
%td IP Address
%td= @runner.ip_address
%tr
%td Revision
%td= @runner.revision
......
---
title: Display Runner IP Address
merge_request: 17286
author:
type: added
---
title: Fix code and wiki search results pages when non-ASCII text is displayed
merge_request: 17413
author:
type: fixed
---
title: Enable filtering MR list based on clicked label in MR sidebar
merge_request: 17390
author:
type: fixed
---
title: Make sure wiki exists when it's enabled
merge_request:
author:
type: fixed
---
title: Add Assignees vue component missing data container
merge_request: 17426
author: George Tsiolis
type: fixed
---
title: 'Pages custom domain: allow update of key/certificate'
merge_request: 17376
author: rfwatson
type: changed
......@@ -12,9 +12,14 @@ unless Sidekiq.server?
config.lograge.logger = ActiveSupport::Logger.new(filename)
# Add request parameters to log output
config.lograge.custom_options = lambda do |event|
params = event.payload[:params]
.except(*%w(controller action format))
.each_pair
.map { |k, v| { key: k, value: v } }
payload = {
time: event.time.utc.iso8601(3),
params: event.payload[:params].except(*%w(controller action format)),
params: params,
remote_ip: event.payload[:remote_ip],
user_id: event.payload[:user_id],
username: event.payload[:username]
......
......@@ -55,7 +55,7 @@ constraints(ProjectUrlConstrainer.new) do
end
resource :pages, only: [:show, :destroy] do
resources :domains, only: [:show, :new, :create, :destroy], controller: 'pages_domains', constraints: { id: %r{[^/]+} } do
resources :domains, except: :index, controller: 'pages_domains', constraints: { id: %r{[^/]+} } do
member do
post :verify
end
......
class AddIpAddressToRunner < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def change
add_column :ci_runners, :ip_address, :string
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20180216121030) do
ActiveRecord::Schema.define(version: 20180222043024) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -518,6 +518,7 @@ ActiveRecord::Schema.define(version: 20180216121030) do
t.boolean "run_untagged", default: true, null: false
t.boolean "locked", default: false, null: false
t.integer "access_level", default: 0, null: false
t.string "ip_address"
end
add_index "ci_runners", ["contacted_at"], name: "index_ci_runners_on_contacted_at", using: :btree
......
......@@ -56,6 +56,9 @@ future GitLab releases.**
| **CI_RUNNER_DESCRIPTION** | 8.10 | 0.5 | The description of the runner as saved in GitLab |
| **CI_RUNNER_ID** | 8.10 | 0.5 | The unique id of runner being used |
| **CI_RUNNER_TAGS** | 8.10 | 0.5 | The defined runner tags |
| **CI_RUNNER_VERSION** | all | 10.6 | GitLab Runner version that is executing the current job |
| **CI_RUNNER_REVISION** | all | 10.6 | GitLab Runner revision that is executing the current job |
| **CI_RUNNER_EXECUTABLE_ARCH** | all | 10.6 | The OS/architecture of the GitLab Runner executable (note that this is not necessarily the same as the environment of the executor) |
| **CI_PIPELINE_ID** | 8.10 | 0.5 | The unique id of the current pipeline that GitLab CI uses internally |
| **CI_PIPELINE_SOURCE** | 9.3 | all | ([Premium]) The variable indicates how the pipeline was triggered, possible options are: push, web, trigger, schedule, api, pipeline |
| **CI_PIPELINE_TRIGGERED** | all | all | The flag to indicate that job was [triggered] |
......
......@@ -109,8 +109,7 @@ in your SAML IdP:
1. Change the value of `issuer` to a unique name, which will identify the application
to the IdP.
1. [Reconfigure][] or [restart GitLab][] for the changes to take effect if you
installed GitLab via Omnibus or from source respectively.
1. For the changes to take effect, you must [reconfigure][] GitLab if you installed via Omnibus or [restart GitLab][] if you installed from source.
1. Register the GitLab SP in your SAML 2.0 IdP, using the application name specified
in `issuer`.
......
......@@ -37,12 +37,16 @@ GFM honors the markdown specification in how [paragraphs and line breaks are han
A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines.
Line-breaks, or softreturns, are rendered if you end a line with two or more spaces:
Roses are red [followed by two or more spaces]
[//]: # (Do *NOT* remove the two ending whitespaces in the following line.)
[//]: # (They are needed for the Markdown text to render correctly.)
Roses are red [followed by two or more spaces]
Violets are blue
Sugar is sweet
Roses are red
[//]: # (Do *NOT* remove the two ending whitespaces in the following line.)
[//]: # (They are needed for the Markdown text to render correctly.)
Roses are red
Violets are blue
Sugar is sweet
......
......@@ -31,10 +31,10 @@ With GitLab merge requests, you can:
With **[GitLab Enterprise Edition][ee]**, you can also:
- View the deployment process across projects with [Multi-Project Pipeline Graphs](../../../ci/multi_project_pipeline_graphs.md) (available only in GitLab Premium)
- Request [approvals](#merge-request-approvals) from your managers (available in GitLab Starter)
- [Squash and merge](#squash-and-merge) for a cleaner commit history (available in GitLab Starter)
- Analyze the impact of your changes with [Code Quality reports](#code-quality-reports) (available in GitLab Starter)
- View the deployment process across projects with [Multi-Project Pipeline Graphs](https://docs.gitlab.com/ee/ci/multi_project_pipeline_graphs.html#multi-project-pipeline-graphs) (available only in GitLab Premium)
- Request [approvals](https://docs.gitlab.com/ee/user/project/merge_requests/merge_request_approvals.html) from your managers (available in GitLab Starter)
- [Squash and merge](https://docs.gitlab.com/ee/user/project/merge_requests/squash_and_merge.html) for a cleaner commit history (available in GitLab Starter)
- Analyze the impact of your changes with [Code Quality reports](https://docs.gitlab.com/ee/user/project/merge_requests/code_quality_diff.html) (available in GitLab Starter)
- Determine the performance impact of changes with [Browser Performance Testing](#browser-performance-testing) (available in GitLab Premium)
## Use cases
......
......@@ -11,16 +11,22 @@ module API
Gitlab::CurrentSettings.runners_registration_token)
end
def get_runner_version_from_params
return unless params['info'].present?
def authenticate_runner!
forbidden! unless current_runner
attributes_for_keys(%w(name version revision platform architecture), params['info'])
current_runner
.update_cached_info(get_runner_details_from_request)
end
def authenticate_runner!
forbidden! unless current_runner
def get_runner_details_from_request
return get_runner_ip unless params['info'].present?
attributes_for_keys(%w(name version revision platform architecture), params['info'])
.merge(get_runner_ip)
end
current_runner.update_cached_info(get_runner_version_from_params)
def get_runner_ip
{ ip_address: request.ip }
end
def current_runner
......
......@@ -16,7 +16,8 @@ module API
optional :tag_list, type: Array[String], desc: %q(List of Runner's tags)
end
post '/' do
attributes = attributes_for_keys [:description, :locked, :run_untagged, :tag_list]
attributes = attributes_for_keys([:description, :locked, :run_untagged, :tag_list])
.merge(get_runner_details_from_request)
runner =
if runner_registration_token_valid?
......@@ -30,7 +31,6 @@ module API
return forbidden! unless runner
if runner.id
runner.update(get_runner_version_from_params)
present runner, with: Entities::RunnerRegistrationDetails
else
not_found!
......
......@@ -59,7 +59,7 @@ module Gitlab
end
def pages(limit: nil)
@repository.gitaly_migrate(:wiki_get_all_pages, status: Gitlab::GitalyClient::MigrationStatus::DISABLED) do |is_enabled|
@repository.gitaly_migrate(:wiki_get_all_pages) do |is_enabled|
if is_enabled
gitaly_get_all_pages
else
......@@ -68,9 +68,8 @@ module Gitlab
end
end
# Disable because of https://gitlab.com/gitlab-org/gitlab-ce/issues/42039
def page(title:, version: nil, dir: nil)
@repository.gitaly_migrate(:wiki_find_page, status: Gitlab::GitalyClient::MigrationStatus::DISABLED) do |is_enabled|
@repository.gitaly_migrate(:wiki_find_page) do |is_enabled|
if is_enabled
gitaly_find_page(title: title, version: version, dir: dir)
else
......
module Gitlab
class SearchResults
class FoundBlob
include EncodingHelper
attr_reader :id, :filename, :basename, :ref, :startline, :data, :project_id
def initialize(opts = {})
......@@ -9,7 +11,7 @@ module Gitlab
@basename = opts.fetch(:basename, nil)
@ref = opts.fetch(:ref, nil)
@startline = opts.fetch(:startline, nil)
@data = opts.fetch(:data, nil)
@data = encode_utf8(opts.fetch(:data, nil))
@per_page = opts.fetch(:per_page, 20)
@project_id = opts.fetch(:project_id, nil)
end
......
......@@ -21,6 +21,8 @@ else
File.open(hook_path, 'w') do |file|
IO.copy_stream(DATA, file)
end
File.chmod(0755, hook_path)
end
# Toggle the harness on or off
......
......@@ -53,6 +53,66 @@ describe Projects::PagesDomainsController do
end
end
describe 'GET edit' do
it "displays the 'edit' page" do
get(:edit, request_params.merge(id: pages_domain.domain))
expect(response).to have_gitlab_http_status(200)
expect(response).to render_template('edit')
end
end
describe 'PATCH update' do
before do
controller.instance_variable_set(:@domain, pages_domain)
end
let(:pages_domain_params) do
attributes_for(:pages_domain, :with_certificate, :with_key).slice(:key, :certificate)
end
let(:params) do
request_params.merge(id: pages_domain.domain, pages_domain: pages_domain_params)
end
it 'updates the domain' do
expect(pages_domain)
.to receive(:update)
.with(pages_domain_params)
.and_return(true)
patch(:update, params)
end
it 'redirects to the project page' do
patch(:update, params)
expect(flash[:notice]).to eq 'Domain was updated'
expect(response).to redirect_to(project_pages_path(project))
end
context 'the domain is invalid' do
it 'renders the edit action' do
allow(pages_domain).to receive(:update).and_return(false)
patch(:update, params)
expect(response).to render_template('edit')
end
end
context 'the parameters include the domain' do
it 'renders 400 Bad Request' do
expect(pages_domain)
.to receive(:update)
.with(hash_not_including(:domain))
.and_return(true)
patch(:update, params.deep_merge(pages_domain: { domain: 'abc' }))
end
end
end
describe 'POST verify' do
let(:params) { request_params.merge(id: pages_domain.domain) }
......
......@@ -160,6 +160,37 @@ feature 'Pages' do
expect(page).to have_content('my.test.domain.com')
end
describe 'updating the certificate for an existing domain' do
let!(:domain) do
create(:pages_domain, :with_key, :with_certificate, project: project)
end
it 'allows the certificate to be updated' do
visit project_pages_path(project)
within('#content-body') { click_link 'Details' }
click_link 'Edit'
click_button 'Save Changes'
expect(page).to have_content('Domain was updated')
end
context 'when the certificate is invalid' do
it 'tells the user what the problem is' do
visit project_pages_path(project)
within('#content-body') { click_link 'Details' }
click_link 'Edit'
fill_in 'Certificate (PEM)', with: 'invalid data'
click_button 'Save Changes'
expect(page).to have_content('Certificate must be a valid PEM certificate')
expect(page).to have_content('Certificate misses intermediates')
expect(page).to have_content("Key doesn't match the certificate")
end
end
end
end
end
......
......@@ -367,23 +367,6 @@ describe 'Pipelines', :js do
expect(build.reload).to be_canceled
end
end
context 'dropdown jobs list' do
it 'should keep the dropdown open when the user ctr/cmd + clicks in the job name' do
find('.js-builds-dropdown-button').click
dropdown_item = find('.mini-pipeline-graph-dropdown-item').native
%i(alt control).each do |meta_key|
page.driver.browser.action
.key_down(meta_key)
.click(dropdown_item)
.key_up(meta_key)
.perform
end
expect(page).to have_selector('.js-ci-action-icon')
end
end
end
context 'with pagination' do
......
import LabelsSelect from '~/labels_select';
const mockUrl = '/foo/bar/url';
const mockLabels = [
{
id: 26,
title: 'Foo Label',
description: 'Foobar',
color: '#BADA55',
text_color: '#FFFFFF',
},
];
describe('LabelsSelect', () => {
describe('getLabelTemplate', () => {
const label = mockLabels[0];
let $labelEl;
beforeEach(() => {
$labelEl = $(LabelsSelect.getLabelTemplate({
labels: mockLabels,
issueUpdateURL: mockUrl,
}));
});
it('generated label item template has correct label URL', () => {
expect($labelEl.attr('href')).toBe('/foo/bar?label_name[]=Foo%20Label');
});
it('generated label item template has correct label title', () => {
expect($labelEl.find('span.label').text()).toBe(label.title);
});
it('generated label item template has label description as title attribute', () => {
expect($labelEl.find('span.label').attr('title')).toBe(label.description);
});
it('generated label item template has correct label styles', () => {
expect($labelEl.find('span.label').attr('style')).toBe(`background-color: ${label.color}; color: ${label.text_color};`);
});
});
});
# coding: utf-8
require 'spec_helper'
describe Gitlab::ProjectSearchResults do
......@@ -105,6 +106,32 @@ describe Gitlab::ProjectSearchResults do
end
end
context 'when the search returns non-ASCII data' do
context 'with UTF-8' do
let(:results) { project.repository.search_files_by_content("файл", 'master') }
it 'returns results as UTF-8' do
expect(subject.filename).to eq('encoding/russian.rb')
expect(subject.basename).to eq('encoding/russian')
expect(subject.ref).to eq('master')
expect(subject.startline).to eq(1)
expect(subject.data).to eq("Хороший файл")
end
end
context 'with ISO-8859-1' do
let(:search_result) { "master:encoding/iso8859.txt\x001\x00\xC4\xFC\nmaster:encoding/iso8859.txt\x002\x00\nmaster:encoding/iso8859.txt\x003\x00foo\n".force_encoding(Encoding::ASCII_8BIT) }
it 'returns results as UTF-8' do
expect(subject.filename).to eq('encoding/iso8859.txt')
expect(subject.basename).to eq('encoding/iso8859')
expect(subject.ref).to eq('master')
expect(subject.startline).to eq(1)
expect(subject.data).to eq("Äü\n\nfoo")
end
end
end
context "when filename has extension" do
let(:search_result) { "master:CONTRIBUTE.md\x005\x00- [Contribute to GitLab](#contribute-to-gitlab)\n" }
......
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20170711145558_migrate_stages_statuses.rb')
describe MigrateStagesStatuses, :migration do
describe MigrateStagesStatuses, :sidekiq, :migration do
let(:jobs) { table(:ci_builds) }
let(:stages) { table(:ci_stages) }
let(:pipelines) { table(:ci_pipelines) }
......
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20180212101928_schedule_build_stage_migration')
describe ScheduleBuildStageMigration, :migration do
describe ScheduleBuildStageMigration, :sidekiq, :migration do
let(:projects) { table(:projects) }
let(:pipelines) { table(:ci_pipelines) }
let(:stages) { table(:ci_stages) }
......
......@@ -122,6 +122,15 @@ describe API::Runner do
end
end
end
it "sets the runner's ip_address" do
post api('/runners'),
{ token: registration_token },
{ 'REMOTE_ADDR' => '123.111.123.111' }
expect(response).to have_gitlab_http_status 201
expect(Ci::Runner.first.ip_address).to eq('123.111.123.111')
end
end
describe 'DELETE /api/v4/runners' do
......@@ -424,6 +433,15 @@ describe API::Runner do
end
end
it "sets the runner's ip_address" do
post api('/jobs/request'),
{ token: runner.token },
{ 'User-Agent' => user_agent, 'REMOTE_ADDR' => '123.222.123.222' }
expect(response).to have_gitlab_http_status 201
expect(runner.reload.ip_address).to eq('123.222.123.222')
end
context 'when concurrently updating a job' do
before do
expect_any_instance_of(Ci::Build).to receive(:run!)
......
......@@ -124,6 +124,40 @@ describe Projects::UpdateService, '#execute' do
end
end
context 'when we update project but not enabling a wiki' do
it 'does not try to create an empty wiki' do
FileUtils.rm_rf(project.wiki.repository.path)
result = update_project(project, user, { name: 'test1' })
expect(result).to eq({ status: :success })
expect(project.wiki_repository_exists?).to be false
end
end
context 'when enabling a wiki' do
it 'creates a wiki' do
project.project_feature.update(wiki_access_level: ProjectFeature::DISABLED)
FileUtils.rm_rf(project.wiki.repository.path)
result = update_project(project, user, project_feature_attributes: { wiki_access_level: ProjectFeature::ENABLED })
expect(result).to eq({ status: :success })
expect(project.wiki_repository_exists?).to be true
expect(project.wiki_enabled?).to be true
end
it 'logs an error and creates a metric when wiki can not be created' do
project.project_feature.update(wiki_access_level: ProjectFeature::DISABLED)
expect_any_instance_of(ProjectWiki).to receive(:wiki).and_raise(ProjectWiki::CouldNotCreateWikiError)
expect_any_instance_of(described_class).to receive(:log_error).with("Could not create wiki for #{project.full_name}")
expect(Gitlab::Metrics).to receive(:counter)
update_project(project, user, project_feature_attributes: { wiki_access_level: ProjectFeature::ENABLED })
end
end
context 'when updating a project that contains container images' do
before do
stub_container_registry_config(enabled: true)
......
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