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
9645e8e0
Commit
9645e8e0
authored
Jun 05, 2020
by
Nicolò Maria Mezzopera
Committed by
Natalia Tepluhina
Jun 05, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add new delete_alert component
- new component - unit tests
parent
bb396938
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
544 additions
and
326 deletions
+544
-326
app/assets/javascripts/registry/explorer/components/details_page/delete_alert.vue
...egistry/explorer/components/details_page/delete_alert.vue
+70
-0
app/assets/javascripts/registry/explorer/components/details_page/delete_modal.vue
...egistry/explorer/components/details_page/delete_modal.vue
+67
-0
app/assets/javascripts/registry/explorer/components/details_page/details_header.vue
...istry/explorer/components/details_page/details_header.vue
+30
-0
app/assets/javascripts/registry/explorer/constants/details.js
...assets/javascripts/registry/explorer/constants/details.js
+11
-0
app/assets/javascripts/registry/explorer/pages/details.vue
app/assets/javascripts/registry/explorer/pages/details.vue
+48
-136
spec/frontend/registry/explorer/components/details_page/delete_alert_spec.js
...try/explorer/components/details_page/delete_alert_spec.js
+111
-0
spec/frontend/registry/explorer/components/details_page/delete_modal_spec.js
...try/explorer/components/details_page/delete_modal_spec.js
+74
-0
spec/frontend/registry/explorer/components/details_page/details_header_spec.js
...y/explorer/components/details_page/details_header_spec.js
+27
-0
spec/frontend/registry/explorer/mock_data.js
spec/frontend/registry/explorer/mock_data.js
+2
-2
spec/frontend/registry/explorer/pages/details_spec.js
spec/frontend/registry/explorer/pages/details_spec.js
+104
-188
No files found.
app/assets/javascripts/registry/explorer/components/details_page/delete_alert.vue
0 → 100644
View file @
9645e8e0
<
script
>
import
{
GlSprintf
,
GlAlert
,
GlLink
}
from
'
@gitlab/ui
'
;
import
{
ALERT_MESSAGES
,
ADMIN_GARBAGE_COLLECTION_TIP
}
from
'
../../constants/index
'
;
export
default
{
components
:
{
GlSprintf
,
GlAlert
,
GlLink
,
},
model
:
{
prop
:
'
deleteAlertType
'
,
event
:
'
change
'
,
},
props
:
{
deleteAlertType
:
{
type
:
String
,
default
:
null
,
required
:
false
,
validator
(
value
)
{
return
!
value
||
ALERT_MESSAGES
[
value
]
!==
undefined
;
},
},
garbageCollectionHelpPagePath
:
{
type
:
String
,
required
:
false
,
default
:
''
},
isAdmin
:
{
type
:
Boolean
,
default
:
false
,
required
:
false
,
},
},
computed
:
{
deleteAlertConfig
()
{
const
config
=
{
title
:
''
,
message
:
''
,
type
:
'
success
'
,
};
if
(
this
.
deleteAlertType
)
{
[
config
.
type
]
=
this
.
deleteAlertType
.
split
(
'
_
'
);
config
.
message
=
ALERT_MESSAGES
[
this
.
deleteAlertType
];
if
(
this
.
isAdmin
&&
config
.
type
===
'
success
'
)
{
config
.
title
=
config
.
message
;
config
.
message
=
ADMIN_GARBAGE_COLLECTION_TIP
;
}
}
return
config
;
},
},
};
</
script
>
<
template
>
<gl-alert
v-if=
"deleteAlertType"
:variant=
"deleteAlertConfig.type"
:title=
"deleteAlertConfig.title"
@
dismiss=
"$emit('change', null)"
>
<gl-sprintf
:message=
"deleteAlertConfig.message"
>
<template
#docLink
="
{content}">
<gl-link
:href=
"garbageCollectionHelpPagePath"
target=
"_blank"
>
{{
content
}}
</gl-link>
</
template
>
</gl-sprintf>
</gl-alert>
</template>
app/assets/javascripts/registry/explorer/components/details_page/delete_modal.vue
0 → 100644
View file @
9645e8e0
<
script
>
import
{
GlModal
,
GlSprintf
}
from
'
@gitlab/ui
'
;
import
{
n__
}
from
'
~/locale
'
;
import
{
REMOVE_TAG_CONFIRMATION_TEXT
,
REMOVE_TAGS_CONFIRMATION_TEXT
}
from
'
../../constants/index
'
;
export
default
{
components
:
{
GlModal
,
GlSprintf
,
},
props
:
{
itemsToBeDeleted
:
{
type
:
Array
,
required
:
false
,
default
:
()
=>
[],
},
},
computed
:
{
modalAction
()
{
return
n__
(
'
ContainerRegistry|Remove tag
'
,
'
ContainerRegistry|Remove tags
'
,
this
.
itemsToBeDeleted
.
length
,
);
},
modalDescription
()
{
if
(
this
.
itemsToBeDeleted
.
length
>
1
)
{
return
{
message
:
REMOVE_TAGS_CONFIRMATION_TEXT
,
item
:
this
.
itemsToBeDeleted
.
length
,
};
}
const
[
first
]
=
this
.
itemsToBeDeleted
;
return
{
message
:
REMOVE_TAG_CONFIRMATION_TEXT
,
item
:
first
?.
path
,
};
},
},
methods
:
{
show
()
{
this
.
$refs
.
deleteModal
.
show
();
},
},
};
</
script
>
<
template
>
<gl-modal
ref=
"deleteModal"
modal-id=
"delete-tag-modal"
ok-variant=
"danger"
@
ok=
"$emit('confirmDelete')"
@
cancel=
"$emit('cancelDelete')"
>
<template
#modal-title
>
{{
modalAction
}}
</
template
>
<
template
#modal-ok
>
{{
modalAction
}}
</
template
>
<p
v-if=
"modalDescription"
data-testid=
"description"
>
<gl-sprintf
:message=
"modalDescription.message"
>
<
template
#item
><b>
{{
modalDescription
.
item
}}
</b></
template
>
</gl-sprintf>
</p>
</gl-modal>
</template>
app/assets/javascripts/registry/explorer/components/details_page/details_header.vue
0 → 100644
View file @
9645e8e0
<
script
>
import
{
GlSprintf
}
from
'
@gitlab/ui
'
;
import
{
DETAILS_PAGE_TITLE
}
from
'
../../constants/index
'
;
export
default
{
components
:
{
GlSprintf
},
props
:
{
imageName
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
},
i18n
:
{
DETAILS_PAGE_TITLE
,
},
};
</
script
>
<
template
>
<div
class=
"gl-display-flex gl-my-2 gl-align-items-center"
>
<h4>
<gl-sprintf
:message=
"$options.i18n.DETAILS_PAGE_TITLE"
>
<template
#imageName
>
{{
imageName
}}
</
template
>
</gl-sprintf>
</h4>
</div>
</template>
app/assets/javascripts/registry/explorer/constants/details.js
View file @
9645e8e0
...
...
@@ -47,3 +47,14 @@ export const LIST_KEY_SIZE = 'total_size';
export
const
LIST_KEY_LAST_UPDATED
=
'
created_at
'
;
export
const
LIST_KEY_ACTIONS
=
'
actions
'
;
export
const
LIST_KEY_CHECKBOX
=
'
checkbox
'
;
export
const
ALERT_SUCCESS_TAG
=
'
success_tag
'
;
export
const
ALERT_DANGER_TAG
=
'
danger_tag
'
;
export
const
ALERT_SUCCESS_TAGS
=
'
success_tags
'
;
export
const
ALERT_DANGER_TAGS
=
'
danger_tags
'
;
export
const
ALERT_MESSAGES
=
{
[
ALERT_SUCCESS_TAG
]:
DELETE_TAG_SUCCESS_MESSAGE
,
[
ALERT_DANGER_TAG
]:
DELETE_TAG_ERROR_MESSAGE
,
[
ALERT_SUCCESS_TAGS
]:
DELETE_TAGS_SUCCESS_MESSAGE
,
[
ALERT_DANGER_TAGS
]:
DELETE_TAGS_ERROR_MESSAGE
,
};
app/assets/javascripts/registry/explorer/pages/details.vue
View file @
9645e8e0
...
...
@@ -7,10 +7,6 @@ import {
GlIcon
,
GlTooltipDirective
,
GlPagination
,
GlModal
,
GlSprintf
,
GlAlert
,
GlLink
,
GlEmptyState
,
GlResizeObserverDirective
,
GlSkeletonLoader
,
...
...
@@ -21,6 +17,9 @@ import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import
{
numberToHumanSize
}
from
'
~/lib/utils/number_utils
'
;
import
timeagoMixin
from
'
~/vue_shared/mixins/timeago
'
;
import
Tracking
from
'
~/tracking
'
;
import
DeleteAlert
from
'
../components/details_page/delete_alert.vue
'
;
import
DeleteModal
from
'
../components/details_page/delete_modal.vue
'
;
import
DetailsHeader
from
'
../components/details_page/details_header.vue
'
;
import
{
decodeAndParse
}
from
'
../utils
'
;
import
{
LIST_KEY_TAG
,
...
...
@@ -33,34 +32,29 @@ import {
LIST_LABEL_IMAGE_ID
,
LIST_LABEL_SIZE
,
LIST_LABEL_LAST_UPDATED
,
DELETE_TAG_SUCCESS_MESSAGE
,
DELETE_TAG_ERROR_MESSAGE
,
DELETE_TAGS_SUCCESS_MESSAGE
,
DELETE_TAGS_ERROR_MESSAGE
,
REMOVE_TAG_CONFIRMATION_TEXT
,
REMOVE_TAGS_CONFIRMATION_TEXT
,
DETAILS_PAGE_TITLE
,
REMOVE_TAGS_BUTTON_TITLE
,
REMOVE_TAG_BUTTON_TITLE
,
EMPTY_IMAGE_REPOSITORY_TITLE
,
EMPTY_IMAGE_REPOSITORY_MESSAGE
,
ADMIN_GARBAGE_COLLECTION_TIP
,
ALERT_SUCCESS_TAG
,
ALERT_DANGER_TAG
,
ALERT_SUCCESS_TAGS
,
ALERT_DANGER_TAGS
,
}
from
'
../constants/index
'
;
export
default
{
components
:
{
DeleteAlert
,
DetailsHeader
,
GlTable
,
GlFormCheckbox
,
GlDeprecatedButton
,
GlIcon
,
ClipboardButton
,
GlPagination
,
Gl
Modal
,
Delete
Modal
,
GlSkeletonLoader
,
GlSprintf
,
GlEmptyState
,
GlAlert
,
GlLink
,
},
directives
:
{
GlTooltip
:
GlTooltipDirective
,
...
...
@@ -73,18 +67,11 @@ export default {
height
:
40
,
},
i18n
:
{
DETAILS_PAGE_TITLE
,
REMOVE_TAGS_BUTTON_TITLE
,
REMOVE_TAG_BUTTON_TITLE
,
EMPTY_IMAGE_REPOSITORY_TITLE
,
EMPTY_IMAGE_REPOSITORY_MESSAGE
,
},
alertMessages
:
{
success_tag
:
DELETE_TAG_SUCCESS_MESSAGE
,
danger_tag
:
DELETE_TAG_ERROR_MESSAGE
,
success_tags
:
DELETE_TAGS_SUCCESS_MESSAGE
,
danger_tags
:
DELETE_TAGS_ERROR_MESSAGE
,
},
data
()
{
return
{
selectedItems
:
[],
...
...
@@ -92,7 +79,7 @@ export default {
selectAllChecked
:
false
,
modalDescription
:
null
,
isDesktop
:
true
,
deleteAlertType
:
false
,
deleteAlertType
:
null
,
};
},
computed
:
{
...
...
@@ -119,21 +106,12 @@ export default {
{
key
:
LIST_KEY_ACTIONS
,
label
:
''
},
].
filter
(
f
=>
f
.
key
!==
LIST_KEY_CHECKBOX
||
this
.
isDesktop
);
},
isMultiDelete
()
{
return
this
.
itemsToBeDeleted
.
length
>
1
;
},
tracking
()
{
return
{
label
:
this
.
isMultiDelete
?
'
bulk_registry_tag_delete
'
:
'
registry_tag_delete
'
,
label
:
this
.
itemsToBeDeleted
?.
length
>
1
?
'
bulk_registry_tag_delete
'
:
'
registry_tag_delete
'
,
};
},
modalAction
()
{
return
n__
(
'
ContainerRegistry|Remove tag
'
,
'
ContainerRegistry|Remove tags
'
,
this
.
isMultiDelete
?
this
.
itemsToBeDeleted
.
length
:
1
,
);
},
currentPage
:
{
get
()
{
return
this
.
tagsPagination
.
page
;
...
...
@@ -142,47 +120,12 @@ export default {
this
.
requestTagsList
({
pagination
:
{
page
},
params
:
this
.
$route
.
params
.
id
});
},
},
deleteAlertConfig
()
{
const
config
=
{
title
:
''
,
message
:
''
,
type
:
'
success
'
,
};
if
(
this
.
deleteAlertType
)
{
[
config
.
type
]
=
this
.
deleteAlertType
.
split
(
'
_
'
);
const
defaultMessage
=
this
.
$options
.
alertMessages
[
this
.
deleteAlertType
];
if
(
this
.
config
.
isAdmin
&&
config
.
type
===
'
success
'
)
{
config
.
title
=
defaultMessage
;
config
.
message
=
ADMIN_GARBAGE_COLLECTION_TIP
;
}
else
{
config
.
message
=
defaultMessage
;
}
}
return
config
;
},
},
mounted
()
{
this
.
requestTagsList
({
params
:
this
.
$route
.
params
.
id
});
},
methods
:
{
...
mapActions
([
'
requestTagsList
'
,
'
requestDeleteTag
'
,
'
requestDeleteTags
'
]),
setModalDescription
(
itemIndex
=
-
1
)
{
if
(
itemIndex
===
-
1
)
{
this
.
modalDescription
=
{
message
:
REMOVE_TAGS_CONFIRMATION_TEXT
,
item
:
this
.
itemsToBeDeleted
.
length
,
};
}
else
{
const
{
path
}
=
this
.
tags
[
itemIndex
];
this
.
modalDescription
=
{
message
:
REMOVE_TAG_CONFIRMATION_TEXT
,
item
:
path
,
};
}
},
formatSize
(
size
)
{
return
numberToHumanSize
(
size
);
},
...
...
@@ -197,53 +140,49 @@ export default {
}
},
selectAll
()
{
this
.
selectedItems
=
this
.
tags
.
map
(
(
x
,
index
)
=>
index
);
this
.
selectedItems
=
this
.
tags
.
map
(
x
=>
x
.
name
);
this
.
selectAllChecked
=
true
;
},
deselectAll
()
{
this
.
selectedItems
=
[];
this
.
selectAllChecked
=
false
;
},
updateSelectedItems
(
index
)
{
const
delIndex
=
this
.
selectedItems
.
findIndex
(
x
=>
x
===
index
);
updateSelectedItems
(
name
)
{
const
delIndex
=
this
.
selectedItems
.
findIndex
(
x
=>
x
===
name
);
if
(
delIndex
>
-
1
)
{
this
.
selectedItems
.
splice
(
delIndex
,
1
);
this
.
selectAllChecked
=
false
;
}
else
{
this
.
selectedItems
.
push
(
index
);
this
.
selectedItems
.
push
(
name
);
if
(
this
.
selectedItems
.
length
===
this
.
tags
.
length
)
{
this
.
selectAllChecked
=
true
;
}
}
},
deleteSingleItem
(
index
)
{
this
.
setModalDescription
(
index
);
this
.
itemsToBeDeleted
=
[
index
];
deleteSingleItem
(
name
)
{
this
.
itemsToBeDeleted
=
[{
...
this
.
tags
.
find
(
t
=>
t
.
name
===
name
)
}];
this
.
track
(
'
click_button
'
);
this
.
$refs
.
deleteModal
.
show
();
},
deleteMultipleItems
()
{
this
.
itemsToBeDeleted
=
[...
this
.
selectedItems
];
if
(
this
.
selectedItems
.
length
===
1
)
{
this
.
setModalDescription
(
this
.
itemsToBeDeleted
[
0
]);
}
else
if
(
this
.
selectedItems
.
length
>
1
)
{
this
.
setModalDescription
();
}
this
.
itemsToBeDeleted
=
this
.
selectedItems
.
map
(
name
=>
({
...
this
.
tags
.
find
(
t
=>
t
.
name
===
name
),
}));
this
.
track
(
'
click_button
'
);
this
.
$refs
.
deleteModal
.
show
();
},
handleSingleDelete
(
index
)
{
const
itemToDelete
=
this
.
tags
[
index
]
;
handleSingleDelete
()
{
const
[
itemToDelete
]
=
this
.
itemsToBeDeleted
;
this
.
itemsToBeDeleted
=
[];
this
.
selectedItems
=
this
.
selectedItems
.
filter
(
i
=>
i
!==
index
);
this
.
selectedItems
=
this
.
selectedItems
.
filter
(
name
=>
name
!==
itemToDelete
.
name
);
return
this
.
requestDeleteTag
({
tag
:
itemToDelete
,
params
:
this
.
$route
.
params
.
id
})
.
then
(()
=>
{
this
.
deleteAlertType
=
'
success_tag
'
;
this
.
deleteAlertType
=
ALERT_SUCCESS_TAG
;
})
.
catch
(()
=>
{
this
.
deleteAlertType
=
'
danger_tag
'
;
this
.
deleteAlertType
=
ALERT_DANGER_TAG
;
});
},
handleMultipleDelete
()
{
...
...
@@ -252,22 +191,22 @@ export default {
this
.
selectedItems
=
[];
return
this
.
requestDeleteTags
({
ids
:
itemsToBeDeleted
.
map
(
x
=>
this
.
tags
[
x
]
.
name
),
ids
:
itemsToBeDeleted
.
map
(
x
=>
x
.
name
),
params
:
this
.
$route
.
params
.
id
,
})
.
then
(()
=>
{
this
.
deleteAlertType
=
'
success_tags
'
;
this
.
deleteAlertType
=
ALERT_SUCCESS_TAGS
;
})
.
catch
(()
=>
{
this
.
deleteAlertType
=
'
danger_tags
'
;
this
.
deleteAlertType
=
ALERT_DANGER_TAGS
;
});
},
onDeletionConfirmed
()
{
this
.
track
(
'
confirm_delete
'
);
if
(
this
.
i
sMultiDelete
)
{
if
(
this
.
i
temsToBeDeleted
.
length
>
1
)
{
this
.
handleMultipleDelete
();
}
else
{
this
.
handleSingleDelete
(
this
.
itemsToBeDeleted
[
0
]
);
this
.
handleSingleDelete
();
}
},
handleResize
()
{
...
...
@@ -279,30 +218,14 @@ export default {
<
template
>
<div
v-gl-resize-observer=
"handleResize"
class=
"my-3 w-100 slide-enter-to-element"
>
<
gl
-alert
v-
if
=
"deleteAlertType"
:
variant=
"deleteAlertConfig.type
"
:
title=
"deleteAlertConfig.title
"
<
delete
-alert
v-
model
=
"deleteAlertType"
:
garbage-collection-help-page-path=
"config.garbageCollectionHelpPagePath
"
:
is-admin=
"config.isAdmin
"
class=
"my-2"
@
dismiss=
"deleteAlertType = null"
>
<gl-sprintf
:message=
"deleteAlertConfig.message"
>
<template
#docLink
="
{content}">
<gl-link
:href=
"config.garbageCollectionHelpPagePath"
target=
"_blank"
>
{{
content
}}
</gl-link>
</
template
>
</gl-sprintf>
</gl-alert>
<div
class=
"d-flex my-3 align-items-center"
>
<h4>
<gl-sprintf
:message=
"$options.i18n.DETAILS_PAGE_TITLE"
>
<
template
#imageName
>
{{
imageName
}}
</
template
>
</gl-sprintf>
</h4>
</div>
/>
<details-header
:image-name=
"imageName"
/>
<gl-table
:items=
"tags"
:fields=
"fields"
:stacked=
"!isDesktop"
show-empty
>
<template
v-if=
"isDesktop"
#head
(
checkbox
)
>
...
...
@@ -327,12 +250,12 @@ export default {
</gl-deprecated-button>
</
template
>
<
template
#cell(checkbox)=
"{i
ndex
}"
>
<
template
#cell(checkbox)=
"{i
tem
}"
>
<gl-form-checkbox
ref=
"rowCheckbox"
class=
"js-row-checkbox"
:checked=
"selectedItems.includes(i
ndex
)"
@
change=
"updateSelectedItems(i
ndex
)"
:checked=
"selectedItems.includes(i
tem.name
)"
@
change=
"updateSelectedItems(i
tem.name
)"
/>
</
template
>
<
template
#cell(name)=
"{item, field}"
>
...
...
@@ -373,7 +296,7 @@ export default {
{{
timeFormatted
(
value
)
}}
</span>
</
template
>
<
template
#cell(actions)=
"{i
ndex, i
tem}"
>
<
template
#cell(actions)=
"{item}"
>
<gl-deprecated-button
ref=
"singleDeleteButton"
:title=
"$options.i18n.REMOVE_TAG_BUTTON_TITLE"
...
...
@@ -381,7 +304,7 @@ export default {
:disabled=
"!item.destroy_path"
variant=
"danger"
class=
"js-delete-registry float-right btn-inverted btn-border-color btn-icon"
@
click=
"deleteSingleItem(i
ndex
)"
@
click=
"deleteSingleItem(i
tem.name
)"
>
<gl-icon
name=
"remove"
/>
</gl-deprecated-button>
...
...
@@ -425,22 +348,11 @@ export default {
class=
"w-100"
/>
<
gl
-modal
<
delete
-modal
ref=
"deleteModal"
modal-id=
"delete-tag-modal"
ok-variant=
"danger"
@
ok=
"onDeletionConfirmed"
:items-to-be-deleted=
"itemsToBeDeleted"
@
confirmDelete=
"onDeletionConfirmed"
@
cancel=
"track('cancel_delete')"
>
<
template
#modal-title
>
{{
modalAction
}}
</
template
>
<
template
#modal-ok
>
{{
modalAction
}}
</
template
>
<p
v-if=
"modalDescription"
>
<gl-sprintf
:message=
"modalDescription.message"
>
<
template
#item
>
<b>
{{
modalDescription
.
item
}}
</b>
</
template
>
</gl-sprintf>
</p>
</gl-modal>
/>
</div>
</template>
spec/frontend/registry/explorer/components/details_page/delete_alert_spec.js
0 → 100644
View file @
9645e8e0
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
GlAlert
,
GlSprintf
,
GlLink
}
from
'
@gitlab/ui
'
;
import
component
from
'
~/registry/explorer/components/details_page/delete_alert.vue
'
;
import
{
DELETE_TAG_SUCCESS_MESSAGE
,
DELETE_TAG_ERROR_MESSAGE
,
DELETE_TAGS_SUCCESS_MESSAGE
,
DELETE_TAGS_ERROR_MESSAGE
,
ADMIN_GARBAGE_COLLECTION_TIP
,
}
from
'
~/registry/explorer/constants
'
;
describe
(
'
Delete alert
'
,
()
=>
{
let
wrapper
;
const
findAlert
=
()
=>
wrapper
.
find
(
GlAlert
);
const
findLink
=
()
=>
wrapper
.
find
(
GlLink
);
const
mountComponent
=
propsData
=>
{
wrapper
=
shallowMount
(
component
,
{
stubs
:
{
GlSprintf
},
propsData
});
};
describe
(
'
when deleteAlertType is null
'
,
()
=>
{
it
(
'
does not show the alert
'
,
()
=>
{
mountComponent
();
expect
(
findAlert
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
when deleteAlertType is not null
'
,
()
=>
{
describe
(
'
success states
'
,
()
=>
{
describe
.
each
`
deleteAlertType | message
${
'
success_tag
'
}
|
${
DELETE_TAG_SUCCESS_MESSAGE
}
${
'
success_tags
'
}
|
${
DELETE_TAGS_SUCCESS_MESSAGE
}
`
(
'
when deleteAlertType is $deleteAlertType
'
,
({
deleteAlertType
,
message
})
=>
{
it
(
'
alert exists
'
,
()
=>
{
mountComponent
({
deleteAlertType
});
expect
(
findAlert
().
exists
()).
toBe
(
true
);
});
describe
(
'
when the user is an admin
'
,
()
=>
{
beforeEach
(()
=>
{
mountComponent
({
deleteAlertType
,
isAdmin
:
true
,
garbageCollectionHelpPagePath
:
'
foo
'
,
});
});
it
(
`alert title is
${
message
}
`
,
()
=>
{
expect
(
findAlert
().
attributes
(
'
title
'
)).
toBe
(
message
);
});
it
(
'
alert body contains admin tip
'
,
()
=>
{
expect
(
findAlert
().
text
()).
toMatchInterpolatedText
(
ADMIN_GARBAGE_COLLECTION_TIP
);
});
it
(
'
alert body contains link
'
,
()
=>
{
const
alertLink
=
findLink
();
expect
(
alertLink
.
exists
()).
toBe
(
true
);
expect
(
alertLink
.
attributes
(
'
href
'
)).
toBe
(
'
foo
'
);
});
});
describe
(
'
when the user is not an admin
'
,
()
=>
{
it
(
'
alert exist and text is appropriate
'
,
()
=>
{
mountComponent
({
deleteAlertType
});
expect
(
findAlert
().
exists
()).
toBe
(
true
);
expect
(
findAlert
().
text
()).
toBe
(
message
);
});
});
});
});
describe
(
'
error states
'
,
()
=>
{
describe
.
each
`
deleteAlertType | message
${
'
danger_tag
'
}
|
${
DELETE_TAG_ERROR_MESSAGE
}
${
'
danger_tags
'
}
|
${
DELETE_TAGS_ERROR_MESSAGE
}
`
(
'
when deleteAlertType is $deleteAlertType
'
,
({
deleteAlertType
,
message
})
=>
{
it
(
'
alert exists
'
,
()
=>
{
mountComponent
({
deleteAlertType
});
expect
(
findAlert
().
exists
()).
toBe
(
true
);
});
describe
(
'
when the user is an admin
'
,
()
=>
{
it
(
'
alert exist and text is appropriate
'
,
()
=>
{
mountComponent
({
deleteAlertType
});
expect
(
findAlert
().
exists
()).
toBe
(
true
);
expect
(
findAlert
().
text
()).
toBe
(
message
);
});
});
describe
(
'
when the user is not an admin
'
,
()
=>
{
it
(
'
alert exist and text is appropriate
'
,
()
=>
{
mountComponent
({
deleteAlertType
});
expect
(
findAlert
().
exists
()).
toBe
(
true
);
expect
(
findAlert
().
text
()).
toBe
(
message
);
});
});
});
});
describe
(
'
dismissing alert
'
,
()
=>
{
it
(
'
GlAlert dismiss event triggers a change event
'
,
()
=>
{
mountComponent
({
deleteAlertType
:
'
success_tags
'
});
findAlert
().
vm
.
$emit
(
'
dismiss
'
);
expect
(
wrapper
.
emitted
(
'
change
'
)).
toEqual
([[
null
]]);
});
});
});
});
spec/frontend/registry/explorer/components/details_page/delete_modal_spec.js
0 → 100644
View file @
9645e8e0
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
GlSprintf
}
from
'
@gitlab/ui
'
;
import
component
from
'
~/registry/explorer/components/details_page/delete_modal.vue
'
;
import
{
REMOVE_TAG_CONFIRMATION_TEXT
,
REMOVE_TAGS_CONFIRMATION_TEXT
,
}
from
'
~/registry/explorer/constants
'
;
import
{
GlModal
}
from
'
../../stubs
'
;
describe
(
'
Delete Modal
'
,
()
=>
{
let
wrapper
;
const
findModal
=
()
=>
wrapper
.
find
(
GlModal
);
const
findDescription
=
()
=>
wrapper
.
find
(
'
[data-testid="description"]
'
);
const
mountComponent
=
propsData
=>
{
wrapper
=
shallowMount
(
component
,
{
propsData
,
stubs
:
{
GlSprintf
,
GlModal
,
},
});
};
it
(
'
contains a GlModal
'
,
()
=>
{
mountComponent
();
expect
(
findModal
().
exists
()).
toBe
(
true
);
});
describe
(
'
events
'
,
()
=>
{
it
.
each
`
glEvent | localEvent
${
'
ok
'
}
|
${
'
confirmDelete
'
}
${
'
cancel
'
}
|
${
'
cancelDelete
'
}
`
(
'
GlModal $glEvent emits $localEvent
'
,
({
glEvent
,
localEvent
})
=>
{
mountComponent
();
findModal
().
vm
.
$emit
(
glEvent
);
expect
(
wrapper
.
emitted
(
localEvent
)).
toBeTruthy
();
});
});
describe
(
'
methods
'
,
()
=>
{
it
(
'
show calls gl-modal show
'
,
()
=>
{
mountComponent
();
wrapper
.
vm
.
show
();
expect
(
GlModal
.
methods
.
show
).
toHaveBeenCalled
();
});
});
describe
(
'
itemsToBeDeleted contains one element
'
,
()
=>
{
beforeEach
(()
=>
{
mountComponent
({
itemsToBeDeleted
:
[{
path
:
'
foo
'
}]
});
});
it
(
`has the correct description`
,
()
=>
{
expect
(
findDescription
().
text
()).
toBe
(
REMOVE_TAG_CONFIRMATION_TEXT
.
replace
(
'
%{item}
'
,
'
foo
'
));
});
it
(
'
has the correct action
'
,
()
=>
{
expect
(
wrapper
.
text
()).
toContain
(
'
Remove tag
'
);
});
});
describe
(
'
itemsToBeDeleted contains more than element
'
,
()
=>
{
beforeEach
(()
=>
{
mountComponent
({
itemsToBeDeleted
:
[{
path
:
'
foo
'
},
{
path
:
'
bar
'
}]
});
});
it
(
`has the correct description`
,
()
=>
{
expect
(
findDescription
().
text
()).
toBe
(
REMOVE_TAGS_CONFIRMATION_TEXT
.
replace
(
'
%{item}
'
,
'
2
'
));
});
it
(
'
has the correct action
'
,
()
=>
{
expect
(
wrapper
.
text
()).
toContain
(
'
Remove tags
'
);
});
});
});
spec/frontend/registry/explorer/components/details_page/details_header_spec.js
0 → 100644
View file @
9645e8e0
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
GlSprintf
}
from
'
@gitlab/ui
'
;
import
component
from
'
~/registry/explorer/components/details_page/details_header.vue
'
;
import
{
DETAILS_PAGE_TITLE
}
from
'
~/registry/explorer/constants
'
;
describe
(
'
Details Header
'
,
()
=>
{
let
wrapper
;
const
mountComponent
=
propsData
=>
{
wrapper
=
shallowMount
(
component
,
{
propsData
,
stubs
:
{
GlSprintf
,
},
});
};
it
(
'
has the correct title
'
,
()
=>
{
mountComponent
();
expect
(
wrapper
.
text
()).
toMatchInterpolatedText
(
DETAILS_PAGE_TITLE
);
});
it
(
'
shows imageName in the title
'
,
()
=>
{
mountComponent
({
imageName
:
'
foo
'
});
expect
(
wrapper
.
text
()).
toContain
(
'
foo
'
);
});
});
spec/frontend/registry/explorer/mock_data.js
View file @
9645e8e0
...
...
@@ -64,7 +64,7 @@ export const imagesListResponse = {
export
const
tagsListResponse
=
{
data
:
[
{
tag
:
'
centos6
'
,
name
:
'
centos6
'
,
revision
:
'
b118ab5b0e90b7cb5127db31d5321ac14961d097516a8e0e72084b6cdc783b43
'
,
short_revision
:
'
b118ab5b0
'
,
size
:
19
,
...
...
@@ -75,7 +75,7 @@ export const tagsListResponse = {
destroy_path
:
'
path
'
,
},
{
tag
:
'
test-image
'
,
name
:
'
test-tag
'
,
revision
:
'
b969de599faea2b3d9b6605a8b0897261c571acaa36db1bdc7349b5775b4e0b4
'
,
short_revision
:
'
b969de599
'
,
size
:
19
,
...
...
spec/frontend/registry/explorer/pages/details_spec.js
View file @
9645e8e0
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
GlTable
,
GlPagination
,
GlSkeletonLoader
,
GlAlert
,
GlLink
}
from
'
@gitlab/ui
'
;
import
{
GlTable
,
GlPagination
,
GlSkeletonLoader
}
from
'
@gitlab/ui
'
;
import
Tracking
from
'
~/tracking
'
;
import
stubChildren
from
'
helpers/stub_children
'
;
import
component
from
'
~/registry/explorer/pages/details.vue
'
;
import
DeleteAlert
from
'
~/registry/explorer/components/details_page/delete_alert.vue
'
;
import
DeleteModal
from
'
~/registry/explorer/components/details_page/delete_modal.vue
'
;
import
DetailsHeader
from
'
~/registry/explorer/components/details_page/details_header.vue
'
;
import
{
createStore
}
from
'
~/registry/explorer/stores/
'
;
import
{
SET_MAIN_LOADING
,
SET_INITIAL_STATE
,
SET_TAGS_LIST_SUCCESS
,
SET_TAGS_PAGINATION
,
SET_INITIAL_STATE
,
}
from
'
~/registry/explorer/stores/mutation_types/
'
;
import
{
DELETE_TAG_SUCCESS_MESSAGE
,
DELETE_TAG_ERROR_MESSAGE
,
DELETE_TAGS_SUCCESS_MESSAGE
,
DELETE_TAGS_ERROR_MESSAGE
,
ADMIN_GARBAGE_COLLECTION_TIP
,
}
from
'
~/registry/explorer/constants
'
;
import
{
tagsListResponse
}
from
'
../mock_data
'
;
import
{
GlModal
}
from
'
../stubs
'
;
import
{
$toast
}
from
'
../../shared/mocks
'
;
describe
(
'
Details Page
'
,
()
=>
{
...
...
@@ -26,7 +22,7 @@ describe('Details Page', () => {
let
dispatchSpy
;
let
store
;
const
findDeleteModal
=
()
=>
wrapper
.
find
(
Gl
Modal
);
const
findDeleteModal
=
()
=>
wrapper
.
find
(
Delete
Modal
);
const
findPagination
=
()
=>
wrapper
.
find
(
GlPagination
);
const
findSkeletonLoader
=
()
=>
wrapper
.
find
(
GlSkeletonLoader
);
const
findMainCheckbox
=
()
=>
wrapper
.
find
({
ref
:
'
mainCheckbox
'
});
...
...
@@ -38,7 +34,8 @@ describe('Details Page', () => {
const
findCheckedCheckboxes
=
()
=>
findAllCheckboxes
().
filter
(
c
=>
c
.
attributes
(
'
checked
'
));
const
findFirsTagColumn
=
()
=>
wrapper
.
find
(
'
.js-tag-column
'
);
const
findFirstTagNameText
=
()
=>
wrapper
.
find
(
'
[data-testid="rowNameText"]
'
);
const
findAlert
=
()
=>
wrapper
.
find
(
GlAlert
);
const
findDeleteAlert
=
()
=>
wrapper
.
find
(
DeleteAlert
);
const
findDetailsHeader
=
()
=>
wrapper
.
find
(
DetailsHeader
);
const
routeId
=
window
.
btoa
(
JSON
.
stringify
({
name
:
'
foo
'
,
tags_path
:
'
bar
'
}));
...
...
@@ -47,9 +44,9 @@ describe('Details Page', () => {
store
,
stubs
:
{
...
stubChildren
(
component
),
GlModal
,
GlSprintf
:
false
,
GlTable
,
DeleteModal
,
},
mocks
:
{
$route
:
{
...
...
@@ -70,6 +67,7 @@ describe('Details Page', () => {
store
.
commit
(
SET_TAGS_LIST_SUCCESS
,
tagsListResponse
.
data
);
store
.
commit
(
SET_TAGS_PAGINATION
,
tagsListResponse
.
headers
);
jest
.
spyOn
(
Tracking
,
'
event
'
);
jest
.
spyOn
(
DeleteModal
.
methods
,
'
show
'
);
});
afterEach
(()
=>
{
...
...
@@ -100,10 +98,6 @@ describe('Details Page', () => {
});
describe
(
'
table
'
,
()
=>
{
beforeEach
(()
=>
{
mountComponent
();
});
it
.
each
([
'
rowCheckbox
'
,
'
rowName
'
,
...
...
@@ -112,6 +106,7 @@ describe('Details Page', () => {
'
rowTime
'
,
'
singleDeleteButton
'
,
])(
'
%s exist in the table
'
,
element
=>
{
mountComponent
();
expect
(
findFirstRowItem
(
element
).
exists
()).
toBe
(
true
);
});
...
...
@@ -143,16 +138,20 @@ describe('Details Page', () => {
});
describe
(
'
row checkbox
'
,
()
=>
{
beforeEach
(()
=>
{
mountComponent
();
});
it
(
'
if selected adds item to selectedItems
'
,
()
=>
{
findFirstRowItem
(
'
rowCheckbox
'
).
vm
.
$emit
(
'
change
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
expect
(
wrapper
.
vm
.
selectedItems
).
toEqual
([
1
]);
expect
(
wrapper
.
vm
.
selectedItems
).
toEqual
([
store
.
state
.
tags
[
1
].
name
]);
expect
(
findFirstRowItem
(
'
rowCheckbox
'
).
attributes
(
'
checked
'
)).
toBeTruthy
();
});
});
it
(
'
if deselect remove
index
from selectedItems
'
,
()
=>
{
wrapper
.
setData
({
selectedItems
:
[
1
]
});
it
(
'
if deselect remove
name
from selectedItems
'
,
()
=>
{
wrapper
.
setData
({
selectedItems
:
[
store
.
state
.
tags
[
1
].
name
]
});
findFirstRowItem
(
'
rowCheckbox
'
).
vm
.
$emit
(
'
change
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
expect
(
wrapper
.
vm
.
selectedItems
.
length
).
toBe
(
0
);
...
...
@@ -167,14 +166,17 @@ describe('Details Page', () => {
});
it
(
'
exists
'
,
()
=>
{
mountComponent
();
expect
(
findBulkDeleteButton
().
exists
()).
toBe
(
true
);
});
it
(
'
is disabled if no item is selected
'
,
()
=>
{
mountComponent
();
expect
(
findBulkDeleteButton
().
attributes
(
'
disabled
'
)).
toBe
(
'
true
'
);
});
it
(
'
is enabled if at least one item is selected
'
,
()
=>
{
mountComponent
({
data
:
()
=>
({
selectedItems
:
[
store
.
state
.
tags
[
0
].
name
]
})
});
wrapper
.
setData
({
selectedItems
:
[
1
]
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
expect
(
findBulkDeleteButton
().
attributes
(
'
disabled
'
)).
toBeFalsy
();
...
...
@@ -183,30 +185,26 @@ describe('Details Page', () => {
describe
(
'
on click
'
,
()
=>
{
it
(
'
when one item is selected
'
,
()
=>
{
wrapper
.
setData
({
selectedItems
:
[
1
]
});
mountComponent
({
data
:
()
=>
({
selectedItems
:
[
store
.
state
.
tags
[
0
].
name
]
})
});
jest
.
spyOn
(
wrapper
.
vm
.
$refs
.
deleteModal
,
'
show
'
);
findBulkDeleteButton
().
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
expect
(
findDeleteModal
().
html
()).
toContain
(
'
You are about to remove <b>foo</b>. Are you sure?
'
,
);
expect
(
GlModal
.
methods
.
show
).
toHaveBeenCalled
();
expect
(
Tracking
.
event
).
toHaveBeenCalledWith
(
undefined
,
'
click_button
'
,
{
label
:
'
registry_tag_delete
'
,
});
expect
(
wrapper
.
vm
.
itemsToBeDeleted
).
toEqual
([
store
.
state
.
tags
[
0
]]);
expect
(
DeleteModal
.
methods
.
show
).
toHaveBeenCalled
();
expect
(
Tracking
.
event
).
toHaveBeenCalledWith
(
undefined
,
'
click_button
'
,
{
label
:
'
registry_tag_delete
'
,
});
});
it
(
'
when multiple items are selected
'
,
()
=>
{
wrapper
.
setData
({
selectedItems
:
[
0
,
1
]
});
mountComponent
({
data
:
()
=>
({
selectedItems
:
store
.
state
.
tags
.
map
(
t
=>
t
.
name
)
}),
});
findBulkDeleteButton
().
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
expect
(
findDeleteModal
().
html
()).
toContain
(
'
You are about to remove <b>2</b> tags. Are you sure?
'
,
);
expect
(
GlModal
.
methods
.
show
).
toHaveBeenCalled
();
expect
(
Tracking
.
event
).
toHaveBeenCalledWith
(
undefined
,
'
click_button
'
,
{
label
:
'
bulk_registry_tag_delete
'
,
});
expect
(
wrapper
.
vm
.
itemsToBeDeleted
).
toEqual
(
tagsListResponse
.
data
);
expect
(
DeleteModal
.
methods
.
show
).
toHaveBeenCalled
();
expect
(
Tracking
.
event
).
toHaveBeenCalledWith
(
undefined
,
'
click_button
'
,
{
label
:
'
bulk_registry_tag_delete
'
,
});
});
});
...
...
@@ -237,14 +235,10 @@ describe('Details Page', () => {
findAllDeleteButtons
()
.
at
(
0
)
.
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
expect
(
findDeleteModal
().
html
()).
toContain
(
'
You are about to remove <b>bar</b>. Are you sure?
'
,
);
expect
(
GlModal
.
methods
.
show
).
toHaveBeenCalled
();
expect
(
Tracking
.
event
).
toHaveBeenCalledWith
(
undefined
,
'
click_button
'
,
{
label
:
'
registry_tag_delete
'
,
});
expect
(
DeleteModal
.
methods
.
show
).
toHaveBeenCalled
();
expect
(
Tracking
.
event
).
toHaveBeenCalledWith
(
undefined
,
'
click_button
'
,
{
label
:
'
registry_tag_delete
'
,
});
});
});
...
...
@@ -292,6 +286,7 @@ describe('Details Page', () => {
let
timeCell
;
beforeEach
(()
=>
{
mountComponent
();
timeCell
=
findFirstRowItem
(
'
rowTime
'
);
});
...
...
@@ -331,176 +326,97 @@ describe('Details Page', () => {
});
describe
(
'
modal
'
,
()
=>
{
beforeEach
(()
=>
{
mountComponent
();
});
it
(
'
exists
'
,
()
=>
{
mountComponent
();
expect
(
findDeleteModal
().
exists
()).
toBe
(
true
);
});
describe
(
'
when ok event is emitted
'
,
()
=>
{
beforeEach
(()
=>
{
dispatchSpy
.
mockResolvedValue
();
});
it
(
'
tracks confirm_delete
'
,
()
=>
{
const
deleteModal
=
findDeleteModal
();
deleteModal
.
vm
.
$emit
(
'
ok
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
expect
(
Tracking
.
event
).
toHaveBeenCalledWith
(
undefined
,
'
confirm_delete
'
,
{
label
:
'
registry_tag_delete
'
,
});
describe
(
'
cancel event
'
,
()
=>
{
it
(
'
tracks cancel_delete
'
,
()
=>
{
mountComponent
();
findDeleteModal
().
vm
.
$emit
(
'
cancel
'
);
expect
(
Tracking
.
event
).
toHaveBeenCalledWith
(
undefined
,
'
cancel_delete
'
,
{
label
:
'
registry_tag_delete
'
,
});
});
});
describe
(
'
when only one element is selected
'
,
()
=>
{
it
(
'
execute the delete and remove selection
'
,
()
=>
{
wrapper
.
setData
({
itemsToBeDeleted
:
[
0
]
});
findDeleteModal
().
vm
.
$emit
(
'
ok
'
);
describe
(
'
confirmDelete event
'
,
()
=>
{
describe
(
'
when one item is selected to be deleted
'
,
()
=>
{
const
itemsToBeDeleted
=
[{
name
:
'
foo
'
}];
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
requestDeleteTag
'
,
{
tag
:
store
.
state
.
tags
[
0
],
params
:
wrapper
.
vm
.
$route
.
params
.
id
,
it
(
'
dispatch requestDeleteTag with the right parameters
'
,
()
=>
{
mountComponent
({
data
:
()
=>
({
itemsToBeDeleted
})
});
findDeleteModal
().
vm
.
$emit
(
'
confirmDelete
'
);
expect
(
dispatchSpy
).
toHaveBeenCalledWith
(
'
requestDeleteTag
'
,
{
tag
:
itemsToBeDeleted
[
0
],
params
:
routeId
,
});
// itemsToBeDeleted is not represented in the DOM, is used as parking variable between selected and deleted items
expect
(
wrapper
.
vm
.
itemsToBeDeleted
).
toEqual
([]);
expect
(
wrapper
.
vm
.
selectedItems
).
toEqual
([]);
expect
(
findCheckedCheckboxes
()).
toHaveLength
(
0
);
});
it
(
'
remove the deleted item from the selected items
'
,
()
=>
{
mountComponent
({
data
:
()
=>
({
itemsToBeDeleted
,
selectedItems
:
[
'
foo
'
,
'
bar
'
]
})
});
findDeleteModal
().
vm
.
$emit
(
'
confirmDelete
'
);
expect
(
wrapper
.
vm
.
selectedItems
).
toEqual
([
'
bar
'
]);
});
});
describe
(
'
when m
ultiple elements are selec
ted
'
,
()
=>
{
describe
(
'
when m
ore than one item is selected to be dele
ted
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
.
setData
({
itemsToBeDeleted
:
[
0
,
1
]
});
mountComponent
({
data
:
()
=>
({
itemsToBeDeleted
:
[{
name
:
'
foo
'
},
{
name
:
'
bar
'
}],
selectedItems
:
[
'
foo
'
,
'
bar
'
],
}),
});
});
it
(
'
execute the delete and remove selection
'
,
()
=>
{
findDeleteModal
().
vm
.
$emit
(
'
ok
'
);
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
requestDeleteTags
'
,
{
ids
:
store
.
state
.
tags
.
map
(
t
=>
t
.
name
),
params
:
wrapper
.
vm
.
$route
.
params
.
id
,
it
(
'
dispatch requestDeleteTags with the right parameters
'
,
()
=>
{
findDeleteModal
().
vm
.
$emit
(
'
confirmDelete
'
);
expect
(
dispatchSpy
).
toHaveBeenCalledWith
(
'
requestDeleteTags
'
,
{
ids
:
[
'
foo
'
,
'
bar
'
],
params
:
routeId
,
});
// itemsToBeDeleted is not represented in the DOM, is used as parking variable between selected and deleted items
expect
(
wrapper
.
vm
.
itemsToBeDeleted
).
toEqual
([]);
expect
(
findCheckedCheckboxes
()).
toHaveLength
(
0
);
});
it
(
'
clears the selectedItems
'
,
()
=>
{
findDeleteModal
().
vm
.
$emit
(
'
confirmDelete
'
);
expect
(
wrapper
.
vm
.
selectedItems
).
toEqual
([]);
});
});
});
});
it
(
'
tracks cancel_delete when cancel event is emitted
'
,
()
=>
{
const
deleteModal
=
findDeleteModal
();
deleteModal
.
vm
.
$emit
(
'
cancel
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
expect
(
Tracking
.
event
).
toHaveBeenCalledWith
(
undefined
,
'
cancel_delete
'
,
{
label
:
'
registry_tag_delete
'
,
});
});
describe
(
'
Header
'
,
()
=>
{
it
(
'
exists
'
,
()
=>
{
mountComponent
();
expect
(
findDetailsHeader
().
exists
()).
toBe
(
true
);
});
it
(
'
has the correct props
'
,
()
=>
{
mountComponent
();
expect
(
findDetailsHeader
().
props
()).
toEqual
({
imageName
:
'
foo
'
});
});
});
describe
(
'
Delete
a
lert
'
,
()
=>
{
describe
(
'
Delete
A
lert
'
,
()
=>
{
const
config
=
{
garbageCollectionHelpPagePath
:
'
foo
'
,
isAdmin
:
true
,
garbageCollectionHelpPagePath
:
'
baz
'
,
};
const
deleteAlertType
=
'
success_tag
'
;
describe
(
'
when the user is an admin
'
,
()
=>
{
beforeEach
(()
=>
{
store
.
commit
(
SET_INITIAL_STATE
,
{
...
config
,
isAdmin
:
true
});
});
afterEach
(()
=>
{
store
.
commit
(
SET_INITIAL_STATE
,
config
);
});
describe
.
each
`
deleteType | successTitle | errorTitle
${
'
handleSingleDelete
'
}
|
${
DELETE_TAG_SUCCESS_MESSAGE
}
|
${
DELETE_TAG_ERROR_MESSAGE
}
${
'
handleMultipleDelete
'
}
|
${
DELETE_TAGS_SUCCESS_MESSAGE
}
|
${
DELETE_TAGS_ERROR_MESSAGE
}
`
(
'
behaves correctly on $deleteType
'
,
({
deleteType
,
successTitle
,
errorTitle
})
=>
{
describe
(
'
when delete is successful
'
,
()
=>
{
beforeEach
(()
=>
{
dispatchSpy
.
mockResolvedValue
();
mountComponent
();
return
wrapper
.
vm
[
deleteType
](
'
foo
'
);
});
it
(
'
alert exists
'
,
()
=>
{
expect
(
findAlert
().
exists
()).
toBe
(
true
);
});
it
(
'
alert body contains admin tip
'
,
()
=>
{
expect
(
findAlert
()
.
text
()
.
replace
(
/
\s\s
+/gm
,
'
'
),
).
toBe
(
ADMIN_GARBAGE_COLLECTION_TIP
.
replace
(
/%{
\w
+}/gm
,
''
));
});
it
(
'
alert body contains link
'
,
()
=>
{
const
alertLink
=
findAlert
().
find
(
GlLink
);
expect
(
alertLink
.
exists
()).
toBe
(
true
);
expect
(
alertLink
.
attributes
(
'
href
'
)).
toBe
(
config
.
garbageCollectionHelpPagePath
);
});
it
(
'
alert title is appropriate
'
,
()
=>
{
expect
(
findAlert
().
attributes
(
'
title
'
)).
toBe
(
successTitle
);
});
});
describe
(
'
when delete is not successful
'
,
()
=>
{
beforeEach
(()
=>
{
mountComponent
();
dispatchSpy
.
mockRejectedValue
();
return
wrapper
.
vm
[
deleteType
](
'
foo
'
);
});
it
(
'
exists
'
,
()
=>
{
mountComponent
();
expect
(
findDeleteAlert
().
exists
()).
toBe
(
true
);
});
it
(
'
alert exist and text is appropriate
'
,
()
=>
{
expect
(
findAlert
().
exists
()).
toBe
(
true
);
expect
(
findAlert
().
text
()).
toBe
(
errorTitle
);
});
});
it
(
'
has the correct props
'
,
()
=>
{
store
.
commit
(
SET_INITIAL_STATE
,
{
...
config
});
mountComponent
({
data
:
()
=>
({
deleteAlertType
,
}),
});
expect
(
findDeleteAlert
().
props
()).
toEqual
({
...
config
,
deleteAlertType
});
});
describe
.
each
`
deleteType | successTitle | errorTitle
${
'
handleSingleDelete
'
}
|
${
DELETE_TAG_SUCCESS_MESSAGE
}
|
${
DELETE_TAG_ERROR_MESSAGE
}
${
'
handleMultipleDelete
'
}
|
${
DELETE_TAGS_SUCCESS_MESSAGE
}
|
${
DELETE_TAGS_ERROR_MESSAGE
}
`
(
'
when the user is not an admin alert behaves correctly on $deleteType
'
,
({
deleteType
,
successTitle
,
errorTitle
})
=>
{
beforeEach
(()
=>
{
store
.
commit
(
'
SET_INITIAL_STATE
'
,
{
...
config
});
});
describe
(
'
when delete is successful
'
,
()
=>
{
beforeEach
(()
=>
{
dispatchSpy
.
mockResolvedValue
();
mountComponent
();
return
wrapper
.
vm
[
deleteType
](
'
foo
'
);
});
it
(
'
alert exist and text is appropriate
'
,
()
=>
{
expect
(
findAlert
().
exists
()).
toBe
(
true
);
expect
(
findAlert
().
text
()).
toBe
(
successTitle
);
});
});
describe
(
'
when delete is not successful
'
,
()
=>
{
beforeEach
(()
=>
{
mountComponent
();
dispatchSpy
.
mockRejectedValue
();
return
wrapper
.
vm
[
deleteType
](
'
foo
'
);
});
it
(
'
alert exist and text is appropriate
'
,
()
=>
{
expect
(
findAlert
().
exists
()).
toBe
(
true
);
expect
(
findAlert
().
text
()).
toBe
(
errorTitle
);
});
});
},
);
});
});
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