mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-23 19:46:12 +10:00
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into award-emoji-fixes
This commit is contained in:
@@ -28,6 +28,7 @@ v 8.9.0 (unreleased)
|
||||
- Add DB index on users.state
|
||||
- Add rake task 'gitlab:db:configure' for conditionally seeding or migrating the database
|
||||
- Changed the Slack build message to use the singular duration if necessary (Aran Koning)
|
||||
- Links from a wiki page to other wiki pages should be rewritten as expected
|
||||
- Fix issues filter when ordering by milestone
|
||||
- Todos will display target state if issuable target is 'Closed' or 'Merged'
|
||||
- Fix bug when sorting issues by milestone due date and filtering by two or more labels
|
||||
@@ -38,6 +39,7 @@ v 8.9.0 (unreleased)
|
||||
- Use downcased path to container repository as this is expected path by Docker
|
||||
- Projects pending deletion will render a 404 page
|
||||
- Measure queue duration between gitlab-workhorse and Rails
|
||||
- Make Omniauth providers specs to not modify global configuration
|
||||
- Make authentication service for Container Registry to be compatible with < Docker 1.11
|
||||
- Add Application Setting to configure Container Registry token expire delay (default 5min)
|
||||
- Cache assigned issue and merge request counts in sidebar nav
|
||||
@@ -65,6 +67,7 @@ v 8.8.4 (unreleased)
|
||||
- Fix importer for GitHub comments on diff
|
||||
- Disable Webhooks before proceeding with the GitHub import
|
||||
- Added descriptions to notification settings dropdown
|
||||
- Markdown editor now correctly resets the input value on edit cancellation !4175
|
||||
|
||||
v 8.8.3
|
||||
- Fix 404 page when viewing TODOs that contain milestones or labels in different projects. !4312
|
||||
|
||||
@@ -22,6 +22,24 @@ GitLab.GfmAutoComplete =
|
||||
Milestones:
|
||||
template: '<li>${title}</li>'
|
||||
|
||||
Loading:
|
||||
template: '<li><i class="fa fa-refresh fa-spin"></i> Loading...</li>'
|
||||
|
||||
DefaultOptions:
|
||||
sorter: (query, items, searchKey) ->
|
||||
return items if items[0].name? and items[0].name is 'loading'
|
||||
|
||||
$.fn.atwho.default.callbacks.sorter(query, items, searchKey)
|
||||
filter: (query, data, searchKey) ->
|
||||
return data if data[0] is 'loading'
|
||||
|
||||
$.fn.atwho.default.callbacks.filter(query, data, searchKey)
|
||||
beforeInsert: (value) ->
|
||||
if value.indexOf('undefined')
|
||||
@at
|
||||
else
|
||||
value
|
||||
|
||||
# Add GFM auto-completion to all input fields, that accept GFM input.
|
||||
setup: (wrap) ->
|
||||
@input = $('.js-gfm-input')
|
||||
@@ -53,18 +71,37 @@ GitLab.GfmAutoComplete =
|
||||
# Emoji
|
||||
@input.atwho
|
||||
at: ':'
|
||||
displayTpl: @Emoji.template
|
||||
displayTpl: (value) =>
|
||||
if value.path?
|
||||
@Emoji.template
|
||||
else
|
||||
@Loading.template
|
||||
insertTpl: ':${name}:'
|
||||
data: ['loading']
|
||||
callbacks:
|
||||
sorter: @DefaultOptions.sorter
|
||||
filter: @DefaultOptions.filter
|
||||
beforeInsert: @DefaultOptions.beforeInsert
|
||||
|
||||
# Team Members
|
||||
@input.atwho
|
||||
at: '@'
|
||||
displayTpl: @Members.template
|
||||
displayTpl: (value) =>
|
||||
if value.username?
|
||||
@Members.template
|
||||
else
|
||||
@Loading.template
|
||||
insertTpl: '${atwho-at}${username}'
|
||||
searchKey: 'search'
|
||||
data: ['loading']
|
||||
callbacks:
|
||||
sorter: @DefaultOptions.sorter
|
||||
filter: @DefaultOptions.filter
|
||||
beforeInsert: @DefaultOptions.beforeInsert
|
||||
beforeSave: (members) ->
|
||||
$.map members, (m) ->
|
||||
return m if not m.username?
|
||||
|
||||
title = m.name
|
||||
title += " (#{m.count})" if m.count
|
||||
|
||||
@@ -76,11 +113,21 @@ GitLab.GfmAutoComplete =
|
||||
at: '#'
|
||||
alias: 'issues'
|
||||
searchKey: 'search'
|
||||
displayTpl: @Issues.template
|
||||
displayTpl: (value) =>
|
||||
if value.title?
|
||||
@Issues.template
|
||||
else
|
||||
@Loading.template
|
||||
data: ['loading']
|
||||
insertTpl: '${atwho-at}${id}'
|
||||
callbacks:
|
||||
sorter: @DefaultOptions.sorter
|
||||
filter: @DefaultOptions.filter
|
||||
beforeInsert: @DefaultOptions.beforeInsert
|
||||
beforeSave: (issues) ->
|
||||
$.map issues, (i) ->
|
||||
return i if not i.title?
|
||||
|
||||
id: i.iid
|
||||
title: sanitize(i.title)
|
||||
search: "#{i.iid} #{i.title}"
|
||||
@@ -89,11 +136,18 @@ GitLab.GfmAutoComplete =
|
||||
at: '%'
|
||||
alias: 'milestones'
|
||||
searchKey: 'search'
|
||||
displayTpl: @Milestones.template
|
||||
displayTpl: (value) =>
|
||||
if value.title?
|
||||
@Milestones.template
|
||||
else
|
||||
@Loading.template
|
||||
insertTpl: '${atwho-at}"${title}"'
|
||||
data: ['loading']
|
||||
callbacks:
|
||||
beforeSave: (milestones) ->
|
||||
$.map milestones, (m) ->
|
||||
return m if not m.title?
|
||||
|
||||
id: m.iid
|
||||
title: sanitize(m.title)
|
||||
search: "#{m.title}"
|
||||
@@ -102,11 +156,21 @@ GitLab.GfmAutoComplete =
|
||||
at: '!'
|
||||
alias: 'mergerequests'
|
||||
searchKey: 'search'
|
||||
displayTpl: @Issues.template
|
||||
displayTpl: (value) =>
|
||||
if value.title?
|
||||
@Issues.template
|
||||
else
|
||||
@Loading.template
|
||||
data: ['loading']
|
||||
insertTpl: '${atwho-at}${id}'
|
||||
callbacks:
|
||||
sorter: @DefaultOptions.sorter
|
||||
filter: @DefaultOptions.filter
|
||||
beforeInsert: @DefaultOptions.beforeInsert
|
||||
beforeSave: (merges) ->
|
||||
$.map merges, (m) ->
|
||||
return m if not m.title?
|
||||
|
||||
id: m.iid
|
||||
title: sanitize(m.title)
|
||||
search: "#{m.iid} #{m.title}"
|
||||
@@ -128,3 +192,7 @@ GitLab.GfmAutoComplete =
|
||||
@input.atwho 'load', 'mergerequests', data.mergerequests
|
||||
# load emojis
|
||||
@input.atwho 'load', ':', data.emojis
|
||||
|
||||
# This trigger at.js again
|
||||
# otherwise we would be stuck with loading until the user types
|
||||
$(':focus').trigger('keyup')
|
||||
|
||||
@@ -354,8 +354,7 @@ class @Notes
|
||||
Called in response to clicking the edit note link
|
||||
|
||||
Replaces the note text with the note edit form
|
||||
Adds a hidden div with the original content of the note to fill the edit note form with
|
||||
if the user cancels
|
||||
Adds a data attribute to the form with the original content of the note for cancellations
|
||||
###
|
||||
showEditForm: (e, scrollTo, myLastNote) ->
|
||||
e.preventDefault()
|
||||
@@ -371,6 +370,8 @@ class @Notes
|
||||
done = ($noteText) ->
|
||||
# Neat little trick to put the cursor at the end
|
||||
noteTextVal = $noteText.val()
|
||||
# Store the original note text in a data attribute to retrieve if a user cancels edit.
|
||||
form.find('form.edit-note').data 'original-note', noteTextVal
|
||||
$noteText.val('').val(noteTextVal);
|
||||
|
||||
new GLForm form
|
||||
@@ -393,14 +394,16 @@ class @Notes
|
||||
###
|
||||
Called in response to clicking the edit note link
|
||||
|
||||
Hides edit form
|
||||
Hides edit form and restores the original note text to the editor textarea.
|
||||
###
|
||||
cancelEdit: (e) ->
|
||||
e.preventDefault()
|
||||
note = $(this).closest(".note")
|
||||
form = note.find(".current-note-edit-form")
|
||||
note.removeClass "is-editting"
|
||||
note.find(".current-note-edit-form")
|
||||
.removeClass("current-note-edit-form")
|
||||
form.removeClass("current-note-edit-form")
|
||||
# Replace markdown textarea text with original note text.
|
||||
form.find(".js-note-text").val(form.find('form.edit-note').data('original-note'))
|
||||
|
||||
###
|
||||
Called in response to deleting a note of any kind.
|
||||
|
||||
@@ -38,6 +38,11 @@
|
||||
.header-logo {
|
||||
height: $header-height;
|
||||
padding: 8px 26px;
|
||||
width: $sidebar_width;
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
overflow: hidden;
|
||||
transition-duration: .3s;
|
||||
|
||||
&:hover {
|
||||
background-color: #eee;
|
||||
@@ -73,7 +78,8 @@
|
||||
|
||||
|
||||
.nav-sidebar {
|
||||
margin: 22px 0;
|
||||
margin-top: 22 + $header-height;
|
||||
margin-bottom: 116px;
|
||||
transition-duration: .3s;
|
||||
list-style: none;
|
||||
overflow: hidden;
|
||||
@@ -166,6 +172,7 @@
|
||||
|
||||
.header-logo {
|
||||
width: 0;
|
||||
padding: 8px 0;
|
||||
|
||||
a {
|
||||
padding-left: ($sidebar_collapsed_width - 36) / 2;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
class Projects::GitHttpController < Projects::ApplicationController
|
||||
attr_reader :user
|
||||
|
||||
# Git clients will not know what authenticity token to send along
|
||||
skip_before_action :verify_authenticity_token
|
||||
skip_before_action :repository
|
||||
before_action :authenticate_user
|
||||
before_action :ensure_project_found!
|
||||
|
||||
@@ -95,7 +95,7 @@ class Projects::WikisController < Projects::ApplicationController
|
||||
ext.analyze(text, author: current_user)
|
||||
|
||||
render json: {
|
||||
body: view_context.markdown(text, pipeline: :wiki, project_wiki: @project_wiki),
|
||||
body: view_context.markdown(text, pipeline: :wiki, project_wiki: @project_wiki, page_slug: params[:id]),
|
||||
references: {
|
||||
users: ext.users.map(&:username)
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ module GitlabMarkdownHelper
|
||||
def render_wiki_content(wiki_page)
|
||||
case wiki_page.format
|
||||
when :markdown
|
||||
markdown(wiki_page.content, pipeline: :wiki, project_wiki: @project_wiki)
|
||||
markdown(wiki_page.content, pipeline: :wiki, project_wiki: @project_wiki, page_slug: wiki_page.slug)
|
||||
when :asciidoc
|
||||
asciidoc(wiki_page.content)
|
||||
else
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
- content_for :scripts_body_top do
|
||||
- project = @target_project || @project
|
||||
- if @project_wiki
|
||||
- markdown_preview_path = namespace_project_wikis_markdown_preview_path(project.namespace, project)
|
||||
- if @project_wiki && @page
|
||||
- markdown_preview_path = namespace_project_wiki_markdown_preview_path(project.namespace, project, params[:id])
|
||||
- else
|
||||
- markdown_preview_path = markdown_preview_namespace_project_path(project.namespace, project)
|
||||
- if current_user
|
||||
|
||||
@@ -20,10 +20,11 @@
|
||||
- access = note.project.team.human_max_access(note.author.id)
|
||||
- if access
|
||||
%span.note-role.hidden-xs= access
|
||||
- if note_editable
|
||||
- if current_user
|
||||
= link_to '#', title: 'Award Emoji', class: 'note-action-button note-emoji-button js-add-award js-note-emoji', data: { position: 'right' } do
|
||||
= icon('spinner spin')
|
||||
= icon('smile-o')
|
||||
- if note_editable
|
||||
= link_to '#', title: 'Edit comment', class: 'note-action-button js-note-edit' do
|
||||
= icon('pencil')
|
||||
= link_to namespace_project_note_path(note.project.namespace, note.project, note), title: 'Remove comment', method: :delete, data: { confirm: 'Are you sure you want to remove this comment?' }, remote: true, class: 'note-action-button hidden-xs js-note-delete danger' do
|
||||
|
||||
+1
-1
@@ -616,7 +616,6 @@ Rails.application.routes.draw do
|
||||
# Order matters to give priority to these matches
|
||||
get '/wikis/git_access', to: 'wikis#git_access'
|
||||
get '/wikis/pages', to: 'wikis#pages', as: 'wiki_pages'
|
||||
post '/wikis/markdown_preview', to:'wikis#markdown_preview'
|
||||
post '/wikis', to: 'wikis#create'
|
||||
|
||||
get '/wikis/*id/history', to: 'wikis#history', as: 'wiki_history', constraints: WIKI_SLUG_ID
|
||||
@@ -625,6 +624,7 @@ Rails.application.routes.draw do
|
||||
get '/wikis/*id', to: 'wikis#show', as: 'wiki', constraints: WIKI_SLUG_ID
|
||||
delete '/wikis/*id', to: 'wikis#destroy', constraints: WIKI_SLUG_ID
|
||||
put '/wikis/*id', to: 'wikis#update', constraints: WIKI_SLUG_ID
|
||||
post '/wikis/*id/markdown_preview', to:'wikis#markdown_preview', constraints: WIKI_SLUG_ID, as: 'wiki_markdown_preview'
|
||||
end
|
||||
|
||||
resource :repository, only: [:show, :create] do
|
||||
|
||||
@@ -97,7 +97,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps
|
||||
file = Gollum::File.new(wiki.wiki)
|
||||
Gollum::Wiki.any_instance.stub(:file).with("image.jpg", "master", true).and_return(file)
|
||||
Gollum::File.any_instance.stub(:mime_type).and_return("image/jpeg")
|
||||
expect(page).to have_link('image', href: "image.jpg")
|
||||
expect(page).to have_link('image', href: "#{wiki.wiki_base_path}/image.jpg")
|
||||
click_on "image"
|
||||
end
|
||||
|
||||
@@ -113,7 +113,7 @@ class Spinach::Features::ProjectWiki < Spinach::FeatureSteps
|
||||
end
|
||||
|
||||
step 'I click on image link' do
|
||||
expect(page).to have_link('image', href: "image.jpg")
|
||||
expect(page).to have_link('image', href: "#{wiki.wiki_base_path}/image.jpg")
|
||||
click_on "image"
|
||||
end
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@ require 'uri'
|
||||
|
||||
module Banzai
|
||||
module Filter
|
||||
# HTML filter that "fixes" relative links to files in a repository.
|
||||
# HTML filter that "fixes" links to pages/files in a wiki.
|
||||
# Rewrite rules are documented in the `WikiPipeline` spec.
|
||||
#
|
||||
# Context options:
|
||||
# :project_wiki
|
||||
@@ -25,36 +26,15 @@ module Banzai
|
||||
end
|
||||
|
||||
def process_link_attr(html_attr)
|
||||
return if html_attr.blank? || file_reference?(html_attr) || hierarchical_link?(html_attr)
|
||||
return if html_attr.blank?
|
||||
|
||||
uri = URI(html_attr.value)
|
||||
if uri.relative? && uri.path.present?
|
||||
html_attr.value = rebuild_wiki_uri(uri).to_s
|
||||
end
|
||||
html_attr.value = apply_rewrite_rules(html_attr.value)
|
||||
rescue URI::Error
|
||||
# noop
|
||||
end
|
||||
|
||||
def rebuild_wiki_uri(uri)
|
||||
uri.path = ::File.join(project_wiki_base_path, uri.path)
|
||||
uri
|
||||
end
|
||||
|
||||
def project_wiki
|
||||
context[:project_wiki]
|
||||
end
|
||||
|
||||
def file_reference?(html_attr)
|
||||
!File.extname(html_attr.value).blank?
|
||||
end
|
||||
|
||||
# Of the form `./link`, `../link`, or similar
|
||||
def hierarchical_link?(html_attr)
|
||||
html_attr.value[0] == '.'
|
||||
end
|
||||
|
||||
def project_wiki_base_path
|
||||
project_wiki && project_wiki.wiki_base_path
|
||||
def apply_rewrite_rules(link_string)
|
||||
Rewriter.new(link_string, wiki: context[:project_wiki], slug: context[:page_slug]).apply_rules
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
module Banzai
|
||||
module Filter
|
||||
class WikiLinkFilter < HTML::Pipeline::Filter
|
||||
class Rewriter
|
||||
def initialize(link_string, wiki:, slug:)
|
||||
@uri = Addressable::URI.parse(link_string)
|
||||
@wiki_base_path = wiki && wiki.wiki_base_path
|
||||
@slug = slug
|
||||
end
|
||||
|
||||
def apply_rules
|
||||
apply_file_link_rules!
|
||||
apply_hierarchical_link_rules!
|
||||
apply_relative_link_rules!
|
||||
@uri.to_s
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Of the form 'file.md'
|
||||
def apply_file_link_rules!
|
||||
@uri = Addressable::URI.join(@slug, @uri) if @uri.extname.present?
|
||||
end
|
||||
|
||||
# Of the form `./link`, `../link`, or similar
|
||||
def apply_hierarchical_link_rules!
|
||||
@uri = Addressable::URI.join(@slug, @uri) if @uri.to_s[0] == '.'
|
||||
end
|
||||
|
||||
# Any link _not_ of the form `http://example.com/`
|
||||
def apply_relative_link_rules!
|
||||
if @uri.relative? && @uri.path.present?
|
||||
link = ::File.join(@wiki_base_path, @uri.path)
|
||||
@uri = Addressable::URI.parse(link)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -69,13 +69,20 @@ module Gitlab
|
||||
return unless ldap_person
|
||||
|
||||
# If a corresponding person exists with same uid in a LDAP server,
|
||||
# set up a Gitlab user with dual LDAP and Omniauth identities.
|
||||
if user = Gitlab::LDAP::User.find_by_uid_and_provider(ldap_person.dn, ldap_person.provider)
|
||||
# Case when a LDAP user already exists in Gitlab. Add the Omniauth identity to existing account.
|
||||
# check if the user already has a GitLab account.
|
||||
user = Gitlab::LDAP::User.find_by_uid_and_provider(ldap_person.dn, ldap_person.provider)
|
||||
if user
|
||||
# Case when a LDAP user already exists in Gitlab. Add the OAuth identity to existing account.
|
||||
log.info "LDAP account found for user #{user.username}. Building new #{auth_hash.provider} identity."
|
||||
user.identities.build(extern_uid: auth_hash.uid, provider: auth_hash.provider)
|
||||
else
|
||||
# No account in Gitlab yet: create it and add the LDAP identity
|
||||
user = build_new_user
|
||||
log.info "No existing LDAP account was found in GitLab. Checking for #{auth_hash.provider} account."
|
||||
user = find_by_uid_and_provider
|
||||
if user.nil?
|
||||
log.info "No user found using #{auth_hash.provider} provider. Creating a new one."
|
||||
user = build_new_user
|
||||
end
|
||||
log.info "Correct account has been found. Adding LDAP identity to user: #{user.username}."
|
||||
user.identities.new(provider: ldap_person.provider, extern_uid: ldap_person.dn)
|
||||
end
|
||||
|
||||
|
||||
@@ -12,12 +12,12 @@ module Gitlab
|
||||
end
|
||||
|
||||
def gl_user
|
||||
@user ||= find_by_uid_and_provider
|
||||
|
||||
if auto_link_ldap_user?
|
||||
@user ||= find_or_create_ldap_user
|
||||
end
|
||||
|
||||
@user ||= find_by_uid_and_provider
|
||||
|
||||
if auto_link_saml_user?
|
||||
@user ||= find_by_email
|
||||
end
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
require 'spec_helper'
|
||||
require_relative 'import_spec_helper'
|
||||
|
||||
describe Import::BitbucketController do
|
||||
include ImportSpecHelper
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
require 'spec_helper'
|
||||
require_relative 'import_spec_helper'
|
||||
|
||||
describe Import::FogbugzController do
|
||||
include ImportSpecHelper
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
require 'spec_helper'
|
||||
require_relative 'import_spec_helper'
|
||||
|
||||
describe Import::GithubController do
|
||||
include ImportSpecHelper
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
require 'spec_helper'
|
||||
require_relative 'import_spec_helper'
|
||||
|
||||
describe Import::GitlabController do
|
||||
include ImportSpecHelper
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
require 'spec_helper'
|
||||
require_relative 'import_spec_helper'
|
||||
|
||||
describe Import::GitoriousController do
|
||||
include ImportSpecHelper
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
require 'spec_helper'
|
||||
require_relative 'import_spec_helper'
|
||||
|
||||
describe Import::GoogleCodeController do
|
||||
include ImportSpecHelper
|
||||
|
||||
@@ -2,7 +2,7 @@ require 'ostruct'
|
||||
|
||||
FactoryGirl.define do
|
||||
factory :wiki_page do
|
||||
page = OpenStruct.new(url_path: 'some-name')
|
||||
page { OpenStruct.new(url_path: 'some-name') }
|
||||
association :wiki, factory: :project_wiki, strategy: :build
|
||||
initialize_with { new(wiki, page, true) }
|
||||
end
|
||||
|
||||
@@ -241,13 +241,14 @@ describe 'GitLab Markdown', feature: true do
|
||||
context 'wiki pipeline' do
|
||||
before do
|
||||
@project_wiki = @feat.project_wiki
|
||||
@project_wiki_page = @feat.project_wiki_page
|
||||
|
||||
file = Gollum::File.new(@project_wiki.wiki)
|
||||
expect(file).to receive(:path).and_return('images/example.jpg')
|
||||
expect(@project_wiki).to receive(:find_file).with('images/example.jpg').and_return(file)
|
||||
allow(@project_wiki).to receive(:wiki_base_path) { '/namespace1/gitlabhq/wikis' }
|
||||
|
||||
@html = markdown(@feat.raw_markdown, { pipeline: :wiki, project_wiki: @project_wiki })
|
||||
@html = markdown(@feat.raw_markdown, { pipeline: :wiki, project_wiki: @project_wiki, page_slug: @project_wiki_page.slug })
|
||||
end
|
||||
|
||||
it_behaves_like 'all pipelines'
|
||||
|
||||
@@ -121,13 +121,14 @@ describe GitlabMarkdownHelper do
|
||||
before do
|
||||
@wiki = double('WikiPage')
|
||||
allow(@wiki).to receive(:content).and_return('wiki content')
|
||||
allow(@wiki).to receive(:slug).and_return('nested/page')
|
||||
helper.instance_variable_set(:@project_wiki, @wiki)
|
||||
end
|
||||
|
||||
it "should use Wiki pipeline for markdown files" do
|
||||
allow(@wiki).to receive(:format).and_return(:markdown)
|
||||
|
||||
expect(helper).to receive(:markdown).with('wiki content', pipeline: :wiki, project_wiki: @wiki)
|
||||
expect(helper).to receive(:markdown).with('wiki content', pipeline: :wiki, project_wiki: @wiki, page_slug: "nested/page")
|
||||
|
||||
helper.render_wiki_content(@wiki)
|
||||
end
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Banzai::Filter::WikiLinkFilter, lib: true do
|
||||
include FilterSpecHelper
|
||||
|
||||
let(:namespace) { build_stubbed(:namespace, name: "wiki_link_ns") }
|
||||
let(:project) { build_stubbed(:empty_project, :public, name: "wiki_link_project", namespace: namespace) }
|
||||
let(:user) { double }
|
||||
let(:project_wiki) { ProjectWiki.new(project, user) }
|
||||
|
||||
describe "links within the wiki (relative)" do
|
||||
describe "hierarchical links to the current directory" do
|
||||
it "doesn't rewrite non-file links" do
|
||||
link = "<a href='./page'>Link to Page</a>"
|
||||
filtered_link = filter(link, project_wiki: project_wiki).children[0]
|
||||
|
||||
expect(filtered_link.attribute('href').value).to eq('./page')
|
||||
end
|
||||
|
||||
it "doesn't rewrite file links" do
|
||||
link = "<a href='./page.md'>Link to Page</a>"
|
||||
filtered_link = filter(link, project_wiki: project_wiki).children[0]
|
||||
|
||||
expect(filtered_link.attribute('href').value).to eq('./page.md')
|
||||
end
|
||||
end
|
||||
|
||||
describe "hierarchical links to the parent directory" do
|
||||
it "doesn't rewrite non-file links" do
|
||||
link = "<a href='../page'>Link to Page</a>"
|
||||
filtered_link = filter(link, project_wiki: project_wiki).children[0]
|
||||
|
||||
expect(filtered_link.attribute('href').value).to eq('../page')
|
||||
end
|
||||
|
||||
it "doesn't rewrite file links" do
|
||||
link = "<a href='../page.md'>Link to Page</a>"
|
||||
filtered_link = filter(link, project_wiki: project_wiki).children[0]
|
||||
|
||||
expect(filtered_link.attribute('href').value).to eq('../page.md')
|
||||
end
|
||||
end
|
||||
|
||||
describe "hierarchical links to a sub-directory" do
|
||||
it "doesn't rewrite non-file links" do
|
||||
link = "<a href='./subdirectory/page'>Link to Page</a>"
|
||||
filtered_link = filter(link, project_wiki: project_wiki).children[0]
|
||||
|
||||
expect(filtered_link.attribute('href').value).to eq('./subdirectory/page')
|
||||
end
|
||||
|
||||
it "doesn't rewrite file links" do
|
||||
link = "<a href='./subdirectory/page.md'>Link to Page</a>"
|
||||
filtered_link = filter(link, project_wiki: project_wiki).children[0]
|
||||
|
||||
expect(filtered_link.attribute('href').value).to eq('./subdirectory/page.md')
|
||||
end
|
||||
end
|
||||
|
||||
describe "non-hierarchical links" do
|
||||
it 'rewrites non-file links to be at the scope of the wiki root' do
|
||||
link = "<a href='page'>Link to Page</a>"
|
||||
filtered_link = filter(link, project_wiki: project_wiki).children[0]
|
||||
|
||||
expect(filtered_link.attribute('href').value).to match('/wiki_link_ns/wiki_link_project/wikis/page')
|
||||
end
|
||||
|
||||
it "doesn't rewrite file links" do
|
||||
link = "<a href='page.md'>Link to Page</a>"
|
||||
filtered_link = filter(link, project_wiki: project_wiki).children[0]
|
||||
|
||||
expect(filtered_link.attribute('href').value).to eq('page.md')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "links outside the wiki (absolute)" do
|
||||
it "doesn't rewrite links" do
|
||||
link = "<a href='http://example.com/page'>Link to Page</a>"
|
||||
filtered_link = filter(link, project_wiki: project_wiki).children[0]
|
||||
|
||||
expect(filtered_link.attribute('href').value).to eq('http://example.com/page')
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -50,4 +50,112 @@ describe Banzai::Pipeline::WikiPipeline do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Links" do
|
||||
let(:namespace) { build_stubbed(:namespace, name: "wiki_link_ns") }
|
||||
let(:project) { build_stubbed(:empty_project, :public, name: "wiki_link_project", namespace: namespace) }
|
||||
let(:project_wiki) { ProjectWiki.new(project, double(:user)) }
|
||||
let(:page) { build(:wiki_page, wiki: project_wiki, page: OpenStruct.new(url_path: 'nested/twice/start-page')) }
|
||||
|
||||
{ "when GitLab is hosted at a root URL" => '/',
|
||||
"when GitLab is hosted at a relative URL" => '/nested/relative/gitlab' }.each do |test_name, relative_url_root|
|
||||
|
||||
context test_name do
|
||||
before do
|
||||
allow(Gitlab.config.gitlab).to receive(:relative_url_root).and_return(relative_url_root)
|
||||
end
|
||||
|
||||
describe "linking to pages within the wiki" do
|
||||
context "when creating hierarchical links to the current directory" do
|
||||
it "rewrites non-file links to be at the scope of the current directory" do
|
||||
markdown = "[Page](./page)"
|
||||
output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
|
||||
|
||||
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/page\"")
|
||||
end
|
||||
|
||||
it "rewrites file links to be at the scope of the current directory" do
|
||||
markdown = "[Link to Page](./page.md)"
|
||||
output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
|
||||
|
||||
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/page.md\"")
|
||||
end
|
||||
end
|
||||
|
||||
context "when creating hierarchical links to the parent directory" do
|
||||
it "rewrites non-file links to be at the scope of the parent directory" do
|
||||
markdown = "[Link to Page](../page)"
|
||||
output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
|
||||
|
||||
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/page\"")
|
||||
end
|
||||
|
||||
it "rewrites file links to be at the scope of the parent directory" do
|
||||
markdown = "[Link to Page](../page.md)"
|
||||
output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
|
||||
|
||||
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/page.md\"")
|
||||
end
|
||||
end
|
||||
|
||||
context "when creating hierarchical links to a sub-directory" do
|
||||
it "rewrites non-file links to be at the scope of the sub-directory" do
|
||||
markdown = "[Link to Page](./subdirectory/page)"
|
||||
output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
|
||||
|
||||
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/subdirectory/page\"")
|
||||
end
|
||||
|
||||
it "rewrites file links to be at the scope of the sub-directory" do
|
||||
markdown = "[Link to Page](./subdirectory/page.md)"
|
||||
output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
|
||||
|
||||
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/subdirectory/page.md\"")
|
||||
end
|
||||
end
|
||||
|
||||
describe "when creating non-hierarchical links" do
|
||||
it 'rewrites non-file links to be at the scope of the wiki root' do
|
||||
markdown = "[Link to Page](page)"
|
||||
output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
|
||||
|
||||
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/page\"")
|
||||
end
|
||||
|
||||
it "rewrites file links to be at the scope of the current directory" do
|
||||
markdown = "[Link to Page](page.md)"
|
||||
output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
|
||||
|
||||
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/page.md\"")
|
||||
end
|
||||
end
|
||||
|
||||
describe "when creating root links" do
|
||||
it 'rewrites non-file links to be at the scope of the wiki root' do
|
||||
markdown = "[Link to Page](/page)"
|
||||
output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
|
||||
|
||||
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/page\"")
|
||||
end
|
||||
|
||||
it 'rewrites file links to be at the scope of the wiki root' do
|
||||
markdown = "[Link to Page](/page.md)"
|
||||
output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
|
||||
|
||||
expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/page.md\"")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "linking to pages outside the wiki (absolute)" do
|
||||
it "doesn't rewrite links" do
|
||||
markdown = "[Link to Page](http://example.com/page)"
|
||||
output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug)
|
||||
|
||||
expect(output).to include('href="http://example.com/page"')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::BitbucketImport::Client, lib: true do
|
||||
include ImportSpecHelper
|
||||
|
||||
let(:token) { '123456' }
|
||||
let(:secret) { 'secret' }
|
||||
let(:client) { Gitlab::BitbucketImport::Client.new(token, secret) }
|
||||
|
||||
before do
|
||||
Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "bitbucket")
|
||||
stub_omniauth_provider('bitbucket')
|
||||
end
|
||||
|
||||
it 'all OAuth client options are symbols' do
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::BitbucketImport::Importer, lib: true do
|
||||
include ImportSpecHelper
|
||||
|
||||
before do
|
||||
Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "bitbucket")
|
||||
stub_omniauth_provider('bitbucket')
|
||||
end
|
||||
|
||||
let(:statuses) do
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::GitlabImport::Client, lib: true do
|
||||
include ImportSpecHelper
|
||||
|
||||
let(:token) { '123456' }
|
||||
let(:client) { Gitlab::GitlabImport::Client.new(token) }
|
||||
|
||||
before do
|
||||
Gitlab.config.omniauth.providers << OpenStruct.new(app_id: "asd123", app_secret: "asd123", name: "gitlab")
|
||||
stub_omniauth_provider('gitlab')
|
||||
end
|
||||
|
||||
it 'all OAuth2 client options are symbols' do
|
||||
|
||||
@@ -145,6 +145,7 @@ describe Gitlab::Saml::User, lib: true do
|
||||
allow(ldap_user).to receive(:email) { %w(john@mail.com john2@example.com) }
|
||||
allow(ldap_user).to receive(:dn) { 'uid=user1,ou=People,dc=example' }
|
||||
allow(Gitlab::LDAP::Person).to receive(:find_by_uid).and_return(ldap_user)
|
||||
allow(Gitlab::LDAP::Person).to receive(:find_by_dn).and_return(ldap_user)
|
||||
end
|
||||
|
||||
context 'and no account for the LDAP user' do
|
||||
@@ -177,6 +178,23 @@ describe Gitlab::Saml::User, lib: true do
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
context 'user has SAML user, and wants to add their LDAP identity' do
|
||||
it 'adds the LDAP identity to the existing SAML user' do
|
||||
create(:omniauth_user, email: 'john@mail.com', extern_uid: 'uid=user1,ou=People,dc=example', provider: 'saml', username: 'john')
|
||||
local_hash = OmniAuth::AuthHash.new(uid: 'uid=user1,ou=People,dc=example', provider: provider, info: info_hash)
|
||||
local_saml_user = described_class.new(local_hash)
|
||||
local_saml_user.save
|
||||
local_gl_user = local_saml_user.gl_user
|
||||
|
||||
expect(local_gl_user).to be_valid
|
||||
expect(local_gl_user.identities.length).to eql 2
|
||||
identities_as_hash = local_gl_user.identities.map { |id| { provider: id.provider, extern_uid: id.extern_uid } }
|
||||
expect(identities_as_hash).to match_array([ { provider: 'ldapmain', extern_uid: 'uid=user1,ou=People,dc=example' },
|
||||
{ provider: 'saml', extern_uid: 'uid=user1,ou=People,dc=example' }
|
||||
])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -124,7 +124,7 @@ describe Projects::ImportService, services: true do
|
||||
}
|
||||
)
|
||||
|
||||
Gitlab.config.omniauth.providers << provider
|
||||
allow(Gitlab.config.omniauth).to receive(:providers).and_return([provider])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -28,6 +28,6 @@ module ImportSpecHelper
|
||||
app_id: 'asd123',
|
||||
app_secret: 'asd123'
|
||||
)
|
||||
Gitlab.config.omniauth.providers << provider
|
||||
allow(Gitlab.config.omniauth).to receive(:providers).and_return([provider])
|
||||
end
|
||||
end
|
||||
@@ -32,6 +32,10 @@ class MarkdownFeature
|
||||
@project_wiki ||= ProjectWiki.new(project, user)
|
||||
end
|
||||
|
||||
def project_wiki_page
|
||||
@project_wiki_page ||= build(:wiki_page, wiki: project_wiki)
|
||||
end
|
||||
|
||||
def issue
|
||||
@issue ||= create(:issue, project: project)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user