2022-08-13 15:12:31 +05:30
import { GlSprintf , GlModal } from '@gitlab/ui' ;
import { shallowMount } from '@vue/test-utils' ;
2021-03-08 18:12:59 +05:30
import { TEST _HOST } from 'helpers/test_constants' ;
2018-03-17 18:26:18 +05:30
import axios from '~/lib/utils/axios_utils' ;
2022-08-13 15:12:31 +05:30
import DeleteMilestoneModal from '~/milestones/components/delete_milestone_modal.vue' ;
2022-01-26 12:08:38 +05:30
import eventHub from '~/milestones/event_hub' ;
2023-04-23 21:23:45 +05:30
import { HTTP _STATUS _IM _A _TEAPOT , HTTP _STATUS _NOT _FOUND } from '~/lib/utils/http_status' ;
2022-08-13 15:12:31 +05:30
import { redirectTo } from '~/lib/utils/url_utility' ;
import { createAlert } from '~/flash' ;
2018-03-17 18:26:18 +05:30
2022-08-13 15:12:31 +05:30
jest . mock ( '~/lib/utils/url_utility' ) ;
jest . mock ( '~/flash' ) ;
2020-05-24 23:13:21 +05:30
2022-08-13 15:12:31 +05:30
describe ( 'Delete milestone modal' , ( ) => {
let wrapper ;
const mockProps = {
2018-03-17 18:26:18 +05:30
issueCount : 1 ,
mergeRequestCount : 2 ,
milestoneId : 3 ,
milestoneTitle : 'my milestone title' ,
2020-07-28 23:09:34 +05:30
milestoneUrl : ` ${ TEST _HOST } /delete_milestone_modal.vue/milestone ` ,
2018-03-17 18:26:18 +05:30
} ;
2022-08-13 15:12:31 +05:30
const findModal = ( ) => wrapper . findComponent ( GlModal ) ;
const createComponent = ( props ) => {
wrapper = shallowMount ( DeleteMilestoneModal , {
propsData : {
... mockProps ,
... props ,
} ,
stubs : {
GlSprintf ,
} ,
} ) ;
} ;
beforeEach ( ( ) => {
createComponent ( ) ;
} ) ;
2018-03-17 18:26:18 +05:30
afterEach ( ( ) => {
2022-08-13 15:12:31 +05:30
wrapper . destroy ( ) ;
2018-03-17 18:26:18 +05:30
} ) ;
describe ( 'onSubmit' , ( ) => {
beforeEach ( ( ) => {
2020-05-24 23:13:21 +05:30
jest . spyOn ( eventHub , '$emit' ) . mockImplementation ( ( ) => { } ) ;
2018-03-17 18:26:18 +05:30
} ) ;
2022-06-21 17:19:12 +05:30
it ( 'deletes milestone and redirects to overview page' , async ( ) => {
2020-07-28 23:09:34 +05:30
const responseURL = ` ${ TEST _HOST } /delete_milestone_modal.vue/milestoneOverview ` ;
2021-03-08 18:12:59 +05:30
jest . spyOn ( axios , 'delete' ) . mockImplementation ( ( url ) => {
2022-08-13 15:12:31 +05:30
expect ( url ) . toBe ( mockProps . milestoneUrl ) ;
2018-12-13 13:39:08 +05:30
expect ( eventHub . $emit ) . toHaveBeenCalledWith (
'deleteMilestoneModal.requestStarted' ,
2022-08-13 15:12:31 +05:30
mockProps . milestoneUrl ,
2018-12-13 13:39:08 +05:30
) ;
2020-05-24 23:13:21 +05:30
eventHub . $emit . mockReset ( ) ;
2018-03-17 18:26:18 +05:30
return Promise . resolve ( {
request : {
responseURL ,
} ,
} ) ;
} ) ;
2022-08-13 15:12:31 +05:30
await findModal ( ) . vm . $emit ( 'primary' ) ;
2022-06-21 17:19:12 +05:30
expect ( redirectTo ) . toHaveBeenCalledWith ( responseURL ) ;
expect ( eventHub . $emit ) . toHaveBeenCalledWith ( 'deleteMilestoneModal.requestFinished' , {
2022-08-13 15:12:31 +05:30
milestoneUrl : mockProps . milestoneUrl ,
2022-06-21 17:19:12 +05:30
successful : true ,
} ) ;
2018-03-17 18:26:18 +05:30
} ) ;
2022-08-13 15:12:31 +05:30
it . each `
2023-04-23 21:23:45 +05:30
statusCode | alertMessage
$ { HTTP _STATUS _IM _A _TEAPOT } | $ { ` Failed to delete milestone ${ mockProps . milestoneTitle } ` }
$ { HTTP _STATUS _NOT _FOUND } | $ { ` Milestone ${ mockProps . milestoneTitle } was not found ` }
2022-08-13 15:12:31 +05:30
` (
'displays error if deleting milestone failed with code $statusCode' ,
async ( { statusCode , alertMessage } ) => {
const dummyError = new Error ( 'deleting milestone failed' ) ;
dummyError . response = { status : statusCode } ;
jest . spyOn ( axios , 'delete' ) . mockImplementation ( ( url ) => {
expect ( url ) . toBe ( mockProps . milestoneUrl ) ;
expect ( eventHub . $emit ) . toHaveBeenCalledWith (
'deleteMilestoneModal.requestStarted' ,
mockProps . milestoneUrl ,
) ;
eventHub . $emit . mockReset ( ) ;
return Promise . reject ( dummyError ) ;
} ) ;
2018-03-17 18:26:18 +05:30
2022-08-13 15:12:31 +05:30
await expect ( wrapper . vm . onSubmit ( ) ) . rejects . toEqual ( dummyError ) ;
expect ( createAlert ) . toHaveBeenCalledWith ( {
message : alertMessage ,
} ) ;
expect ( redirectTo ) . not . toHaveBeenCalled ( ) ;
expect ( eventHub . $emit ) . toHaveBeenCalledWith ( 'deleteMilestoneModal.requestFinished' , {
milestoneUrl : mockProps . milestoneUrl ,
successful : false ,
} ) ;
} ,
) ;
2018-03-17 18:26:18 +05:30
} ) ;
2022-08-13 15:12:31 +05:30
describe ( 'Modal title and description' , ( ) => {
const emptyDescription = ` You’ re about to permanently delete the milestone ${ mockProps . milestoneTitle } . This milestone is not currently used in any issues or merge requests. ` ;
const description = ` You’ re about to permanently delete the milestone ${ mockProps . milestoneTitle } and remove it from 1 issue and 2 merge requests. Once deleted, it cannot be undone or recovered. ` ;
const title = ` Delete milestone ${ mockProps . milestoneTitle } ? ` ;
2018-03-17 18:26:18 +05:30
2022-08-13 15:12:31 +05:30
it ( 'renders proper title' , ( ) => {
const value = findModal ( ) . props ( 'title' ) ;
expect ( value ) . toBe ( title ) ;
2018-03-17 18:26:18 +05:30
} ) ;
2022-08-13 15:12:31 +05:30
it . each `
statement | descriptionText | issueCount | mergeRequestCount
$ { '1 issue and 2 merge requests' } | $ { description } | $ { 1 } | $ { 2 }
$ { 'no issues and merge requests' } | $ { emptyDescription } | $ { 0 } | $ { 0 }
` (
'renders proper description when the milestone contains $statement' ,
( { issueCount , mergeRequestCount , descriptionText } ) => {
createComponent ( {
issueCount ,
mergeRequestCount ,
} ) ;
2018-03-17 18:26:18 +05:30
2022-08-13 15:12:31 +05:30
const value = findModal ( ) . text ( ) ;
expect ( value ) . toBe ( descriptionText ) ;
} ,
) ;
2018-03-17 18:26:18 +05:30
} ) ;
} ) ;