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
ad82e502
Commit
ad82e502
authored
Oct 29, 2021
by
Nicolò Maria Mezzopera
Committed by
Natalia Tepluhina
Oct 29, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add delete package to refactored list
parent
cd56feb8
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
363 additions
and
140 deletions
+363
-140
app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue
...nd_registries/package_registry/components/details/app.vue
+34
-52
app/assets/javascripts/packages_and_registries/package_registry/components/functional/delete_package.vue
...package_registry/components/functional/delete_package.vue
+60
-0
app/assets/javascripts/packages_and_registries/package_registry/components/list/app.vue
...s_and_registries/package_registry/components/list/app.vue
+42
-22
app/assets/javascripts/packages_and_registries/package_registry/components/list/packages_list.vue
...stries/package_registry/components/list/packages_list.vue
+11
-4
app/assets/javascripts/packages_and_registries/package_registry/constants.js
...pts/packages_and_registries/package_registry/constants.js
+0
-3
locale/gitlab.pot
locale/gitlab.pot
+3
-0
spec/frontend/packages_and_registries/package_registry/components/details/app_spec.js
...egistries/package_registry/components/details/app_spec.js
+5
-48
spec/frontend/packages_and_registries/package_registry/components/functional/delete_package_spec.js
...age_registry/components/functional/delete_package_spec.js
+160
-0
spec/frontend/packages_and_registries/package_registry/components/list/app_spec.js
...d_registries/package_registry/components/list/app_spec.js
+45
-1
spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js
...es/package_registry/components/list/packages_list_spec.js
+3
-10
No files found.
app/assets/javascripts/packages_and_registries/package_registry/components/details/app.vue
View file @
ad82e502
...
...
@@ -23,6 +23,7 @@ import PackageFiles from '~/packages_and_registries/package_registry/components/
import
PackageHistory
from
'
~/packages_and_registries/package_registry/components/details/package_history.vue
'
;
import
PackageTitle
from
'
~/packages_and_registries/package_registry/components/details/package_title.vue
'
;
import
VersionRow
from
'
~/packages_and_registries/package_registry/components/details/version_row.vue
'
;
import
DeletePackage
from
'
~/packages_and_registries/package_registry/components/functional/delete_package.vue
'
;
import
{
PACKAGE_TYPE_NUGET
,
PACKAGE_TYPE_COMPOSER
,
...
...
@@ -35,12 +36,10 @@ import {
CANCEL_DELETE_PACKAGE_FILE_TRACKING_ACTION
,
SHOW_DELETE_SUCCESS_ALERT
,
FETCH_PACKAGE_DETAILS_ERROR_MESSAGE
,
DELETE_PACKAGE_ERROR_MESSAGE
,
DELETE_PACKAGE_FILE_ERROR_MESSAGE
,
DELETE_PACKAGE_FILE_SUCCESS_MESSAGE
,
}
from
'
~/packages_and_registries/package_registry/constants
'
;
import
destroyPackageMutation
from
'
~/packages_and_registries/package_registry/graphql/mutations/destroy_package.mutation.graphql
'
;
import
destroyPackageFileMutation
from
'
~/packages_and_registries/package_registry/graphql/mutations/destroy_package_file.mutation.graphql
'
;
import
getPackageDetails
from
'
~/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql
'
;
import
Tracking
from
'
~/tracking
'
;
...
...
@@ -62,6 +61,7 @@ export default {
AdditionalMetadata
,
InstallationCommands
,
PackageFiles
,
DeletePackage
,
},
directives
:
{
GlTooltip
:
GlTooltipDirective
,
...
...
@@ -148,40 +148,15 @@ export default {
formatSize
(
size
)
{
return
numberToHumanSize
(
size
);
},
async
deletePackage
()
{
const
{
data
}
=
await
this
.
$apollo
.
mutate
({
mutation
:
destroyPackageMutation
,
variables
:
{
id
:
this
.
packageEntity
.
id
,
},
});
navigateToListWithSuccessModal
()
{
const
returnTo
=
!
this
.
groupListUrl
||
document
.
referrer
.
includes
(
this
.
projectName
)
?
this
.
projectListUrl
:
this
.
groupListUrl
;
// to avoid security issue url are supplied from backend
if
(
data
?.
destroyPackage
?.
errors
[
0
])
{
throw
data
.
destroyPackage
.
errors
[
0
];
}
},
async
confirmPackageDeletion
()
{
this
.
track
(
DELETE_PACKAGE_TRACKING_ACTION
);
try
{
await
this
.
deletePackage
();
const
returnTo
=
!
this
.
groupListUrl
||
document
.
referrer
.
includes
(
this
.
projectName
)
?
this
.
projectListUrl
:
this
.
groupListUrl
;
// to avoid security issue url are supplied from backend
const
modalQuery
=
objectToQuery
({
[
SHOW_DELETE_SUCCESS_ALERT
]:
true
});
const
modalQuery
=
objectToQuery
({
[
SHOW_DELETE_SUCCESS_ALERT
]:
true
});
window
.
location
.
replace
(
`
${
returnTo
}
?
${
modalQuery
}
`
);
}
catch
(
error
)
{
createFlash
({
message
:
DELETE_PACKAGE_ERROR_MESSAGE
,
type
:
'
warning
'
,
captureError
:
true
,
error
,
});
}
window
.
location
.
replace
(
`
${
returnTo
}
?
${
modalQuery
}
`
);
},
async
deletePackageFile
(
id
)
{
try
{
...
...
@@ -322,26 +297,33 @@ export default {
</gl-tab>
</gl-tabs>
<gl-modal
ref=
"deleteModal"
modal-id=
"delete-modal"
data-testid=
"delete-modal"
:action-primary=
"$options.modal.packageDeletePrimaryAction"
:action-cancel=
"$options.modal.cancelAction"
@
primary=
"confirmPackageDeletion"
@
canceled=
"track($options.trackingActions.CANCEL_DELETE_PACKAGE)"
<delete-package
@
start=
"track($options.trackingActions.DELETE_PACKAGE_TRACKING_ACTION)"
@
end=
"navigateToListWithSuccessModal"
>
<
template
#modal-title
>
{{
$options
.
i18n
.
deleteModalTitle
}}
</
template
>
<gl-sprintf
:message=
"$options.i18n.deleteModalContent"
>
<
template
#version
>
<strong>
{{
packageEntity
.
version
}}
</strong>
</
template
>
<
template
#default=
"{ deletePackage }"
>
<gl-modal
ref=
"deleteModal"
modal-id=
"delete-modal"
data-testid=
"delete-modal"
:action-primary=
"$options.modal.packageDeletePrimaryAction"
:action-cancel=
"$options.modal.cancelAction"
@
primary=
"deletePackage(packageEntity)"
@
canceled=
"track($options.trackingActions.CANCEL_DELETE_PACKAGE)"
>
<template
#modal-title
>
{{
$options
.
i18n
.
deleteModalTitle
}}
</
template
>
<gl-sprintf
:message=
"$options.i18n.deleteModalContent"
>
<
template
#version
>
<strong>
{{
packageEntity
.
version
}}
</strong>
</
template
>
<
template
#name
>
<strong>
{{
packageEntity
.
name
}}
</strong>
</
template
>
</gl-sprintf>
</gl-modal>
<
template
#name
>
<strong>
{{
packageEntity
.
name
}}
</strong>
</
template
>
</gl-sprintf>
</gl-modal>
</template>
</delete-package>
<gl-modal
ref=
"deleteFileModal"
...
...
app/assets/javascripts/packages_and_registries/package_registry/components/functional/delete_package.vue
0 → 100644
View file @
ad82e502
<
script
>
import
destroyPackageMutation
from
'
~/packages_and_registries/package_registry/graphql/mutations/destroy_package.mutation.graphql
'
;
import
createFlash
from
'
~/flash
'
;
import
{
s__
}
from
'
~/locale
'
;
export
default
{
props
:
{
refetchQueries
:
{
type
:
Array
,
required
:
false
,
default
:
null
,
},
showSuccessAlert
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
},
i18n
:
{
errorMessage
:
s__
(
'
PackageRegistry|Something went wrong while deleting the package.
'
),
successMessage
:
s__
(
'
PackageRegistry|Package deleted successfully
'
),
},
methods
:
{
async
deletePackage
(
packageEntity
)
{
try
{
this
.
$emit
(
'
start
'
);
const
{
data
}
=
await
this
.
$apollo
.
mutate
({
mutation
:
destroyPackageMutation
,
variables
:
{
id
:
packageEntity
.
id
,
},
awaitRefetchQueries
:
Boolean
(
this
.
refetchQueries
),
refetchQueries
:
this
.
refetchQueries
,
});
if
(
data
?.
destroyPackage
?.
errors
[
0
])
{
throw
data
.
destroyPackage
.
errors
[
0
];
}
if
(
this
.
showSuccessAlert
)
{
createFlash
({
message
:
this
.
$options
.
i18n
.
successMessage
,
type
:
'
success
'
,
});
}
}
catch
(
error
)
{
createFlash
({
message
:
this
.
$options
.
i18n
.
errorMessage
,
type
:
'
warning
'
,
captureError
:
true
,
error
,
});
}
this
.
$emit
(
'
end
'
);
},
},
render
()
{
return
this
.
$scopedSlots
.
default
({
deletePackage
:
this
.
deletePackage
});
},
};
</
script
>
app/assets/javascripts/packages_and_registries/package_registry/components/list/app.vue
View file @
ad82e502
<
script
>
/*
* The following component has several commented lines, this is because we are refactoring them piece by piece on several mrs
* For a complete overview of the plan please check: https://gitlab.com/gitlab-org/gitlab/-/issues/330846
* This work is behind feature flag: https://gitlab.com/gitlab-org/gitlab/-/issues/341136
*/
import
{
GlEmptyState
,
GlLink
,
GlSprintf
}
from
'
@gitlab/ui
'
;
import
createFlash
from
'
~/flash
'
;
import
{
historyReplaceState
}
from
'
~/lib/utils/common_utils
'
;
import
{
s__
}
from
'
~/locale
'
;
import
{
DELETE_PACKAGE_SUCCESS_MESSAGE
}
from
'
~/packages/list/constants
'
;
import
{
SHOW_DELETE_SUCCESS_ALERT
}
from
'
~/packages/shared/constants
'
;
import
getPackagesQuery
from
'
~/packages_and_registries/package_registry/graphql/queries/get_packages.query.graphql
'
;
import
{
PROJECT_RESOURCE_TYPE
,
GROUP_RESOURCE_TYPE
,
LIST_QUERY_DEBOUNCE_TIME
,
GRAPHQL_PAGE_SIZE
,
}
from
'
~/packages_and_registries/package_registry/constants
'
;
import
getPackagesQuery
from
'
~/packages_and_registries/package_registry/graphql/queries/get_packages.query.graphql
'
;
import
DeletePackage
from
'
~/packages_and_registries/package_registry/components/functional/delete_package.vue
'
;
import
PackageTitle
from
'
./package_title.vue
'
;
import
PackageSearch
from
'
./package_search.vue
'
;
import
PackageList
from
'
./packages_list.vue
'
;
...
...
@@ -29,6 +26,7 @@ export default {
PackageList
,
PackageTitle
,
PackageSearch
,
DeletePackage
,
},
inject
:
[
'
packageHelpUrl
'
,
...
...
@@ -42,6 +40,7 @@ export default {
packages
:
{},
sort
:
''
,
filters
:
{},
mutationLoading
:
false
,
};
},
apollo
:
{
...
...
@@ -88,6 +87,17 @@ export default {
?
this
.
$options
.
i18n
.
emptyPageTitle
:
this
.
$options
.
i18n
.
noResultsTitle
;
},
isLoading
()
{
return
this
.
$apollo
.
queries
.
packages
.
loading
||
this
.
mutationLoading
;
},
refetchQueriesData
()
{
return
[
{
query
:
getPackagesQuery
,
variables
:
this
.
queryVariables
,
},
];
},
},
mounted
()
{
this
.
checkDeleteAlert
();
...
...
@@ -153,25 +163,35 @@ export default {
<package-title
:help-url=
"packageHelpUrl"
:count=
"packagesCount"
/>
<package-search
@
update=
"handleSearchUpdate"
/>
<package-list
:list=
"packages.nodes"
:is-loading=
"$apollo.queries.packages.loading"
:page-info=
"pageInfo"
@
prev-page=
"fetchPreviousPage"
@
next-page=
"fetchNextPage"
<delete-package
:refetch-queries=
"refetchQueriesData"
show-success-alert
@
start=
"mutationLoading = true"
@
end=
"mutationLoading = false"
>
<template
#empty-state
>
<gl-empty-state
:title=
"emptyStateTitle"
:svg-path=
"emptyListIllustration"
>
<template
#description
>
<gl-sprintf
v-if=
"hasFilters"
:message=
"$options.i18n.widenFilters"
/>
<gl-sprintf
v-else
:message=
"$options.i18n.noResultsText"
>
<template
#noPackagesLink
="
{ content }">
<gl-link
:href=
"emptyListHelpUrl"
target=
"_blank"
>
{{
content
}}
</gl-link>
<template
#default
="
{ deletePackage }">
<package-list
:list=
"packages.nodes"
:is-loading=
"isLoading"
:page-info=
"pageInfo"
@
prev-page=
"fetchPreviousPage"
@
next-page=
"fetchNextPage"
@
package:delete=
"deletePackage"
>
<template
#empty-state
>
<gl-empty-state
:title=
"emptyStateTitle"
:svg-path=
"emptyListIllustration"
>
<template
#description
>
<gl-sprintf
v-if=
"hasFilters"
:message=
"$options.i18n.widenFilters"
/>
<gl-sprintf
v-else
:message=
"$options.i18n.noResultsText"
>
<template
#noPackagesLink
="
{ content }">
<gl-link
:href=
"emptyListHelpUrl"
target=
"_blank"
>
{{
content
}}
</gl-link>
</
template
>
</gl-sprintf>
</template>
</gl-
sprintf
>
</gl-
empty-state
>
</template>
</
gl-empty-state
>
</
package-list
>
</template>
</
package-list
>
</
delete-package
>
</div>
</template>
app/assets/javascripts/packages_and_registries/package_registry/components/list/packages_list.vue
View file @
ad82e502
...
...
@@ -60,21 +60,28 @@ export default {
showPagination
()
{
return
this
.
pageInfo
.
hasPreviousPage
||
this
.
pageInfo
.
hasNextPage
;
},
showDeleteModal
:
{
get
()
{
return
Boolean
(
this
.
itemToBeDeleted
);
},
set
(
value
)
{
if
(
!
value
)
{
this
.
itemToBeDeleted
=
null
;
}
},
},
},
methods
:
{
setItemToBeDeleted
(
item
)
{
this
.
itemToBeDeleted
=
{
...
item
};
this
.
track
(
REQUEST_DELETE_PACKAGE_TRACKING_ACTION
);
this
.
$refs
.
packageListDeleteModal
.
show
();
},
deleteItemConfirmation
()
{
this
.
$emit
(
'
package:delete
'
,
this
.
itemToBeDeleted
);
this
.
track
(
DELETE_PACKAGE_TRACKING_ACTION
);
this
.
itemToBeDeleted
=
null
;
},
deleteItemCanceled
()
{
this
.
track
(
CANCEL_DELETE_PACKAGE_TRACKING_ACTION
);
this
.
itemToBeDeleted
=
null
;
},
},
i18n
:
{
...
...
@@ -115,7 +122,7 @@ export default {
</div>
<gl-modal
ref=
"packageList
DeleteModal"
v-model=
"show
DeleteModal"
modal-id=
"confirm-delete-pacakge"
ok-variant=
"danger"
@
ok=
"deleteItemConfirmation"
...
...
app/assets/javascripts/packages_and_registries/package_registry/constants.js
View file @
ad82e502
...
...
@@ -60,9 +60,6 @@ export const TRACKING_ACTION_COPY_COMPOSER_PACKAGE_INCLUDE_COMMAND =
'
copy_composer_package_include_command
'
;
export
const
SHOW_DELETE_SUCCESS_ALERT
=
'
showSuccessDeleteAlert
'
;
export
const
DELETE_PACKAGE_ERROR_MESSAGE
=
s__
(
'
PackageRegistry|Something went wrong while deleting the package.
'
,
);
export
const
DELETE_PACKAGE_FILE_ERROR_MESSAGE
=
s__
(
'
PackageRegistry|Something went wrong while deleting the package file.
'
,
);
...
...
locale/gitlab.pot
View file @
ad82e502
...
...
@@ -24512,6 +24512,9 @@ msgstr ""
msgid "PackageRegistry|Package Registry"
msgstr ""
msgid "PackageRegistry|Package deleted successfully"
msgstr ""
msgid "PackageRegistry|Package file deleted successfully"
msgstr ""
...
...
spec/frontend/packages_and_registries/package_registry/components/details/app_spec.js
View file @
ad82e502
...
...
@@ -16,16 +16,15 @@ import PackageFiles from '~/packages_and_registries/package_registry/components/
import
PackageHistory
from
'
~/packages_and_registries/package_registry/components/details/package_history.vue
'
;
import
PackageTitle
from
'
~/packages_and_registries/package_registry/components/details/package_title.vue
'
;
import
VersionRow
from
'
~/packages_and_registries/package_registry/components/details/version_row.vue
'
;
import
DeletePackage
from
'
~/packages_and_registries/package_registry/components/functional/delete_package.vue
'
;
import
{
FETCH_PACKAGE_DETAILS_ERROR_MESSAGE
,
DELETE_PACKAGE_ERROR_MESSAGE
,
PACKAGE_TYPE_COMPOSER
,
DELETE_PACKAGE_FILE_SUCCESS_MESSAGE
,
DELETE_PACKAGE_FILE_ERROR_MESSAGE
,
PACKAGE_TYPE_NUGET
,
}
from
'
~/packages_and_registries/package_registry/constants
'
;
import
destroyPackageMutation
from
'
~/packages_and_registries/package_registry/graphql/mutations/destroy_package.mutation.graphql
'
;
import
destroyPackageFileMutation
from
'
~/packages_and_registries/package_registry/graphql/mutations/destroy_package_file.mutation.graphql
'
;
import
getPackageDetails
from
'
~/packages_and_registries/package_registry/graphql/queries/get_package_details.query.graphql
'
;
import
{
...
...
@@ -34,8 +33,6 @@ import {
packageVersions
,
dependencyLinks
,
emptyPackageDetailsQuery
,
packageDestroyMutation
,
packageDestroyMutationError
,
packageFiles
,
packageDestroyFileMutation
,
packageDestroyFileMutationError
,
...
...
@@ -64,14 +61,12 @@ describe('PackagesApp', () => {
function
createComponent
({
resolver
=
jest
.
fn
().
mockResolvedValue
(
packageDetailsQuery
()),
mutationResolver
=
jest
.
fn
().
mockResolvedValue
(
packageDestroyMutation
()),
fileDeleteMutationResolver
=
jest
.
fn
().
mockResolvedValue
(
packageDestroyFileMutation
()),
}
=
{})
{
localVue
.
use
(
VueApollo
);
const
requestHandlers
=
[
[
getPackageDetails
,
resolver
],
[
destroyPackageMutation
,
mutationResolver
],
[
destroyPackageFileMutation
,
fileDeleteMutationResolver
],
];
apolloProvider
=
createMockApollo
(
requestHandlers
);
...
...
@@ -82,6 +77,7 @@ describe('PackagesApp', () => {
provide
,
stubs
:
{
PackageTitle
,
DeletePackage
,
GlModal
:
{
template
:
'
<div></div>
'
,
methods
:
{
...
...
@@ -108,6 +104,7 @@ describe('PackagesApp', () => {
const
findDependenciesCountBadge
=
()
=>
wrapper
.
findComponent
(
GlBadge
);
const
findNoDependenciesMessage
=
()
=>
wrapper
.
findByTestId
(
'
no-dependencies-message
'
);
const
findDependencyRows
=
()
=>
wrapper
.
findAllComponents
(
DependencyRow
);
const
findDeletePackage
=
()
=>
wrapper
.
findComponent
(
DeletePackage
);
afterEach
(()
=>
{
wrapper
.
destroy
();
...
...
@@ -187,14 +184,6 @@ describe('PackagesApp', () => {
});
};
const
performDeletePackage
=
async
()
=>
{
await
findDeleteButton
().
trigger
(
'
click
'
);
findDeleteModal
().
vm
.
$emit
(
'
primary
'
);
await
waitForPromises
();
};
afterEach
(()
=>
{
Object
.
defineProperty
(
document
,
'
referrer
'
,
{
value
:
originalReferrer
,
...
...
@@ -220,7 +209,7 @@ describe('PackagesApp', () => {
await
waitForPromises
();
await
performDeletePackage
(
);
findDeletePackage
().
vm
.
$emit
(
'
end
'
);
expect
(
window
.
location
.
replace
).
toHaveBeenCalledWith
(
'
projectListUrl?showSuccessDeleteAlert=true
'
,
...
...
@@ -234,45 +223,13 @@ describe('PackagesApp', () => {
await
waitForPromises
();
await
performDeletePackage
(
);
findDeletePackage
().
vm
.
$emit
(
'
end
'
);
expect
(
window
.
location
.
replace
).
toHaveBeenCalledWith
(
'
groupListUrl?showSuccessDeleteAlert=true
'
,
);
});
});
describe
(
'
request failure
'
,
()
=>
{
it
(
'
on global failure it displays an alert
'
,
async
()
=>
{
createComponent
({
mutationResolver
:
jest
.
fn
().
mockRejectedValue
()
});
await
waitForPromises
();
await
performDeletePackage
();
expect
(
createFlash
).
toHaveBeenCalledWith
(
expect
.
objectContaining
({
message
:
DELETE_PACKAGE_ERROR_MESSAGE
,
}),
);
});
it
(
'
on payload with error it displays an alert
'
,
async
()
=>
{
createComponent
({
mutationResolver
:
jest
.
fn
().
mockResolvedValue
(
packageDestroyMutationError
()),
});
await
waitForPromises
();
await
performDeletePackage
();
expect
(
createFlash
).
toHaveBeenCalledWith
(
expect
.
objectContaining
({
message
:
DELETE_PACKAGE_ERROR_MESSAGE
,
}),
);
});
});
});
describe
(
'
package files
'
,
()
=>
{
...
...
spec/frontend/packages_and_registries/package_registry/components/functional/delete_package_spec.js
0 → 100644
View file @
ad82e502
import
{
createLocalVue
}
from
'
@vue/test-utils
'
;
import
VueApollo
from
'
vue-apollo
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
{
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
createMockApollo
from
'
helpers/mock_apollo_helper
'
;
import
createFlash
from
'
~/flash
'
;
import
DeletePackage
from
'
~/packages_and_registries/package_registry/components/functional/delete_package.vue
'
;
import
destroyPackageMutation
from
'
~/packages_and_registries/package_registry/graphql/mutations/destroy_package.mutation.graphql
'
;
import
getPackagesQuery
from
'
~/packages_and_registries/package_registry/graphql/queries/get_packages.query.graphql
'
;
import
{
packageDestroyMutation
,
packageDestroyMutationError
,
packagesListQuery
,
}
from
'
../../mock_data
'
;
jest
.
mock
(
'
~/flash
'
);
const
localVue
=
createLocalVue
();
describe
(
'
DeletePackage
'
,
()
=>
{
let
wrapper
;
let
apolloProvider
;
let
resolver
;
let
mutationResolver
;
const
eventPayload
=
{
id
:
'
1
'
};
function
createComponent
(
propsData
=
{})
{
localVue
.
use
(
VueApollo
);
const
requestHandlers
=
[
[
getPackagesQuery
,
resolver
],
[
destroyPackageMutation
,
mutationResolver
],
];
apolloProvider
=
createMockApollo
(
requestHandlers
);
wrapper
=
shallowMountExtended
(
DeletePackage
,
{
propsData
,
localVue
,
apolloProvider
,
scopedSlots
:
{
default
(
props
)
{
return
this
.
$createElement
(
'
button
'
,
{
attrs
:
{
'
data-testid
'
:
'
trigger-button
'
,
},
on
:
{
click
:
props
.
deletePackage
,
},
});
},
},
});
}
const
findButton
=
()
=>
wrapper
.
findByTestId
(
'
trigger-button
'
);
const
clickOnButtonAndWait
=
(
payload
)
=>
{
findButton
().
trigger
(
'
click
'
,
payload
);
return
waitForPromises
();
};
beforeEach
(()
=>
{
resolver
=
jest
.
fn
().
mockResolvedValue
(
packagesListQuery
());
mutationResolver
=
jest
.
fn
().
mockResolvedValue
(
packageDestroyMutation
());
});
afterEach
(()
=>
{
wrapper
.
destroy
();
});
it
(
'
binds deletePackage method to the default slot
'
,
()
=>
{
createComponent
();
findButton
().
trigger
(
'
click
'
);
expect
(
wrapper
.
emitted
(
'
start
'
)).
toEqual
([[]]);
});
it
(
'
calls apollo mutation
'
,
async
()
=>
{
createComponent
();
await
clickOnButtonAndWait
(
eventPayload
);
expect
(
mutationResolver
).
toHaveBeenCalledWith
(
eventPayload
);
});
it
(
'
passes refetchQueries to apollo mutate
'
,
async
()
=>
{
const
variables
=
{
isGroupPage
:
true
};
createComponent
({
refetchQueries
:
[{
query
:
getPackagesQuery
,
variables
}],
});
await
clickOnButtonAndWait
(
eventPayload
);
expect
(
mutationResolver
).
toHaveBeenCalledWith
(
eventPayload
);
expect
(
resolver
).
toHaveBeenCalledWith
(
variables
);
});
describe
(
'
on mutation success
'
,
()
=>
{
it
(
'
emits end event
'
,
async
()
=>
{
createComponent
();
await
clickOnButtonAndWait
(
eventPayload
);
expect
(
wrapper
.
emitted
(
'
end
'
)).
toEqual
([[]]);
});
it
(
'
does not call createFlash
'
,
async
()
=>
{
createComponent
();
await
clickOnButtonAndWait
(
eventPayload
);
expect
(
createFlash
).
not
.
toHaveBeenCalled
();
});
it
(
'
calls createFlash with the success message when showSuccessAlert is true
'
,
async
()
=>
{
createComponent
({
showSuccessAlert
:
true
});
await
clickOnButtonAndWait
(
eventPayload
);
expect
(
createFlash
).
toHaveBeenCalledWith
({
message
:
DeletePackage
.
i18n
.
successMessage
,
type
:
'
success
'
,
});
});
});
describe
.
each
`
errorType | mutationResolverResponse
${
'
connectionError
'
}
|
${
jest
.
fn
().
mockRejectedValue
()}
${
'
localError
'
}
|
${
jest
.
fn
().
mockResolvedValue
(
packageDestroyMutationError
())}
`
(
'
on mutation $errorType
'
,
({
mutationResolverResponse
})
=>
{
beforeEach
(()
=>
{
mutationResolver
=
mutationResolverResponse
;
});
it
(
'
emits end event
'
,
async
()
=>
{
createComponent
();
await
clickOnButtonAndWait
(
eventPayload
);
expect
(
wrapper
.
emitted
(
'
end
'
)).
toEqual
([[]]);
});
it
(
'
calls createFlash with the error message
'
,
async
()
=>
{
createComponent
({
showSuccessAlert
:
true
});
await
clickOnButtonAndWait
(
eventPayload
);
expect
(
createFlash
).
toHaveBeenCalledWith
({
message
:
DeletePackage
.
i18n
.
errorMessage
,
type
:
'
warning
'
,
captureError
:
true
,
error
:
expect
.
any
(
Error
),
});
});
});
});
spec/frontend/packages_and_registries/package_registry/components/list/app_spec.js
View file @
ad82e502
...
...
@@ -10,6 +10,7 @@ import PackageListApp from '~/packages_and_registries/package_registry/component
import
PackageTitle
from
'
~/packages_and_registries/package_registry/components/list/package_title.vue
'
;
import
PackageSearch
from
'
~/packages_and_registries/package_registry/components/list/package_search.vue
'
;
import
OriginalPackageList
from
'
~/packages_and_registries/package_registry/components/list/packages_list.vue
'
;
import
DeletePackage
from
'
~/packages_and_registries/package_registry/components/functional/delete_package.vue
'
;
import
{
PROJECT_RESOURCE_TYPE
,
...
...
@@ -55,6 +56,7 @@ describe('PackagesListApp', () => {
const
findSearch
=
()
=>
wrapper
.
findComponent
(
PackageSearch
);
const
findListComponent
=
()
=>
wrapper
.
findComponent
(
PackageList
);
const
findEmptyState
=
()
=>
wrapper
.
findComponent
(
GlEmptyState
);
const
findDeletePackage
=
()
=>
wrapper
.
findComponent
(
DeletePackage
);
const
mountComponent
=
({
resolver
=
jest
.
fn
().
mockResolvedValue
(
packagesListQuery
()),
...
...
@@ -72,9 +74,10 @@ describe('PackagesListApp', () => {
stubs
:
{
GlEmptyState
,
GlLoadingIcon
,
PackageList
,
GlSprintf
,
GlLink
,
PackageList
,
DeletePackage
,
},
});
};
...
...
@@ -228,4 +231,45 @@ describe('PackagesListApp', () => {
expect
(
findEmptyState
().
text
()).
toContain
(
PackageListApp
.
i18n
.
widenFilters
);
});
});
describe
(
'
delete package
'
,
()
=>
{
it
(
'
exists and has the correct props
'
,
async
()
=>
{
mountComponent
();
await
waitForDebouncedApollo
();
expect
(
findDeletePackage
().
props
()).
toMatchObject
({
refetchQueries
:
[{
query
:
getPackagesQuery
,
variables
:
{}
}],
showSuccessAlert
:
true
,
});
});
it
(
'
deletePackage is bound to package-list package:delete event
'
,
async
()
=>
{
mountComponent
();
await
waitForDebouncedApollo
();
findListComponent
().
vm
.
$emit
(
'
package:delete
'
,
{
id
:
1
});
expect
(
findDeletePackage
().
emitted
(
'
start
'
)).
toEqual
([[]]);
});
it
(
'
start and end event set loading correctly
'
,
async
()
=>
{
mountComponent
();
await
waitForDebouncedApollo
();
findDeletePackage
().
vm
.
$emit
(
'
start
'
);
await
nextTick
();
expect
(
findListComponent
().
props
(
'
isLoading
'
)).
toBe
(
true
);
findDeletePackage
().
vm
.
$emit
(
'
end
'
);
await
nextTick
();
expect
(
findListComponent
().
props
(
'
isLoading
'
)).
toBe
(
false
);
});
});
});
spec/frontend/packages_and_registries/package_registry/components/list/packages_list_spec.js
View file @
ad82e502
...
...
@@ -122,14 +122,6 @@ describe('packages_list', () => {
expect
(
findPackageListDeleteModal
().
text
()).
toContain
(
firstPackage
.
name
);
});
it
(
'
confirming delete empties itemsToBeDeleted
'
,
async
()
=>
{
findPackageListDeleteModal
().
vm
.
$emit
(
'
ok
'
);
await
nextTick
();
expect
(
findPackageListDeleteModal
().
text
()).
not
.
toContain
(
firstPackage
.
name
);
});
it
(
'
confirming on the modal emits package:delete
'
,
async
()
=>
{
findPackageListDeleteModal
().
vm
.
$emit
(
'
ok
'
);
...
...
@@ -138,8 +130,9 @@ describe('packages_list', () => {
expect
(
wrapper
.
emitted
(
'
package:delete
'
)[
0
]).
toEqual
([
firstPackage
]);
});
it
(
'
cancel event resets itemToBeDeleted
'
,
async
()
=>
{
findPackageListDeleteModal
().
vm
.
$emit
(
'
cancel
'
);
it
(
'
closing the modal resets itemToBeDeleted
'
,
async
()
=>
{
// triggering the v-model
findPackageListDeleteModal
().
vm
.
$emit
(
'
input
'
,
false
);
await
nextTick
();
...
...
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