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
0d6b1f91
Commit
0d6b1f91
authored
Jan 24, 2022
by
Stanislav Lashmanov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor nextTick to use direct import from Vue package
RFC:
https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/47
parent
b568065f
Changes
69
Show whitespace changes
Inline
Side-by-side
Showing
69 changed files
with
722 additions
and
833 deletions
+722
-833
spec/frontend/diffs/components/collapsed_files_warning_spec.js
...frontend/diffs/components/collapsed_files_warning_spec.js
+2
-2
spec/frontend/diffs/components/compare_versions_spec.js
spec/frontend/diffs/components/compare_versions_spec.js
+8
-10
spec/frontend/diffs/components/diff_file_header_spec.js
spec/frontend/diffs/components/diff_file_header_spec.js
+10
-13
spec/frontend/diffs/components/diff_file_spec.js
spec/frontend/diffs/components/diff_file_spec.js
+15
-15
spec/frontend/diffs/components/diff_gutter_avatars_spec.js
spec/frontend/diffs/components/diff_gutter_avatars_spec.js
+10
-12
spec/frontend/diffs/components/tree_list_spec.js
spec/frontend/diffs/components/tree_list_spec.js
+15
-19
spec/frontend/environments/canary_update_modal_spec.js
spec/frontend/environments/canary_update_modal_spec.js
+6
-5
spec/frontend/environments/deploy_board_component_spec.js
spec/frontend/environments/deploy_board_component_spec.js
+5
-5
spec/frontend/environments/environment_actions_spec.js
spec/frontend/environments/environment_actions_spec.js
+2
-2
spec/frontend/environments/environment_table_spec.js
spec/frontend/environments/environment_table_spec.js
+2
-1
spec/frontend/environments/environments_app_spec.js
spec/frontend/environments/environments_app_spec.js
+4
-4
spec/frontend/error_tracking/components/error_details_spec.js
.../frontend/error_tracking/components/error_details_spec.js
+56
-67
spec/frontend/error_tracking/components/error_tracking_actions_spec.js
.../error_tracking/components/error_tracking_actions_spec.js
+11
-13
spec/frontend/error_tracking/components/error_tracking_list_spec.js
...end/error_tracking/components/error_tracking_list_spec.js
+17
-20
spec/frontend/error_tracking_settings/components/app_spec.js
spec/frontend/error_tracking_settings/components/app_spec.js
+3
-4
spec/frontend/error_tracking_settings/components/project_dropdown_spec.js
...ror_tracking_settings/components/project_dropdown_spec.js
+7
-7
spec/frontend/feature_flags/components/configure_feature_flags_modal_spec.js
...re_flags/components/configure_feature_flags_modal_spec.js
+4
-3
spec/frontend/feature_flags/components/edit_feature_flag_spec.js
...ontend/feature_flags/components/edit_feature_flag_spec.js
+7
-7
spec/frontend/feature_flags/components/empty_state_spec.js
spec/frontend/feature_flags/components/empty_state_spec.js
+2
-1
spec/frontend/feature_flags/components/environments_dropdown_spec.js
...nd/feature_flags/components/environments_dropdown_spec.js
+8
-7
spec/frontend/feature_flags/components/feature_flags_spec.js
spec/frontend/feature_flags/components/feature_flags_spec.js
+2
-2
spec/frontend/feature_flags/components/feature_flags_table_spec.js
...tend/feature_flags/components/feature_flags_table_spec.js
+4
-4
spec/frontend/feature_flags/components/form_spec.js
spec/frontend/feature_flags/components/form_spec.js
+10
-11
spec/frontend/feature_flags/components/new_environments_dropdown_spec.js
...eature_flags/components/new_environments_dropdown_spec.js
+5
-7
spec/frontend/feature_flags/components/new_feature_flag_spec.js
...rontend/feature_flags/components/new_feature_flag_spec.js
+6
-7
spec/frontend/feature_flags/components/strategies/flexible_rollout_spec.js
...ture_flags/components/strategies/flexible_rollout_spec.js
+2
-1
spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js
...ture_flags/components/strategies/gitlab_user_list_spec.js
+3
-3
spec/frontend/feature_flags/components/strategies/percent_rollout_spec.js
...ature_flags/components/strategies/percent_rollout_spec.js
+2
-1
spec/frontend/feature_flags/components/strategy_spec.js
spec/frontend/feature_flags/components/strategy_spec.js
+63
-71
spec/frontend/feature_highlight/feature_highlight_popover_spec.js
...ntend/feature_highlight/feature_highlight_popover_spec.js
+2
-1
spec/frontend/frequent_items/components/app_spec.js
spec/frontend/frequent_items/components/app_spec.js
+4
-4
spec/frontend/frequent_items/components/frequent_items_list_spec.js
...end/frequent_items/components/frequent_items_list_spec.js
+13
-15
spec/frontend/frequent_items/components/frequent_items_search_input_spec.js
...uent_items/components/frequent_items_search_input_spec.js
+2
-2
spec/frontend/grafana_integration/components/grafana_integration_spec.js
...rafana_integration/components/grafana_integration_spec.js
+11
-11
spec/frontend/group_settings/components/shared_runners_form_spec.js
...end/group_settings/components/shared_runners_form_spec.js
+2
-1
spec/frontend/groups/components/invite_members_banner_spec.js
.../frontend/groups/components/invite_members_banner_spec.js
+2
-1
spec/frontend/header_search/components/app_spec.js
spec/frontend/header_search/components/app_spec.js
+7
-7
spec/frontend/header_search/components/header_search_autocomplete_items_spec.js
...earch/components/header_search_autocomplete_items_spec.js
+2
-2
spec/frontend/ide/components/branches/search_list_spec.js
spec/frontend/ide/components/branches/search_list_spec.js
+4
-5
spec/frontend/ide/components/commit_sidebar/form_spec.js
spec/frontend/ide/components/commit_sidebar/form_spec.js
+21
-21
spec/frontend/ide/components/error_message_spec.js
spec/frontend/ide/components/error_message_spec.js
+13
-20
spec/frontend/ide/components/file_templates/dropdown_spec.js
spec/frontend/ide/components/file_templates/dropdown_spec.js
+14
-17
spec/frontend/ide/components/ide_file_row_spec.js
spec/frontend/ide/components/ide_file_row_spec.js
+12
-15
spec/frontend/ide/components/ide_review_spec.js
spec/frontend/ide/components/ide_review_spec.js
+5
-5
spec/frontend/ide/components/ide_side_bar_spec.js
spec/frontend/ide/components/ide_side_bar_spec.js
+7
-7
spec/frontend/ide/components/jobs/stage_spec.js
spec/frontend/ide/components/jobs/stage_spec.js
+7
-8
spec/frontend/ide/components/merge_requests/list_spec.js
spec/frontend/ide/components/merge_requests/list_spec.js
+31
-39
spec/frontend/ide/components/panes/right_spec.js
spec/frontend/ide/components/panes/right_spec.js
+11
-12
spec/frontend/ide/components/preview/clientside_spec.js
spec/frontend/ide/components/preview/clientside_spec.js
+12
-15
spec/frontend/ide/components/preview/navigator_spec.js
spec/frontend/ide/components/preview/navigator_spec.js
+52
-68
spec/frontend/ide/components/repo_tabs_spec.js
spec/frontend/ide/components/repo_tabs_spec.js
+7
-10
spec/frontend/ide/components/resizable_panel_spec.js
spec/frontend/ide/components/resizable_panel_spec.js
+4
-5
spec/frontend/ide/components/terminal/session_spec.js
spec/frontend/ide/components/terminal/session_spec.js
+9
-11
spec/frontend/ide/components/terminal/terminal_controls_spec.js
...rontend/ide/components/terminal/terminal_controls_spec.js
+7
-8
spec/frontend/incidents/components/incidents_list_spec.js
spec/frontend/incidents/components/incidents_list_spec.js
+6
-5
spec/frontend/integrations/edit/components/active_checkbox_spec.js
...tend/integrations/edit/components/active_checkbox_spec.js
+2
-1
spec/frontend/integrations/edit/components/confirmation_modal_spec.js
...d/integrations/edit/components/confirmation_modal_spec.js
+2
-1
spec/frontend/integrations/edit/components/jira_issues_fields_spec.js
...d/integrations/edit/components/jira_issues_fields_spec.js
+2
-1
spec/frontend/integrations/edit/components/jira_trigger_fields_spec.js
.../integrations/edit/components/jira_trigger_fields_spec.js
+9
-10
spec/frontend/invite_members/components/import_a_project_modal_spec.js
.../invite_members/components/import_a_project_modal_spec.js
+3
-2
spec/frontend/invite_members/components/invite_members_modal_spec.js
...nd/invite_members/components/invite_members_modal_spec.js
+4
-3
spec/frontend/issuable/components/related_issuable_item_spec.js
...rontend/issuable/components/related_issuable_item_spec.js
+5
-4
spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js
...uable/related_issues/components/add_issuable_form_spec.js
+20
-27
spec/frontend/issuable/related_issues/components/related_issues_root_spec.js
...ble/related_issues/components/related_issues_root_spec.js
+14
-16
spec/frontend/issues/new/components/title_suggestions_spec.js
.../frontend/issues/new/components/title_suggestions_spec.js
+25
-32
spec/frontend/issues/show/components/app_spec.js
spec/frontend/issues/show/components/app_spec.js
+72
-93
spec/frontend/issues/show/components/fields/type_spec.js
spec/frontend/issues/show/components/fields/type_spec.js
+2
-1
spec/frontend/issues/show/components/form_spec.js
spec/frontend/issues/show/components/form_spec.js
+2
-1
spec/frontend/issues/show/components/header_actions_spec.js
spec/frontend/issues/show/components/header_actions_spec.js
+2
-2
No files found.
spec/frontend/diffs/components/collapsed_files_warning_spec.js
View file @
0d6b1f91
...
...
@@ -19,7 +19,7 @@ async function files(store, count) {
const
copies
=
Array
(
count
).
fill
(
file
);
store
.
state
.
diffs
.
diffFiles
.
push
(...
copies
);
return
nextTick
();
await
nextTick
();
}
describe
(
'
CollapsedFilesWarning
'
,
()
=>
{
...
...
@@ -84,7 +84,7 @@ describe('CollapsedFilesWarning', () => {
getAlertCloseButton
().
element
.
click
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
find
(
'
[data-testid="root"]
'
).
exists
()).
toBe
(
false
);
});
...
...
spec/frontend/diffs/components/compare_versions_spec.js
View file @
0d6b1f91
import
{
mount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
getDiffWithCommit
from
'
test_fixtures/merge_request_diffs/with_commit.json
'
;
import
setWindowLocation
from
'
helpers/set_window_location_helper
'
;
...
...
@@ -232,16 +232,15 @@ describe('CompareVersions', () => {
expect
(
link
.
element
.
getAttribute
(
'
href
'
)).
toEqual
(
PREV_COMMIT_URL
);
});
it
(
'
triggers the correct Vuex action on click
'
,
()
=>
{
it
(
'
triggers the correct Vuex action on click
'
,
async
()
=>
{
const
link
=
getPrevCommitNavElement
();
link
.
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
moveToNeighboringCommit
).
toHaveBeenCalledWith
({
direction
:
'
previous
'
,
});
});
});
it
(
'
renders a disabled button when there is no prev commit
'
,
()
=>
{
createWrapper
({},
{
...
mrCommit
,
prev_commit_id
:
null
});
...
...
@@ -267,14 +266,13 @@ describe('CompareVersions', () => {
expect
(
link
.
element
.
getAttribute
(
'
href
'
)).
toEqual
(
NEXT_COMMIT_URL
);
});
it
(
'
triggers the correct Vuex action on click
'
,
()
=>
{
it
(
'
triggers the correct Vuex action on click
'
,
async
()
=>
{
const
link
=
getNextCommitNavElement
();
link
.
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
moveToNeighboringCommit
).
toHaveBeenCalledWith
({
direction
:
'
next
'
});
});
});
it
(
'
renders a disabled button when there is no next commit
'
,
()
=>
{
createWrapper
({},
{
...
mrCommit
,
next_commit_id
:
null
});
...
...
spec/frontend/diffs/components/diff_file_header_spec.js
View file @
0d6b1f91
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
{
cloneDeep
}
from
'
lodash
'
;
import
Vuex
from
'
vuex
'
;
...
...
@@ -125,31 +125,28 @@ describe('DiffFileHeader component', () => {
expect
(
findCollapseIcon
().
props
(
'
name
'
)).
toBe
(
icon
);
});
it
(
'
when header is clicked emits toggleFile
'
,
()
=>
{
it
(
'
when header is clicked emits toggleFile
'
,
async
()
=>
{
createComponent
();
findHeader
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
().
toggleFile
).
toBeDefined
();
});
});
it
(
'
when collapseIcon is clicked emits toggleFile
'
,
()
=>
{
it
(
'
when collapseIcon is clicked emits toggleFile
'
,
async
()
=>
{
createComponent
({
props
:
{
collapsible
:
true
}
});
findCollapseIcon
().
vm
.
$emit
(
'
click
'
,
new
Event
(
'
click
'
));
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
().
toggleFile
).
toBeDefined
();
});
});
it
(
'
when other element in header is clicked does not emits toggleFile
'
,
()
=>
{
it
(
'
when other element in header is clicked does not emits toggleFile
'
,
async
()
=>
{
createComponent
({
props
:
{
collapsible
:
true
}
});
findTitleLink
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
().
toggleFile
).
not
.
toBeDefined
();
});
});
describe
(
'
copy to clipboard
'
,
()
=>
{
beforeEach
(()
=>
{
...
...
spec/frontend/diffs/components/diff_file_spec.js
View file @
0d6b1f91
...
...
@@ -160,7 +160,7 @@ describe('DiffFile', () => {
last
,
}));
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
eventHub
.
$emit
).
toHaveBeenCalledTimes
(
events
.
length
);
events
.
forEach
((
event
)
=>
{
...
...
@@ -184,13 +184,13 @@ describe('DiffFile', () => {
makeFileAutomaticallyCollapsed
(
store
);
await
wrapper
.
vm
.
$
nextTick
();
// Wait for store updates to flow into the component
await
nextTick
();
// Wait for store updates to flow into the component
toggleFile
(
wrapper
);
await
wrapper
.
vm
.
$
nextTick
();
// Wait for the load to resolve
await
wrapper
.
vm
.
$
nextTick
();
// Wait for the idleCallback
await
wrapper
.
vm
.
$
nextTick
();
// Wait for nextTick inside postRender
await
nextTick
();
// Wait for the load to resolve
await
nextTick
();
// Wait for the idleCallback
await
nextTick
();
// Wait for nextTick inside postRender
expect
(
eventHub
.
$emit
).
toHaveBeenCalledTimes
(
2
);
expect
(
eventHub
.
$emit
).
toHaveBeenCalledWith
(
EVT_PERF_MARK_FIRST_DIFF_FILE_SHOWN
);
...
...
@@ -214,7 +214,7 @@ describe('DiffFile', () => {
markFileToBeRendered
(
store
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
find
(
DiffContentComponent
).
exists
()).
toBe
(
true
);
});
...
...
@@ -264,7 +264,7 @@ describe('DiffFile', () => {
it
(
'
performs the normal file toggle when the file is collapsed
'
,
async
()
=>
{
makeFileAutomaticallyCollapsed
(
store
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
eventHub
.
$emit
(
EVT_EXPAND_ALL_FILES
);
...
...
@@ -274,7 +274,7 @@ describe('DiffFile', () => {
it
(
'
does nothing when the file is not collapsed
'
,
async
()
=>
{
eventHub
.
$emit
(
EVT_EXPAND_ALL_FILES
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
vm
.
handleToggle
).
not
.
toHaveBeenCalled
();
});
...
...
@@ -286,7 +286,7 @@ describe('DiffFile', () => {
});
it
(
'
should not have any content at all
'
,
async
()
=>
{
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findDiffContentArea
(
wrapper
).
element
.
children
.
length
).
toBe
(
0
);
});
...
...
@@ -392,7 +392,7 @@ describe('DiffFile', () => {
readableText
,
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
toggleFile
(
wrapper
);
};
...
...
@@ -440,7 +440,7 @@ describe('DiffFile', () => {
makeFileAutomaticallyCollapsed
(
store
);
wrapper
.
vm
.
requestDiff
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findLoader
(
wrapper
).
exists
()).
toBe
(
true
);
});
...
...
@@ -451,7 +451,7 @@ describe('DiffFile', () => {
({
wrapper
,
store
}
=
createComponent
({
file
:
getUnreadableFile
()
}));
makeFileAutomaticallyCollapsed
(
store
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findDiffContentArea
(
wrapper
).
html
()).
toContain
(
'
Files with large changes are collapsed by default.
'
,
...
...
@@ -470,7 +470,7 @@ describe('DiffFile', () => {
markFileToBeRendered
(
store
);
changeViewerType
(
store
,
mode
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
classes
(
'
has-body
'
)).
toBe
(
true
);
expect
(
wrapper
.
find
(
DiffContentComponent
).
exists
()).
toBe
(
true
);
...
...
@@ -496,7 +496,7 @@ describe('DiffFile', () => {
},
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
const
button
=
wrapper
.
find
(
'
[data-testid="blob-button"]
'
);
...
...
@@ -521,7 +521,7 @@ describe('DiffFile', () => {
({
wrapper
,
store
}
=
createComponent
({
file
,
props
:
{
viewDiffsFileByFile
:
true
}
}));
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findLoader
(
wrapper
).
exists
()).
toBe
(
true
);
});
...
...
spec/frontend/diffs/components/diff_gutter_avatars_spec.js
View file @
0d6b1f91
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
DiffGutterAvatars
from
'
~/diffs/components/diff_gutter_avatars.vue
'
;
import
discussionsMockData
from
'
../mock_data/diff_discussions
'
;
...
...
@@ -35,14 +36,13 @@ describe('DiffGutterAvatars', () => {
expect
(
findCollapseButton
().
exists
()).
toBe
(
true
);
});
it
(
'
should emit toggleDiscussions event on button click
'
,
()
=>
{
it
(
'
should emit toggleDiscussions event on button click
'
,
async
()
=>
{
findCollapseButton
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
().
toggleLineDiscussions
).
toBeTruthy
();
});
});
});
describe
(
'
when collapsed
'
,
()
=>
{
beforeEach
(()
=>
{
...
...
@@ -65,22 +65,20 @@ describe('DiffGutterAvatars', () => {
expect
(
findMoreCount
().
text
()).
toBe
(
'
+2
'
);
});
it
(
'
should emit toggleDiscussions event on avatars click
'
,
()
=>
{
it
(
'
should emit toggleDiscussions event on avatars click
'
,
async
()
=>
{
findUserAvatars
().
at
(
0
).
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
().
toggleLineDiscussions
).
toBeTruthy
();
});
});
it
(
'
should emit toggleDiscussions event on more count text click
'
,
()
=>
{
it
(
'
should emit toggleDiscussions event on more count text click
'
,
async
()
=>
{
findMoreCount
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
().
toggleLineDiscussions
).
toBeTruthy
();
});
});
});
it
(
'
renders an empty more count string if there are no discussions
'
,
()
=>
{
createComponent
({
...
...
spec/frontend/diffs/components/tree_list_spec.js
View file @
0d6b1f91
import
{
shallowMount
,
mount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
TreeList
from
'
~/diffs/components/tree_list.vue
'
;
import
createStore
from
'
~/diffs/store/modules
'
;
...
...
@@ -91,13 +91,12 @@ describe('Diffs tree list component', () => {
expect
(
getFileRows
().
at
(
1
).
html
()).
toContain
(
'
app
'
);
});
it
(
'
hides file stats
'
,
()
=>
{
it
(
'
hides file stats
'
,
async
()
=>
{
wrapper
.
setProps
({
hideFileStats
:
true
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
'
.file-row-stats
'
).
exists
()).
toBe
(
false
);
});
});
it
(
'
calls toggleTreeOpen when clicking folder
'
,
()
=>
{
jest
.
spyOn
(
wrapper
.
vm
.
$store
,
'
dispatch
'
).
mockReturnValue
(
undefined
);
...
...
@@ -117,22 +116,20 @@ describe('Diffs tree list component', () => {
});
});
it
(
'
renders as file list when renderTreeList is false
'
,
()
=>
{
it
(
'
renders as file list when renderTreeList is false
'
,
async
()
=>
{
wrapper
.
vm
.
$store
.
state
.
diffs
.
renderTreeList
=
false
;
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
getFileRows
()).
toHaveLength
(
1
);
});
});
it
(
'
renders file paths when renderTreeList is false
'
,
()
=>
{
it
(
'
renders file paths when renderTreeList is false
'
,
async
()
=>
{
wrapper
.
vm
.
$store
.
state
.
diffs
.
renderTreeList
=
false
;
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
'
.file-row
'
).
html
()).
toContain
(
'
index.js
'
);
});
});
});
describe
(
'
with viewedDiffFileIds
'
,
()
=>
{
const
viewedDiffFileIds
=
{
fileId
:
'
#12345
'
};
...
...
@@ -142,14 +139,13 @@ describe('Diffs tree list component', () => {
store
.
state
.
diffs
.
viewedDiffFileIds
=
viewedDiffFileIds
;
});
it
(
'
passes the viewedDiffFileIds to the FileTree
'
,
()
=>
{
it
(
'
passes the viewedDiffFileIds to the FileTree
'
,
async
()
=>
{
createComponent
(
shallowMount
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
// Have to use $attrs['viewed-files'] because we are passing down an object
// and attributes('') stringifies values (e.g. [object])...
expect
(
wrapper
.
find
(
FileTree
).
vm
.
$attrs
[
'
viewed-files
'
]).
toBe
(
viewedDiffFileIds
);
});
});
});
});
spec/frontend/environments/canary_update_modal_spec.js
View file @
0d6b1f91
import
{
GlAlert
,
GlModal
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
CanaryUpdateModal
from
'
~/environments/components/canary_update_modal.vue
'
;
import
updateCanaryIngress
from
'
~/environments/graphql/mutations/update_canary_ingress.mutation.graphql
'
;
...
...
@@ -86,7 +87,7 @@ describe('/environments/components/canary_update_modal.vue', () => {
mutate
.
mockResolvedValue
({
data
:
{
environmentsCanaryIngressUpdate
:
{
errors
:
[]
}
}
});
modal
.
vm
.
$emit
(
'
primary
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findAlert
().
exists
()).
toBe
(
false
);
});
...
...
@@ -95,7 +96,7 @@ describe('/environments/components/canary_update_modal.vue', () => {
mutate
.
mockResolvedValue
({
data
:
{
environmentsCanaryIngressUpdate
:
{
errors
:
[
'
error
'
]
}
}
});
modal
.
vm
.
$emit
(
'
primary
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findAlert
().
text
()).
toBe
(
'
error
'
);
});
...
...
@@ -105,7 +106,7 @@ describe('/environments/components/canary_update_modal.vue', () => {
modal
.
vm
.
$emit
(
'
primary
'
);
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findAlert
().
text
()).
toBe
(
'
Something went wrong. Please try again later
'
);
});
...
...
@@ -114,12 +115,12 @@ describe('/environments/components/canary_update_modal.vue', () => {
mutate
.
mockResolvedValue
({
data
:
{
environmentsCanaryIngressUpdate
:
{
errors
:
[
'
error
'
]
}
}
});
modal
.
vm
.
$emit
(
'
primary
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
const
alert
=
findAlert
();
alert
.
vm
.
$emit
(
'
dismiss
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
alert
.
exists
()).
toBe
(
false
);
});
...
...
spec/frontend/environments/deploy_board_component_spec.js
View file @
0d6b1f91
import
{
GlTooltip
,
GlIcon
,
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
CanaryIngress
from
'
~/environments/components/canary_ingress.vue
'
;
import
DeployBoard
from
'
~/environments/components/deploy_board.vue
'
;
import
{
deployBoardMockData
,
environment
}
from
'
./mock_data
'
;
...
...
@@ -24,7 +24,7 @@ describe('Deploy Board', () => {
describe
(
'
with valid data
'
,
()
=>
{
beforeEach
((
done
)
=>
{
wrapper
=
createComponent
();
wrapper
.
vm
.
$
nextTick
(
done
);
nextTick
(
done
);
});
it
(
'
should render percentage with completion value provided
'
,
()
=>
{
...
...
@@ -79,7 +79,7 @@ describe('Deploy Board', () => {
isEmpty
:
true
,
logsPath
,
});
wrapper
.
vm
.
$
nextTick
(
done
);
nextTick
(
done
);
});
it
(
'
should render the empty state
'
,
()
=>
{
...
...
@@ -98,7 +98,7 @@ describe('Deploy Board', () => {
isEmpty
:
false
,
logsPath
,
});
wrapper
.
vm
.
$
nextTick
(
done
);
nextTick
(
done
);
});
it
(
'
should render loading spinner
'
,
()
=>
{
...
...
@@ -116,7 +116,7 @@ describe('Deploy Board', () => {
deployBoardData
:
deployBoardMockData
,
});
({
statuses
}
=
wrapper
.
vm
);
wrapper
.
vm
.
$
nextTick
(
done
);
nextTick
(
done
);
});
it
(
'
with all the possible statuses
'
,
()
=>
{
...
...
spec/frontend/environments/environment_actions_spec.js
View file @
0d6b1f91
import
{
GlDropdown
,
GlDropdownItem
,
GlLoadingIcon
,
GlIcon
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
,
mount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
VueApollo
from
'
vue-apollo
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
import
{
createMockDirective
,
getBinding
}
from
'
helpers/vue_mock_directive
'
;
...
...
@@ -108,7 +108,7 @@ describe('EnvironmentActions Component', () => {
jest
.
spyOn
(
window
,
'
confirm
'
).
mockImplementation
(()
=>
confirm
);
findDropdownItem
(
scheduledJobAction
).
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
};
beforeEach
(()
=>
{
...
...
spec/frontend/environments/environment_table_spec.js
View file @
0d6b1f91
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
CanaryUpdateModal
from
'
~/environments/components/canary_update_modal.vue
'
;
import
DeployBoard
from
'
~/environments/components/deploy_board.vue
'
;
import
EnvironmentTable
from
'
~/environments/components/environments_table.vue
'
;
...
...
@@ -181,7 +182,7 @@ describe('Environment table', () => {
});
wrapper
.
find
(
DeployBoard
).
vm
.
$emit
(
'
changeCanaryWeight
'
,
40
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
find
(
CanaryUpdateModal
).
props
()).
toMatchObject
({
weight
:
40
,
...
...
spec/frontend/environments/environments_app_spec.js
View file @
0d6b1f91
import
{
GlTabs
}
from
'
@gitlab/ui
'
;
import
{
mount
,
shallowMount
}
from
'
@vue/test-utils
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
Container
from
'
~/environments/components/container.vue
'
;
import
DeployBoard
from
'
~/environments/components/deploy_board.vue
'
;
...
...
@@ -186,15 +187,14 @@ describe('Environment', () => {
expect
(
wrapper
.
find
(
'
.folder-icon[data-testid="chevron-right-icon"]
'
).
exists
()).
toBe
(
false
);
});
it
(
'
should close an opened folder
'
,
()
=>
{
it
(
'
should close an opened folder
'
,
async
()
=>
{
expect
(
wrapper
.
find
(
'
.folder-icon[data-testid="chevron-down-icon"]
'
).
exists
()).
toBe
(
true
);
// close folder
wrapper
.
find
(
'
.folder-name
'
).
trigger
(
'
click
'
);
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
'
.folder-icon[data-testid="chevron-down-icon"]
'
).
exists
()).
toBe
(
false
);
});
});
it
(
'
should show children environments
'
,
()
=>
{
expect
(
wrapper
.
findAll
(
'
.js-child-row
'
).
length
).
toEqual
(
1
);
...
...
spec/frontend/error_tracking/components/error_details_spec.js
View file @
0d6b1f91
...
...
@@ -8,7 +8,7 @@ import {
GlSprintf
,
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
{
severityLevel
,
...
...
@@ -139,24 +139,23 @@ describe('ErrorDetails', () => {
mountComponent
();
});
it
(
'
when before timeout, still shows loading
'
,
()
=>
{
it
(
'
when before timeout, still shows loading
'
,
async
()
=>
{
Date
.
now
.
mockReturnValue
(
endTime
-
1
);
wrapper
.
vm
.
onNoApolloResult
();
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
true
);
expect
(
createFlash
).
not
.
toHaveBeenCalled
();
expect
(
mocks
.
$apollo
.
queries
.
error
.
stopPolling
).
not
.
toHaveBeenCalled
();
});
});
it
(
'
when timeout is hit and no apollo result, stops loading and shows flash
'
,
()
=>
{
it
(
'
when timeout is hit and no apollo result, stops loading and shows flash
'
,
async
()
=>
{
Date
.
now
.
mockReturnValue
(
endTime
+
1
);
wrapper
.
vm
.
onNoApolloResult
();
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
false
);
expect
(
wrapper
.
find
(
GlLink
).
exists
()).
toBe
(
false
);
expect
(
createFlash
).
toHaveBeenCalledWith
({
...
...
@@ -166,7 +165,6 @@ describe('ErrorDetails', () => {
expect
(
mocks
.
$apollo
.
queries
.
error
.
stopPolling
).
toHaveBeenCalled
();
});
});
});
describe
(
'
Error details
'
,
()
=>
{
beforeEach
(()
=>
{
...
...
@@ -224,7 +222,7 @@ describe('ErrorDetails', () => {
});
describe
(
'
Badges
'
,
()
=>
{
it
(
'
should show language and error level badges
'
,
()
=>
{
it
(
'
should show language and error level badges
'
,
async
()
=>
{
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
({
...
...
@@ -232,12 +230,11 @@ describe('ErrorDetails', () => {
tags
:
{
level
:
'
error
'
,
logger
:
'
ruby
'
},
},
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
findAll
(
GlBadge
).
length
).
toBe
(
2
);
});
});
it
(
'
should NOT show the badge if the tag is not present
'
,
()
=>
{
it
(
'
should NOT show the badge if the tag is not present
'
,
async
()
=>
{
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
({
...
...
@@ -245,14 +242,13 @@ describe('ErrorDetails', () => {
tags
:
{
level
:
'
error
'
},
},
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
findAll
(
GlBadge
).
length
).
toBe
(
1
);
});
});
it
.
each
(
Object
.
keys
(
severityLevel
))(
'
should set correct severity level variant for %s badge
'
,
(
level
)
=>
{
async
(
level
)
=>
{
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
({
...
...
@@ -260,15 +256,14 @@ describe('ErrorDetails', () => {
tags
:
{
level
:
severityLevel
[
level
]
},
},
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
GlBadge
).
props
(
'
variant
'
)).
toEqual
(
severityLevelVariant
[
severityLevel
[
level
]],
);
});
},
);
it
(
'
should fallback for ERROR severityLevelVariant when severityLevel is unknown
'
,
()
=>
{
it
(
'
should fallback for ERROR severityLevelVariant when severityLevel is unknown
'
,
async
()
=>
{
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
({
...
...
@@ -276,34 +271,31 @@ describe('ErrorDetails', () => {
tags
:
{
level
:
'
someNewErrorLevel
'
},
},
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
GlBadge
).
props
(
'
variant
'
)).
toEqual
(
severityLevelVariant
[
severityLevel
.
ERROR
],
);
});
});
});
describe
(
'
Stacktrace
'
,
()
=>
{
it
(
'
should show stacktrace
'
,
()
=>
{
it
(
'
should show stacktrace
'
,
async
()
=>
{
store
.
state
.
details
.
loadingStacktrace
=
false
;
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
false
);
expect
(
wrapper
.
find
(
Stacktrace
).
exists
()).
toBe
(
true
);
expect
(
findAlert
().
exists
()).
toBe
(
false
);
});
});
it
(
'
should NOT show stacktrace if no entries and show Alert message
'
,
()
=>
{
it
(
'
should NOT show stacktrace if no entries and show Alert message
'
,
async
()
=>
{
store
.
state
.
details
.
loadingStacktrace
=
false
;
store
.
getters
=
{
'
details/sentryUrl
'
:
()
=>
'
sentry.io
'
,
'
details/stacktrace
'
:
()
=>
[]
};
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
false
);
expect
(
wrapper
.
find
(
Stacktrace
).
exists
()).
toBe
(
false
);
expect
(
findAlert
().
text
()).
toBe
(
'
No stack trace for this error
'
);
});
});
});
describe
(
'
When a user clicks the create issue button
'
,
()
=>
{
it
(
'
should send sentry_issue_identifier
'
,
()
=>
{
...
...
@@ -338,10 +330,10 @@ describe('ErrorDetails', () => {
});
describe
(
'
when error is unresolved
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
store
.
state
.
details
.
errorStatus
=
errorStatus
.
UNRESOLVED
;
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
displays Ignore and Resolve buttons
'
,
()
=>
{
...
...
@@ -365,10 +357,10 @@ describe('ErrorDetails', () => {
});
describe
(
'
when error is ignored
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
store
.
state
.
details
.
errorStatus
=
errorStatus
.
IGNORED
;
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
displays Undo Ignore and Resolve buttons
'
,
()
=>
{
...
...
@@ -392,10 +384,10 @@ describe('ErrorDetails', () => {
});
describe
(
'
when error is resolved
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
store
.
state
.
details
.
errorStatus
=
errorStatus
.
RESOLVED
;
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
displays Ignore and Unresolve buttons
'
,
()
=>
{
...
...
@@ -417,7 +409,7 @@ describe('ErrorDetails', () => {
);
});
it
(
'
should show alert with closed issueId
'
,
()
=>
{
it
(
'
should show alert with closed issueId
'
,
async
()
=>
{
const
closedIssueId
=
123
;
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
...
...
@@ -426,13 +418,12 @@ describe('ErrorDetails', () => {
closedIssueId
,
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findAlert
().
exists
()).
toBe
(
true
);
expect
(
findAlert
().
text
()).
toContain
(
`#
${
closedIssueId
}
`
);
});
});
});
});
describe
(
'
GitLab issue link
'
,
()
=>
{
const
gitlabIssuePath
=
'
https://gitlab.example.com/issues/1
'
;
...
...
@@ -495,7 +486,7 @@ describe('ErrorDetails', () => {
'
/gitlab-org/gitlab-test/commit/7975be0116940bf2ad4321f79d02a55c5f7779aa
'
;
const
findGitLabCommitLink
=
()
=>
wrapper
.
find
(
`[href$="
${
gitlabCommitPath
}
"]`
);
it
(
'
should display a link
'
,
()
=>
{
it
(
'
should display a link
'
,
async
()
=>
{
mocks
.
$apollo
.
queries
.
error
.
loading
=
false
;
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
...
...
@@ -505,12 +496,11 @@ describe('ErrorDetails', () => {
gitlabCommitPath
,
},
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findGitLabCommitLink
().
exists
()).
toBe
(
true
);
});
});
it
(
'
should not display a link
'
,
()
=>
{
it
(
'
should not display a link
'
,
async
()
=>
{
mocks
.
$apollo
.
queries
.
error
.
loading
=
false
;
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
...
...
@@ -519,11 +509,10 @@ describe('ErrorDetails', () => {
gitlabCommit
:
null
,
},
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findGitLabCommitLink
().
exists
()).
toBe
(
false
);
});
});
});
describe
(
'
Release links
'
,
()
=>
{
const
firstReleaseVersion
=
'
7975be01
'
;
...
...
spec/frontend/error_tracking/components/error_tracking_actions_spec.js
View file @
0d6b1f91
import
{
GlButton
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
ErrorTrackingActions
from
'
~/error_tracking/components/error_tracking_actions.vue
'
;
describe
(
'
Error Tracking Actions
'
,
()
=>
{
...
...
@@ -37,41 +38,38 @@ describe('Error Tracking Actions', () => {
const
findButtons
=
()
=>
wrapper
.
findAll
(
GlButton
);
describe
(
'
when error status is unresolved
'
,
()
=>
{
it
(
'
renders the correct actions buttons to allow ignore and resolve
'
,
()
=>
{
it
(
'
renders the correct actions buttons to allow ignore and resolve
'
,
async
()
=>
{
expect
(
findButtons
().
exists
()).
toBe
(
true
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findButtons
().
at
(
0
).
attributes
(
'
title
'
)).
toBe
(
'
Ignore
'
);
expect
(
findButtons
().
at
(
1
).
attributes
(
'
title
'
)).
toBe
(
'
Resolve
'
);
});
});
});
describe
(
'
when error status is ignored
'
,
()
=>
{
beforeEach
(()
=>
{
mountComponent
({
error
:
{
status
:
'
ignored
'
}
});
});
it
(
'
renders the correct action button to undo ignore
'
,
()
=>
{
it
(
'
renders the correct action button to undo ignore
'
,
async
()
=>
{
expect
(
findButtons
().
exists
()).
toBe
(
true
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findButtons
().
at
(
0
).
attributes
(
'
title
'
)).
toBe
(
'
Undo Ignore
'
);
});
});
});
describe
(
'
when error status is resolved
'
,
()
=>
{
beforeEach
(()
=>
{
mountComponent
({
error
:
{
status
:
'
resolved
'
}
});
});
it
(
'
renders the correct action button to undo unresolve
'
,
()
=>
{
it
(
'
renders the correct action button to undo unresolve
'
,
async
()
=>
{
expect
(
findButtons
().
exists
()).
toBe
(
true
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findButtons
().
at
(
1
).
attributes
(
'
title
'
)).
toBe
(
'
Unresolve
'
);
});
});
});
});
spec/frontend/error_tracking/components/error_tracking_list_spec.js
View file @
0d6b1f91
import
{
GlEmptyState
,
GlLoadingIcon
,
GlFormInput
,
GlPagination
,
GlDropdown
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
stubChildren
from
'
helpers/stub_children
'
;
import
ErrorTrackingActions
from
'
~/error_tracking/components/error_tracking_actions.vue
'
;
...
...
@@ -316,16 +316,15 @@ describe('ErrorTrackingList', () => {
expect
(
findRecentSearchesDropdown
().
text
()).
toContain
(
"
You don't have any recent searches
"
);
});
it
(
'
shows items
'
,
()
=>
{
it
(
'
shows items
'
,
async
()
=>
{
store
.
state
.
list
.
recentSearches
=
[
'
great
'
,
'
search
'
];
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
const
dropdownItems
=
wrapper
.
findAll
(
'
.filtered-search-box li
'
);
expect
(
dropdownItems
.
length
).
toBe
(
3
);
expect
(
dropdownItems
.
at
(
0
).
text
()).
toBe
(
'
great
'
);
expect
(
dropdownItems
.
at
(
1
).
text
()).
toBe
(
'
search
'
);
});
});
describe
(
'
clear
'
,
()
=>
{
const
clearRecentButton
=
()
=>
wrapper
.
find
({
ref
:
'
clearRecentSearches
'
});
...
...
@@ -336,26 +335,24 @@ describe('ErrorTrackingList', () => {
expect
(
clearRecentButton
().
exists
()).
toBe
(
false
);
});
it
(
'
is visible when list has items
'
,
()
=>
{
it
(
'
is visible when list has items
'
,
async
()
=>
{
store
.
state
.
list
.
recentSearches
=
[
'
some
'
,
'
searches
'
];
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
clearRecentButton
().
exists
()).
toBe
(
true
);
expect
(
clearRecentButton
().
text
()).
toBe
(
'
Clear recent searches
'
);
});
});
it
(
'
clears items on click
'
,
()
=>
{
it
(
'
clears items on click
'
,
async
()
=>
{
store
.
state
.
list
.
recentSearches
=
[
'
some
'
,
'
searches
'
];
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
clearRecentButton
().
vm
.
$emit
(
'
click
'
);
expect
(
actions
.
clearRecentSearches
).
toHaveBeenCalledTimes
(
1
);
});
});
});
});
describe
(
'
When pagination is not required
'
,
()
=>
{
beforeEach
(()
=>
{
...
...
@@ -387,7 +384,7 @@ describe('ErrorTrackingList', () => {
describe
(
'
and the user is not on the first page
'
,
()
=>
{
describe
(
'
and the previous button is clicked
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
store
.
state
.
list
.
loading
=
false
;
mountComponent
({
stubs
:
{
...
...
@@ -398,7 +395,7 @@ describe('ErrorTrackingList', () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
({
pageValue
:
2
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
fetches the previous page of results
'
,
()
=>
{
...
...
spec/frontend/error_tracking_settings/components/app_spec.js
View file @
0d6b1f91
...
...
@@ -79,14 +79,13 @@ describe('error tracking settings app', () => {
expect
(
wrapper
.
find
(
'
.js-error-tracking-button
'
).
attributes
(
'
disabled
'
)).
toBeFalsy
();
});
it
(
'
disables the button when saving
'
,
()
=>
{
it
(
'
disables the button when saving
'
,
async
()
=>
{
store
.
state
.
settingsLoading
=
true
;
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
'
.js-error-tracking-button
'
).
attributes
(
'
disabled
'
)).
toBeTruthy
();
});
});
});
describe
(
'
tracking-backend settings
'
,
()
=>
{
it
(
'
contains a form-group with the correct label
'
,
()
=>
{
...
...
spec/frontend/error_tracking_settings/components/project_dropdown_spec.js
View file @
0d6b1f91
import
{
GlDropdown
,
GlDropdownItem
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
{
pick
,
clone
}
from
'
lodash
'
;
import
Vuex
from
'
vuex
'
;
import
ProjectDropdown
from
'
~/error_tracking_settings/components/project_dropdown.vue
'
;
...
...
@@ -63,10 +63,10 @@ describe('error tracking settings project dropdown', () => {
});
describe
(
'
populated project list
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
wrapper
.
setProps
({
projects
:
clone
(
projectList
),
hasProjects
:
true
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
renders the dropdown
'
,
()
=>
{
...
...
@@ -83,9 +83,9 @@ describe('error tracking settings project dropdown', () => {
describe
(
'
selected project
'
,
()
=>
{
const
selectedProject
=
clone
(
projectList
[
0
]);
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
wrapper
.
setProps
({
projects
:
clone
(
projectList
),
selectedProject
,
hasProjects
:
true
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
does not show helper text
'
,
()
=>
{
...
...
@@ -95,13 +95,13 @@ describe('error tracking settings project dropdown', () => {
});
describe
(
'
invalid project selected
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
wrapper
.
setProps
({
projects
:
clone
(
projectList
),
selectedProject
:
staleProject
,
isProjectInvalid
:
true
,
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
displays a error
'
,
()
=>
{
...
...
spec/frontend/feature_flags/components/configure_feature_flags_modal_spec.js
View file @
0d6b1f91
import
{
GlModal
,
GlSprintf
,
GlAlert
}
from
'
@gitlab/ui
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
Component
from
'
~/feature_flags/components/configure_feature_flags_modal.vue
'
;
...
...
@@ -56,7 +57,7 @@ describe('Configure Feature Flags Modal', () => {
it
(
'
should emit a `token` event when clicking on the Primary action
'
,
async
()
=>
{
findGlModal
().
vm
.
$emit
(
'
secondary
'
,
mockEvent
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
emitted
(
'
token
'
)).
toEqual
([[]]);
expect
(
mockEvent
.
preventDefault
).
toHaveBeenCalled
();
});
...
...
@@ -64,7 +65,7 @@ describe('Configure Feature Flags Modal', () => {
it
(
'
should clear the project name input after generating the token
'
,
async
()
=>
{
findProjectNameInput
().
vm
.
$emit
(
'
input
'
,
provide
.
projectName
);
findGlModal
().
vm
.
$emit
(
'
primary
'
,
mockEvent
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findProjectNameInput
().
attributes
(
'
value
'
)).
toBe
(
''
);
});
...
...
@@ -116,7 +117,7 @@ describe('Configure Feature Flags Modal', () => {
it
(
'
should enable the secondary action
'
,
async
()
=>
{
findProjectNameInput
().
vm
.
$emit
(
'
input
'
,
provide
.
projectName
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
const
[{
disabled
}]
=
findSecondaryAction
().
attributes
;
expect
(
disabled
).
toBe
(
false
);
});
...
...
spec/frontend/feature_flags/components/edit_feature_flag_spec.js
View file @
0d6b1f91
import
{
GlToggle
,
GlAlert
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
{
mockTracking
}
from
'
helpers/tracking_helper
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
...
...
@@ -12,6 +12,7 @@ import createStore from '~/feature_flags/store/edit';
import
axios
from
'
~/lib/utils/axios_utils
'
;
Vue
.
use
(
Vuex
);
describe
(
'
Edit feature flag form
'
,
()
=>
{
let
wrapper
;
let
mock
;
...
...
@@ -66,15 +67,14 @@ describe('Edit feature flag form', () => {
});
describe
(
'
with error
'
,
()
=>
{
it
(
'
should render the error
'
,
()
=>
{
it
(
'
should render the error
'
,
async
()
=>
{
store
.
dispatch
(
'
receiveUpdateFeatureFlagError
'
,
{
message
:
[
'
The name is required
'
]
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
const
warningGlAlert
=
findWarningGlAlert
();
expect
(
warningGlAlert
.
exists
()).
toEqual
(
true
);
expect
(
warningGlAlert
.
text
()).
toContain
(
'
The name is required
'
);
});
});
});
describe
(
'
without error
'
,
()
=>
{
it
(
'
renders form title
'
,
()
=>
{
...
...
spec/frontend/feature_flags/components/empty_state_spec.js
View file @
0d6b1f91
import
{
GlAlert
,
GlEmptyState
,
GlLink
,
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
EmptyState
from
'
~/feature_flags/components/empty_state.vue
'
;
const
DEFAULT_PROPS
=
{
...
...
@@ -123,7 +124,7 @@ describe('feature_flags/components/feature_flags_tab.vue', () => {
beforeEach
(
async
()
=>
{
wrapper
=
factory
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
slot
=
wrapper
.
find
(
'
[data-testid="test-slot"]
'
);
});
...
...
spec/frontend/feature_flags/components/environments_dropdown_spec.js
View file @
0d6b1f91
import
{
GlLoadingIcon
,
GlButton
,
GlSearchBoxByType
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
{
nextTick
}
from
'
vue
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
{
TEST_HOST
}
from
'
spec/test_constants
'
;
import
EnvironmentsDropdown
from
'
~/feature_flags/components/environments_dropdown.vue
'
;
...
...
@@ -54,7 +55,7 @@ describe('Feature flags > Environments dropdown ', () => {
factory
();
findEnvironmentSearchInput
().
vm
.
$emit
(
'
focus
'
);
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
find
(
'
.dropdown-content > ul
'
).
exists
()).
toBe
(
true
);
expect
(
wrapper
.
findAll
(
'
.dropdown-content > ul > li
'
).
exists
()).
toBe
(
true
);
});
...
...
@@ -66,7 +67,7 @@ describe('Feature flags > Environments dropdown ', () => {
factory
();
findEnvironmentSearchInput
().
vm
.
$emit
(
'
keyup
'
);
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
find
(
'
.dropdown-content > ul
'
).
exists
()).
toBe
(
true
);
expect
(
wrapper
.
findAll
(
'
.dropdown-content > ul > li
'
).
exists
()).
toBe
(
true
);
});
...
...
@@ -80,7 +81,7 @@ describe('Feature flags > Environments dropdown ', () => {
findEnvironmentSearchInput
().
vm
.
$emit
(
'
focus
'
);
findEnvironmentSearchInput
().
vm
.
$emit
(
'
input
'
,
'
production
'
);
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
sets filter value
'
,
()
=>
{
...
...
@@ -103,7 +104,7 @@ describe('Feature flags > Environments dropdown ', () => {
.
filter
((
b
)
=>
b
.
text
()
===
'
production
'
)
.
at
(
0
);
button
.
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
emitted
(
'
selectEnvironment
'
)).
toEqual
([[
'
production
'
]]);
});
});
...
...
@@ -111,7 +112,7 @@ describe('Feature flags > Environments dropdown ', () => {
describe
(
'
on click clear button
'
,
()
=>
{
beforeEach
(
async
()
=>
{
wrapper
.
find
(
GlButton
).
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
resets filter value
'
,
()
=>
{
...
...
@@ -132,12 +133,12 @@ describe('Feature flags > Environments dropdown ', () => {
findEnvironmentSearchInput
().
vm
.
$emit
(
'
focus
'
);
findEnvironmentSearchInput
().
vm
.
$emit
(
'
input
'
,
'
production
'
);
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
emits create event
'
,
async
()
=>
{
wrapper
.
findAll
(
GlButton
).
at
(
0
).
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
emitted
(
'
createClicked
'
)).
toEqual
([[
'
production
'
]]);
});
});
...
...
spec/frontend/feature_flags/components/feature_flags_spec.js
View file @
0d6b1f91
import
{
GlAlert
,
GlEmptyState
,
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
Vuex
from
'
vuex
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
...
...
@@ -172,7 +172,7 @@ describe('Feature flags', () => {
factory
();
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
emptyState
=
wrapper
.
findComponent
(
GlEmptyState
);
});
...
...
spec/frontend/feature_flags/components/feature_flags_table_spec.js
View file @
0d6b1f91
import
{
GlToggle
,
GlBadge
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
trimText
}
from
'
helpers/text_helper
'
;
import
{
mockTracking
}
from
'
helpers/tracking_helper
'
;
import
FeatureFlagsTable
from
'
~/feature_flags/components/feature_flags_table.vue
'
;
...
...
@@ -148,14 +149,13 @@ describe('Feature flag table', () => {
});
});
it
(
'
should trigger a toggle event
'
,
()
=>
{
it
(
'
should trigger a toggle event
'
,
async
()
=>
{
toggle
.
vm
.
$emit
(
'
change
'
);
const
flag
=
{
...
props
.
featureFlags
[
0
],
active
:
!
props
.
featureFlags
[
0
].
active
};
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
(
'
toggle-flag
'
)).
toEqual
([[
flag
]]);
});
});
it
(
'
tracks a click
'
,
()
=>
{
toggle
.
trigger
(
'
click
'
);
...
...
spec/frontend/feature_flags/components/form_spec.js
View file @
0d6b1f91
import
{
GlButton
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
Api
from
'
~/api
'
;
import
Form
from
'
~/feature_flags/components/form.vue
'
;
...
...
@@ -126,28 +127,26 @@ describe('feature flag form', () => {
expect
(
wrapper
.
findAll
(
Strategy
)).
toHaveLength
(
2
);
});
it
(
'
adds an all users strategy when clicking the Add button
'
,
()
=>
{
it
(
'
adds an all users strategy when clicking the Add button
'
,
async
()
=>
{
wrapper
.
find
(
GlButton
).
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
const
strategies
=
wrapper
.
findAll
(
Strategy
);
expect
(
strategies
).
toHaveLength
(
3
);
expect
(
strategies
.
at
(
2
).
props
(
'
strategy
'
)).
toEqual
(
allUsersStrategy
);
});
});
it
(
'
should remove a strategy on delete
'
,
()
=>
{
it
(
'
should remove a strategy on delete
'
,
async
()
=>
{
const
strategy
=
{
type
:
ROLLOUT_STRATEGY_PERCENT_ROLLOUT
,
parameters
:
{
percentage
:
'
30
'
},
scopes
:
[],
};
wrapper
.
find
(
Strategy
).
vm
.
$emit
(
'
delete
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
findAll
(
Strategy
)).
toHaveLength
(
1
);
expect
(
wrapper
.
find
(
Strategy
).
props
(
'
strategy
'
)).
not
.
toEqual
(
strategy
);
});
});
});
});
spec/frontend/feature_flags/components/new_environments_dropdown_spec.js
View file @
0d6b1f91
import
{
GlLoadingIcon
,
GlSearchBoxByType
,
GlDropdownItem
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
{
nextTick
}
from
'
vue
'
;
import
NewEnvironmentsDropdown
from
'
~/feature_flags/components/new_environments_dropdown.vue
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
httpStatusCodes
from
'
~/lib/utils/http_status
'
;
...
...
@@ -47,17 +48,14 @@ describe('New Environments Dropdown', () => {
describe
(
'
with empty results
'
,
()
=>
{
let
item
;
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
axiosMock
.
onGet
(
TEST_HOST
).
reply
(
200
,
[]);
wrapper
.
find
(
GlSearchBoxByType
).
vm
.
$emit
(
'
focus
'
);
wrapper
.
find
(
GlSearchBoxByType
).
vm
.
$emit
(
'
input
'
,
TEST_SEARCH
);
return
axios
.
waitForAll
()
.
then
(()
=>
wrapper
.
vm
.
$nextTick
())
.
then
(()
=>
{
await
axios
.
waitForAll
();
await
nextTick
();
item
=
wrapper
.
find
(
GlDropdownItem
);
});
});
it
(
'
should display a Create item label
'
,
()
=>
{
expect
(
item
.
text
()).
toBe
(
'
Create production
'
);
...
...
spec/frontend/feature_flags/components/new_feature_flag_spec.js
View file @
0d6b1f91
import
{
GlAlert
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
{
TEST_HOST
}
from
'
spec/test_constants
'
;
import
Form
from
'
~/feature_flags/components/form.vue
'
;
...
...
@@ -51,15 +51,14 @@ describe('New feature flag form', () => {
});
describe
(
'
with error
'
,
()
=>
{
it
(
'
should render the error
'
,
()
=>
{
it
(
'
should render the error
'
,
async
()
=>
{
store
.
dispatch
(
'
receiveCreateFeatureFlagError
'
,
{
message
:
[
'
The name is required
'
]
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
const
warningGlAlert
=
findWarningGlAlert
();
expect
(
warningGlAlert
.
at
(
0
).
exists
()).
toBe
(
true
);
expect
(
warningGlAlert
.
at
(
0
).
text
()).
toContain
(
'
The name is required
'
);
});
});
});
it
(
'
renders form title
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
h3
'
).
text
()).
toEqual
(
'
New feature flag
'
);
...
...
spec/frontend/feature_flags/components/strategies/flexible_rollout_spec.js
View file @
0d6b1f91
import
{
GlFormInput
,
GlFormSelect
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
FlexibleRollout
from
'
~/feature_flags/components/strategies/flexible_rollout.vue
'
;
import
ParameterFormGroup
from
'
~/feature_flags/components/strategies/parameter_form_group.vue
'
;
import
{
PERCENT_ROLLOUT_GROUP_ID
}
from
'
~/feature_flags/constants
'
;
...
...
@@ -51,7 +52,7 @@ describe('feature_flags/components/strategies/flexible_rollout.vue', () => {
it
(
'
emits a change when the percentage value changes
'
,
async
()
=>
{
percentageInput
.
setValue
(
'
75
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
emitted
(
'
change
'
)).
toEqual
([
[
{
...
...
spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js
View file @
0d6b1f91
import
{
GlDropdown
,
GlDropdownItem
,
GlSearchBoxByType
,
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
Api
from
'
~/api
'
;
import
GitlabUserList
from
'
~/feature_flags/components/strategies/gitlab_user_list.vue
'
;
...
...
@@ -71,7 +71,7 @@ describe('~/feature_flags/components/strategies/gitlab_user_list.vue', () => {
);
const
searchWrapper
=
wrapper
.
find
(
GlSearchBoxByType
);
searchWrapper
.
vm
.
$emit
(
'
input
'
,
'
new
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
const
loadingIcon
=
wrapper
.
find
(
GlLoadingIcon
);
expect
(
loadingIcon
.
exists
()).
toBe
(
true
);
...
...
@@ -79,7 +79,7 @@ describe('~/feature_flags/components/strategies/gitlab_user_list.vue', () => {
r
({
data
:
[
userList
]
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
loadingIcon
.
exists
()).
toBe
(
false
);
});
...
...
spec/frontend/feature_flags/components/strategies/percent_rollout_spec.js
View file @
0d6b1f91
import
{
GlFormInput
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
ParameterFormGroup
from
'
~/feature_flags/components/strategies/parameter_form_group.vue
'
;
import
PercentRollout
from
'
~/feature_flags/components/strategies/percent_rollout.vue
'
;
import
{
PERCENT_ROLLOUT_GROUP_ID
}
from
'
~/feature_flags/constants
'
;
...
...
@@ -39,7 +40,7 @@ describe('~/feature_flags/components/strategies/percent_rollout.vue', () => {
it
(
'
emits a change when the value changes
'
,
async
()
=>
{
input
.
setValue
(
'
75
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
emitted
(
'
change
'
)).
toEqual
([
[{
parameters
:
{
percentage
:
'
75
'
,
groupId
:
PERCENT_ROLLOUT_GROUP_ID
}
}],
]);
...
...
spec/frontend/feature_flags/components/strategy_spec.js
View file @
0d6b1f91
import
{
GlAlert
,
GlFormSelect
,
GlLink
,
GlToken
,
GlButton
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
{
last
}
from
'
lodash
'
;
import
Vuex
from
'
vuex
'
;
import
Api
from
'
~/api
'
;
...
...
@@ -85,11 +85,11 @@ describe('Feature flags strategy', () => {
let
propsData
;
let
strategy
;
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
strategy
=
{
name
,
parameters
:
{},
scopes
:
[]
};
propsData
=
{
strategy
,
index
:
0
};
factory
({
propsData
,
provide
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
should set the select to match the strategy name
'
,
()
=>
{
...
...
@@ -138,10 +138,10 @@ describe('Feature flags strategy', () => {
factory
({
propsData
,
provide
});
});
it
(
'
should revert to all-environments scope when last scope is removed
'
,
()
=>
{
it
(
'
should revert to all-environments scope when last scope is removed
'
,
async
()
=>
{
const
token
=
wrapper
.
find
(
GlToken
);
token
.
vm
.
$emit
(
'
close
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
findAll
(
GlToken
)).
toHaveLength
(
0
);
expect
(
last
(
wrapper
.
emitted
(
'
change
'
))).
toEqual
([
{
...
...
@@ -152,7 +152,6 @@ describe('Feature flags strategy', () => {
]);
});
});
});
describe
(
'
with an all-environments scope defined
'
,
()
=>
{
let
strategy
;
...
...
@@ -167,10 +166,10 @@ describe('Feature flags strategy', () => {
factory
({
propsData
,
provide
});
});
it
(
'
should change the parameters if a different strategy is chosen
'
,
()
=>
{
it
(
'
should change the parameters if a different strategy is chosen
'
,
async
()
=>
{
const
select
=
wrapper
.
find
(
GlFormSelect
);
select
.
setValue
(
ROLLOUT_STRATEGY_ALL_USERS
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
last
(
wrapper
.
emitted
(
'
change
'
))).
toEqual
([
{
name
:
ROLLOUT_STRATEGY_ALL_USERS
,
...
...
@@ -179,33 +178,30 @@ describe('Feature flags strategy', () => {
},
]);
});
});
it
(
'
should display selected scopes
'
,
()
=>
{
it
(
'
should display selected scopes
'
,
async
()
=>
{
const
dropdown
=
wrapper
.
find
(
NewEnvironmentsDropdown
);
dropdown
.
vm
.
$emit
(
'
add
'
,
'
production
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
findAll
(
GlToken
)).
toHaveLength
(
1
);
expect
(
wrapper
.
find
(
GlToken
).
text
()).
toBe
(
'
production
'
);
});
});
it
(
'
should display all selected scopes
'
,
()
=>
{
it
(
'
should display all selected scopes
'
,
async
()
=>
{
const
dropdown
=
wrapper
.
find
(
NewEnvironmentsDropdown
);
dropdown
.
vm
.
$emit
(
'
add
'
,
'
production
'
);
dropdown
.
vm
.
$emit
(
'
add
'
,
'
staging
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
const
tokens
=
wrapper
.
findAll
(
GlToken
);
expect
(
tokens
).
toHaveLength
(
2
);
expect
(
tokens
.
at
(
0
).
text
()).
toBe
(
'
production
'
);
expect
(
tokens
.
at
(
1
).
text
()).
toBe
(
'
staging
'
);
});
});
it
(
'
should emit selected scopes
'
,
()
=>
{
it
(
'
should emit selected scopes
'
,
async
()
=>
{
const
dropdown
=
wrapper
.
find
(
NewEnvironmentsDropdown
);
dropdown
.
vm
.
$emit
(
'
add
'
,
'
production
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
last
(
wrapper
.
emitted
(
'
change
'
))).
toEqual
([
{
name
:
ROLLOUT_STRATEGY_PERCENT_ROLLOUT
,
...
...
@@ -217,7 +213,6 @@ describe('Feature flags strategy', () => {
},
]);
});
});
it
(
'
should emit a delete if the delete button is clicked
'
,
()
=>
{
wrapper
.
find
(
GlButton
).
vm
.
$emit
(
'
click
'
);
...
...
@@ -236,31 +231,29 @@ describe('Feature flags strategy', () => {
factory
({
propsData
,
provide
});
});
it
(
'
should display selected scopes
'
,
()
=>
{
it
(
'
should display selected scopes
'
,
async
()
=>
{
const
dropdown
=
wrapper
.
find
(
NewEnvironmentsDropdown
);
dropdown
.
vm
.
$emit
(
'
add
'
,
'
production
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
findAll
(
GlToken
)).
toHaveLength
(
1
);
expect
(
wrapper
.
find
(
GlToken
).
text
()).
toBe
(
'
production
'
);
});
});
it
(
'
should display all selected scopes
'
,
()
=>
{
it
(
'
should display all selected scopes
'
,
async
()
=>
{
const
dropdown
=
wrapper
.
find
(
NewEnvironmentsDropdown
);
dropdown
.
vm
.
$emit
(
'
add
'
,
'
production
'
);
dropdown
.
vm
.
$emit
(
'
add
'
,
'
staging
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
const
tokens
=
wrapper
.
findAll
(
GlToken
);
expect
(
tokens
).
toHaveLength
(
2
);
expect
(
tokens
.
at
(
0
).
text
()).
toBe
(
'
production
'
);
expect
(
tokens
.
at
(
1
).
text
()).
toBe
(
'
staging
'
);
});
});
it
(
'
should emit selected scopes
'
,
()
=>
{
it
(
'
should emit selected scopes
'
,
async
()
=>
{
const
dropdown
=
wrapper
.
find
(
NewEnvironmentsDropdown
);
dropdown
.
vm
.
$emit
(
'
add
'
,
'
production
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
last
(
wrapper
.
emitted
(
'
change
'
))).
toEqual
([
{
name
:
ROLLOUT_STRATEGY_PERCENT_ROLLOUT
,
...
...
@@ -271,5 +264,4 @@ describe('Feature flags strategy', () => {
});
});
});
});
});
spec/frontend/feature_highlight/feature_highlight_popover_spec.js
View file @
0d6b1f91
import
{
GlPopover
,
GlLink
,
GlButton
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
POPOVER_TARGET_ID
}
from
'
~/feature_highlight/constants
'
;
import
{
dismiss
}
from
'
~/feature_highlight/feature_highlight_helper
'
;
import
FeatureHighlightPopover
from
'
~/feature_highlight/feature_highlight_popover.vue
'
;
...
...
@@ -71,7 +72,7 @@ describe('feature_highlight/feature_highlight_popover', () => {
it
(
'
hides the popover target
'
,
async
()
=>
{
await
findDismissButton
().
trigger
(
'
click
'
);
findPopover
().
vm
.
$emit
(
'
hidden
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findPopoverTarget
().
exists
()).
toBe
(
false
);
});
...
...
spec/frontend/frequent_items/components/app_spec.js
View file @
0d6b1f91
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
{
useLocalStorageSpy
}
from
'
helpers/local_storage_helper
'
;
import
{
mountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
...
...
@@ -97,7 +97,7 @@ describe('Frequent Items App Component', () => {
triggerDropdownOpen
();
store
.
state
[
TEST_VUEX_MODULE
].
isLoadingItems
=
true
;
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
const
loading
=
findLoading
();
...
...
@@ -119,7 +119,7 @@ describe('Frequent Items App Component', () => {
expect
(
findFrequentItems
().
length
).
toBe
(
1
);
triggerDropdownOpen
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findFrequentItems
().
length
).
toBe
(
expectedResult
.
length
);
expect
(
findFrequentItemsList
().
props
()).
toEqual
({
...
...
@@ -135,7 +135,7 @@ describe('Frequent Items App Component', () => {
mock
.
onGet
(
/
\/
api
\/
v4
\/
projects.json
(
.*
)
$/
).
replyOnce
(
200
,
mockSearchedProjects
.
data
);
setSearch
(
'
gitlab
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findLoading
().
exists
()).
toBe
(
true
);
...
...
spec/frontend/frequent_items/components/frequent_items_list_spec.js
View file @
0d6b1f91
import
{
mount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
frequentItemsListComponent
from
'
~/frequent_items/components/frequent_items_list.vue
'
;
import
frequentItemsListItemComponent
from
'
~/frequent_items/components/frequent_items_list_item.vue
'
;
...
...
@@ -44,7 +44,7 @@ describe('FrequentItemsListComponent', () => {
wrapper
.
setProps
({
items
:
mockFrequentProjects
,
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
vm
.
isListEmpty
).
toBe
(
false
);
});
...
...
@@ -63,7 +63,7 @@ describe('FrequentItemsListComponent', () => {
wrapper
.
setProps
({
isFetchFailed
:
false
,
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
vm
.
listEmptyMessage
).
toBe
(
'
Projects you visit often will appear here
'
);
});
...
...
@@ -81,7 +81,7 @@ describe('FrequentItemsListComponent', () => {
wrapper
.
setProps
({
isFetchFailed
:
false
,
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
vm
.
listEmptyMessage
).
toBe
(
'
Sorry, no projects matched your search
'
);
});
...
...
@@ -89,25 +89,23 @@ describe('FrequentItemsListComponent', () => {
});
describe
(
'
template
'
,
()
=>
{
it
(
'
should render component element with list of projects
'
,
()
=>
{
it
(
'
should render component element with list of projects
'
,
async
()
=>
{
createComponent
();
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
classes
(
'
frequent-items-list-container
'
)).
toBe
(
true
);
expect
(
wrapper
.
findAll
({
ref
:
'
frequentItemsList
'
})).
toHaveLength
(
1
);
expect
(
wrapper
.
findAll
(
frequentItemsListItemComponent
)).
toHaveLength
(
5
);
});
});
it
(
'
should render component element with empty message
'
,
()
=>
{
it
(
'
should render component element with empty message
'
,
async
()
=>
{
createComponent
({
items
:
[],
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
$el
.
querySelectorAll
(
'
li.section-empty
'
)).
toHaveLength
(
1
);
expect
(
wrapper
.
findAll
(
frequentItemsListItemComponent
)).
toHaveLength
(
0
);
});
});
});
});
spec/frontend/frequent_items/components/frequent_items_search_input_spec.js
View file @
0d6b1f91
import
{
GlSearchBoxByType
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
{
mockTracking
,
unmockTracking
}
from
'
helpers/tracking_helper
'
;
import
searchComponent
from
'
~/frequent_items/components/frequent_items_search_input.vue
'
;
...
...
@@ -61,7 +61,7 @@ describe('FrequentItemsSearchInputComponent', () => {
findSearchBoxByType
().
vm
.
$emit
(
'
input
'
,
value
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
trackingSpy
).
toHaveBeenCalledWith
(
undefined
,
'
type_search_query
'
,
{
label
:
'
projects_dropdown_frequent_items_search_input
'
,
...
...
spec/frontend/grafana_integration/components/grafana_integration_spec.js
View file @
0d6b1f91
import
{
GlButton
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
import
{
mountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
createFlash
from
'
~/flash
'
;
...
...
@@ -93,29 +94,28 @@ describe('grafana integration component', () => {
},
];
it
(
'
submits form on click
'
,
()
=>
{
it
(
'
submits form on click
'
,
async
()
=>
{
axios
.
patch
.
mockResolvedValue
();
findSubmitButton
(
wrapper
).
trigger
(
'
click
'
);
expect
(
axios
.
patch
).
toHaveBeenCalledWith
(...
endpointRequest
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
expect
(
refreshCurrentPage
).
toHaveBeenCalled
());
await
nextTick
();
expect
(
refreshCurrentPage
).
toHaveBeenCalled
();
});
it
(
'
creates flash banner on error
'
,
()
=>
{
it
(
'
creates flash banner on error
'
,
async
()
=>
{
const
message
=
'
mockErrorMessage
'
;
axios
.
patch
.
mockRejectedValue
({
response
:
{
data
:
{
message
}
}
});
findSubmitButton
().
trigger
(
'
click
'
);
expect
(
axios
.
patch
).
toHaveBeenCalledWith
(...
endpointRequest
);
return
wrapper
.
vm
.
$nextTick
()
.
then
(
jest
.
runAllTicks
)
.
then
(()
=>
await
nextTick
();
await
jest
.
runAllTicks
();
expect
(
createFlash
).
toHaveBeenCalledWith
({
message
:
`There was an error saving your changes.
${
message
}
`
,
}),
);
});
});
});
});
...
...
spec/frontend/group_settings/components/shared_runners_form_spec.js
View file @
0d6b1f91
import
{
GlLoadingIcon
,
GlAlert
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
MockAxiosAdapter
from
'
axios-mock-adapter
'
;
import
{
nextTick
}
from
'
vue
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
SharedRunnersForm
from
'
~/group_settings/components/shared_runners_form.vue
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
...
...
@@ -76,7 +77,7 @@ describe('group_settings/components/shared_runners_form', () => {
findEnabledToggle
().
vm
.
$emit
(
'
change
'
,
true
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
isLoadingIconVisible
()).
toBe
(
true
);
...
...
spec/frontend/groups/components/invite_members_banner_spec.js
View file @
0d6b1f91
import
{
GlBanner
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
mockTracking
,
unmockTracking
}
from
'
helpers/tracking_helper
'
;
import
InviteMembersBanner
from
'
~/groups/components/invite_members_banner.vue
'
;
import
eventHub
from
'
~/invite_members/event_hub
'
;
...
...
@@ -140,7 +141,7 @@ describe('InviteMembersBanner', () => {
expect
(
wrapper
.
find
(
GlBanner
).
exists
()).
toBe
(
true
);
wrapper
.
find
(
GlBanner
).
vm
.
$emit
(
'
close
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
find
(
GlBanner
).
exists
()).
toBe
(
false
);
});
});
...
...
spec/frontend/header_search/components/app_spec.js
View file @
0d6b1f91
import
{
GlSearchBoxByType
}
from
'
@gitlab/ui
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
{
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
HeaderSearchApp
from
'
~/header_search/components/app.vue
'
;
...
...
@@ -202,7 +202,7 @@ describe('HeaderSearchApp', () => {
expect
(
findHeaderSearchDropdown
().
exists
()).
toBe
(
false
);
findHeaderSearchInput
().
vm
.
$emit
(
'
focus
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findHeaderSearchDropdown
().
exists
()).
toBe
(
true
);
});
...
...
@@ -211,7 +211,7 @@ describe('HeaderSearchApp', () => {
expect
(
findHeaderSearchDropdown
().
exists
()).
toBe
(
false
);
findHeaderSearchInput
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findHeaderSearchDropdown
().
exists
()).
toBe
(
true
);
});
...
...
@@ -265,7 +265,7 @@ describe('HeaderSearchApp', () => {
expect
(
findHeaderSearchDropdown
().
exists
()).
toBe
(
true
);
findDropdownKeyboardNavigation
().
vm
.
$emit
(
'
tab
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findHeaderSearchDropdown
().
exists
()).
toBe
(
false
);
});
...
...
@@ -284,7 +284,7 @@ describe('HeaderSearchApp', () => {
it
(
`when currentFocusIndex changes to
${
MOCK_INDEX
}
updates the data to searchOptions[
${
MOCK_INDEX
}
]`
,
async
()
=>
{
findDropdownKeyboardNavigation
().
vm
.
$emit
(
'
change
'
,
MOCK_INDEX
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
vm
.
currentFocusedOption
).
toBe
(
MOCK_DEFAULT_SEARCH_OPTIONS
[
MOCK_INDEX
]);
});
});
...
...
@@ -299,7 +299,7 @@ describe('HeaderSearchApp', () => {
it
(
'
onKey-enter submits a search
'
,
async
()
=>
{
findHeaderSearchInput
().
vm
.
$emit
(
'
keydown
'
,
new
KeyboardEvent
({
key
:
ENTER_KEY
}));
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
visitUrl
).
toHaveBeenCalledWith
(
MOCK_SEARCH_QUERY
);
});
...
...
@@ -316,7 +316,7 @@ describe('HeaderSearchApp', () => {
it
(
'
onKey-enter clicks the selected dropdown item rather than submitting a search
'
,
async
()
=>
{
findDropdownKeyboardNavigation
().
vm
.
$emit
(
'
change
'
,
MOCK_INDEX
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
findHeaderSearchInput
().
vm
.
$emit
(
'
keydown
'
,
new
KeyboardEvent
({
key
:
ENTER_KEY
}));
expect
(
visitUrl
).
toHaveBeenCalledWith
(
MOCK_DEFAULT_SEARCH_OPTIONS
[
MOCK_INDEX
].
url
);
});
...
...
spec/frontend/header_search/components/header_search_autocomplete_items_spec.js
View file @
0d6b1f91
import
{
GlDropdownItem
,
GlLoadingIcon
,
GlAvatar
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
HeaderSearchAutocompleteItems
from
'
~/header_search/components/header_search_autocomplete_items.vue
'
;
import
{
...
...
@@ -143,7 +143,7 @@ describe('HeaderSearchAutocompleteItems', () => {
wrapper.setProps({ currentFocusedOption: MOCK_SORTED_AUTOCOMPLETE_OPTIONS[0] });
await
wrapper.vm.$
nextTick();
await nextTick();
expect(scrollSpy).toHaveBeenCalledWith(false);
scrollSpy.mockRestore();
...
...
spec/frontend/ide/components/branches/search_list_spec.js
View file @
0d6b1f91
import
{
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
Item
from
'
~/ide/components/branches/item.vue
'
;
import
List
from
'
~/ide/components/branches/search_list.vue
'
;
...
...
@@ -50,14 +50,13 @@ describe('IDE branches search list', () => {
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
true
);
});
it
(
'
renders branches not found when search is not empty and branches list is empty
'
,
()
=>
{
it
(
'
renders branches not found when search is not empty and branches list is empty
'
,
async
()
=>
{
createComponent
({
branches
:
[]
});
wrapper
.
find
(
'
input[type="search"]
'
).
setValue
(
'
something
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
text
()).
toContain
(
__
(
'
No branches found
'
));
});
});
describe
(
'
with branches
'
,
()
=>
{
it
(
'
renders list
'
,
()
=>
{
...
...
spec/frontend/ide/components/commit_sidebar/form_spec.js
View file @
0d6b1f91
import
{
GlModal
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
{
stubComponent
}
from
'
helpers/stub_component
'
;
import
{
createMockDirective
,
getBinding
}
from
'
helpers/vue_mock_directive
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
...
...
@@ -98,7 +98,7 @@ describe('IDE commit form', () => {
it
(
`at view=
${
viewFn
.
name
}
,
${
buttonFn
.
name
}
has disabled=
${
disabled
}
tooltip=
${
tooltip
}
`
,
async
()
=>
{
viewFn
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
buttonFn
()).
toEqual
({
disabled
,
...
...
@@ -116,7 +116,7 @@ describe('IDE commit form', () => {
goToEditView
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
renders commit button in compact mode
'
,
()
=>
{
...
...
@@ -135,7 +135,7 @@ describe('IDE commit form', () => {
it
(
'
when begin commit button is clicked, shows form
'
,
async
()
=>
{
findBeginCommitButton
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findForm
().
exists
()).
toBe
(
true
);
});
...
...
@@ -143,7 +143,7 @@ describe('IDE commit form', () => {
it
(
'
when begin commit button is clicked, sets activity view
'
,
async
()
=>
{
findBeginCommitButton
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
store
.
state
.
currentActivityView
).
toBe
(
leftSidebarViews
.
commit
.
name
);
});
...
...
@@ -153,14 +153,14 @@ describe('IDE commit form', () => {
setLastCommitMessage
(
'
test
'
);
goToEditView
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findForm
().
exists
()).
toBe
(
true
);
// Now test that it collapses when lastCommitMsg is cleared
setLastCommitMessage
(
''
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findForm
().
exists
()).
toBe
(
false
);
});
...
...
@@ -177,7 +177,7 @@ describe('IDE commit form', () => {
goToCommitView
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
afterEach
(()
=>
{
...
...
@@ -188,12 +188,12 @@ describe('IDE commit form', () => {
expect
(
findForm
().
exists
()).
toBe
(
false
);
store
.
state
.
stagedFiles
=
[];
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findForm
().
exists
()).
toBe
(
false
);
store
.
state
.
stagedFiles
.
push
(
'
test
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findForm
().
exists
()).
toBe
(
false
);
});
...
...
@@ -208,7 +208,7 @@ describe('IDE commit form', () => {
goToCommitView
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
shows form
'
,
()
=>
{
...
...
@@ -222,7 +222,7 @@ describe('IDE commit form', () => {
describe
(
'
when no changed files
'
,
()
=>
{
beforeEach
(
async
()
=>
{
store
.
state
.
stagedFiles
=
[];
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
hides form
'
,
()
=>
{
...
...
@@ -231,7 +231,7 @@ describe('IDE commit form', () => {
it
(
'
expands again when staged files are added
'
,
async
()
=>
{
store
.
state
.
stagedFiles
.
push
(
'
test
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findForm
().
exists
()).
toBe
(
true
);
});
...
...
@@ -240,7 +240,7 @@ describe('IDE commit form', () => {
it
(
'
updates commitMessage in store on input
'
,
async
()
=>
{
setCommitMessageInput
(
'
testing commit message
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
store
.
state
.
commit
.
commitMessage
).
toBe
(
'
testing commit message
'
);
});
...
...
@@ -253,14 +253,14 @@ describe('IDE commit form', () => {
it
(
'
resets commitMessage when clicking discard button
'
,
async
()
=>
{
setCommitMessageInput
(
'
testing commit message
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findCommitMessageInput
().
props
(
'
text
'
)).
toBe
(
'
testing commit message
'
);
// Test that commitMessage is cleared on click
findDiscardDraftButton
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findCommitMessageInput
().
props
(
'
text
'
)).
toBe
(
''
);
});
...
...
@@ -274,11 +274,11 @@ describe('IDE commit form', () => {
goToCommitView
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
setCommitMessageInput
(
'
testing commit message
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
jest
.
spyOn
(
store
,
'
dispatch
'
).
mockResolvedValue
();
});
...
...
@@ -291,7 +291,7 @@ describe('IDE commit form', () => {
it
(
'
when cannot push code, submitting does nothing
'
,
async
()
=>
{
store
.
state
.
projects
.
abcproject
.
userPermissions
.
pushCode
=
false
;
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
submitForm
();
...
...
@@ -309,7 +309,7 @@ describe('IDE commit form', () => {
const
error
=
createError
();
store
.
state
.
commit
.
commitError
=
error
;
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
modal
.
vm
.
show
).
toHaveBeenCalled
();
expect
(
modal
.
props
()).
toMatchObject
({
...
...
@@ -342,7 +342,7 @@ describe('IDE commit form', () => {
async
({
commitError
,
expectedActions
})
=>
{
store
.
state
.
commit
.
commitError
=
commitError
(
'
test message
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
wrapper
.
find
(
GlModal
).
vm
.
$emit
(
'
ok
'
);
...
...
spec/frontend/ide/components/error_message_spec.js
View file @
0d6b1f91
import
{
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
ErrorMessage
from
'
~/ide/components/error_message.vue
'
;
...
...
@@ -86,19 +86,15 @@ describe('IDE error message component', () => {
expect
(
actionMock
).
toHaveBeenCalledWith
(
message
.
actionPayload
);
});
it
(
'
does not dispatch action when already loading
'
,
()
=>
{
it
(
'
does not dispatch action when already loading
'
,
async
()
=>
{
findActionButton
().
trigger
(
'
click
'
);
actionMock
.
mockReset
();
return
wrapper
.
vm
.
$nextTick
(()
=>
{
findActionButton
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
actionMock
).
not
.
toHaveBeenCalled
();
});
});
});
it
(
'
shows loading icon when loading
'
,
()
=>
{
it
(
'
shows loading icon when loading
'
,
async
()
=>
{
let
resolveAction
;
actionMock
.
mockImplementation
(
()
=>
...
...
@@ -108,19 +104,16 @@ describe('IDE error message component', () => {
);
findActionButton
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
GlLoadingIcon
).
isVisible
()).
toBe
(
true
);
resolveAction
();
});
});
it
(
'
hides loading icon when operation finishes
'
,
()
=>
{
it
(
'
hides loading icon when operation finishes
'
,
async
()
=>
{
findActionButton
().
trigger
(
'
click
'
);
return
actionMock
()
.
then
(()
=>
wrapper
.
vm
.
$nextTick
())
.
then
(()
=>
{
await
actionMock
();
await
nextTick
();
expect
(
wrapper
.
find
(
GlLoadingIcon
).
isVisible
()).
toBe
(
false
);
});
});
});
});
spec/frontend/ide/components/file_templates/dropdown_spec.js
View file @
0d6b1f91
import
{
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
$
from
'
jquery
'
;
import
Vuex
from
'
vuex
'
;
import
Dropdown
from
'
~/ide/components/file_templates/dropdown.vue
'
;
...
...
@@ -54,16 +54,15 @@ describe('IDE file templates dropdown component', () => {
wrapper
=
null
;
});
it
(
'
calls clickItem on click
'
,
()
=>
{
it
(
'
calls clickItem on click
'
,
async
()
=>
{
const
itemData
=
{
name
:
'
test.yml
'
};
createComponent
({
props
:
{
data
:
[
itemData
]
}
});
const
item
=
findItemButtons
().
at
(
0
);
item
.
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
().
click
[
0
][
0
]).
toBe
(
itemData
);
});
});
it
(
'
renders dropdown title
'
,
()
=>
{
const
title
=
'
Test title
'
;
...
...
@@ -111,7 +110,7 @@ describe('IDE file templates dropdown component', () => {
expect
(
items
.
wrappers
.
map
((
x
)
=>
x
.
text
())).
toEqual
(
templates
.
map
((
x
)
=>
x
.
name
));
});
it
(
'
searches template data
'
,
()
=>
{
it
(
'
searches template data
'
,
async
()
=>
{
const
templates
=
[{
name
:
'
match 1
'
},
{
name
:
'
other
'
},
{
name
:
'
match 2
'
}];
const
matches
=
[
'
match 1
'
,
'
match 2
'
];
createComponent
({
...
...
@@ -119,13 +118,12 @@ describe('IDE file templates dropdown component', () => {
state
:
{
templates
},
});
findSearch
().
setValue
(
'
match
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
const
items
=
findItemButtons
();
expect
(
items
.
length
).
toBe
(
matches
.
length
);
expect
(
items
.
wrappers
.
map
((
x
)
=>
x
.
text
())).
toEqual
(
matches
);
});
});
it
(
'
does not render input when `searchable` is true & `showLoading` is true
'
,
()
=>
{
createComponent
({
...
...
@@ -159,17 +157,16 @@ describe('IDE file templates dropdown component', () => {
expect
(
findSearch
().
exists
()).
toBe
(
true
);
});
it
(
'
searches data
'
,
()
=>
{
it
(
'
searches data
'
,
async
()
=>
{
const
data
=
[{
name
:
'
match 1
'
},
{
name
:
'
other
'
},
{
name
:
'
match 2
'
}];
const
matches
=
[
'
match 1
'
,
'
match 2
'
];
createComponent
({
props
:
{
searchable
:
true
,
data
}
});
findSearch
().
setValue
(
'
match
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
const
items
=
findItemButtons
();
expect
(
items
.
length
).
toBe
(
matches
.
length
);
expect
(
items
.
wrappers
.
map
((
x
)
=>
x
.
text
())).
toEqual
(
matches
);
});
});
});
});
spec/frontend/ide/components/ide_file_row_spec.js
View file @
0d6b1f91
import
{
mount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
FileRowExtra
from
'
~/ide/components/file_row_extra.vue
'
;
import
IdeFileRow
from
'
~/ide/components/ide_file_row.vue
'
;
...
...
@@ -43,7 +43,7 @@ describe('Ide File Row component', () => {
const
findFileRow
=
()
=>
wrapper
.
find
(
FileRow
);
const
hasDropdownOpen
=
()
=>
findFileRowExtra
().
props
(
'
dropdownOpen
'
);
it
(
'
fileRow component has listeners
'
,
()
=>
{
it
(
'
fileRow component has listeners
'
,
async
()
=>
{
const
toggleTreeOpen
=
jest
.
fn
();
createComponent
(
{},
...
...
@@ -56,10 +56,9 @@ describe('Ide File Row component', () => {
findFileRow
().
vm
.
$emit
(
'
toggleTreeOpen
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
toggleTreeOpen
).
toHaveBeenCalled
();
});
});
describe
(
'
default
'
,
()
=>
{
beforeEach
(()
=>
{
...
...
@@ -85,32 +84,30 @@ describe('Ide File Row component', () => {
});
describe
(
'
with open dropdown
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
createComponent
();
findFileRowExtra
().
vm
.
$emit
(
'
toggle
'
,
true
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
shows open dropdown
'
,
()
=>
{
expect
(
hasDropdownOpen
()).
toBe
(
true
);
});
it
(
'
hides dropdown when mouseleave
'
,
()
=>
{
it
(
'
hides dropdown when mouseleave
'
,
async
()
=>
{
findFileRow
().
vm
.
$emit
(
'
mouseleave
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
hasDropdownOpen
()).
toEqual
(
false
);
});
});
it
(
'
hides dropdown on toggle
'
,
()
=>
{
it
(
'
hides dropdown on toggle
'
,
async
()
=>
{
findFileRowExtra
().
vm
.
$emit
(
'
toggle
'
,
false
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
hasDropdownOpen
()).
toEqual
(
false
);
});
});
});
});
spec/frontend/ide/components/ide_review_spec.js
View file @
0d6b1f91
import
{
mount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
{
keepAlive
}
from
'
helpers/keep_alive_component_helper
'
;
import
{
trimText
}
from
'
helpers/text_helper
'
;
...
...
@@ -74,14 +74,14 @@ describe('IDE review mode', () => {
});
describe
(
'
merge request
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
store
.
state
.
currentMergeRequestId
=
'
1
'
;
store
.
state
.
projects
.
abcproject
.
mergeRequests
[
'
1
'
]
=
{
iid
:
123
,
web_url
:
'
testing123
'
,
};
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
renders edit dropdown
'
,
()
=>
{
...
...
@@ -91,7 +91,7 @@ describe('IDE review mode', () => {
it
(
'
renders merge request link & IID
'
,
async
()
=>
{
store
.
state
.
viewer
=
'
mrdiff
'
;
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
trimText
(
wrapper
.
text
())).
toContain
(
'
Merge request (!123)
'
);
});
...
...
@@ -99,7 +99,7 @@ describe('IDE review mode', () => {
it
(
'
changes text to latest changes when viewer is not mrdiff
'
,
async
()
=>
{
store
.
state
.
viewer
=
'
diff
'
;
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
text
()).
toContain
(
'
Latest changes
'
);
});
...
...
spec/frontend/ide/components/ide_side_bar_spec.js
View file @
0d6b1f91
import
{
GlSkeletonLoading
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
IdeReview
from
'
~/ide/components/ide_review.vue
'
;
...
...
@@ -45,7 +45,7 @@ describe('IdeSidebar', () => {
store
.
state
.
loading
=
true
;
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
findAll
(
GlSkeletonLoading
)).
toHaveLength
(
3
);
});
...
...
@@ -60,7 +60,7 @@ describe('IdeSidebar', () => {
store
.
state
.
currentActivityView
=
leftSidebarViews
.
review
.
name
;
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
find
(
IdeTree
).
exists
()).
toBe
(
false
);
expect
(
wrapper
.
find
(
IdeReview
).
exists
()).
toBe
(
true
);
...
...
@@ -68,7 +68,7 @@ describe('IdeSidebar', () => {
store
.
state
.
currentActivityView
=
leftSidebarViews
.
commit
.
name
;
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
find
(
IdeTree
).
exists
()).
toBe
(
false
);
expect
(
wrapper
.
find
(
IdeReview
).
exists
()).
toBe
(
false
);
...
...
@@ -84,7 +84,7 @@ describe('IdeSidebar', () => {
view
,
});
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
find
(
IdeTree
).
exists
()).
toBe
(
tree
);
expect
(
wrapper
.
find
(
IdeReview
).
exists
()).
toBe
(
review
);
...
...
@@ -99,7 +99,7 @@ describe('IdeSidebar', () => {
store
.
state
.
currentActivityView
=
leftSidebarViews
.
commit
.
name
;
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
find
(
IdeTree
).
exists
()).
toBe
(
false
);
expect
(
wrapper
.
find
(
RepoCommitSection
).
exists
()).
toBe
(
true
);
...
...
@@ -107,7 +107,7 @@ describe('IdeSidebar', () => {
store
.
state
.
currentActivityView
=
leftSidebarViews
.
edit
.
name
;
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
// reference to the elements remains the same, meaning the components were kept alive
expect
(
wrapper
.
find
(
IdeTree
).
element
).
toEqual
(
ideTreeComponent
);
...
...
spec/frontend/ide/components/jobs/stage_spec.js
View file @
0d6b1f91
import
{
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
Item
from
'
~/ide/components/jobs/item.vue
'
;
import
Stage
from
'
~/ide/components/jobs/stage.vue
'
;
import
{
stages
,
jobs
}
from
'
../../mock_data
'
;
...
...
@@ -47,24 +48,22 @@ describe('IDE pipeline stage', () => {
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
true
);
});
it
(
'
emits toggleCollaped event with stage id when clicking header
'
,
()
=>
{
it
(
'
emits toggleCollaped event with stage id when clicking header
'
,
async
()
=>
{
const
id
=
5
;
createComponent
({
stage
:
{
...
defaultProps
.
stage
,
id
}
});
findHeader
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
().
toggleCollapsed
[
0
][
0
]).
toBe
(
id
);
});
});
it
(
'
emits clickViewLog entity with job
'
,
()
=>
{
it
(
'
emits clickViewLog entity with job
'
,
async
()
=>
{
const
[
job
]
=
defaultProps
.
stage
.
jobs
;
createComponent
();
wrapper
.
findAll
(
Item
).
at
(
0
).
vm
.
$emit
(
'
clickViewLog
'
,
job
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
().
clickViewLog
[
0
][
0
]).
toBe
(
job
);
});
});
it
(
'
renders stage details & icon
'
,
()
=>
{
createComponent
();
...
...
spec/frontend/ide/components/merge_requests/list_spec.js
View file @
0d6b1f91
import
{
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
Item
from
'
~/ide/components/merge_requests/item.vue
'
;
import
List
from
'
~/ide/components/merge_requests/list.vue
'
;
...
...
@@ -66,25 +66,21 @@ describe('IDE merge requests list', () => {
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
true
);
});
it
(
'
renders no search results text when search is not empty
'
,
()
=>
{
it
(
'
renders no search results text when search is not empty
'
,
async
()
=>
{
createComponent
();
findTokenedInput
().
vm
.
$emit
(
'
input
'
,
'
something
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
text
()).
toContain
(
'
No merge requests found
'
);
});
});
it
(
'
clicking on search type, sets currentSearchType and loads merge requests
'
,
()
=>
{
it
(
'
clicking on search type, sets currentSearchType and loads merge requests
'
,
async
()
=>
{
createComponent
();
findTokenedInput
().
vm
.
$emit
(
'
focus
'
);
return
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
{
await
nextTick
();
findSearchTypeButtons
().
at
(
0
).
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
();
})
.
then
(()
=>
{
await
nextTick
();
const
searchType
=
wrapper
.
vm
.
$options
.
searchTypes
[
0
];
expect
(
findTokenedInput
().
props
(
'
tokens
'
)).
toEqual
([
searchType
]);
...
...
@@ -93,7 +89,6 @@ describe('IDE merge requests list', () => {
search
:
''
,
});
});
});
describe
(
'
with merge requests
'
,
()
=>
{
let
defaultStateWithMergeRequests
;
...
...
@@ -119,12 +114,12 @@ describe('IDE merge requests list', () => {
});
describe
(
'
when searching merge requests
'
,
()
=>
{
it
(
'
calls `loadMergeRequests` on input in search field
'
,
()
=>
{
it
(
'
calls `loadMergeRequests` on input in search field
'
,
async
()
=>
{
createComponent
(
defaultStateWithMergeRequests
);
const
input
=
findTokenedInput
();
input
.
vm
.
$emit
(
'
input
'
,
'
something
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
fetchMergeRequestsMock
).
toHaveBeenCalledWith
(
expect
.
any
(
Object
),
{
search
:
'
something
'
,
type
:
''
,
...
...
@@ -132,7 +127,6 @@ describe('IDE merge requests list', () => {
});
});
});
});
describe
(
'
on search focus
'
,
()
=>
{
let
input
;
...
...
@@ -143,9 +137,9 @@ describe('IDE merge requests list', () => {
});
describe
(
'
without search value
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
input
.
vm
.
$emit
(
'
focus
'
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
shows search types
'
,
()
=>
{
...
...
@@ -155,22 +149,20 @@ describe('IDE merge requests list', () => {
);
});
it
(
'
hides search types when search changes
'
,
()
=>
{
it
(
'
hides search types when search changes
'
,
async
()
=>
{
input
.
vm
.
$emit
(
'
input
'
,
'
something
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findSearchTypeButtons
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
with search type
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
findSearchTypeButtons
().
at
(
0
).
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
input
.
vm
.
$emit
(
'
focus
'
))
.
then
(()
=>
wrapper
.
vm
.
$nextTick
());
await
nextTick
();
await
input
.
vm
.
$emit
(
'
focus
'
);
await
nextTick
();
});
it
(
'
does not show search types
'
,
()
=>
{
...
...
@@ -180,10 +172,10 @@ describe('IDE merge requests list', () => {
});
describe
(
'
with search value
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
input
.
vm
.
$emit
(
'
input
'
,
'
something
'
);
input
.
vm
.
$emit
(
'
focus
'
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
does not show search types
'
,
()
=>
{
...
...
spec/frontend/ide/components/panes/right_spec.js
View file @
0d6b1f91
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
CollapsibleSidebar
from
'
~/ide/components/panes/collapsible_sidebar.vue
'
;
import
RightPane
from
'
~/ide/components/panes/right.vue
'
;
...
...
@@ -86,10 +86,10 @@ describe('ide/components/panes/right.vue', () => {
createComponent
();
});
it
(
'
adds terminal tab
'
,
()
=>
{
it
(
'
adds terminal tab
'
,
async
()
=>
{
store
.
state
.
terminal
.
isVisible
=
true
;
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
CollapsibleSidebar
).
props
(
'
extensionTabs
'
)).
toEqual
(
expect
.
arrayContaining
([
expect
.
objectContaining
({
...
...
@@ -99,7 +99,6 @@ describe('ide/components/panes/right.vue', () => {
]),
);
});
});
it
(
'
hides terminal tab when not visible
'
,
()
=>
{
store
.
state
.
terminal
.
isVisible
=
false
;
...
...
spec/frontend/ide/components/preview/clientside_spec.js
View file @
0d6b1f91
import
{
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
smooshpack
from
'
smooshpack
'
;
import
Vuex
from
'
vuex
'
;
import
Clientside
from
'
~/ide/components/preview/clientside.vue
'
;
...
...
@@ -351,41 +351,38 @@ describe('IDE clientside preview', () => {
});
describe
(
'
template
'
,
()
=>
{
it
(
'
renders ide-preview element when showPreview is true
'
,
()
=>
{
it
(
'
renders ide-preview element when showPreview is true
'
,
async
()
=>
{
createComponent
({
getters
:
{
packageJson
:
dummyPackageJson
}
});
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
({
loading
:
false
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
'
#ide-preview
'
).
exists
()).
toBe
(
true
);
});
});
it
(
'
renders empty state
'
,
()
=>
{
it
(
'
renders empty state
'
,
async
()
=>
{
createComponent
();
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
({
loading
:
false
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
text
()).
toContain
(
'
Preview your web application using Web IDE client-side evaluation.
'
,
);
});
});
it
(
'
renders loading icon
'
,
()
=>
{
it
(
'
renders loading icon
'
,
async
()
=>
{
createComponent
();
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
({
loading
:
true
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
true
);
});
});
});
describe
(
'
when destroyed
'
,
()
=>
{
let
spy
;
...
...
spec/frontend/ide/components/preview/navigator_spec.js
View file @
0d6b1f91
import
{
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
listen
}
from
'
codesandbox-api
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
import
ClientsideNavigator
from
'
~/ide/components/preview/navigator.vue
'
;
...
...
@@ -29,32 +30,29 @@ describe('IDE clientside preview navigator', () => {
wrapper
.
destroy
();
});
it
(
'
renders readonly URL bar
'
,
()
=>
{
it
(
'
renders readonly URL bar
'
,
async
()
=>
{
listenHandler
({
type
:
'
urlchange
'
,
url
:
manager
.
bundlerURL
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
'
input[readonly]
'
).
element
.
value
).
toBe
(
'
/
'
);
});
});
it
(
'
renders loading icon by default
'
,
()
=>
{
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
true
);
});
it
(
'
removes loading icon when done event is fired
'
,
()
=>
{
it
(
'
removes loading icon when done event is fired
'
,
async
()
=>
{
listenHandler
({
type
:
'
done
'
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
GlLoadingIcon
).
exists
()).
toBe
(
false
);
});
});
it
(
'
does not count visiting same url multiple times
'
,
()
=>
{
it
(
'
does not count visiting same url multiple times
'
,
async
()
=>
{
listenHandler
({
type
:
'
done
'
});
listenHandler
({
type
:
'
done
'
,
url
:
`
${
TEST_HOST
}
/url1`
});
listenHandler
({
type
:
'
done
'
,
url
:
`
${
TEST_HOST
}
/url1`
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findBackButton
().
attributes
(
'
disabled
'
)).
toBe
(
'
disabled
'
);
});
});
it
(
'
unsubscribes from listen on destroy
'
,
()
=>
{
const
unsubscribeFn
=
listen
();
...
...
@@ -64,107 +62,93 @@ describe('IDE clientside preview navigator', () => {
});
describe
(
'
back button
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
listenHandler
({
type
:
'
done
'
});
listenHandler
({
type
:
'
urlchange
'
,
url
:
TEST_HOST
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
is disabled by default
'
,
()
=>
{
expect
(
findBackButton
().
attributes
(
'
disabled
'
)).
toBe
(
'
disabled
'
);
});
it
(
'
is enabled when there is previous entry
'
,
()
=>
{
it
(
'
is enabled when there is previous entry
'
,
async
()
=>
{
listenHandler
({
type
:
'
urlchange
'
,
url
:
`
${
TEST_HOST
}
/url1`
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
findBackButton
().
trigger
(
'
click
'
);
expect
(
findBackButton
().
attributes
(
'
disabled
'
)).
toBeFalsy
();
});
});
it
(
'
is disabled when there is no previous entry
'
,
()
=>
{
it
(
'
is disabled when there is no previous entry
'
,
async
()
=>
{
listenHandler
({
type
:
'
urlchange
'
,
url
:
`
${
TEST_HOST
}
/url1`
});
return
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
{
await
nextTick
();
findBackButton
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
();
})
.
then
(()
=>
{
await
nextTick
();
expect
(
findBackButton
().
attributes
(
'
disabled
'
)).
toBe
(
'
disabled
'
);
});
});
it
(
'
updates manager iframe src
'
,
()
=>
{
it
(
'
updates manager iframe src
'
,
async
()
=>
{
listenHandler
({
type
:
'
urlchange
'
,
url
:
`
${
TEST_HOST
}
/url1`
});
listenHandler
({
type
:
'
urlchange
'
,
url
:
`
${
TEST_HOST
}
/url2`
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
findBackButton
().
trigger
(
'
click
'
);
expect
(
manager
.
iframe
.
src
).
toBe
(
`
${
TEST_HOST
}
/url1`
);
});
});
});
describe
(
'
forward button
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
listenHandler
({
type
:
'
done
'
});
listenHandler
({
type
:
'
urlchange
'
,
url
:
TEST_HOST
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
is disabled by default
'
,
()
=>
{
expect
(
findForwardButton
().
attributes
(
'
disabled
'
)).
toBe
(
'
disabled
'
);
});
it
(
'
is enabled when there is next entry
'
,
()
=>
{
it
(
'
is enabled when there is next entry
'
,
async
()
=>
{
listenHandler
({
type
:
'
urlchange
'
,
url
:
`
${
TEST_HOST
}
/url1`
});
return
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
{
await
nextTick
();
findBackButton
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
();
})
.
then
(()
=>
{
await
nextTick
();
expect
(
findForwardButton
().
attributes
(
'
disabled
'
)).
toBeFalsy
();
});
});
it
(
'
is disabled when there is no next entry
'
,
()
=>
{
it
(
'
is disabled when there is no next entry
'
,
async
()
=>
{
listenHandler
({
type
:
'
urlchange
'
,
url
:
`
${
TEST_HOST
}
/url1`
});
return
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
{
await
nextTick
();
findBackButton
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
();
})
.
then
(()
=>
{
await
nextTick
();
findForwardButton
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
();
})
.
then
(()
=>
{
await
nextTick
();
expect
(
findForwardButton
().
attributes
(
'
disabled
'
)).
toBe
(
'
disabled
'
);
});
});
it
(
'
updates manager iframe src
'
,
()
=>
{
it
(
'
updates manager iframe src
'
,
async
()
=>
{
listenHandler
({
type
:
'
urlchange
'
,
url
:
`
${
TEST_HOST
}
/url1`
});
listenHandler
({
type
:
'
urlchange
'
,
url
:
`
${
TEST_HOST
}
/url2`
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
findBackButton
().
trigger
(
'
click
'
);
expect
(
manager
.
iframe
.
src
).
toBe
(
`
${
TEST_HOST
}
/url1`
);
});
});
});
describe
(
'
refresh button
'
,
()
=>
{
const
url
=
`
${
TEST_HOST
}
/some_url`
;
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
listenHandler
({
type
:
'
done
'
});
listenHandler
({
type
:
'
urlchange
'
,
url
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
calls refresh with current path
'
,
()
=>
{
...
...
spec/frontend/ide/components/repo_tabs_spec.js
View file @
0d6b1f91
import
{
mount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
RepoTabs
from
'
~/ide/components/repo_tabs.vue
'
;
import
{
createStore
}
from
'
~/ide/stores
'
;
...
...
@@ -29,17 +29,14 @@ describe('RepoTabs', () => {
wrapper
.
destroy
();
});
it
(
'
renders a list of tabs
'
,
(
done
)
=>
{
it
(
'
renders a list of tabs
'
,
async
(
)
=>
{
store
.
state
.
openFiles
[
0
].
active
=
true
;
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
const
tabs
=
[...
wrapper
.
vm
.
$el
.
querySelectorAll
(
'
.multi-file-tab
'
)];
expect
(
tabs
.
length
).
toEqual
(
2
);
expect
(
tabs
[
0
].
parentNode
.
classList
.
contains
(
'
active
'
)).
toEqual
(
true
);
expect
(
tabs
[
1
].
parentNode
.
classList
.
contains
(
'
active
'
)).
toEqual
(
false
);
done
();
});
});
});
spec/frontend/ide/components/resizable_panel_spec.js
View file @
0d6b1f91
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
ResizablePanel
from
'
~/ide/components/resizable_panel.vue
'
;
import
{
SIDE_LEFT
,
SIDE_RIGHT
}
from
'
~/ide/constants
'
;
...
...
@@ -99,15 +99,14 @@ describe('~/ide/components/resizable_panel', () => {
});
});
it
(
'
when resizer emits update:size, changes inline width
'
,
()
=>
{
it
(
'
when resizer emits update:size, changes inline width
'
,
async
()
=>
{
const
newSize
=
TEST_WIDTH
-
100
;
const
resizer
=
findResizer
();
resizer
.
vm
.
$emit
(
'
update:size
'
,
newSize
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findInlineStyle
()).
toBe
(
createInlineStyle
(
newSize
));
});
});
});
});
spec/frontend/ide/components/terminal/session_spec.js
View file @
0d6b1f91
import
{
GlButton
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
TerminalSession
from
'
~/ide/components/terminal/session.vue
'
;
import
Terminal
from
'
~/ide/components/terminal/terminal.vue
'
;
...
...
@@ -67,32 +67,30 @@ describe('IDE TerminalSession', () => {
});
[
STARTING
,
PENDING
,
RUNNING
].
forEach
((
status
)
=>
{
it
(
`show stop button when status is
${
status
}
`
,
()
=>
{
it
(
`show stop button when status is
${
status
}
`
,
async
()
=>
{
state
.
session
=
{
status
};
factory
();
const
button
=
findButton
();
button
.
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
button
.
text
()).
toEqual
(
'
Stop Terminal
'
);
expect
(
actions
.
stopSession
).
toHaveBeenCalled
();
});
});
});
[
STOPPING
,
STOPPED
].
forEach
((
status
)
=>
{
it
(
`show stop button when status is
${
status
}
`
,
()
=>
{
it
(
`show stop button when status is
${
status
}
`
,
async
()
=>
{
state
.
session
=
{
status
};
factory
();
const
button
=
findButton
();
button
.
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
button
.
text
()).
toEqual
(
'
Restart Terminal
'
);
expect
(
actions
.
restartSession
).
toHaveBeenCalled
();
});
});
});
});
spec/frontend/ide/components/terminal/terminal_controls_spec.js
View file @
0d6b1f91
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
ScrollButton
from
'
~/ide/components/jobs/detail/scroll_button.vue
'
;
import
TerminalControls
from
'
~/ide/components/terminal/terminal_controls.vue
'
;
...
...
@@ -39,27 +40,25 @@ describe('IDE TerminalControls', () => {
);
});
it
(
'
emits "scroll-up" when click up button
'
,
()
=>
{
it
(
'
emits "scroll-up" when click up button
'
,
async
()
=>
{
factory
({
propsData
:
{
canScrollUp
:
true
}
});
expect
(
wrapper
.
emitted
()).
toEqual
({});
buttons
.
at
(
0
).
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
(
'
scroll-up
'
)).
toEqual
([[]]);
});
});
it
(
'
emits "scroll-down" when click down button
'
,
()
=>
{
it
(
'
emits "scroll-down" when click down button
'
,
async
()
=>
{
factory
({
propsData
:
{
canScrollDown
:
true
}
});
expect
(
wrapper
.
emitted
()).
toEqual
({});
buttons
.
at
(
1
).
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
(
'
scroll-down
'
)).
toEqual
([[]]);
});
});
});
spec/frontend/incidents/components/incidents_list_spec.js
View file @
0d6b1f91
import
{
GlAlert
,
GlLoadingIcon
,
GlTable
,
GlAvatar
,
GlEmptyState
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
IncidentsList
from
'
~/incidents/components/incidents_list.vue
'
;
import
{
I18N
,
...
...
@@ -210,7 +211,7 @@ describe('Incidents List', () => {
it
(
'
sets button loading on click
'
,
async
()
=>
{
findCreateIncidentBtn
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findCreateIncidentBtn
().
attributes
(
'
loading
'
)).
toBe
(
'
true
'
);
});
...
...
@@ -233,7 +234,7 @@ describe('Incidents List', () => {
it
(
'
should track create new incident button
'
,
async
()
=>
{
findCreateIncidentBtn
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
Tracking
.
event
).
toHaveBeenCalled
();
});
});
...
...
@@ -263,10 +264,10 @@ describe('Incidents List', () => {
const
columnHeader
=
()
=>
wrapper
.
find
(
`[
${
attr
}
="
${
value
}
"]`
);
expect
(
columnHeader
().
attributes
(
'
aria-sort
'
)).
toBe
(
initialSort
);
columnHeader
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
columnHeader
().
attributes
(
'
aria-sort
'
)).
toBe
(
firstSort
);
columnHeader
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
columnHeader
().
attributes
(
'
aria-sort
'
)).
toBe
(
nextSort
);
},
);
...
...
@@ -287,7 +288,7 @@ describe('Incidents List', () => {
it
(
'
should track incident creation events
'
,
async
()
=>
{
findCreateIncidentBtn
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
const
{
category
,
action
}
=
trackIncidentCreateNewOptions
;
expect
(
Tracking
.
event
).
toHaveBeenCalledWith
(
category
,
action
);
});
...
...
spec/frontend/integrations/edit/components/active_checkbox_spec.js
View file @
0d6b1f91
import
{
GlFormCheckbox
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
ActiveCheckbox
from
'
~/integrations/edit/components/active_checkbox.vue
'
;
import
{
createStore
}
from
'
~/integrations/edit/store
'
;
...
...
@@ -68,7 +69,7 @@ describe('ActiveCheckbox', () => {
it
(
'
switches the form value
'
,
async
()
=>
{
findInputInCheckbox
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findGlFormCheckbox
().
vm
.
$attrs
.
checked
).
toBe
(
false
);
});
});
...
...
spec/frontend/integrations/edit/components/confirmation_modal_spec.js
View file @
0d6b1f91
import
{
GlModal
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
ConfirmationModal
from
'
~/integrations/edit/components/confirmation_modal.vue
'
;
import
{
createStore
}
from
'
~/integrations/edit/store
'
;
...
...
@@ -40,7 +41,7 @@ describe('ConfirmationModal', () => {
findGlModal
().
vm
.
$emit
(
'
primary
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
emitted
().
submit
).
toHaveLength
(
1
);
});
...
...
spec/frontend/integrations/edit/components/jira_issues_fields_spec.js
View file @
0d6b1f91
import
{
GlFormCheckbox
,
GlFormInput
}
from
'
@gitlab/ui
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
mountExtended
,
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
JiraIssuesFields
from
'
~/integrations/edit/components/jira_issues_fields.vue
'
;
...
...
@@ -193,7 +194,7 @@ describe('JiraIssuesFields', () => {
await
setEnableCheckbox
(
true
);
expect
(
findJiraForVulnerabilities
().
attributes
(
'
show-full-feature
'
)).
toBe
(
'
true
'
);
wrapper
.
setProps
({
showJiraVulnerabilitiesIntegration
:
false
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findJiraForVulnerabilities
().
attributes
(
'
show-full-feature
'
)).
toBeUndefined
();
});
...
...
spec/frontend/integrations/edit/components/jira_trigger_fields_spec.js
View file @
0d6b1f91
import
{
GlFormCheckbox
}
from
'
@gitlab/ui
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
mountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
JiraTriggerFields
from
'
~/integrations/edit/components/jira_trigger_fields.vue
'
;
...
...
@@ -71,15 +72,14 @@ describe('JiraTriggerFields', () => {
});
describe
(
'
on enable comments
'
,
()
=>
{
it
(
'
shows comment detail
'
,
()
=>
{
it
(
'
shows comment detail
'
,
async
()
=>
{
findCommentSettingsCheckbox
().
vm
.
$emit
(
'
input
'
,
true
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findCommentDetail
().
isVisible
()).
toBe
(
true
);
});
});
});
});
describe
(
'
initialTriggerMergeRequest is true
'
,
()
=>
{
it
(
'
shows trigger settings
'
,
()
=>
{
...
...
@@ -107,7 +107,7 @@ describe('JiraTriggerFields', () => {
});
describe
(
'
initialJiraIssueTransitionAutomatic is false, initialJiraIssueTransitionId is not set
'
,
()
=>
{
it
(
'
selects automatic transitions when enabling transitions
'
,
()
=>
{
it
(
'
selects automatic transitions when enabling transitions
'
,
async
()
=>
{
createComponent
({
initialTriggerCommit
:
true
,
initialEnableComments
:
true
,
...
...
@@ -117,13 +117,12 @@ describe('JiraTriggerFields', () => {
expect
(
checkbox
.
element
.
checked
).
toBe
(
false
);
checkbox
.
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
const
[
radio1
,
radio2
]
=
findIssueTransitionModeRadios
().
wrappers
;
expect
(
radio1
.
element
.
checked
).
toBe
(
true
);
expect
(
radio2
.
element
.
checked
).
toBe
(
false
);
});
});
});
describe
(
'
initialJiraIssueTransitionAutomatic is true
'
,
()
=>
{
it
(
'
uses automatic transitions
'
,
()
=>
{
...
...
spec/frontend/invite_members/components/import_a_project_modal_spec.js
View file @
0d6b1f91
import
{
GlFormGroup
,
GlSprintf
,
GlModal
}
from
'
@gitlab/ui
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
stubComponent
}
from
'
helpers/stub_component
'
;
import
{
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
...
...
@@ -91,7 +92,7 @@ describe('ImportAProjectModal', () => {
it
(
'
sets isLoading to true when the Invite button is clicked
'
,
async
()
=>
{
clickImportButton
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findImportButton
().
props
(
'
loading
'
)).
toBe
(
true
);
});
...
...
@@ -157,7 +158,7 @@ describe('ImportAProjectModal', () => {
clickCancelButton
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
formGroupInvalidFeedback
()).
toBe
(
''
);
expect
(
formGroupErrorState
()).
not
.
toBe
(
false
);
...
...
spec/frontend/invite_members/components/invite_members_modal_spec.js
View file @
0d6b1f91
...
...
@@ -8,6 +8,7 @@ import {
GlModal
,
}
from
'
@gitlab/ui
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
stubComponent
}
from
'
helpers/stub_component
'
;
import
{
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
...
...
@@ -508,7 +509,7 @@ describe('InviteMembersModal', () => {
findMembersSelect
().
vm
.
$emit
(
'
clear
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
membersFormGroupInvalidFeedback
()).
toBe
(
''
);
expect
(
findMembersFormGroup
().
props
(
'
state
'
)).
not
.
toBe
(
false
);
...
...
@@ -518,7 +519,7 @@ describe('InviteMembersModal', () => {
it
(
'
clears the error when the cancel button is clicked
'
,
async
()
=>
{
clickCancelButton
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
membersFormGroupInvalidFeedback
()).
toBe
(
''
);
expect
(
findMembersFormGroup
().
props
(
'
state
'
)).
not
.
toBe
(
false
);
...
...
@@ -528,7 +529,7 @@ describe('InviteMembersModal', () => {
it
(
'
clears the error when the modal is hidden
'
,
async
()
=>
{
wrapper
.
findComponent
(
GlModal
).
vm
.
$emit
(
'
hide
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
membersFormGroupInvalidFeedback
()).
toBe
(
''
);
expect
(
findMembersFormGroup
().
props
(
'
state
'
)).
not
.
toBe
(
false
);
...
...
spec/frontend/issuable/components/related_issuable_item_spec.js
View file @
0d6b1f91
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
import
IssueDueDate
from
'
~/boards/components/issue_due_date.vue
'
;
import
{
formatDate
}
from
'
~/lib/utils/datetime_utility
'
;
...
...
@@ -105,7 +106,7 @@ describe('RelatedIssuableItem', () => {
state
:
'
closed
'
,
closedAt
:
'
2018-12-01T00:00:00.00Z
'
,
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
tokenState
().
classes
(
'
issue-token-state-icon-closed
'
)).
toBe
(
true
);
});
...
...
@@ -140,7 +141,7 @@ describe('RelatedIssuableItem', () => {
closedAt
:
'
2018-12-01T00:00:00.00Z
'
,
},
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
find
(
IssueDueDate
).
props
(
'
closed
'
)).
toBe
(
true
);
});
...
...
@@ -172,14 +173,14 @@ describe('RelatedIssuableItem', () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
({
removeDisabled
:
true
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findRemoveButton
().
attributes
(
'
disabled
'
)).
toEqual
(
'
disabled
'
);
});
it
(
'
triggers onRemoveRequest when clicked
'
,
async
()
=>
{
findRemoveButton
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
const
{
relatedIssueRemoveRequest
}
=
wrapper
.
emitted
();
expect
(
relatedIssueRemoveRequest
.
length
).
toBe
(
1
);
...
...
spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js
View file @
0d6b1f91
import
{
mount
,
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
AddIssuableForm
from
'
~/related_issues/components/add_issuable_form.vue
'
;
import
IssueToken
from
'
~/related_issues/components/issue_token.vue
'
;
import
{
issuableTypesMap
,
linkedIssueTypesMap
,
PathIdSeparator
}
from
'
~/related_issues/constants
'
;
...
...
@@ -194,63 +195,55 @@ describe('AddIssuableForm', () => {
});
describe
(
'
when the form is submitted
'
,
()
=>
{
it
(
'
emits an event with a "relates_to" link type when the "relates to" radio input selected
'
,
(
done
)
=>
{
it
(
'
emits an event with a "relates_to" link type when the "relates to" radio input selected
'
,
async
(
)
=>
{
jest
.
spyOn
(
wrapper
.
vm
,
'
$emit
'
).
mockImplementation
(()
=>
{});
wrapper
.
vm
.
linkedIssueType
=
linkedIssueTypesMap
.
RELATES_TO
;
wrapper
.
vm
.
onFormSubmit
();
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
$emit
).
toHaveBeenCalledWith
(
'
addIssuableFormSubmit
'
,
{
pendingReferences
:
''
,
linkedIssueType
:
linkedIssueTypesMap
.
RELATES_TO
,
});
done
();
});
});
it
(
'
emits an event with a "blocks" link type when the "blocks" radio input selected
'
,
(
done
)
=>
{
it
(
'
emits an event with a "blocks" link type when the "blocks" radio input selected
'
,
async
(
)
=>
{
jest
.
spyOn
(
wrapper
.
vm
,
'
$emit
'
).
mockImplementation
(()
=>
{});
wrapper
.
vm
.
linkedIssueType
=
linkedIssueTypesMap
.
BLOCKS
;
wrapper
.
vm
.
onFormSubmit
();
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
$emit
).
toHaveBeenCalledWith
(
'
addIssuableFormSubmit
'
,
{
pendingReferences
:
''
,
linkedIssueType
:
linkedIssueTypesMap
.
BLOCKS
,
});
done
();
});
});
it
(
'
emits an event with a "is_blocked_by" link type when the "is blocked by" radio input selected
'
,
(
done
)
=>
{
it
(
'
emits an event with a "is_blocked_by" link type when the "is blocked by" radio input selected
'
,
async
(
)
=>
{
jest
.
spyOn
(
wrapper
.
vm
,
'
$emit
'
).
mockImplementation
(()
=>
{});
wrapper
.
vm
.
linkedIssueType
=
linkedIssueTypesMap
.
IS_BLOCKED_BY
;
wrapper
.
vm
.
onFormSubmit
();
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
$emit
).
toHaveBeenCalledWith
(
'
addIssuableFormSubmit
'
,
{
pendingReferences
:
''
,
linkedIssueType
:
linkedIssueTypesMap
.
IS_BLOCKED_BY
,
});
done
();
});
});
it
(
'
shows error message when error is present
'
,
(
done
)
=>
{
it
(
'
shows error message when error is present
'
,
async
(
)
=>
{
const
itemAddFailureMessage
=
'
Something went wrong while submitting.
'
;
wrapper
.
setProps
({
hasError
:
true
,
itemAddFailureMessage
,
});
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
'
.gl-field-error
'
).
exists
()).
toBe
(
true
);
expect
(
wrapper
.
find
(
'
.gl-field-error
'
).
text
()).
toContain
(
itemAddFailureMessage
);
done
();
});
});
});
});
...
...
spec/frontend/issuable/related_issues/components/related_issues_root_spec.js
View file @
0d6b1f91
import
{
mount
,
shallowMount
}
from
'
@vue/test-utils
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
{
nextTick
}
from
'
vue
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
{
defaultProps
,
...
...
@@ -210,42 +211,39 @@ describe('RelatedIssuesRoot', () => {
}),
);
it
(
'
when canceling and hiding add issuable form
'
,
()
=>
{
it
(
'
when canceling and hiding add issuable form
'
,
async
()
=>
{
wrapper
.
vm
.
onPendingFormCancel
();
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
isFormVisible
).
toEqual
(
false
);
expect
(
wrapper
.
vm
.
inputValue
).
toEqual
(
''
);
expect
(
wrapper
.
vm
.
state
.
pendingReferences
).
toHaveLength
(
0
);
});
});
});
describe
(
'
fetchRelatedIssues
'
,
()
=>
{
beforeEach
(()
=>
createComponent
());
it
(
'
sets isFetching while fetching
'
,
()
=>
{
it
(
'
sets isFetching while fetching
'
,
async
()
=>
{
wrapper
.
vm
.
fetchRelatedIssues
();
expect
(
wrapper
.
vm
.
isFetching
).
toEqual
(
true
);
return
waitForPromises
().
then
(()
=>
{
await
waitForPromises
();
expect
(
wrapper
.
vm
.
isFetching
).
toEqual
(
false
);
});
});
it
(
'
should fetch related issues
'
,
()
=>
{
it
(
'
should fetch related issues
'
,
async
()
=>
{
mock
.
onGet
(
defaultProps
.
endpoint
).
reply
(
200
,
[
issuable1
,
issuable2
]);
wrapper
.
vm
.
fetchRelatedIssues
();
return
waitForPromises
().
then
(()
=>
{
await
waitForPromises
();
expect
(
wrapper
.
vm
.
state
.
relatedIssues
).
toHaveLength
(
2
);
expect
(
wrapper
.
vm
.
state
.
relatedIssues
[
0
].
id
).
toEqual
(
issuable1
.
id
);
expect
(
wrapper
.
vm
.
state
.
relatedIssues
[
1
].
id
).
toEqual
(
issuable2
.
id
);
});
});
});
describe
(
'
onInput
'
,
()
=>
{
beforeEach
(()
=>
createComponent
());
...
...
spec/frontend/issues/new/components/title_suggestions_spec.js
View file @
0d6b1f91
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
TitleSuggestions
from
'
~/issues/new/components/title_suggestions.vue
'
;
import
TitleSuggestionsItem
from
'
~/issues/new/components/title_suggestions_item.vue
'
;
...
...
@@ -22,13 +23,12 @@ describe('Issue title suggestions component', () => {
wrapper
.
destroy
();
});
it
(
'
does not render with empty search
'
,
()
=>
{
it
(
'
does not render with empty search
'
,
async
()
=>
{
wrapper
.
setProps
({
search
:
''
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
isVisible
()).
toBe
(
false
);
});
});
describe
(
'
with data
'
,
()
=>
{
let
data
;
...
...
@@ -37,28 +37,26 @@ describe('Issue title suggestions component', () => {
data
=
{
issues
:
[{
id
:
1
},
{
id
:
2
}]
};
});
it
(
'
renders component
'
,
()
=>
{
it
(
'
renders component
'
,
async
()
=>
{
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
(
data
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
findAll
(
'
li
'
).
length
).
toBe
(
data
.
issues
.
length
);
});
});
it
(
'
does not render with empty search
'
,
()
=>
{
it
(
'
does not render with empty search
'
,
async
()
=>
{
wrapper
.
setProps
({
search
:
''
});
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
(
data
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
isVisible
()).
toBe
(
false
);
});
});
it
(
'
does not render when loading
'
,
()
=>
{
it
(
'
does not render when loading
'
,
async
()
=>
{
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
({
...
...
@@ -66,49 +64,44 @@ describe('Issue title suggestions component', () => {
loading
:
1
,
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
isVisible
()).
toBe
(
false
);
});
});
it
(
'
does not render with empty issues data
'
,
()
=>
{
it
(
'
does not render with empty issues data
'
,
async
()
=>
{
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
({
issues
:
[]
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
isVisible
()).
toBe
(
false
);
});
});
it
(
'
renders list of issues
'
,
()
=>
{
it
(
'
renders list of issues
'
,
async
()
=>
{
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
(
data
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
findAll
(
TitleSuggestionsItem
).
length
).
toBe
(
2
);
});
});
it
(
'
adds margin class to first item
'
,
()
=>
{
it
(
'
adds margin class to first item
'
,
async
()
=>
{
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
(
data
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
findAll
(
'
li
'
).
at
(
0
).
classes
()).
toContain
(
'
gl-mb-3
'
);
});
});
it
(
'
does not add margin class to last item
'
,
()
=>
{
it
(
'
does not add margin class to last item
'
,
async
()
=>
{
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
(
data
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
findAll
(
'
li
'
).
at
(
1
).
classes
()).
not
.
toContain
(
'
gl-mb-3
'
);
});
});
});
});
spec/frontend/issues/show/components/app_spec.js
View file @
0d6b1f91
...
...
@@ -145,34 +145,31 @@ describe('Issuable output', () => {
});
});
it
(
'
shows actions if permissions are correct
'
,
()
=>
{
it
(
'
shows actions if permissions are correct
'
,
async
()
=>
{
wrapper
.
vm
.
showForm
=
true
;
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
'
.markdown-selector
'
).
exists
()).
toBe
(
true
);
});
});
it
(
'
does not show actions if permissions are incorrect
'
,
()
=>
{
it
(
'
does not show actions if permissions are incorrect
'
,
async
()
=>
{
wrapper
.
vm
.
showForm
=
true
;
wrapper
.
setProps
({
canUpdate
:
false
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
'
.markdown-selector
'
).
exists
()).
toBe
(
false
);
});
});
it
(
'
does not update formState if form is already open
'
,
()
=>
{
it
(
'
does not update formState if form is already open
'
,
async
()
=>
{
wrapper
.
vm
.
updateAndShowForm
();
wrapper
.
vm
.
state
.
titleText
=
'
testing 123
'
;
wrapper
.
vm
.
updateAndShowForm
();
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
store
.
formState
.
title
).
not
.
toBe
(
'
testing 123
'
);
});
});
describe
(
'
Pinned links propagated
'
,
()
=>
{
it
.
each
`
...
...
@@ -186,31 +183,29 @@ describe('Issuable output', () => {
});
describe
(
'
updateIssuable
'
,
()
=>
{
it
(
'
fetches new data after update
'
,
()
=>
{
it
(
'
fetches new data after update
'
,
async
()
=>
{
const
updateStoreSpy
=
jest
.
spyOn
(
wrapper
.
vm
,
'
updateStoreState
'
);
const
getDataSpy
=
jest
.
spyOn
(
wrapper
.
vm
.
service
,
'
getData
'
);
jest
.
spyOn
(
wrapper
.
vm
.
service
,
'
updateIssuable
'
).
mockResolvedValue
({
data
:
{
web_url
:
window
.
location
.
pathname
},
});
return
wrapper
.
vm
.
updateIssuable
().
then
(()
=>
{
await
wrapper
.
vm
.
updateIssuable
();
expect
(
updateStoreSpy
).
toHaveBeenCalled
();
expect
(
getDataSpy
).
toHaveBeenCalled
();
});
});
it
(
'
correctly updates issuable data
'
,
()
=>
{
it
(
'
correctly updates issuable data
'
,
async
()
=>
{
const
spy
=
jest
.
spyOn
(
wrapper
.
vm
.
service
,
'
updateIssuable
'
).
mockResolvedValue
({
data
:
{
web_url
:
window
.
location
.
pathname
},
});
return
wrapper
.
vm
.
updateIssuable
().
then
(()
=>
{
await
wrapper
.
vm
.
updateIssuable
();
expect
(
spy
).
toHaveBeenCalledWith
(
wrapper
.
vm
.
formState
);
expect
(
eventHub
.
$emit
).
toHaveBeenCalledWith
(
'
close.form
'
);
});
});
it
(
'
does not redirect if issue has not moved
'
,
()
=>
{
it
(
'
does not redirect if issue has not moved
'
,
async
()
=>
{
jest
.
spyOn
(
wrapper
.
vm
.
service
,
'
updateIssuable
'
).
mockResolvedValue
({
data
:
{
web_url
:
window
.
location
.
pathname
,
...
...
@@ -218,12 +213,11 @@ describe('Issuable output', () => {
},
});
return
wrapper
.
vm
.
updateIssuable
().
then
(()
=>
{
await
wrapper
.
vm
.
updateIssuable
();
expect
(
visitUrl
).
not
.
toHaveBeenCalled
();
});
});
it
(
'
does not redirect if issue has not moved and user has switched tabs
'
,
()
=>
{
it
(
'
does not redirect if issue has not moved and user has switched tabs
'
,
async
()
=>
{
jest
.
spyOn
(
wrapper
.
vm
.
service
,
'
updateIssuable
'
).
mockResolvedValue
({
data
:
{
web_url
:
''
,
...
...
@@ -231,12 +225,11 @@ describe('Issuable output', () => {
},
});
return
wrapper
.
vm
.
updateIssuable
().
then
(()
=>
{
await
wrapper
.
vm
.
updateIssuable
();
expect
(
visitUrl
).
not
.
toHaveBeenCalled
();
});
});
it
(
'
redirects if returned web_url has changed
'
,
()
=>
{
it
(
'
redirects if returned web_url has changed
'
,
async
()
=>
{
jest
.
spyOn
(
wrapper
.
vm
.
service
,
'
updateIssuable
'
).
mockResolvedValue
({
data
:
{
web_url
:
'
/testing-issue-move
'
,
...
...
@@ -246,110 +239,97 @@ describe('Issuable output', () => {
wrapper
.
vm
.
updateIssuable
();
return
wrapper
.
vm
.
updateIssuable
().
then
(()
=>
{
await
wrapper
.
vm
.
updateIssuable
();
expect
(
visitUrl
).
toHaveBeenCalledWith
(
'
/testing-issue-move
'
);
});
});
describe
(
'
shows dialog when issue has unsaved changed
'
,
()
=>
{
it
(
'
confirms on title change
'
,
()
=>
{
it
(
'
confirms on title change
'
,
async
()
=>
{
wrapper
.
vm
.
showForm
=
true
;
wrapper
.
vm
.
state
.
titleText
=
'
title has changed
'
;
const
e
=
{
returnValue
:
null
};
wrapper
.
vm
.
handleBeforeUnloadEvent
(
e
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
e
.
returnValue
).
not
.
toBeNull
();
});
});
it
(
'
confirms on description change
'
,
()
=>
{
it
(
'
confirms on description change
'
,
async
()
=>
{
wrapper
.
vm
.
showForm
=
true
;
wrapper
.
vm
.
state
.
descriptionText
=
'
description has changed
'
;
const
e
=
{
returnValue
:
null
};
wrapper
.
vm
.
handleBeforeUnloadEvent
(
e
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
e
.
returnValue
).
not
.
toBeNull
();
});
});
it
(
'
does nothing when nothing has changed
'
,
()
=>
{
it
(
'
does nothing when nothing has changed
'
,
async
()
=>
{
const
e
=
{
returnValue
:
null
};
wrapper
.
vm
.
handleBeforeUnloadEvent
(
e
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
e
.
returnValue
).
toBeNull
();
});
});
});
describe
(
'
error when updating
'
,
()
=>
{
it
(
'
closes form on error
'
,
()
=>
{
it
(
'
closes form on error
'
,
async
()
=>
{
jest
.
spyOn
(
wrapper
.
vm
.
service
,
'
updateIssuable
'
).
mockRejectedValue
();
return
wrapper
.
vm
.
updateIssuable
().
then
(()
=>
{
await
wrapper
.
vm
.
updateIssuable
();
expect
(
eventHub
.
$emit
).
not
.
toHaveBeenCalledWith
(
'
close.form
'
);
expect
(
document
.
querySelector
(
'
.flash-container .flash-text
'
).
innerText
.
trim
()).
toBe
(
`Error updating issue`
,
);
});
});
it
(
'
returns the correct error message for issuableType
'
,
()
=>
{
it
(
'
returns the correct error message for issuableType
'
,
async
()
=>
{
jest
.
spyOn
(
wrapper
.
vm
.
service
,
'
updateIssuable
'
).
mockRejectedValue
();
wrapper
.
setProps
({
issuableType
:
'
merge request
'
});
return
wrapper
.
vm
.
$nextTick
()
.
then
(
wrapper
.
vm
.
updateIssuable
)
.
then
(()
=>
{
await
nextTick
();
await
wrapper
.
vm
.
updateIssuable
();
expect
(
eventHub
.
$emit
).
not
.
toHaveBeenCalledWith
(
'
close.form
'
);
expect
(
document
.
querySelector
(
'
.flash-container .flash-text
'
).
innerText
.
trim
()).
toBe
(
`Error updating merge request`
,
);
});
});
it
(
'
shows error message from backend if exists
'
,
()
=>
{
it
(
'
shows error message from backend if exists
'
,
async
()
=>
{
const
msg
=
'
Custom error message from backend
'
;
jest
.
spyOn
(
wrapper
.
vm
.
service
,
'
updateIssuable
'
)
.
mockRejectedValue
({
response
:
{
data
:
{
errors
:
[
msg
]
}
}
});
return
wrapper
.
vm
.
updateIssuable
().
then
(()
=>
{
await
wrapper
.
vm
.
updateIssuable
();
expect
(
document
.
querySelector
(
'
.flash-container .flash-text
'
).
innerText
.
trim
()).
toBe
(
`
${
wrapper
.
vm
.
defaultErrorMessage
}
.
${
msg
}
`
,
);
});
});
});
});
describe
(
'
updateAndShowForm
'
,
()
=>
{
it
(
'
shows locked warning if form is open & data is different
'
,
()
=>
{
return
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
{
it
(
'
shows locked warning if form is open & data is different
'
,
async
()
=>
{
await
nextTick
();
wrapper
.
vm
.
updateAndShowForm
();
wrapper
.
vm
.
poll
.
makeRequest
();
return
new
Promise
((
resolve
)
=>
{
await
new
Promise
((
resolve
)
=>
{
wrapper
.
vm
.
$watch
(
'
formState.lockedWarningVisible
'
,
(
value
)
=>
{
if
(
value
)
{
resolve
();
}
});
});
})
.
then
(()
=>
{
expect
(
wrapper
.
vm
.
formState
.
lockedWarningVisible
).
toBe
(
true
);
expect
(
wrapper
.
vm
.
formState
.
lock_version
).
toBe
(
1
);
expect
(
findAlert
().
exists
()).
toBe
(
true
);
});
});
});
describe
(
'
requestTemplatesAndShowForm
'
,
()
=>
{
let
formSpy
;
...
...
@@ -398,14 +378,13 @@ describe('Issuable output', () => {
expect
(
wrapper
.
find
(
'
.btn-edit
'
).
exists
()).
toBe
(
true
);
});
it
(
'
should render if showInlineEditButton
'
,
()
=>
{
it
(
'
should render if showInlineEditButton
'
,
async
()
=>
{
wrapper
.
setProps
({
showInlineEditButton
:
true
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
'
.btn-edit
'
).
exists
()).
toBe
(
true
);
});
});
});
describe
(
'
updateStoreState
'
,
()
=>
{
it
(
'
should make a request and update the state of the store
'
,
()
=>
{
...
...
spec/frontend/issues/show/components/fields/type_spec.js
View file @
0d6b1f91
import
{
GlFormGroup
,
GlDropdown
,
GlDropdownItem
,
GlIcon
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
VueApollo
from
'
vue-apollo
'
;
import
{
nextTick
}
from
'
vue
'
;
import
createMockApollo
from
'
helpers/mock_apollo_helper
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
IssueTypeField
,
{
i18n
}
from
'
~/issues/show/components/fields/type.vue
'
;
...
...
@@ -93,7 +94,7 @@ describe('Issue type field component', () => {
it
(
'
updates the `issue_type` in the apollo cache when the value is changed
'
,
async
()
=>
{
findTypeFromDropDownItems
().
at
(
1
).
vm
.
$emit
(
'
click
'
,
issuableTypes
.
incident
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findTypeFromDropDown
().
attributes
(
'
value
'
)).
toBe
(
issuableTypes
.
incident
);
});
...
...
spec/frontend/issues/show/components/form_spec.js
View file @
0d6b1f91
import
{
GlAlert
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
Autosave
from
'
~/autosave
'
;
import
DescriptionTemplate
from
'
~/issues/show/components/fields/description_template.vue
'
;
import
IssueTypeField
from
'
~/issues/show/components/fields/type.vue
'
;
...
...
@@ -148,7 +149,7 @@ describe('Inline edit form component', () => {
formState
:
{
...
defaultProps
.
formState
,
lock_version
:
'
lock version from server
'
},
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findAlert
().
exists
()).
toBe
(
true
);
});
});
...
...
spec/frontend/issues/show/components/header_actions_spec.js
View file @
0d6b1f91
import
{
GlButton
,
GlDropdown
,
GlDropdownItem
,
GlLink
,
GlModal
}
from
'
@gitlab/ui
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vuex
from
'
vuex
'
;
import
{
mockTracking
}
from
'
helpers/tracking_helper
'
;
...
...
@@ -153,7 +153,7 @@ describe('HeaderActions component', () => {
it
(
'
dispatches a custom event to update the issue page
'
,
async
()
=>
{
findToggleIssueStateButton
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
dispatchEventSpy
).
toHaveBeenCalledTimes
(
1
);
});
...
...
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