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
94b93e49
Commit
94b93e49
authored
Apr 27, 2017
by
Phil Hughes
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into emoji-button-titles
parents
429a42b0
4d4aefc5
Changes
54
Hide whitespace changes
Inline
Side-by-side
Showing
54 changed files
with
642 additions
and
438 deletions
+642
-438
.gitlab/issue_templates/Bug.md
.gitlab/issue_templates/Bug.md
+4
-0
Gemfile.lock
Gemfile.lock
+1
-1
app/assets/javascripts/commit/pipelines/pipelines_table.js
app/assets/javascripts/commit/pipelines/pipelines_table.js
+0
-9
app/assets/javascripts/environments/components/environment.vue
...ssets/javascripts/environments/components/environment.vue
+84
-69
app/assets/javascripts/environments/environments_bundle.js
app/assets/javascripts/environments/environments_bundle.js
+9
-12
app/assets/javascripts/environments/folder/environments_folder_bundle.js
...scripts/environments/folder/environments_folder_bundle.js
+9
-12
app/assets/javascripts/environments/folder/environments_folder_view.vue
...ascripts/environments/folder/environments_folder_view.vue
+58
-46
app/assets/javascripts/pipelines/components/time_ago.js
app/assets/javascripts/pipelines/components/time_ago.js
+64
-37
app/assets/javascripts/pipelines/pipelines.js
app/assets/javascripts/pipelines/pipelines.js
+0
-10
app/assets/javascripts/pipelines/stores/pipelines_store.js
app/assets/javascripts/pipelines/stores/pipelines_store.js
+0
-31
app/assets/javascripts/vue_realtime_listener/index.js
app/assets/javascripts/vue_realtime_listener/index.js
+0
-9
app/assets/javascripts/vue_shared/components/pipelines_table_row.js
.../javascripts/vue_shared/components/pipelines_table_row.js
+29
-2
app/helpers/application_helper.rb
app/helpers/application_helper.rb
+0
-32
app/helpers/markup_helper.rb
app/helpers/markup_helper.rb
+86
-51
app/helpers/tree_helper.rb
app/helpers/tree_helper.rb
+0
-4
app/mailers/base_mailer.rb
app/mailers/base_mailer.rb
+1
-1
app/models/application_setting.rb
app/models/application_setting.rb
+9
-0
app/models/network/graph.rb
app/models/network/graph.rb
+2
-1
app/models/repository.rb
app/models/repository.rb
+9
-5
app/services/projects/create_service.rb
app/services/projects/create_service.rb
+2
-1
app/views/projects/_readme.html.haml
app/views/projects/_readme.html.haml
+1
-2
app/views/projects/blob/_markup.html.haml
app/views/projects/blob/_markup.html.haml
+1
-1
app/views/projects/blob/preview.html.haml
app/views/projects/blob/preview.html.haml
+2
-6
app/views/projects/tree/_readme.html.haml
app/views/projects/tree/_readme.html.haml
+1
-1
app/views/search/results/_snippet_blob.html.haml
app/views/search/results/_snippet_blob.html.haml
+1
-1
app/views/shared/snippets/_blob.html.haml
app/views/shared/snippets/_blob.html.haml
+1
-1
changelogs/unreleased/2246-uuid-is-nil-for-new-installation.yml
...logs/unreleased/2246-uuid-is-nil-for-new-installation.yml
+4
-0
changelogs/unreleased/26585-remove-readme-view-caching.yml
changelogs/unreleased/26585-remove-readme-view-caching.yml
+4
-0
changelogs/unreleased/29505-allow-admins-sudo-to-blocked-users.yml
...s/unreleased/29505-allow-admins-sudo-to-blocked-users.yml
+4
-0
changelogs/unreleased/30973-fix-network-graph-ordering.yml
changelogs/unreleased/30973-fix-network-graph-ordering.yml
+4
-0
changelogs/unreleased/tc-make-user-master-project-by-admin.yml
...elogs/unreleased/tc-make-user-master-project-by-admin.yml
+4
-0
db/migrate/20170426175636_fill_missing_uuid_on_application_settings.rb
...170426175636_fill_missing_uuid_on_application_settings.rb
+10
-0
db/schema.rb
db/schema.rb
+1
-1
lib/api/helpers.rb
lib/api/helpers.rb
+1
-1
lib/gitlab/asciidoc.rb
lib/gitlab/asciidoc.rb
+4
-16
lib/gitlab/git/repository.rb
lib/gitlab/git/repository.rb
+17
-6
lib/gitlab/other_markup.rb
lib/gitlab/other_markup.rb
+1
-9
spec/features/admin/admin_cohorts_spec.rb
spec/features/admin/admin_cohorts_spec.rb
+15
-0
spec/features/copy_as_gfm_spec.rb
spec/features/copy_as_gfm_spec.rb
+1
-1
spec/features/markdown_spec.rb
spec/features/markdown_spec.rb
+1
-1
spec/helpers/application_helper_spec.rb
spec/helpers/application_helper_spec.rb
+0
-27
spec/helpers/markup_helper_spec.rb
spec/helpers/markup_helper_spec.rb
+26
-5
spec/javascripts/environments/environment_spec.js
spec/javascripts/environments/environment_spec.js
+4
-1
spec/javascripts/environments/folder/environments_folder_view_spec.js
...ipts/environments/folder/environments_folder_view_spec.js
+3
-1
spec/javascripts/pipelines/time_ago_spec.js
spec/javascripts/pipelines/time_ago_spec.js
+64
-0
spec/lib/gitlab/asciidoc_spec.rb
spec/lib/gitlab/asciidoc_spec.rb
+2
-19
spec/lib/gitlab/git/repository_spec.rb
spec/lib/gitlab/git/repository_spec.rb
+29
-0
spec/lib/gitlab/other_markup_spec.rb
spec/lib/gitlab/other_markup_spec.rb
+1
-1
spec/models/application_setting_spec.rb
spec/models/application_setting_spec.rb
+1
-0
spec/models/network/graph_spec.rb
spec/models/network/graph_spec.rb
+21
-0
spec/models/repository_spec.rb
spec/models/repository_spec.rb
+2
-2
spec/requests/api/helpers_spec.rb
spec/requests/api/helpers_spec.rb
+27
-1
spec/services/projects/create_service_spec.rb
spec/services/projects/create_service_spec.rb
+16
-0
spec/services/system_note_service_spec.rb
spec/services/system_note_service_spec.rb
+1
-1
No files found.
.gitlab/issue_templates/Bug.md
View file @
94b93e49
...
...
@@ -26,6 +26,7 @@ logs, and code as it's very hard to read otherwise.)
#### Results of GitLab environment info
<details>
<pre>
(For installations with omnibus-gitlab package run and paste the output of:
`sudo gitlab-rake gitlab:env:info`
)
...
...
@@ -33,11 +34,13 @@ logs, and code as it's very hard to read otherwise.)
(For installations from source run and paste the output of:
`sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production`
)
</pre>
</details>
#### Results of GitLab application Check
<details>
<pre>
(For installations with omnibus-gitlab package run and paste the output of:
`sudo gitlab-rake gitlab:check SANITIZE=true`
)
...
...
@@ -47,6 +50,7 @@ logs, and code as it's very hard to read otherwise.)
(we will only investigate if the tests are passing)
</pre>
</details>
### Possible fixes
...
...
Gemfile.lock
View file @
94b93e49
...
...
@@ -429,7 +429,7 @@ GEM
multi_json (~> 1.10)
loofah (2.0.3)
nokogiri (>= 1.5.9)
mail (2.6.
4
)
mail (2.6.
5
)
mime-types (>= 1.16, < 4)
mail_room (0.9.1)
memoist (0.15.0)
...
...
app/assets/javascripts/commit/pipelines/pipelines_table.js
View file @
94b93e49
...
...
@@ -106,15 +106,6 @@ export default Vue.component('pipelines-table', {
eventHub
.
$on
(
'
refreshPipelines
'
,
this
.
fetchPipelines
);
},
beforeUpdate
()
{
if
(
this
.
state
.
pipelines
.
length
&&
this
.
$children
&&
!
this
.
isMakingRequest
&&
!
this
.
isLoading
)
{
this
.
store
.
startTimeAgoLoops
.
call
(
this
,
Vue
);
}
},
beforeDestroyed
()
{
eventHub
.
$off
(
'
refreshPipelines
'
);
},
...
...
app/assets/javascripts/environments/components/environment.
js
→
app/assets/javascripts/environments/components/environment.
vue
View file @
94b93e49
<
script
>
/* eslint-disable no-new */
/* global Flash */
import
Vue
from
'
vue
'
;
import
EnvironmentsService
from
'
../services/environments_service
'
;
import
EnvironmentTable
from
'
./environments_table.vue
'
;
import
EnvironmentsStore
from
'
../stores/environments_store
'
;
...
...
@@ -8,7 +9,7 @@ import TablePaginationComponent from '../../vue_shared/components/table_paginati
import
'
../../lib/utils/common_utils
'
;
import
eventHub
from
'
../event_hub
'
;
export
default
Vue
.
component
(
'
environment-component
'
,
{
export
default
{
components
:
{
'
environment-table
'
:
EnvironmentTable
,
...
...
@@ -140,76 +141,90 @@ export default Vue.component('environment-component', {
});
},
},
template
:
`
<div :class="cssContainerClass">
<div class="top-area">
<ul v-if="!isLoading" class="nav-links">
<li v-bind:class="{ 'active': scope === null || scope === 'available' }">
<a :href="projectEnvironmentsPath">
Available
<span class="badge js-available-environments-count">
{{state.availableCounter}}
</span>
</a>
</li>
<li v-bind:class="{ 'active' : scope === 'stopped' }">
<a :href="projectStoppedEnvironmentsPath">
Stopped
<span class="badge js-stopped-environments-count">
{{state.stoppedCounter}}
</span>
</a>
</li>
</ul>
<div v-if="canCreateEnvironmentParsed && !isLoading" class="nav-controls">
<a :href="newEnvironmentPath" class="btn btn-create">
New environment
};
</
script
>
<
template
>
<div
:class=
"cssContainerClass"
>
<div
class=
"top-area"
>
<ul
v-if=
"!isLoading"
class=
"nav-links"
>
<li
:class=
"
{ active: scope === null || scope === 'available' }">
<a
:href=
"projectEnvironmentsPath"
>
Available
<span
class=
"badge js-available-environments-count"
>
{{
state
.
availableCounter
}}
</span>
</a>
</li>
<li
:class=
"
{ active : scope === 'stopped' }">
<a
:href=
"projectStoppedEnvironmentsPath"
>
Stopped
<span
class=
"badge js-stopped-environments-count"
>
{{
state
.
stoppedCounter
}}
</span>
</a>
</div>
</li>
</ul>
<div
v-if=
"canCreateEnvironmentParsed && !isLoading"
class=
"nav-controls"
>
<a
:href=
"newEnvironmentPath"
class=
"btn btn-create"
>
New environment
</a>
</div>
</div>
<div
class=
"content-list environments-container"
>
<div
class=
"environments-list-loading text-center"
v-if=
"isLoading"
>
<div class="content-list environments-container">
<div class="environments-list-loading text-center" v-if="isLoading">
<i class="fa fa-spinner fa-spin" aria-hidden="true"></i>
</div>
<div class="blank-state blank-state-no-icon"
v-if="!isLoading && state.environments.length === 0">
<h2 class="blank-state-title js-blank-state-title">
You don't have any environments right now.
</h2>
<p class="blank-state-text">
Environments are places where code gets deployed, such as staging or production.
<br />
<a :href="helpPagePath">
Read more about environments
</a>
</p>
<a v-if="canCreateEnvironmentParsed"
:href="newEnvironmentPath"
class="btn btn-create js-new-environment-button">
New Environment
<i
class=
"fa fa-spinner fa-spin"
aria-hidden=
"true"
/>
</div>
<div
class=
"blank-state blank-state-no-icon"
v-if=
"!isLoading && state.environments.length === 0"
>
<h2
class=
"blank-state-title js-blank-state-title"
>
You don't have any environments right now.
</h2>
<p
class=
"blank-state-text"
>
Environments are places where code gets deployed, such as staging or production.
<br
/>
<a
:href=
"helpPagePath"
>
Read more about environments
</a>
</div>
<div class="table-holder"
v-if="!isLoading && state.environments.length > 0">
<environment-table
:environments="state.environments"
:can-create-deployment="canCreateDeploymentParsed"
:can-read-environment="canReadEnvironmentParsed"
:service="service"
:is-loading-folder-content="isLoadingFolderContent" />
</div>
<table-pagination v-if="state.paginationInformation && state.paginationInformation.totalPages > 1"
:change="changePage"
:pageInfo="state.paginationInformation">
</table-pagination>
</p>
<a
v-if=
"canCreateEnvironmentParsed"
:href=
"newEnvironmentPath"
class=
"btn btn-create js-new-environment-button"
>
New Environment
</a>
</div>
<div
class=
"table-holder"
v-if=
"!isLoading && state.environments.length > 0"
>
<environment-table
:environments=
"state.environments"
:can-create-deployment=
"canCreateDeploymentParsed"
:can-read-environment=
"canReadEnvironmentParsed"
:service=
"service"
:is-loading-folder-content=
"isLoadingFolderContent"
/>
</div>
<table-pagination
v-if=
"state.paginationInformation && state.paginationInformation.totalPages > 1"
:change=
"changePage"
:pageInfo=
"state.paginationInformation"
/>
</div>
`
,
});
</div>
</
template
>
app/assets/javascripts/environments/environments_bundle.js
View file @
94b93e49
import
EnvironmentsComponent
from
'
./components/environment
'
;
import
Vue
from
'
vue
'
;
import
EnvironmentsComponent
from
'
./components/environment.vue
'
;
$
(()
=>
{
window
.
gl
=
window
.
gl
||
{};
if
(
gl
.
EnvironmentsListApp
)
{
gl
.
EnvironmentsListApp
.
$destroy
(
true
);
}
gl
.
EnvironmentsListApp
=
new
EnvironmentsComponent
({
el
:
document
.
querySelector
(
'
#environments-list-view
'
),
});
});
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
new
Vue
({
el
:
'
#environments-list-view
'
,
components
:
{
'
environments-table-app
'
:
EnvironmentsComponent
,
},
render
:
createElement
=>
createElement
(
'
environments-table-app
'
),
}));
app/assets/javascripts/environments/folder/environments_folder_bundle.js
View file @
94b93e49
import
EnvironmentsFolderComponent
from
'
./environments_folder_view
'
;
import
Vue
from
'
vue
'
;
import
EnvironmentsFolderComponent
from
'
./environments_folder_view.vue
'
;
$
(()
=>
{
window
.
gl
=
window
.
gl
||
{};
if
(
gl
.
EnvironmentsListFolderApp
)
{
gl
.
EnvironmentsListFolderApp
.
$destroy
(
true
);
}
gl
.
EnvironmentsListFolderApp
=
new
EnvironmentsFolderComponent
({
el
:
document
.
querySelector
(
'
#environments-folder-list-view
'
),
});
});
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
new
Vue
({
el
:
'
#environments-folder-list-view
'
,
components
:
{
'
environments-folder-app
'
:
EnvironmentsFolderComponent
,
},
render
:
createElement
=>
createElement
(
'
environments-folder-app
'
),
}));
app/assets/javascripts/environments/folder/environments_folder_view.
js
→
app/assets/javascripts/environments/folder/environments_folder_view.
vue
View file @
94b93e49
<
script
>
/* eslint-disable no-new */
/* global Flash */
import
Vue
from
'
vue
'
;
import
EnvironmentsService
from
'
../services/environments_service
'
;
import
EnvironmentTable
from
'
../components/environments_table.vue
'
;
import
EnvironmentsStore
from
'
../stores/environments_store
'
;
...
...
@@ -8,7 +8,7 @@ import TablePaginationComponent from '../../vue_shared/components/table_paginati
import
'
../../lib/utils/common_utils
'
;
import
'
../../vue_shared/vue_resource_interceptor
'
;
export
default
Vue
.
component
(
'
environment-folder-view
'
,
{
export
default
{
components
:
{
'
environment-table
'
:
EnvironmentTable
,
'
table-pagination
'
:
TablePaginationComponent
,
...
...
@@ -116,54 +116,66 @@ export default Vue.component('environment-folder-view', {
return
param
;
},
},
};
</
script
>
<
template
>
<div
:class=
"cssContainerClass"
>
<div
class=
"top-area"
v-if=
"!isLoading"
>
<h4
class=
"js-folder-name environments-folder-name"
>
Environments /
<b>
{{
folderName
}}
</b>
</h4>
<ul
class=
"nav-links"
>
<li
:class=
"
{ active: scope === null || scope === 'available' }">
<a
:href=
"availablePath"
class=
"js-available-environments-folder-tab"
>
Available
<span
class=
"badge js-available-environments-count"
>
{{
state
.
availableCounter
}}
</span>
</a>
</li>
<li
:class=
"
{ active : scope === 'stopped' }">
<a
:href=
"stoppedPath"
class=
"js-stopped-environments-folder-tab"
>
Stopped
<span
class=
"badge js-stopped-environments-count"
>
{{
state
.
stoppedCounter
}}
</span>
</a>
</li>
</ul>
</div>
template
:
`
<div :class="cssContainerClass">
<div class="top-area" v-if="!isLoading">
<h4 class="js-folder-name environments-folder-name">
Environments / <b>{{folderName}}</b>
</h4>
<ul class="nav-links">
<li v-bind:class="{ 'active': scope === null || scope === 'available' }">
<a :href="availablePath" class="js-available-environments-folder-tab">
Available
<span class="badge js-available-environments-count">
{{state.availableCounter}}
</span>
</a>
</li>
<li v-bind:class="{ 'active' : scope === 'stopped' }">
<a :href="stoppedPath" class="js-stopped-environments-folder-tab">
Stopped
<span class="badge js-stopped-environments-count">
{{state.stoppedCounter}}
</span>
</a>
</li>
</ul>
<div
class=
"environments-container"
>
<div
class=
"environments-list-loading text-center"
v-if=
"isLoading"
>
<i
class=
"fa fa-spinner fa-spin"
aria-hidden=
"true"
/>
</div>
<div class="environments-container">
<div class="environments-list-loading text-center" v-if="isLoading">
<i class="fa fa-spinner fa-spin"></i>
</div>
<div class="table-holder"
v-if="!isLoading && state.environments.length > 0">
<div
class=
"table-holder"
v-if=
"!isLoading && state.environments.length > 0"
>
<environment-table
:environments="state.environments"
:can-create-deployment="canCreateDeploymentParsed"
:can-read-environment="canReadEnvironmentParsed"
:service="service"/>
<environment-table
:environments=
"state.environments"
:can-create-deployment=
"canCreateDeploymentParsed"
:can-read-environment=
"canReadEnvironmentParsed"
:service=
"service"
/>
<table-pagination v-if="state.paginationInformation && state.paginationInformation.totalPages > 1"
:change="changePage
"
:pageInfo="state.paginationInformation"/>
</div
>
<table-pagination
v-if=
"state.paginationInformation && state.paginationInformation.totalPages > 1
"
:change=
"changePage"
:pageInfo=
"state.paginationInformation"
/
>
</div>
</div>
`
,
});
</div>
</
template
>
app/assets/javascripts/pipelines/components/time_ago.js
View file @
94b93e49
...
...
@@ -2,68 +2,95 @@ import iconTimerSvg from 'icons/_icon_timer.svg';
import
'
../../lib/utils/datetime_utility
'
;
export
default
{
props
:
{
finishedTime
:
{
type
:
String
,
required
:
true
,
},
duration
:
{
type
:
Number
,
required
:
true
,
},
},
data
()
{
return
{
currentTime
:
new
Date
(),
iconTimerSvg
,
};
},
props
:
[
'
pipeline
'
],
updated
()
{
$
(
this
.
$refs
.
tooltip
).
tooltip
(
'
fixTitle
'
);
},
computed
:
{
timeAgo
()
{
return
gl
.
utils
.
getTimeago
()
;
hasDuration
()
{
return
this
.
duration
>
0
;
},
localTimeFinished
()
{
return
gl
.
utils
.
formatDate
(
this
.
pipeline
.
details
.
finished_at
);
hasFinishedTime
()
{
return
this
.
finishedTime
!==
''
;
},
timeStopped
()
{
const
changeTime
=
this
.
currentTime
;
const
options
=
{
weekday
:
'
long
'
,
year
:
'
numeric
'
,
month
:
'
short
'
,
day
:
'
numeric
'
,
};
options
.
timeZoneName
=
'
short
'
;
const
finished
=
this
.
pipeline
.
details
.
finished_at
;
if
(
!
finished
&&
changeTime
)
return
false
;
return
({
words
:
this
.
timeAgo
.
format
(
finished
)
});
localTimeFinished
()
{
return
gl
.
utils
.
formatDate
(
this
.
finishedTime
);
},
duration
()
{
const
{
duration
}
=
this
.
pipeline
.
details
;
const
date
=
new
Date
(
duration
*
1000
);
durationFormated
()
{
const
date
=
new
Date
(
this
.
duration
*
1000
);
let
hh
=
date
.
getUTCHours
();
let
mm
=
date
.
getUTCMinutes
();
let
ss
=
date
.
getSeconds
();
if
(
hh
<
10
)
hh
=
`0
${
hh
}
`
;
if
(
mm
<
10
)
mm
=
`0
${
mm
}
`
;
if
(
ss
<
10
)
ss
=
`0
${
ss
}
`
;
// left pad
if
(
hh
<
10
)
{
hh
=
`0
${
hh
}
`
;
}
if
(
mm
<
10
)
{
mm
=
`0
${
mm
}
`
;
}
if
(
ss
<
10
)
{
ss
=
`0
${
ss
}
`
;
}
if
(
duration
!==
null
)
return
`
${
hh
}
:
${
mm
}
:
${
ss
}
`
;
return
false
;
return
`
${
hh
}
:
${
mm
}
:
${
ss
}
`
;
},
},
methods
:
{
changeTime
()
{
this
.
currentTime
=
new
Date
();
finishedTimeFormated
()
{
const
timeAgo
=
gl
.
utils
.
getTimeago
();
return
timeAgo
.
format
(
this
.
finishedTime
);
},
},
template
:
`
<td class="pipelines-time-ago">
<p class="duration" v-if='duration'>
<span v-html="iconTimerSvg"></span>
{{duration}}
<p
class="duration"
v-if="hasDuration">
<span
v-html="iconTimerSvg">
</span>
{{durationFormated}}
</p>
<p class="finished-at" v-if='timeStopped'>
<i class="fa fa-calendar"></i>
<p
class="finished-at"
v-if="hasFinishedTime">
<i
class="fa fa-calendar"
aria-hidden="true" />
<time
ref="tooltip"
data-toggle="tooltip"
data-placement="top"
data-container="body"
:
data-original-title='localTimeFinished'
>
{{
timeStopped.words
}}
:
title="localTimeFinished"
>
{{
finishedTimeFormated
}}
</time>
</p>
</td>
...
...
app/assets/javascripts/pipelines/pipelines.js
View file @
94b93e49
import
Vue
from
'
vue
'
;
import
Visibility
from
'
visibilityjs
'
;
import
PipelinesService
from
'
./services/pipelines_service
'
;
import
eventHub
from
'
./event_hub
'
;
...
...
@@ -161,15 +160,6 @@ export default {
eventHub
.
$on
(
'
refreshPipelines
'
,
this
.
fetchPipelines
);
},
beforeUpdate
()
{
if
(
this
.
state
.
pipelines
.
length
&&
this
.
$children
&&
!
this
.
isMakingRequest
&&
!
this
.
isLoading
)
{
this
.
store
.
startTimeAgoLoops
.
call
(
this
,
Vue
);
}
},
beforeDestroyed
()
{
eventHub
.
$off
(
'
refreshPipelines
'
);
},
...
...
app/assets/javascripts/pipelines/stores/pipelines_store.js
View file @
94b93e49
/* eslint-disable no-underscore-dangle*/
import
VueRealtimeListener
from
'
../../vue_realtime_listener
'
;
export
default
class
PipelinesStore
{
constructor
()
{
this
.
state
=
{};
...
...
@@ -30,32 +27,4 @@ export default class PipelinesStore {
this
.
state
.
pageInfo
=
paginationInfo
;
}
/**
* FIXME: Move this inside the component.
*
* Once the data is received we will start the time ago loops.
*
* Everytime a request is made like retry or cancel a pipeline, every 10 seconds we
* update the time to show how long as passed.
*
*/
startTimeAgoLoops
()
{
const
startTimeLoops
=
()
=>
{
this
.
timeLoopInterval
=
setInterval
(()
=>
{
this
.
$children
[
0
].
$children
.
reduce
((
acc
,
component
)
=>
{
const
timeAgoComponent
=
component
.
$children
.
filter
(
el
=>
el
.
$options
.
_componentTag
===
'
time-ago
'
)[
0
];
acc
.
push
(
timeAgoComponent
);
return
acc
;
},
[]).
forEach
(
e
=>
e
.
changeTime
());
},
10000
);
};
startTimeLoops
();
const
removeIntervals
=
()
=>
clearInterval
(
this
.
timeLoopInterval
);
const
startIntervals
=
()
=>
startTimeLoops
();
VueRealtimeListener
(
removeIntervals
,
startIntervals
);
}
}
app/assets/javascripts/vue_realtime_listener/index.js
deleted
100644 → 0
View file @
429a42b0
export
default
(
removeIntervals
,
startIntervals
)
=>
{
window
.
removeEventListener
(
'
focus
'
,
startIntervals
);
window
.
removeEventListener
(
'
blur
'
,
removeIntervals
);
window
.
removeEventListener
(
'
onbeforeload
'
,
removeIntervals
);
window
.
addEventListener
(
'
focus
'
,
startIntervals
);
window
.
addEventListener
(
'
blur
'
,
removeIntervals
);
window
.
addEventListener
(
'
onbeforeload
'
,
removeIntervals
);
};
app/assets/javascripts/vue_shared/components/pipelines_table_row.js
View file @
94b93e49
/* eslint-disable no-param-reassign */
import
AsyncButtonComponent
from
'
../../pipelines/components/async_button.vue
'
;
import
PipelinesActionsComponent
from
'
../../pipelines/components/pipelines_actions
'
;
import
PipelinesArtifactsComponent
from
'
../../pipelines/components/pipelines_artifacts
'
;
...
...
@@ -166,6 +165,32 @@ export default {
}
return
undefined
;
},
/**
* Timeago components expects a number
*
* @return {type} description
*/
pipelineDuration
()
{
if
(
this
.
pipeline
.
details
&&
this
.
pipeline
.
details
.
duration
)
{
return
this
.
pipeline
.
details
.
duration
;
}
return
0
;
},
/**
* Timeago component expects a String.
*
* @return {String}
*/
pipelineFinishedAt
()
{
if
(
this
.
pipeline
.
details
&&
this
.
pipeline
.
details
.
finished_at
)
{
return
this
.
pipeline
.
details
.
finished_at
;
}
return
''
;
},
},
template
:
`
...
...
@@ -192,7 +217,9 @@ export default {
</div>
</td>
<time-ago :pipeline="pipeline"/>
<time-ago
:duration="pipelineDuration"
:finished-time="pipelineFinishedAt" />
<td class="pipeline-actions">
<div class="pull-right btn-group">
...
...
app/helpers/application_helper.rb
View file @
94b93e49
...
...
@@ -196,38 +196,6 @@ module ApplicationHelper
end
end
def
render_markup
(
file_name
,
file_content
)
if
gitlab_markdown?
(
file_name
)
Hamlit
::
RailsHelpers
.
preserve
(
markdown
(
file_content
))
elsif
asciidoc?
(
file_name
)
asciidoc
(
file_content
)
elsif
plain?
(
file_name
)
content_tag
:pre
,
class:
'plain-readme'
do
file_content
end
else
other_markup
(
file_name
,
file_content
)
end
rescue
RuntimeError
simple_format
(
file_content
)
end
def
plain?
(
filename
)
Gitlab
::
MarkupHelper
.
plain?
(
filename
)
end
def
markup?
(
filename
)
Gitlab
::
MarkupHelper
.
markup?
(
filename
)
end
def
gitlab_markdown?
(
filename
)
Gitlab
::
MarkupHelper
.
gitlab_markdown?
(
filename
)
end
def
asciidoc?
(
filename
)
Gitlab
::
MarkupHelper
.
asciidoc?
(
filename
)
end
def
promo_host
'about.gitlab.com'
end
...
...
app/helpers/
gitlab_markdown
_helper.rb
→
app/helpers/
markup
_helper.rb
View file @
94b93e49
require
'nokogiri'
module
GitlabMarkdownHelper
module
MarkupHelper
def
plain?
(
filename
)
Gitlab
::
MarkupHelper
.
plain?
(
filename
)
end
def
markup?
(
filename
)
Gitlab
::
MarkupHelper
.
markup?
(
filename
)
end
def
gitlab_markdown?
(
filename
)
Gitlab
::
MarkupHelper
.
gitlab_markdown?
(
filename
)
end
def
asciidoc?
(
filename
)
Gitlab
::
MarkupHelper
.
asciidoc?
(
filename
)
end
# Use this in places where you would normally use link_to(gfm(...), ...).
#
# It solves a problem occurring with nested links (i.e.
...
...
@@ -11,7 +27,7 @@ module GitlabMarkdownHelper
# explicitly produce the correct linking behavior (i.e.
# "<a>outer text </a><a>gfm ref</a><a> more outer text</a>").
def
link_to_gfm
(
body
,
url
,
html_options
=
{})
return
""
if
body
.
blank?
return
''
if
body
.
blank?
context
=
{
project:
@project
,
...
...
@@ -43,71 +59,73 @@ module GitlabMarkdownHelper
fragment
.
to_html
.
html_safe
end
# Return the first line of +text+, up to +max_chars+, after parsing the line
# as Markdown. HTML tags in the parsed output are not counted toward the
# +max_chars+ limit. If the length limit falls within a tag's contents, then
# the tag contents are truncated without removing the closing tag.
def
first_line_in_markdown
(
text
,
max_chars
=
nil
,
options
=
{})
md
=
markdown
(
text
,
options
).
strip
truncate_visible
(
md
,
max_chars
||
md
.
length
)
if
md
.
present?
end
def
markdown
(
text
,
context
=
{})
return
""
unless
text
.
present?
return
''
unless
text
.
present?
context
[
:project
]
||=
@project
html
=
Banzai
.
render
(
text
,
context
)
html
=
markdown_unsafe
(
text
,
context
)
banzai_postprocess
(
html
,
context
)
end
def
markdown_field
(
object
,
field
)
object
=
object
.
for_display
if
object
.
respond_to?
(
:for_display
)
return
""
unless
object
.
present?
return
''
unless
object
.
present?
html
=
Banzai
.
render_field
(
object
,
field
)
banzai_postprocess
(
html
,
object
.
banzai_render_context
(
field
))
end
def
asciidoc
(
text
)
Gitlab
::
Asciidoc
.
render
(
text
,
project:
@project
,
current_user:
(
current_user
if
defined?
(
current_user
)),
# RelativeLinkFilter
project_wiki:
@project_wiki
,
requested_path:
@path
,
ref:
@ref
,
commit:
@commit
)
def
markup
(
file_name
,
text
,
context
=
{})
context
[
:project
]
||=
@project
html
=
context
.
delete
(
:rendered
)
||
markup_unsafe
(
file_name
,
text
,
context
)
banzai_postprocess
(
html
,
context
)
end
def
other_markup
(
file_name
,
text
)
Gitlab
::
OtherMarkup
.
render
(
file_name
,
text
,
project:
@project
,
current_user:
(
current_user
if
defined?
(
current_user
)),
def
render_wiki_content
(
wiki_page
)
text
=
wiki_page
.
content
return
''
unless
text
.
present?
context
=
{
pipeline: :wiki
,
project:
@project
,
project_wiki:
@project_wiki
,
page_slug:
wiki_page
.
slug
}
html
=
case
wiki_page
.
format
when
:markdown
markdown_unsafe
(
text
,
context
)
when
:asciidoc
asciidoc_unsafe
(
text
)
else
wiki_page
.
formatted_content
.
html_safe
end
# RelativeLinkFilter
project_wiki:
@project_wiki
,
requested_path:
@path
,
ref:
@ref
,
commit:
@commit
)
banzai_postprocess
(
html
,
context
)
end
# Return the first line of +text+, up to +max_chars+, after parsing the line
# as Markdown. HTML tags in the parsed output are not counted toward the
# +max_chars+ limit. If the length limit falls within a tag's contents, then
# the tag contents are truncated without removing the closing tag.
def
first_line_in_markdown
(
text
,
max_chars
=
nil
,
options
=
{})
md
=
markdown
(
text
,
options
).
strip
def
markup_unsafe
(
file_name
,
text
,
context
=
{})
return
''
unless
text
.
present?
truncate_visible
(
md
,
max_chars
||
md
.
length
)
if
md
.
present?
end
def
render_wiki_content
(
wiki_page
)
case
wiki_page
.
format
when
:markdown
markdown
(
wiki_page
.
content
,
pipeline: :wiki
,
project_wiki:
@project_wiki
,
page_slug:
wiki_page
.
slug
)
when
:asciidoc
asciidoc
(
wiki_page
.
content
)
if
gitlab_markdown?
(
file_name
)
Hamlit
::
RailsHelpers
.
preserve
(
markdown_unsafe
(
text
,
context
))
elsif
asciidoc?
(
file_name
)
asciidoc_unsafe
(
text
)
elsif
plain?
(
file_name
)
content_tag
:pre
,
class:
'plain-readme'
do
text
end
else
wiki_page
.
formatted_content
.
html_safe
other_markup_unsafe
(
file_name
,
text
)
end
rescue
RuntimeError
simple_format
(
text
)
end
# Returns the text necessary to reference `entity` across projects
...
...
@@ -183,10 +201,10 @@ module GitlabMarkdownHelper
end
def
markdown_toolbar_button
(
options
=
{})
data
=
options
[
:data
].
merge
({
container:
"body"
})
data
=
options
[
:data
].
merge
({
container:
'body'
})
content_tag
:button
,
type:
"button"
,
class:
"toolbar-btn js-md has-tooltip hidden-xs"
,
type:
'button'
,
class:
'toolbar-btn js-md has-tooltip hidden-xs'
,
tabindex:
-
1
,
data:
data
,
title:
options
[
:title
],
...
...
@@ -195,17 +213,34 @@ module GitlabMarkdownHelper
end
end
def
markdown_unsafe
(
text
,
context
=
{})
Banzai
.
render
(
text
,
context
)
end
def
asciidoc_unsafe
(
text
)
Gitlab
::
Asciidoc
.
render
(
text
)
end
def
other_markup_unsafe
(
file_name
,
text
)
Gitlab
::
OtherMarkup
.
render
(
file_name
,
text
)
end
# Calls Banzai.post_process with some common context options
def
banzai_postprocess
(
html
,
context
=
{})
return
''
unless
html
.
present?
context
.
merge!
(
current_user:
(
current_user
if
defined?
(
current_user
)),
# RelativeLinkFilter
requested_path:
@path
,
commit:
@commit
,
project_wiki:
@project_wiki
,
ref:
@ref
ref:
@ref
,
requested_path:
@path
)
Banzai
.
post_process
(
html
,
context
)
end
extend
self
end
app/helpers/tree_helper.rb
View file @
94b93e49
...
...
@@ -12,10 +12,6 @@ module TreeHelper
tree
.
html_safe
end
def
render_readme
(
readme
)
render_markup
(
readme
.
name
,
readme
.
data
)
end
# Return an image icon depending on the file type and mode
#
# type - String type of the tree item; either 'folder' or 'file'
...
...
app/mailers/base_mailer.rb
View file @
94b93e49
class
BaseMailer
<
ActionMailer
::
Base
helper
ApplicationHelper
helper
GitlabMarkdown
Helper
helper
Markup
Helper
attr_accessor
:current_user
helper_method
:current_user
,
:can?
...
...
app/models/application_setting.rb
View file @
94b93e49
...
...
@@ -28,6 +28,8 @@ class ApplicationSetting < ActiveRecord::Base
attr_accessor
:domain_whitelist_raw
,
:domain_blacklist_raw
validates
:uuid
,
presence:
true
validates
:session_expire_delay
,
presence:
true
,
numericality:
{
only_integer:
true
,
greater_than_or_equal_to:
0
}
...
...
@@ -159,6 +161,7 @@ class ApplicationSetting < ActiveRecord::Base
end
end
before_validation
:ensure_uuid!
before_save
:ensure_runners_registration_token
before_save
:ensure_health_check_access_token
...
...
@@ -344,6 +347,12 @@ class ApplicationSetting < ActiveRecord::Base
private
def
ensure_uuid!
return
if
uuid?
self
.
uuid
=
SecureRandom
.
uuid
end
def
check_repository_storages
invalid
=
repository_storages
-
Gitlab
.
config
.
repositories
.
storages
.
keys
errors
.
add
(
:repository_storages
,
"can't include:
#{
invalid
.
join
(
", "
)
}
"
)
unless
...
...
app/models/network/graph.rb
View file @
94b93e49
...
...
@@ -107,7 +107,8 @@ module Network
def
find_commits
(
skip
=
0
)
opts
=
{
max_count:
self
.
class
.
max_count
,
skip:
skip
skip:
skip
,
order: :date
}
opts
[
:ref
]
=
@commit
.
id
if
@filter_ref
...
...
app/models/repository.rb
View file @
94b93e49
...
...
@@ -17,9 +17,9 @@ class Repository
# same name. The cache key used by those methods must also match method's
# name.
#
# For example, for entry `:
readme` there's a method called `readme
` which
# stores its data in the `
readme
` cache key.
CACHED_METHODS
=
%i(size commit_count readme contribution_guide
# For example, for entry `:
commit_count` there's a method called `commit_count
` which
# stores its data in the `
commit_count
` cache key.
CACHED_METHODS
=
%i(size commit_count re
ndered_re
adme contribution_guide
changelog license_blob license_key gitignore koding_yml
gitlab_ci_yml branch_names tag_names branch_count
tag_count avatar exists? empty? root_ref)
.
freeze
...
...
@@ -28,7 +28,7 @@ class Repository
# changed. This Hash maps file types (as returned by Gitlab::FileDetector) to
# the corresponding methods to call for refreshing caches.
METHOD_CACHES_FOR_FILE_TYPES
=
{
readme: :readme
,
readme: :re
ndered_re
adme
,
changelog: :changelog
,
license:
%i(license_blob license_key)
,
contributing: :contribution_guide
,
...
...
@@ -527,7 +527,11 @@ class Repository
head
.
readme
end
end
cache_method
:readme
def
rendered_readme
MarkupHelper
.
markup_unsafe
(
readme
.
name
,
readme
.
data
,
project:
project
)
if
readme
end
cache_method
:rendered_readme
def
contribution_guide
file_on_head
(
:contributing
)
...
...
app/services/projects/create_service.rb
View file @
94b93e49
...
...
@@ -97,7 +97,8 @@ module Projects
system_hook_service
.
execute_hooks_for
(
@project
,
:create
)
unless
@project
.
group
||
@project
.
gitlab_project_import?
@project
.
team
<<
[
current_user
,
:master
,
current_user
]
owners
=
[
current_user
,
@project
.
namespace
.
owner
].
compact
.
uniq
@project
.
add_master
(
owners
,
current_user:
current_user
)
end
@project
.
group
&
.
refresh_members_authorized_projects
...
...
app/views/projects/_readme.html.haml
View file @
94b93e49
...
...
@@ -4,8 +4,7 @@
-
if
can?
(
current_user
,
:push_code
,
@project
)
=
link_to
icon
(
'pencil'
),
namespace_project_edit_blob_path
(
@project
.
namespace
,
@project
,
tree_join
(
@repository
.
root_ref
,
readme
.
name
)),
class:
'light edit-project-readme'
.file-content.wiki
=
cache
(
readme_cache_key
)
do
=
render_readme
(
readme
)
=
markup
(
readme
.
name
,
readme
.
data
,
rendered:
@repository
.
rendered_readme
)
-
else
.row-content-block.second-block.center
%h3
.page-title
...
...
app/views/projects/blob/_markup.html.haml
View file @
94b93e49
-
blob
.
load_all_data!
(
@repository
)
.file-content.wiki
=
render_
markup
(
blob
.
name
,
blob
.
data
)
=
markup
(
blob
.
name
,
blob
.
data
)
app/views/projects/blob/preview.html.haml
View file @
94b93e49
.diff-file
.diff-content
-
if
gitlab_markdown
?
(
@blob
.
name
)
-
if
markup
?
(
@blob
.
name
)
.file-content.wiki
=
preserve
do
=
markdown
(
@content
)
-
elsif
markup?
(
@blob
.
name
)
.file-content.wiki
=
raw
render_markup
(
@blob
.
name
,
@content
)
=
markup
(
@blob
.
name
,
@content
)
-
else
.file-content.code.js-syntax-highlight
-
unless
@diff_lines
.
empty?
...
...
app/views/projects/tree/_readme.html.haml
View file @
94b93e49
...
...
@@ -5,4 +5,4 @@
%strong
=
readme
.
name
.file-content.wiki
=
render_readme
(
readme
)
=
markup
(
readme
.
name
,
readme
.
data
)
app/views/search/results/_snippet_blob.html.haml
View file @
94b93e49
...
...
@@ -21,7 +21,7 @@
.file-content.wiki
-
snippet_chunks
.
each
do
|
chunk
|
-
unless
chunk
[
:data
].
empty?
=
render_
markup
(
snippet
.
file_name
,
chunk
[
:data
])
=
markup
(
snippet
.
file_name
,
chunk
[
:data
])
-
else
.file-content.code
.nothing-here-block
Empty file
...
...
app/views/shared/snippets/_blob.html.haml
View file @
94b93e49
...
...
@@ -24,6 +24,6 @@
-
if
gitlab_markdown?
(
@snippet
.
file_name
)
=
preserve
(
markdown_field
(
@snippet
,
:content
))
-
else
=
render_
markup
(
@snippet
.
file_name
,
@snippet
.
content
)
=
markup
(
@snippet
.
file_name
,
@snippet
.
content
)
-
else
=
render
'shared/file_highlight'
,
blob:
@snippet
changelogs/unreleased/2246-uuid-is-nil-for-new-installation.yml
0 → 100644
View file @
94b93e49
---
title
:
Lazily sets UUID in ApplicationSetting for new installations
merge_request
:
author
:
changelogs/unreleased/26585-remove-readme-view-caching.yml
0 → 100644
View file @
94b93e49
---
title
:
'
Remove
view
fragment
caching
for
project
READMEs'
merge_request
:
8838
author
:
changelogs/unreleased/29505-allow-admins-sudo-to-blocked-users.yml
0 → 100644
View file @
94b93e49
---
title
:
Allow admins to sudo to blocked users via the API
merge_request
:
10842
author
:
changelogs/unreleased/30973-fix-network-graph-ordering.yml
0 → 100644
View file @
94b93e49
---
title
:
Fix ordering of commits in the network graph
merge_request
:
10936
author
:
changelogs/unreleased/tc-make-user-master-project-by-admin.yml
0 → 100644
View file @
94b93e49
---
title
:
Ensure namespace owner is Master of project upon creation
merge_request
:
10910
author
:
db/migrate/20170426175636_fill_missing_uuid_on_application_settings.rb
0 → 100644
View file @
94b93e49
class
FillMissingUuidOnApplicationSettings
<
ActiveRecord
::
Migration
DOWNTIME
=
false
def
up
execute
(
"UPDATE application_settings SET uuid =
#{
quote
(
SecureRandom
.
uuid
)
}
WHERE uuid is NULL"
)
end
def
down
end
end
db/schema.rb
View file @
94b93e49
...
...
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord
::
Schema
.
define
(
version:
2017042
4142900
)
do
ActiveRecord
::
Schema
.
define
(
version:
2017042
6175636
)
do
# These are extensions that must be enabled in order to support this database
enable_extension
"plpgsql"
...
...
lib/api/helpers.rb
View file @
94b93e49
...
...
@@ -102,7 +102,7 @@ module API
end
def
authenticate!
unauthorized!
unless
current_user
&&
can?
(
current_user
,
:access_api
)
unauthorized!
unless
current_user
&&
can?
(
initial_
current_user
,
:access_api
)
end
def
authenticate_non_get!
...
...
lib/gitlab/asciidoc.rb
View file @
94b93e49
...
...
@@ -14,28 +14,16 @@ module Gitlab
# Public: Converts the provided Asciidoc markup into HTML.
#
# input - the source text in Asciidoc format
# context - a Hash with the template context:
# :commit
# :project
# :project_wiki
# :requested_path
# :ref
# asciidoc_opts - a Hash of options to pass to the Asciidoctor converter
#
def
self
.
render
(
input
,
context
,
asciidoc_opts
=
{})
asciidoc_opts
.
reverse_merge!
(
safe: :secure
,
backend: :gitlab_html5
,
attributes:
[]
)
asciidoc_opts
[
:attributes
].
unshift
(
*
DEFAULT_ADOC_ATTRS
)
def
self
.
render
(
input
)
asciidoc_opts
=
{
safe: :secure
,
backend: :gitlab_html5
,
attributes:
DEFAULT_ADOC_ATTRS
}
plantuml_setup
html
=
::
Asciidoctor
.
convert
(
input
,
asciidoc_opts
)
html
=
Banzai
.
post_process
(
html
,
context
)
filter
=
Banzai
::
Filter
::
SanitizationFilter
.
new
(
html
)
html
=
filter
.
call
.
to_s
...
...
lib/gitlab/git/repository.rb
View file @
94b93e49
...
...
@@ -494,7 +494,9 @@ module Gitlab
# :contains is the commit contained by the refs from which to begin (SHA1 or name)
# :max_count is the maximum number of commits to fetch
# :skip is the number of commits to skip
# :order is the commits order and allowed value is :date(default) or :topo
# :order is the commits order and allowed value is :none (default), :date, or :topo
# commit ordering types are documented here:
# http://www.rubydoc.info/github/libgit2/rugged/Rugged#SORT_NONE-constant)
#
def
find_commits
(
options
=
{})
actual_options
=
options
.
dup
...
...
@@ -522,11 +524,8 @@ module Gitlab
end
end
if
actual_options
[
:order
]
==
:topo
walker
.
sorting
(
Rugged
::
SORT_TOPO
)
else
walker
.
sorting
(
Rugged
::
SORT_NONE
)
end
sort_type
=
rugged_sort_type
(
actual_options
[
:order
])
walker
.
sorting
(
sort_type
)
commits
=
[]
offset
=
actual_options
[
:skip
]
...
...
@@ -1273,6 +1272,18 @@ module Gitlab
def
gitaly_ref_client
@gitaly_ref_client
||=
Gitlab
::
GitalyClient
::
Ref
.
new
(
self
)
end
# Returns the `Rugged` sorting type constant for a given
# sort type key. Valid keys are `:none`, `:topo`, and `:date`
def
rugged_sort_type
(
key
)
@rugged_sort_types
||=
{
none:
Rugged
::
SORT_NONE
,
topo:
Rugged
::
SORT_TOPO
,
date:
Rugged
::
SORT_DATE
}
@rugged_sort_types
.
fetch
(
key
,
Rugged
::
SORT_NONE
)
end
end
end
end
lib/gitlab/other_markup.rb
View file @
94b93e49
...
...
@@ -4,19 +4,11 @@ module Gitlab
# Public: Converts the provided markup into HTML.
#
# input - the source text in a markup format
# context - a Hash with the template context:
# :commit
# :project
# :project_wiki
# :requested_path
# :ref
#
def
self
.
render
(
file_name
,
input
,
context
)
def
self
.
render
(
file_name
,
input
)
html
=
GitHub
::
Markup
.
render
(
file_name
,
input
).
force_encoding
(
input
.
encoding
)
html
=
Banzai
.
post_process
(
html
,
context
)
filter
=
Banzai
::
Filter
::
SanitizationFilter
.
new
(
html
)
html
=
filter
.
call
.
to_s
...
...
spec/features/admin/admin_cohorts_spec.rb
0 → 100644
View file @
94b93e49
require
'rails_helper'
feature
'Admin cohorts page'
,
feature:
true
do
before
do
login_as
:admin
end
scenario
'See users count per month'
do
2
.
times
{
create
(
:user
)
}
visit
admin_cohorts_path
expect
(
page
).
to
have_content
(
"
#{
Time
.
now
.
strftime
(
'%b %Y'
)
}
3 0"
)
end
end
spec/features/copy_as_gfm_spec.rb
View file @
94b93e49
require
'spec_helper'
describe
'Copy as GFM'
,
feature:
true
,
js:
true
do
include
GitlabMarkdown
Helper
include
Markup
Helper
include
RepoHelpers
include
ActionView
::
Helpers
::
JavaScriptHelper
...
...
spec/features/markdown_spec.rb
View file @
94b93e49
...
...
@@ -26,7 +26,7 @@ require 'erb'
describe
'GitLab Markdown'
,
feature:
true
do
include
Capybara
::
Node
::
Matchers
include
GitlabMarkdown
Helper
include
Markup
Helper
include
MarkdownMatchers
# Sometimes it can be useful to see the parsed output of the Markdown document
...
...
spec/helpers/application_helper_spec.rb
View file @
94b93e49
...
...
@@ -239,33 +239,6 @@ describe ApplicationHelper do
end
end
describe
'render_markup'
do
let
(
:content
)
{
'Noël'
}
let
(
:user
)
{
create
(
:user
)
}
before
do
allow
(
helper
).
to
receive
(
:current_user
).
and_return
(
user
)
end
it
'preserves encoding'
do
expect
(
content
.
encoding
.
name
).
to
eq
(
'UTF-8'
)
expect
(
helper
.
render_markup
(
'foo.rst'
,
content
).
encoding
.
name
).
to
eq
(
'UTF-8'
)
end
it
"delegates to #markdown when file name corresponds to Markdown"
do
expect
(
helper
).
to
receive
(
:gitlab_markdown?
).
with
(
'foo.md'
).
and_return
(
true
)
expect
(
helper
).
to
receive
(
:markdown
).
and_return
(
'NOEL'
)
expect
(
helper
.
render_markup
(
'foo.md'
,
content
)).
to
eq
(
'NOEL'
)
end
it
"delegates to #asciidoc when file name corresponds to AsciiDoc"
do
expect
(
helper
).
to
receive
(
:asciidoc?
).
with
(
'foo.adoc'
).
and_return
(
true
)
expect
(
helper
).
to
receive
(
:asciidoc
).
and_return
(
'NOEL'
)
expect
(
helper
.
render_markup
(
'foo.adoc'
,
content
)).
to
eq
(
'NOEL'
)
end
end
describe
'#active_when'
do
it
{
expect
(
helper
.
active_when
(
true
)).
to
eq
(
'active'
)
}
it
{
expect
(
helper
.
active_when
(
false
)).
to
eq
(
nil
)
}
...
...
spec/helpers/
gitlab_markdown
_helper_spec.rb
→
spec/helpers/
markup
_helper_spec.rb
View file @
94b93e49
require
'spec_helper'
describe
GitlabMarkdownHelper
do
include
ApplicationHelper
describe
MarkupHelper
do
let!
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:user
)
{
create
(
:user
,
username:
'gfm'
)
}
...
...
@@ -128,7 +126,7 @@ describe GitlabMarkdownHelper do
it
"uses Wiki pipeline for markdown files"
do
allow
(
@wiki
).
to
receive
(
:format
).
and_return
(
:markdown
)
expect
(
helper
).
to
receive
(
:markdown
).
with
(
'wiki content'
,
pipeline: :wiki
,
project_wiki:
@wiki
,
page_slug:
"nested/page"
)
expect
(
helper
).
to
receive
(
:markdown
_unsafe
).
with
(
'wiki content'
,
pipeline: :wiki
,
project:
project
,
project_wiki:
@wiki
,
page_slug:
"nested/page"
)
helper
.
render_wiki_content
(
@wiki
)
end
...
...
@@ -136,7 +134,7 @@ describe GitlabMarkdownHelper do
it
"uses Asciidoctor for asciidoc files"
do
allow
(
@wiki
).
to
receive
(
:format
).
and_return
(
:asciidoc
)
expect
(
helper
).
to
receive
(
:asciidoc
).
with
(
'wiki content'
)
expect
(
helper
).
to
receive
(
:asciidoc
_unsafe
).
with
(
'wiki content'
)
helper
.
render_wiki_content
(
@wiki
)
end
...
...
@@ -151,6 +149,29 @@ describe GitlabMarkdownHelper do
end
end
describe
'markup'
do
let
(
:content
)
{
'Noël'
}
it
'preserves encoding'
do
expect
(
content
.
encoding
.
name
).
to
eq
(
'UTF-8'
)
expect
(
helper
.
markup
(
'foo.rst'
,
content
).
encoding
.
name
).
to
eq
(
'UTF-8'
)
end
it
"delegates to #markdown_unsafe when file name corresponds to Markdown"
do
expect
(
helper
).
to
receive
(
:gitlab_markdown?
).
with
(
'foo.md'
).
and_return
(
true
)
expect
(
helper
).
to
receive
(
:markdown_unsafe
).
and_return
(
'NOEL'
)
expect
(
helper
.
markup
(
'foo.md'
,
content
)).
to
eq
(
'NOEL'
)
end
it
"delegates to #asciidoc_unsafe when file name corresponds to AsciiDoc"
do
expect
(
helper
).
to
receive
(
:asciidoc?
).
with
(
'foo.adoc'
).
and_return
(
true
)
expect
(
helper
).
to
receive
(
:asciidoc_unsafe
).
and_return
(
'NOEL'
)
expect
(
helper
.
markup
(
'foo.adoc'
,
content
)).
to
eq
(
'NOEL'
)
end
end
describe
'#first_line_in_markdown'
do
it
'truncates Markdown properly'
do
text
=
"@
#{
user
.
username
}
, can you look at this?
\n
Hello world
\n
"
...
...
spec/javascripts/environments/environment_spec.js
View file @
94b93e49
import
Vue
from
'
vue
'
;
import
'
~/flash
'
;
import
EnvironmentsComponent
from
'
~/environments/components/environment
'
;
import
environmentsComponent
from
'
~/environments/components/environment.vue
'
;
import
{
environment
,
folder
}
from
'
./mock_data
'
;
describe
(
'
Environment
'
,
()
=>
{
preloadFixtures
(
'
static/environments/environments.html.raw
'
);
let
EnvironmentsComponent
;
let
component
;
beforeEach
(()
=>
{
loadFixtures
(
'
static/environments/environments.html.raw
'
);
EnvironmentsComponent
=
Vue
.
extend
(
environmentsComponent
);
});
describe
(
'
successfull request
'
,
()
=>
{
...
...
spec/javascripts/environments/folder/environments_folder_view_spec.js
View file @
94b93e49
import
Vue
from
'
vue
'
;
import
'
~/flash
'
;
import
EnvironmentsFolderViewComponent
from
'
~/environments/folder/environments_folder_view
'
;
import
environmentsFolderViewComponent
from
'
~/environments/folder/environments_folder_view.vue
'
;
import
{
environmentsList
}
from
'
../mock_data
'
;
describe
(
'
Environments Folder View
'
,
()
=>
{
preloadFixtures
(
'
static/environments/environments_folder_view.html.raw
'
);
let
EnvironmentsFolderViewComponent
;
beforeEach
(()
=>
{
loadFixtures
(
'
static/environments/environments_folder_view.html.raw
'
);
EnvironmentsFolderViewComponent
=
Vue
.
extend
(
environmentsFolderViewComponent
);
window
.
history
.
pushState
({},
null
,
'
environments/folders/build
'
);
});
...
...
spec/javascripts/pipelines/time_ago_spec.js
0 → 100644
View file @
94b93e49
import
Vue
from
'
vue
'
;
import
timeAgo
from
'
~/pipelines/components/time_ago
'
;
describe
(
'
Timeago component
'
,
()
=>
{
let
TimeAgo
;
beforeEach
(()
=>
{
TimeAgo
=
Vue
.
extend
(
timeAgo
);
});
describe
(
'
with duration
'
,
()
=>
{
it
(
'
should render duration and timer svg
'
,
()
=>
{
const
component
=
new
TimeAgo
({
propsData
:
{
duration
:
10
,
finishedTime
:
''
,
},
}).
$mount
();
expect
(
component
.
$el
.
querySelector
(
'
.duration
'
)).
toBeDefined
();
expect
(
component
.
$el
.
querySelector
(
'
.duration svg
'
)).
toBeDefined
();
});
});
describe
(
'
without duration
'
,
()
=>
{
it
(
'
should not render duration and timer svg
'
,
()
=>
{
const
component
=
new
TimeAgo
({
propsData
:
{
duration
:
0
,
finishedTime
:
''
,
},
}).
$mount
();
expect
(
component
.
$el
.
querySelector
(
'
.duration
'
)).
toBe
(
null
);
});
});
describe
(
'
with finishedTime
'
,
()
=>
{
it
(
'
should render time and calendar icon
'
,
()
=>
{
const
component
=
new
TimeAgo
({
propsData
:
{
duration
:
0
,
finishedTime
:
'
2017-04-26T12:40:23.277Z
'
,
},
}).
$mount
();
expect
(
component
.
$el
.
querySelector
(
'
.finished-at
'
)).
toBeDefined
();
expect
(
component
.
$el
.
querySelector
(
'
.finished-at i.fa-calendar
'
)).
toBeDefined
();
expect
(
component
.
$el
.
querySelector
(
'
.finished-at time
'
)).
toBeDefined
();
});
});
describe
(
'
without finishedTime
'
,
()
=>
{
it
(
'
should not render time and calendar icon
'
,
()
=>
{
const
component
=
new
TimeAgo
({
propsData
:
{
duration
:
0
,
finishedTime
:
''
,
},
}).
$mount
();
expect
(
component
.
$el
.
querySelector
(
'
.finished-at
'
)).
toBe
(
null
);
});
});
});
spec/lib/gitlab/asciidoc_spec.rb
View file @
94b93e49
...
...
@@ -22,26 +22,9 @@ module Gitlab
expect
(
Asciidoctor
).
to
receive
(
:convert
)
.
with
(
input
,
expected_asciidoc_opts
).
and_return
(
html
)
expect
(
render
(
input
,
context
)
).
to
eql
html
expect
(
render
(
input
)).
to
eq
(
html
)
end
context
"with asciidoc_opts"
do
let
(
:asciidoc_opts
)
{
{
safe: :safe
,
attributes:
[
'foo'
]
}
}
it
"merges the options with default ones"
do
expected_asciidoc_opts
=
{
safe: :safe
,
backend: :gitlab_html5
,
attributes:
described_class
::
DEFAULT_ADOC_ATTRS
+
[
'foo'
]
}
expect
(
Asciidoctor
).
to
receive
(
:convert
)
.
with
(
input
,
expected_asciidoc_opts
).
and_return
(
html
)
render
(
input
,
context
,
asciidoc_opts
)
end
end
context
"XSS"
do
links
=
{
'links'
=>
{
...
...
@@ -60,7 +43,7 @@ module Gitlab
links
.
each
do
|
name
,
data
|
it
"does not convert dangerous
#{
name
}
into HTML"
do
expect
(
render
(
data
[
:input
]
,
context
)).
to
eql
data
[
:output
]
expect
(
render
(
data
[
:input
]
)).
to
eq
(
data
[
:output
])
end
end
end
...
...
spec/lib/gitlab/git/repository_spec.rb
View file @
94b93e49
...
...
@@ -1031,6 +1031,35 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
end
describe
'#find_commits'
do
it
'should return a return a collection of commits'
do
commits
=
repository
.
find_commits
expect
(
commits
).
not_to
be_empty
expect
(
commits
).
to
all
(
be_a_kind_of
(
Gitlab
::
Git
::
Commit
)
)
end
context
'while applying a sort order based on the `order` option'
do
it
"allows ordering topologically (no parents shown before their children)"
do
expect_any_instance_of
(
Rugged
::
Walker
).
to
receive
(
:sorting
).
with
(
Rugged
::
SORT_TOPO
)
repository
.
find_commits
(
order: :topo
)
end
it
"allows ordering by date"
do
expect_any_instance_of
(
Rugged
::
Walker
).
to
receive
(
:sorting
).
with
(
Rugged
::
SORT_DATE
)
repository
.
find_commits
(
order: :date
)
end
it
"applies no sorting by default"
do
expect_any_instance_of
(
Rugged
::
Walker
).
to
receive
(
:sorting
).
with
(
Rugged
::
SORT_NONE
)
repository
.
find_commits
end
end
end
describe
'#branches with deleted branch'
do
before
(
:each
)
do
ref
=
double
()
...
...
spec/lib/gitlab/other_markup_spec.rb
View file @
94b93e49
...
...
@@ -13,7 +13,7 @@ describe Gitlab::OtherMarkup, lib: true do
}
links
.
each
do
|
name
,
data
|
it
"does not convert dangerous
#{
name
}
into HTML"
do
expect
(
render
(
data
[
:file
],
data
[
:input
]
,
context
)).
to
eql
data
[
:output
]
expect
(
render
(
data
[
:file
],
data
[
:input
]
)).
to
eq
(
data
[
:output
])
end
end
end
...
...
spec/models/application_setting_spec.rb
View file @
94b93e49
...
...
@@ -4,6 +4,7 @@ describe ApplicationSetting, models: true do
let
(
:setting
)
{
ApplicationSetting
.
create_from_defaults
}
it
{
expect
(
setting
).
to
be_valid
}
it
{
expect
(
setting
.
uuid
).
to
be_present
}
describe
'validations'
do
let
(
:http
)
{
'http://example.com'
}
...
...
spec/models/network/graph_spec.rb
View file @
94b93e49
...
...
@@ -9,4 +9,25 @@ describe Network::Graph, models: true do
expect
(
graph
.
notes
).
to
eq
(
{
note_on_commit
.
commit_id
=>
1
}
)
end
describe
"#commits"
do
let
(
:graph
)
{
described_class
.
new
(
project
,
'refs/heads/master'
,
project
.
repository
.
commit
,
nil
)
}
it
"returns a list of commits"
do
commits
=
graph
.
commits
expect
(
commits
).
not_to
be_empty
expect
(
commits
).
to
all
(
be_kind_of
(
Network
::
Commit
)
)
end
it
"sorts the commits by commit date (descending)"
do
# Remove duplicate timestamps because they make it harder to
# assert that the commits are sorted as expected.
commits
=
graph
.
commits
.
uniq
(
&
:date
)
sorted_commits
=
commits
.
sort_by
(
&
:date
).
reverse
expect
(
commits
).
not_to
be_empty
expect
(
commits
.
map
(
&
:id
)).
to
eq
(
sorted_commits
.
map
(
&
:id
))
end
end
end
spec/models/repository_spec.rb
View file @
94b93e49
...
...
@@ -1803,9 +1803,9 @@ describe Repository, models: true do
describe
'#refresh_method_caches'
do
it
'refreshes the caches of the given types'
do
expect
(
repository
).
to
receive
(
:expire_method_caches
).
with
(
%i(readme license_blob license_key)
)
with
(
%i(re
ndered_re
adme license_blob license_key)
)
expect
(
repository
).
to
receive
(
:readme
)
expect
(
repository
).
to
receive
(
:re
ndered_re
adme
)
expect
(
repository
).
to
receive
(
:license_blob
)
expect
(
repository
).
to
receive
(
:license_key
)
...
...
spec/requests/api/helpers_spec.rb
View file @
94b93e49
...
...
@@ -427,6 +427,7 @@ describe API::Helpers do
context
'current_user is nil'
do
before
do
expect_any_instance_of
(
self
.
class
).
to
receive
(
:current_user
).
and_return
(
nil
)
allow_any_instance_of
(
self
.
class
).
to
receive
(
:initial_current_user
).
and_return
(
nil
)
end
it
'returns a 401 response'
do
...
...
@@ -435,13 +436,38 @@ describe API::Helpers do
end
context
'current_user is present'
do
let
(
:user
)
{
build
(
:user
)
}
before
do
expect_any_instance_of
(
self
.
class
).
to
receive
(
:current_user
).
at_least
(
:once
).
and_return
(
User
.
new
)
expect_any_instance_of
(
self
.
class
).
to
receive
(
:current_user
).
at_least
(
:once
).
and_return
(
user
)
expect_any_instance_of
(
self
.
class
).
to
receive
(
:initial_current_user
).
and_return
(
user
)
end
it
'does not raise an error'
do
expect
{
authenticate!
}.
not_to
raise_error
end
end
context
'current_user is blocked'
do
let
(
:user
)
{
build
(
:user
,
:blocked
)
}
before
do
expect_any_instance_of
(
self
.
class
).
to
receive
(
:current_user
).
at_least
(
:once
).
and_return
(
user
)
end
it
'raises an error'
do
expect_any_instance_of
(
self
.
class
).
to
receive
(
:initial_current_user
).
and_return
(
user
)
expect
{
authenticate!
}.
to
raise_error
'401 - {"message"=>"401 Unauthorized"}'
end
it
"doesn't raise an error if an admin user is impersonating a blocked user (via sudo)"
do
admin_user
=
build
(
:user
,
:admin
)
expect_any_instance_of
(
self
.
class
).
to
receive
(
:initial_current_user
).
and_return
(
admin_user
)
expect
{
authenticate!
}.
not_to
raise_error
end
end
end
end
spec/services/projects/create_service_spec.rb
View file @
94b93e49
...
...
@@ -27,6 +27,22 @@ describe Projects::CreateService, '#execute', services: true do
end
end
context
"admin creates project with other user's namespace_id"
do
it
'sets the correct permissions'
do
admin
=
create
(
:admin
)
opts
=
{
name:
'GitLab'
,
namespace_id:
user
.
namespace
.
id
}
project
=
create_project
(
admin
,
opts
)
expect
(
project
).
to
be_persisted
expect
(
project
.
owner
).
to
eq
(
user
)
expect
(
project
.
team
.
masters
).
to
include
(
user
,
admin
)
expect
(
project
.
namespace
).
to
eq
(
user
.
namespace
)
end
end
context
'group namespace'
do
let
(
:group
)
do
create
(
:group
).
tap
do
|
group
|
...
...
spec/services/system_note_service_spec.rb
View file @
94b93e49
...
...
@@ -595,7 +595,7 @@ describe SystemNoteService, services: true do
end
shared_examples
'cross project mentionable'
do
include
GitlabMarkdown
Helper
include
Markup
Helper
it
'contains cross reference to new noteable'
do
expect
(
subject
.
note
).
to
include
cross_project_reference
(
new_project
,
new_noteable
)
...
...
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