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
0
Merge Requests
0
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
Boxiang Sun
gitlab-ce
Commits
228b73d5
Commit
228b73d5
authored
Jun 02, 2017
by
Filipa Lacerda
Committed by
Phil Hughes
Jun 02, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Pipeline show view real time header section
parent
68112433
Changes
27
Show whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
375 additions
and
62 deletions
+375
-62
app/assets/javascripts/commit/pipelines/pipelines_table.js
app/assets/javascripts/commit/pipelines/pipelines_table.js
+1
-1
app/assets/javascripts/environments/components/environment.vue
...ssets/javascripts/environments/components/environment.vue
+1
-1
app/assets/javascripts/pipelines/components/header_component.vue
...ets/javascripts/pipelines/components/header_component.vue
+97
-0
app/assets/javascripts/pipelines/components/pipeline_url.vue
app/assets/javascripts/pipelines/components/pipeline_url.vue
+1
-1
app/assets/javascripts/pipelines/pipeline_details_bundle.js
app/assets/javascripts/pipelines/pipeline_details_bundle.js
+39
-2
app/assets/javascripts/pipelines/pipeline_details_mediatior.js
...ssets/javascripts/pipelines/pipeline_details_mediatior.js
+8
-0
app/assets/javascripts/pipelines/pipelines.js
app/assets/javascripts/pipelines/pipelines.js
+1
-1
app/assets/javascripts/pipelines/services/pipeline_service.js
...assets/javascripts/pipelines/services/pipeline_service.js
+5
-0
app/assets/javascripts/pipelines/services/pipelines_service.js
...ssets/javascripts/pipelines/services/pipelines_service.js
+0
-2
app/assets/javascripts/vue_shared/components/commit.js
app/assets/javascripts/vue_shared/components/commit.js
+2
-2
app/assets/javascripts/vue_shared/components/header_ci_component.vue
...javascripts/vue_shared/components/header_ci_component.vue
+32
-21
app/assets/javascripts/vue_shared/components/pipelines_table_row.js
.../javascripts/vue_shared/components/pipelines_table_row.js
+1
-1
app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue
...s/vue_shared/components/user_avatar/user_avatar_image.vue
+7
-1
app/assets/stylesheets/pages/pipelines.scss
app/assets/stylesheets/pages/pipelines.scss
+8
-0
app/serializers/user_entity.rb
app/serializers/user_entity.rb
+5
-0
app/views/projects/pipelines/_info.html.haml
app/views/projects/pipelines/_info.html.haml
+1
-15
changelogs/unreleased/31849-pipeline-real-time-header.yml
changelogs/unreleased/31849-pipeline-real-time-header.yml
+4
-0
spec/features/commits_spec.rb
spec/features/commits_spec.rb
+11
-9
spec/features/projects/pipelines/pipeline_spec.rb
spec/features/projects/pipelines/pipeline_spec.rb
+0
-2
spec/javascripts/pipelines/header_component_spec.js
spec/javascripts/pipelines/header_component_spec.js
+60
-0
spec/javascripts/pipelines/pipeline_details_mediator_spec.js
spec/javascripts/pipelines/pipeline_details_mediator_spec.js
+41
-0
spec/javascripts/pipelines/pipeline_store_spec.js
spec/javascripts/pipelines/pipeline_store_spec.js
+27
-0
spec/javascripts/pipelines/pipeline_url_spec.js
spec/javascripts/pipelines/pipeline_url_spec.js
+1
-0
spec/javascripts/vue_shared/components/commit_spec.js
spec/javascripts/vue_shared/components/commit_spec.js
+3
-1
spec/javascripts/vue_shared/components/header_ci_component_spec.js
...scripts/vue_shared/components/header_ci_component_spec.js
+11
-0
spec/javascripts/vue_shared/components/pipelines_table_row_spec.js
...scripts/vue_shared/components/pipelines_table_row_spec.js
+2
-2
spec/serializers/user_entity_spec.rb
spec/serializers/user_entity_spec.rb
+6
-0
No files found.
app/assets/javascripts/commit/pipelines/pipelines_table.js
View file @
228b73d5
...
@@ -118,7 +118,7 @@ export default Vue.component('pipelines-table', {
...
@@ -118,7 +118,7 @@ export default Vue.component('pipelines-table', {
eventHub
.
$on
(
'
refreshPipelines
'
,
this
.
fetchPipelines
);
eventHub
.
$on
(
'
refreshPipelines
'
,
this
.
fetchPipelines
);
},
},
beforeDestroy
ed
()
{
beforeDestroy
()
{
eventHub
.
$off
(
'
refreshPipelines
'
);
eventHub
.
$off
(
'
refreshPipelines
'
);
},
},
...
...
app/assets/javascripts/environments/components/environment.vue
View file @
228b73d5
...
@@ -109,7 +109,7 @@ export default {
...
@@ -109,7 +109,7 @@ export default {
eventHub
.
$on
(
'
postAction
'
,
this
.
postAction
);
eventHub
.
$on
(
'
postAction
'
,
this
.
postAction
);
},
},
beforeDestroy
ed
()
{
beforeDestroy
()
{
eventHub
.
$off
(
'
toggleFolder
'
);
eventHub
.
$off
(
'
toggleFolder
'
);
eventHub
.
$off
(
'
postAction
'
);
eventHub
.
$off
(
'
postAction
'
);
},
},
...
...
app/assets/javascripts/pipelines/components/header_component.vue
0 → 100644
View file @
228b73d5
<
script
>
import
ciHeader
from
'
../../vue_shared/components/header_ci_component.vue
'
;
import
eventHub
from
'
../event_hub
'
;
import
loadingIcon
from
'
../../vue_shared/components/loading_icon.vue
'
;
export
default
{
name
:
'
PipelineHeaderSection
'
,
props
:
{
pipeline
:
{
type
:
Object
,
required
:
true
,
},
isLoading
:
{
type
:
Boolean
,
required
:
true
,
},
},
components
:
{
ciHeader
,
loadingIcon
,
},
data
()
{
return
{
actions
:
this
.
getActions
(),
};
},
computed
:
{
status
()
{
return
this
.
pipeline
.
details
&&
this
.
pipeline
.
details
.
status
;
},
shouldRenderContent
()
{
return
!
this
.
isLoading
&&
Object
.
keys
(
this
.
pipeline
).
length
;
},
},
methods
:
{
postAction
(
action
)
{
const
index
=
this
.
actions
.
indexOf
(
action
);
this
.
$set
(
this
.
actions
[
index
],
'
isLoading
'
,
true
);
eventHub
.
$emit
(
'
headerPostAction
'
,
action
);
},
getActions
()
{
const
actions
=
[];
if
(
this
.
pipeline
.
retry_path
)
{
actions
.
push
({
label
:
'
Retry
'
,
path
:
this
.
pipeline
.
retry_path
,
cssClass
:
'
js-retry-button btn btn-inverted-secondary
'
,
type
:
'
button
'
,
isLoading
:
false
,
});
}
if
(
this
.
pipeline
.
cancel_path
)
{
actions
.
push
({
label
:
'
Cancel running
'
,
path
:
this
.
pipeline
.
cancel_path
,
cssClass
:
'
js-btn-cancel-pipeline btn btn-danger
'
,
type
:
'
button
'
,
isLoading
:
false
,
});
}
return
actions
;
},
},
watch
:
{
pipeline
()
{
this
.
actions
=
this
.
getActions
();
},
},
};
</
script
>
<
template
>
<div
class=
"pipeline-header-container"
>
<ci-header
v-if=
"shouldRenderContent"
:status=
"status"
item-name=
"Pipeline"
:item-id=
"pipeline.id"
:time=
"pipeline.created_at"
:user=
"pipeline.user"
:actions=
"actions"
@
actionClicked=
"postAction"
/>
<loading-icon
v-else
size=
"2"
/>
</div>
</
template
>
app/assets/javascripts/pipelines/components/pipeline_url.vue
View file @
228b73d5
...
@@ -33,7 +33,7 @@ export default {
...
@@ -33,7 +33,7 @@ export default {
<user-avatar-link
<user-avatar-link
v-if=
"user"
v-if=
"user"
class=
"js-pipeline-url-user"
class=
"js-pipeline-url-user"
:link-href=
"pipeline.user.
web_url
"
:link-href=
"pipeline.user.
path
"
:img-src=
"pipeline.user.avatar_url"
:img-src=
"pipeline.user.avatar_url"
:tooltip-text=
"pipeline.user.name"
:tooltip-text=
"pipeline.user.name"
/>
/>
...
...
app/assets/javascripts/pipelines/pipeline_details_bundle.js
View file @
228b73d5
/* global Flash */
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
PipelinesMediator
from
'
./pipeline_details_mediatior
'
;
import
PipelinesMediator
from
'
./pipeline_details_mediatior
'
;
import
pipelineGraph
from
'
./components/graph/graph_component.vue
'
;
import
pipelineGraph
from
'
./components/graph/graph_component.vue
'
;
import
pipelineHeader
from
'
./components/header_component.vue
'
;
import
eventHub
from
'
./event_hub
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
const
dataset
=
document
.
querySelector
(
'
.js-pipeline-details-vue
'
).
dataset
;
const
dataset
=
document
.
querySelector
(
'
.js-pipeline-details-vue
'
).
dataset
;
...
@@ -9,7 +13,8 @@ document.addEventListener('DOMContentLoaded', () => {
...
@@ -9,7 +13,8 @@ document.addEventListener('DOMContentLoaded', () => {
mediator
.
fetchPipeline
();
mediator
.
fetchPipeline
();
const
pipelineGraphApp
=
new
Vue
({
// eslint-disable-next-line
new
Vue
({
el
:
'
#js-pipeline-graph-vue
'
,
el
:
'
#js-pipeline-graph-vue
'
,
data
()
{
data
()
{
return
{
return
{
...
@@ -29,5 +34,37 @@ document.addEventListener('DOMContentLoaded', () => {
...
@@ -29,5 +34,37 @@ document.addEventListener('DOMContentLoaded', () => {
},
},
});
});
return
pipelineGraphApp
;
// eslint-disable-next-line
new
Vue
({
el
:
'
#js-pipeline-header-vue
'
,
data
()
{
return
{
mediator
,
};
},
components
:
{
pipelineHeader
,
},
created
()
{
eventHub
.
$on
(
'
headerPostAction
'
,
this
.
postAction
);
},
beforeDestroy
()
{
eventHub
.
$off
(
'
headerPostAction
'
,
this
.
postAction
);
},
methods
:
{
postAction
(
action
)
{
this
.
mediator
.
service
.
postAction
(
action
.
path
)
.
then
(()
=>
this
.
mediator
.
refreshPipeline
())
.
catch
(()
=>
new
Flash
(
'
An error occurred while making the request.
'
));
},
},
render
(
createElement
)
{
return
createElement
(
'
pipeline-header
'
,
{
props
:
{
isLoading
:
this
.
mediator
.
state
.
isLoading
,
pipeline
:
this
.
mediator
.
store
.
state
.
pipeline
,
},
});
},
});
});
});
app/assets/javascripts/pipelines/pipeline_details_mediatior.js
View file @
228b73d5
...
@@ -26,6 +26,8 @@ export default class pipelinesMediator {
...
@@ -26,6 +26,8 @@ export default class pipelinesMediator {
if
(
!
Visibility
.
hidden
())
{
if
(
!
Visibility
.
hidden
())
{
this
.
state
.
isLoading
=
true
;
this
.
state
.
isLoading
=
true
;
this
.
poll
.
makeRequest
();
this
.
poll
.
makeRequest
();
}
else
{
this
.
refreshPipeline
();
}
}
Visibility
.
change
(()
=>
{
Visibility
.
change
(()
=>
{
...
@@ -48,4 +50,10 @@ export default class pipelinesMediator {
...
@@ -48,4 +50,10 @@ export default class pipelinesMediator {
this
.
state
.
isLoading
=
false
;
this
.
state
.
isLoading
=
false
;
return
new
Flash
(
'
An error occurred while fetching the pipeline.
'
);
return
new
Flash
(
'
An error occurred while fetching the pipeline.
'
);
}
}
refreshPipeline
()
{
this
.
service
.
getPipeline
()
.
then
(
response
=>
this
.
successCallback
(
response
))
.
catch
(()
=>
this
.
errorCallback
());
}
}
}
app/assets/javascripts/pipelines/pipelines.js
View file @
228b73d5
...
@@ -169,7 +169,7 @@ export default {
...
@@ -169,7 +169,7 @@ export default {
eventHub
.
$on
(
'
refreshPipelines
'
,
this
.
fetchPipelines
);
eventHub
.
$on
(
'
refreshPipelines
'
,
this
.
fetchPipelines
);
},
},
beforeDestroy
ed
()
{
beforeDestroy
()
{
eventHub
.
$off
(
'
refreshPipelines
'
);
eventHub
.
$off
(
'
refreshPipelines
'
);
},
},
...
...
app/assets/javascripts/pipelines/services/pipeline_service.js
View file @
228b73d5
...
@@ -11,4 +11,9 @@ export default class PipelineService {
...
@@ -11,4 +11,9 @@ export default class PipelineService {
getPipeline
()
{
getPipeline
()
{
return
this
.
pipeline
.
get
();
return
this
.
pipeline
.
get
();
}
}
// eslint-disable-next-line
postAction
(
endpoint
)
{
return
Vue
.
http
.
post
(
`
${
endpoint
}
.json`
);
}
}
}
app/assets/javascripts/pipelines/services/pipelines_service.js
View file @
228b73d5
...
@@ -33,8 +33,6 @@ export default class PipelinesService {
...
@@ -33,8 +33,6 @@ export default class PipelinesService {
/**
/**
* Post request for all pipelines actions.
* Post request for all pipelines actions.
* Endpoint content type needs to be:
* `Content-Type:application/x-www-form-urlencoded`
*
*
* @param {String} endpoint
* @param {String} endpoint
* @return {Promise}
* @return {Promise}
...
...
app/assets/javascripts/vue_shared/components/commit.js
View file @
228b73d5
...
@@ -91,7 +91,7 @@ export default {
...
@@ -91,7 +91,7 @@ export default {
hasAuthor
()
{
hasAuthor
()
{
return
this
.
author
&&
return
this
.
author
&&
this
.
author
.
avatar_url
&&
this
.
author
.
avatar_url
&&
this
.
author
.
web_url
&&
this
.
author
.
path
&&
this
.
author
.
username
;
this
.
author
.
username
;
},
},
...
@@ -140,7 +140,7 @@ export default {
...
@@ -140,7 +140,7 @@ export default {
<user-avatar-link
<user-avatar-link
v-if="hasAuthor"
v-if="hasAuthor"
class="avatar-image-container"
class="avatar-image-container"
:link-href="author.
web_url
"
:link-href="author.
path
"
:img-src="author.avatar_url"
:img-src="author.avatar_url"
:img-alt="userImageAltDescription"
:img-alt="userImageAltDescription"
:tooltip-text="author.username"
:tooltip-text="author.username"
...
...
app/assets/javascripts/vue_shared/components/header_ci_component.vue
View file @
228b73d5
<
script
>
<
script
>
import
ciIconBadge
from
'
./ci_badge_link.vue
'
;
import
ciIconBadge
from
'
./ci_badge_link.vue
'
;
import
loadingIcon
from
'
./loading_icon.vue
'
;
import
timeagoTooltip
from
'
./time_ago_tooltip.vue
'
;
import
timeagoTooltip
from
'
./time_ago_tooltip.vue
'
;
import
tooltipMixin
from
'
../mixins/tooltip
'
;
import
tooltipMixin
from
'
../mixins/tooltip
'
;
import
userAvatar
Link
from
'
./user_avatar/user_avatar_link
.vue
'
;
import
userAvatar
Image
from
'
./user_avatar/user_avatar_image
.vue
'
;
/**
/**
* Renders header component for job and pipeline page based on UI mockups
* Renders header component for job and pipeline page based on UI mockups
...
@@ -31,7 +32,8 @@ export default {
...
@@ -31,7 +32,8 @@ export default {
},
},
user
:
{
user
:
{
type
:
Object
,
type
:
Object
,
required
:
true
,
required
:
false
,
default
:
()
=>
({}),
},
},
actions
:
{
actions
:
{
type
:
Array
,
type
:
Array
,
...
@@ -46,8 +48,9 @@ export default {
...
@@ -46,8 +48,9 @@ export default {
components
:
{
components
:
{
ciIconBadge
,
ciIconBadge
,
loadingIcon
,
timeagoTooltip
,
timeagoTooltip
,
userAvatar
Link
,
userAvatar
Image
,
},
},
computed
:
{
computed
:
{
...
@@ -58,13 +61,13 @@ export default {
...
@@ -58,13 +61,13 @@ export default {
methods
:
{
methods
:
{
onClickAction
(
action
)
{
onClickAction
(
action
)
{
this
.
$emit
(
'
postAction
'
,
action
);
this
.
$emit
(
'
actionClicked
'
,
action
);
},
},
},
},
};
};
</
script
>
</
script
>
<
template
>
<
template
>
<header
class=
"page-content-header
top-area
"
>
<header
class=
"page-content-header"
>
<section
class=
"header-main-content"
>
<section
class=
"header-main-content"
>
<ci-icon-badge
:status=
"status"
/>
<ci-icon-badge
:status=
"status"
/>
...
@@ -79,21 +82,23 @@ export default {
...
@@ -79,21 +82,23 @@ export default {
by
by
<user-avatar-link
<template
v-if=
"user"
>
:link-href=
"user.web_url"
<a
:href=
"user.path"
:title=
"user.email"
class=
"js-user-link commit-committer-link"
ref=
"tooltip"
>
<user-avatar-image
:img-src=
"user.avatar_url"
:img-src=
"user.avatar_url"
:img-alt=
"userAvatarAltText"
:img-alt=
"userAvatarAltText"
:tooltip-text=
"user.name"
:tooltip-text=
"user.name"
:img-size=
"24"
:img-size=
"24"
/>
/>
<a
:href=
"user.web_url"
:title=
"user.email"
class=
"js-user-link commit-committer-link"
ref=
"tooltip"
>
{{
user
.
name
}}
{{
user
.
name
}}
</a>
</a>
</
template
>
</section>
</section>
<section
<section
...
@@ -111,11 +116,17 @@ export default {
...
@@ -111,11 +116,17 @@ export default {
<button
<button
v-else=
"action.type === 'button'"
v-else=
"action.type === 'button'"
@
click=
"onClickAction(action)"
@
click=
"onClickAction(action)"
:disabled=
"action.isLoading"
:class=
"action.cssClass"
:class=
"action.cssClass"
type=
"button"
>
type=
"button"
>
{{
action
.
label
}}
{{
action
.
label
}}
</button>
<i
v-show=
"action.isLoading"
class=
"fa fa-spin fa-spinner"
aria-hidden=
"true"
>
</i>
</button>
</
template
>
</
template
>
</section>
</section>
</header>
</header>
...
...
app/assets/javascripts/vue_shared/components/pipelines_table_row.js
View file @
228b73d5
...
@@ -83,7 +83,7 @@ export default {
...
@@ -83,7 +83,7 @@ export default {
}
else
{
}
else
{
commitAuthorInformation
=
{
commitAuthorInformation
=
{
avatar_url
:
this
.
pipeline
.
commit
.
author_gravatar_url
,
avatar_url
:
this
.
pipeline
.
commit
.
author_gravatar_url
,
web_url
:
`mailto:
${
this
.
pipeline
.
commit
.
author_email
}
`
,
path
:
`mailto:
${
this
.
pipeline
.
commit
.
author_email
}
`
,
username
:
this
.
pipeline
.
commit
.
author_name
,
username
:
this
.
pipeline
.
commit
.
author_name
,
};
};
}
}
...
...
app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue
View file @
228b73d5
...
@@ -60,6 +60,12 @@ export default {
...
@@ -60,6 +60,12 @@ export default {
avatarSizeClass
()
{
avatarSizeClass
()
{
return
`s
${
this
.
size
}
`
;
return
`s
${
this
.
size
}
`
;
},
},
// API response sends null when gravatar is disabled and
// we provide an empty string when we use it inside user avatar link.
// In both cases we should render the defaultAvatarUrl
imageSource
()
{
return
this
.
imgSrc
===
''
||
this
.
imgSrc
===
null
?
defaultAvatarUrl
:
this
.
imgSrc
;
},
},
},
};
};
</
script
>
</
script
>
...
@@ -68,7 +74,7 @@ export default {
...
@@ -68,7 +74,7 @@ export default {
<img
<img
class=
"avatar"
class=
"avatar"
:class=
"[avatarSizeClass, cssClasses]"
:class=
"[avatarSizeClass, cssClasses]"
:src=
"im
gSrc
"
:src=
"im
ageSource
"
:width=
"size"
:width=
"size"
:height=
"size"
:height=
"size"
:alt=
"imgAlt"
:alt=
"imgAlt"
...
...
app/assets/stylesheets/pages/pipelines.scss
View file @
228b73d5
...
@@ -984,3 +984,11 @@
...
@@ -984,3 +984,11 @@
width
:
12px
;
width
:
12px
;
}
}
}
}
.pipeline-header-container
{
min-height
:
55px
;
.text-center
{
padding-top
:
12px
;
}
}
app/serializers/user_entity.rb
View file @
228b73d5
class
UserEntity
<
API
::
Entities
::
UserBasic
class
UserEntity
<
API
::
Entities
::
UserBasic
include
RequestAwareEntity
expose
:path
do
|
user
|
user_path
(
user
)
end
end
end
app/views/projects/pipelines/_info.html.haml
View file @
228b73d5
.page-content-header
#js-pipeline-header-vue
.pipeline-header-container
.header-main-content
=
render
'ci/status/badge'
,
status:
@pipeline
.
detailed_status
(
current_user
),
title:
@pipeline
.
status_title
%strong
Pipeline ##{@pipeline.id}
triggered
#{
time_ago_with_tooltip
(
@pipeline
.
created_at
)
}
-
if
@pipeline
.
user
by
=
user_avatar
(
user:
@pipeline
.
user
,
size:
24
)
=
user_link
(
@pipeline
.
user
)
.header-action-buttons
-
if
can?
(
current_user
,
:update_pipeline
,
@pipeline
.
project
)
-
if
@pipeline
.
retryable?
=
link_to
"Retry"
,
retry_namespace_project_pipeline_path
(
@pipeline
.
project
.
namespace
,
@pipeline
.
project
,
@pipeline
.
id
),
class:
'js-retry-button btn btn-inverted-secondary'
,
method: :post
-
if
@pipeline
.
cancelable?
=
link_to
"Cancel running"
,
cancel_namespace_project_pipeline_path
(
@pipeline
.
project
.
namespace
,
@pipeline
.
project
,
@pipeline
.
id
),
data:
{
confirm:
'Are you sure?'
},
class:
'btn btn-danger'
,
method: :post
-
if
@commit
-
if
@commit
.commit-box
.commit-box
...
...
changelogs/unreleased/31849-pipeline-real-time-header.yml
0 → 100644
View file @
228b73d5
---
title
:
Makes header information of pipeline show page realtine
merge_request
:
author
:
spec/features/commits_spec.rb
View file @
228b73d5
...
@@ -76,7 +76,7 @@ describe 'Commits' do
...
@@ -76,7 +76,7 @@ describe 'Commits' do
end
end
end
end
describe
'Commit builds'
do
describe
'Commit builds'
,
:feature
,
:js
do
before
do
before
do
visit
ci_status_path
(
pipeline
)
visit
ci_status_path
(
pipeline
)
end
end
...
@@ -85,7 +85,6 @@ describe 'Commits' do
...
@@ -85,7 +85,6 @@ describe 'Commits' do
expect
(
page
).
to
have_content
pipeline
.
sha
[
0
..
7
]
expect
(
page
).
to
have_content
pipeline
.
sha
[
0
..
7
]
expect
(
page
).
to
have_content
pipeline
.
git_commit_message
expect
(
page
).
to
have_content
pipeline
.
git_commit_message
expect
(
page
).
to
have_content
pipeline
.
user
.
name
expect
(
page
).
to
have_content
pipeline
.
user
.
name
expect
(
page
).
to
have_content
pipeline
.
created_at
.
strftime
(
'%b %d, %Y'
)
end
end
end
end
...
@@ -102,7 +101,7 @@ describe 'Commits' do
...
@@ -102,7 +101,7 @@ describe 'Commits' do
end
end
describe
'Cancel all builds'
do
describe
'Cancel all builds'
do
it
'cancels commit'
do
it
'cancels commit'
,
:js
do
visit
ci_status_path
(
pipeline
)
visit
ci_status_path
(
pipeline
)
click_on
'Cancel running'
click_on
'Cancel running'
expect
(
page
).
to
have_content
'canceled'
expect
(
page
).
to
have_content
'canceled'
...
@@ -110,9 +109,9 @@ describe 'Commits' do
...
@@ -110,9 +109,9 @@ describe 'Commits' do
end
end
describe
'Cancel build'
do
describe
'Cancel build'
do
it
'cancels build'
do
it
'cancels build'
,
:js
do
visit
ci_status_path
(
pipeline
)
visit
ci_status_path
(
pipeline
)
find
(
'
a.btn[title="Cancel"]
'
).
click
find
(
'
.js-btn-cancel-pipeline
'
).
click
expect
(
page
).
to
have_content
'canceled'
expect
(
page
).
to
have_content
'canceled'
end
end
end
end
...
@@ -152,17 +151,20 @@ describe 'Commits' do
...
@@ -152,17 +151,20 @@ describe 'Commits' do
visit
ci_status_path
(
pipeline
)
visit
ci_status_path
(
pipeline
)
end
end
it
do
it
'Renders header'
,
:feature
,
:js
do
expect
(
page
).
to
have_content
pipeline
.
sha
[
0
..
7
]
expect
(
page
).
to
have_content
pipeline
.
sha
[
0
..
7
]
expect
(
page
).
to
have_content
pipeline
.
git_commit_message
expect
(
page
).
to
have_content
pipeline
.
git_commit_message
expect
(
page
).
to
have_content
pipeline
.
user
.
name
expect
(
page
).
to
have_content
pipeline
.
user
.
name
expect
(
page
).
to
have_link
(
'Download artifacts'
)
expect
(
page
).
not_to
have_link
(
'Cancel running'
)
expect
(
page
).
not_to
have_link
(
'Cancel running'
)
expect
(
page
).
not_to
have_link
(
'Retry'
)
expect
(
page
).
not_to
have_link
(
'Retry'
)
end
end
it
do
expect
(
page
).
to
have_link
(
'Download artifacts'
)
end
end
end
context
'when accessing internal project with disallowed access'
do
context
'when accessing internal project with disallowed access'
,
:feature
,
:js
do
before
do
before
do
project
.
update
(
project
.
update
(
visibility_level:
Gitlab
::
VisibilityLevel
::
INTERNAL
,
visibility_level:
Gitlab
::
VisibilityLevel
::
INTERNAL
,
...
@@ -175,7 +177,7 @@ describe 'Commits' do
...
@@ -175,7 +177,7 @@ describe 'Commits' do
expect
(
page
).
to
have_content
pipeline
.
sha
[
0
..
7
]
expect
(
page
).
to
have_content
pipeline
.
sha
[
0
..
7
]
expect
(
page
).
to
have_content
pipeline
.
git_commit_message
expect
(
page
).
to
have_content
pipeline
.
git_commit_message
expect
(
page
).
to
have_content
pipeline
.
user
.
name
expect
(
page
).
to
have_content
pipeline
.
user
.
name
expect
(
page
).
not_to
have_link
(
'Download artifacts'
)
expect
(
page
).
not_to
have_link
(
'Cancel running'
)
expect
(
page
).
not_to
have_link
(
'Cancel running'
)
expect
(
page
).
not_to
have_link
(
'Retry'
)
expect
(
page
).
not_to
have_link
(
'Retry'
)
end
end
...
...
spec/features/projects/pipelines/pipeline_spec.rb
View file @
228b73d5
...
@@ -229,7 +229,6 @@ describe 'Pipeline', :feature, :js do
...
@@ -229,7 +229,6 @@ describe 'Pipeline', :feature, :js do
before
{
find
(
'.js-retry-button'
).
trigger
(
'click'
)
}
before
{
find
(
'.js-retry-button'
).
trigger
(
'click'
)
}
it
{
expect
(
page
).
not_to
have_content
(
'Retry'
)
}
it
{
expect
(
page
).
not_to
have_content
(
'Retry'
)
}
it
{
expect
(
page
).
to
have_selector
(
'.retried'
)
}
end
end
end
end
...
@@ -240,7 +239,6 @@ describe 'Pipeline', :feature, :js do
...
@@ -240,7 +239,6 @@ describe 'Pipeline', :feature, :js do
before
{
click_on
'Cancel running'
}
before
{
click_on
'Cancel running'
}
it
{
expect
(
page
).
not_to
have_content
(
'Cancel running'
)
}
it
{
expect
(
page
).
not_to
have_content
(
'Cancel running'
)
}
it
{
expect
(
page
).
to
have_selector
(
'.ci-canceled'
)
}
end
end
end
end
...
...
spec/javascripts/pipelines/header_component_spec.js
0 → 100644
View file @
228b73d5
import
Vue
from
'
vue
'
;
import
headerComponent
from
'
~/pipelines/components/header_component.vue
'
;
import
eventHub
from
'
~/pipelines/event_hub
'
;
describe
(
'
Pipeline details header
'
,
()
=>
{
let
HeaderComponent
;
let
vm
;
let
props
;
beforeEach
(()
=>
{
HeaderComponent
=
Vue
.
extend
(
headerComponent
);
props
=
{
pipeline
:
{
details
:
{
status
:
{
group
:
'
failed
'
,
icon
:
'
ci-status-failed
'
,
label
:
'
failed
'
,
text
:
'
failed
'
,
details_path
:
'
path
'
,
},
},
id
:
123
,
created_at
:
'
2017-05-08T14:57:39.781Z
'
,
user
:
{
web_url
:
'
path
'
,
name
:
'
Foo
'
,
username
:
'
foobar
'
,
email
:
'
foo@bar.com
'
,
avatar_url
:
'
link
'
,
},
retry_path
:
'
path
'
,
},
isLoading
:
false
,
};
vm
=
new
HeaderComponent
({
propsData
:
props
}).
$mount
();
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
it
(
'
should render provided pipeline info
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.header-main-content
'
).
textContent
.
replace
(
/
\s
+/g
,
'
'
).
trim
(),
).
toEqual
(
'
failed Pipeline #123 triggered 3 weeks ago by Foo
'
);
});
describe
(
'
action buttons
'
,
()
=>
{
it
(
'
should call postAction when button action is clicked
'
,
()
=>
{
eventHub
.
$on
(
'
headerPostAction
'
,
(
action
)
=>
{
expect
(
action
.
path
).
toEqual
(
'
path
'
);
});
vm
.
$el
.
querySelector
(
'
button
'
).
click
();
});
});
});
spec/javascripts/pipelines/pipeline_details_mediator_spec.js
0 → 100644
View file @
228b73d5
import
Vue
from
'
vue
'
;
import
PipelineMediator
from
'
~/pipelines/pipeline_details_mediatior
'
;
describe
(
'
PipelineMdediator
'
,
()
=>
{
let
mediator
;
beforeEach
(()
=>
{
mediator
=
new
PipelineMediator
({
endpoint
:
'
foo
'
});
});
it
(
'
should set defaults
'
,
()
=>
{
expect
(
mediator
.
options
).
toEqual
({
endpoint
:
'
foo
'
});
expect
(
mediator
.
state
.
isLoading
).
toEqual
(
false
);
expect
(
mediator
.
store
).
toBeDefined
();
expect
(
mediator
.
service
).
toBeDefined
();
});
describe
(
'
request and store data
'
,
()
=>
{
const
interceptor
=
(
request
,
next
)
=>
{
next
(
request
.
respondWith
(
JSON
.
stringify
({
foo
:
'
bar
'
}),
{
status
:
200
,
}));
};
beforeEach
(()
=>
{
Vue
.
http
.
interceptors
.
push
(
interceptor
);
});
afterEach
(()
=>
{
Vue
.
http
.
interceptors
=
_
.
without
(
Vue
.
http
.
interceptor
,
interceptor
);
});
it
(
'
should store received data
'
,
(
done
)
=>
{
mediator
.
fetchPipeline
();
setTimeout
(()
=>
{
expect
(
mediator
.
store
.
state
.
pipeline
).
toEqual
({
foo
:
'
bar
'
});
done
();
});
});
});
});
spec/javascripts/pipelines/pipeline_store_spec.js
0 → 100644
View file @
228b73d5
import
PipelineStore
from
'
~/pipelines/stores/pipeline_store
'
;
describe
(
'
Pipeline Store
'
,
()
=>
{
let
store
;
beforeEach
(()
=>
{
store
=
new
PipelineStore
();
});
it
(
'
should set defaults
'
,
()
=>
{
expect
(
store
.
state
).
toEqual
({
pipeline
:
{}
});
expect
(
store
.
state
.
pipeline
).
toEqual
({});
});
describe
(
'
storePipeline
'
,
()
=>
{
it
(
'
should store empty object if none is provided
'
,
()
=>
{
store
.
storePipeline
();
expect
(
store
.
state
.
pipeline
).
toEqual
({});
});
it
(
'
should store received object
'
,
()
=>
{
store
.
storePipeline
({
foo
:
'
bar
'
});
expect
(
store
.
state
.
pipeline
).
toEqual
({
foo
:
'
bar
'
});
});
});
});
spec/javascripts/pipelines/pipeline_url_spec.js
View file @
228b73d5
...
@@ -47,6 +47,7 @@ describe('Pipeline Url Component', () => {
...
@@ -47,6 +47,7 @@ describe('Pipeline Url Component', () => {
web_url
:
'
/
'
,
web_url
:
'
/
'
,
name
:
'
foo
'
,
name
:
'
foo
'
,
avatar_url
:
'
/
'
,
avatar_url
:
'
/
'
,
path
:
'
/
'
,
},
},
},
},
};
};
...
...
spec/javascripts/vue_shared/components/commit_spec.js
View file @
228b73d5
...
@@ -24,6 +24,7 @@ describe('Commit component', () => {
...
@@ -24,6 +24,7 @@ describe('Commit component', () => {
author
:
{
author
:
{
avatar_url
:
'
https://gitlab.com/uploads/user/avatar/300478/avatar.png
'
,
avatar_url
:
'
https://gitlab.com/uploads/user/avatar/300478/avatar.png
'
,
web_url
:
'
https://gitlab.com/jschatz1
'
,
web_url
:
'
https://gitlab.com/jschatz1
'
,
path
:
'
/jschatz1
'
,
username
:
'
jschatz1
'
,
username
:
'
jschatz1
'
,
},
},
},
},
...
@@ -46,6 +47,7 @@ describe('Commit component', () => {
...
@@ -46,6 +47,7 @@ describe('Commit component', () => {
author
:
{
author
:
{
avatar_url
:
'
https://gitlab.com/uploads/user/avatar/300478/avatar.png
'
,
avatar_url
:
'
https://gitlab.com/uploads/user/avatar/300478/avatar.png
'
,
web_url
:
'
https://gitlab.com/jschatz1
'
,
web_url
:
'
https://gitlab.com/jschatz1
'
,
path
:
'
/jschatz1
'
,
username
:
'
jschatz1
'
,
username
:
'
jschatz1
'
,
},
},
commitIconSvg
:
'
<svg></svg>
'
,
commitIconSvg
:
'
<svg></svg>
'
,
...
@@ -81,7 +83,7 @@ describe('Commit component', () => {
...
@@ -81,7 +83,7 @@ describe('Commit component', () => {
it
(
'
should render a link to the author profile
'
,
()
=>
{
it
(
'
should render a link to the author profile
'
,
()
=>
{
expect
(
expect
(
component
.
$el
.
querySelector
(
'
.commit-title .avatar-image-container
'
).
getAttribute
(
'
href
'
),
component
.
$el
.
querySelector
(
'
.commit-title .avatar-image-container
'
).
getAttribute
(
'
href
'
),
).
toEqual
(
props
.
author
.
web_url
);
).
toEqual
(
props
.
author
.
path
);
});
});
it
(
'
Should render the author avatar with title and alt attributes
'
,
()
=>
{
it
(
'
Should render the author avatar with title and alt attributes
'
,
()
=>
{
...
...
spec/javascripts/vue_shared/components/header_ci_component_spec.js
View file @
228b73d5
...
@@ -33,12 +33,14 @@ describe('Header CI Component', () => {
...
@@ -33,12 +33,14 @@ describe('Header CI Component', () => {
path
:
'
path
'
,
path
:
'
path
'
,
type
:
'
button
'
,
type
:
'
button
'
,
cssClass
:
'
btn
'
,
cssClass
:
'
btn
'
,
isLoading
:
false
,
},
},
{
{
label
:
'
Go
'
,
label
:
'
Go
'
,
path
:
'
path
'
,
path
:
'
path
'
,
type
:
'
link
'
,
type
:
'
link
'
,
cssClass
:
'
link
'
,
cssClass
:
'
link
'
,
isLoading
:
false
,
},
},
],
],
};
};
...
@@ -79,4 +81,13 @@ describe('Header CI Component', () => {
...
@@ -79,4 +81,13 @@ describe('Header CI Component', () => {
expect
(
vm
.
$el
.
querySelector
(
'
.link
'
).
textContent
.
trim
()).
toEqual
(
props
.
actions
[
1
].
label
);
expect
(
vm
.
$el
.
querySelector
(
'
.link
'
).
textContent
.
trim
()).
toEqual
(
props
.
actions
[
1
].
label
);
expect
(
vm
.
$el
.
querySelector
(
'
.link
'
).
getAttribute
(
'
href
'
)).
toEqual
(
props
.
actions
[
0
].
path
);
expect
(
vm
.
$el
.
querySelector
(
'
.link
'
).
getAttribute
(
'
href
'
)).
toEqual
(
props
.
actions
[
0
].
path
);
});
});
it
(
'
should show loading icon
'
,
(
done
)
=>
{
vm
.
actions
[
0
].
isLoading
=
true
;
Vue
.
nextTick
(()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.btn .fa-spinner
'
).
getAttribute
(
'
style
'
)).
toEqual
(
''
);
done
();
});
});
});
});
spec/javascripts/vue_shared/components/pipelines_table_row_spec.js
View file @
228b73d5
...
@@ -76,7 +76,7 @@ describe('Pipelines Table Row', () => {
...
@@ -76,7 +76,7 @@ describe('Pipelines Table Row', () => {
it
(
'
should render user information
'
,
()
=>
{
it
(
'
should render user information
'
,
()
=>
{
expect
(
expect
(
component
.
$el
.
querySelector
(
'
td:nth-child(2) a:nth-child(3)
'
).
getAttribute
(
'
href
'
),
component
.
$el
.
querySelector
(
'
td:nth-child(2) a:nth-child(3)
'
).
getAttribute
(
'
href
'
),
).
toEqual
(
pipeline
.
user
.
web_url
);
).
toEqual
(
pipeline
.
user
.
path
);
expect
(
expect
(
component
.
$el
.
querySelector
(
'
td:nth-child(2) img
'
).
getAttribute
(
'
data-original-title
'
),
component
.
$el
.
querySelector
(
'
td:nth-child(2) img
'
).
getAttribute
(
'
data-original-title
'
),
...
@@ -120,7 +120,7 @@ describe('Pipelines Table Row', () => {
...
@@ -120,7 +120,7 @@ describe('Pipelines Table Row', () => {
component
=
buildComponent
(
pipeline
);
component
=
buildComponent
(
pipeline
);
const
{
commitAuthorLink
,
commitAuthorName
}
=
findElements
();
const
{
commitAuthorLink
,
commitAuthorName
}
=
findElements
();
expect
(
commitAuthorLink
).
toEqual
(
pipeline
.
commit
.
author
.
web_url
);
expect
(
commitAuthorLink
).
toEqual
(
pipeline
.
commit
.
author
.
path
);
expect
(
commitAuthorName
).
toEqual
(
pipeline
.
commit
.
author
.
username
);
expect
(
commitAuthorName
).
toEqual
(
pipeline
.
commit
.
author
.
username
);
});
});
...
...
spec/serializers/user_entity_spec.rb
View file @
228b73d5
require
'spec_helper'
require
'spec_helper'
describe
UserEntity
do
describe
UserEntity
do
include
Gitlab
::
Routing
let
(
:entity
)
{
described_class
.
new
(
user
)
}
let
(
:entity
)
{
described_class
.
new
(
user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
subject
{
entity
.
as_json
}
subject
{
entity
.
as_json
}
...
@@ -20,4 +22,8 @@ describe UserEntity do
...
@@ -20,4 +22,8 @@ describe UserEntity do
it
'does not expose 2FA OTPs'
do
it
'does not expose 2FA OTPs'
do
expect
(
subject
).
not_to
include
(
/otp/
)
expect
(
subject
).
not_to
include
(
/otp/
)
end
end
it
'exposes user path'
do
expect
(
subject
[
:path
]).
to
eq
user_path
(
user
)
end
end
end
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