BigW Consortium Gitlab

Commit 9f57d082 by Mark Fletcher

Merge branch '10-4-stable-with-rc5-and-rc6' into '10-4-stable'

10-4-stable with rc5 and rc6 from dev See merge request gitlab-org/gitlab-ce!16508
parents 904b1cda 3cf7681a
app/assets/images/multi-editor-on.png

5.34 KB | W: | H:

app/assets/images/multi-editor-on.png

3.88 KB | W: | H:

app/assets/images/multi-editor-on.png
app/assets/images/multi-editor-on.png
app/assets/images/multi-editor-on.png
app/assets/images/multi-editor-on.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -30,8 +30,12 @@ ...@@ -30,8 +30,12 @@
shouldRenderContent() { shouldRenderContent() {
return !this.isLoading && Object.keys(this.job).length; return !this.isLoading && Object.keys(this.job).length;
}, },
/**
* When job has not started the key will be `false`
* When job started the key will be a string with a date.
*/
jobStarted() { jobStarted() {
return this.job.started; return !this.job.started === false;
}, },
}, },
methods: { methods: {
......
...@@ -19,11 +19,8 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -19,11 +19,8 @@ document.addEventListener('DOMContentLoaded', () => {
return; return;
} }
$(navEl).on('show.bs.dropdown', (e) => { $(navEl).on('shown.bs.dropdown', () => {
const dropdownEl = $(e.currentTarget).find('.projects-dropdown-menu'); eventHub.$emit('dropdownOpen');
dropdownEl.one('transitionend', () => {
eventHub.$emit('dropdownOpen');
});
}); });
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
......
...@@ -651,12 +651,18 @@ ...@@ -651,12 +651,18 @@
min-width: 0; min-width: 0;
} }
.diff-changed-file-name { .diff-changed-file-name,
.diff-changed-blank-file-name {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.diff-changed-blank-file-name {
color: $gl-text-color-tertiary;
font-style: italic;
}
.diff-changed-file-path { .diff-changed-file-path {
color: $gl-text-color-tertiary; color: $gl-text-color-tertiary;
} }
......
...@@ -303,7 +303,6 @@ ...@@ -303,7 +303,6 @@
.gutter-toggle { .gutter-toggle {
margin-top: 7px; margin-top: 7px;
border-left: 1px solid $border-gray-normal; border-left: 1px solid $border-gray-normal;
padding-left: 0;
text-align: center; text-align: center;
} }
......
...@@ -29,7 +29,7 @@ class Projects::JobsController < Projects::ApplicationController ...@@ -29,7 +29,7 @@ class Projects::JobsController < Projects::ApplicationController
:project, :project,
:tags :tags
]) ])
@builds = @builds.page(params[:page]).per(30) @builds = @builds.page(params[:page]).per(30).without_count
end end
def cancel_all def cancel_all
......
...@@ -46,7 +46,7 @@ module BlobHelper ...@@ -46,7 +46,7 @@ module BlobHelper
end end
def ide_edit_text def ide_edit_text
"#{_('Multi Edit')} <span class='label label-primary'>#{_('Beta')}</span>".html_safe "#{_('Web IDE')}"
end end
def ide_blob_link(project = @project, ref = @ref, path = @path, options = {}) def ide_blob_link(project = @project, ref = @ref, path = @path, options = {})
......
...@@ -103,6 +103,10 @@ class Repository ...@@ -103,6 +103,10 @@ class Repository
"#<#{self.class.name}:#{@disk_path}>" "#<#{self.class.name}:#{@disk_path}>"
end end
def create_hooks
Gitlab::Git::Repository.create_hooks(path_to_repo, Gitlab.config.gitlab_shell.hooks_path)
end
def commit(ref = 'HEAD') def commit(ref = 'HEAD')
return nil unless exists? return nil unless exists?
return ref if ref.is_a?(::Commit) return ref if ref.is_a?(::Commit)
......
...@@ -154,13 +154,9 @@ module MergeRequests ...@@ -154,13 +154,9 @@ module MergeRequests
end end
def assign_title_from_issue def assign_title_from_issue
return unless issue return unless issue && issue.is_a?(Issue)
merge_request.title = merge_request.title = "Resolve \"#{issue.title}\""
case issue
when Issue then "Resolve \"#{issue.title}\""
when ExternalIssue then "Resolve #{issue.title}"
end
end end
def issue_iid def issue_iid
......
...@@ -56,8 +56,6 @@ ...@@ -56,8 +56,6 @@
= link_to "Profile", current_user, class: 'profile-link', data: { user: current_user.username } = link_to "Profile", current_user, class: 'profile-link', data: { user: current_user.username }
%li %li
= link_to "Settings", profile_path = link_to "Settings", profile_path
%li
= link_to "Turn on multi edit", profile_preferences_path
- if current_user - if current_user
%li %li
= link_to "Help", help_path = link_to "Help", help_path
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
= form_for @user, url: profile_preferences_path, remote: true, method: :put, html: { class: 'row prepend-top-default js-preferences-form' } do |f| = form_for @user, url: profile_preferences_path, remote: true, method: :put, html: { class: 'row prepend-top-default js-preferences-form' } do |f|
.col-lg-4 .col-lg-4
%h4.prepend-top-0 %h4.prepend-top-0
GitLab multi file editor Web IDE (Beta)
%p Unlock an additional editing experience which makes it possible to edit and commit multiple files %p Enable the new web IDE on this device to make it possible to open and edit multiple files with a single commit
.col-lg-8.multi-file-editor-options .col-lg-8.multi-file-editor-options
= label_tag do = label_tag do
.preview.append-bottom-10= image_tag "multi-editor-off.png" .preview.append-bottom-10= image_tag "multi-editor-off.png"
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
- unless diff_file.submodule? - unless diff_file.submodule?
- blob = diff_file.blob - blob = diff_file.blob
.file-actions.hidden-xs .file-actions.hidden-xs
- if blob.readable_text? - if blob&.readable_text?
= link_to '#', class: 'js-toggle-diff-comments btn active has-tooltip', title: "Toggle comments for this file", disabled: @diff_notes_disabled do = link_to '#', class: 'js-toggle-diff-comments btn active has-tooltip', title: "Toggle comments for this file", disabled: @diff_notes_disabled do
= icon('comment') = icon('comment')
\ \
......
...@@ -35,3 +35,6 @@ ...@@ -35,3 +35,6 @@
- if diff_file.mode_changed? - if diff_file.mode_changed?
%small %small
#{diff_file.a_mode}#{diff_file.b_mode} #{diff_file.a_mode}#{diff_file.b_mode}
- if diff_file.stored_externally? && diff_file.external_storage == :lfs
%span.label.label-lfs.append-right-5 LFS
...@@ -24,7 +24,12 @@ ...@@ -24,7 +24,12 @@
%a.diff-changed-file{ href: "##{hexdigest(diff_file.file_path)}", title: diff_file.new_path } %a.diff-changed-file{ href: "##{hexdigest(diff_file.file_path)}", title: diff_file.new_path }
= sprite_icon(diff_file_changed_icon(diff_file), size: 16, css_class: "#{diff_file_changed_icon_color(diff_file)} diff-file-changed-icon append-right-8") = sprite_icon(diff_file_changed_icon(diff_file), size: 16, css_class: "#{diff_file_changed_icon_color(diff_file)} diff-file-changed-icon append-right-8")
%span.diff-changed-file-content.append-right-8 %span.diff-changed-file-content.append-right-8
%strong.diff-changed-file-name= diff_file.blob.name - if diff_file.blob&.name
%strong.diff-changed-file-name
= diff_file.blob.name
- else
%strong.diff-changed-blank-file-name
= s_('Diffs|No file name available')
%span.diff-changed-file-path.prepend-top-5= diff_file_path_text(diff_file) %span.diff-changed-file-path.prepend-top-5= diff_file_path_text(diff_file)
%span.diff-changed-stats %span.diff-changed-stats
%span.cgreen< %span.cgreen<
......
- illustration = local_assigns.fetch(:illustration) - illustration = local_assigns.fetch(:illustration)
- illustration_size = local_assigns.fetch(:illustration_size) - illustration_size = local_assigns.fetch(:illustration_size)
- title = local_assigns.fetch(:title) - title = local_assigns.fetch(:title)
- content = local_assigns.fetch(:content) - content = local_assigns.fetch(:content, nil)
- action = local_assigns.fetch(:action, nil) - action = local_assigns.fetch(:action, nil)
.row.empty-state .row.empty-state
...@@ -11,7 +11,8 @@ ...@@ -11,7 +11,8 @@
.col-xs-12 .col-xs-12
.text-content .text-content
%h4.text-center= title %h4.text-center= title
%p= content - if content
%p= content
- if action - if action
.text-center .text-center
= action = action
...@@ -22,4 +22,4 @@ ...@@ -22,4 +22,4 @@
= render partial: "projects/ci/builds/build", collection: builds, as: :build, locals: { commit_sha: true, ref: true, pipeline_link: true, stage: true, allow_retry: true, admin: admin } = render partial: "projects/ci/builds/build", collection: builds, as: :build, locals: { commit_sha: true, ref: true, pipeline_link: true, stage: true, allow_retry: true, admin: admin }
= paginate builds, theme: 'gitlab' = paginate_collection(builds)
...@@ -93,14 +93,13 @@ ...@@ -93,14 +93,13 @@
illustration: 'illustrations/manual_action.svg', illustration: 'illustrations/manual_action.svg',
illustration_size: 'svg-394', illustration_size: 'svg-394',
title: _('This job requires a manual action'), title: _('This job requires a manual action'),
content: _('This job depends on a user to trigger its process. Often they are used to deploy code to production environments.'), content: _('This job depends on a user to trigger its process. Often they are used to deploy code to production environments'),
action: ( link_to _('Trigger this manual action'), play_project_job_path(@project, @build), class: 'btn btn-primary', title: _('Trigger this manual action') ) action: ( link_to _('Trigger this manual action'), play_project_job_path(@project, @build), method: :post, class: 'btn btn-primary', title: _('Trigger this manual action') )
- else - else
= render 'empty_state', = render 'empty_state',
illustration: 'illustrations/job_not_triggered.svg', illustration: 'illustrations/job_not_triggered.svg',
illustration_size: 'svg-306', illustration_size: 'svg-306',
title: _('This job has not been triggered yet'), title: _('This job has not been triggered yet')
content: _('This job depends on upstream jobs that need to succeed in order for this job to be triggered.')
= render "sidebar" = render "sidebar"
......
---
title: Default merge request title is set correctly again when external issue tracker is activated
merge_request: 16356
author: Ben305
type: fixed
---
title: Fix 500 error when visiting a commit where the blobs do not exist
merge_request:
author:
type: fixed
---
title: Fix web ide user preferences copy and buttons
merge_request: 41789
author:
type: other
---
title: Ensure that emails contain absolute, rather than relative, links to user uploads
merge_request: 16364
author:
type: fixed
---
title: "[API] Fix creating issue when assignee_id is empty"
merge_request:
author:
type: fixed
---
title: Use simple Next/Prev paging for jobs to avoid large count queries on arbitrarily
large sets of historical jobs
merge_request:
author:
type: performance
---
title: Fixing rack request mime type when using rack attack
merge_request: 16427
author:
type: fixed
---
title: Fix hooks not being set up properly for bare import Rake task
merge_request:
author:
type: fixed
...@@ -16,7 +16,8 @@ codequality: ...@@ -16,7 +16,8 @@ codequality:
- docker:dind - docker:dind
script: script:
- docker pull codeclimate/codeclimate - docker pull codeclimate/codeclimate
- docker run --env CODECLIMATE_CODE="$PWD" --volume "$PWD":/code --volume /var/run/docker.sock:/var/run/docker.sock --volume /tmp/cc:/tmp/cc codeclimate/codeclimate analyze -f json > codeclimate.json || true - docker run --env CODECLIMATE_CODE="$PWD" --volume "$PWD":/code --volume /var/run/docker.sock:/var/run/docker.sock --volume /tmp/cc:/tmp/cc codeclimate/codeclimate:0.69.0 init
- docker run --env CODECLIMATE_CODE="$PWD" --volume "$PWD":/code --volume /var/run/docker.sock:/var/run/docker.sock --volume /tmp/cc:/tmp/cc codeclimate/codeclimate:0.69.0 analyze -f json > codeclimate.json || true
artifacts: artifacts:
paths: [codeclimate.json] paths: [codeclimate.json]
``` ```
......
...@@ -64,7 +64,7 @@ up-to-date and install it. ...@@ -64,7 +64,7 @@ up-to-date and install it.
Install the required packages (needed to compile Ruby and native extensions to Ruby gems): Install the required packages (needed to compile Ruby and native extensions to Ruby gems):
sudo apt-get install -y build-essential zlib1g-dev libyaml-dev libssl-dev libgdbm-dev libre2-dev libreadline-dev libncurses5-dev libffi-dev curl openssh-server checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libicu-dev logrotate python-docutils pkg-config cmake sudo apt-get install -y build-essential zlib1g-dev libyaml-dev libssl-dev libgdbm-dev libre2-dev libreadline-dev libncurses5-dev libffi-dev curl openssh-server checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libicu-dev logrotate rsync python-docutils pkg-config cmake
Ubuntu 14.04 (Trusty Tahr) doesn't have the `libre2-dev` package available, but Ubuntu 14.04 (Trusty Tahr) doesn't have the `libre2-dev` package available, but
you can [install re2 manually](https://github.com/google/re2/wiki/Install). you can [install re2 manually](https://github.com/google/re2/wiki/Install).
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
An application data backup creates an archive file that contains the database, An application data backup creates an archive file that contains the database,
all repositories and all attachments. all repositories and all attachments.
You can only restore a backup to **exactly the same version and type (CE/EE)** You can only restore a backup to **exactly the same version and type (CE/EE)**
of GitLab on which it was created. The best way to migrate your repositories of GitLab on which it was created. The best way to migrate your repositories
from one server to another is through backup restore. from one server to another is through backup restore.
## Backup ## Backup
...@@ -14,6 +14,19 @@ from one server to another is through backup restore. ...@@ -14,6 +14,19 @@ from one server to another is through backup restore.
GitLab provides a simple command line interface to backup your whole installation, GitLab provides a simple command line interface to backup your whole installation,
and is flexible enough to fit your needs. and is flexible enough to fit your needs.
### Requirements
If you're using GitLab with the Omnibus package, you're all set. If you
installed GitLab from source, make sure the following packages are installed:
* rsync
If you're using Ubuntu, you could run:
```
sudo apt-get install -y rsync
```
### Backup timestamp ### Backup timestamp
>**Note:** >**Note:**
...@@ -431,7 +444,7 @@ The [restore prerequisites section](#restore-prerequisites) includes crucial ...@@ -431,7 +444,7 @@ The [restore prerequisites section](#restore-prerequisites) includes crucial
information. Make sure to read and test the whole restore process at least once information. Make sure to read and test the whole restore process at least once
before attempting to perform it in a production environment. before attempting to perform it in a production environment.
You can only restore a backup to **exactly the same version and type (CE/EE)** of You can only restore a backup to **exactly the same version and type (CE/EE)** of
GitLab that you created it on, for example CE 9.1.0. GitLab that you created it on, for example CE 9.1.0.
### Restore prerequisites ### Restore prerequisites
...@@ -511,7 +524,7 @@ sudo service gitlab restart ...@@ -511,7 +524,7 @@ sudo service gitlab restart
This procedure assumes that: This procedure assumes that:
- You have installed the **exact same version and type (CE/EE)** of GitLab - You have installed the **exact same version and type (CE/EE)** of GitLab
Omnibus with which the backup was created. Omnibus with which the backup was created.
- You have run `sudo gitlab-ctl reconfigure` at least once. - You have run `sudo gitlab-ctl reconfigure` at least once.
- GitLab is running. If not, start it using `sudo gitlab-ctl start`. - GitLab is running. If not, start it using `sudo gitlab-ctl start`.
......
...@@ -21,6 +21,8 @@ sudo service gitlab stop ...@@ -21,6 +21,8 @@ sudo service gitlab stop
### 2. Backup ### 2. Backup
NOTE: If you installed GitLab from source, make sure `rsync` is installed.
```bash ```bash
cd /home/git/gitlab cd /home/git/gitlab
......
...@@ -2,9 +2,6 @@ ...@@ -2,9 +2,6 @@
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/35954) in 10.1. > [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/35954) in 10.1.
CAUTION: **Warning:**
The Cluster integration is currently in **Beta**.
With a cluster associated to your project, you can use Review Apps, deploy your With a cluster associated to your project, you can use Review Apps, deploy your
applications, run your pipelines, and much more, in an easy way. applications, run your pipelines, and much more, in an easy way.
......
...@@ -3,8 +3,10 @@ module API ...@@ -3,8 +3,10 @@ module API
module CommonHelpers module CommonHelpers
def convert_parameters_from_legacy_format(params) def convert_parameters_from_legacy_format(params)
params.tap do |params| params.tap do |params|
if params[:assignee_id].present? assignee_id = params.delete(:assignee_id)
params[:assignee_ids] = [params.delete(:assignee_id)]
if assignee_id.present?
params[:assignee_ids] = [assignee_id]
end end
end end
end end
......
...@@ -50,15 +50,22 @@ module Banzai ...@@ -50,15 +50,22 @@ module Banzai
end end
def process_link_to_upload_attr(html_attr) def process_link_to_upload_attr(html_attr)
uri_parts = [html_attr.value] path_parts = [html_attr.value]
if group if group
uri_parts.unshift(relative_url_root, 'groups', group.full_path, '-') path_parts.unshift(relative_url_root, 'groups', group.full_path, '-')
elsif project elsif project
uri_parts.unshift(relative_url_root, project.full_path) path_parts.unshift(relative_url_root, project.full_path)
end end
html_attr.value = File.join(*uri_parts) path = File.join(*path_parts)
html_attr.value =
if context[:only_path]
path
else
URI.join(Gitlab.config.gitlab.base_url, path).to_s
end
end end
def process_link_to_repository_attr(html_attr) def process_link_to_repository_attr(html_attr)
......
...@@ -96,9 +96,7 @@ module Gitlab ...@@ -96,9 +96,7 @@ module Gitlab
end end
def ensure_action_dispatch_request(request) def ensure_action_dispatch_request(request)
return request if request.is_a?(ActionDispatch::Request) ActionDispatch::Request.new(request.env.dup)
ActionDispatch::Request.new(request.env)
end end
def current_request def current_request
......
...@@ -63,6 +63,7 @@ module Gitlab ...@@ -63,6 +63,7 @@ module Gitlab
log " * Created #{project.name} (#{project_full_path})".color(:green) log " * Created #{project.name} (#{project_full_path})".color(:green)
project.write_repository_config project.write_repository_config
project.repository.create_hooks
ProjectCacheWorker.perform_async(project.id) ProjectCacheWorker.perform_async(project.id)
else else
......
require 'spec_helper' require 'spec_helper'
describe 'User broweses commits' do describe 'User browses commits' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:project) { create(:project, :repository, namespace: user.namespace) } let(:project) { create(:project, :repository, namespace: user.namespace) }
...@@ -31,6 +31,19 @@ describe 'User broweses commits' do ...@@ -31,6 +31,19 @@ describe 'User broweses commits' do
check_author_link(RepoHelpers.sample_commit.author_email, user) check_author_link(RepoHelpers.sample_commit.author_email, user)
end end
end end
context 'when the blob does not exist' do
let(:commit) { create(:commit, project: project) }
it 'shows a blank label' do
allow_any_instance_of(Gitlab::Diff::File).to receive(:blob).and_return(nil)
allow_any_instance_of(Gitlab::Diff::File).to receive(:raw_binary?).and_return(true)
visit(project_commit_path(project, commit))
expect(find('.diff-file-changes', visible: false)).to have_content('No file name available')
end
end
end end
private private
......
...@@ -380,9 +380,18 @@ feature 'Jobs' do ...@@ -380,9 +380,18 @@ feature 'Jobs' do
it 'shows manual action empty state' do it 'shows manual action empty state' do
expect(page).to have_content('This job requires a manual action') expect(page).to have_content('This job requires a manual action')
expect(page).to have_content('This job depends on a user to trigger its process. Often they are used to deploy code to production environments.') expect(page).to have_content('This job depends on a user to trigger its process. Often they are used to deploy code to production environments')
expect(page).to have_link('Trigger this manual action') expect(page).to have_link('Trigger this manual action')
end end
it 'plays manual action', :js do
click_link 'Trigger this manual action'
wait_for_requests
expect(page).to have_content('This job has not been triggered')
expect(page).to have_content('This job is stuck, because the project doesn\'t have any runners online assigned to it.')
expect(page).to have_content('pending')
end
end end
context 'Non triggered job' do context 'Non triggered job' do
...@@ -392,9 +401,8 @@ feature 'Jobs' do ...@@ -392,9 +401,8 @@ feature 'Jobs' do
visit project_job_path(project, job) visit project_job_path(project, job)
end end
it 'shows manual action empty state' do it 'shows empty state' do
expect(page).to have_content('This job has not been triggered yet') expect(page).to have_content('This job has not been triggered yet')
expect(page).to have_content('This job depends on upstream jobs that need to succeed in order for this job to be triggered.')
end end
end end
end end
......
...@@ -14,7 +14,7 @@ feature 'Multi-file editor new directory', :js do ...@@ -14,7 +14,7 @@ feature 'Multi-file editor new directory', :js do
wait_for_requests wait_for_requests
click_link('Multi Edit') click_link('Web IDE')
wait_for_requests wait_for_requests
end end
......
...@@ -14,7 +14,7 @@ feature 'Multi-file editor new file', :js do ...@@ -14,7 +14,7 @@ feature 'Multi-file editor new file', :js do
wait_for_requests wait_for_requests
click_link('Multi Edit') click_link('Web IDE')
wait_for_requests wait_for_requests
end end
......
...@@ -16,7 +16,7 @@ feature 'Multi-file editor upload file', :js do ...@@ -16,7 +16,7 @@ feature 'Multi-file editor upload file', :js do
wait_for_requests wait_for_requests
click_link('Multi Edit') click_link('Web IDE')
wait_for_requests wait_for_requests
end end
......
...@@ -31,6 +31,7 @@ describe('Job details header', () => { ...@@ -31,6 +31,7 @@ describe('Job details header', () => {
email: 'foo@bar.com', email: 'foo@bar.com',
avatar_url: 'link', avatar_url: 'link',
}, },
started: '2018-01-08T09:48:27.319Z',
new_issue_path: 'path', new_issue_path: 'path',
}, },
isLoading: false, isLoading: false,
...@@ -43,15 +44,32 @@ describe('Job details header', () => { ...@@ -43,15 +44,32 @@ describe('Job details header', () => {
vm.$destroy(); vm.$destroy();
}); });
it('should render provided job information', () => { describe('triggered job', () => {
expect( beforeEach(() => {
vm.$el.querySelector('.header-main-content').textContent.replace(/\s+/g, ' ').trim(), vm = mountComponent(HeaderComponent, props);
).toEqual('failed Job #123 triggered 3 weeks ago by Foo'); });
it('should render provided job information', () => {
expect(
vm.$el.querySelector('.header-main-content').textContent.replace(/\s+/g, ' ').trim(),
).toEqual('failed Job #123 triggered 3 weeks ago by Foo');
});
it('should render new issue link', () => {
expect(
vm.$el.querySelector('.js-new-issue').getAttribute('href'),
).toEqual(props.job.new_issue_path);
});
}); });
it('should render new issue link', () => { describe('created job', () => {
expect( it('should render created key', () => {
vm.$el.querySelector('.js-new-issue').getAttribute('href'), props.job.started = false;
).toEqual(props.job.new_issue_path); vm = mountComponent(HeaderComponent, props);
expect(
vm.$el.querySelector('.header-main-content').textContent.replace(/\s+/g, ' ').trim(),
).toEqual('failed Job #123 created 3 weeks ago by Foo');
});
}); });
}); });
...@@ -8,7 +8,8 @@ describe Banzai::Filter::RelativeLinkFilter do ...@@ -8,7 +8,8 @@ describe Banzai::Filter::RelativeLinkFilter do
group: group, group: group,
project_wiki: project_wiki, project_wiki: project_wiki,
ref: ref, ref: ref,
requested_path: requested_path requested_path: requested_path,
only_path: only_path
}) })
described_class.call(doc, contexts) described_class.call(doc, contexts)
...@@ -37,6 +38,7 @@ describe Banzai::Filter::RelativeLinkFilter do ...@@ -37,6 +38,7 @@ describe Banzai::Filter::RelativeLinkFilter do
let(:commit) { project.commit(ref) } let(:commit) { project.commit(ref) }
let(:project_wiki) { nil } let(:project_wiki) { nil }
let(:requested_path) { '/' } let(:requested_path) { '/' }
let(:only_path) { true }
shared_examples :preserve_unchanged do shared_examples :preserve_unchanged do
it 'does not modify any relative URL in anchor' do it 'does not modify any relative URL in anchor' do
...@@ -240,26 +242,35 @@ describe Banzai::Filter::RelativeLinkFilter do ...@@ -240,26 +242,35 @@ describe Banzai::Filter::RelativeLinkFilter do
let(:commit) { nil } let(:commit) { nil }
let(:ref) { nil } let(:ref) { nil }
let(:requested_path) { nil } let(:requested_path) { nil }
let(:upload_path) { '/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg' }
let(:relative_path) { "/#{project.full_path}#{upload_path}" }
context 'to a project upload' do context 'to a project upload' do
context 'with an absolute URL' do
let(:absolute_path) { Gitlab.config.gitlab.url + relative_path }
let(:only_path) { false }
it 'rewrites the link correctly' do
doc = filter(link(upload_path))
expect(doc.at_css('a')['href']).to eq(absolute_path)
end
end
it 'rebuilds relative URL for a link' do it 'rebuilds relative URL for a link' do
doc = filter(link('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg')) doc = filter(link(upload_path))
expect(doc.at_css('a')['href']) expect(doc.at_css('a')['href']).to eq(relative_path)
.to eq "/#{project.full_path}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
doc = filter(nested(link('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'))) doc = filter(nested(link(upload_path)))
expect(doc.at_css('a')['href']) expect(doc.at_css('a')['href']).to eq(relative_path)
.to eq "/#{project.full_path}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
end end
it 'rebuilds relative URL for an image' do it 'rebuilds relative URL for an image' do
doc = filter(image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg')) doc = filter(image(upload_path))
expect(doc.at_css('img')['src']) expect(doc.at_css('img')['src']).to eq(relative_path)
.to eq "/#{project.full_path}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
doc = filter(nested(image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'))) doc = filter(nested(image(upload_path)))
expect(doc.at_css('img')['src']) expect(doc.at_css('img')['src']).to eq(relative_path)
.to eq "/#{project.full_path}/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg"
end end
it 'does not modify absolute URL' do it 'does not modify absolute URL' do
...@@ -288,6 +299,17 @@ describe Banzai::Filter::RelativeLinkFilter do ...@@ -288,6 +299,17 @@ describe Banzai::Filter::RelativeLinkFilter do
let(:project) { nil } let(:project) { nil }
let(:relative_path) { "/groups/#{group.full_path}/-/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" } let(:relative_path) { "/groups/#{group.full_path}/-/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" }
context 'with an absolute URL' do
let(:absolute_path) { Gitlab.config.gitlab.url + relative_path }
let(:only_path) { false }
it 'rewrites the link correctly' do
doc = filter(upload_link)
expect(doc.at_css('a')['href']).to eq(absolute_path)
end
end
it 'rewrites the link correctly' do it 'rewrites the link correctly' do
doc = filter(upload_link) doc = filter(upload_link)
......
...@@ -76,6 +76,16 @@ describe Gitlab::Auth::UserAuthFinders do ...@@ -76,6 +76,16 @@ describe Gitlab::Auth::UserAuthFinders do
expect(find_user_from_rss_token).to be_nil expect(find_user_from_rss_token).to be_nil
end end
end end
context 'when the request format is empty' do
it 'the method call does not modify the original value' do
env['action_dispatch.request.formats'] = nil
find_user_from_rss_token
expect(env['action_dispatch.request.formats']).to be_nil
end
end
end end
describe '#find_user_from_access_token' do describe '#find_user_from_access_token' do
......
...@@ -74,14 +74,18 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do ...@@ -74,14 +74,18 @@ describe Gitlab::BareRepositoryImport::Importer, repository: true do
importer.create_project_if_needed importer.create_project_if_needed
end end
it 'creates the Git repo in disk' do it 'creates the Git repo on disk with the proper symlink for hooks' do
create_bare_repository("#{project_path}.git") create_bare_repository("#{project_path}.git")
importer.create_project_if_needed importer.create_project_if_needed
project = Project.find_by_full_path(project_path) project = Project.find_by_full_path(project_path)
repo_path = File.join(project.repository_storage_path, project.disk_path + '.git')
hook_path = File.join(repo_path, 'hooks')
expect(File).to exist(File.join(project.repository_storage_path, project.disk_path + '.git')) expect(File).to exist(repo_path)
expect(File.symlink?(hook_path)).to be true
expect(File.readlink(hook_path)).to eq(Gitlab.config.gitlab_shell.hooks_path)
end end
context 'hashed storage enabled' do context 'hashed storage enabled' do
......
...@@ -412,6 +412,28 @@ describe Repository do ...@@ -412,6 +412,28 @@ describe Repository do
end end
end end
describe '#create_hooks' do
let(:hook_path) { File.join(repository.path_to_repo, 'hooks') }
it 'symlinks the global hooks directory' do
repository.create_hooks
expect(File.symlink?(hook_path)).to be true
expect(File.readlink(hook_path)).to eq(Gitlab.config.gitlab_shell.hooks_path)
end
it 'replaces existing symlink with the right directory' do
FileUtils.mkdir_p(hook_path)
expect(File.symlink?(hook_path)).to be false
repository.create_hooks
expect(File.symlink?(hook_path)).to be true
expect(File.readlink(hook_path)).to eq(Gitlab.config.gitlab_shell.hooks_path)
end
end
describe "#create_dir" do describe "#create_dir" do
it "commits a change that creates a new directory" do it "commits a change that creates a new directory" do
expect do expect do
......
...@@ -847,6 +847,15 @@ describe API::Issues, :mailer do ...@@ -847,6 +847,15 @@ describe API::Issues, :mailer do
expect(json_response['assignee']['name']).to eq(user2.name) expect(json_response['assignee']['name']).to eq(user2.name)
expect(json_response['assignees'].first['name']).to eq(user2.name) expect(json_response['assignees'].first['name']).to eq(user2.name)
end end
it 'creates a new project issue when assignee_id is empty' do
post api("/projects/#{project.id}/issues", user),
title: 'new issue', assignee_id: ''
expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new issue')
expect(json_response['assignee']).to be_nil
end
end end
context 'single assignee restrictions' do context 'single assignee restrictions' do
......
...@@ -171,6 +171,24 @@ describe MergeRequests::BuildService do ...@@ -171,6 +171,24 @@ describe MergeRequests::BuildService do
end end
end end
end end
context 'branch starts with external issue IID followed by a hyphen' do
let(:source_branch) { '12345-fix-issue' }
before do
allow(project).to receive(:external_issue_tracker).and_return(true)
end
it 'uses the title of the commit as the title of the merge request' do
expect(merge_request.title).to eq(commit_1.safe_message.split("\n").first)
end
it 'uses the description of the commit as the description of the merge request and appends the closes text' do
commit_description = commit_1.safe_message.split(/\n+/, 2).last
expect(merge_request.description).to eq("#{commit_description}\n\nCloses #12345")
end
end
end end
context 'more than one commit in the diff' do context 'more than one commit in the diff' do
...@@ -241,8 +259,12 @@ describe MergeRequests::BuildService do ...@@ -241,8 +259,12 @@ describe MergeRequests::BuildService do
allow(project).to receive(:external_issue_tracker).and_return(true) allow(project).to receive(:external_issue_tracker).and_return(true)
end end
it 'sets the title to: Resolves External Issue $issue-iid' do it 'sets the title to the humanized branch title' do
expect(merge_request.title).to eq('Resolve External Issue 12345') expect(merge_request.title).to eq('12345 fix issue')
end
it 'appends the closes text' do
expect(merge_request.description).to eq('Closes #12345')
end end
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