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
2a33bcbc
Commit
2a33bcbc
authored
Sep 09, 2020
by
Nicolò Maria Mezzopera
Committed by
Kushal Pandya
Sep 09, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add new title_area component
- new component - tests
parent
a729fbbe
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
486 additions
and
346 deletions
+486
-346
app/assets/javascripts/packages/details/components/app.vue
app/assets/javascripts/packages/details/components/app.vue
+4
-6
app/assets/javascripts/packages/details/components/package_title.vue
...javascripts/packages/details/components/package_title.vue
+51
-67
app/assets/javascripts/registry/explorer/components/details_page/details_header.vue
...istry/explorer/components/details_page/details_header.vue
+6
-5
app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue
...egistry/explorer/components/list_page/registry_header.vue
+27
-30
app/assets/javascripts/vue_shared/components/registry/title_area.vue
...javascripts/vue_shared/components/registry/title_area.vue
+66
-0
spec/frontend/packages/details/components/__snapshots__/package_title_spec.js.snap
...tails/components/__snapshots__/package_title_spec.js.snap
+126
-127
spec/frontend/packages/details/components/app_spec.js
spec/frontend/packages/details/components/app_spec.js
+2
-0
spec/frontend/packages/details/components/package_title_spec.js
...rontend/packages/details/components/package_title_spec.js
+42
-39
spec/frontend/registry/explorer/components/details_page/details_header_spec.js
...y/explorer/components/details_page/details_header_spec.js
+2
-0
spec/frontend/registry/explorer/components/list_page/registry_header_spec.js
...try/explorer/components/list_page/registry_header_spec.js
+59
-71
spec/frontend/registry/explorer/pages/list_spec.js
spec/frontend/registry/explorer/pages/list_spec.js
+2
-0
spec/frontend/vue_shared/components/registry/title_area_spec.js
...rontend/vue_shared/components/registry/title_area_spec.js
+98
-0
spec/support/shared_examples/features/packages_shared_examples.rb
...port/shared_examples/features/packages_shared_examples.rb
+1
-1
No files found.
app/assets/javascripts/packages/details/components/app.vue
View file @
2a33bcbc
...
...
@@ -147,10 +147,8 @@ export default {
/>
<div
v-else
class=
"packages-app"
>
<div
class=
"detail-page-header d-flex justify-content-between flex-column flex-sm-row"
>
<package-title
/>
<div
class=
"mt-sm-2"
>
<package-title>
<template
#delete-button
>
<gl-button
v-if=
"canDeletePackage"
v-gl-modal=
"'delete-modal'"
...
...
@@ -161,8 +159,8 @@ export default {
>
{{
__
(
'
Delete
'
)
}}
</gl-button>
</
div
>
</
div
>
</
template
>
</
package-title
>
<gl-tabs>
<gl-tab
:title=
"__('Detail')"
>
...
...
app/assets/javascripts/packages/details/components/package_title.vue
View file @
2a33bcbc
<
script
>
import
{
mapState
,
mapGetters
}
from
'
vuex
'
;
import
{
Gl
Avatar
,
Gl
Icon
,
GlLink
,
GlSprintf
,
GlTooltipDirective
}
from
'
@gitlab/ui
'
;
import
{
GlIcon
,
GlLink
,
GlSprintf
,
GlTooltipDirective
}
from
'
@gitlab/ui
'
;
import
PackageTags
from
'
../../shared/components/package_tags.vue
'
;
import
{
numberToHumanSize
}
from
'
~/lib/utils/number_utils
'
;
import
timeagoMixin
from
'
~/vue_shared/mixins/timeago
'
;
import
TitleArea
from
'
~/vue_shared/components/registry/title_area.vue
'
;
import
{
__
}
from
'
~/locale
'
;
export
default
{
name
:
'
PackageTitle
'
,
components
:
{
GlAvatar
,
TitleArea
,
GlIcon
,
GlLink
,
GlSprintf
,
...
...
@@ -36,77 +37,60 @@ export default {
</
script
>
<
template
>
<div
class=
"gl-flex-direction-column"
>
<div
class=
"gl-display-flex"
>
<gl-avatar
v-if=
"packageIcon"
:src=
"packageIcon"
shape=
"rect"
class=
"gl-align-self-center gl-mr-4"
data-testid=
"package-icon"
/>
<title-area
:title=
"packageEntity.name"
:avatar=
"packageIcon"
data-qa-selector=
"package_title"
>
<template
#sub-header
>
<gl-icon
name=
"eye"
class=
"gl-mr-3"
/>
<gl-sprintf
:message=
"$options.i18n.packageInfo"
>
<template
#version
>
{{
packageEntity
.
version
}}
</
template
>
<div
class=
"gl-display-flex gl-flex-direction-column"
>
<h1
class=
"gl-font-size-h1 gl-mt-3 gl-mb-2"
>
{{
packageEntity
.
name
}}
</h1>
<
template
#timeAgo
>
<span
v-gl-tooltip
:title=
"tooltipTitle(packageEntity.created_at)"
>
{{
timeFormatted
(
packageEntity
.
created_at
)
}}
</span>
</
template
>
</gl-sprintf>
</template>
<div
class=
"gl-display-flex gl-align-items-center gl-text-gray-500"
>
<gl-icon
name=
"eye"
class=
"gl-mr-3"
/>
<gl-sprintf
:message=
"$options.i18n.packageInfo"
>
<template
#version
>
{{
packageEntity
.
version
}}
</
template
>
<
template
v-if=
"packageTypeDisplay"
#metadata_type
>
<gl-icon
name=
"package"
class=
"gl-text-gray-500 gl-mr-3"
/>
<span
data-testid=
"package-type"
class=
"gl-font-weight-bold"
>
{{
packageTypeDisplay
}}
</span>
</
template
>
<
template
#timeAgo
>
<span
v-gl-tooltip
:title=
"tooltipTitle(packageEntity.created_at)"
>
{{
timeFormatted
(
packageEntity
.
created_at
)
}}
</span>
</
template
>
</gl-sprintf>
</div>
</div>
</div>
<
template
#metadata_size
>
<gl-icon
name=
"disk"
class=
"gl-text-gray-500 gl-mr-3"
/>
<span
data-testid=
"package-size"
class=
"gl-font-weight-bold"
>
{{
totalSize
}}
</span>
</
template
>
<div
class=
"gl-display-flex gl-flex-wrap gl-align-items-center gl-mb-3"
>
<div
v-if=
"packageTypeDisplay"
class=
"gl-display-flex gl-align-items-center gl-mr-5"
>
<gl-icon
name=
"package"
class=
"gl-text-gray-500 gl-mr-3"
/>
<span
data-testid=
"package-type"
class=
"gl-font-weight-bold"
>
{{ packageTypeDisplay }}
</span>
</div>
<div
class=
"gl-display-flex gl-align-items-center gl-mr-5"
>
<gl-icon
name=
"disk"
class=
"gl-text-gray-500 gl-mr-3"
/>
<span
data-testid=
"package-size"
class=
"gl-font-weight-bold"
>
{{ totalSize }}
</span>
</div>
<div
v-if=
"packagePipeline"
class=
"gl-display-flex gl-align-items-center gl-mr-5"
>
<gl-icon
name=
"review-list"
class=
"gl-text-gray-500 gl-mr-3"
/>
<gl-link
data-testid=
"pipeline-project"
:href=
"packagePipeline.project.web_url"
class=
"gl-font-weight-bold text-truncate"
>
{{ packagePipeline.project.name }}
</gl-link>
</div>
<
template
v-if=
"packagePipeline"
#metadata_pipeline
>
<gl-icon
name=
"review-list"
class=
"gl-text-gray-500 gl-mr-3"
/>
<gl-link
data-testid=
"pipeline-project"
:href=
"packagePipeline.project.web_url"
class=
"gl-font-weight-bold gl-str-truncated"
>
{{
packagePipeline
.
project
.
name
}}
</gl-link>
</
template
>
<div
v-if=
"packagePipeline"
<
template
v-if=
"packagePipeline"
#metadata_ref
>
<gl-icon
name=
"branch"
data-testid=
"package-ref-icon"
class=
"gl-text-gray-500 gl-mr-3"
/>
<span
v-gl-tooltip
data-testid=
"package-ref"
class=
"gl-display-flex gl-align-items-center gl-mr-5"
class=
"gl-font-weight-bold gl-str-truncated mw-xs"
:title=
"packagePipeline.ref"
>
{{
packagePipeline
.
ref
}}
</span
>
<gl-icon
name=
"branch"
class=
"gl-text-gray-500 gl-mr-3"
/>
<span
v-gl-tooltip
class=
"gl-font-weight-bold text-truncate mw-xs"
:title=
"packagePipeline.ref"
>
{{ packagePipeline.ref }}
</span
>
</div>
</
template
>
<
template
v-if=
"hasTagsToDisplay"
#metadata_tags
>
<package-tags
:tag-display-limit=
"2"
:tags=
"packageEntity.tags"
hide-label
/>
</
template
>
<div
v-if=
"hasTagsToDisplay"
class=
"gl-display-flex gl-align-items-center gl-mr-5"
>
<package-tags
:tag-display-limit=
"2"
:tags=
"packageEntity.tags"
hide-label
/>
</div>
</div>
</div>
<
template
#right-actions
>
<slot
name=
"delete-button"
></slot>
</
template
>
</title-area>
</template>
app/assets/javascripts/registry/explorer/components/details_page/details_header.vue
View file @
2a33bcbc
<
script
>
import
{
GlSprintf
}
from
'
@gitlab/ui
'
;
import
TitleArea
from
'
~/vue_shared/components/registry/title_area.vue
'
;
import
{
DETAILS_PAGE_TITLE
}
from
'
../../constants/index
'
;
export
default
{
components
:
{
GlSprintf
},
components
:
{
GlSprintf
,
TitleArea
},
props
:
{
imageName
:
{
type
:
String
,
...
...
@@ -18,13 +19,13 @@ export default {
</
script
>
<
template
>
<
div
class=
"gl-display-flex gl-my-2 gl-align-items-center"
>
<
h4
>
<
title-area
>
<
template
#title
>
<gl-sprintf
:message=
"$options.i18n.DETAILS_PAGE_TITLE"
>
<template
#imageName
>
{{
imageName
}}
</
template
>
</gl-sprintf>
</
h4
>
</
div
>
</
template
>
</
title-area
>
</template>
app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue
View file @
2a33bcbc
<
script
>
import
{
GlSprintf
,
GlLink
,
GlIcon
}
from
'
@gitlab/ui
'
;
import
TitleArea
from
'
~/vue_shared/components/registry/title_area.vue
'
;
import
{
n__
}
from
'
~/locale
'
;
import
{
approximateDuration
,
calculateRemainingMilliseconds
}
from
'
~/lib/utils/datetime_utility
'
;
...
...
@@ -16,6 +17,7 @@ export default {
GlIcon
,
GlSprintf
,
GlLink
,
TitleArea
,
},
props
:
{
expirationPolicy
:
{
...
...
@@ -85,37 +87,32 @@ export default {
<
template
>
<div>
<div
class=
"gl-display-flex gl-justify-content-space-between gl-align-items-center"
data-testid=
"header"
>
<h4
data-testid=
"title"
>
{{
$options
.
i18n
.
CONTAINER_REGISTRY_TITLE
}}
</h4>
<div
class=
"gl-display-none d-sm-block"
data-testid=
"commands-slot"
>
<title-area
:title=
"$options.i18n.CONTAINER_REGISTRY_TITLE"
>
<template
#right-actions
>
<slot
name=
"commands"
></slot>
</div>
</div>
<div
v-if=
"imagesCount"
class=
"gl-display-flex gl-align-items-center gl-mt-1 gl-mb-3 gl-text-gray-500"
data-testid=
"subheader"
>
<span
class=
"gl-mr-3"
data-testid=
"images-count"
>
<gl-icon
class=
"gl-mr-1"
name=
"container-image"
/>
<gl-sprintf
:message=
"imagesCountText"
>
<template
#count
>
{{
imagesCount
}}
</
template
>
</gl-sprintf>
</span>
<span
v-if=
"!hideExpirationPolicyData"
data-testid=
"expiration-policy"
>
<gl-icon
class=
"gl-mr-1"
name=
"expire"
/>
<gl-sprintf
:message=
"expirationPolicyText"
>
<
template
#time
>
{{
timeTillRun
}}
</
template
>
</gl-sprintf>
</span>
</div>
</
template
>
<
template
#metadata_count
>
<span
v-if=
"imagesCount"
data-testid=
"images-count"
>
<gl-icon
class=
"gl-mr-1"
name=
"container-image"
/>
<gl-sprintf
:message=
"imagesCountText"
>
<template
#count
>
{{
imagesCount
}}
</
template
>
</gl-sprintf>
</span>
</template>
<
template
#metadata_exp_policies
>
<span
v-if=
"!hideExpirationPolicyData"
data-testid=
"expiration-policy"
>
<gl-icon
class=
"gl-mr-1"
name=
"expire"
/>
<gl-sprintf
:message=
"expirationPolicyText"
>
<template
#time
>
{{
timeTillRun
}}
</
template
>
</gl-sprintf>
</span>
</template>
</title-area>
<div
data-testid=
"info-area"
>
<p>
<span
data-testid=
"default-intro"
>
...
...
app/assets/javascripts/vue_shared/components/registry/title_area.vue
0 → 100644
View file @
2a33bcbc
<
script
>
import
{
GlAvatar
}
from
'
@gitlab/ui
'
;
export
default
{
name
:
'
TitleArea
'
,
components
:
{
GlAvatar
,
},
props
:
{
avatar
:
{
type
:
String
,
default
:
null
,
required
:
false
,
},
title
:
{
type
:
String
,
default
:
null
,
required
:
false
,
},
},
data
()
{
return
{
metadataSlots
:
[],
};
},
mounted
()
{
this
.
metadataSlots
=
Object
.
keys
(
this
.
$slots
).
filter
(
k
=>
k
.
startsWith
(
'
metadata_
'
));
},
};
</
script
>
<
template
>
<div
class=
"gl-display-flex gl-justify-content-space-between gl-py-3"
>
<div
class=
"gl-flex-direction-column"
>
<div
class=
"gl-display-flex"
>
<gl-avatar
v-if=
"avatar"
:src=
"avatar"
shape=
"rect"
class=
"gl-align-self-center gl-mr-4"
/>
<div
class=
"gl-display-flex gl-flex-direction-column"
>
<h1
class=
"gl-font-size-h1 gl-mt-3 gl-mb-2"
data-testid=
"title"
>
<slot
name=
"title"
>
{{
title
}}
</slot>
</h1>
<div
v-if=
"$slots['sub-header']"
class=
"gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-1"
>
<slot
name=
"sub-header"
></slot>
</div>
</div>
</div>
<div
class=
"gl-display-flex gl-flex-wrap gl-align-items-center gl-mt-3"
>
<div
v-for=
"(row, metadataIndex) in metadataSlots"
:key=
"metadataIndex"
class=
"gl-display-flex gl-align-items-center gl-mr-5"
>
<slot
:name=
"row"
></slot>
</div>
</div>
</div>
<div
v-if=
"$slots['right-actions']"
class=
"gl-mt-3"
>
<slot
name=
"right-actions"
></slot>
</div>
</div>
</
template
>
spec/frontend/packages/details/components/__snapshots__/package_title_spec.js.snap
View file @
2a33bcbc
...
...
@@ -2,172 +2,171 @@
exports[`PackageTitle renders with tags 1`] = `
<div
class="gl-flex-direction-column"
class="gl-display-flex gl-justify-content-space-between gl-py-3"
data-qa-selector="package_title"
>
<div
class="gl-
display-flex
"
class="gl-
flex-direction-column
"
>
<!---->
<div
class="gl-display-flex"
>
<!---->
<div
class="gl-display-flex gl-flex-direction-column"
>
<h1
class="gl-font-size-h1 gl-mt-3 gl-mb-2"
data-testid="title"
>
Test package
</h1>
<div
class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-1"
>
<gl-icon-stub
class="gl-mr-3"
name="eye"
size="16"
/>
<gl-sprintf-stub
message="v%{version} published %{timeAgo}"
/>
</div>
</div>
</div>
<div
class="gl-display-flex gl-flex-
direction-column
"
class="gl-display-flex gl-flex-
wrap gl-align-items-center gl-mt-3
"
>
<
h1
class="gl-
font-size-h1 gl-mt-3 gl-mb-2
"
<
div
class="gl-
display-flex gl-align-items-center gl-mr-5
"
>
Test package
</h1>
<gl-icon-stub
class="gl-text-gray-500 gl-mr-3"
name="package"
size="16"
/>
<span
class="gl-font-weight-bold"
data-testid="package-type"
>
maven
</span>
</div>
<div
class="gl-display-flex gl-align-items-center gl-
text-gray-500
"
class="gl-display-flex gl-align-items-center gl-
mr-5
"
>
<gl-icon-stub
class="gl-mr-3"
name="
eye
"
class="gl-
text-gray-500 gl-
mr-3"
name="
disk
"
size="16"
/>
<gl-sprintf-stub
message="v%{version} published %{timeAgo}"
<span
class="gl-font-weight-bold"
data-testid="package-size"
>
300 bytes
</span>
</div>
<div
class="gl-display-flex gl-align-items-center gl-mr-5"
>
<package-tags-stub
hidelabel="true"
tagdisplaylimit="2"
tags="[object Object],[object Object],[object Object],[object Object]"
/>
</div>
</div>
</div>
<div
class="gl-display-flex gl-flex-wrap gl-align-items-center gl-mb-3"
>
<div
class="gl-display-flex gl-align-items-center gl-mr-5"
>
<gl-icon-stub
class="gl-text-gray-500 gl-mr-3"
name="package"
size="16"
/>
<span
class="gl-font-weight-bold"
data-testid="package-type"
>
maven
</span>
</div>
<div
class="gl-display-flex gl-align-items-center gl-mr-5"
>
<gl-icon-stub
class="gl-text-gray-500 gl-mr-3"
name="disk"
size="16"
/>
<span
class="gl-font-weight-bold"
data-testid="package-size"
>
300 bytes
</span>
</div>
<!---->
<!---->
<div
class="gl-display-flex gl-align-items-center gl-mr-5"
>
<package-tags-stub
hidelabel="true"
tagdisplaylimit="2"
tags="[object Object],[object Object],[object Object],[object Object]"
/>
</div>
</div>
<!---->
</div>
`;
exports[`PackageTitle renders without tags 1`] = `
<div
class="gl-flex-direction-column"
class="gl-display-flex gl-justify-content-space-between gl-py-3"
data-qa-selector="package_title"
>
<div
class="gl-
display-flex
"
class="gl-
flex-direction-column
"
>
<!---->
<div
class="gl-display-flex
gl-flex-direction-column
"
class="gl-display-flex"
>
<h1
class="gl-font-size-h1 gl-mt-3 gl-mb-2"
>
Test package
</h1>
<!---->
<div
class="gl-display-flex gl-
align-items-center gl-text-gray-500
"
class="gl-display-flex gl-
flex-direction-column
"
>
<gl-icon-stub
class="gl-mr-3"
name="eye"
size="16"
/>
<h1
class="gl-font-size-h1 gl-mt-3 gl-mb-2"
data-testid="title"
>
Test package
</h1>
<gl-sprintf-stub
message="v%{version} published %{timeAgo}"
/>
<div
class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-1"
>
<gl-icon-stub
class="gl-mr-3"
name="eye"
size="16"
/>
<gl-sprintf-stub
message="v%{version} published %{timeAgo}"
/>
</div>
</div>
</div>
</div>
<div
class="gl-display-flex gl-flex-wrap gl-align-items-center gl-mb-3"
>
<div
class="gl-display-flex gl-align-items-center gl-mr-5"
>
<gl-icon-stub
class="gl-text-gray-500 gl-mr-3"
name="package"
size="16"
/>
<span
class="gl-font-weight-bold"
data-testid="package-type"
>
maven
</span>
</div>
<div
class="gl-display-flex gl-
align-items-center gl-mr-5
"
class="gl-display-flex gl-
flex-wrap gl-align-items-center gl-mt-3
"
>
<gl-icon-stub
class="gl-text-gray-500 gl-mr-3"
name="disk"
size="16"
/>
<span
class="gl-font-weight-bold"
data-testid="package-size"
<div
class="gl-display-flex gl-align-items-center gl-mr-5"
>
300 bytes
</span>
<gl-icon-stub
class="gl-text-gray-500 gl-mr-3"
name="package"
size="16"
/>
<span
class="gl-font-weight-bold"
data-testid="package-type"
>
maven
</span>
</div>
<div
class="gl-display-flex gl-align-items-center gl-mr-5"
>
<gl-icon-stub
class="gl-text-gray-500 gl-mr-3"
name="disk"
size="16"
/>
<span
class="gl-font-weight-bold"
data-testid="package-size"
>
300 bytes
</span>
</div>
</div>
<!---->
<!---->
<!---->
</div>
<!---->
</div>
`;
spec/frontend/packages/details/components/app_spec.js
View file @
2a33bcbc
...
...
@@ -65,6 +65,8 @@ describe('PackagesApp', () => {
store
,
stubs
:
{
...
stubChildren
(
PackagesApp
),
PackageTitle
:
false
,
TitleArea
:
false
,
GlButton
:
false
,
GlModal
:
false
,
GlTab
:
false
,
...
...
spec/frontend/packages/details/components/package_title_spec.js
View file @
2a33bcbc
...
...
@@ -2,6 +2,7 @@ import Vuex from 'vuex';
import
{
shallowMount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
PackageTitle
from
'
~/packages/details/components/package_title.vue
'
;
import
PackageTags
from
'
~/packages/shared/components/package_tags.vue
'
;
import
TitleArea
from
'
~/vue_shared/components/registry/title_area.vue
'
;
import
{
conanPackage
,
mavenFiles
,
...
...
@@ -39,14 +40,19 @@ describe('PackageTitle', () => {
wrapper
=
shallowMount
(
PackageTitle
,
{
localVue
,
store
,
stubs
:
{
TitleArea
,
},
});
return
wrapper
.
vm
.
$nextTick
();
}
const
packageIcon
=
()
=>
wrapper
.
find
(
'
[data-testid="package-icon"]
'
);
const
findTitleArea
=
()
=>
wrapper
.
find
(
TitleArea
);
const
packageType
=
()
=>
wrapper
.
find
(
'
[data-testid="package-type"]
'
);
const
packageSize
=
()
=>
wrapper
.
find
(
'
[data-testid="package-size"]
'
);
const
pipelineProject
=
()
=>
wrapper
.
find
(
'
[data-testid="pipeline-project"]
'
);
const
packageRef
=
()
=>
wrapper
.
find
(
'
[data-testid="package-ref"]
'
);
const
packageRefIcon
=
()
=>
wrapper
.
find
(
'
[data-testid="package-ref-icon"]
'
);
const
packageTags
=
()
=>
wrapper
.
find
(
PackageTags
);
afterEach
(()
=>
{
...
...
@@ -54,38 +60,40 @@ describe('PackageTitle', () => {
});
describe
(
'
renders
'
,
()
=>
{
it
(
'
without tags
'
,
()
=>
{
createComponent
();
it
(
'
without tags
'
,
async
()
=>
{
await
createComponent
();
expect
(
wrapper
.
element
).
toMatchSnapshot
();
});
it
(
'
with tags
'
,
()
=>
{
createComponent
({
packageEntity
:
{
...
mavenPackage
,
tags
:
mockTags
}
});
it
(
'
with tags
'
,
async
()
=>
{
await
createComponent
({
packageEntity
:
{
...
mavenPackage
,
tags
:
mockTags
}
});
expect
(
wrapper
.
element
).
toMatchSnapshot
();
});
});
describe
(
'
package icon
'
,
()
=>
{
const
fakeSrc
=
'
a-fake-src
'
;
describe
(
'
package title
'
,
()
=>
{
it
(
'
is correctly bound
'
,
async
()
=>
{
await
createComponent
();
it
(
'
shows an icon when provided one from vuex
'
,
()
=>
{
createComponent
({
icon
:
fakeSrc
});
expect
(
packageIcon
().
exists
()).
toBe
(
true
);
expect
(
findTitleArea
().
props
(
'
title
'
)).
toBe
(
'
Test package
'
);
});
});
it
(
'
has the correct src attribute
'
,
()
=>
{
createComponent
({
icon
:
fakeSrc
})
;
describe
(
'
package icon
'
,
()
=>
{
const
fakeSrc
=
'
a-fake-src
'
;
expect
(
packageIcon
().
props
(
'
src
'
)).
toBe
(
fakeSrc
);
it
(
'
binds an icon when provided one from vuex
'
,
async
()
=>
{
await
createComponent
({
icon
:
fakeSrc
});
expect
(
findTitleArea
().
props
(
'
avatar
'
)).
toBe
(
fakeSrc
);
});
it
(
'
do
es not show an icon when not provided one
'
,
()
=>
{
createComponent
();
it
(
'
do
not binds an icon when not provided one
'
,
async
()
=>
{
await
createComponent
();
expect
(
packageIcon
().
exists
()).
toBe
(
false
);
expect
(
findTitleArea
().
props
(
'
avatar
'
)).
toBe
(
null
);
});
});
...
...
@@ -104,22 +112,22 @@ describe('PackageTitle', () => {
});
describe
(
'
calculates the package size
'
,
()
=>
{
it
(
'
correctly cal
ulates when there is only 1 file
'
,
()
=>
{
createComponent
({
packageEntity
:
npmPackage
,
packageFiles
:
npmFiles
});
it
(
'
correctly cal
culates when there is only 1 file
'
,
async
()
=>
{
await
createComponent
({
packageEntity
:
npmPackage
,
packageFiles
:
npmFiles
});
expect
(
packageSize
().
text
()).
toBe
(
'
200 bytes
'
);
});
it
(
'
correctly calulates when there are multiple files
'
,
()
=>
{
createComponent
();
it
(
'
correctly calulates when there are multiple files
'
,
async
()
=>
{
await
createComponent
();
expect
(
packageSize
().
text
()).
toBe
(
'
300 bytes
'
);
});
});
describe
(
'
package tags
'
,
()
=>
{
it
(
'
displays the package-tags component when the package has tags
'
,
()
=>
{
createComponent
({
it
(
'
displays the package-tags component when the package has tags
'
,
async
()
=>
{
await
createComponent
({
packageEntity
:
{
...
npmPackage
,
tags
:
mockTags
,
...
...
@@ -129,41 +137,36 @@ describe('PackageTitle', () => {
expect
(
packageTags
().
exists
()).
toBe
(
true
);
});
it
(
'
does not display the package-tags component when there are no tags
'
,
()
=>
{
createComponent
();
it
(
'
does not display the package-tags component when there are no tags
'
,
async
()
=>
{
await
createComponent
();
expect
(
packageTags
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
package ref
'
,
()
=>
{
it
(
'
does not display the ref if missing
'
,
()
=>
{
createComponent
();
it
(
'
does not display the ref if missing
'
,
async
()
=>
{
await
createComponent
();
expect
(
packageRef
().
exists
()).
toBe
(
false
);
});
it
(
'
correctly shows the package ref if there is one
'
,
()
=>
{
createComponent
({
packageEntity
:
npmPackage
});
expect
(
packageRef
()
.
find
(
'
gl-icon-stub
'
)
.
exists
(),
).
toBe
(
true
);
it
(
'
correctly shows the package ref if there is one
'
,
async
()
=>
{
await
createComponent
({
packageEntity
:
npmPackage
});
expect
(
packageRefIcon
().
exists
()).
toBe
(
true
);
expect
(
packageRef
().
text
()).
toBe
(
npmPackage
.
pipeline
.
ref
);
});
});
describe
(
'
pipeline project
'
,
()
=>
{
it
(
'
does not display the project if missing
'
,
()
=>
{
createComponent
();
it
(
'
does not display the project if missing
'
,
async
()
=>
{
await
createComponent
();
expect
(
pipelineProject
().
exists
()).
toBe
(
false
);
});
it
(
'
correctly shows the pipeline project if there is one
'
,
()
=>
{
createComponent
({
packageEntity
:
npmPackage
});
it
(
'
correctly shows the pipeline project if there is one
'
,
async
()
=>
{
await
createComponent
({
packageEntity
:
npmPackage
});
expect
(
pipelineProject
().
text
()).
toBe
(
npmPackage
.
pipeline
.
project
.
name
);
expect
(
pipelineProject
().
attributes
(
'
href
'
)).
toBe
(
npmPackage
.
pipeline
.
project
.
web_url
);
...
...
spec/frontend/registry/explorer/components/details_page/details_header_spec.js
View file @
2a33bcbc
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
GlSprintf
}
from
'
@gitlab/ui
'
;
import
TitleArea
from
'
~/vue_shared/components/registry/title_area.vue
'
;
import
component
from
'
~/registry/explorer/components/details_page/details_header.vue
'
;
import
{
DETAILS_PAGE_TITLE
}
from
'
~/registry/explorer/constants
'
;
...
...
@@ -11,6 +12,7 @@ describe('Details Header', () => {
propsData
,
stubs
:
{
GlSprintf
,
TitleArea
,
},
});
};
...
...
spec/frontend/registry/explorer/components/list_page/registry_header_spec.js
View file @
2a33bcbc
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
GlSprintf
,
GlLink
}
from
'
@gitlab/ui
'
;
import
Component
from
'
~/registry/explorer/components/list_page/registry_header.vue
'
;
import
TitleArea
from
'
~/vue_shared/components/registry/title_area.vue
'
;
import
{
CONTAINER_REGISTRY_TITLE
,
LIST_INTRO_TEXT
,
...
...
@@ -17,12 +18,10 @@ jest.mock('~/lib/utils/datetime_utility', () => ({
describe
(
'
registry_header
'
,
()
=>
{
let
wrapper
;
const
findHeader
=
()
=>
wrapper
.
find
(
'
[data-testid="header"]
'
);
const
findTitle
=
()
=>
wrapper
.
find
(
'
[data-testid="title"]
'
);
const
findTitleArea
=
()
=>
wrapper
.
find
(
TitleArea
);
const
findCommandsSlot
=
()
=>
wrapper
.
find
(
'
[data-testid="commands-slot"]
'
);
const
findInfoArea
=
()
=>
wrapper
.
find
(
'
[data-testid="info-area"]
'
);
const
findIntroText
=
()
=>
wrapper
.
find
(
'
[data-testid="default-intro"]
'
);
const
findSubHeader
=
()
=>
wrapper
.
find
(
'
[data-testid="subheader"]
'
);
const
findImagesCountSubHeader
=
()
=>
wrapper
.
find
(
'
[data-testid="images-count"]
'
);
const
findExpirationPolicySubHeader
=
()
=>
wrapper
.
find
(
'
[data-testid="expiration-policy"]
'
);
const
findDisabledExpirationPolicyMessage
=
()
=>
...
...
@@ -32,10 +31,12 @@ describe('registry_header', () => {
wrapper
=
shallowMount
(
Component
,
{
stubs
:
{
GlSprintf
,
TitleArea
,
},
propsData
,
slots
,
});
return
wrapper
.
vm
.
$nextTick
();
};
afterEach
(()
=>
{
...
...
@@ -44,90 +45,73 @@ describe('registry_header', () => {
});
describe
(
'
header
'
,
()
=>
{
it
(
'
exists
'
,
()
=>
{
it
(
'
has a title
'
,
()
=>
{
mountComponent
();
expect
(
findHeader
().
exists
()).
toBe
(
true
);
});
it
(
'
contains the title of the page
'
,
()
=>
{
mountComponent
();
const
title
=
findTitle
();
expect
(
title
.
exists
()).
toBe
(
true
);
expect
(
title
.
text
()).
toBe
(
CONTAINER_REGISTRY_TITLE
);
expect
(
findTitleArea
().
props
(
'
title
'
)).
toBe
(
CONTAINER_REGISTRY_TITLE
);
});
it
(
'
has a commands slot
'
,
()
=>
{
mountComponent
(
null
,
{
commands
:
'
baz
'
});
mountComponent
(
null
,
{
commands
:
'
<div data-testid="commands-slot">baz</div>
'
});
expect
(
findCommandsSlot
().
text
()).
toBe
(
'
baz
'
);
});
});
describe
(
'
subheader
'
,
()
=>
{
describe
(
'
when there are no images
'
,
()
=>
{
it
(
'
is hidden
'
,
()
=>
{
mountComponent
();
expect
(
findSubHeader
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
sub header parts
'
,
()
=>
{
describe
(
'
images count
'
,
()
=>
{
it
(
'
exists
'
,
async
()
=>
{
await
mountComponent
({
imagesCount
:
1
});
describe
(
'
when there are images
'
,
()
=>
{
it
(
'
is visible
'
,
()
=>
{
mountComponent
({
imagesCount
:
1
});
expect
(
findSubHeader
().
exists
()).
toBe
(
true
);
});
expect
(
findImagesCountSubHeader
().
exists
()).
toBe
(
true
);
});
describe
(
'
sub header parts
'
,
()
=>
{
describe
(
'
images count
'
,
()
=>
{
it
(
'
exists
'
,
()
=>
{
mountComponent
({
imagesCount
:
1
});
expect
(
findImagesCountSubHeader
().
exists
()).
toBe
(
true
);
});
it
(
'
when there is one image
'
,
async
()
=>
{
await
mountComponent
({
imagesCount
:
1
});
it
(
'
when there is one image
'
,
()
=>
{
mountComponent
({
imagesCount
:
1
});
expect
(
findImagesCountSubHeader
().
text
()).
toMatchInterpolatedText
(
'
1 Image repository
'
);
});
expect
(
findImagesCountSubHeader
().
text
()).
toMatchInterpolatedText
(
'
1 Image repository
'
);
});
it
(
'
when there is more than one image
'
,
()
=>
{
mountComponent
({
imagesCount
:
3
});
expect
(
findImagesCountSubHeader
().
text
()).
toMatchInterpolatedText
(
'
3 Image repositories
'
,
);
});
it
(
'
when there is more than one image
'
,
async
()
=>
{
await
mountComponent
({
imagesCount
:
3
});
expect
(
findImagesCountSubHeader
().
text
()).
toMatchInterpolatedText
(
'
3 Image repositories
'
);
});
});
describe
(
'
expiration policy
'
,
()
=>
{
it
(
'
when is disabled
'
,
()
=>
{
mountComponent
({
expirationPolicy
:
{
enabled
:
false
},
expirationPolicyHelpPagePath
:
'
foo
'
,
imagesCount
:
1
,
});
const
text
=
findExpirationPolicySubHeader
();
expect
(
text
.
exists
()).
toBe
(
true
);
expect
(
text
.
text
()).
toMatchInterpolatedText
(
EXPIRATION_POLICY_DISABLED_TEXT
);
describe
(
'
expiration policy
'
,
()
=>
{
it
(
'
when is disabled
'
,
async
()
=>
{
await
mountComponent
({
expirationPolicy
:
{
enabled
:
false
},
expirationPolicyHelpPagePath
:
'
foo
'
,
imagesCount
:
1
,
});
it
(
'
when is enabled
'
,
()
=>
{
mountComponent
({
expirationPolicy
:
{
enabled
:
true
},
expirationPolicyHelpPagePath
:
'
foo
'
,
imagesCount
:
1
,
});
const
text
=
findExpirationPolicySubHeader
();
expect
(
text
.
exists
()).
toBe
(
true
);
expect
(
text
.
text
()).
toMatchInterpolatedText
(
EXPIRATION_POLICY_WILL_RUN_IN
);
const
text
=
findExpirationPolicySubHeader
();
expect
(
text
.
exists
()).
toBe
(
true
);
expect
(
text
.
text
()).
toMatchInterpolatedText
(
EXPIRATION_POLICY_DISABLED_TEXT
);
});
it
(
'
when is enabled
'
,
async
()
=>
{
await
mountComponent
({
expirationPolicy
:
{
enabled
:
true
},
expirationPolicyHelpPagePath
:
'
foo
'
,
imagesCount
:
1
,
});
it
(
'
when the expiration policy is completely disabled
'
,
()
=>
{
mountComponent
({
expirationPolicy
:
{
enabled
:
true
},
expirationPolicyHelpPagePath
:
'
foo
'
,
imagesCount
:
1
,
hideExpirationPolicyData
:
true
,
});
const
text
=
findExpirationPolicySubHeader
();
expect
(
text
.
exists
()).
toBe
(
false
);
const
text
=
findExpirationPolicySubHeader
();
expect
(
text
.
exists
()).
toBe
(
true
);
expect
(
text
.
text
()).
toMatchInterpolatedText
(
EXPIRATION_POLICY_WILL_RUN_IN
);
});
it
(
'
when the expiration policy is completely disabled
'
,
async
()
=>
{
await
mountComponent
({
expirationPolicy
:
{
enabled
:
true
},
expirationPolicyHelpPagePath
:
'
foo
'
,
imagesCount
:
1
,
hideExpirationPolicyData
:
true
,
});
const
text
=
findExpirationPolicySubHeader
();
expect
(
text
.
exists
()).
toBe
(
false
);
});
});
});
...
...
@@ -136,12 +120,13 @@ describe('registry_header', () => {
describe
(
'
info area
'
,
()
=>
{
it
(
'
exists
'
,
()
=>
{
mountComponent
();
expect
(
findInfoArea
().
exists
()).
toBe
(
true
);
});
describe
(
'
default message
'
,
()
=>
{
beforeEach
(()
=>
{
mountComponent
({
helpPagePath
:
'
bar
'
});
return
mountComponent
({
helpPagePath
:
'
bar
'
});
});
it
(
'
exists
'
,
()
=>
{
...
...
@@ -165,6 +150,7 @@ describe('registry_header', () => {
describe
(
'
when there are no images
'
,
()
=>
{
it
(
'
is hidden
'
,
()
=>
{
mountComponent
();
expect
(
findDisabledExpirationPolicyMessage
().
exists
()).
toBe
(
false
);
});
});
...
...
@@ -172,7 +158,7 @@ describe('registry_header', () => {
describe
(
'
when there are images
'
,
()
=>
{
describe
(
'
when expiration policy is disabled
'
,
()
=>
{
beforeEach
(()
=>
{
mountComponent
({
return
mountComponent
({
expirationPolicy
:
{
enabled
:
false
},
expirationPolicyHelpPagePath
:
'
foo
'
,
imagesCount
:
1
,
...
...
@@ -202,6 +188,7 @@ describe('registry_header', () => {
expirationPolicy
:
{
enabled
:
true
},
imagesCount
:
1
,
});
expect
(
findDisabledExpirationPolicyMessage
().
exists
()).
toBe
(
false
);
});
});
...
...
@@ -212,6 +199,7 @@ describe('registry_header', () => {
imagesCount
:
1
,
hideExpirationPolicyData
:
true
,
});
expect
(
findDisabledExpirationPolicyMessage
().
exists
()).
toBe
(
false
);
});
});
...
...
spec/frontend/registry/explorer/pages/list_spec.js
View file @
2a33bcbc
...
...
@@ -8,6 +8,7 @@ import GroupEmptyState from '~/registry/explorer/components/list_page/group_empt
import
ProjectEmptyState
from
'
~/registry/explorer/components/list_page/project_empty_state.vue
'
;
import
RegistryHeader
from
'
~/registry/explorer/components/list_page/registry_header.vue
'
;
import
ImageList
from
'
~/registry/explorer/components/list_page/image_list.vue
'
;
import
TitleArea
from
'
~/vue_shared/components/registry/title_area.vue
'
;
import
{
createStore
}
from
'
~/registry/explorer/stores/
'
;
import
{
SET_MAIN_LOADING
,
...
...
@@ -54,6 +55,7 @@ describe('List Page', () => {
GlEmptyState
,
GlSprintf
,
RegistryHeader
,
TitleArea
,
},
mocks
:
{
$toast
,
...
...
spec/frontend/vue_shared/components/registry/title_area_spec.js
0 → 100644
View file @
2a33bcbc
import
{
GlAvatar
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
component
from
'
~/vue_shared/components/registry/title_area.vue
'
;
describe
(
'
title area
'
,
()
=>
{
let
wrapper
;
const
findSubHeaderSlot
=
()
=>
wrapper
.
find
(
'
[data-testid="sub-header"]
'
);
const
findRightActionsSlot
=
()
=>
wrapper
.
find
(
'
[data-testid="right-actions"]
'
);
const
findMetadataSlot
=
name
=>
wrapper
.
find
(
`[data-testid="
${
name
}
"]`
);
const
findTitle
=
()
=>
wrapper
.
find
(
'
[data-testid="title"]
'
);
const
findAvatar
=
()
=>
wrapper
.
find
(
GlAvatar
);
const
mountComponent
=
({
propsData
=
{
title
:
'
foo
'
},
slots
}
=
{})
=>
{
wrapper
=
shallowMount
(
component
,
{
propsData
,
slots
:
{
'
sub-header
'
:
'
<div data-testid="sub-header" />
'
,
'
right-actions
'
:
'
<div data-testid="right-actions" />
'
,
...
slots
,
},
});
};
afterEach
(()
=>
{
wrapper
.
destroy
();
wrapper
=
null
;
});
describe
(
'
title
'
,
()
=>
{
it
(
'
if slot is not present defaults to prop
'
,
()
=>
{
mountComponent
();
expect
(
findTitle
().
text
()).
toBe
(
'
foo
'
);
});
it
(
'
if slot is present uses slot
'
,
()
=>
{
mountComponent
({
slots
:
{
title
:
'
slot_title
'
,
},
});
expect
(
findTitle
().
text
()).
toBe
(
'
slot_title
'
);
});
});
describe
(
'
avatar
'
,
()
=>
{
it
(
'
is shown if avatar props exist
'
,
()
=>
{
mountComponent
({
propsData
:
{
title
:
'
foo
'
,
avatar
:
'
baz
'
}
});
expect
(
findAvatar
().
props
(
'
src
'
)).
toBe
(
'
baz
'
);
});
it
(
'
is hidden if avatar props does not exist
'
,
()
=>
{
mountComponent
();
expect
(
findAvatar
().
exists
()).
toBe
(
false
);
});
});
describe
.
each
`
slotName | finderFunction
${
'
sub-header
'
}
|
${
findSubHeaderSlot
}
${
'
right-actions
'
}
|
${
findRightActionsSlot
}
`
(
'
$slotName slot
'
,
({
finderFunction
,
slotName
})
=>
{
it
(
'
exist when the slot is filled
'
,
()
=>
{
mountComponent
();
expect
(
finderFunction
().
exists
()).
toBe
(
true
);
});
it
(
'
does not exist when the slot is empty
'
,
()
=>
{
mountComponent
({
slots
:
{
[
slotName
]:
''
}
});
expect
(
finderFunction
().
exists
()).
toBe
(
false
);
});
});
describe
.
each
`
slotNames
${[
'
metadata_foo
'
]}
${[
'
metadata_foo
'
,
'
metadata_bar
'
]}
${[
'
metadata_foo
'
,
'
metadata_bar
'
,
'
metadata_baz
'
]}
`
(
'
$slotNames metadata slots
'
,
({
slotNames
})
=>
{
const
slotMocks
=
slotNames
.
reduce
((
acc
,
current
)
=>
{
acc
[
current
]
=
`<div data-testid="
${
current
}
" />`
;
return
acc
;
},
{});
it
(
'
exist when the slot is present
'
,
async
()
=>
{
mountComponent
({
slots
:
slotMocks
});
await
wrapper
.
vm
.
$nextTick
();
slotNames
.
forEach
(
name
=>
{
expect
(
findMetadataSlot
(
name
).
exists
()).
toBe
(
true
);
});
});
});
});
spec/support/shared_examples/features/packages_shared_examples.rb
View file @
2a33bcbc
...
...
@@ -32,7 +32,7 @@ RSpec.shared_examples 'package details link' do |property|
expect
(
page
).
to
have_current_path
(
project_package_path
(
package
.
project
,
package
))
page
.
within
(
'
.detail-page-header
'
)
do
page
.
within
(
'
[data-qa-selector="package_title"]
'
)
do
expect
(
page
).
to
have_content
(
package
.
name
)
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