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
3d28e372
Commit
3d28e372
authored
May 27, 2021
by
Robert Hunt
Committed by
Natalia Tepluhina
May 27, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Create the delete modal for status checks
parent
cb611101
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
311 additions
and
12 deletions
+311
-12
ee/app/assets/javascripts/status_checks/components/actions.vue
...p/assets/javascripts/status_checks/components/actions.vue
+5
-1
ee/app/assets/javascripts/status_checks/components/modal_delete.vue
...ets/javascripts/status_checks/components/modal_delete.vue
+93
-0
ee/app/assets/javascripts/status_checks/components/status_checks.vue
...ts/javascripts/status_checks/components/status_checks.vue
+13
-1
ee/app/assets/javascripts/status_checks/store/actions.js
ee/app/assets/javascripts/status_checks/store/actions.js
+6
-0
ee/spec/frontend/status_checks/components/__snapshots__/modal_delete_spec.js.snap
...checks/components/__snapshots__/modal_delete_spec.js.snap
+20
-0
ee/spec/frontend/status_checks/components/actions_spec.js
ee/spec/frontend/status_checks/components/actions_spec.js
+10
-10
ee/spec/frontend/status_checks/components/modal_delete_spec.js
...ec/frontend/status_checks/components/modal_delete_spec.js
+121
-0
ee/spec/frontend/status_checks/components/status_checks_spec.js
...c/frontend/status_checks/components/status_checks_spec.js
+28
-0
ee/spec/frontend/status_checks/store/actions_spec.js
ee/spec/frontend/status_checks/store/actions_spec.js
+12
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-0
No files found.
ee/app/assets/javascripts/status_checks/components/actions.vue
View file @
3d28e372
...
...
@@ -24,7 +24,11 @@ export default {
<gl-button
data-testid=
"edit-btn"
@
click=
"$emit('open-update-modal', statusCheck)"
>
{{
$options
.
i18n
.
editButton
}}
</gl-button>
<gl-button
class=
"gl-ml-3"
data-testid=
"remove-btn"
>
<gl-button
class=
"gl-ml-3"
data-testid=
"remove-btn"
@
click=
"$emit('open-delete-modal', statusCheck)"
>
{{
$options
.
i18n
.
removeButton
}}
</gl-button>
</div>
...
...
ee/app/assets/javascripts/status_checks/components/modal_delete.vue
0 → 100644
View file @
3d28e372
<
script
>
import
{
GlModal
,
GlModalDirective
,
GlSprintf
}
from
'
@gitlab/ui
'
;
import
{
mapActions
,
mapState
}
from
'
vuex
'
;
import
createFlash
from
'
~/flash
'
;
import
{
__
,
s__
,
sprintf
}
from
'
~/locale
'
;
const
i18n
=
{
cancelButton
:
__
(
'
Cancel
'
),
deleteError
:
s__
(
'
StatusCheck|An error occurred deleting the %{name} status check.
'
),
primaryButton
:
s__
(
'
StatusCheck|Remove status check
'
),
title
:
s__
(
'
StatusCheck|Remove status check?
'
),
warningText
:
s__
(
'
StatusCheck|You are about to remove the %{name} status check.
'
),
};
export
default
{
components
:
{
GlModal
,
GlSprintf
,
},
directives
:
{
GlModal
:
GlModalDirective
,
},
props
:
{
statusCheck
:
{
type
:
Object
,
required
:
true
,
},
},
data
()
{
return
{
submitting
:
false
,
};
},
computed
:
{
...
mapState
({
projectId
:
({
settings
})
=>
settings
.
projectId
,
}),
primaryActionProps
()
{
return
{
text
:
i18n
.
primaryButton
,
attributes
:
[{
variant
:
'
danger
'
,
loading
:
this
.
submitting
}],
};
},
},
methods
:
{
...
mapActions
([
'
deleteStatusCheck
'
]),
async
submit
()
{
const
{
id
,
name
}
=
this
.
statusCheck
;
this
.
submitting
=
true
;
try
{
await
this
.
deleteStatusCheck
(
id
);
}
catch
(
error
)
{
createFlash
({
message
:
sprintf
(
i18n
.
deleteError
,
{
name
}),
captureError
:
true
,
error
,
});
}
this
.
submitting
=
false
;
this
.
$refs
.
modal
.
hide
();
},
show
()
{
this
.
$refs
.
modal
.
show
();
},
},
modalId
:
'
status-checks-delete-modal
'
,
cancelActionProps
:
{
text
:
i18n
.
cancelButton
,
},
i18n
,
};
</
script
>
<
template
>
<gl-modal
ref=
"modal"
:modal-id=
"$options.modalId"
:title=
"$options.i18n.title"
:action-primary=
"primaryActionProps"
:action-cancel=
"$options.cancelActionProps"
size=
"sm"
@
ok.prevent=
"submit"
>
<gl-sprintf
:message=
"$options.i18n.warningText"
>
<template
#name
>
<strong>
{{
statusCheck
.
name
}}
</strong>
</
template
>
</gl-sprintf>
</gl-modal>
</template>
ee/app/assets/javascripts/status_checks/components/status_checks.vue
View file @
3d28e372
...
...
@@ -8,6 +8,7 @@ import { EMPTY_STATUS_CHECK } from '../constants';
import
Actions
from
'
./actions.vue
'
;
import
Branch
from
'
./branch.vue
'
;
import
ModalCreate
from
'
./modal_create.vue
'
;
import
ModalDelete
from
'
./modal_delete.vue
'
;
import
ModalUpdate
from
'
./modal_update.vue
'
;
export
const
i18n
=
{
...
...
@@ -23,10 +24,12 @@ export default {
Branch
,
GlTable
,
ModalCreate
,
ModalDelete
,
ModalUpdate
,
},
data
()
{
return
{
statusCheckToDelete
:
EMPTY_STATUS_CHECK
,
statusCheckToUpdate
:
EMPTY_STATUS_CHECK
,
};
},
...
...
@@ -34,6 +37,10 @@ export default {
...
mapState
([
'
statusChecks
'
]),
},
methods
:
{
openDeleteModal
(
statusCheck
)
{
this
.
statusCheckToDelete
=
statusCheck
;
this
.
$refs
.
deleteModal
.
show
();
},
openUpdateModal
(
statusCheck
)
{
this
.
statusCheckToUpdate
=
statusCheck
;
this
.
$refs
.
updateModal
.
show
();
...
...
@@ -80,11 +87,16 @@ export default {
<branch
:branches=
"item.protectedBranches"
/>
</
template
>
<
template
#cell(actions)=
"{ item }"
>
<actions
:status-check=
"item"
@
open-update-modal=
"openUpdateModal"
/>
<actions
:status-check=
"item"
@
open-delete-modal=
"openDeleteModal"
@
open-update-modal=
"openUpdateModal"
/>
</
template
>
</gl-table>
<modal-create
/>
<modal-delete
ref=
"deleteModal"
:status-check=
"statusCheckToDelete"
/>
<modal-update
ref=
"updateModal"
:status-check=
"statusCheckToUpdate"
/>
</div>
</template>
ee/app/assets/javascripts/status_checks/store/actions.js
View file @
3d28e372
...
...
@@ -35,3 +35,9 @@ export const postStatusCheck = ({ dispatch, rootState }, statusCheck) => {
return
axios
.
post
(
statusChecksPath
,
data
).
then
(()
=>
dispatch
(
'
fetchStatusChecks
'
));
};
export
const
deleteStatusCheck
=
({
rootState
,
dispatch
},
id
)
=>
{
const
{
statusChecksPath
}
=
rootState
.
settings
;
return
axios
.
delete
(
`
${
statusChecksPath
}
/
${
id
}
`
).
then
(()
=>
dispatch
(
'
fetchStatusChecks
'
));
};
ee/spec/frontend/status_checks/components/__snapshots__/modal_delete_spec.js.snap
0 → 100644
View file @
3d28e372
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Modal delete Modal the modal text matches the snapshot 1`] = `
<gl-modal-stub
actioncancel="[object Object]"
actionprimary="[object Object]"
dismisslabel="Close"
modalclass=""
modalid="status-checks-delete-modal"
size="sm"
title="Remove status check?"
titletag="h4"
>
You are about to remove the
<strong>
Foo
</strong>
status check.
</gl-modal-stub>
`;
ee/spec/frontend/status_checks/components/actions_spec.js
View file @
3d28e372
...
...
@@ -34,19 +34,19 @@ describe('Status checks actions', () => {
const
findEditBtn
=
()
=>
wrapper
.
findByTestId
(
'
edit-btn
'
);
const
findRemoveBtn
=
()
=>
wrapper
.
findByTestId
(
'
remove-btn
'
);
describe
(
'
Edit button
'
,
()
=>
{
it
(
'
renders the edit button
'
,
()
=>
{
expect
(
findEditBtn
().
text
()).
toBe
(
'
Edit
'
);
describe
.
each
`
text | button | event
${
'
Edit
'
}
|
${
findEditBtn
}
|
${
'
open-update-modal
'
}
${
'
Remove...
'
}
|
${
findRemoveBtn
}
|
${
'
open-delete-modal
'
}
`
(
'
$text button
'
,
({
text
,
button
,
event
})
=>
{
it
(
`renders the button text as '
${
text
}
'`
,
()
=>
{
expect
(
button
().
text
()).
toBe
(
text
);
});
it
(
'
sends the status check to the update event
'
,
()
=>
{
findEditBt
n
().
trigger
(
'
click
'
);
it
(
`sends the status check with the '
${
event
}
' event`
,
()
=>
{
butto
n
().
trigger
(
'
click
'
);
expect
(
wrapper
.
emitted
(
'
open-update-modal
'
)[
0
][
0
]).
toStrictEqual
(
statusCheck
);
expect
(
wrapper
.
emitted
(
event
)[
0
][
0
]).
toStrictEqual
(
statusCheck
);
});
});
it
(
'
renders the remove button
'
,
()
=>
{
expect
(
findRemoveBtn
().
text
()).
toBe
(
'
Remove...
'
);
});
});
ee/spec/frontend/status_checks/components/modal_delete_spec.js
0 → 100644
View file @
3d28e372
import
{
GlModal
,
GlSprintf
}
from
'
@gitlab/ui
'
;
import
Vue
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
ModalDelete
from
'
ee/status_checks/components/modal_delete.vue
'
;
import
{
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
createFlash
from
'
~/flash
'
;
jest
.
mock
(
'
~/flash
'
);
Vue
.
use
(
Vuex
);
const
projectId
=
'
1
'
;
const
statusChecksPath
=
'
/api/v4/projects/1/external_approval_rules
'
;
const
statusCheck
=
{
externalUrl
:
'
https://foo.com
'
,
id
:
1
,
name
:
'
Foo
'
,
protectedBranches
:
[],
};
const
modalId
=
'
status-checks-delete-modal
'
;
describe
(
'
Modal delete
'
,
()
=>
{
let
wrapper
;
let
store
;
const
glModalDirective
=
jest
.
fn
();
const
actions
=
{
deleteStatusCheck
:
jest
.
fn
(),
};
const
createWrapper
=
()
=>
{
store
=
new
Vuex
.
Store
({
actions
,
state
:
{
isLoading
:
false
,
settings
:
{
projectId
,
statusChecksPath
},
statusChecks
:
[],
},
});
wrapper
=
shallowMountExtended
(
ModalDelete
,
{
directives
:
{
glModal
:
{
bind
(
el
,
{
modifiers
})
{
glModalDirective
(
modifiers
);
},
},
},
propsData
:
{
statusCheck
,
},
store
,
stubs
:
{
GlSprintf
},
});
wrapper
.
vm
.
$refs
.
modal
.
hide
=
jest
.
fn
();
};
beforeEach
(()
=>
{
createWrapper
();
});
afterEach
(()
=>
{
wrapper
.
destroy
();
});
const
findModal
=
()
=>
wrapper
.
findComponent
(
GlModal
);
const
clickModalOk
=
async
()
=>
{
await
findModal
().
vm
.
$emit
(
'
ok
'
,
{
preventDefault
:
()
=>
null
});
return
waitForPromises
();
};
describe
(
'
Modal
'
,
()
=>
{
it
(
'
sets the modals props
'
,
()
=>
{
expect
(
findModal
().
props
()).
toMatchObject
({
actionPrimary
:
{
text
:
'
Remove status check
'
,
attributes
:
[{
variant
:
'
danger
'
,
loading
:
false
}],
},
actionCancel
:
{
text
:
'
Cancel
'
},
modalId
,
size
:
'
sm
'
,
title
:
'
Remove status check?
'
,
});
});
it
(
'
the modal text matches the snapshot
'
,
()
=>
{
expect
(
wrapper
.
element
).
toMatchSnapshot
();
});
});
describe
(
'
Submission
'
,
()
=>
{
it
(
'
submits and hides the modal
'
,
async
()
=>
{
await
clickModalOk
();
expect
(
actions
.
deleteStatusCheck
).
toHaveBeenCalledWith
(
expect
.
any
(
Object
),
statusCheck
.
id
);
expect
(
wrapper
.
vm
.
$refs
.
modal
.
hide
).
toHaveBeenCalled
();
});
it
(
'
submits, hides the modal and shows the error
'
,
async
()
=>
{
const
error
=
new
Error
(
'
Something went wrong
'
);
actions
.
deleteStatusCheck
.
mockRejectedValueOnce
(
error
);
await
clickModalOk
();
expect
(
actions
.
deleteStatusCheck
).
toHaveBeenCalledWith
(
expect
.
any
(
Object
),
statusCheck
.
id
);
expect
(
wrapper
.
vm
.
$refs
.
modal
.
hide
).
toHaveBeenCalled
();
expect
(
createFlash
).
toHaveBeenCalledWith
({
message
:
'
An error occurred deleting the Foo status check.
'
,
captureError
:
true
,
error
,
});
});
});
});
ee/spec/frontend/status_checks/components/status_checks_spec.js
View file @
3d28e372
...
...
@@ -5,6 +5,7 @@ import Vuex from 'vuex';
import
Actions
from
'
ee/status_checks/components/actions.vue
'
;
import
Branch
from
'
ee/status_checks/components/branch.vue
'
;
import
ModalCreate
from
'
ee/status_checks/components/modal_create.vue
'
;
import
ModalDelete
from
'
ee/status_checks/components/modal_delete.vue
'
;
import
ModalUpdate
from
'
ee/status_checks/components/modal_update.vue
'
;
import
StatusChecks
,
{
i18n
}
from
'
ee/status_checks/components/status_checks.vue
'
;
import
createStore
from
'
ee/status_checks/store
'
;
...
...
@@ -25,6 +26,7 @@ describe('Status checks', () => {
store
=
createStore
();
wrapper
=
mountFn
(
StatusChecks
,
{
store
});
wrapper
.
vm
.
$refs
.
deleteModal
.
show
=
jest
.
fn
();
wrapper
.
vm
.
$refs
.
updateModal
.
show
=
jest
.
fn
();
};
...
...
@@ -33,6 +35,7 @@ describe('Status checks', () => {
});
const
findCreateModal
=
()
=>
wrapper
.
findComponent
(
ModalCreate
);
const
findDeleteModal
=
()
=>
wrapper
.
findComponent
(
ModalDelete
);
const
findUpdateModal
=
()
=>
wrapper
.
findComponent
(
ModalUpdate
);
const
findTable
=
()
=>
wrapper
.
findComponent
(
GlTable
);
const
findHeaders
=
()
=>
findTable
().
find
(
'
thead
'
).
find
(
'
tr
'
).
findAll
(
'
th
'
);
...
...
@@ -103,6 +106,31 @@ describe('Status checks', () => {
});
});
describe
(
'
Delete modal filling
'
,
()
=>
{
beforeEach
(()
=>
{
createWrapper
();
store
.
commit
(
SET_STATUS_CHECKS
,
statusChecks
);
});
it
(
'
opens the delete modal with the correct status check when a remove button is clicked
'
,
async
()
=>
{
const
statusCheck
=
findActions
(
0
,
1
).
props
(
'
statusCheck
'
);
await
findActions
(
0
,
1
).
vm
.
$emit
(
'
open-delete-modal
'
,
statusCheck
);
expect
(
findDeleteModal
().
props
(
'
statusCheck
'
)).
toStrictEqual
(
statusCheck
);
expect
(
wrapper
.
vm
.
$refs
.
deleteModal
.
show
).
toHaveBeenCalled
();
});
it
(
'
updates the status check prop for the delete modal when another remove button is clicked
'
,
async
()
=>
{
const
statusCheck
=
findActions
(
1
,
1
).
props
(
'
statusCheck
'
);
await
findActions
(
0
,
1
).
vm
.
$emit
(
'
open-delete-modal
'
,
findActions
(
0
,
1
).
props
(
'
statusCheck
'
));
await
findActions
(
1
,
1
).
vm
.
$emit
(
'
open-delete-modal
'
,
statusCheck
);
expect
(
findDeleteModal
().
props
(
'
statusCheck
'
)).
toStrictEqual
(
statusCheck
);
});
});
describe
(
'
Update modal filling
'
,
()
=>
{
beforeEach
(()
=>
{
createWrapper
();
...
...
ee/spec/frontend/status_checks/store/actions_spec.js
View file @
3d28e372
...
...
@@ -79,4 +79,16 @@ describe('Status checks actions', () => {
},
);
});
describe
(
'
deleteStatusCheck
'
,
()
=>
{
it
(
`should DELETE call the API and then dispatch a new fetchStatusChecks`
,
async
()
=>
{
const
id
=
1
;
mockAxios
.
onPost
(
statusChecksPath
).
replyOnce
(
httpStatusCodes
.
OK
);
await
actions
.
postStatusCheck
({
dispatch
,
rootState
},
id
);
expect
(
dispatch
).
toHaveBeenCalledWith
(
'
fetchStatusChecks
'
);
});
});
});
locale/gitlab.pot
View file @
3d28e372
...
...
@@ -31066,6 +31066,9 @@ msgstr ""
msgid "StatusCheck|Add status check"
msgstr ""
msgid "StatusCheck|An error occurred deleting the %{name} status check."
msgstr ""
msgid "StatusCheck|An error occurred fetching the status checks."
msgstr ""
...
...
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