Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
a62bd121
Commit
a62bd121
authored
Oct 18, 2015
by
Douwe Maan
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into zj/gitlab-ce-index-milestone-title-label
parents
0108cdf4
38785046
Changes
74
Hide whitespace changes
Inline
Side-by-side
Showing
74 changed files
with
1058 additions
and
559 deletions
+1058
-559
CHANGELOG
CHANGELOG
+7
-0
GITLAB_GIT_HTTP_SERVER_VERSION
GITLAB_GIT_HTTP_SERVER_VERSION
+1
-0
app/assets/stylesheets/framework/blocks.scss
app/assets/stylesheets/framework/blocks.scss
+5
-0
app/assets/stylesheets/framework/selects.scss
app/assets/stylesheets/framework/selects.scss
+2
-2
app/assets/stylesheets/framework/timeline.scss
app/assets/stylesheets/framework/timeline.scss
+4
-0
app/assets/stylesheets/framework/typography.scss
app/assets/stylesheets/framework/typography.scss
+35
-43
app/assets/stylesheets/pages/help.scss
app/assets/stylesheets/pages/help.scss
+4
-0
app/assets/stylesheets/pages/notes.scss
app/assets/stylesheets/pages/notes.scss
+4
-1
app/assets/stylesheets/pages/projects.scss
app/assets/stylesheets/pages/projects.scss
+35
-0
app/controllers/ci/projects_controller.rb
app/controllers/ci/projects_controller.rb
+8
-3
app/helpers/gitlab_markdown_helper.rb
app/helpers/gitlab_markdown_helper.rb
+16
-5
app/helpers/labels_helper.rb
app/helpers/labels_helper.rb
+13
-5
app/helpers/projects_helper.rb
app/helpers/projects_helper.rb
+1
-1
app/models/commit.rb
app/models/commit.rb
+2
-2
app/models/concerns/issuable.rb
app/models/concerns/issuable.rb
+2
-3
app/models/concerns/mentionable.rb
app/models/concerns/mentionable.rb
+13
-7
app/models/concerns/participable.rb
app/models/concerns/participable.rb
+19
-13
app/models/group_label.rb
app/models/group_label.rb
+9
-0
app/models/group_milestone.rb
app/models/group_milestone.rb
+2
-10
app/models/note.rb
app/models/note.rb
+2
-2
app/models/user.rb
app/models/user.rb
+9
-6
app/services/labels/group_service.rb
app/services/labels/group_service.rb
+26
-0
app/views/ci/projects/index.html.haml
app/views/ci/projects/index.html.haml
+20
-0
app/views/events/_event_issue.atom.haml
app/views/events/_event_issue.atom.haml
+1
-2
app/views/events/_event_merge_request.atom.haml
app/views/events/_event_merge_request.atom.haml
+1
-2
app/views/events/_event_note.atom.haml
app/views/events/_event_note.atom.haml
+1
-1
app/views/events/_event_push.atom.haml
app/views/events/_event_push.atom.haml
+1
-1
app/views/notify/_note_message.html.haml
app/views/notify/_note_message.html.haml
+1
-1
app/views/notify/new_issue_email.html.haml
app/views/notify/new_issue_email.html.haml
+1
-1
app/views/notify/new_merge_request_email.html.haml
app/views/notify/new_merge_request_email.html.haml
+1
-1
app/views/projects/_last_commit.html.haml
app/views/projects/_last_commit.html.haml
+12
-0
app/views/projects/imports/new.html.haml
app/views/projects/imports/new.html.haml
+1
-1
app/views/projects/show.html.haml
app/views/projects/show.html.haml
+4
-0
app/views/shared/issuable/_filter.html.haml
app/views/shared/issuable/_filter.html.haml
+4
-5
db/migrate/20151016131433_add_ci_projects_gl_project_id_index.rb
...ate/20151016131433_add_ci_projects_gl_project_id_index.rb
+5
-0
db/migrate/20151016195451_add_ci_builds_and_projects_indexes.rb
...rate/20151016195451_add_ci_builds_and_projects_indexes.rb
+9
-0
db/migrate/20151016195706_add_notes_line_code_index.rb
db/migrate/20151016195706_add_notes_line_code_index.rb
+5
-0
db/schema.rb
db/schema.rb
+8
-1
doc/install/installation.md
doc/install/installation.md
+1
-0
doc/update/7.14-to-8.0.md
doc/update/7.14-to-8.0.md
+1
-0
features/project/project.feature
features/project/project.feature
+6
-0
features/steps/shared/project.rb
features/steps/shared/project.rb
+7
-0
lib/gitlab/markdown.rb
lib/gitlab/markdown.rb
+77
-41
lib/gitlab/markdown/commit_range_reference_filter.rb
lib/gitlab/markdown/commit_range_reference_filter.rb
+13
-3
lib/gitlab/markdown/commit_reference_filter.rb
lib/gitlab/markdown/commit_reference_filter.rb
+17
-7
lib/gitlab/markdown/cross_project_reference.rb
lib/gitlab/markdown/cross_project_reference.rb
+2
-9
lib/gitlab/markdown/external_issue_reference_filter.rb
lib/gitlab/markdown/external_issue_reference_filter.rb
+2
-1
lib/gitlab/markdown/issue_reference_filter.rb
lib/gitlab/markdown/issue_reference_filter.rb
+5
-3
lib/gitlab/markdown/label_reference_filter.rb
lib/gitlab/markdown/label_reference_filter.rb
+5
-3
lib/gitlab/markdown/merge_request_reference_filter.rb
lib/gitlab/markdown/merge_request_reference_filter.rb
+5
-3
lib/gitlab/markdown/redactor_filter.rb
lib/gitlab/markdown/redactor_filter.rb
+40
-0
lib/gitlab/markdown/reference_filter.rb
lib/gitlab/markdown/reference_filter.rb
+41
-24
lib/gitlab/markdown/reference_gatherer_filter.rb
lib/gitlab/markdown/reference_gatherer_filter.rb
+63
-0
lib/gitlab/markdown/snippet_reference_filter.rb
lib/gitlab/markdown/snippet_reference_filter.rb
+5
-3
lib/gitlab/markdown/user_reference_filter.rb
lib/gitlab/markdown/user_reference_filter.rb
+29
-16
lib/gitlab/reference_extractor.rb
lib/gitlab/reference_extractor.rb
+19
-7
spec/features/markdown_spec.rb
spec/features/markdown_spec.rb
+1
-1
spec/helpers/gitlab_markdown_helper_spec.rb
spec/helpers/gitlab_markdown_helper_spec.rb
+15
-12
spec/helpers/labels_helper_spec.rb
spec/helpers/labels_helper_spec.rb
+0
-5
spec/lib/gitlab/closing_issue_extractor_spec.rb
spec/lib/gitlab/closing_issue_extractor_spec.rb
+5
-5
spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb
...lib/gitlab/markdown/commit_range_reference_filter_spec.rb
+32
-38
spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
+30
-36
spec/lib/gitlab/markdown/cross_project_reference_spec.rb
spec/lib/gitlab/markdown/cross_project_reference_spec.rb
+8
-28
spec/lib/gitlab/markdown/issue_reference_filter_spec.rb
spec/lib/gitlab/markdown/issue_reference_filter_spec.rb
+35
-41
spec/lib/gitlab/markdown/label_reference_filter_spec.rb
spec/lib/gitlab/markdown/label_reference_filter_spec.rb
+13
-5
spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb
...ib/gitlab/markdown/merge_request_reference_filter_spec.rb
+30
-36
spec/lib/gitlab/markdown/redactor_filter_spec.rb
spec/lib/gitlab/markdown/redactor_filter_spec.rb
+91
-0
spec/lib/gitlab/markdown/reference_gatherer_filter_spec.rb
spec/lib/gitlab/markdown/reference_gatherer_filter_spec.rb
+89
-0
spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
+29
-35
spec/lib/gitlab/markdown/user_reference_filter_spec.rb
spec/lib/gitlab/markdown/user_reference_filter_spec.rb
+18
-37
spec/lib/gitlab/reference_extractor_spec.rb
spec/lib/gitlab/reference_extractor_spec.rb
+7
-7
spec/support/filter_spec_helper.rb
spec/support/filter_spec_helper.rb
+8
-15
spec/support/markdown_feature.rb
spec/support/markdown_feature.rb
+13
-19
spec/support/mentionable_shared_examples.rb
spec/support/mentionable_shared_examples.rb
+2
-0
No files found.
CHANGELOG
View file @
a62bd121
Please view this file on the master branch, on stable branches it's out of date.
v 8.2.0 (unreleased)
- Show last project commit to default branch on project home page
- Highlight comment based on anchor in URL
v 8.1.0 (unreleased)
- Fix nonatomic database update potentially causing project star counts to go negative (Stan Hu)
- Fix error preventing displaying of commit data for a directory with a leading dot (Stan Hu)
- Speed up load times of issue detail pages by roughly 1.5x
- Add a system note and update relevant merge requests when a branch is deleted or re-added (Stan Hu)
...
...
@@ -55,6 +60,7 @@ v 8.1.0 (unreleased)
- Fix position of hamburger in header for smaller screens (Han Loong Liauw)
- Fix bug where Emojis in Markdown would truncate remaining text (Sakata Sinji)
- Persist filters when sorting on admin user page (Jerry Lukins)
- Allow dashboard and group issues/MRs to be filtered by label
- Add spellcheck=false to certain input fields
- Invalidate stored service password if the endpoint URL is changed
- Project names are not fully shown if group name is too big, even on group page view
...
...
@@ -64,6 +70,7 @@ v 8.1.0 (unreleased)
- Hide passwords from services API (Alex Lossent)
- Fix: Images cannot show when projects' path was changed
- Optimize query when filtering on issuables (Zeger-Jan van de Weg)
- Fix padding of outdated discussion item.
v 8.0.4
- Fix Message-ID header to be RFC 2111-compliant to prevent e-mails being dropped (Stan Hu)
...
...
GITLAB_GIT_HTTP_SERVER_VERSION
0 → 100644
View file @
a62bd121
0.3.0
app/assets/stylesheets/framework/blocks.scss
View file @
a62bd121
...
...
@@ -18,6 +18,7 @@
line-height
:
36px
;
}
.content-block
,
.gray-content-block
{
margin
:
-
$gl-padding
;
background-color
:
$background-color
;
...
...
@@ -27,6 +28,10 @@
border-bottom
:
1px
solid
$border-color
;
color
:
$gl-gray
;
&
.white
{
background-color
:
white
;
}
&
.top-block
{
border-top
:
none
;
}
...
...
app/assets/stylesheets/framework/selects.scss
View file @
a62bd121
...
...
@@ -32,7 +32,7 @@
}
.select2-results
.select2-result-label
{
padding
:
16
px
;
padding
:
9
px
;
}
.select2-drop
{
...
...
@@ -143,4 +143,4 @@
.ajax-users-dropdown
{
min-width
:
250px
!
important
;
}
}
\ No newline at end of file
app/assets/stylesheets/framework/timeline.scss
View file @
a62bd121
...
...
@@ -13,6 +13,10 @@
border-bottom
:
1px
solid
#ECEEF1
;
border-right
:
1px
solid
#ECEEF1
;
&
:target
{
background
:
$hover
;
}
&
:last-child
{
border-bottom
:
none
;
}
...
...
app/assets/stylesheets/framework/typography.scss
View file @
a62bd121
@mixin
md-typography
{
color
:
$md-text-color
;
word-wrap
:
break-word
;
a
{
color
:
$md-link-color
;
...
...
@@ -73,6 +74,8 @@
}
blockquote
{
color
:
#7f8fa4
;
font-size
:
inherit
;
padding
:
8px
21px
;
margin
:
12px
0
12px
;
border-left
:
3px
solid
#e7e9ed
;
...
...
@@ -80,7 +83,7 @@
blockquote
p
{
color
:
#7f8fa4
!
important
;
font-size
:
15px
;
font-size
:
inherit
;
line-height
:
1
.5
;
}
...
...
@@ -112,9 +115,9 @@
font-weight
:
inherit
;
}
ul
{
color
:
#5c5d5e
;
ul
,
ol
{
padding
:
0
;
margin
:
6px
0
6px
18px
!
important
;
}
li
{
...
...
@@ -136,6 +139,33 @@
text-decoration
:
none
;
}
}
/* Link to current header. */
h1
,
h2
,
h3
,
h4
,
h5
,
h6
{
position
:
relative
;
a
.anchor
{
// Setting `display: none` would prevent the anchor being scrolled to, so
// instead we set the height to 0 and it gets updated on hover.
height
:
0
;
}
&
:hover
>
a
.anchor
{
$size
:
16px
;
position
:
absolute
;
right
:
100%
;
top
:
50%
;
margin-top
:
-
$size
/
2
;
margin-right
:
0px
;
padding-right
:
20px
;
display
:
inline-block
;
width
:
$size
;
height
:
$size
;
background-image
:
image-url
(
"icon-link.png"
);
background-size
:
contain
;
background-repeat
:
no-repeat
;
}
}
}
...
...
@@ -202,49 +232,11 @@ a > code {
}
/**
*
Wiki
typography
*
Apply Markdown
typography
*
*/
.wiki
{
@include
md-typography
;
word-wrap
:
break-word
;
padding
:
7px
;
/* Link to current header. */
h1
,
h2
,
h3
,
h4
,
h5
,
h6
{
position
:
relative
;
a
.anchor
{
// Setting `display: none` would prevent the anchor being scrolled to, so
// instead we set the height to 0 and it gets updated on hover.
height
:
0
;
}
&
:hover
>
a
.anchor
{
$size
:
16px
;
position
:
absolute
;
right
:
100%
;
top
:
50%
;
margin-top
:
-
$size
/
2
;
margin-right
:
0px
;
padding-right
:
20px
;
display
:
inline-block
;
width
:
$size
;
height
:
$size
;
background-image
:
image-url
(
"icon-link.png"
);
background-size
:
contain
;
background-repeat
:
no-repeat
;
}
}
ul
,
ol
{
padding
:
0
;
margin
:
6px
0
6px
18px
!
important
;
}
ol
{
color
:
#5c5d5e
;
}
}
.md-area
{
...
...
app/assets/stylesheets/pages/help.scss
View file @
a62bd121
...
...
@@ -68,3 +68,7 @@ body.modal-open {
.modal
.modal-dialog
{
width
:
860px
;
}
.documentation
{
padding
:
7px
;
}
app/assets/stylesheets/pages/notes.scss
View file @
a62bd121
...
...
@@ -30,7 +30,6 @@ ul.notes {
.discussion-header
,
.note-header
{
@extend
.cgray
;
padding-bottom
:
15px
;
a
:hover
{
text-decoration
:
none
;
...
...
@@ -75,6 +74,10 @@ ul.notes {
}
}
.discussion-body
{
padding-top
:
15px
;
}
.discussion
{
overflow
:
hidden
;
display
:
block
;
...
...
app/assets/stylesheets/pages/projects.scss
View file @
a62bd121
...
...
@@ -511,3 +511,38 @@ pre.light-well {
margin-top
:
-1px
;
}
}
.project-last-commit
{
margin
:
0
7px
;
.ci-status
{
margin-right
:
16px
;
}
.commit-row-message
{
color
:
$gl-gray
;
}
.commit_short_id
{
margin-right
:
5px
;
color
:
$gl-link-color
;
font-weight
:
600
;
}
.commit-author-link
{
margin-left
:
7px
;
text-decoration
:
none
;
.avatar
{
float
:
none
;
margin-right
:
4px
;
}
.commit-author-name
{
font-weight
:
600
;
}
}
}
.project-show-readme
.readme-holder
{
padding
:
7px
;
}
app/controllers/ci/projects_controller.rb
View file @
a62bd121
module
Ci
class
ProjectsController
<
Ci
::
ApplicationController
before_action
:project
before_action
:authenticate_user!
,
except:
[
:build
,
:badge
]
before_action
:authorize_access_project!
,
except:
[
:badge
]
before_action
:project
,
except:
[
:index
]
before_action
:authenticate_user!
,
except:
[
:
index
,
:
build
,
:badge
]
before_action
:authorize_access_project!
,
except:
[
:
index
,
:
badge
]
before_action
:authorize_manage_project!
,
only:
[
:toggle_shared_runners
,
:dumped_yaml
]
before_action
:no_cache
,
only:
[
:badge
]
protect_from_forgery
def
show
# Temporary compatibility with CI badges pointing to CI project page
redirect_to
namespace_project_path
(
project
.
gl_project
.
namespace
,
project
.
gl_project
)
end
# Project status badge
# Image with build status for sha or ref
def
badge
...
...
app/helpers/gitlab_markdown_helper.rb
View file @
a62bd121
...
...
@@ -19,7 +19,8 @@ module GitlabMarkdownHelper
escape_once
(
body
)
end
gfm_body
=
Gitlab
::
Markdown
.
gfm
(
escaped_body
,
project:
@project
,
current_user:
current_user
)
user
=
current_user
if
defined?
(
current_user
)
gfm_body
=
Gitlab
::
Markdown
.
gfm
(
escaped_body
,
project:
@project
,
current_user:
user
)
fragment
=
Nokogiri
::
HTML
::
DocumentFragment
.
parse
(
gfm_body
)
if
fragment
.
children
.
size
==
1
&&
fragment
.
children
[
0
].
name
==
'a'
...
...
@@ -45,29 +46,39 @@ module GitlabMarkdownHelper
end
def
markdown
(
text
,
context
=
{})
return
""
unless
text
.
present?
context
.
reverse_merge!
(
current_user:
current_user
,
path:
@path
,
pipeline: :default
,
project:
@project
,
project_wiki:
@project_wiki
,
ref:
@ref
)
Gitlab
::
Markdown
.
render
(
text
,
context
)
user
=
current_user
if
defined?
(
current_user
)
html
=
Gitlab
::
Markdown
.
render
(
text
,
context
)
Gitlab
::
Markdown
.
post_process
(
html
,
pipeline:
context
[
:pipeline
],
project:
@project
,
user:
user
)
end
# TODO (rspeicher): Remove all usages of this helper and just call `markdown`
# with a custom pipeline depending on the content being rendered
def
gfm
(
text
,
options
=
{})
return
""
unless
text
.
present?
options
.
reverse_merge!
(
current_user:
current_user
,
path:
@path
,
pipeline: :default
,
project:
@project
,
project_wiki:
@project_wiki
,
ref:
@ref
)
Gitlab
::
Markdown
.
gfm
(
text
,
options
)
user
=
current_user
if
defined?
(
current_user
)
html
=
Gitlab
::
Markdown
.
gfm
(
text
,
options
)
Gitlab
::
Markdown
.
post_process
(
html
,
pipeline:
options
[
:pipeline
],
project:
@project
,
user:
user
)
end
def
asciidoc
(
text
)
...
...
app/helpers/labels_helper.rb
View file @
a62bd121
...
...
@@ -92,11 +92,19 @@ module LabelsHelper
end
end
def
project_labels_options
(
project
)
labels
=
project
.
labels
.
to_a
labels
.
unshift
(
Label
::
None
)
labels
.
unshift
(
Label
::
Any
)
options_from_collection_for_select
(
labels
,
'name'
,
'title'
,
params
[
:label_name
])
def
projects_labels_options
labels
=
if
@project
@project
.
labels
else
Label
.
where
(
project_id:
@projects
)
end
grouped_labels
=
Labels
::
GroupService
.
new
(
labels
).
execute
grouped_labels
.
unshift
(
Label
::
None
)
grouped_labels
.
unshift
(
Label
::
Any
)
options_from_collection_for_select
(
grouped_labels
,
'name'
,
'title'
,
params
[
:label_name
])
end
# Required for Gitlab::Markdown::LabelReferenceFilter
...
...
app/helpers/projects_helper.rb
View file @
a62bd121
...
...
@@ -113,7 +113,7 @@ module ProjectsHelper
nav_tabs
<<
:merge_requests
end
if
can?
(
current_user
,
:read_build
,
project
)
if
project
.
gitlab_ci?
&&
can?
(
current_user
,
:read_build
,
project
)
nav_tabs
<<
:builds
end
...
...
app/models/commit.rb
View file @
a62bd121
...
...
@@ -2,13 +2,13 @@ class Commit
extend
ActiveModel
::
Naming
include
ActiveModel
::
Conversion
include
Mentionable
include
Participable
include
Mentionable
include
Referable
include
StaticModel
attr_mentionable
:safe_message
participant
:author
,
:committer
,
:notes
,
:mentioned_users
participant
:author
,
:committer
,
:notes
attr_accessor
:project
...
...
app/models/concerns/issuable.rb
View file @
a62bd121
...
...
@@ -6,8 +6,8 @@
#
module
Issuable
extend
ActiveSupport
::
Concern
include
Mentionable
include
Participable
include
Mentionable
included
do
belongs_to
:author
,
class_name:
"User"
...
...
@@ -47,8 +47,7 @@ module Issuable
prefix:
true
attr_mentionable
:title
,
:description
participant
:author
,
:assignee
,
:notes_with_associations
,
:mentioned_users
participant
:author
,
:assignee
,
:notes_with_associations
end
module
ClassMethods
...
...
app/models/concerns/mentionable.rb
View file @
a62bd121
...
...
@@ -20,6 +20,12 @@ module Mentionable
end
end
included
do
if
self
<
Participable
participant
->
(
current_user
)
{
mentioned_users
(
current_user
,
load_lazy_references:
false
)
}
end
end
# Returns the text used as the body of a Note when this object is referenced
#
# By default this will be the class name and the result of calling
...
...
@@ -41,22 +47,22 @@ module Mentionable
self
end
def
all_references
(
current_user
=
self
.
author
,
text
=
self
.
mentionable_text
)
ext
=
Gitlab
::
ReferenceExtractor
.
new
(
self
.
project
,
current_user
)
def
all_references
(
current_user
=
self
.
author
,
text
=
self
.
mentionable_text
,
load_lazy_references:
true
)
ext
=
Gitlab
::
ReferenceExtractor
.
new
(
self
.
project
,
current_user
,
load_lazy_references:
load_lazy_references
)
ext
.
analyze
(
text
)
ext
end
def
mentioned_users
(
current_user
=
nil
)
all_references
(
current_user
).
users
.
uniq
def
mentioned_users
(
current_user
=
nil
,
load_lazy_references:
true
)
all_references
(
current_user
,
load_lazy_references:
load_lazy_references
).
users
end
# Extract GFM references to other Mentionables from this Mentionable. Always excludes its #local_reference.
def
referenced_mentionables
(
current_user
=
self
.
author
,
text
=
self
.
mentionable_text
)
def
referenced_mentionables
(
current_user
=
self
.
author
,
text
=
self
.
mentionable_text
,
load_lazy_references:
true
)
return
[]
if
text
.
blank?
refs
=
all_references
(
current_user
,
text
)
(
refs
.
issues
+
refs
.
merge_requests
+
refs
.
commits
)
.
uniq
-
[
local_reference
]
refs
=
all_references
(
current_user
,
text
,
load_lazy_references:
load_lazy_references
)
(
refs
.
issues
+
refs
.
merge_requests
+
refs
.
commits
)
-
[
local_reference
]
end
# Create a cross-reference Note for each GFM reference to another Mentionable found in +mentionable_text+.
...
...
app/models/concerns/participable.rb
View file @
a62bd121
...
...
@@ -12,7 +12,7 @@
#
# # ...
#
# participant :author, :assignee, :
mentioned_users, :notes
# participant :author, :assignee, :
notes, ->(current_user) { mentioned_users(current_user) }
# end
#
# issue = Issue.last
...
...
@@ -27,7 +27,7 @@ module Participable
module
ClassMethods
def
participant
(
*
attrs
)
participant_attrs
.
concat
(
attrs
.
map
(
&
:to_s
)
)
participant_attrs
.
concat
(
attrs
)
end
def
participant_attrs
...
...
@@ -37,33 +37,39 @@ module Participable
# Be aware that this method makes a lot of sql queries.
# Save result into variable if you are going to reuse it inside same request
def
participants
(
current_user
=
self
.
author
)
self
.
class
.
participant_attrs
.
flat_map
do
|
attr
|
meth
=
method
(
attr
)
def
participants
(
current_user
=
self
.
author
,
load_lazy_references:
true
)
participants
=
self
.
class
.
participant_attrs
.
flat_map
do
|
attr
|
value
=
if
meth
.
arity
==
1
||
meth
.
arity
==
-
1
meth
.
call
(
current_use
r
)
if
attr
.
respond_to?
(
:call
)
instance_exec
(
current_user
,
&
att
r
)
else
meth
.
call
send
(
attr
)
end
participants_for
(
value
,
current_user
)
end
.
compact
.
uniq
.
select
do
|
user
|
user
.
can?
(
:read_project
,
self
.
project
)
end
.
compact
.
uniq
if
load_lazy_references
participants
=
Gitlab
::
Markdown
::
ReferenceFilter
::
LazyReference
.
load
(
participants
).
uniq
participants
.
select!
do
|
user
|
user
.
can?
(
:read_project
,
project
)
end
end
participants
end
private
def
participants_for
(
value
,
current_user
=
nil
)
case
value
when
User
when
User
,
Gitlab
::
Markdown
::
ReferenceFilter
::
LazyReference
[
value
]
when
Enumerable
,
ActiveRecord
::
Relation
value
.
flat_map
{
|
v
|
participants_for
(
v
,
current_user
)
}
when
Participable
value
.
participants
(
current_user
)
value
.
participants
(
current_user
,
load_lazy_references:
false
)
end
end
end
app/models/group_label.rb
0 → 100644
View file @
a62bd121
class
GroupLabel
attr_accessor
:title
,
:labels
alias_attribute
:name
,
:title
def
initialize
(
title
,
labels
)
@title
=
title
@labels
=
labels
end
end
app/models/group_milestone.rb
View file @
a62bd121
class
GroupMilestone
attr_accessor
:title
,
:milestones
alias_attribute
:name
,
:title
def
initialize
(
title
,
milestones
)
...
...
@@ -7,18 +7,10 @@ class GroupMilestone
@milestones
=
milestones
end
def
title
@title
end
def
safe_title
@title
.
parameterize
end
def
milestones
@milestones
end
def
projects
milestones
.
map
{
|
milestone
|
milestone
.
project
}
end
...
...
app/models/note.rb
View file @
a62bd121
...
...
@@ -22,14 +22,14 @@ require 'carrierwave/orm/activerecord'
require
'file_size_validator'
class
Note
<
ActiveRecord
::
Base
include
Mentionable
include
Gitlab
::
CurrentSettings
include
Participable
include
Mentionable
default_value_for
:system
,
false
attr_mentionable
:note
participant
:author
,
:mentioned_users
participant
:author
belongs_to
:project
belongs_to
:noteable
,
polymorphic:
true
...
...
app/models/user.rb
View file @
a62bd121
...
...
@@ -706,12 +706,15 @@ class User < ActiveRecord::Base
end
def
toggle_star
(
project
)
user_star_project
=
users_star_projects
.
where
(
project:
project
,
user:
self
).
take
if
user_star_project
user_star_project
.
destroy
else
UsersStarProject
.
create!
(
project:
project
,
user:
self
)
UsersStarProject
.
transaction
do
user_star_project
=
users_star_projects
.
where
(
project:
project
,
user:
self
).
lock
(
true
).
first
if
user_star_project
user_star_project
.
destroy
else
UsersStarProject
.
create!
(
project:
project
,
user:
self
)
end
end
end
...
...
app/services/labels/group_service.rb
0 → 100644
View file @
a62bd121
module
Labels
class
GroupService
<
::
BaseService
def
initialize
(
project_labels
)
@project_labels
=
project_labels
.
group_by
(
&
:title
)
end
def
execute
build
(
@project_labels
)
end
def
label
(
title
)
if
title
group_label
=
@project_labels
[
title
].
group_by
(
&
:title
)
build
(
group_label
).
first
else
nil
end
end
private
def
build
(
label
)
label
.
map
{
|
title
,
labels
|
GroupLabel
.
new
(
title
,
labels
)
}
end
end
end
app/views/ci/projects/index.html.haml
0 → 100644
View file @
a62bd121
.wiki
%h1
GitLab CI is now integrated in GitLab UI
%h2
For existing projects
%p
Check the following pages to find the CI status you're looking for:
%ul
%li
Projects page - shows CI status for each project.
%li
Project commits page - show CI status for each commit.
%h2
For new projects
%p
If you want to enable CI for a new project it is easy as adding
=
link_to
".gitlab-ci.yml"
,
"http://doc.gitlab.com/ce/ci/yaml/README.html"
file to your repository
app/views/events/_event_issue.atom.haml
View file @
a62bd121
%div
{
xmlns:
"http://www.w3.org/1999/xhtml"
}
-
if
issue
.
description
.
present?
=
markdown
(
issue
.
description
,
xhtml:
true
,
reference_only_path:
false
,
project:
issue
.
project
)
=
markdown
(
issue
.
description
,
pipeline: :atom
,
project:
issue
.
project
)
app/views/events/_event_merge_request.atom.haml
View file @
a62bd121
%div
{
xmlns:
"http://www.w3.org/1999/xhtml"
}
-
if
merge_request
.
description
.
present?
=
markdown
(
merge_request
.
description
,
xhtml:
true
,
reference_only_path:
false
,
project:
merge_request
.
project
)
=
markdown
(
merge_request
.
description
,
pipeline: :atom
,
project:
merge_request
.
project
)
app/views/events/_event_note.atom.haml
View file @
a62bd121
%div
{
xmlns:
"http://www.w3.org/1999/xhtml"
}
=
markdown
(
note
.
note
,
xhtml:
true
,
reference_only_path:
false
,
project:
note
.
project
)
=
markdown
(
note
.
note
,
pipeline: :atom
,
project:
note
.
project
)
app/views/events/_event_push.atom.haml
View file @
a62bd121
...
...
@@ -6,7 +6,7 @@
%i
at
=
commit
[
:timestamp
].
to_time
.
to_s
(
:short
)
%blockquote
=
markdown
(
escape_once
(
commit
[
:message
]),
xhtml:
true
,
reference_only_path:
false
,
project:
event
.
project
)
%blockquote
=
markdown
(
escape_once
(
commit
[
:message
]),
pipeline: :atom
,
project:
event
.
project
)
-
if
event
.
commits_count
>
15
%p
%i
...
...
app/views/notify/_note_message.html.haml
View file @
a62bd121
%div
=
markdown
(
@note
.
note
,
reference_only_path:
false
)
=
markdown
(
@note
.
note
,
pipeline: :email
)
app/views/notify/new_issue_email.html.haml
View file @
a62bd121
-
if
@issue
.
description
=
markdown
(
@issue
.
description
,
reference_only_path:
false
)
=
markdown
(
@issue
.
description
,
pipeline: :email
)
-
if
@issue
.
assignee_id
.
present?
%p
...
...
app/views/notify/new_merge_request_email.html.haml
View file @
a62bd121
...
...
@@ -6,4 +6,4 @@
Assignee:
#{
@merge_request
.
author_name
}
→
#{
@merge_request
.
assignee_name
}
-
if
@merge_request
.
description
=
markdown
(
@merge_request
.
description
,
reference_only_path:
false
)
=
markdown
(
@merge_request
.
description
,
pipeline: :email
)
app/views/projects/_last_commit.html.haml
0 → 100644
View file @
a62bd121
.project-last-commit
-
ci_commit
=
project
.
ci_commit
(
commit
.
sha
)
-
if
ci_commit
=
link_to
ci_status_path
(
ci_commit
),
class:
"ci-status ci-
#{
ci_commit
.
status
}
"
do
=
ci_status_icon
(
ci_commit
)
=
ci_commit
.
status
=
link_to
commit
.
short_id
,
namespace_project_commit_path
(
project
.
namespace
,
project
,
commit
),
class:
"commit_short_id"
=
link_to_gfm
commit
.
title
,
namespace_project_commit_path
(
project
.
namespace
,
project
,
commit
.
id
),
class:
"commit-row-message"
·
#{
time_ago_with_tooltip
(
commit
.
committed_date
,
skip_js:
true
)
}
by
=
commit_author_link
(
commit
,
avatar:
true
,
size:
24
)
app/views/projects/imports/new.html.haml
View file @
a62bd121
...
...
@@ -17,6 +17,6 @@
This URL must be publicly accessible or you can add a username and password like this: https://username:password@gitlab.com/company/project.git.
%br
The import will time out after 4 minutes. For big repositories, use a clone/push combination.
For SVN repositories, check
#{
link_to
"this migrating from SVN doc."
,
"http://doc.gitlab.com/ce/workflow/migrating_from_svn.html"
}
For SVN repositories, check
#{
link_to
"this migrating from SVN doc."
,
"http://doc.gitlab.com/ce/workflow/
importing/
migrating_from_svn.html"
}
.form-actions
=
f
.
submit
'Start import'
,
class:
"btn btn-create"
,
tabindex:
4
app/views/projects/show.html.haml
View file @
a62bd121
...
...
@@ -64,6 +64,10 @@
=
icon
(
"exclamation-triangle fw"
)
Archived project! Repository is read-only
-
if
@repository
.
commit
.content-block.second-block.white
=
render
'projects/last_commit'
,
commit:
@repository
.
commit
,
project:
@project
%section
-
if
prefer_readme?
.project-show-readme
...
...
app/views/shared/issuable/_filter.html.haml
View file @
a62bd121
...
...
@@ -42,11 +42,10 @@
class:
'select2 trigger-submit'
,
include_blank:
true
,
data:
{
placeholder:
'Milestone'
})
-
if
@project
.filter-item.inline.labels-filter
=
select_tag
(
'label_name'
,
project_labels_options
(
@project
),
class:
'select2 trigger-submit'
,
include_blank:
true
,
data:
{
placeholder:
'Label'
})
.filter-item.inline.labels-filter
=
select_tag
(
'label_name'
,
projects_labels_options
,
class:
'select2 trigger-submit'
,
include_blank:
true
,
data:
{
placeholder:
'Label'
})
.pull-right
=
render
'shared/sort_dropdown'
...
...
db/migrate/20151016131433_add_ci_projects_gl_project_id_index.rb
0 → 100644
View file @
a62bd121
class
AddCiProjectsGlProjectIdIndex
<
ActiveRecord
::
Migration
def
change
add_index
:ci_commits
,
:gl_project_id
end
end
db/migrate/20151016195451_add_ci_builds_and_projects_indexes.rb
0 → 100644
View file @
a62bd121
class
AddCiBuildsAndProjectsIndexes
<
ActiveRecord
::
Migration
def
change
add_index
:ci_projects
,
:gitlab_id
add_index
:ci_projects
,
:shared_runners_enabled
add_index
:ci_builds
,
:type
add_index
:ci_builds
,
:status
end
end
db/migrate/20151016195706_add_notes_line_code_index.rb
0 → 100644
View file @
a62bd121
class
AddNotesLineCodeIndex
<
ActiveRecord
::
Migration
def
change
add_index
:notes
,
:line_code
end
end
db/schema.rb
View file @
a62bd121
...
...
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord
::
Schema
.
define
(
version:
201510
08130321
)
do
ActiveRecord
::
Schema
.
define
(
version:
201510
16195706
)
do
# These are extensions that must be enabled in order to support this database
enable_extension
"plpgsql"
...
...
@@ -115,6 +115,8 @@ ActiveRecord::Schema.define(version: 20151008130321) do
add_index
"ci_builds"
,
[
"project_id"
,
"commit_id"
],
name:
"index_ci_builds_on_project_id_and_commit_id"
,
using: :btree
add_index
"ci_builds"
,
[
"project_id"
],
name:
"index_ci_builds_on_project_id"
,
using: :btree
add_index
"ci_builds"
,
[
"runner_id"
],
name:
"index_ci_builds_on_runner_id"
,
using: :btree
add_index
"ci_builds"
,
[
"status"
],
name:
"index_ci_builds_on_status"
,
using: :btree
add_index
"ci_builds"
,
[
"type"
],
name:
"index_ci_builds_on_type"
,
using: :btree
create_table
"ci_commits"
,
force:
true
do
|
t
|
t
.
integer
"project_id"
...
...
@@ -130,6 +132,7 @@ ActiveRecord::Schema.define(version: 20151008130321) do
t
.
integer
"gl_project_id"
end
add_index
"ci_commits"
,
[
"gl_project_id"
],
name:
"index_ci_commits_on_gl_project_id"
,
using: :btree
add_index
"ci_commits"
,
[
"project_id"
,
"committed_at"
,
"id"
],
name:
"index_ci_commits_on_project_id_and_committed_at_and_id"
,
using: :btree
add_index
"ci_commits"
,
[
"project_id"
,
"committed_at"
],
name:
"index_ci_commits_on_project_id_and_committed_at"
,
using: :btree
add_index
"ci_commits"
,
[
"project_id"
,
"sha"
],
name:
"index_ci_commits_on_project_id_and_sha"
,
using: :btree
...
...
@@ -189,6 +192,9 @@ ActiveRecord::Schema.define(version: 20151008130321) do
t
.
text
"generated_yaml_config"
end
add_index
"ci_projects"
,
[
"gitlab_id"
],
name:
"index_ci_projects_on_gitlab_id"
,
using: :btree
add_index
"ci_projects"
,
[
"shared_runners_enabled"
],
name:
"index_ci_projects_on_shared_runners_enabled"
,
using: :btree
create_table
"ci_runner_projects"
,
force:
true
do
|
t
|
t
.
integer
"runner_id"
,
null:
false
t
.
integer
"project_id"
,
null:
false
...
...
@@ -531,6 +537,7 @@ ActiveRecord::Schema.define(version: 20151008130321) do
add_index
"notes"
,
[
"commit_id"
],
name:
"index_notes_on_commit_id"
,
using: :btree
add_index
"notes"
,
[
"created_at"
,
"id"
],
name:
"index_notes_on_created_at_and_id"
,
using: :btree
add_index
"notes"
,
[
"created_at"
],
name:
"index_notes_on_created_at"
,
using: :btree
add_index
"notes"
,
[
"line_code"
],
name:
"index_notes_on_line_code"
,
using: :btree
add_index
"notes"
,
[
"noteable_id"
,
"noteable_type"
],
name:
"index_notes_on_noteable_id_and_noteable_type"
,
using: :btree
add_index
"notes"
,
[
"noteable_type"
],
name:
"index_notes_on_noteable_type"
,
using: :btree
add_index
"notes"
,
[
"project_id"
,
"noteable_type"
],
name:
"index_notes_on_project_id_and_noteable_type"
,
using: :btree
...
...
doc/install/installation.md
View file @
a62bd121
...
...
@@ -325,6 +325,7 @@ GitLab Shell is an SSH access and repository management software developed speci
cd /home/git
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-git-http-server.git
cd gitlab-git-http-server
sudo -u git -H git checkout 0.3.0
sudo -u git -H make
### Initialize Database and Activate Advanced Features
...
...
doc/update/7.14-to-8.0.md
View file @
a62bd121
...
...
@@ -84,6 +84,7 @@ Now we download `gitlab-git-http-server` and install it in `/home/git/gitlab-git
cd
/home/git
sudo
-u
git
-H
git clone https://gitlab.com/gitlab-org/gitlab-git-http-server.git
cd
gitlab-git-http-server
sudo
-u
git
-H
git checkout 0.2.14
sudo
-u
git
-H
make
```
...
...
features/project/project.feature
View file @
a62bd121
...
...
@@ -31,6 +31,12 @@ Feature: Project
And
I visit project
"Shop"
page
Then
I should see project
"Shop"
README
Scenario
:
I
should see last commit with CI
Given
project
"Shop"
has CI enabled
Given
project
"Shop"
has CI build
And
I visit project
"Shop"
page
And
I should see last commit with CI status
@javascript
Scenario
:
I
should see project activity
When
I visit project
"Shop"
activity page
...
...
features/steps/shared/project.rb
View file @
a62bd121
...
...
@@ -206,4 +206,11 @@ module SharedProject
project
=
Project
.
find_by
(
name:
"Shop"
)
create
:ci_commit
,
gl_project:
project
,
sha:
project
.
commit
.
sha
end
step
'I should see last commit with CI status'
do
page
.
within
".project-last-commit"
do
expect
(
page
).
to
have_content
(
project
.
commit
.
sha
[
0
..
6
])
expect
(
page
).
to
have_content
(
"skipped"
)
end
end
end
lib/gitlab/markdown.rb
View file @
a62bd121
...
...
@@ -7,6 +7,14 @@ module Gitlab
module
Markdown
# Convert a Markdown String into an HTML-safe String of HTML
#
# Note that while the returned HTML will have been sanitized of dangerous
# HTML, it may post a risk of information leakage if it's not also passed
# through `post_process`.
#
# Also note that the returned String is always HTML, not XHTML. Views
# requiring XHTML, such as Atom feeds, need to call `post_process` on the
# result, providing the appropriate `pipeline` option.
#
# markdown - Markdown String
# context - Hash of context options passed to our HTML Pipeline
#
...
...
@@ -31,6 +39,33 @@ module Gitlab
renderer
.
render
(
markdown
)
end
# Perform post-processing on an HTML String
#
# This method is used to perform state-dependent changes to a String of
# HTML, such as removing references that the current user doesn't have
# permission to make (`RedactorFilter`).
#
# html - String to process
# options - Hash of options to customize output
# :pipeline - Symbol pipeline type
# :project - Project
# :user - User object
#
# Returns an HTML-safe String
def
self
.
post_process
(
html
,
options
)
context
=
{
project:
options
[
:project
],
current_user:
options
[
:user
]
}
doc
=
post_processor
.
to_document
(
html
,
context
)
if
options
[
:pipeline
]
==
:atom
doc
.
to_html
(
save_with:
Nokogiri
::
XML
::
Node
::
SaveOptions
::
AS_XHTML
)
else
doc
.
to_html
end
.
html_safe
end
# Provide autoload paths for filters to prevent a circular dependency error
autoload
:AutolinkFilter
,
'gitlab/markdown/autolink_filter'
autoload
:CommitRangeReferenceFilter
,
'gitlab/markdown/commit_range_reference_filter'
...
...
@@ -41,6 +76,7 @@ module Gitlab
autoload
:IssueReferenceFilter
,
'gitlab/markdown/issue_reference_filter'
autoload
:LabelReferenceFilter
,
'gitlab/markdown/label_reference_filter'
autoload
:MergeRequestReferenceFilter
,
'gitlab/markdown/merge_request_reference_filter'
autoload
:RedactorFilter
,
'gitlab/markdown/redactor_filter'
autoload
:RelativeLinkFilter
,
'gitlab/markdown/relative_link_filter'
autoload
:SanitizationFilter
,
'gitlab/markdown/sanitization_filter'
autoload
:SnippetReferenceFilter
,
'gitlab/markdown/snippet_reference_filter'
...
...
@@ -50,26 +86,20 @@ module Gitlab
autoload
:UserReferenceFilter
,
'gitlab/markdown/user_reference_filter'
autoload
:UploadLinkFilter
,
'gitlab/markdown/upload_link_filter'
# Public: Parse the provided text with GitLab-Flavored Markdown
# Public: Parse the provided HTML with GitLab-Flavored Markdown
#
# html - HTML String
# options - A Hash of options used to customize output (default: {})
# :no_header_anchors - Disable header anchors in TableOfContentsFilter
# :path - Current path String
# :pipeline - Symbol pipeline type
# :project - Current Project object
# :project_wiki - Current ProjectWiki object
# :ref - Current ref String
#
# text - the source text
# options - A Hash of options used to customize output (default: {}):
# :xhtml - output XHTML instead of HTML
# :reference_only_path - Use relative path for reference links
def
self
.
gfm
(
text
,
options
=
{})
return
text
if
text
.
nil?
# Duplicate the string so we don't alter the original, then call to_str
# to cast it back to a String instead of a SafeBuffer. This is required
# for gsub calls to work as we need them to.
text
=
text
.
dup
.
to_str
options
.
reverse_merge!
(
xhtml:
false
,
reference_only_path:
true
,
project:
options
[
:project
],
current_user:
options
[
:current_user
]
)
# Returns an HTML-safe String
def
self
.
gfm
(
html
,
options
=
{})
return
''
unless
html
.
present?
@pipeline
||=
HTML
::
Pipeline
.
new
(
filters
)
...
...
@@ -78,41 +108,36 @@ module Gitlab
pipeline:
options
[
:pipeline
],
# EmojiFilter
asset_root:
Gitlab
.
config
.
gitlab
.
base_url
,
asset_host:
Gitlab
::
Application
.
config
.
asset_host
,
# TableOfContentsFilter
no_header_anchors:
options
[
:no_header_anchors
],
asset_root:
Gitlab
.
config
.
gitlab
.
base_url
,
# ReferenceFilter
current_user:
options
[
:current_user
],
only_path:
options
[
:reference_only_path
],
project:
options
[
:project
],
only_path:
only_path_pipeline?
(
options
[
:pipeline
]),
project:
options
[
:project
],
# RelativeLinkFilter
project_wiki:
options
[
:project_wiki
],
ref:
options
[
:ref
],
requested_path:
options
[
:path
],
project_wiki:
options
[
:project_wiki
]
}
result
=
@pipeline
.
call
(
text
,
context
)
save_options
=
0
if
options
[
:xhtml
]
save_options
|=
Nokogiri
::
XML
::
Node
::
SaveOptions
::
AS_XHTML
end
text
=
result
[
:output
].
to_html
(
save_with:
save_options
)
# TableOfContentsFilter
no_header_anchors:
options
[
:no_header_anchors
]
}
text
.
html_safe
@pipeline
.
to_html
(
html
,
context
)
.
html_safe
end
private
def
self
.
renderer
@markdown
||=
begin
renderer
=
Redcarpet
::
Render
::
HTML
.
new
Redcarpet
::
Markdown
.
new
(
renderer
,
redcarpet_options
)
# Check if a pipeline enables the `only_path` context option
#
# Returns Boolean
def
self
.
only_path_pipeline?
(
pipeline
)
case
pipeline
when
:atom
,
:email
false
else
true
end
end
...
...
@@ -130,6 +155,17 @@ module Gitlab
}.
freeze
end
def
self
.
renderer
@markdown
||=
begin
renderer
=
Redcarpet
::
Render
::
HTML
.
new
Redcarpet
::
Markdown
.
new
(
renderer
,
redcarpet_options
)
end
end
def
self
.
post_processor
@post_processor
||=
HTML
::
Pipeline
.
new
([
Gitlab
::
Markdown
::
RedactorFilter
])
end
# Filters used in our pipeline
#
# SanitizationFilter should come first so that all generated reference HTML
...
...
lib/gitlab/markdown/commit_range_reference_filter.rb
View file @
a62bd121
...
...
@@ -26,6 +26,18 @@ module Gitlab
end
end
def
self
.
referenced_by
(
node
)
project
=
Project
.
find
(
node
.
attr
(
"data-project"
))
rescue
nil
return
unless
project
id
=
node
.
attr
(
"data-commit-range"
)
range
=
CommitRange
.
new
(
id
,
project
)
return
unless
range
.
valid_commits?
{
commit_range:
range
}
end
def
initialize
(
*
args
)
super
...
...
@@ -53,13 +65,11 @@ module Gitlab
range
=
CommitRange
.
new
(
id
,
project
)
if
range
.
valid_commits?
push_result
(
:commit_range
,
range
)
url
=
url_for_commit_range
(
project
,
range
)
title
=
range
.
reference_title
klass
=
reference_class
(
:commit_range
)
data
=
data_attribute
(
project
.
id
)
data
=
data_attribute
(
project
:
project
.
id
,
commit_range:
id
)
project_ref
+=
'@'
if
project_ref
...
...
lib/gitlab/markdown/commit_reference_filter.rb
View file @
a62bd121
...
...
@@ -26,6 +26,18 @@ module Gitlab
end
end
def
self
.
referenced_by
(
node
)
project
=
Project
.
find
(
node
.
attr
(
"data-project"
))
rescue
nil
return
unless
project
id
=
node
.
attr
(
"data-commit"
)
commit
=
commit_from_ref
(
project
,
id
)
return
unless
commit
{
commit:
commit
}
end
def
call
replace_text_nodes_matching
(
Commit
.
reference_pattern
)
do
|
content
|
commit_link_filter
(
content
)
...
...
@@ -39,17 +51,15 @@ module Gitlab
# Returns a String with commit references replaced with links. All links
# have `gfm` and `gfm-commit` class names attached for styling.
def
commit_link_filter
(
text
)
self
.
class
.
references_in
(
text
)
do
|
match
,
commit_ref
,
project_ref
|
self
.
class
.
references_in
(
text
)
do
|
match
,
id
,
project_ref
|
project
=
self
.
project_from_ref
(
project_ref
)
if
commit
=
commit_from_ref
(
project
,
commit_ref
)
push_result
(
:commit
,
commit
)
if
commit
=
self
.
class
.
commit_from_ref
(
project
,
id
)
url
=
url_for_commit
(
project
,
commit
)
title
=
escape_once
(
commit
.
link_title
)
klass
=
reference_class
(
:commit
)
data
=
data_attribute
(
project
.
id
)
data
=
data_attribute
(
project
:
project
.
id
,
commit:
id
)
project_ref
+=
'@'
if
project_ref
...
...
@@ -62,9 +72,9 @@ module Gitlab
end
end
def
commit_from_ref
(
project
,
commit_ref
)
def
self
.
commit_from_ref
(
project
,
id
)
if
project
&&
project
.
valid_repo?
project
.
commit
(
commit_ref
)
project
.
commit
(
id
)
end
end
...
...
lib/gitlab/markdown/cross_project_reference.rb
View file @
a62bd121
...
...
@@ -13,18 +13,11 @@ module Gitlab
#
# ref - String reference.
#
# Returns a Project, or nil if the reference can't be
accesse
d
# Returns a Project, or nil if the reference can't be
foun
d
def
project_from_ref
(
ref
)
return
context
[
:project
]
unless
ref
other
=
Project
.
find_with_namespace
(
ref
)
return
nil
unless
other
&&
user_can_reference_project?
(
other
)
other
end
def
user_can_reference_project?
(
project
,
user
=
context
[
:current_user
])
Ability
.
abilities
.
allowed?
(
user
,
:read_project
,
project
)
Project
.
find_with_namespace
(
ref
)
end
end
end
...
...
lib/gitlab/markdown/external_issue_reference_filter.rb
View file @
a62bd121
...
...
@@ -47,8 +47,9 @@ module Gitlab
title
=
escape_once
(
"Issue in
#{
project
.
external_issue_tracker
.
title
}
"
)
klass
=
reference_class
(
:issue
)
data
=
data_attribute
(
project:
project
.
id
)
%(<a href="#{url}"
%(<a href="#{url}"
#{data}
title="#{title}"
class="#{klass}">#{match}</a>)
end
...
...
lib/gitlab/markdown/issue_reference_filter.rb
View file @
a62bd121
...
...
@@ -27,6 +27,10 @@ module Gitlab
end
end
def
self
.
referenced_by
(
node
)
{
issue:
LazyReference
.
new
(
Issue
,
node
.
attr
(
"data-issue"
))
}
end
def
call
replace_text_nodes_matching
(
Issue
.
reference_pattern
)
do
|
content
|
issue_link_filter
(
content
)
...
...
@@ -45,13 +49,11 @@ module Gitlab
project
=
self
.
project_from_ref
(
project_ref
)
if
project
&&
issue
=
project
.
get_issue
(
id
)
push_result
(
:issue
,
issue
)
url
=
url_for_issue
(
id
,
project
,
only_path:
context
[
:only_path
])
title
=
escape_once
(
"Issue:
#{
issue
.
title
}
"
)
klass
=
reference_class
(
:issue
)
data
=
data_attribute
(
project
.
id
)
data
=
data_attribute
(
project
:
project
.
id
,
issue:
issue
.
id
)
%(<a href="#{url}" #{data}
title="#{title}"
...
...
lib/gitlab/markdown/label_reference_filter.rb
View file @
a62bd121
...
...
@@ -22,6 +22,10 @@ module Gitlab
end
end
def
self
.
referenced_by
(
node
)
{
label:
LazyReference
.
new
(
Label
,
node
.
attr
(
"data-label"
))
}
end
def
call
replace_text_nodes_matching
(
Label
.
reference_pattern
)
do
|
content
|
label_link_filter
(
content
)
...
...
@@ -41,11 +45,9 @@ module Gitlab
params
=
label_params
(
id
,
name
)
if
label
=
project
.
labels
.
find_by
(
params
)
push_result
(
:label
,
label
)
url
=
url_for_label
(
project
,
label
)
klass
=
reference_class
(
:label
)
data
=
data_attribute
(
project
.
id
)
data
=
data_attribute
(
project
:
project
.
id
,
label:
label
.
id
)
%(<a href="#{url}" #{data}
class="#{klass}">#{render_colored_label(label)}</a>)
...
...
lib/gitlab/markdown/merge_request_reference_filter.rb
View file @
a62bd121
...
...
@@ -27,6 +27,10 @@ module Gitlab
end
end
def
self
.
referenced_by
(
node
)
{
merge_request:
LazyReference
.
new
(
MergeRequest
,
node
.
attr
(
"data-merge-request"
))
}
end
def
call
replace_text_nodes_matching
(
MergeRequest
.
reference_pattern
)
do
|
content
|
merge_request_link_filter
(
content
)
...
...
@@ -45,11 +49,9 @@ module Gitlab
project
=
self
.
project_from_ref
(
project_ref
)
if
project
&&
merge_request
=
project
.
merge_requests
.
find_by
(
iid:
id
)
push_result
(
:merge_request
,
merge_request
)
title
=
escape_once
(
"Merge Request:
#{
merge_request
.
title
}
"
)
klass
=
reference_class
(
:merge_request
)
data
=
data_attribute
(
project
.
id
)
data
=
data_attribute
(
project
:
project
.
id
,
merge_request:
merge_request
.
id
)
url
=
url_for_merge_request
(
merge_request
,
project
)
...
...
lib/gitlab/markdown/redactor_filter.rb
0 → 100644
View file @
a62bd121
require
'gitlab/markdown'
require
'html/pipeline/filter'
module
Gitlab
module
Markdown
# HTML filter that removes references to records that the current user does
# not have permission to view.
#
# Expected to be run in its own post-processing pipeline.
#
class
RedactorFilter
<
HTML
::
Pipeline
::
Filter
def
call
doc
.
css
(
'a.gfm'
).
each
do
|
node
|
unless
user_can_reference?
(
node
)
node
.
replace
(
node
.
text
)
end
end
doc
end
private
def
user_can_reference?
(
node
)
if
node
.
has_attribute?
(
'data-reference-filter'
)
reference_type
=
node
.
attr
(
'data-reference-filter'
)
reference_filter
=
reference_type
.
constantize
reference_filter
.
user_can_reference?
(
current_user
,
node
,
context
)
else
true
end
end
def
current_user
context
[
:current_user
]
end
end
end
end
lib/gitlab/markdown/reference_filter.rb
View file @
a62bd121
...
...
@@ -11,30 +11,57 @@ module Gitlab
# Context options:
# :project (required) - Current project, ignored if reference is cross-project.
# :only_path - Generate path-only links.
#
# Results:
# :references - A Hash of references that were found and replaced.
class
ReferenceFilter
<
HTML
::
Pipeline
::
Filter
def
initialize
(
*
args
)
super
LazyReference
=
Struct
.
new
(
:klass
,
:ids
)
do
def
self
.
load
(
refs
)
lazy_references
,
values
=
refs
.
partition
{
|
ref
|
ref
.
is_a?
(
self
)
}
lazy_values
=
lazy_references
.
group_by
(
&
:klass
).
flat_map
do
|
klass
,
refs
|
ids
=
refs
.
flat_map
(
&
:ids
)
klass
.
where
(
id:
ids
)
end
values
+
lazy_values
end
def
load
self
.
klass
.
where
(
id:
self
.
ids
)
end
end
def
self
.
user_can_reference?
(
user
,
node
,
context
)
if
node
.
has_attribute?
(
'data-project'
)
project_id
=
node
.
attr
(
'data-project'
).
to_i
return
true
if
project_id
==
context
[
:project
].
try
(
:id
)
project
=
Project
.
find
(
project_id
)
rescue
nil
Ability
.
abilities
.
allowed?
(
user
,
:read_project
,
project
)
else
true
end
end
result
[
:references
]
=
Hash
.
new
{
|
hash
,
type
|
hash
[
type
]
=
[]
}
def
self
.
referenced_by
(
node
)
raise
NotImplementedError
,
"
#{
self
}
does not implement
#{
__method__
}
"
end
# Returns a data attribute String to attach to a reference link
#
#
id - Object ID
#
type - Object type (default: :project)
#
attributes - Hash, where the key becomes the data attribute name and the
#
value is the data attribute value
#
# Examples:
#
# data_attribute(1) # => "data-project-id=\"1\""
# data_attribute(2, :user) # => "data-user-id=\"2\""
# data_attribute(3, :group) # => "data-group-id=\"3\""
# data_attribute(project: 1, issue: 2)
# # => "data-reference-filter=\"Gitlab::Markdown::SomeReferenceFilter\" data-project=\"1\" data-issue=\"2\""
#
# data_attribute(project: 3, merge_request: 4)
# # => "data-reference-filter=\"Gitlab::Markdown::SomeReferenceFilter\" data-project=\"3\" data-merge-request=\"4\""
#
# Returns a String
def
data_attribute
(
id
,
type
=
:project
)
%Q(data-
#{
type
}
-id="
#{
id
}
")
def
data_attribute
(
attributes
=
{})
attributes
[
:reference_filter
]
=
self
.
class
.
name
attributes
.
map
{
|
key
,
value
|
%Q(data-
#{
key
.
to_s
.
dasherize
}
="
#{
value
}
")
}.
join
(
" "
)
end
def
escape_once
(
html
)
...
...
@@ -59,16 +86,6 @@ module Gitlab
context
[
:project
]
end
# Add a reference to the pipeline's result Hash
#
# type - Singular Symbol reference type (e.g., :issue, :user, etc.)
# values - One or more Objects to add
def
push_result
(
type
,
*
values
)
return
if
values
.
empty?
result
[
:references
][
type
].
push
(
*
values
)
end
def
reference_class
(
type
)
"gfm gfm-
#{
type
}
"
end
...
...
@@ -85,7 +102,7 @@ module Gitlab
# Yields the current node's String contents. The result of the block will
# replace the node's existing content and update the current document.
#
# Returns the updated Nokogiri::
XML::Docu
ment object.
# Returns the updated Nokogiri::
HTML::DocumentFrag
ment object.
def
replace_text_nodes_matching
(
pattern
)
return
doc
if
project
.
nil?
...
...
lib/gitlab/markdown/reference_gatherer_filter.rb
0 → 100644
View file @
a62bd121
require
'gitlab/markdown'
require
'html/pipeline/filter'
module
Gitlab
module
Markdown
# HTML filter that gathers all referenced records that the current user has
# permission to view.
#
# Expected to be run in its own post-processing pipeline.
#
class
ReferenceGathererFilter
<
HTML
::
Pipeline
::
Filter
def
initialize
(
*
)
super
result
[
:references
]
||=
Hash
.
new
{
|
hash
,
type
|
hash
[
type
]
=
[]
}
end
def
call
doc
.
css
(
'a.gfm'
).
each
do
|
node
|
gather_references
(
node
)
end
load_lazy_references
unless
context
[
:load_lazy_references
]
==
false
doc
end
private
def
gather_references
(
node
)
return
unless
node
.
has_attribute?
(
'data-reference-filter'
)
reference_type
=
node
.
attr
(
'data-reference-filter'
)
reference_filter
=
reference_type
.
constantize
return
if
context
[
:reference_filter
]
&&
reference_filter
!=
context
[
:reference_filter
]
return
unless
reference_filter
.
user_can_reference?
(
current_user
,
node
,
context
)
references
=
reference_filter
.
referenced_by
(
node
)
return
unless
references
references
.
each
do
|
type
,
values
|
Array
.
wrap
(
values
).
each
do
|
value
|
result
[
:references
][
type
]
<<
value
end
end
end
# Will load all references of one type using one query.
def
load_lazy_references
refs
=
result
[
:references
]
refs
.
each
do
|
type
,
values
|
refs
[
type
]
=
ReferenceFilter
::
LazyReference
.
load
(
values
)
end
end
def
current_user
context
[
:current_user
]
end
end
end
end
lib/gitlab/markdown/snippet_reference_filter.rb
View file @
a62bd121
...
...
@@ -27,6 +27,10 @@ module Gitlab
end
end
def
self
.
referenced_by
(
node
)
{
snippet:
LazyReference
.
new
(
Snippet
,
node
.
attr
(
"data-snippet"
))
}
end
def
call
replace_text_nodes_matching
(
Snippet
.
reference_pattern
)
do
|
content
|
snippet_link_filter
(
content
)
...
...
@@ -45,11 +49,9 @@ module Gitlab
project
=
self
.
project_from_ref
(
project_ref
)
if
project
&&
snippet
=
project
.
snippets
.
find_by
(
id:
id
)
push_result
(
:snippet
,
snippet
)
title
=
escape_once
(
"Snippet:
#{
snippet
.
title
}
"
)
klass
=
reference_class
(
:snippet
)
data
=
data_attribute
(
project
.
id
)
data
=
data_attribute
(
project
:
project
.
id
,
snippet:
snippet
.
id
)
url
=
url_for_snippet
(
snippet
,
project
)
...
...
lib/gitlab/markdown/user_reference_filter.rb
View file @
a62bd121
...
...
@@ -23,6 +23,31 @@ module Gitlab
end
end
def
self
.
referenced_by
(
node
)
if
node
.
has_attribute?
(
'data-group'
)
group
=
Group
.
find
(
node
.
attr
(
'data-group'
))
rescue
nil
return
unless
group
{
user:
group
.
users
}
elsif
node
.
has_attribute?
(
'data-user'
)
{
user:
LazyReference
.
new
(
User
,
node
.
attr
(
'data-user'
))
}
elsif
node
.
has_attribute?
(
'data-project'
)
project
=
Project
.
find
(
node
.
attr
(
'data-project'
))
rescue
nil
return
unless
project
{
user:
project
.
team
.
members
.
flatten
}
end
end
def
self
.
user_can_reference?
(
user
,
node
,
context
)
if
node
.
has_attribute?
(
'data-group'
)
group
=
Group
.
find
(
node
.
attr
(
'data-group'
))
rescue
nil
Ability
.
abilities
.
allowed?
(
user
,
:read_group
,
group
)
else
super
end
end
def
call
replace_text_nodes_matching
(
User
.
reference_pattern
)
do
|
content
|
user_link_filter
(
content
)
...
...
@@ -61,14 +86,12 @@ module Gitlab
def
link_to_all
project
=
context
[
:project
]
# FIXME (rspeicher): Law of Demeter
push_result
(
:user
,
*
project
.
team
.
members
.
flatten
)
url
=
urls
.
namespace_project_url
(
project
.
namespace
,
project
,
only_path:
context
[
:only_path
])
data
=
data_attribute
(
project:
project
.
id
)
text
=
User
.
reference_prefix
+
'all'
%(<a href="#{url}" class="#{link_class}">#{text}</a>)
%(<a href="#{url}"
#{data}
class="#{link_class}">#{text}</a>)
end
def
link_to_namespace
(
namespace
)
...
...
@@ -80,30 +103,20 @@ module Gitlab
end
def
link_to_group
(
group
,
namespace
)
return
unless
user_can_reference_group?
(
namespace
)
push_result
(
:user
,
*
namespace
.
users
)
url
=
urls
.
group_url
(
group
,
only_path:
context
[
:only_path
])
data
=
data_attribute
(
namespace
.
id
,
:group
)
data
=
data_attribute
(
group:
namespace
.
id
)
text
=
Group
.
reference_prefix
+
group
%(<a href="#{url}" #{data} class="#{link_class}">#{text}</a>)
end
def
link_to_user
(
user
,
namespace
)
push_result
(
:user
,
namespace
.
owner
)
url
=
urls
.
user_url
(
user
,
only_path:
context
[
:only_path
])
data
=
data_attribute
(
namespace
.
owner_id
,
:user
)
data
=
data_attribute
(
user:
namespace
.
owner_id
)
text
=
User
.
reference_prefix
+
user
%(<a href="#{url}" #{data} class="#{link_class}">#{text}</a>)
end
def
user_can_reference_group?
(
group
)
Ability
.
abilities
.
allowed?
(
context
[
:current_user
],
:read_group
,
group
)
end
end
end
end
lib/gitlab/reference_extractor.rb
View file @
a62bd121
...
...
@@ -3,11 +3,12 @@ require 'gitlab/markdown'
module
Gitlab
# Extract possible GFM references from an arbitrary String for further processing.
class
ReferenceExtractor
attr_accessor
:project
,
:current_user
attr_accessor
:project
,
:current_user
,
:load_lazy_references
def
initialize
(
project
,
current_user
=
nil
)
def
initialize
(
project
,
current_user
=
nil
,
load_lazy_references:
true
)
@project
=
project
@current_user
=
current_user
@load_lazy_references
=
load_lazy_references
end
def
analyze
(
text
)
...
...
@@ -28,7 +29,7 @@ module Gitlab
type
=
type
.
to_sym
return
references
[
type
]
if
references
.
has_key?
(
type
)
references
[
type
]
=
pipeline_result
(
type
)
.
uniq
references
[
type
]
=
pipeline_result
(
type
)
end
end
...
...
@@ -41,21 +42,32 @@ module Gitlab
def
pipeline_result
(
filter_type
)
return
[]
if
@text
.
blank?
klass
=
filter_type
.
to_s
.
camelize
+
'ReferenceFilter'
klass
=
"
#{
filter_type
.
to_s
.
camelize
}
ReferenceFilter"
filter
=
Gitlab
::
Markdown
.
const_get
(
klass
)
context
=
{
project:
project
,
current_user:
current_user
,
# We don't actually care about the links generated
only_path:
true
,
ignore_blockquotes:
true
ignore_blockquotes:
true
,
# ReferenceGathererFilter
load_lazy_references:
false
,
reference_filter:
filter
}
pipeline
=
HTML
::
Pipeline
.
new
([
filter
],
context
)
pipeline
=
HTML
::
Pipeline
.
new
([
filter
,
Gitlab
::
Markdown
::
ReferenceGathererFilter
],
context
)
result
=
pipeline
.
call
(
@text
)
result
[
:references
][
filter_type
]
values
=
result
[
:references
][
filter_type
].
uniq
if
@load_lazy_references
values
=
Gitlab
::
Markdown
::
ReferenceFilter
::
LazyReference
.
load
(
values
).
uniq
end
values
end
end
end
spec/features/markdown_spec.rb
View file @
a62bd121
...
...
@@ -220,7 +220,7 @@ describe 'GitLab Markdown', feature: true do
end
end
#
`markdown` calls these two methods
#
Fake a `current_user` helper
def
current_user
@feat
.
user
end
...
...
spec/helpers/gitlab_markdown_helper_spec.rb
View file @
a62bd121
...
...
@@ -11,12 +11,15 @@ describe GitlabMarkdownHelper do
let
(
:merge_request
)
{
create
(
:merge_request
,
source_project:
project
,
target_project:
project
)
}
let
(
:snippet
)
{
create
(
:project_snippet
,
project:
project
)
}
# Helper expects a current_user method.
let
(
:current_user
)
{
user
}
before
do
# Ensure the generated reference links aren't redacted
project
.
team
<<
[
user
,
:master
]
# Helper expects a @project instance variable
@project
=
project
helper
.
instance_variable_set
(
:@project
,
project
)
# Stub the `current_user` helper
allow
(
helper
).
to
receive
(
:current_user
).
and_return
(
user
)
end
describe
"#markdown"
do
...
...
@@ -25,23 +28,23 @@ describe GitlabMarkdownHelper do
it
"should link to the merge request"
do
expected
=
namespace_project_merge_request_path
(
project
.
namespace
,
project
,
merge_request
)
expect
(
markdown
(
actual
)).
to
match
(
expected
)
expect
(
helper
.
markdown
(
actual
)).
to
match
(
expected
)
end
it
"should link to the commit"
do
expected
=
namespace_project_commit_path
(
project
.
namespace
,
project
,
commit
)
expect
(
markdown
(
actual
)).
to
match
(
expected
)
expect
(
helper
.
markdown
(
actual
)).
to
match
(
expected
)
end
it
"should link to the issue"
do
expected
=
namespace_project_issue_path
(
project
.
namespace
,
project
,
issue
)
expect
(
markdown
(
actual
)).
to
match
(
expected
)
expect
(
helper
.
markdown
(
actual
)).
to
match
(
expected
)
end
end
describe
"override default project"
do
let
(
:actual
)
{
issue
.
to_reference
}
let
(
:second_project
)
{
create
(
:project
)
}
let
(
:second_project
)
{
create
(
:project
,
:public
)
}
let
(
:second_issue
)
{
create
(
:issue
,
project:
second_project
)
}
it
'should link to the issue'
do
...
...
@@ -56,7 +59,7 @@ describe GitlabMarkdownHelper do
let
(
:issues
)
{
create_list
(
:issue
,
2
,
project:
project
)
}
it
'should handle references nested in links with all the text'
do
actual
=
link_to_gfm
(
"This should finally fix
#{
issues
[
0
].
to_reference
}
and
#{
issues
[
1
].
to_reference
}
for real"
,
commit_path
)
actual
=
helper
.
link_to_gfm
(
"This should finally fix
#{
issues
[
0
].
to_reference
}
and
#{
issues
[
1
].
to_reference
}
for real"
,
commit_path
)
doc
=
Nokogiri
::
HTML
.
parse
(
actual
)
# Make sure we didn't create invalid markup
...
...
@@ -86,7 +89,7 @@ describe GitlabMarkdownHelper do
end
it
'should forward HTML options'
do
actual
=
link_to_gfm
(
"Fixed in
#{
commit
.
id
}
"
,
commit_path
,
class:
'foo'
)
actual
=
helper
.
link_to_gfm
(
"Fixed in
#{
commit
.
id
}
"
,
commit_path
,
class:
'foo'
)
doc
=
Nokogiri
::
HTML
.
parse
(
actual
)
expect
(
doc
.
css
(
'a'
)).
to
satisfy
do
|
v
|
...
...
@@ -97,13 +100,13 @@ describe GitlabMarkdownHelper do
it
"escapes HTML passed in as the body"
do
actual
=
"This is a <h1>test</h1> - see
#{
issues
[
0
].
to_reference
}
"
expect
(
link_to_gfm
(
actual
,
commit_path
)).
expect
(
helper
.
link_to_gfm
(
actual
,
commit_path
)).
to
match
(
'<h1>test</h1>'
)
end
it
'ignores reference links when they are the entire body'
do
text
=
issues
[
0
].
to_reference
act
=
link_to_gfm
(
text
,
'/foo'
)
act
=
helper
.
link_to_gfm
(
text
,
'/foo'
)
expect
(
act
).
to
eq
%Q(<a href="/foo">
#{
issues
[
0
].
to_reference
}
</a>)
end
...
...
spec/helpers/labels_helper_spec.rb
View file @
a62bd121
...
...
@@ -14,11 +14,6 @@ describe LabelsHelper do
expect
(
label
).
not_to
receive
(
:project
)
link_to_label
(
label
)
end
it
'includes option for "No Label"'
do
result
=
project_labels_options
(
project
)
expect
(
result
).
to
include
(
'No Label'
)
end
end
context
'without @project set'
do
...
...
spec/lib/gitlab/closing_issue_extractor_spec.rb
View file @
a62bd121
...
...
@@ -140,28 +140,28 @@ describe Gitlab::ClosingIssueExtractor do
message
=
"Closes
#{
reference
}
and fix
#{
reference2
}
"
expect
(
subject
.
closed_by_message
(
message
)).
to
eq
([
issue
,
other_issue
])
to
match_array
([
issue
,
other_issue
])
end
it
'fetches comma-separated issues references in single line message'
do
message
=
"Closes
#{
reference
}
, closes
#{
reference2
}
"
expect
(
subject
.
closed_by_message
(
message
)).
to
eq
([
issue
,
other_issue
])
to
match_array
([
issue
,
other_issue
])
end
it
'fetches comma-separated issues numbers in single line message'
do
message
=
"Closes
#{
reference
}
,
#{
reference2
}
and
#{
reference3
}
"
expect
(
subject
.
closed_by_message
(
message
)).
to
eq
([
issue
,
other_issue
,
third_issue
])
to
match_array
([
issue
,
other_issue
,
third_issue
])
end
it
'fetches issues in multi-line message'
do
message
=
"Awesome commit (closes
#{
reference
}
)
\n
Also fixes
#{
reference2
}
"
expect
(
subject
.
closed_by_message
(
message
)).
to
eq
([
issue
,
other_issue
])
to
match_array
([
issue
,
other_issue
])
end
it
'fetches issues in hybrid message'
do
...
...
@@ -169,7 +169,7 @@ describe Gitlab::ClosingIssueExtractor do
"Also fixing issues
#{
reference2
}
,
#{
reference3
}
and #4"
expect
(
subject
.
closed_by_message
(
message
)).
to
eq
([
issue
,
other_issue
,
third_issue
])
to
match_array
([
issue
,
other_issue
,
third_issue
])
end
end
end
...
...
spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb
View file @
a62bd121
...
...
@@ -4,7 +4,7 @@ module Gitlab::Markdown
describe
CommitRangeReferenceFilter
do
include
FilterSpecHelper
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:commit1
)
{
project
.
commit
}
let
(
:commit2
)
{
project
.
commit
(
"HEAD~2"
)
}
...
...
@@ -75,12 +75,20 @@ module Gitlab::Markdown
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-commit_range'
end
it
'includes a data-project
-id
attribute'
do
it
'includes a data-project attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-project-id'
)
expect
(
link
.
attr
(
'data-project-id'
)).
to
eq
project
.
id
.
to_s
expect
(
link
).
to
have_attribute
(
'data-project'
)
expect
(
link
.
attr
(
'data-project'
)).
to
eq
project
.
id
.
to_s
end
it
'includes a data-commit-range attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-commit-range'
)
expect
(
link
.
attr
(
'data-commit-range'
)).
to
eq
range
.
to_reference
end
it
'supports an :only_path option'
do
...
...
@@ -92,59 +100,45 @@ module Gitlab::Markdown
end
it
'adds to the results hash'
do
result
=
pipeline_result
(
"See
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"See
#{
reference
}
"
)
expect
(
result
[
:references
][
:commit_range
]).
not_to
be_empty
end
end
context
'cross-project reference'
do
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
let
(
:project2
)
{
create
(
:project
,
namespace:
namespace
)
}
let
(
:project2
)
{
create
(
:project
,
:public
,
namespace:
namespace
)
}
let
(
:reference
)
{
range
.
to_reference
(
project
)
}
before
do
range
.
project
=
project2
end
context
'when user can access reference'
do
before
{
allow_cross_reference!
}
it
'links to a valid reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
namespace_project_compare_url
(
project2
.
namespace
,
project2
,
range
.
to_param
)
end
it
'links with adjacent text'
do
doc
=
filter
(
"Fixed (
#{
reference
}
.)"
)
exp
=
Regexp
.
escape
(
"
#{
project2
.
to_reference
}
@
#{
range
.
to_s
}
"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
exp
}
<\/a>\.\)/
)
end
it
'links to a valid reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
it
'ignores invalid commit IDs on the referenced project'
do
exp
=
act
=
"Fixed
#{
project2
.
to_reference
}
@
#{
commit1
.
id
.
reverse
}
...
#{
commit2
.
id
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
namespace_project_compare_url
(
project2
.
namespace
,
project2
,
range
.
to_param
)
end
exp
=
act
=
"Fixed
#{
project2
.
to_reference
}
@
#{
commit1
.
id
}
...
#{
commit2
.
id
.
reverse
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
it
'links with adjacent text'
do
doc
=
filter
(
"Fixed (
#{
reference
}
.)"
)
it
'adds to the results hash'
do
result
=
pipeline_result
(
"See
#{
reference
}
"
)
expect
(
result
[
:references
][
:commit_range
]).
not_to
be_empty
end
exp
=
Regexp
.
escape
(
"
#{
project2
.
to_reference
}
@
#{
range
.
to_s
}
"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
exp
}
<\/a>\.\)/
)
end
context
'when user cannot access reference'
do
before
{
disallow_cross_reference!
}
it
'ignores invalid commit IDs on the referenced project'
do
exp
=
act
=
"Fixed
#{
project2
.
to_reference
}
@
#{
commit1
.
id
.
reverse
}
...
#{
commit2
.
id
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
it
'ignores valid references'
do
exp
=
act
=
"See
#{
reference
}
"
exp
=
act
=
"Fixed
#{
project2
.
to_reference
}
@
#{
commit1
.
id
}
...
#{
commit2
.
id
.
reverse
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
it
'adds to the results hash'
do
result
=
reference_pipeline_result
(
"See
#{
reference
}
"
)
expect
(
result
[
:references
][
:commit_range
]).
not_to
be_empty
end
end
end
...
...
spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
View file @
a62bd121
...
...
@@ -4,7 +4,7 @@ module Gitlab::Markdown
describe
CommitReferenceFilter
do
include
FilterSpecHelper
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:commit
)
{
project
.
commit
}
it
'requires project context'
do
...
...
@@ -71,12 +71,20 @@ module Gitlab::Markdown
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-commit'
end
it
'includes a data-project
-id
attribute'
do
it
'includes a data-project attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-project-id'
)
expect
(
link
.
attr
(
'data-project-id'
)).
to
eq
project
.
id
.
to_s
expect
(
link
).
to
have_attribute
(
'data-project'
)
expect
(
link
.
attr
(
'data-project'
)).
to
eq
project
.
id
.
to_s
end
it
'includes a data-commit attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-commit'
)
expect
(
link
.
attr
(
'data-commit'
)).
to
eq
commit
.
id
end
it
'supports an :only_path context'
do
...
...
@@ -88,53 +96,39 @@ module Gitlab::Markdown
end
it
'adds to the results hash'
do
result
=
pipeline_result
(
"See
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"See
#{
reference
}
"
)
expect
(
result
[
:references
][
:commit
]).
not_to
be_empty
end
end
context
'cross-project reference'
do
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
let
(
:project2
)
{
create
(
:project
,
namespace:
namespace
)
}
let
(
:project2
)
{
create
(
:project
,
:public
,
namespace:
namespace
)
}
let
(
:commit
)
{
project2
.
commit
}
let
(
:reference
)
{
commit
.
to_reference
(
project
)
}
context
'when user can access reference'
do
before
{
allow_cross_reference!
}
it
'links to a valid reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
namespace_project_commit_url
(
project2
.
namespace
,
project2
,
commit
.
id
)
end
it
'links with adjacent text'
do
doc
=
filter
(
"Fixed (
#{
reference
}
.)"
)
it
'links to a valid reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
exp
=
Regexp
.
escape
(
project2
.
to_reference
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
exp
}
@
#{
commit
.
short_id
}
<\/a>\.\)/
)
end
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
namespace_project_commit_url
(
project2
.
namespace
,
project2
,
commit
.
id
)
end
it
'ignores invalid commit IDs on the referenced project'
do
exp
=
act
=
"Committed
#{
invalidate_reference
(
reference
)
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
it
'links with adjacent text'
do
doc
=
filter
(
"Fixed (
#{
reference
}
.)"
)
it
'adds to the results hash'
do
result
=
pipeline_result
(
"See
#{
reference
}
"
)
expect
(
result
[
:references
][
:commit
]).
not_to
be_empty
end
exp
=
Regexp
.
escape
(
project2
.
to_reference
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
exp
}
@
#{
commit
.
short_id
}
<\/a>\.\)/
)
end
context
'when user cannot access reference'
do
before
{
disallow_cross_reference!
}
it
'ignores valid references'
do
exp
=
act
=
"See
#{
reference
}
"
it
'ignores invalid commit IDs on the referenced project'
do
exp
=
act
=
"Committed
#{
invalidate_reference
(
reference
)
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
it
'adds to the results hash'
do
result
=
reference_pipeline_result
(
"See
#{
reference
}
"
)
expect
(
result
[
:references
][
:commit
]).
not_to
be_empty
end
end
end
...
...
spec/lib/gitlab/markdown/cross_project_reference_spec.rb
View file @
a62bd121
...
...
@@ -2,20 +2,16 @@ require 'spec_helper'
module
Gitlab::Markdown
describe
CrossProjectReference
do
# context in the html-pipeline sense, not in the rspec sense
let
(
:context
)
do
{
current_user:
double
(
'user'
),
project:
double
(
'project'
)
}
end
include
described_class
describe
'#project_from_ref'
do
context
'when no project was referenced'
do
it
'returns the project from context'
do
expect
(
project_from_ref
(
nil
)).
to
eq
context
[
:project
]
project
=
double
allow
(
self
).
to
receive
(
:context
).
and_return
({
project:
project
})
expect
(
project_from_ref
(
nil
)).
to
eq
project
end
end
...
...
@@ -26,29 +22,13 @@ module Gitlab::Markdown
end
context
'when referenced project exists'
do
let
(
:project2
)
{
double
(
'referenced project'
)
}
it
'returns the referenced project'
do
project2
=
double
(
'referenced project'
)
before
do
expect
(
Project
).
to
receive
(
:find_with_namespace
).
with
(
'cross/reference'
).
and_return
(
project2
)
end
context
'and the user has permission to read it'
do
it
'returns the referenced project'
do
expect
(
self
).
to
receive
(
:user_can_reference_project?
).
with
(
project2
).
and_return
(
true
)
expect
(
project_from_ref
(
'cross/reference'
)).
to
eq
project2
end
end
context
'and the user does not have permission to read it'
do
it
'returns nil'
do
expect
(
self
).
to
receive
(
:user_can_reference_project?
).
with
(
project2
).
and_return
(
false
)
expect
(
project_from_ref
(
'cross/reference'
)).
to
be_nil
end
expect
(
project_from_ref
(
'cross/reference'
)).
to
eq
project2
end
end
end
...
...
spec/lib/gitlab/markdown/issue_reference_filter_spec.rb
View file @
a62bd121
...
...
@@ -8,7 +8,7 @@ module Gitlab::Markdown
IssuesHelper
end
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:project
)
{
create
(
:empty_project
,
:public
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
it
'requires project context'
do
...
...
@@ -68,12 +68,20 @@ module Gitlab::Markdown
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-issue'
end
it
'includes a data-project
-id
attribute'
do
it
'includes a data-project attribute'
do
doc
=
filter
(
"Issue
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-project-id'
)
expect
(
link
.
attr
(
'data-project-id'
)).
to
eq
project
.
id
.
to_s
expect
(
link
).
to
have_attribute
(
'data-project'
)
expect
(
link
.
attr
(
'data-project'
)).
to
eq
project
.
id
.
to_s
end
it
'includes a data-issue attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-issue'
)
expect
(
link
.
attr
(
'data-issue'
)).
to
eq
issue
.
id
.
to_s
end
it
'supports an :only_path context'
do
...
...
@@ -85,60 +93,46 @@ module Gitlab::Markdown
end
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Fixed
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"Fixed
#{
reference
}
"
)
expect
(
result
[
:references
][
:issue
]).
to
eq
[
issue
]
end
end
context
'cross-project reference'
do
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
let
(
:project2
)
{
create
(
:empty_project
,
namespace:
namespace
)
}
let
(
:project2
)
{
create
(
:empty_project
,
:public
,
namespace:
namespace
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project2
)
}
let
(
:reference
)
{
issue
.
to_reference
(
project
)
}
context
'when user can access reference'
do
before
{
allow_cross_reference!
}
it
'ignores valid references when cross-reference project uses external tracker'
do
expect_any_instance_of
(
Project
).
to
receive
(
:get_issue
).
with
(
issue
.
iid
).
and_return
(
nil
)
exp
=
act
=
"Issue
#{
reference
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
it
'ignores valid references when cross-reference project uses external tracker'
do
expect_any_instance_of
(
Project
).
to
receive
(
:get_issue
).
with
(
issue
.
iid
).
and_return
(
nil
)
it
'links to a valid reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
helper
.
url_for_issue
(
issue
.
iid
,
project2
)
end
it
'links with adjacent text'
do
doc
=
filter
(
"Fixed (
#{
reference
}
.)"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
exp
=
act
=
"Issue
#{
reference
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
it
'ignores invalid issue IDs on the referenced project
'
do
exp
=
act
=
"Fixed
#{
invalidate_reference
(
reference
)
}
"
it
'links to a valid reference
'
do
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
helper
.
url_for_issue
(
issue
.
iid
,
project2
)
end
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Fixed
#{
reference
}
"
)
expect
(
result
[
:references
][
:issue
]).
to
eq
[
issue
]
end
it
'links with adjacent text'
do
doc
=
filter
(
"Fixed (
#{
reference
}
.)"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
context
'when user cannot access reference
'
do
before
{
disallow_cross_reference!
}
it
'ignores invalid issue IDs on the referenced project
'
do
exp
=
act
=
"Fixed
#{
invalidate_reference
(
reference
)
}
"
it
'ignores valid references'
do
exp
=
act
=
"See
#{
reference
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
it
'adds to the results hash'
do
result
=
reference_pipeline_result
(
"Fixed
#{
reference
}
"
)
expect
(
result
[
:references
][
:issue
]).
to
eq
[
issue
]
end
end
end
...
...
spec/lib/gitlab/markdown/label_reference_filter_spec.rb
View file @
a62bd121
...
...
@@ -5,7 +5,7 @@ module Gitlab::Markdown
describe
LabelReferenceFilter
do
include
FilterSpecHelper
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:project
)
{
create
(
:empty_project
,
:public
)
}
let
(
:label
)
{
create
(
:label
,
project:
project
)
}
let
(
:reference
)
{
label
.
to_reference
}
...
...
@@ -25,12 +25,20 @@ module Gitlab::Markdown
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-label'
end
it
'includes a data-project
-id
attribute'
do
it
'includes a data-project attribute'
do
doc
=
filter
(
"Label
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-project-id'
)
expect
(
link
.
attr
(
'data-project-id'
)).
to
eq
project
.
id
.
to_s
expect
(
link
).
to
have_attribute
(
'data-project'
)
expect
(
link
.
attr
(
'data-project'
)).
to
eq
project
.
id
.
to_s
end
it
'includes a data-label attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-label'
)
expect
(
link
.
attr
(
'data-label'
)).
to
eq
label
.
id
.
to_s
end
it
'supports an :only_path context'
do
...
...
@@ -42,7 +50,7 @@ module Gitlab::Markdown
end
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Label
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"Label
#{
reference
}
"
)
expect
(
result
[
:references
][
:label
]).
to
eq
[
label
]
end
...
...
spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb
View file @
a62bd121
...
...
@@ -4,7 +4,7 @@ module Gitlab::Markdown
describe
MergeRequestReferenceFilter
do
include
FilterSpecHelper
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:merge
)
{
create
(
:merge_request
,
source_project:
project
)
}
it
'requires project context'
do
...
...
@@ -56,12 +56,20 @@ module Gitlab::Markdown
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-merge_request'
end
it
'includes a data-project
-id
attribute'
do
it
'includes a data-project attribute'
do
doc
=
filter
(
"Merge
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-project-id'
)
expect
(
link
.
attr
(
'data-project-id'
)).
to
eq
project
.
id
.
to_s
expect
(
link
).
to
have_attribute
(
'data-project'
)
expect
(
link
.
attr
(
'data-project'
)).
to
eq
project
.
id
.
to_s
end
it
'includes a data-merge-request attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-merge-request'
)
expect
(
link
.
attr
(
'data-merge-request'
)).
to
eq
merge
.
id
.
to_s
end
it
'supports an :only_path context'
do
...
...
@@ -73,53 +81,39 @@ module Gitlab::Markdown
end
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Merge
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"Merge
#{
reference
}
"
)
expect
(
result
[
:references
][
:merge_request
]).
to
eq
[
merge
]
end
end
context
'cross-project reference'
do
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
let
(
:project2
)
{
create
(
:project
,
namespace:
namespace
)
}
let
(
:project2
)
{
create
(
:project
,
:public
,
namespace:
namespace
)
}
let
(
:merge
)
{
create
(
:merge_request
,
source_project:
project2
)
}
let
(
:reference
)
{
merge
.
to_reference
(
project
)
}
context
'when user can access reference'
do
before
{
allow_cross_reference!
}
it
'links to a valid reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
namespace_project_merge_request_url
(
project2
.
namespace
,
project
,
merge
)
end
it
'links with adjacent text'
do
doc
=
filter
(
"Merge (
#{
reference
}
.)"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
it
'ignores invalid merge IDs on the referenced project'
do
exp
=
act
=
"Merge
#{
invalidate_reference
(
reference
)
}
"
it
'links to a valid reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
namespace_project_merge_request_url
(
project2
.
namespace
,
project
,
merge
)
end
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Merge
#{
reference
}
"
)
expect
(
result
[
:references
][
:merge_request
]).
to
eq
[
merge
]
end
it
'links with adjacent text'
do
doc
=
filter
(
"Merge (
#{
reference
}
.)"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
context
'when user cannot access reference
'
do
before
{
disallow_cross_reference!
}
it
'ignores invalid merge IDs on the referenced project
'
do
exp
=
act
=
"Merge
#{
invalidate_reference
(
reference
)
}
"
it
'ignores valid references'
do
exp
=
act
=
"See
#{
reference
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
it
'adds to the results hash'
do
result
=
reference_pipeline_result
(
"Merge
#{
reference
}
"
)
expect
(
result
[
:references
][
:merge_request
]).
to
eq
[
merge
]
end
end
end
...
...
spec/lib/gitlab/markdown/redactor_filter_spec.rb
0 → 100644
View file @
a62bd121
require
'spec_helper'
module
Gitlab::Markdown
describe
RedactorFilter
do
include
ActionView
::
Helpers
::
UrlHelper
include
FilterSpecHelper
it
'ignores non-GFM links'
do
html
=
%(See <a href="https://google.com/">Google</a>)
doc
=
filter
(
html
,
current_user:
double
)
expect
(
doc
.
css
(
'a'
).
length
).
to
eq
1
end
def
reference_link
(
data
)
link_to
(
'text'
,
''
,
class:
'gfm'
,
data:
data
)
end
context
'with data-project'
do
it
'removes unpermitted Project references'
do
user
=
create
(
:user
)
project
=
create
(
:empty_project
)
link
=
reference_link
(
project:
project
.
id
,
reference_filter:
Gitlab
::
Markdown
::
ReferenceFilter
.
name
)
doc
=
filter
(
link
,
current_user:
user
)
expect
(
doc
.
css
(
'a'
).
length
).
to
eq
0
end
it
'allows permitted Project references'
do
user
=
create
(
:user
)
project
=
create
(
:empty_project
)
project
.
team
<<
[
user
,
:master
]
link
=
reference_link
(
project:
project
.
id
,
reference_filter:
Gitlab
::
Markdown
::
ReferenceFilter
.
name
)
doc
=
filter
(
link
,
current_user:
user
)
expect
(
doc
.
css
(
'a'
).
length
).
to
eq
1
end
it
'handles invalid Project references'
do
link
=
reference_link
(
project:
12345
,
reference_filter:
Gitlab
::
Markdown
::
ReferenceFilter
.
name
)
expect
{
filter
(
link
)
}.
not_to
raise_error
end
end
context
"for user references"
do
context
'with data-group'
do
it
'removes unpermitted Group references'
do
user
=
create
(
:user
)
group
=
create
(
:group
)
link
=
reference_link
(
group:
group
.
id
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
doc
=
filter
(
link
,
current_user:
user
)
expect
(
doc
.
css
(
'a'
).
length
).
to
eq
0
end
it
'allows permitted Group references'
do
user
=
create
(
:user
)
group
=
create
(
:group
)
group
.
add_developer
(
user
)
link
=
reference_link
(
group:
group
.
id
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
doc
=
filter
(
link
,
current_user:
user
)
expect
(
doc
.
css
(
'a'
).
length
).
to
eq
1
end
it
'handles invalid Group references'
do
link
=
reference_link
(
group:
12345
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
expect
{
filter
(
link
)
}.
not_to
raise_error
end
end
context
'with data-user'
do
it
'allows any User reference'
do
user
=
create
(
:user
)
link
=
reference_link
(
user:
user
.
id
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
doc
=
filter
(
link
)
expect
(
doc
.
css
(
'a'
).
length
).
to
eq
1
end
end
end
end
end
spec/lib/gitlab/markdown/reference_gatherer_filter_spec.rb
0 → 100644
View file @
a62bd121
require
'spec_helper'
module
Gitlab::Markdown
describe
ReferenceGathererFilter
do
include
ActionView
::
Helpers
::
UrlHelper
include
FilterSpecHelper
def
reference_link
(
data
)
link_to
(
'text'
,
''
,
class:
'gfm'
,
data:
data
)
end
context
"for issue references"
do
context
'with data-project'
do
it
'removes unpermitted Project references'
do
user
=
create
(
:user
)
project
=
create
(
:empty_project
)
issue
=
create
(
:issue
,
project:
project
)
link
=
reference_link
(
project:
project
.
id
,
issue:
issue
.
id
,
reference_filter:
Gitlab
::
Markdown
::
IssueReferenceFilter
.
name
)
result
=
pipeline_result
(
link
,
current_user:
user
)
expect
(
result
[
:references
][
:issue
]).
to
be_empty
end
it
'allows permitted Project references'
do
user
=
create
(
:user
)
project
=
create
(
:empty_project
)
issue
=
create
(
:issue
,
project:
project
)
project
.
team
<<
[
user
,
:master
]
link
=
reference_link
(
project:
project
.
id
,
issue:
issue
.
id
,
reference_filter:
Gitlab
::
Markdown
::
IssueReferenceFilter
.
name
)
result
=
pipeline_result
(
link
,
current_user:
user
)
expect
(
result
[
:references
][
:issue
]).
to
eq
([
issue
])
end
it
'handles invalid Project references'
do
link
=
reference_link
(
project:
12345
,
issue:
12345
,
reference_filter:
Gitlab
::
Markdown
::
IssueReferenceFilter
.
name
)
expect
{
pipeline_result
(
link
)
}.
not_to
raise_error
end
end
end
context
"for user references"
do
context
'with data-group'
do
it
'removes unpermitted Group references'
do
user
=
create
(
:user
)
group
=
create
(
:group
)
link
=
reference_link
(
group:
group
.
id
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
result
=
pipeline_result
(
link
,
current_user:
user
)
expect
(
result
[
:references
][
:user
]).
to
be_empty
end
it
'allows permitted Group references'
do
user
=
create
(
:user
)
group
=
create
(
:group
)
group
.
add_developer
(
user
)
link
=
reference_link
(
group:
group
.
id
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
result
=
pipeline_result
(
link
,
current_user:
user
)
expect
(
result
[
:references
][
:user
]).
to
eq
([
user
])
end
it
'handles invalid Group references'
do
link
=
reference_link
(
group:
12345
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
expect
{
pipeline_result
(
link
)
}.
not_to
raise_error
end
end
context
'with data-user'
do
it
'allows any User reference'
do
user
=
create
(
:user
)
link
=
reference_link
(
user:
user
.
id
,
reference_filter:
Gitlab
::
Markdown
::
UserReferenceFilter
.
name
)
result
=
pipeline_result
(
link
)
expect
(
result
[
:references
][
:user
]).
to
eq
([
user
])
end
end
end
end
end
spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
View file @
a62bd121
...
...
@@ -4,7 +4,7 @@ module Gitlab::Markdown
describe
SnippetReferenceFilter
do
include
FilterSpecHelper
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:project
)
{
create
(
:empty_project
,
:public
)
}
let
(
:snippet
)
{
create
(
:project_snippet
,
project:
project
)
}
let
(
:reference
)
{
snippet
.
to_reference
}
...
...
@@ -55,12 +55,20 @@ module Gitlab::Markdown
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'class'
)).
to
eq
'gfm gfm-snippet'
end
it
'includes a data-project
-id
attribute'
do
it
'includes a data-project attribute'
do
doc
=
filter
(
"Snippet
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-project-id'
)
expect
(
link
.
attr
(
'data-project-id'
)).
to
eq
project
.
id
.
to_s
expect
(
link
).
to
have_attribute
(
'data-project'
)
expect
(
link
.
attr
(
'data-project'
)).
to
eq
project
.
id
.
to_s
end
it
'includes a data-snippet attribute'
do
doc
=
filter
(
"See
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-snippet'
)
expect
(
link
.
attr
(
'data-snippet'
)).
to
eq
snippet
.
id
.
to_s
end
it
'supports an :only_path context'
do
...
...
@@ -72,52 +80,38 @@ module Gitlab::Markdown
end
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Snippet
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"Snippet
#{
reference
}
"
)
expect
(
result
[
:references
][
:snippet
]).
to
eq
[
snippet
]
end
end
context
'cross-project reference'
do
let
(
:namespace
)
{
create
(
:namespace
,
name:
'cross-reference'
)
}
let
(
:project2
)
{
create
(
:empty_project
,
namespace:
namespace
)
}
let
(
:project2
)
{
create
(
:empty_project
,
:public
,
namespace:
namespace
)
}
let
(
:snippet
)
{
create
(
:project_snippet
,
project:
project2
)
}
let
(
:reference
)
{
snippet
.
to_reference
(
project
)
}
context
'when user can access reference'
do
before
{
allow_cross_reference!
}
it
'links to a valid reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
namespace_project_snippet_url
(
project2
.
namespace
,
project2
,
snippet
)
end
it
'links with adjacent text'
do
doc
=
filter
(
"See (
#{
reference
}
.)"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
it
'ignores invalid snippet IDs on the referenced project'
do
exp
=
act
=
"See
#{
invalidate_reference
(
reference
)
}
"
it
'links to a valid reference'
do
doc
=
filter
(
"See
#{
reference
}
"
)
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
namespace_project_snippet_url
(
project2
.
namespace
,
project2
,
snippet
)
end
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Snippet
#{
reference
}
"
)
expect
(
result
[
:references
][
:snippet
]).
to
eq
[
snippet
]
end
it
'links with adjacent text'
do
doc
=
filter
(
"See (
#{
reference
}
.)"
)
expect
(
doc
.
to_html
).
to
match
(
/\(<a.+>
#{
Regexp
.
escape
(
reference
)
}
<\/a>\.\)/
)
end
context
'when user cannot access reference
'
do
before
{
disallow_cross_reference!
}
it
'ignores invalid snippet IDs on the referenced project
'
do
exp
=
act
=
"See
#{
invalidate_reference
(
reference
)
}
"
it
'ignores valid references'
do
exp
=
act
=
"See
#{
reference
}
"
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
expect
(
filter
(
act
).
to_html
).
to
eq
exp
end
it
'adds to the results hash'
do
result
=
reference_pipeline_result
(
"Snippet
#{
reference
}
"
)
expect
(
result
[
:references
][
:snippet
]).
to
eq
[
snippet
]
end
end
end
...
...
spec/lib/gitlab/markdown/user_reference_filter_spec.rb
View file @
a62bd121
...
...
@@ -4,7 +4,7 @@ module Gitlab::Markdown
describe
UserReferenceFilter
do
include
FilterSpecHelper
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:project
)
{
create
(
:empty_project
,
:public
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:reference
)
{
user
.
to_reference
}
...
...
@@ -39,7 +39,7 @@ module Gitlab::Markdown
end
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Hey
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"Hey
#{
reference
}
"
)
expect
(
result
[
:references
][
:user
]).
to
eq
[
project
.
creator
]
end
end
...
...
@@ -64,59 +64,40 @@ module Gitlab::Markdown
expect
(
doc
.
css
(
'a'
).
length
).
to
eq
1
end
it
'includes a data-user
-id
attribute'
do
it
'includes a data-user attribute'
do
doc
=
filter
(
"Hey
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
expect
(
link
).
to
have_attribute
(
'data-user
-id
'
)
expect
(
link
.
attr
(
'data-user
-id
'
)).
to
eq
user
.
namespace
.
owner_id
.
to_s
expect
(
link
).
to
have_attribute
(
'data-user'
)
expect
(
link
.
attr
(
'data-user'
)).
to
eq
user
.
namespace
.
owner_id
.
to_s
end
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Hey
#{
reference
}
"
)
result
=
reference_
pipeline_result
(
"Hey
#{
reference
}
"
)
expect
(
result
[
:references
][
:user
]).
to
eq
[
user
]
end
end
context
'mentioning a group'
do
let
(
:group
)
{
create
(
:group
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:reference
)
{
group
.
to_reference
}
context
'that the current user can read'
do
before
do
group
.
add_developer
(
user
)
end
it
'links to the Group'
do
doc
=
filter
(
"Hey
#{
reference
}
"
,
current_user:
user
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
group_url
(
group
)
end
it
'includes a data-group-id attribute'
do
doc
=
filter
(
"Hey
#{
reference
}
"
,
current_user:
user
)
link
=
doc
.
css
(
'a'
).
first
it
'links to the Group'
do
doc
=
filter
(
"Hey
#{
reference
}
"
)
expect
(
doc
.
css
(
'a'
).
first
.
attr
(
'href'
)).
to
eq
urls
.
group_url
(
group
)
end
expect
(
link
).
to
have_attribute
(
'data-group-id'
)
expect
(
link
.
attr
(
'data-group-id'
)).
to
eq
group
.
id
.
to_s
end
it
'includes a data-group attribute'
do
doc
=
filter
(
"Hey
#{
reference
}
"
)
link
=
doc
.
css
(
'a'
).
first
it
'adds to the results hash'
do
result
=
pipeline_result
(
"Hey
#{
reference
}
"
,
current_user:
user
)
expect
(
result
[
:references
][
:user
]).
to
eq
group
.
users
end
expect
(
link
).
to
have_attribute
(
'data-group'
)
expect
(
link
.
attr
(
'data-group'
)).
to
eq
group
.
id
.
to_s
end
context
'that the current user cannot read'
do
it
'ignores references to the Group'
do
doc
=
filter
(
"Hey
#{
reference
}
"
,
current_user:
user
)
expect
(
doc
.
to_html
).
to
eq
"Hey
#{
reference
}
"
end
it
'does not add to the results hash'
do
result
=
pipeline_result
(
"Hey
#{
reference
}
"
,
current_user:
user
)
expect
(
result
[
:references
][
:user
]).
to
eq
[]
end
it
'adds to the results hash'
do
result
=
reference_pipeline_result
(
"Hey
#{
reference
}
"
)
expect
(
result
[
:references
][
:user
]).
to
eq
group
.
users
end
end
...
...
spec/lib/gitlab/reference_extractor_spec.rb
View file @
a62bd121
...
...
@@ -13,7 +13,7 @@ describe Gitlab::ReferenceExtractor do
project
.
team
<<
[
@u_bar
,
:guest
]
subject
.
analyze
(
'@foo, @baduser, @bar, and @offteam'
)
expect
(
subject
.
users
).
to
eq
([
@u_foo
,
@u_bar
,
@u_offteam
])
expect
(
subject
.
users
).
to
match_array
([
@u_foo
,
@u_bar
,
@u_offteam
])
end
it
'ignores user mentions inside specific elements'
do
...
...
@@ -37,7 +37,7 @@ describe Gitlab::ReferenceExtractor do
> @offteam
}
)
expect
(
subject
.
users
).
to
eq
([])
expect
(
subject
.
users
).
to
match_array
([])
end
it
'accesses valid issue objects'
do
...
...
@@ -45,7 +45,7 @@ describe Gitlab::ReferenceExtractor do
@i1
=
create
(
:issue
,
project:
project
)
subject
.
analyze
(
"
#{
@i0
.
to_reference
}
,
#{
@i1
.
to_reference
}
, and
#{
Issue
.
reference_prefix
}
999."
)
expect
(
subject
.
issues
).
to
eq
([
@i0
,
@i1
])
expect
(
subject
.
issues
).
to
match_array
([
@i0
,
@i1
])
end
it
'accesses valid merge requests'
do
...
...
@@ -53,7 +53,7 @@ describe Gitlab::ReferenceExtractor do
@m1
=
create
(
:merge_request
,
source_project:
project
,
target_project:
project
,
source_branch:
'feature_conflict'
)
subject
.
analyze
(
"!999, !
#{
@m1
.
iid
}
, and !
#{
@m0
.
iid
}
."
)
expect
(
subject
.
merge_requests
).
to
eq
([
@m1
,
@m0
])
expect
(
subject
.
merge_requests
).
to
match_array
([
@m1
,
@m0
])
end
it
'accesses valid labels'
do
...
...
@@ -62,7 +62,7 @@ describe Gitlab::ReferenceExtractor do
@l2
=
create
(
:label
)
subject
.
analyze
(
"~
#{
@l0
.
id
}
, ~999, ~
#{
@l2
.
id
}
, ~
#{
@l1
.
id
}
"
)
expect
(
subject
.
labels
).
to
eq
([
@l0
,
@l1
])
expect
(
subject
.
labels
).
to
match_array
([
@l0
,
@l1
])
end
it
'accesses valid snippets'
do
...
...
@@ -71,7 +71,7 @@ describe Gitlab::ReferenceExtractor do
@s2
=
create
(
:project_snippet
)
subject
.
analyze
(
"$
#{
@s0
.
id
}
, $999, $
#{
@s2
.
id
}
, $
#{
@s1
.
id
}
"
)
expect
(
subject
.
snippets
).
to
eq
([
@s0
,
@s1
])
expect
(
subject
.
snippets
).
to
match_array
([
@s0
,
@s1
])
end
it
'accesses valid commits'
do
...
...
@@ -109,7 +109,7 @@ describe Gitlab::ReferenceExtractor do
subject
.
analyze
(
"this refers issue
#{
issue
.
to_reference
(
project
)
}
"
)
extracted
=
subject
.
issues
expect
(
extracted
.
size
).
to
eq
(
1
)
expect
(
extracted
).
to
eq
([
issue
])
expect
(
extracted
).
to
match_array
([
issue
])
end
end
end
spec/support/filter_spec_helper.rb
View file @
a62bd121
...
...
@@ -29,12 +29,19 @@ module FilterSpecHelper
#
# Returns the Hash
def
pipeline_result
(
body
,
contexts
=
{})
contexts
.
reverse_merge!
(
project:
project
)
contexts
.
reverse_merge!
(
project:
project
)
if
defined?
(
project
)
pipeline
=
HTML
::
Pipeline
.
new
([
described_class
],
contexts
)
pipeline
.
call
(
body
)
end
def
reference_pipeline_result
(
body
,
contexts
=
{})
contexts
.
reverse_merge!
(
project:
project
)
if
defined?
(
project
)
pipeline
=
HTML
::
Pipeline
.
new
([
described_class
,
Gitlab
::
Markdown
::
ReferenceGathererFilter
],
contexts
)
pipeline
.
call
(
body
)
end
# Modify a String reference to make it invalid
#
# Commit SHAs get reversed, IDs get incremented by 1, all other Strings get
...
...
@@ -55,20 +62,6 @@ module FilterSpecHelper
end
end
# Stub CrossProjectReference#user_can_reference_project? to return true for
# the current test
def
allow_cross_reference!
allow_any_instance_of
(
described_class
).
to
receive
(
:user_can_reference_project?
).
and_return
(
true
)
end
# Stub CrossProjectReference#user_can_reference_project? to return false for
# the current test
def
disallow_cross_reference!
allow_any_instance_of
(
described_class
).
to
receive
(
:user_can_reference_project?
).
and_return
(
false
)
end
# Shortcut to Rails' auto-generated routes helpers, to avoid including the
# module
def
urls
...
...
spec/support/markdown_feature.rb
View file @
a62bd121
...
...
@@ -15,18 +15,17 @@ class MarkdownFeature
end
def
group
unless
@group
@group
=
create
(
:group
)
@group
.
add_developer
(
user
)
@group
||=
create
(
:group
).
tap
do
|
group
|
group
.
add_developer
(
user
)
end
@group
end
# Direct references ----------------------------------------------------------
def
project
@project
||=
create
(
:project
)
@project
||=
create
(
:project
).
tap
do
|
project
|
project
.
team
<<
[
user
,
:master
]
end
end
def
issue
...
...
@@ -46,12 +45,10 @@ class MarkdownFeature
end
def
commit_range
unless
@commit_range
@commit_range
||=
begin
commit2
=
project
.
commit
(
'HEAD~3'
)
@commit_range
=
CommitRange
.
new
(
"
#{
commit
.
id
}
...
#{
commit2
.
id
}
"
,
project
)
CommitRange
.
new
(
"
#{
commit
.
id
}
...
#{
commit2
.
id
}
"
,
project
)
end
@commit_range
end
def
simple_label
...
...
@@ -65,13 +62,12 @@ class MarkdownFeature
# Cross-references -----------------------------------------------------------
def
xproject
unless
@xproject
@xproject
||=
begin
namespace
=
create
(
:namespace
,
name:
'cross-reference'
)
@xproject
=
create
(
:project
,
namespace:
namespace
)
@xproject
.
team
<<
[
user
,
:developer
]
create
(
:project
,
namespace:
namespace
)
do
|
project
|
project
.
team
<<
[
user
,
:developer
]
end
end
@xproject
end
def
xissue
...
...
@@ -91,12 +87,10 @@ class MarkdownFeature
end
def
xcommit_range
unless
@xcommit_range
@xcommit_range
||=
begin
xcommit2
=
xproject
.
commit
(
'HEAD~2'
)
@xcommit_range
=
CommitRange
.
new
(
"
#{
xcommit
.
id
}
...
#{
xcommit2
.
id
}
"
,
xproject
)
CommitRange
.
new
(
"
#{
xcommit
.
id
}
...
#{
xcommit2
.
id
}
"
,
xproject
)
end
@xcommit_range
end
def
raw_markdown
...
...
spec/support/mentionable_shared_examples.rb
View file @
a62bd121
...
...
@@ -50,6 +50,8 @@ def common_mentionable_setup
}
extra_commits
.
each
{
|
c
|
commitmap
[
c
.
short_id
]
=
c
}
allow
(
Project
).
to
receive
(
:find
).
and_call_original
allow
(
Project
).
to
receive
(
:find
).
with
(
project
.
id
.
to_s
).
and_return
(
project
)
allow
(
project
.
repository
).
to
receive
(
:commit
)
{
|
sha
|
commitmap
[
sha
]
}
set_mentionable_text
.
call
(
ref_string
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment