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
8af0ee79
Commit
8af0ee79
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
62
Show whitespace changes
Inline
Side-by-side
Showing
62 changed files
with
845 additions
and
977 deletions
+845
-977
spec/frontend/jira_connect/branches/components/project_dropdown_spec.js
...jira_connect/branches/components/project_dropdown_spec.js
+2
-1
spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js
...s/components/add_namespace_modal/groups_list_item_spec.js
+2
-1
spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_spec.js
...ptions/components/add_namespace_modal/groups_list_spec.js
+4
-3
spec/frontend/jira_connect/subscriptions/components/app_spec.js
...rontend/jira_connect/subscriptions/components/app_spec.js
+5
-4
spec/frontend/jira_connect/subscriptions/components/subscriptions_list_spec.js
...nnect/subscriptions/components/subscriptions_list_spec.js
+2
-1
spec/frontend/jobs/components/job_app_spec.js
spec/frontend/jobs/components/job_app_spec.js
+6
-8
spec/frontend/jobs/components/job_container_item_spec.js
spec/frontend/jobs/components/job_container_item_spec.js
+2
-1
spec/frontend/jobs/components/job_log_controllers_spec.js
spec/frontend/jobs/components/job_log_controllers_spec.js
+5
-4
spec/frontend/jobs/components/log/collapsible_section_spec.js
.../frontend/jobs/components/log/collapsible_section_spec.js
+4
-4
spec/frontend/jobs/components/log/line_header_spec.js
spec/frontend/jobs/components/log/line_header_spec.js
+4
-4
spec/frontend/jobs/components/sidebar_spec.js
spec/frontend/jobs/components/sidebar_spec.js
+2
-1
spec/frontend/jobs/components/table/job_table_app_spec.js
spec/frontend/jobs/components/table/job_table_app_spec.js
+2
-1
spec/frontend/jobs/mixins/delayed_job_mixin_spec.js
spec/frontend/jobs/mixins/delayed_job_mixin_spec.js
+6
-5
spec/frontend/logs/components/environment_logs_spec.js
spec/frontend/logs/components/environment_logs_spec.js
+10
-12
spec/frontend/logs/components/log_control_buttons_spec.js
spec/frontend/logs/components/log_control_buttons_spec.js
+15
-16
spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
..._conflicts/components/merge_conflict_resolver_app_spec.js
+3
-3
spec/frontend/monitoring/components/charts/stacked_column_spec.js
...ntend/monitoring/components/charts/stacked_column_spec.js
+12
-13
spec/frontend/monitoring/components/charts/time_series_spec.js
...frontend/monitoring/components/charts/time_series_spec.js
+65
-77
spec/frontend/monitoring/components/create_dashboard_modal_spec.js
...tend/monitoring/components/create_dashboard_modal_spec.js
+5
-5
spec/frontend/monitoring/components/dashboard_actions_menu_spec.js
...tend/monitoring/components/dashboard_actions_menu_spec.js
+43
-57
spec/frontend/monitoring/components/dashboard_header_spec.js
spec/frontend/monitoring/components/dashboard_header_spec.js
+63
-80
spec/frontend/monitoring/components/dashboard_panel_builder_spec.js
...end/monitoring/components/dashboard_panel_builder_spec.js
+31
-36
spec/frontend/monitoring/components/dashboard_panel_spec.js
spec/frontend/monitoring/components/dashboard_panel_spec.js
+62
-75
spec/frontend/monitoring/components/dashboard_spec.js
spec/frontend/monitoring/components/dashboard_spec.js
+155
-186
spec/frontend/monitoring/components/dashboard_url_time_spec.js
...frontend/monitoring/components/dashboard_url_time_spec.js
+48
-53
spec/frontend/monitoring/components/embeds/embed_group_spec.js
...frontend/monitoring/components/embeds/embed_group_spec.js
+4
-6
spec/frontend/monitoring/components/graph_group_spec.js
spec/frontend/monitoring/components/graph_group_spec.js
+16
-19
spec/frontend/monitoring/components/links_section_spec.js
spec/frontend/monitoring/components/links_section_spec.js
+9
-11
spec/frontend/monitoring/components/refresh_button_spec.js
spec/frontend/monitoring/components/refresh_button_spec.js
+7
-6
spec/frontend/monitoring/components/variables/dropdown_field_spec.js
...nd/monitoring/components/variables/dropdown_field_spec.js
+4
-4
spec/frontend/monitoring/components/variables/text_field_spec.js
...ontend/monitoring/components/variables/text_field_spec.js
+10
-12
spec/frontend/monitoring/components/variables_section_spec.js
.../frontend/monitoring/components/variables_section_spec.js
+19
-20
spec/frontend/mr_popover/mr_popover_spec.js
spec/frontend/mr_popover/mr_popover_spec.js
+13
-16
spec/frontend/nav/components/responsive_app_spec.js
spec/frontend/nav/components/responsive_app_spec.js
+3
-2
spec/frontend/notes/components/comment_form_spec.js
spec/frontend/notes/components/comment_form_spec.js
+6
-6
spec/frontend/notes/components/diff_discussion_header_spec.js
.../frontend/notes/components/diff_discussion_header_spec.js
+23
-40
spec/frontend/notes/components/discussion_counter_spec.js
spec/frontend/notes/components/discussion_counter_spec.js
+9
-11
spec/frontend/notes/components/discussion_filter_spec.js
spec/frontend/notes/components/discussion_filter_spec.js
+19
-31
spec/frontend/notes/components/discussion_notes_spec.js
spec/frontend/notes/components/discussion_notes_spec.js
+13
-16
spec/frontend/notes/components/discussion_resolve_button_spec.js
...ontend/notes/components/discussion_resolve_button_spec.js
+8
-9
spec/frontend/notes/components/noteable_note_spec.js
spec/frontend/notes/components/noteable_note_spec.js
+11
-13
spec/frontend/notes/components/timeline_toggle_spec.js
spec/frontend/notes/components/timeline_toggle_spec.js
+5
-5
spec/frontend/notes/mixins/discussion_navigation_spec.js
spec/frontend/notes/mixins/discussion_navigation_spec.js
+9
-10
spec/frontend/notifications/components/custom_notifications_modal_spec.js
...tifications/components/custom_notifications_modal_spec.js
+4
-3
spec/frontend/operation_settings/components/metrics_settings_spec.js
...nd/operation_settings/components/metrics_settings_spec.js
+10
-11
spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js
...y/explorer/components/details_page/details_header_spec.js
+3
-2
spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/registry_header_spec.js
...try/explorer/components/list_page/registry_header_spec.js
+3
-2
spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/details_title_spec.js
...istry/components/details/components/details_title_spec.js
+6
-3
spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
...registry/components/list/components/packages_list_spec.js
+8
-10
spec/frontend/packages_and_registries/infrastructure_registry/components/shared/package_list_row_spec.js
...cture_registry/components/shared/package_list_row_spec.js
+2
-1
spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js
...package_registry/components/details/package_title_spec.js
+5
-4
spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js
...package_registry/components/list/package_list_row_spec.js
+2
-2
spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js
...stries/settings/group/components/package_settings_spec.js
+2
-1
spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js
...ettings/project/settings/components/settings_form_spec.js
+8
-7
spec/frontend/pages/admin/projects/components/namespace_select_spec.js
.../pages/admin/projects/components/namespace_select_spec.js
+4
-3
spec/frontend/pages/profiles/password_prompt/password_prompt_modal_spec.js
...es/profiles/password_prompt/password_prompt_modal_spec.js
+4
-3
spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
...end/pages/projects/forks/new/components/fork_form_spec.js
+6
-5
spec/frontend/pages/projects/graphs/code_coverage_spec.js
spec/frontend/pages/projects/graphs/code_coverage_spec.js
+3
-2
spec/frontend/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js
...chedules/shared/components/interval_pattern_input_spec.js
+7
-6
spec/frontend/pages/projects/pipeline_schedules/shared/components/pipeline_schedule_callout_spec.js
...dules/shared/components/pipeline_schedule_callout_spec.js
+4
-3
spec/frontend/pages/projects/shared/permissions/components/project_setting_row_spec.js
...shared/permissions/components/project_setting_row_spec.js
+15
-18
spec/frontend/pages/shared/wikis/components/wiki_form_spec.js
.../frontend/pages/shared/wikis/components/wiki_form_spec.js
+3
-3
No files found.
spec/frontend/jira_connect/branches/components/project_dropdown_spec.js
View file @
8af0ee79
import
{
GlDropdown
,
GlDropdownItem
,
GlLoadingIcon
,
GlSearchBoxByType
}
from
'
@gitlab/ui
'
;
import
{
mount
,
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
ProjectDropdown
from
'
~/jira_connect/branches/components/project_dropdown.vue
'
;
...
...
@@ -101,7 +102,7 @@ describe('ProjectDropdown', () => {
beforeEach
(
async
()
=>
{
createComponent
();
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
sets dropdown `loading` prop to `false`
'
,
()
=>
{
...
...
spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_item_spec.js
View file @
8af0ee79
import
{
GlButton
}
from
'
@gitlab/ui
'
;
import
{
mount
,
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
*
as
JiraConnectApi
from
'
~/jira_connect/subscriptions/api
'
;
...
...
@@ -63,7 +64,7 @@ describe('GroupsListItem', () => {
clickLinkButton
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findLinkButton
().
props
(
'
loading
'
)).
toBe
(
true
);
...
...
spec/frontend/jira_connect/subscriptions/components/add_namespace_modal/groups_list_spec.js
View file @
8af0ee79
import
{
GlAlert
,
GlLoadingIcon
,
GlSearchBoxByType
,
GlPagination
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
{
fetchGroups
}
from
'
~/jira_connect/subscriptions/api
'
;
...
...
@@ -61,7 +62,7 @@ describe('GroupsList', () => {
fetchGroups
.
mockReturnValue
(
new
Promise
(()
=>
{}));
createComponent
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findGlLoadingIcon
().
exists
()).
toBe
(
true
);
});
...
...
@@ -124,7 +125,7 @@ describe('GroupsList', () => {
findFirstItem
().
vm
.
$emit
(
'
error
'
,
errorMessage
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findGlAlert
().
exists
()).
toBe
(
true
);
expect
(
findGlAlert
().
text
()).
toContain
(
errorMessage
);
...
...
@@ -139,7 +140,7 @@ describe('GroupsList', () => {
fetchGroups
.
mockReturnValue
(
new
Promise
(()
=>
{}));
findSearchBox
().
vm
.
$emit
(
'
input
'
,
mockSearchTeam
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
calls `fetchGroups` with search term
'
,
()
=>
{
...
...
spec/frontend/jira_connect/subscriptions/components/app_spec.js
View file @
8af0ee79
import
{
GlAlert
,
GlLink
,
GlEmptyState
}
from
'
@gitlab/ui
'
;
import
{
mount
,
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
JiraConnectApp
from
'
~/jira_connect/subscriptions/components/app.vue
'
;
import
AddNamespaceButton
from
'
~/jira_connect/subscriptions/components/add_namespace_button.vue
'
;
import
SignInButton
from
'
~/jira_connect/subscriptions/components/sign_in_button.vue
'
;
...
...
@@ -116,7 +117,7 @@ describe('JiraConnectApp', () => {
createComponent
();
store
.
commit
(
SET_ALERT
,
{
message
,
variant
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
const
alert
=
findAlert
();
...
...
@@ -134,10 +135,10 @@ describe('JiraConnectApp', () => {
createComponent
();
store
.
commit
(
SET_ALERT
,
{
message
:
'
test message
'
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
findAlert
().
vm
.
$emit
(
'
dismiss
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findAlert
().
exists
()).
toBe
(
false
);
});
...
...
@@ -149,7 +150,7 @@ describe('JiraConnectApp', () => {
message
:
__
(
'
test message %{linkStart}test link%{linkEnd}
'
),
linkUrl
:
'
https://gitlab.com
'
,
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
const
alertLink
=
findAlertLink
();
...
...
spec/frontend/jira_connect/subscriptions/components/subscriptions_list_spec.js
View file @
8af0ee79
import
{
GlButton
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
*
as
JiraConnectApi
from
'
~/jira_connect/subscriptions/api
'
;
...
...
@@ -71,7 +72,7 @@ describe('SubscriptionsList', () => {
clickUnlinkButton
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findUnlinkButton
().
props
(
'
loading
'
)).
toBe
(
true
);
...
...
spec/frontend/jobs/components/job_app_spec.js
View file @
8af0ee79
import
{
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
delayedJobFixture
from
'
test_fixtures/jobs/delayed.json
'
;
...
...
@@ -45,7 +45,7 @@ describe('Job App', () => {
wrapper
=
mount
(
JobApp
,
{
propsData
:
{
...
props
},
store
});
};
const
setupAndMount
=
({
jobData
=
{},
jobLogData
=
{}
}
=
{})
=>
{
const
setupAndMount
=
async
({
jobData
=
{},
jobLogData
=
{}
}
=
{})
=>
{
mock
.
onGet
(
initSettings
.
endpoint
).
replyOnce
(
200
,
{
...
job
,
...
jobData
});
mock
.
onGet
(
`
${
initSettings
.
pagePath
}
/trace.json`
).
reply
(
200
,
jobLogData
);
...
...
@@ -53,12 +53,10 @@ describe('Job App', () => {
createComponent
();
return
asyncInit
.
then
(()
=>
{
await
asyncInit
;
jest
.
runOnlyPendingTimers
();
})
.
then
(()
=>
axios
.
waitForAll
())
.
then
(()
=>
wrapper
.
vm
.
$nextTick
());
await
axios
.
waitForAll
();
await
nextTick
();
};
const
findLoadingComponent
=
()
=>
wrapper
.
find
(
GlLoadingIcon
);
...
...
spec/frontend/jobs/components/job_container_item_spec.js
View file @
8af0ee79
import
{
GlIcon
,
GlLink
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
delayedJobFixture
from
'
test_fixtures/jobs/delayed.json
'
;
import
JobContainerItem
from
'
~/jobs/components/job_container_item.vue
'
;
import
CiIcon
from
'
~/vue_shared/components/ci_icon.vue
'
;
...
...
@@ -87,7 +88,7 @@ describe('JobContainerItem', () => {
});
it
(
'
displays remaining time in tooltip
'
,
async
()
=>
{
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
const
link
=
wrapper
.
findComponent
(
GlLink
);
...
...
spec/frontend/jobs/components/job_log_controllers_spec.js
View file @
8af0ee79
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
JobLogControllers
from
'
~/jobs/components/job_log_controllers.vue
'
;
describe
(
'
Job log controllers
'
,
()
=>
{
...
...
@@ -111,7 +112,7 @@ describe('Job log controllers', () => {
it
(
'
emits scrollJobLogTop event on click
'
,
async
()
=>
{
findScrollTop
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
emitted
().
scrollJobLogTop
).
toHaveLength
(
1
);
});
...
...
@@ -133,7 +134,7 @@ describe('Job log controllers', () => {
it
(
'
does not emit scrollJobLogTop event on click
'
,
async
()
=>
{
findScrollTop
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
emitted
().
scrollJobLogTop
).
toBeUndefined
();
});
...
...
@@ -149,7 +150,7 @@ describe('Job log controllers', () => {
it
(
'
emits scrollJobLogBottom event on click
'
,
async
()
=>
{
findScrollBottom
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
emitted
().
scrollJobLogBottom
).
toHaveLength
(
1
);
});
...
...
@@ -171,7 +172,7 @@ describe('Job log controllers', () => {
it
(
'
does not emit scrollJobLogBottom event on click
'
,
async
()
=>
{
findScrollBottom
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
emitted
().
scrollJobLogBottom
).
toBeUndefined
();
});
...
...
spec/frontend/jobs/components/log/collapsible_section_spec.js
View file @
8af0ee79
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
CollapsibleSection
from
'
~/jobs/components/log/collapsible_section.vue
'
;
import
{
collapsibleSectionClosed
,
collapsibleSectionOpened
}
from
'
./mock_data
'
;
...
...
@@ -69,7 +70,7 @@ describe('Job Log Collapsible Section', () => {
});
});
it
(
'
emits onClickCollapsibleLine on click
'
,
()
=>
{
it
(
'
emits onClickCollapsibleLine on click
'
,
async
()
=>
{
createComponent
({
section
:
collapsibleSectionOpened
,
jobLogEndpoint
,
...
...
@@ -77,8 +78,7 @@ describe('Job Log Collapsible Section', () => {
findCollapsibleLine
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
(
'
onClickCollapsibleLine
'
).
length
).
toBe
(
1
);
});
});
});
spec/frontend/jobs/components/log/line_header_spec.js
View file @
8af0ee79
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
DurationBadge
from
'
~/jobs/components/log/duration_badge.vue
'
;
import
LineHeader
from
'
~/jobs/components/log/line_header.vue
'
;
import
LineNumber
from
'
~/jobs/components/log/line_number.vue
'
;
...
...
@@ -75,14 +76,13 @@ describe('Job Log Header Line', () => {
createComponent
(
data
);
});
it
(
'
emits toggleLine event
'
,
()
=>
{
it
(
'
emits toggleLine event
'
,
async
()
=>
{
wrapper
.
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
().
toggleLine
.
length
).
toBe
(
1
);
});
});
});
describe
(
'
with duration
'
,
()
=>
{
beforeEach
(()
=>
{
...
...
spec/frontend/jobs/components/sidebar_spec.js
View file @
8af0ee79
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
ArtifactsBlock
from
'
~/jobs/components/artifacts_block.vue
'
;
import
JobRetryForwardDeploymentModal
from
'
~/jobs/components/job_retry_forward_deployment_modal.vue
'
;
...
...
@@ -189,7 +190,7 @@ describe('Sidebar details block', () => {
locked
:
false
,
};
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findArtifactsBlock
().
exists
()).
toBe
(
true
);
});
...
...
spec/frontend/jobs/components/table/job_table_app_spec.js
View file @
8af0ee79
import
{
GlSkeletonLoader
,
GlAlert
,
GlEmptyState
,
GlPagination
}
from
'
@gitlab/ui
'
;
import
{
createLocalVue
,
mount
,
shallowMount
}
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
getJobsQuery
from
'
~/jobs/components/table/graphql/queries/get_jobs.query.graphql
'
;
...
...
@@ -124,7 +125,7 @@ describe('Job table app', () => {
},
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findPrevious
().
exists
()).
toBe
(
true
);
expect
(
findNext
().
exists
()).
toBe
(
true
);
...
...
spec/frontend/jobs/mixins/delayed_job_mixin_spec.js
View file @
8af0ee79
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
delayedJobFixture
from
'
test_fixtures/jobs/delayed.json
'
;
import
delayedJobMixin
from
'
~/jobs/mixins/delayed_job_mixin
'
;
...
...
@@ -34,7 +35,7 @@ describe('DelayedJobMixin', () => {
});
it
(
'
does not update remaining time after mounting
'
,
async
()
=>
{
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
text
()).
toBe
(
'
00:00:00
'
);
});
...
...
@@ -57,7 +58,7 @@ describe('DelayedJobMixin', () => {
},
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
sets remaining time
'
,
()
=>
{
...
...
@@ -68,7 +69,7 @@ describe('DelayedJobMixin', () => {
remainingTimeInMilliseconds
=
41000
;
jest
.
advanceTimersByTime
(
1000
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
text
()).
toBe
(
'
00:00:41
'
);
});
});
...
...
@@ -104,7 +105,7 @@ describe('DelayedJobMixin', () => {
},
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
sets remaining time
'
,
()
=>
{
...
...
@@ -115,7 +116,7 @@ describe('DelayedJobMixin', () => {
remainingTimeInMilliseconds
=
41000
;
jest
.
advanceTimersByTime
(
1000
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
text
()).
toBe
(
'
00:00:41
'
);
});
});
...
...
spec/frontend/logs/components/environment_logs_spec.js
View file @
8af0ee79
import
{
GlSprintf
,
GlDropdown
,
GlDropdownItem
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
scrollDown
}
from
'
~/lib/utils/scroll_utils
'
;
import
EnvironmentLogs
from
'
~/logs/components/environment_logs.vue
'
;
...
...
@@ -338,35 +339,32 @@ describe('EnvironmentLogs', () => {
expect
(
store
.
dispatch
).
not
.
toHaveBeenCalledWith
(
`
${
module
}
/fetchMoreLogsPrepend`
,
undefined
);
});
it
(
'
`scroll` on a scrollable target results in enabled scroll buttons
'
,
()
=>
{
it
(
'
`scroll` on a scrollable target results in enabled scroll buttons
'
,
async
()
=>
{
const
target
=
{
scrollTop
:
10
,
clientHeight
:
10
,
scrollHeight
:
21
};
state
.
logs
.
isLoading
=
true
;
findInfiniteScroll
().
vm
.
$emit
(
'
scroll
'
,
{
target
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findLogControlButtons
().
props
(
'
scrollDownButtonDisabled
'
)).
toEqual
(
false
);
});
});
it
(
'
`scroll` on a non-scrollable target in disabled scroll buttons
'
,
()
=>
{
it
(
'
`scroll` on a non-scrollable target in disabled scroll buttons
'
,
async
()
=>
{
const
target
=
{
scrollTop
:
10
,
clientHeight
:
10
,
scrollHeight
:
20
};
state
.
logs
.
isLoading
=
true
;
findInfiniteScroll
().
vm
.
$emit
(
'
scroll
'
,
{
target
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findLogControlButtons
().
props
(
'
scrollDownButtonDisabled
'
)).
toEqual
(
true
);
});
});
it
(
'
`scroll` on no target results in disabled scroll buttons
'
,
()
=>
{
it
(
'
`scroll` on no target results in disabled scroll buttons
'
,
async
()
=>
{
state
.
logs
.
isLoading
=
true
;
findInfiniteScroll
().
vm
.
$emit
(
'
scroll
'
,
{
target
:
undefined
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findLogControlButtons
().
props
(
'
scrollDownButtonDisabled
'
)).
toEqual
(
true
);
});
});
});
});
spec/frontend/logs/components/log_control_buttons_spec.js
View file @
8af0ee79
import
{
GlButton
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
LogControlButtons
from
'
~/logs/components/log_control_buttons.vue
'
;
describe
(
'
LogControlButtons
'
,
()
=>
{
...
...
@@ -33,7 +34,7 @@ describe('LogControlButtons', () => {
expect
(
findRefreshBtn
().
is
(
GlButton
)).
toBe
(
true
);
});
it
(
'
emits a `refresh` event on click on `refresh` button
'
,
()
=>
{
it
(
'
emits a `refresh` event on click on `refresh` button
'
,
async
()
=>
{
initWrapper
();
// An `undefined` value means no event was emitted
...
...
@@ -41,16 +42,15 @@ describe('LogControlButtons', () => {
findRefreshBtn
().
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
(
'
refresh
'
)).
toHaveLength
(
1
);
});
});
describe
(
'
when scrolling actions are enabled
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
// mock scrolled to the middle of a long page
initWrapper
();
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
click on "scroll to top" scrolls up
'
,
()
=>
{
...
...
@@ -71,13 +71,13 @@ describe('LogControlButtons', () => {
});
describe
(
'
when scrolling actions are disabled
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
initWrapper
({
listeners
:
{}
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
buttons are disabled
'
,
()
=>
{
return
wrapper
.
vm
.
$nextTick
(()
=>
{
it
(
'
buttons are disabled
'
,
async
()
=>
{
await
nextTick
();
expect
(
findScrollToTop
().
exists
()).
toBe
(
false
);
expect
(
findScrollToBottom
().
exists
()).
toBe
(
false
);
// This should be enabled when gitlab-ui contains:
...
...
@@ -85,5 +85,4 @@ describe('LogControlButtons', () => {
// expect(findScrollToBottom().is('[disabled]')).toBe(true);
});
});
});
});
spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
View file @
8af0ee79
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
InlineConflictLines
from
'
~/merge_conflicts/components/inline_conflict_lines.vue
'
;
import
ParallelConflictLines
from
'
~/merge_conflicts/components/parallel_conflict_lines.vue
'
;
...
...
@@ -93,7 +93,7 @@ describe('Merge Conflict Resolver App', () => {
expect
(
inlineButton
.
props
(
'
selected
'
)).
toBe
(
false
);
inlineButton
.
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
inlineButton
.
props
(
'
selected
'
)).
toBe
(
true
);
});
...
...
@@ -111,7 +111,7 @@ describe('Merge Conflict Resolver App', () => {
mountComponent
();
findSideBySideButton
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
const
parallelConflictLinesComponent
=
findParallelConflictLines
(
findFiles
().
at
(
0
));
...
...
spec/frontend/monitoring/components/charts/stacked_column_spec.js
View file @
8af0ee79
...
...
@@ -2,6 +2,7 @@ import { GlStackedColumnChart, GlChartLegend } from '@gitlab/ui/dist/charts';
import
{
shallowMount
,
mount
}
from
'
@vue/test-utils
'
;
import
{
cloneDeep
}
from
'
lodash
'
;
import
timezoneMock
from
'
timezone-mock
'
;
import
{
nextTick
}
from
'
vue
'
;
import
StackedColumnChart
from
'
~/monitoring/components/charts/stacked_column.vue
'
;
import
{
stackedColumnGraphData
}
from
'
../../graph_data
'
;
...
...
@@ -34,9 +35,9 @@ describe('Stacked column chart component', () => {
});
describe
(
'
when graphData is present
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
createWrapper
();
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
chart is rendered
'
,
()
=>
{
...
...
@@ -116,25 +117,24 @@ describe('Stacked column chart component', () => {
expect
(
xAxis
.
axisLabel
.
formatter
(
'
2020-01-30T12:01:00.000Z
'
)).
toBe
(
'
4:01 AM
'
);
});
it
(
'
date is shown in UTC
'
,
()
=>
{
it
(
'
date is shown in UTC
'
,
async
()
=>
{
wrapper
.
setProps
({
timezone
:
'
UTC
'
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
const
{
xAxis
}
=
findChart
().
props
(
'
option
'
);
expect
(
xAxis
.
axisLabel
.
formatter
(
'
2020-01-30T12:01:00.000Z
'
)).
toBe
(
'
12:01 PM
'
);
});
});
});
});
describe
(
'
when graphData has results missing
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
const
graphData
=
cloneDeep
(
stackedColumnMockedData
);
graphData
.
metrics
[
0
].
result
=
null
;
createWrapper
({
graphData
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
chart is rendered
'
,
()
=>
{
...
...
@@ -147,7 +147,7 @@ describe('Stacked column chart component', () => {
wrapper
=
createWrapper
({},
mount
);
});
it
(
'
allows user to override legend label texts using props
'
,
()
=>
{
it
(
'
allows user to override legend label texts using props
'
,
async
()
=>
{
const
legendRelatedProps
=
{
legendMinText
:
'
legendMinText
'
,
legendMaxText
:
'
legendMaxText
'
,
...
...
@@ -158,10 +158,9 @@ describe('Stacked column chart component', () => {
...
legendRelatedProps
,
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findChart
().
props
()).
toMatchObject
(
legendRelatedProps
);
});
});
it
(
'
should render a tabular legend layout by default
'
,
()
=>
{
expect
(
findLegend
().
props
(
'
layout
'
)).
toBe
(
'
table
'
);
...
...
spec/frontend/monitoring/components/charts/time_series_spec.js
View file @
8af0ee79
...
...
@@ -7,6 +7,7 @@ import {
}
from
'
@gitlab/ui/dist/charts
'
;
import
{
mount
,
shallowMount
}
from
'
@vue/test-utils
'
;
import
timezoneMock
from
'
timezone-mock
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
import
{
setTestTimeout
}
from
'
helpers/timeout
'
;
import
{
shallowWrapperContainsSlotText
}
from
'
helpers/vue_test_utils_helper
'
;
...
...
@@ -70,12 +71,12 @@ describe('Time series component', () => {
describe
(
'
general functions
'
,
()
=>
{
const
findChart
=
()
=>
wrapper
.
find
({
ref
:
'
chart
'
});
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
createWrapper
({},
mount
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
allows user to override legend label texts using props
'
,
()
=>
{
it
(
'
allows user to override legend label texts using props
'
,
async
()
=>
{
const
legendRelatedProps
=
{
legendMinText
:
'
legendMinText
'
,
legendMaxText
:
'
legendMaxText
'
,
...
...
@@ -86,25 +87,23 @@ describe('Time series component', () => {
...
legendRelatedProps
,
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findChart
().
props
()).
toMatchObject
(
legendRelatedProps
);
});
});
it
(
'
chart sets a default height
'
,
()
=>
{
createWrapper
();
expect
(
wrapper
.
props
(
'
height
'
)).
toBe
(
chartHeight
);
});
it
(
'
chart has a configurable height
'
,
()
=>
{
it
(
'
chart has a configurable height
'
,
async
()
=>
{
const
mockHeight
=
599
;
createWrapper
();
wrapper
.
setProps
({
height
:
mockHeight
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
props
(
'
height
'
)).
toBe
(
mockHeight
);
});
});
describe
(
'
events
'
,
()
=>
{
describe
(
'
datazoom
'
,
()
=>
{
...
...
@@ -112,7 +111,7 @@ describe('Time series component', () => {
let
startValue
;
let
endValue
;
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
eChartMock
=
{
handlers
:
{},
getOption
:
()
=>
({
...
...
@@ -132,10 +131,9 @@ describe('Time series component', () => {
};
createWrapper
({},
mount
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
findChart
().
vm
.
$emit
(
'
created
'
,
eChartMock
);
});
});
it
(
'
handles datazoom event from chart
'
,
()
=>
{
startValue
=
1577836800000
;
// 2020-01-01T00:00:00.000Z
...
...
@@ -203,10 +201,10 @@ describe('Time series component', () => {
});
describe
(
'
when series is of line type
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
createWrapper
({},
mount
);
wrapper
.
vm
.
formatTooltipText
(
mockLineSeriesData
());
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
formats tooltip title
'
,
()
=>
{
...
...
@@ -241,34 +239,31 @@ describe('Time series component', () => {
timezoneMock
.
unregister
();
});
it
(
'
formats tooltip title in local timezone by default
'
,
()
=>
{
it
(
'
formats tooltip title in local timezone by default
'
,
async
()
=>
{
createWrapper
();
wrapper
.
vm
.
formatTooltipText
(
mockLineSeriesData
());
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
tooltip
.
title
).
toBe
(
'
16 Jul 2019, 3:14AM (GMT-0700)
'
);
});
});
it
(
'
formats tooltip title in local timezone
'
,
()
=>
{
it
(
'
formats tooltip title in local timezone
'
,
async
()
=>
{
createWrapper
({
timezone
:
'
LOCAL
'
});
wrapper
.
vm
.
formatTooltipText
(
mockLineSeriesData
());
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
tooltip
.
title
).
toBe
(
'
16 Jul 2019, 3:14AM (GMT-0700)
'
);
});
});
it
(
'
formats tooltip title in UTC format
'
,
()
=>
{
it
(
'
formats tooltip title in UTC format
'
,
async
()
=>
{
createWrapper
({
timezone
:
'
UTC
'
});
wrapper
.
vm
.
formatTooltipText
(
mockLineSeriesData
());
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
tooltip
.
title
).
toBe
(
'
16 Jul 2019, 10:14AM (UTC)
'
);
});
});
});
});
describe
(
'
when series is of scatter type, for deployments
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
wrapper
.
vm
.
formatTooltipText
({
...
mockAnnotationsSeriesData
,
seriesData
:
mockAnnotationsSeriesData
.
seriesData
.
map
((
data
)
=>
({
...
...
@@ -276,7 +271,7 @@ describe('Time series component', () => {
data
:
annotationsMetadata
,
})),
});
return
wrapper
.
vm
.
$nextTick
;
await
nextTick
()
;
});
it
(
'
set tooltip type to deployments
'
,
()
=>
{
...
...
@@ -297,9 +292,9 @@ describe('Time series component', () => {
});
describe
(
'
when series is of scatter type and deployments data is missing
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
wrapper
.
vm
.
formatTooltipText
(
mockAnnotationsSeriesData
);
return
wrapper
.
vm
.
$nextTick
;
await
nextTick
()
;
});
it
(
'
formats tooltip title
'
,
()
=>
{
...
...
@@ -397,16 +392,15 @@ describe('Time series component', () => {
});
});
it
(
'
is not set if time range is not set or incorrectly set
'
,
()
=>
{
it
(
'
is not set if time range is not set or incorrectly set
'
,
async
()
=>
{
wrapper
.
setProps
({
timeRange
:
{},
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
getChartOptions
().
xAxis
).
not
.
toHaveProperty
(
'
min
'
);
expect
(
getChartOptions
().
xAxis
).
not
.
toHaveProperty
(
'
max
'
);
});
});
});
describe
(
'
dataZoom
'
,
()
=>
{
it
(
'
renders with scroll handle icons
'
,
()
=>
{
...
...
@@ -430,17 +424,16 @@ describe('Time series component', () => {
option2
:
'
option2
'
,
};
it
(
'
arbitrary options
'
,
()
=>
{
it
(
'
arbitrary options
'
,
async
()
=>
{
wrapper
.
setProps
({
option
:
mockOption
,
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
getChartOptions
()).
toEqual
(
expect
.
objectContaining
(
mockOption
));
});
});
it
(
'
additional series
'
,
()
=>
{
it
(
'
additional series
'
,
async
()
=>
{
wrapper
.
setProps
({
option
:
{
series
:
[
...
...
@@ -453,15 +446,14 @@ describe('Time series component', () => {
},
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
const
optionSeries
=
getChartOptions
().
series
;
expect
(
optionSeries
.
length
).
toEqual
(
2
);
expect
(
optionSeries
[
0
].
name
).
toEqual
(
mockSeriesName
);
});
});
it
(
'
additional y-axis data
'
,
()
=>
{
it
(
'
additional y-axis data
'
,
async
()
=>
{
const
mockCustomYAxisOption
=
{
name
:
'
Custom y-axis label
'
,
axisLabel
:
{
...
...
@@ -475,14 +467,13 @@ describe('Time series component', () => {
},
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
const
{
yAxis
}
=
getChartOptions
();
expect
(
yAxis
[
0
]).
toMatchObject
(
mockCustomYAxisOption
);
});
});
it
(
'
additional x axis data
'
,
()
=>
{
it
(
'
additional x axis data
'
,
async
()
=>
{
const
mockCustomXAxisOption
=
{
name
:
'
Custom x axis label
'
,
};
...
...
@@ -493,13 +484,12 @@ describe('Time series component', () => {
},
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
const
{
xAxis
}
=
getChartOptions
();
expect
(
xAxis
).
toMatchObject
(
mockCustomXAxisOption
);
});
});
});
describe
(
'
yAxis formatter
'
,
()
=>
{
let
dataFormatter
;
...
...
@@ -625,12 +615,12 @@ describe('Time series component', () => {
describe
(
`GitLab UI:
${
dynamicComponent
.
chartType
}
`
,
()
=>
{
const
findChartComponent
=
()
=>
wrapper
.
find
(
dynamicComponent
.
component
);
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
createWrapper
(
{
graphData
:
timeSeriesGraphData
({
type
:
dynamicComponent
.
chartType
})
},
mount
,
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
exists
'
,
()
=>
{
...
...
@@ -645,22 +635,21 @@ describe('Time series component', () => {
expect
(
props
.
formatTooltipText
).
toBe
(
wrapper
.
vm
.
formatTooltipText
);
});
it
(
'
receives a tooltip title
'
,
()
=>
{
it
(
'
receives a tooltip title
'
,
async
()
=>
{
const
mockTitle
=
'
mockTitle
'
;
wrapper
.
vm
.
tooltip
.
title
=
mockTitle
;
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
shallowWrapperContainsSlotText
(
findChartComponent
(),
'
tooltip-title
'
,
mockTitle
),
).
toBe
(
true
);
});
});
describe
(
'
when tooltip is showing deployment data
'
,
()
=>
{
const
mockSha
=
'
mockSha
'
;
const
commitUrl
=
`
${
mockProjectDir
}
/-/commit/
${
mockSha
}
`
;
beforeEach
(()
=>
{
beforeEach
(
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
({
...
...
@@ -668,7 +657,7 @@ describe('Time series component', () => {
type
:
'
deployments
'
,
},
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
uses deployment title
'
,
()
=>
{
...
...
@@ -677,11 +666,11 @@ describe('Time series component', () => {
).
toBe
(
true
);
});
it
(
'
renders clickable commit sha in tooltip content
'
,
()
=>
{
it
(
'
renders clickable commit sha in tooltip content
'
,
async
()
=>
{
wrapper
.
vm
.
tooltip
.
sha
=
mockSha
;
wrapper
.
vm
.
tooltip
.
commitUrl
=
commitUrl
;
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
const
commitLink
=
wrapper
.
find
(
GlLink
);
expect
(
shallowWrapperContainsSlotText
(
commitLink
,
'
default
'
,
mockSha
)).
toBe
(
true
);
...
...
@@ -692,15 +681,14 @@ describe('Time series component', () => {
});
});
});
});
describe
(
'
with multiple time series
'
,
()
=>
{
describe
(
'
General functions
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
const
graphData
=
timeSeriesGraphData
({
type
:
panelTypes
.
AREA_CHART
,
multiMetric
:
true
});
createWrapper
({
graphData
},
mount
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
describe
(
'
Color match
'
,
()
=>
{
...
...
@@ -742,9 +730,9 @@ describe('Time series component', () => {
describe
(
'
legend layout
'
,
()
=>
{
const
findLegend
=
()
=>
wrapper
.
find
(
GlChartLegend
);
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
createWrapper
({},
mount
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
should render a tabular legend layout by default
'
,
()
=>
{
...
...
spec/frontend/monitoring/components/create_dashboard_modal_spec.js
View file @
8af0ee79
import
{
GlModal
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
CreateDashboardModal
from
'
~/monitoring/components/create_dashboard_modal.vue
'
;
describe
(
'
Create dashboard modal
'
,
()
=>
{
...
...
@@ -32,14 +33,13 @@ describe('Create dashboard modal', () => {
wrapper
.
destroy
();
});
it
(
'
has button that links to the project url
'
,
()
=>
{
it
(
'
has button that links to the project url
'
,
async
()
=>
{
findRepoButton
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findRepoButton
().
exists
()).
toBe
(
true
);
expect
(
findRepoButton
().
attributes
(
'
href
'
)).
toBe
(
defaultProps
.
projectPath
);
});
});
it
(
'
has button that links to the docs
'
,
()
=>
{
expect
(
findDocsButton
().
exists
()).
toBe
(
true
);
...
...
spec/frontend/monitoring/components/dashboard_actions_menu_spec.js
View file @
8af0ee79
import
{
GlDropdownItem
,
GlModal
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
CustomMetricsFormFields
from
'
~/custom_metrics/components/custom_metrics_form_fields.vue
'
;
import
{
redirectTo
}
from
'
~/lib/utils/url_utility
'
;
import
ActionsMenu
from
'
~/monitoring/components/dashboard_actions_menu.vue
'
;
...
...
@@ -60,23 +61,21 @@ describe('Actions menu', () => {
});
describe
(
'
add metric item
'
,
()
=>
{
it
(
'
is rendered when custom metrics are available
'
,
()
=>
{
it
(
'
is rendered when custom metrics are available
'
,
async
()
=>
{
createShallowWrapper
();
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findAddMetricItem
().
exists
()).
toBe
(
true
);
});
});
it
(
'
is not rendered when custom metrics are not available
'
,
()
=>
{
it
(
'
is not rendered when custom metrics are not available
'
,
async
()
=>
{
createShallowWrapper
({
addingMetricsAvailable
:
false
,
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findAddMetricItem
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
when available
'
,
()
=>
{
beforeEach
(()
=>
{
...
...
@@ -119,30 +118,23 @@ describe('Actions menu', () => {
origPage
=
document
.
body
.
dataset
.
page
;
document
.
body
.
dataset
.
page
=
'
projects:environments:metrics
'
;
wrapper
.
vm
.
$
nextTick
(
done
);
nextTick
(
done
);
});
afterEach
(()
=>
{
document
.
body
.
dataset
.
page
=
origPage
;
});
it
(
'
is tracked
'
,
(
done
)
=>
{
it
(
'
is tracked
'
,
async
(
)
=>
{
const
submitButton
=
findAddMetricModalSubmitButton
().
vm
;
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
submitButton
.
$el
.
click
();
wrapper
.
vm
.
$nextTick
(()
=>
{
expect
(
Tracking
.
event
).
toHaveBeenCalledWith
(
document
.
body
.
dataset
.
page
,
'
click_button
'
,
{
await
nextTick
();
expect
(
Tracking
.
event
).
toHaveBeenCalledWith
(
document
.
body
.
dataset
.
page
,
'
click_button
'
,
{
label
:
'
add_new_metric
'
,
property
:
'
modal
'
,
value
:
undefined
,
},
);
done
();
});
});
});
});
...
...
@@ -172,15 +164,14 @@ describe('Actions menu', () => {
);
});
it
(
'
is disabled for ootb dashboards
'
,
()
=>
{
it
(
'
is disabled for ootb dashboards
'
,
async
()
=>
{
createShallowWrapper
({
isOotbDashboard
:
true
,
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findAddPanelItemDisabled
().
exists
()).
toBe
(
true
);
});
});
it
(
'
is visible for custom dashboards
'
,
()
=>
{
expect
(
findAddPanelItemEnabled
().
exists
()).
toBe
(
true
);
...
...
@@ -256,18 +247,17 @@ describe('Actions menu', () => {
expect
(
findDuplicateDashboardModal
().
exists
()).
toBe
(
true
);
});
it
(
'
clicking on item opens up the duplicate dashboard modal
'
,
()
=>
{
it
(
'
clicking on item opens up the duplicate dashboard modal
'
,
async
()
=>
{
const
modalId
=
'
duplicateDashboard
'
;
const
modalTrigger
=
findDuplicateDashboardItem
();
const
rootEmit
=
jest
.
spyOn
(
wrapper
.
vm
.
$root
,
'
$emit
'
);
modalTrigger
.
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
rootEmit
.
mock
.
calls
[
0
]).
toContainEqual
(
modalId
);
});
});
});
describe
(
'
when current dashboard is custom
'
,
()
=>
{
beforeEach
(()
=>
{
...
...
@@ -300,19 +290,18 @@ describe('Actions menu', () => {
setupAllDashboards
(
store
,
dashboardGitResponse
[
0
].
path
);
});
it
(
'
redirects to the newly created dashboard
'
,
()
=>
{
it
(
'
redirects to the newly created dashboard
'
,
async
()
=>
{
const
newDashboard
=
dashboardGitResponse
[
1
];
const
newDashboardUrl
=
'
root/sandbox/-/metrics/dashboard.yml
'
;
findDuplicateDashboardModal
().
vm
.
$emit
(
'
dashboardDuplicated
'
,
newDashboard
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
redirectTo
).
toHaveBeenCalled
();
expect
(
redirectTo
).
toHaveBeenCalledWith
(
newDashboardUrl
);
});
});
});
});
describe
(
'
star dashboard item
'
,
()
=>
{
beforeEach
(()
=>
{
...
...
@@ -330,32 +319,30 @@ describe('Actions menu', () => {
expect
(
findStarDashboardItem
().
attributes
(
'
disabled
'
)).
toBeFalsy
();
});
it
(
'
is disabled when starring is taking place
'
,
()
=>
{
it
(
'
is disabled when starring is taking place
'
,
async
()
=>
{
store
.
commit
(
`monitoringDashboard/
${
types
.
REQUEST_DASHBOARD_STARRING
}
`
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findStarDashboardItem
().
exists
()).
toBe
(
true
);
expect
(
findStarDashboardItem
().
attributes
(
'
disabled
'
)).
toBe
(
'
true
'
);
});
});
it
(
'
on click it dispatches a toggle star action
'
,
()
=>
{
it
(
'
on click it dispatches a toggle star action
'
,
async
()
=>
{
findStarDashboardItem
().
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
monitoringDashboard/toggleStarredValue
'
,
undefined
,
);
});
});
describe
(
'
when dashboard is not starred
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
store
.
commit
(
`monitoringDashboard/
${
types
.
SET_INITIAL_STATE
}
`
,
{
currentDashboard
:
dashboardGitResponse
[
0
].
path
,
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
item text shows "Star dashboard"
'
,
()
=>
{
...
...
@@ -364,11 +351,11 @@ describe('Actions menu', () => {
});
describe
(
'
when dashboard is starred
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
store
.
commit
(
`monitoringDashboard/
${
types
.
SET_INITIAL_STATE
}
`
,
{
currentDashboard
:
dashboardGitResponse
[
1
].
path
,
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
item text shows "Unstar dashboard"
'
,
()
=>
{
...
...
@@ -403,17 +390,16 @@ describe('Actions menu', () => {
expect
(
findCreateDashboardModal
().
exists
()).
toBe
(
true
);
});
it
(
'
clicking opens up the modal
'
,
()
=>
{
it
(
'
clicking opens up the modal
'
,
async
()
=>
{
const
modalId
=
'
createDashboard
'
;
const
modalTrigger
=
findCreateDashboardItem
();
const
rootEmit
=
jest
.
spyOn
(
wrapper
.
vm
.
$root
,
'
$emit
'
);
modalTrigger
.
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
rootEmit
.
mock
.
calls
[
0
]).
toContainEqual
(
modalId
);
});
});
it
(
'
modal gets passed correct props
'
,
()
=>
{
expect
(
findCreateDashboardModal
().
props
(
'
projectPath
'
)).
toBe
(
mockProjectPath
);
...
...
spec/frontend/monitoring/components/dashboard_header_spec.js
View file @
8af0ee79
import
{
GlDropdownItem
,
GlSearchBoxByType
,
GlLoadingIcon
,
GlButton
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
redirectTo
}
from
'
~/lib/utils/url_utility
'
;
import
ActionsMenu
from
'
~/monitoring/components/dashboard_actions_menu.vue
'
;
import
DashboardHeader
from
'
~/monitoring/components/dashboard_header.vue
'
;
...
...
@@ -110,9 +111,9 @@ describe('Dashboard header', () => {
});
describe
(
'
when environments data is not loaded
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
setupStoreWithDashboard
(
store
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
there are no environments listed
'
,
()
=>
{
...
...
@@ -124,13 +125,13 @@ describe('Dashboard header', () => {
const
currentDashboard
=
dashboardGitResponse
[
0
].
path
;
const
currentEnvironmentName
=
environmentData
[
0
].
name
;
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
setupStoreWithData
(
store
);
store
.
state
.
monitoringDashboard
.
projectPath
=
mockProjectPath
;
store
.
state
.
monitoringDashboard
.
currentDashboard
=
currentDashboard
;
store
.
state
.
monitoringDashboard
.
currentEnvironmentName
=
currentEnvironmentName
;
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
renders dropdown items with the environment name
'
,
()
=>
{
...
...
@@ -159,54 +160,44 @@ describe('Dashboard header', () => {
expect
(
selectedItems
.
at
(
0
).
text
()).
toBe
(
currentEnvironmentName
);
});
it
(
'
filters rendered dropdown items
'
,
()
=>
{
it
(
'
filters rendered dropdown items
'
,
async
()
=>
{
const
searchTerm
=
'
production
'
;
const
resultEnvs
=
environmentData
.
filter
(({
name
})
=>
name
.
indexOf
(
searchTerm
)
!==
-
1
);
setSearchTerm
(
searchTerm
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findEnvsDropdownItems
()).
toHaveLength
(
resultEnvs
.
length
);
});
});
it
(
'
does not filter dropdown items if search term is empty string
'
,
()
=>
{
it
(
'
does not filter dropdown items if search term is empty string
'
,
async
()
=>
{
const
searchTerm
=
''
;
setSearchTerm
(
searchTerm
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findEnvsDropdownItems
()).
toHaveLength
(
environmentData
.
length
);
});
});
it
(
"
shows error message if search term doesn't match
"
,
()
=>
{
it
(
"
shows error message if search term doesn't match
"
,
async
()
=>
{
const
searchTerm
=
'
does-not-exist
'
;
setSearchTerm
(
searchTerm
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findEnvsDropdownSearchMsg
().
isVisible
()).
toBe
(
true
);
});
});
it
(
'
shows loading element when environments fetch is still loading
'
,
()
=>
{
it
(
'
shows loading element when environments fetch is still loading
'
,
async
()
=>
{
store
.
commit
(
`monitoringDashboard/
${
types
.
REQUEST_ENVIRONMENTS_DATA
}
`
);
return
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
{
await
nextTick
();
expect
(
findEnvsDropdownLoadingIcon
().
exists
()).
toBe
(
true
);
})
.
then
(()
=>
{
store
.
commit
(
await
store
.
commit
(
`monitoringDashboard/
${
types
.
RECEIVE_ENVIRONMENTS_DATA_SUCCESS
}
`
,
environmentData
,
);
})
.
then
(()
=>
{
expect
(
findEnvsDropdownLoadingIcon
().
exists
()).
toBe
(
false
);
});
});
});
});
describe
(
'
date time picker
'
,
()
=>
{
beforeEach
(()
=>
{
...
...
@@ -262,11 +253,11 @@ describe('Dashboard header', () => {
});
describe
(
'
external dashboard link
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
store
.
state
.
monitoringDashboard
.
externalDashboardUrl
=
'
/mockUrl
'
;
createShallowWrapper
();
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
shows the link
'
,
()
=>
{
...
...
@@ -295,84 +286,80 @@ describe('Dashboard header', () => {
});
describe
(
'
adding metrics prop
'
,
()
=>
{
it
.
each
(
ootbDashboards
)(
'
gets passed true if current dashboard is OOTB
'
,
(
dashboardPath
)
=>
{
it
.
each
(
ootbDashboards
)(
'
gets passed true if current dashboard is OOTB
'
,
async
(
dashboardPath
)
=>
{
createShallowWrapper
({
customMetricsAvailable
:
true
});
store
.
state
.
monitoringDashboard
.
emptyState
=
false
;
setupAllDashboards
(
store
,
dashboardPath
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findActionsMenu
().
props
(
'
addingMetricsAvailable
'
)).
toBe
(
true
);
}
);
}
);
}
,
);
it
.
each
(
customDashboards
)(
'
gets passed false if current dashboard is custom
'
,
(
dashboardPath
)
=>
{
async
(
dashboardPath
)
=>
{
createShallowWrapper
({
customMetricsAvailable
:
true
});
store
.
state
.
monitoringDashboard
.
emptyState
=
false
;
setupAllDashboards
(
store
,
dashboardPath
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findActionsMenu
().
props
(
'
addingMetricsAvailable
'
)).
toBe
(
false
);
});
},
);
it
(
'
gets passed false if empty state is shown
'
,
()
=>
{
it
(
'
gets passed false if empty state is shown
'
,
async
()
=>
{
createShallowWrapper
({
customMetricsAvailable
:
true
});
store
.
state
.
monitoringDashboard
.
emptyState
=
true
;
setupAllDashboards
(
store
,
ootbDashboards
[
0
]);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findActionsMenu
().
props
(
'
addingMetricsAvailable
'
)).
toBe
(
false
);
});
});
it
(
'
gets passed false if custom metrics are not available
'
,
()
=>
{
it
(
'
gets passed false if custom metrics are not available
'
,
async
()
=>
{
createShallowWrapper
({
customMetricsAvailable
:
false
});
store
.
state
.
monitoringDashboard
.
emptyState
=
false
;
setupAllDashboards
(
store
,
ootbDashboards
[
0
]);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findActionsMenu
().
props
(
'
addingMetricsAvailable
'
)).
toBe
(
false
);
});
});
});
it
(
'
custom metrics path gets passed
'
,
()
=>
{
it
(
'
custom metrics path gets passed
'
,
async
()
=>
{
const
path
=
'
https://path/to/customMetrics
'
;
createShallowWrapper
({
customMetricsPath
:
path
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findActionsMenu
().
props
(
'
customMetricsPath
'
)).
toBe
(
path
);
});
});
it
(
'
validate query path gets passed
'
,
()
=>
{
it
(
'
validate query path gets passed
'
,
async
()
=>
{
const
path
=
'
https://path/to/validateQuery
'
;
createShallowWrapper
({
validateQueryPath
:
path
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findActionsMenu
().
props
(
'
validateQueryPath
'
)).
toBe
(
path
);
});
});
it
(
'
default branch gets passed
'
,
()
=>
{
it
(
'
default branch gets passed
'
,
async
()
=>
{
const
branch
=
'
branchName
'
;
createShallowWrapper
({
defaultBranch
:
branch
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findActionsMenu
().
props
(
'
defaultBranch
'
)).
toBe
(
branch
);
});
});
});
describe
(
'
metrics settings button
'
,
()
=>
{
const
findSettingsButton
=
()
=>
wrapper
.
find
(
'
[data-testid="metrics-settings-button"]
'
);
...
...
@@ -385,40 +372,36 @@ describe('Dashboard header', () => {
store
.
state
.
monitoringDashboard
.
operationsSettingsPath
=
''
;
});
it
(
'
is rendered when the user can access the project settings and path to settings is available
'
,
()
=>
{
it
(
'
is rendered when the user can access the project settings and path to settings is available
'
,
async
()
=>
{
store
.
state
.
monitoringDashboard
.
canAccessOperationsSettings
=
true
;
store
.
state
.
monitoringDashboard
.
operationsSettingsPath
=
url
;
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findSettingsButton
().
exists
()).
toBe
(
true
);
});
});
it
(
'
is not rendered when the user can not access the project settings
'
,
()
=>
{
it
(
'
is not rendered when the user can not access the project settings
'
,
async
()
=>
{
store
.
state
.
monitoringDashboard
.
canAccessOperationsSettings
=
false
;
store
.
state
.
monitoringDashboard
.
operationsSettingsPath
=
url
;
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findSettingsButton
().
exists
()).
toBe
(
false
);
});
});
it
(
'
is not rendered when the path to settings is unavailable
'
,
()
=>
{
it
(
'
is not rendered when the path to settings is unavailable
'
,
async
()
=>
{
store
.
state
.
monitoringDashboard
.
canAccessOperationsSettings
=
false
;
store
.
state
.
monitoringDashboard
.
operationsSettingsPath
=
''
;
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findSettingsButton
().
exists
()).
toBe
(
false
);
});
});
it
(
'
leads to the project settings page
'
,
()
=>
{
it
(
'
leads to the project settings page
'
,
async
()
=>
{
store
.
state
.
monitoringDashboard
.
canAccessOperationsSettings
=
true
;
store
.
state
.
monitoringDashboard
.
operationsSettingsPath
=
url
;
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findSettingsButton
().
attributes
(
'
href
'
)).
toBe
(
url
);
});
});
});
});
spec/frontend/monitoring/components/dashboard_panel_builder_spec.js
View file @
8af0ee79
import
{
GlCard
,
GlForm
,
GlFormTextarea
,
GlAlert
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
DashboardPanel
from
'
~/monitoring/components/dashboard_panel.vue
'
;
import
DashboardPanelBuilder
from
'
~/monitoring/components/dashboard_panel_builder.vue
'
;
import
{
createStore
}
from
'
~/monitoring/stores
'
;
...
...
@@ -90,21 +91,20 @@ describe('dashboard invalid url parameters', () => {
expect
(
mockShowToast
).
toHaveBeenCalledTimes
(
1
);
});
it
(
'
on submit fetches a panel preview
'
,
()
=>
{
it
(
'
on submit fetches a panel preview
'
,
async
()
=>
{
findForm
().
vm
.
$emit
(
'
submit
'
,
new
Event
(
'
submit
'
));
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
monitoringDashboard/fetchPanelPreview
'
,
expect
.
stringContaining
(
'
title:
'
),
);
});
});
describe
(
'
when form is submitted
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
store
.
commit
(
`monitoringDashboard/
${
types
.
REQUEST_PANEL_PREVIEW
}
`
,
'
mock yml content
'
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
submit button is disabled
'
,
()
=>
{
...
...
@@ -118,54 +118,50 @@ describe('dashboard invalid url parameters', () => {
expect
(
findTimeRangePicker
().
exists
()).
toBe
(
true
);
});
it
(
'
when changed does not trigger data fetch unless preview panel button is clicked
'
,
()
=>
{
it
(
'
when changed does not trigger data fetch unless preview panel button is clicked
'
,
async
()
=>
{
// mimic initial state where SET_PANEL_PREVIEW_IS_SHOWN is set to false
store
.
commit
(
`monitoringDashboard/
${
types
.
SET_PANEL_PREVIEW_IS_SHOWN
}
`
,
false
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
store
.
dispatch
).
not
.
toHaveBeenCalled
();
});
});
it
(
'
when changed triggers data fetch if preview panel button is clicked
'
,
()
=>
{
it
(
'
when changed triggers data fetch if preview panel button is clicked
'
,
async
()
=>
{
findForm
().
vm
.
$emit
(
'
submit
'
,
new
Event
(
'
submit
'
));
store
.
commit
(
`monitoringDashboard/
${
types
.
SET_PANEL_PREVIEW_TIME_RANGE
}
`
,
mockTimeRange
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
store
.
dispatch
).
toHaveBeenCalled
();
});
});
});
describe
(
'
refresh
'
,
()
=>
{
it
(
'
is visible by default
'
,
()
=>
{
expect
(
findRefreshButton
().
exists
()).
toBe
(
true
);
});
it
(
'
when clicked does not trigger data fetch unless preview panel button is clicked
'
,
()
=>
{
it
(
'
when clicked does not trigger data fetch unless preview panel button is clicked
'
,
async
()
=>
{
// mimic initial state where SET_PANEL_PREVIEW_IS_SHOWN is set to false
store
.
commit
(
`monitoringDashboard/
${
types
.
SET_PANEL_PREVIEW_IS_SHOWN
}
`
,
false
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
store
.
dispatch
).
not
.
toHaveBeenCalled
();
});
});
it
(
'
when clicked triggers data fetch if preview panel button is clicked
'
,
()
=>
{
it
(
'
when clicked triggers data fetch if preview panel button is clicked
'
,
async
()
=>
{
// mimic state where preview is visible. SET_PANEL_PREVIEW_IS_SHOWN is set to true
store
.
commit
(
`monitoringDashboard/
${
types
.
SET_PANEL_PREVIEW_IS_SHOWN
}
`
,
true
);
findRefreshButton
().
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
monitoringDashboard/fetchPanelPreviewMetrics
'
,
undefined
,
);
});
});
});
describe
(
'
instructions card
'
,
()
=>
{
const
mockDocsPath
=
'
/docs-path
'
;
...
...
@@ -190,9 +186,9 @@ describe('dashboard invalid url parameters', () => {
describe
(
'
when there is an error
'
,
()
=>
{
const
mockError
=
'
an error occurred!
'
;
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
store
.
commit
(
`monitoringDashboard/
${
types
.
RECEIVE_PANEL_PREVIEW_FAILURE
}
`
,
mockError
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
displays an alert
'
,
()
=>
{
...
...
@@ -204,19 +200,18 @@ describe('dashboard invalid url parameters', () => {
expect
(
findPanel
().
props
(
'
graphData
'
)).
toBe
(
null
);
});
it
(
'
changing time range should not refetch data
'
,
()
=>
{
it
(
'
changing time range should not refetch data
'
,
async
()
=>
{
store
.
commit
(
`monitoringDashboard/
${
types
.
SET_PANEL_PREVIEW_TIME_RANGE
}
`
,
mockTimeRange
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
store
.
dispatch
).
not
.
toHaveBeenCalled
();
});
});
});
describe
(
'
when panel data is available
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
store
.
commit
(
`monitoringDashboard/
${
types
.
RECEIVE_PANEL_PREVIEW_SUCCESS
}
`
,
mockPanel
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
displays no alert
'
,
()
=>
{
...
...
spec/frontend/monitoring/components/dashboard_panel_spec.js
View file @
8af0ee79
...
...
@@ -2,6 +2,7 @@ import { GlDropdownItem } from '@gitlab/ui';
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
AxiosMockAdapter
from
'
axios-mock-adapter
'
;
import
Vuex
from
'
vuex
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
setTestTimeout
}
from
'
helpers/timeout
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
invalidUrl
from
'
~/lib/utils/invalid_url
'
;
...
...
@@ -186,7 +187,7 @@ describe('Dashboard Panel', () => {
expect
(
findCopyLink
().
exists
()).
toBe
(
false
);
});
it
(
'
should emit `timerange` event when a zooming in/out in a chart occcurs
'
,
()
=>
{
it
(
'
should emit `timerange` event when a zooming in/out in a chart occcurs
'
,
async
()
=>
{
const
timeRange
=
{
start
:
'
2020-01-01T00:00:00.000Z
'
,
end
:
'
2020-01-01T01:00:00.000Z
'
,
...
...
@@ -196,10 +197,9 @@ describe('Dashboard Panel', () => {
findTimeChart
().
vm
.
$emit
(
'
datazoom
'
,
timeRange
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
$emit
).
toHaveBeenCalledWith
(
'
timerangezoom
'
,
timeRange
);
});
});
it
(
'
includes a default group id
'
,
()
=>
{
expect
(
wrapper
.
vm
.
groupId
).
toBe
(
'
dashboard-panel
'
);
...
...
@@ -253,9 +253,9 @@ describe('Dashboard Panel', () => {
describe
(
'
computed
'
,
()
=>
{
describe
(
'
fixedCurrentTimeRange
'
,
()
=>
{
it
(
'
returns fixed time for valid time range
'
,
()
=>
{
it
(
'
returns fixed time for valid time range
'
,
async
()
=>
{
state
.
timeRange
=
mockTimeRange
;
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findTimeChart
().
props
(
'
timeRange
'
)).
toEqual
(
expect
.
objectContaining
({
start
:
expect
.
any
(
String
),
...
...
@@ -263,7 +263,6 @@ describe('Dashboard Panel', () => {
}),
);
});
});
it
.
each
`
input | output
...
...
@@ -271,31 +270,29 @@ describe('Dashboard Panel', () => {
$
{
undefined
}
|
${{}}
$
{
null
}
|
${{}}
$
{
'
2020-12-03
'
}
|
${{}}
`('returns $output for invalid input like $input', ({ input, output }) => {
`('returns $output for invalid input like $input',
async
({ input, output }) => {
state.timeRange = input;
return wrapper.vm.$nextTick(() => {
await nextTick();
expect(findTimeChart().props('timeRange')).toEqual(output);
});
});
});
});
});
describe('Edit custom metric dropdown item', () => {
const findEditCustomMetricLink = () => wrapper.find({ ref: 'editMetricLink' });
const mockEditPath = '/root/kubernetes-gke-project/prometheus/metrics/23/edit';
beforeEach(() => {
beforeEach(
async
() => {
createWrapper();
return wrapper.vm.$nextTick();
await nextTick();
});
it('is not present if the panel is not a custom metric', () => {
expect(findEditCustomMetricLink().exists()).toBe(false);
});
it('is present when the panel contains an edit_path property', () => {
it('is present when the panel contains an edit_path property',
async
() => {
wrapper.setProps({
graphData: {
...graphData,
...
...
@@ -308,14 +305,13 @@ describe('Dashboard Panel', () => {
},
});
return wrapper.vm.$nextTick(() => {
await nextTick();
expect(findEditCustomMetricLink().exists()).toBe(true);
expect(findEditCustomMetricLink().text()).toBe('Edit metric');
expect(findEditCustomMetricLink().attributes('href')).toBe(mockEditPath);
});
});
it('shows an "Edit metrics" link pointing to settingsPath for a panel with multiple metrics', () => {
it('shows an "Edit metrics" link pointing to settingsPath for a panel with multiple metrics',
async
() => {
wrapper.setProps({
graphData: {
...graphData,
...
...
@@ -332,63 +328,58 @@ describe('Dashboard Panel', () => {
},
});
return wrapper.vm.$nextTick(() => {
await nextTick();
expect(findEditCustomMetricLink().text()).toBe('Edit metrics');
expect(findEditCustomMetricLink().attributes('href')).toBe(dashboardProps.settingsPath);
});
});
});
describe('View Logs dropdown item', () => {
const findViewLogsLink = () => wrapper.find({ ref: 'viewLogsLink' });
beforeEach(() => {
beforeEach(
async
() => {
createWrapper();
return wrapper.vm.$
nextTick();
await
nextTick();
});
it('is not present by default',
() =>
wrapper.vm.$nextTick(() => {
it('is not present by default',
async () => {
await nextTick();
expect(findViewLogsLink().exists()).toBe(false);
})
);
}
);
it('is not present if a time range is not set', () => {
it('is not present if a time range is not set',
async
() => {
state.logsPath = mockLogsPath;
state.timeRange = null;
return wrapper.vm.$nextTick(() => {
await nextTick();
expect(findViewLogsLink().exists()).toBe(false);
});
});
it('is not present if the logs path is default', () => {
it('is not present if the logs path is default',
async
() => {
state.logsPath = invalidUrl;
state.timeRange = mockTimeRange;
return wrapper.vm.$nextTick(() => {
await nextTick();
expect(findViewLogsLink().exists()).toBe(false);
});
});
it('is not present if the logs path is not set', () => {
it('is not present if the logs path is not set',
async
() => {
state.logsPath = null;
state.timeRange = mockTimeRange;
return wrapper.vm.$nextTick(() => {
await nextTick();
expect(findViewLogsLink().exists()).toBe(false);
});
});
it('is present when logs path and time a range is present', () => {
it('is present when logs path and time a range is present',
async
() => {
state.logsPath = mockLogsPath;
state.timeRange = mockTimeRange;
return wrapper.vm.$nextTick(() => {
await nextTick();
expect(findViewLogsLink().attributes('href')).toMatch(mockLogsHref);
});
});
it('it is overridden when a datazoom event is received', () => {
it('it is overridden when a datazoom event is received',
async
() => {
state.logsPath = mockLogsPath;
state.timeRange = mockTimeRange;
...
...
@@ -399,7 +390,7 @@ describe('Dashboard Panel', () => {
findTimeChart().vm.$emit('datazoom', zoomedTimeRange);
return wrapper.vm.$nextTick(() => {
await nextTick();
const start = encodeURIComponent(zoomedTimeRange.start);
const end = encodeURIComponent(zoomedTimeRange.end);
expect(findViewLogsLink().attributes('href')).toMatch(
...
...
@@ -407,7 +398,6 @@ describe('Dashboard Panel', () => {
);
});
});
});
describe
(
'
when clipboard data is available
'
,
()
=>
{
const
clipboardText
=
'
A value to copy.
'
;
...
...
@@ -447,7 +437,7 @@ describe('Dashboard Panel', () => {
});
describe
(
'
when downloading metrics data as CSV
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
wrapper
=
shallowMount
(
DashboardPanel
,
{
propsData
:
{
clipboardText
:
exampleText
,
...
...
@@ -459,7 +449,7 @@ describe('Dashboard Panel', () => {
},
store
,
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
afterEach
(()
=>
{
...
...
@@ -509,30 +499,27 @@ describe('Dashboard Panel', () => {
});
});
it
(
'
handles namespaced time range and logs path state
'
,
()
=>
{
it
(
'
handles namespaced time range and logs path state
'
,
async
()
=>
{
store
.
state
[
mockNamespace
].
timeRange
=
mockTimeRange
;
store
.
state
[
mockNamespace
].
logsPath
=
mockLogsPath
;
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
({
ref
:
'
viewLogsLink
'
}).
attributes
().
href
).
toBe
(
mockLogsHref
);
});
});
it
(
'
handles namespaced deployment data state
'
,
()
=>
{
it
(
'
handles namespaced deployment data state
'
,
async
()
=>
{
store
.
state
[
mockNamespace
].
deploymentData
=
mockDeploymentData
;
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findTimeChart
().
props
().
deploymentData
).
toEqual
(
mockDeploymentData
);
});
});
it
(
'
handles namespaced project path state
'
,
()
=>
{
it
(
'
handles namespaced project path state
'
,
async
()
=>
{
store
.
state
[
mockNamespace
].
projectPath
=
mockProjectPath
;
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findTimeChart
().
props
().
projectPath
).
toBe
(
mockProjectPath
);
});
});
it
(
'
it renders a time series chart with no errors
'
,
()
=>
{
expect
(
wrapper
.
find
(
MonitorTimeSeriesChart
).
exists
()).
toBe
(
true
);
...
...
spec/frontend/monitoring/components/dashboard_spec.js
View file @
8af0ee79
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
VueDraggable
from
'
vuedraggable
'
;
import
{
nextTick
}
from
'
vue
'
;
import
setWindowLocation
from
'
helpers/set_window_location_helper
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
import
{
mountExtended
,
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
...
...
@@ -77,10 +78,10 @@ describe('Dashboard', () => {
});
describe
(
'
request information to the server
'
,
()
=>
{
it
(
'
calls to set time range and fetch data
'
,
()
=>
{
it
(
'
calls to set time range and fetch data
'
,
async
()
=>
{
createShallowWrapper
({
hasMetrics
:
true
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
monitoringDashboard/setTimeRange
'
,
expect
.
any
(
Object
),
...
...
@@ -88,34 +89,31 @@ describe('Dashboard', () => {
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
monitoringDashboard/fetchData
'
,
undefined
);
});
});
it
(
'
shows up a loading state
'
,
()
=>
{
it
(
'
shows up a loading state
'
,
async
()
=>
{
store
.
state
.
monitoringDashboard
.
emptyState
=
dashboardEmptyStates
.
LOADING
;
createShallowWrapper
({
hasMetrics
:
true
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
EmptyState
).
exists
()).
toBe
(
true
);
expect
(
wrapper
.
find
(
EmptyState
).
props
(
'
selectedState
'
)).
toBe
(
dashboardEmptyStates
.
LOADING
);
});
});
it
(
'
hides the group panels when showPanels is false
'
,
()
=>
{
it
(
'
hides the group panels when showPanels is false
'
,
async
()
=>
{
createMountedWrapper
({
hasMetrics
:
true
,
showPanels
:
false
});
setupStoreWithData
(
store
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
emptyState
).
toBeNull
();
expect
(
wrapper
.
findAll
(
'
.prometheus-panel
'
)).
toHaveLength
(
0
);
});
});
it
(
'
fetches the metrics data with proper time window
'
,
()
=>
{
it
(
'
fetches the metrics data with proper time window
'
,
async
()
=>
{
createMountedWrapper
({
hasMetrics
:
true
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
monitoringDashboard/fetchData
'
,
undefined
);
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
monitoringDashboard/setTimeRange
'
,
...
...
@@ -123,7 +121,6 @@ describe('Dashboard', () => {
);
});
});
});
describe
(
'
panel containers layout
'
,
()
=>
{
const
findPanelLayoutWrapperAt
=
(
index
)
=>
{
...
...
@@ -133,57 +130,52 @@ describe('Dashboard', () => {
.
at
(
index
);
};
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
createMountedWrapper
({
hasMetrics
:
true
});
return
wrapper
.
vm
.
$nextTick
();
await
nextTick
();
});
describe
(
'
when the graph group has an even number of panels
'
,
()
=>
{
it
(
'
2 panels - all panel wrappers take half width of their parent
'
,
()
=>
{
it
(
'
2 panels - all panel wrappers take half width of their parent
'
,
async
()
=>
{
setupStoreWithDataForPanelCount
(
store
,
2
);
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findPanelLayoutWrapperAt
(
0
).
classes
(
'
col-lg-6
'
)).
toBe
(
true
);
expect
(
findPanelLayoutWrapperAt
(
1
).
classes
(
'
col-lg-6
'
)).
toBe
(
true
);
});
});
it
(
'
4 panels - all panel wrappers take half width of their parent
'
,
()
=>
{
it
(
'
4 panels - all panel wrappers take half width of their parent
'
,
async
()
=>
{
setupStoreWithDataForPanelCount
(
store
,
4
);
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findPanelLayoutWrapperAt
(
0
).
classes
(
'
col-lg-6
'
)).
toBe
(
true
);
expect
(
findPanelLayoutWrapperAt
(
1
).
classes
(
'
col-lg-6
'
)).
toBe
(
true
);
expect
(
findPanelLayoutWrapperAt
(
2
).
classes
(
'
col-lg-6
'
)).
toBe
(
true
);
expect
(
findPanelLayoutWrapperAt
(
3
).
classes
(
'
col-lg-6
'
)).
toBe
(
true
);
});
});
});
describe
(
'
when the graph group has an odd number of panels
'
,
()
=>
{
it
(
'
1 panel - panel wrapper does not take half width of its parent
'
,
()
=>
{
it
(
'
1 panel - panel wrapper does not take half width of its parent
'
,
async
()
=>
{
setupStoreWithDataForPanelCount
(
store
,
1
);
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findPanelLayoutWrapperAt
(
0
).
classes
(
'
col-lg-6
'
)).
toBe
(
false
);
});
});
it
(
'
3 panels - all panels but last take half width of their parents
'
,
()
=>
{
it
(
'
3 panels - all panels but last take half width of their parents
'
,
async
()
=>
{
setupStoreWithDataForPanelCount
(
store
,
3
);
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findPanelLayoutWrapperAt
(
0
).
classes
(
'
col-lg-6
'
)).
toBe
(
true
);
expect
(
findPanelLayoutWrapperAt
(
1
).
classes
(
'
col-lg-6
'
)).
toBe
(
true
);
expect
(
findPanelLayoutWrapperAt
(
2
).
classes
(
'
col-lg-6
'
)).
toBe
(
false
);
});
});
it
(
'
5 panels - all panels but last take half width of their parents
'
,
()
=>
{
it
(
'
5 panels - all panels but last take half width of their parents
'
,
async
()
=>
{
setupStoreWithDataForPanelCount
(
store
,
5
);
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findPanelLayoutWrapperAt
(
0
).
classes
(
'
col-lg-6
'
)).
toBe
(
true
);
expect
(
findPanelLayoutWrapperAt
(
1
).
classes
(
'
col-lg-6
'
)).
toBe
(
true
);
expect
(
findPanelLayoutWrapperAt
(
2
).
classes
(
'
col-lg-6
'
)).
toBe
(
true
);
...
...
@@ -192,10 +184,9 @@ describe('Dashboard', () => {
});
});
});
});
describe
(
'
dashboard validation warning
'
,
()
=>
{
it
(
'
displays a warning if there are validation warnings
'
,
()
=>
{
it
(
'
displays a warning if there are validation warnings
'
,
async
()
=>
{
createMountedWrapper
({
hasMetrics
:
true
});
store
.
commit
(
...
...
@@ -203,12 +194,11 @@ describe('Dashboard', () => {
true
,
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
createFlash
).
toHaveBeenCalled
();
});
});
it
(
'
does not display a warning if there are no validation warnings
'
,
()
=>
{
it
(
'
does not display a warning if there are no validation warnings
'
,
async
()
=>
{
createMountedWrapper
({
hasMetrics
:
true
});
store
.
commit
(
...
...
@@ -216,11 +206,10 @@ describe('Dashboard', () => {
false
,
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
createFlash
).
not
.
toHaveBeenCalled
();
});
});
});
describe
(
'
when the URL contains a reference to a panel
'
,
()
=>
{
const
location
=
window
.
location
.
href
;
...
...
@@ -233,7 +222,7 @@ describe('Dashboard', () => {
setWindowLocation
(
location
);
});
it
(
'
when the URL points to a panel it expands
'
,
()
=>
{
it
(
'
when the URL points to a panel it expands
'
,
async
()
=>
{
const
panelGroup
=
metricsDashboardViewModel
.
panelGroups
[
0
];
const
panel
=
panelGroup
.
panels
[
0
];
...
...
@@ -246,7 +235,7 @@ describe('Dashboard', () => {
createMountedWrapper
({
hasMetrics
:
true
});
setupStoreWithData
(
store
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
monitoringDashboard/setExpandedPanel
'
,
{
group
:
panelGroup
.
group
,
panel
:
expect
.
objectContaining
({
...
...
@@ -255,23 +244,21 @@ describe('Dashboard', () => {
}),
});
});
});
it
(
'
when the URL does not link to any panel, no panel is expanded
'
,
()
=>
{
it
(
'
when the URL does not link to any panel, no panel is expanded
'
,
async
()
=>
{
setSearch
();
createMountedWrapper
({
hasMetrics
:
true
});
setupStoreWithData
(
store
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
store
.
dispatch
).
not
.
toHaveBeenCalledWith
(
'
monitoringDashboard/setExpandedPanel
'
,
expect
.
anything
(),
);
});
});
it
(
'
when the URL points to an incorrect panel it shows an error
'
,
()
=>
{
it
(
'
when the URL points to an incorrect panel it shows an error
'
,
async
()
=>
{
const
panelGroup
=
metricsDashboardViewModel
.
panelGroups
[
0
];
const
panel
=
panelGroup
.
panels
[
0
];
...
...
@@ -284,7 +271,7 @@ describe('Dashboard', () => {
createMountedWrapper
({
hasMetrics
:
true
});
setupStoreWithData
(
store
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
createFlash
).
toHaveBeenCalled
();
expect
(
store
.
dispatch
).
not
.
toHaveBeenCalledWith
(
'
monitoringDashboard/setExpandedPanel
'
,
...
...
@@ -292,7 +279,6 @@ describe('Dashboard', () => {
);
});
});
});
describe
(
'
when the panel is expanded
'
,
()
=>
{
let
group
;
...
...
@@ -319,7 +305,7 @@ describe('Dashboard', () => {
window
.
history
.
pushState
.
mockRestore
();
});
it
(
'
URL is updated with panel parameters
'
,
()
=>
{
it
(
'
URL is updated with panel parameters
'
,
async
()
=>
{
createMountedWrapper
({
hasMetrics
:
true
});
expandPanel
(
group
,
panel
);
...
...
@@ -329,7 +315,7 @@ describe('Dashboard', () => {
y_label
:
panel
.
y_label
,
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
window
.
history
.
pushState
).
toHaveBeenCalledTimes
(
1
);
expect
(
window
.
history
.
pushState
).
toHaveBeenCalledWith
(
expect
.
anything
(),
// state
...
...
@@ -337,9 +323,8 @@ describe('Dashboard', () => {
expect
.
stringContaining
(
`
${
expectedSearch
}
`
),
);
});
});
it
(
'
URL is updated with panel parameters and custom dashboard
'
,
()
=>
{
it
(
'
URL is updated with panel parameters and custom dashboard
'
,
async
()
=>
{
const
dashboard
=
'
dashboard.yml
'
;
store
.
commit
(
`monitoringDashboard/
${
types
.
SET_INITIAL_STATE
}
`
,
{
...
...
@@ -355,7 +340,7 @@ describe('Dashboard', () => {
y_label
:
panel
.
y_label
,
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
window
.
history
.
pushState
).
toHaveBeenCalledTimes
(
1
);
expect
(
window
.
history
.
pushState
).
toHaveBeenCalledWith
(
expect
.
anything
(),
// state
...
...
@@ -363,14 +348,13 @@ describe('Dashboard', () => {
expect
.
stringContaining
(
`
${
expectedSearch
}
`
),
);
});
});
it
(
'
URL is updated with no parameters
'
,
()
=>
{
it
(
'
URL is updated with no parameters
'
,
async
()
=>
{
expandPanel
(
group
,
panel
);
createMountedWrapper
({
hasMetrics
:
true
});
expandPanel
(
null
,
null
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
window
.
history
.
pushState
).
toHaveBeenCalledTimes
(
1
);
expect
(
window
.
history
.
pushState
).
toHaveBeenCalledWith
(
expect
.
anything
(),
// state
...
...
@@ -379,12 +363,11 @@ describe('Dashboard', () => {
);
});
});
});
describe
(
'
when all panels in the first group are loading
'
,
()
=>
{
const
findGroupAt
=
(
i
)
=>
wrapper
.
findAll
(
GraphGroup
).
at
(
i
);
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
setupStoreWithDashboard
(
store
);
const
{
panels
}
=
store
.
state
.
monitoringDashboard
.
dashboard
.
panelGroups
[
0
];
...
...
@@ -396,7 +379,7 @@ describe('Dashboard', () => {
createShallowWrapper
();
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
a loading icon appears in the first group
'
,
()
=>
{
...
...
@@ -409,7 +392,7 @@ describe('Dashboard', () => {
});
describe
(
'
when all requests have been committed by the store
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
store
.
commit
(
`monitoringDashboard/
${
types
.
SET_INITIAL_STATE
}
`
,
{
currentEnvironmentName
:
'
production
'
,
currentDashboard
:
dashboardGitResponse
[
0
].
path
,
...
...
@@ -418,26 +401,25 @@ describe('Dashboard', () => {
createMountedWrapper
({
hasMetrics
:
true
});
setupStoreWithData
(
store
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
it does not show loading icons in any group
'
,
()
=>
{
it
(
'
it does not show loading icons in any group
'
,
async
()
=>
{
setupStoreWithData
(
store
);
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
wrapper
.
findAll
(
GraphGroup
).
wrappers
.
forEach
((
groupWrapper
)
=>
{
expect
(
groupWrapper
.
props
(
'
isLoading
'
)).
toBe
(
false
);
});
});
});
});
describe
(
'
variables section
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
createShallowWrapper
({
hasMetrics
:
true
});
setupStoreWithData
(
store
);
store
.
state
.
monitoringDashboard
.
variables
=
storeVariables
;
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
shows the variables section
'
,
()
=>
{
...
...
@@ -446,12 +428,11 @@ describe('Dashboard', () => {
});
describe
(
'
links section
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
createShallowWrapper
({
hasMetrics
:
true
});
setupStoreWithData
(
store
);
setupStoreWithLinks
(
store
);
return
wrapper
.
vm
.
$nextTick
();
await
nextTick
();
});
it
(
'
shows the links section
'
,
()
=>
{
...
...
@@ -464,10 +445,10 @@ describe('Dashboard', () => {
const
findExpandedPanel
=
()
=>
wrapper
.
find
({
ref
:
'
expandedPanel
'
});
describe
(
'
when the panel is not expanded
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
createShallowWrapper
({
hasMetrics
:
true
});
setupStoreWithData
(
store
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
expanded panel is not visible
'
,
()
=>
{
...
...
@@ -502,7 +483,7 @@ describe('Dashboard', () => {
template
:
`<div><slot name="top-left"/></div>`
,
};
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
createShallowWrapper
({
hasMetrics
:
true
},
{
stubs
:
{
DashboardPanel
:
MockPanel
}
});
setupStoreWithData
(
store
);
...
...
@@ -517,8 +498,7 @@ describe('Dashboard', () => {
});
jest
.
spyOn
(
store
,
'
dispatch
'
);
return
wrapper
.
vm
.
$nextTick
();
await
nextTick
();
});
it
(
'
displays a single panel and others are hidden
'
,
()
=>
{
...
...
@@ -561,13 +541,12 @@ describe('Dashboard', () => {
});
describe
(
'
when one of the metrics is missing
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
createShallowWrapper
({
hasMetrics
:
true
});
setupStoreWithDashboard
(
store
);
setMetricResult
({
store
,
result
:
[],
panel
:
2
});
return
wrapper
.
vm
.
$nextTick
();
await
nextTick
();
});
it
(
'
shows a group empty area
'
,
()
=>
{
...
...
@@ -590,14 +569,13 @@ describe('Dashboard', () => {
const
findDraggablePanels
=
()
=>
wrapper
.
findAll
(
'
.js-draggable-panel
'
);
const
findRearrangeButton
=
()
=>
wrapper
.
find
(
'
.js-rearrange-button
'
);
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
// call original dispatch
store
.
dispatch
.
mockRestore
();
createShallowWrapper
({
hasMetrics
:
true
});
setupStoreWithData
(
store
);
return
wrapper
.
vm
.
$nextTick
();
await
nextTick
();
});
it
(
'
wraps vuedraggable
'
,
()
=>
{
...
...
@@ -611,9 +589,9 @@ describe('Dashboard', () => {
});
describe
(
'
when rearrange is enabled
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
wrapper
.
setProps
({
rearrangePanelsAvailable
:
true
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
displays rearrange button
'
,
()
=>
{
...
...
@@ -624,9 +602,9 @@ describe('Dashboard', () => {
const
findFirstDraggableRemoveButton
=
()
=>
findDraggablePanels
().
at
(
0
).
find
(
'
.js-draggable-remove
'
);
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
findRearrangeButton
().
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
it enables draggables
'
,
()
=>
{
...
...
@@ -634,7 +612,7 @@ describe('Dashboard', () => {
expect
(
findEnabledDraggables
().
wrappers
).
toEqual
(
findDraggables
().
wrappers
);
});
it
(
'
metrics can be swapped
'
,
()
=>
{
it
(
'
metrics can be swapped
'
,
async
()
=>
{
const
firstDraggable
=
findDraggables
().
at
(
0
);
const
mockMetrics
=
[...
metricsDashboardViewModel
.
panelGroups
[
0
].
panels
];
...
...
@@ -645,43 +623,40 @@ describe('Dashboard', () => {
[
mockMetrics
[
0
],
mockMetrics
[
1
]]
=
[
mockMetrics
[
1
],
mockMetrics
[
0
]];
firstDraggable
.
vm
.
$emit
(
'
input
'
,
mockMetrics
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
const
{
panels
}
=
wrapper
.
vm
.
dashboard
.
panelGroups
[
0
];
expect
(
panels
[
1
].
title
).
toEqual
(
firstTitle
);
expect
(
panels
[
0
].
title
).
toEqual
(
secondTitle
);
});
});
it
(
'
shows a remove button, which removes a panel
'
,
()
=>
{
it
(
'
shows a remove button, which removes a panel
'
,
async
()
=>
{
expect
(
findFirstDraggableRemoveButton
().
find
(
'
a
'
).
exists
()).
toBe
(
true
);
expect
(
findDraggablePanels
().
length
).
toEqual
(
metricsDashboardPanelCount
);
findFirstDraggableRemoveButton
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findDraggablePanels
().
length
).
toEqual
(
metricsDashboardPanelCount
-
1
);
});
});
it
(
'
it disables draggables when clicked again
'
,
()
=>
{
it
(
'
it disables draggables when clicked again
'
,
async
()
=>
{
findRearrangeButton
().
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findRearrangeButton
().
attributes
(
'
pressed
'
)).
toBeFalsy
();
expect
(
findEnabledDraggables
().
length
).
toBe
(
0
);
});
});
});
});
});
describe
(
'
cluster health
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
createShallowWrapper
({
hasMetrics
:
true
,
showHeader
:
false
});
// all_dashboards is not defined in health dashboards
store
.
commit
(
`monitoringDashboard/
${
types
.
SET_ALL_DASHBOARDS
}
`
,
undefined
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
hides dashboard header by default
'
,
()
=>
{
...
...
@@ -706,34 +681,31 @@ describe('Dashboard', () => {
document
.
title
=
''
;
});
it
(
'
is prepended with the overview dashboard name by default
'
,
()
=>
{
it
(
'
is prepended with the overview dashboard name by default
'
,
async
()
=>
{
setupAllDashboards
(
store
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
document
.
title
.
startsWith
(
`
${
overviewDashboardName
}
· `
)).
toBe
(
true
);
});
});
it
(
'
is prepended with dashboard name if path is known
'
,
()
=>
{
it
(
'
is prepended with dashboard name if path is known
'
,
async
()
=>
{
const
dashboard
=
dashboardGitResponse
[
1
];
const
currentDashboard
=
dashboard
.
path
;
setupAllDashboards
(
store
,
currentDashboard
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
document
.
title
.
startsWith
(
`
${
dashboard
.
display_name
}
· `
)).
toBe
(
true
);
});
});
it
(
'
is prepended with the overview dashboard name if path is not known
'
,
()
=>
{
it
(
'
is prepended with the overview dashboard name if path is not known
'
,
async
()
=>
{
setupAllDashboards
(
store
,
'
unknown/path
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
document
.
title
.
startsWith
(
`
${
overviewDashboardName
}
· `
)).
toBe
(
true
);
});
});
it
(
'
is not modified when dashboard name is not provided
'
,
()
=>
{
it
(
'
is not modified when dashboard name is not provided
'
,
async
()
=>
{
const
dashboard
=
{
...
dashboardGitResponse
[
1
],
display_name
:
null
};
const
currentDashboard
=
dashboard
.
path
;
...
...
@@ -743,11 +715,10 @@ describe('Dashboard', () => {
currentDashboard
,
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
document
.
title
).
toBe
(
originalTitle
);
});
});
});
describe
(
'
Clipboard text in panels
'
,
()
=>
{
const
currentDashboard
=
dashboardGitResponse
[
1
].
path
;
...
...
@@ -756,14 +727,13 @@ describe('Dashboard', () => {
const
getClipboardTextFirstPanel
=
()
=>
wrapper
.
findAll
(
DashboardPanel
).
at
(
panelIndex
).
props
(
'
clipboardText
'
);
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
setupStoreWithData
(
store
);
store
.
commit
(
`monitoringDashboard/
${
types
.
SET_INITIAL_STATE
}
`
,
{
currentDashboard
,
});
createShallowWrapper
({
hasMetrics
:
true
});
return
wrapper
.
vm
.
$nextTick
();
await
nextTick
();
});
it
(
'
contains a link to the dashboard
'
,
()
=>
{
...
...
@@ -785,7 +755,7 @@ describe('Dashboard', () => {
// the dashboard panels have a ref attribute set.
const
getDashboardPanel
=
()
=>
wrapper
.
find
({
ref
:
panelRef
});
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
setupStoreWithData
(
store
);
store
.
commit
(
`monitoringDashboard/
${
types
.
SET_INITIAL_STATE
}
`
,
{
currentDashboard
,
...
...
@@ -795,8 +765,7 @@ describe('Dashboard', () => {
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
({
hoveredPanel
:
panelRef
});
return
wrapper
.
vm
.
$nextTick
();
await
nextTick
();
});
it
(
'
contains a ref attribute inside a DashboardPanel component
'
,
()
=>
{
...
...
spec/frontend/monitoring/components/dashboard_url_time_spec.js
View file @
8af0ee79
import
{
mount
}
from
'
@vue/test-utils
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
{
nextTick
}
from
'
vue
'
;
import
createFlash
from
'
~/flash
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
{
...
...
@@ -51,12 +52,12 @@ describe('dashboard invalid url parameters', () => {
queryToObject
.
mockReset
();
});
it
(
'
passes default url parameters to the time range picker
'
,
()
=>
{
it
(
'
passes default url parameters to the time range picker
'
,
async
()
=>
{
queryToObject
.
mockReturnValue
({});
createMountedWrapper
();
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findDateTimePicker
().
props
(
'
value
'
)).
toEqual
(
defaultTimeRange
);
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
...
...
@@ -65,9 +66,8 @@ describe('dashboard invalid url parameters', () => {
);
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
monitoringDashboard/fetchData
'
,
undefined
);
});
});
it
(
'
passes a fixed time range in the URL to the time range picker
'
,
()
=>
{
it
(
'
passes a fixed time range in the URL to the time range picker
'
,
async
()
=>
{
const
params
=
{
start
:
'
2019-01-01T00:00:00.000Z
'
,
end
:
'
2019-01-10T00:00:00.000Z
'
,
...
...
@@ -77,22 +77,21 @@ describe('dashboard invalid url parameters', () => {
createMountedWrapper
();
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findDateTimePicker
().
props
(
'
value
'
)).
toEqual
(
params
);
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
monitoringDashboard/setTimeRange
'
,
params
);
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
monitoringDashboard/fetchData
'
,
undefined
);
});
});
it
(
'
passes a rolling time range in the URL to the time range picker
'
,
()
=>
{
it
(
'
passes a rolling time range in the URL to the time range picker
'
,
async
()
=>
{
queryToObject
.
mockReturnValue
({
duration_seconds
:
'
120
'
,
});
createMountedWrapper
();
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
const
expectedTimeRange
=
{
duration
:
{
seconds
:
60
*
2
},
};
...
...
@@ -105,9 +104,8 @@ describe('dashboard invalid url parameters', () => {
);
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
monitoringDashboard/fetchData
'
,
undefined
);
});
});
it
(
'
shows an error message and loads a default time range if invalid url parameters are passed
'
,
()
=>
{
it
(
'
shows an error message and loads a default time range if invalid url parameters are passed
'
,
async
()
=>
{
queryToObject
.
mockReturnValue
({
start
:
'
<script>alert("XSS")</script>
'
,
end
:
'
<script>alert("XSS")</script>
'
,
...
...
@@ -115,7 +113,7 @@ describe('dashboard invalid url parameters', () => {
createMountedWrapper
();
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
createFlash
).
toHaveBeenCalled
();
expect
(
findDateTimePicker
().
props
(
'
value
'
)).
toEqual
(
defaultTimeRange
);
...
...
@@ -126,15 +124,14 @@ describe('dashboard invalid url parameters', () => {
);
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
monitoringDashboard/fetchData
'
,
undefined
);
});
});
it
(
'
redirects to different time range
'
,
()
=>
{
it
(
'
redirects to different time range
'
,
async
()
=>
{
const
toUrl
=
`
${
mockProjectDir
}
/-/environments/1/metrics`
;
removeParams
.
mockReturnValueOnce
(
toUrl
);
createMountedWrapper
();
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
findDateTimePicker
().
vm
.
$emit
(
'
input
'
,
{
duration
:
{
seconds
:
120
},
});
...
...
@@ -143,9 +140,8 @@ describe('dashboard invalid url parameters', () => {
expect
(
mergeUrlParams
).
toHaveBeenCalledWith
({
duration_seconds
:
'
120
'
},
toUrl
);
expect
(
redirectTo
).
toHaveBeenCalledTimes
(
1
);
});
});
it
(
'
changes the url when a panel moves the time slider
'
,
()
=>
{
it
(
'
changes the url when a panel moves the time slider
'
,
async
()
=>
{
const
timeRange
=
{
start
:
'
2020-01-01T00:00:00.000Z
'
,
end
:
'
2020-01-01T01:00:00.000Z
'
,
...
...
@@ -155,12 +151,11 @@ describe('dashboard invalid url parameters', () => {
createMountedWrapper
();
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
wrapper
.
vm
.
onTimeRangeZoom
(
timeRange
);
expect
(
updateHistory
).
toHaveBeenCalled
();
expect
(
wrapper
.
vm
.
selectedTimeRange
.
start
.
toString
()).
toBe
(
timeRange
.
start
);
expect
(
wrapper
.
vm
.
selectedTimeRange
.
end
.
toString
()).
toBe
(
timeRange
.
end
);
});
});
});
spec/frontend/monitoring/components/embeds/embed_group_spec.js
View file @
8af0ee79
import
{
GlButton
,
GlCard
}
from
'
@gitlab/ui
'
;
import
{
mount
,
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
import
EmbedGroup
from
'
~/monitoring/components/embeds/embed_group.vue
'
;
...
...
@@ -75,16 +75,14 @@ describe('Embed Group', () => {
expect
(
wrapper
.
find
(
'
.gl-card-body
'
).
classes
()).
not
.
toContain
(
'
d-none
'
);
});
it
(
'
collapses when clicked
'
,
(
done
)
=>
{
it
(
'
collapses when clicked
'
,
async
(
)
=>
{
metricsWithDataGetter
.
mockReturnValue
([
1
]);
mountComponent
({
shallow
:
false
,
stubs
:
{
MetricEmbed
:
true
}
});
wrapper
.
find
(
GlButton
).
trigger
(
'
click
'
);
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
'
.gl-card-body
'
).
classes
()).
toContain
(
'
d-none
'
);
done
();
});
});
});
...
...
spec/frontend/monitoring/components/graph_group_spec.js
View file @
8af0ee79
import
{
GlLoadingIcon
,
GlIcon
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
GraphGroup
from
'
~/monitoring/components/graph_group.vue
'
;
describe
(
'
Graph group component
'
,
()
=>
{
...
...
@@ -38,14 +39,13 @@ describe('Graph group component', () => {
expect
(
findCaretIcon
().
props
(
'
name
'
)).
toBe
(
'
angle-down
'
);
});
it
(
'
should show the angle-right caret icon when the user collapses the group
'
,
()
=>
{
it
(
'
should show the angle-right caret icon when the user collapses the group
'
,
async
()
=>
{
findToggleButton
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findContent
().
isVisible
()).
toBe
(
false
);
expect
(
findCaretIcon
().
props
(
'
name
'
)).
toBe
(
'
angle-right
'
);
});
});
it
(
'
should contain a tab index for the collapse button
'
,
()
=>
{
const
groupToggle
=
findToggleButton
();
...
...
@@ -53,17 +53,16 @@ describe('Graph group component', () => {
expect
(
groupToggle
.
attributes
(
'
tabindex
'
)).
toBeDefined
();
});
it
(
'
should show the open the group when collapseGroup is set to true
'
,
()
=>
{
it
(
'
should show the open the group when collapseGroup is set to true
'
,
async
()
=>
{
wrapper
.
setProps
({
collapseGroup
:
true
,
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findContent
().
isVisible
()).
toBe
(
true
);
expect
(
findCaretIcon
().
props
(
'
name
'
)).
toBe
(
'
angle-down
'
);
});
});
});
describe
(
'
When group is collapsed
'
,
()
=>
{
beforeEach
(()
=>
{
...
...
@@ -77,13 +76,12 @@ describe('Graph group component', () => {
expect
(
findCaretIcon
().
props
(
'
name
'
)).
toBe
(
'
angle-right
'
);
});
it
(
'
should show the angle-right caret icon when collapseGroup is false
'
,
()
=>
{
it
(
'
should show the angle-right caret icon when collapseGroup is false
'
,
async
()
=>
{
findToggleButton
().
trigger
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findCaretIcon
().
props
(
'
name
'
)).
toBe
(
'
angle-down
'
);
});
});
it
(
'
should call collapse the graph group content when enter is pressed on the caret icon
'
,
()
=>
{
const
graphGroupContent
=
findContent
();
...
...
@@ -137,15 +135,14 @@ describe('Graph group component', () => {
expect
(
findCaretIcon
().
exists
()).
toBe
(
false
);
});
it
(
'
should show the panel content when collapse is set to false
'
,
()
=>
{
it
(
'
should show the panel content when collapse is set to false
'
,
async
()
=>
{
wrapper
.
setProps
({
collapseGroup
:
false
,
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findContent
().
isVisible
()).
toBe
(
true
);
expect
(
findCaretIcon
().
exists
()).
toBe
(
false
);
});
});
});
});
spec/frontend/monitoring/components/links_section_spec.js
View file @
8af0ee79
...
...
@@ -36,7 +36,7 @@ describe('Links Section component', () => {
expect
(
findLinks
().
length
).
toBe
(
0
);
});
it
(
'
renders a link inside a section
'
,
()
=>
{
it
(
'
renders a link inside a section
'
,
async
()
=>
{
setState
([
{
title
:
'
GitLab Website
'
,
...
...
@@ -44,23 +44,21 @@ describe('Links Section component', () => {
},
]);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findLinks
()).
toHaveLength
(
1
);
const
firstLink
=
findLinks
().
at
(
0
);
expect
(
firstLink
.
attributes
(
'
href
'
)).
toBe
(
'
https://gitlab.com
'
);
expect
(
firstLink
.
text
()).
toBe
(
'
GitLab Website
'
);
});
});
it
(
'
renders multiple links inside a section
'
,
()
=>
{
it
(
'
renders multiple links inside a section
'
,
async
()
=>
{
const
links
=
new
Array
(
10
)
.
fill
(
null
)
.
map
((
_
,
i
)
=>
({
title
:
`Title
${
i
}
`
,
url
:
`https://gitlab.com/projects/
${
i
}
`
}));
setState
(
links
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findLinks
()).
toHaveLength
(
10
);
});
});
});
spec/frontend/monitoring/components/refresh_button_spec.js
View file @
8af0ee79
import
{
GlDropdown
,
GlDropdownItem
,
GlButton
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Visibility
from
'
visibilityjs
'
;
import
{
nextTick
}
from
'
vue
'
;
import
RefreshButton
from
'
~/monitoring/components/refresh_button.vue
'
;
import
{
createStore
}
from
'
~/monitoring/stores
'
;
...
...
@@ -79,9 +80,9 @@ describe('RefreshButton', () => {
describe
(
'
when a refresh rate is chosen
'
,
()
=>
{
const
optIndex
=
2
;
// Other option than "Off"
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
findOptionAt
(
optIndex
).
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
;
await
nextTick
()
;
});
it
(
'
refresh rate appears in the dropdown
'
,
()
=>
{
...
...
@@ -101,7 +102,7 @@ describe('RefreshButton', () => {
jest
.
runOnlyPendingTimers
();
expectFetchDataToHaveBeenCalledTimes
(
2
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
jest
.
runOnlyPendingTimers
();
expectFetchDataToHaveBeenCalledTimes
(
3
);
...
...
@@ -113,7 +114,7 @@ describe('RefreshButton', () => {
jest
.
runOnlyPendingTimers
();
expectFetchDataToHaveBeenCalledTimes
(
1
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
jest
.
runOnlyPendingTimers
();
expectFetchDataToHaveBeenCalledTimes
(
1
);
...
...
@@ -128,9 +129,9 @@ describe('RefreshButton', () => {
});
describe
(
'
when "Off" refresh rate is chosen
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
findOptionAt
(
0
).
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
;
await
nextTick
()
;
});
it
(
'
refresh rate is "Off" in the dropdown
'
,
()
=>
{
...
...
spec/frontend/monitoring/components/variables/dropdown_field_spec.js
View file @
8af0ee79
import
{
GlDropdown
,
GlDropdownItem
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
DropdownField
from
'
~/monitoring/components/variables/dropdown_field.vue
'
;
describe
(
'
Custom variable component
'
,
()
=>
{
...
...
@@ -53,14 +54,13 @@ describe('Custom variable component', () => {
expect
(
findDropdown
().
exists
()).
toBe
(
true
);
});
it
(
'
changing dropdown items triggers update
'
,
()
=>
{
it
(
'
changing dropdown items triggers update
'
,
async
()
=>
{
createShallowWrapper
();
jest
.
spyOn
(
wrapper
.
vm
,
'
$emit
'
);
findDropdownItems
().
at
(
1
).
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
$emit
).
toHaveBeenCalledWith
(
'
input
'
,
'
canary
'
);
});
});
});
spec/frontend/monitoring/components/variables/text_field_spec.js
View file @
8af0ee79
import
{
GlFormInput
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
TextField
from
'
~/monitoring/components/variables/text_field.vue
'
;
describe
(
'
Text variable component
'
,
()
=>
{
...
...
@@ -23,15 +24,14 @@ describe('Text variable component', () => {
expect
(
findInput
().
exists
()).
toBe
(
true
);
});
it
(
'
always has a default value
'
,
()
=>
{
it
(
'
always has a default value
'
,
async
()
=>
{
createShallowWrapper
();
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
findInput
().
attributes
(
'
value
'
)).
toBe
(
propsData
.
value
);
});
});
it
(
'
triggers keyup enter
'
,
()
=>
{
it
(
'
triggers keyup enter
'
,
async
()
=>
{
createShallowWrapper
();
jest
.
spyOn
(
wrapper
.
vm
,
'
$emit
'
);
...
...
@@ -39,12 +39,11 @@ describe('Text variable component', () => {
findInput
().
trigger
(
'
input
'
);
findInput
().
trigger
(
'
keyup.enter
'
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
$emit
).
toHaveBeenCalledWith
(
'
input
'
,
'
prod-pod
'
);
});
});
it
(
'
triggers blur enter
'
,
()
=>
{
it
(
'
triggers blur enter
'
,
async
()
=>
{
createShallowWrapper
();
jest
.
spyOn
(
wrapper
.
vm
,
'
$emit
'
);
...
...
@@ -52,8 +51,7 @@ describe('Text variable component', () => {
findInput
().
trigger
(
'
input
'
);
findInput
().
trigger
(
'
blur
'
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
$emit
).
toHaveBeenCalledWith
(
'
input
'
,
'
canary-pod
'
);
});
});
});
spec/frontend/monitoring/components/variables_section_spec.js
View file @
8af0ee79
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vuex
from
'
vuex
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
updateHistory
,
mergeUrlParams
}
from
'
~/lib/utils/url_utility
'
;
import
DropdownField
from
'
~/monitoring/components/variables/dropdown_field.vue
'
;
import
TextField
from
'
~/monitoring/components/variables/text_field.vue
'
;
...
...
@@ -40,11 +41,11 @@ describe('Metrics dashboard/variables section component', () => {
});
describe
(
'
when variables are set
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
store
.
state
.
monitoringDashboard
.
variables
=
storeVariables
;
createShallowWrapper
();
return
wrapper
.
vm
.
$nextTick
;
await
nextTick
()
;
});
it
(
'
shows the variables section
'
,
()
=>
{
...
...
@@ -83,12 +84,12 @@ describe('Metrics dashboard/variables section component', () => {
createShallowWrapper
();
});
it
(
'
merges the url params and refreshes the dashboard when a text-based variables inputs are updated
'
,
()
=>
{
it
(
'
merges the url params and refreshes the dashboard when a text-based variables inputs are updated
'
,
async
()
=>
{
const
firstInput
=
findTextInputs
().
at
(
0
);
firstInput
.
vm
.
$emit
(
'
input
'
,
'
test
'
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
updateVariablesAndFetchData
).
toHaveBeenCalled
();
expect
(
mergeUrlParams
).
toHaveBeenCalledWith
(
convertVariablesForURL
(
storeVariables
),
...
...
@@ -96,14 +97,13 @@ describe('Metrics dashboard/variables section component', () => {
);
expect
(
updateHistory
).
toHaveBeenCalled
();
});
});
it
(
'
merges the url params and refreshes the dashboard when a custom-based variables inputs are updated
'
,
()
=>
{
it
(
'
merges the url params and refreshes the dashboard when a custom-based variables inputs are updated
'
,
async
()
=>
{
const
firstInput
=
findCustomInputs
().
at
(
0
);
firstInput
.
vm
.
$emit
(
'
input
'
,
'
test
'
);
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
updateVariablesAndFetchData
).
toHaveBeenCalled
();
expect
(
mergeUrlParams
).
toHaveBeenCalledWith
(
convertVariablesForURL
(
storeVariables
),
...
...
@@ -111,7 +111,6 @@ describe('Metrics dashboard/variables section component', () => {
);
expect
(
updateHistory
).
toHaveBeenCalled
();
});
});
it
(
'
does not merge the url params and refreshes the dashboard if the value entered is not different that is what currently stored
'
,
()
=>
{
const
firstInput
=
findTextInputs
().
at
(
0
);
...
...
spec/frontend/mr_popover/mr_popover_spec.js
View file @
8af0ee79
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
MRPopover
from
'
~/mr_popover/components/mr_popover.vue
'
;
import
CiIcon
from
'
~/vue_shared/components/ci_icon.vue
'
;
...
...
@@ -25,16 +26,15 @@ describe('MR Popover', () => {
});
});
it
(
'
shows skeleton-loader while apollo is loading
'
,
()
=>
{
it
(
'
shows skeleton-loader while apollo is loading
'
,
async
()
=>
{
wrapper
.
vm
.
$apollo
.
queries
.
mergeRequest
.
loading
=
true
;
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
element
).
toMatchSnapshot
();
});
});
describe
(
'
loaded state
'
,
()
=>
{
it
(
'
matches the snapshot
'
,
()
=>
{
it
(
'
matches the snapshot
'
,
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
({
...
...
@@ -51,12 +51,11 @@ describe('MR Popover', () => {
},
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
element
).
toMatchSnapshot
();
});
});
it
(
'
does not show CI Icon if there is no pipeline data
'
,
()
=>
{
it
(
'
does not show CI Icon if there is no pipeline 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
({
...
...
@@ -69,15 +68,13 @@ describe('MR Popover', () => {
},
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
CiIcon
).
exists
()).
toBe
(
false
);
});
});
it
(
'
falls back to cached MR title when request fails
'
,
()
=>
{
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
it
(
'
falls back to cached MR title when request fails
'
,
async
()
=>
{
await
nextTick
();
expect
(
wrapper
.
text
()).
toContain
(
'
MR Title
'
);
});
});
});
});
spec/frontend/nav/components/responsive_app_spec.js
View file @
8af0ee79
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
ResponsiveApp
from
'
~/nav/components/responsive_app.vue
'
;
import
ResponsiveHeader
from
'
~/nav/components/responsive_header.vue
'
;
import
ResponsiveHome
from
'
~/nav/components/responsive_home.vue
'
;
...
...
@@ -62,7 +63,7 @@ describe('~/nav/components/responsive_app.vue', () => {
wrapper
.
vm
.
$root
.
$emit
(
evt
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
},
Promise
.
resolve
());
expect
(
hasMobileOverlayVisible
()).
toBe
(
expectation
);
...
...
@@ -97,7 +98,7 @@ describe('~/nav/components/responsive_app.vue', () => {
findHome
().
vm
.
$emit
(
'
menu-item-click
'
,
{
view
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
shows header
'
,
()
=>
{
...
...
spec/frontend/notes/components/comment_form_spec.js
View file @
8af0ee79
...
...
@@ -466,8 +466,8 @@ describe('issue_comment_form component', () => {
await
findCloseReopenButton
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
;
await
wrapper
.
vm
.
$
nextTick
;
await
nextTick
;
await
nextTick
;
expect
(
createFlash
).
toHaveBeenCalledWith
({
message
:
`Something went wrong while closing the
${
type
}
. Please try again later.`
,
...
...
@@ -502,8 +502,8 @@ describe('issue_comment_form component', () => {
await
findCloseReopenButton
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
;
await
wrapper
.
vm
.
$
nextTick
;
await
nextTick
;
await
nextTick
;
expect
(
createFlash
).
toHaveBeenCalledWith
({
message
:
`Something went wrong while reopening the
${
type
}
. Please try again later.`
,
...
...
@@ -521,7 +521,7 @@ describe('issue_comment_form component', () => {
await
findCloseReopenButton
().
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
refreshUserMergeRequestCounts
).
toHaveBeenCalled
();
});
...
...
@@ -581,7 +581,7 @@ describe('issue_comment_form component', () => {
// check checkbox
checkbox
.
element
.
checked
=
shouldCheckboxBeChecked
;
checkbox
.
trigger
(
'
change
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
// submit comment
findCommentButton
().
trigger
(
'
click
'
);
...
...
spec/frontend/notes/components/diff_discussion_header_spec.js
View file @
8af0ee79
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
diffDiscussionHeader
from
'
~/notes/components/diff_discussion_header.vue
'
;
import
createStore
from
'
~/notes/stores
'
;
...
...
@@ -24,24 +25,23 @@ describe('diff_discussion_header component', () => {
wrapper
.
destroy
();
});
it
(
'
should render user avatar
'
,
()
=>
{
it
(
'
should render user avatar
'
,
async
()
=>
{
const
discussion
=
{
...
discussionMock
};
discussion
.
diff_file
=
mockDiffFile
;
discussion
.
diff_discussion
=
true
;
wrapper
.
setProps
({
discussion
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
'
.user-avatar-link
'
).
exists
()).
toBe
(
true
);
});
});
describe
(
'
action text
'
,
()
=>
{
const
commitId
=
'
razupaltuff
'
;
const
truncatedCommitId
=
commitId
.
substr
(
0
,
8
);
let
commitElement
;
beforeEach
(
(
done
)
=>
{
beforeEach
(
async
(
)
=>
{
store
.
state
.
diffs
=
{
projectPath
:
'
something
'
,
};
...
...
@@ -58,41 +58,30 @@ describe('diff_discussion_header component', () => {
},
});
wrapper
.
vm
.
$nextTick
()
.
then
(()
=>
{
await
nextTick
();
commitElement
=
wrapper
.
find
(
'
.commit-sha
'
);
})
.
then
(
done
)
.
catch
(
done
.
fail
);
});
describe
(
'
for diff threads without a commit id
'
,
()
=>
{
it
(
'
should show started a thread on the diff text
'
,
(
done
)
=>
{
it
(
'
should show started a thread on the diff text
'
,
async
(
)
=>
{
Object
.
assign
(
wrapper
.
vm
.
discussion
,
{
for_commit
:
false
,
commit_id
:
null
,
});
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
text
()).
toContain
(
'
started a thread on the diff
'
);
done
();
});
});
it
(
'
should show thread on older version text
'
,
(
done
)
=>
{
it
(
'
should show thread on older version text
'
,
async
(
)
=>
{
Object
.
assign
(
wrapper
.
vm
.
discussion
,
{
for_commit
:
false
,
commit_id
:
null
,
active
:
false
,
});
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
text
()).
toContain
(
'
started a thread on an old version of the diff
'
);
done
();
});
});
});
...
...
@@ -105,31 +94,25 @@ describe('diff_discussion_header component', () => {
});
describe
(
'
for diff thread with a commit id
'
,
()
=>
{
it
(
'
should display started thread on commit header
'
,
(
done
)
=>
{
it
(
'
should display started thread on commit header
'
,
async
(
)
=>
{
wrapper
.
vm
.
discussion
.
for_commit
=
false
;
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
text
()).
toContain
(
`started a thread on commit
${
truncatedCommitId
}
`
);
expect
(
commitElement
).
not
.
toBe
(
null
);
done
();
});
});
it
(
'
should display outdated change on commit header
'
,
(
done
)
=>
{
it
(
'
should display outdated change on commit header
'
,
async
(
)
=>
{
wrapper
.
vm
.
discussion
.
for_commit
=
false
;
wrapper
.
vm
.
discussion
.
active
=
false
;
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
text
()).
toContain
(
`started a thread on an outdated change in commit
${
truncatedCommitId
}
`
,
);
expect
(
commitElement
).
not
.
toBe
(
null
);
done
();
});
});
});
});
...
...
spec/frontend/notes/components/discussion_counter_spec.js
View file @
8af0ee79
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
DiscussionCounter
from
'
~/notes/components/discussion_counter.vue
'
;
import
notesModule
from
'
~/notes/stores/modules
'
;
...
...
@@ -113,7 +113,7 @@ describe('DiscussionCounter component', () => {
expect
(
setExpandDiscussionsFn
).
toHaveBeenCalledTimes
(
1
);
});
it
(
'
collapses all discussions if expanded
'
,
()
=>
{
it
(
'
collapses all discussions if expanded
'
,
async
()
=>
{
updateStoreWithExpanded
(
true
);
expect
(
wrapper
.
vm
.
allExpanded
).
toBe
(
true
);
...
...
@@ -121,13 +121,12 @@ describe('DiscussionCounter component', () => {
toggleAllButton
.
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
allExpanded
).
toBe
(
false
);
expect
(
toggleAllButton
.
props
(
'
icon
'
)).
toBe
(
'
angle-down
'
);
});
});
it
(
'
expands all discussions if collapsed
'
,
()
=>
{
it
(
'
expands all discussions if collapsed
'
,
async
()
=>
{
updateStoreWithExpanded
(
false
);
expect
(
wrapper
.
vm
.
allExpanded
).
toBe
(
false
);
...
...
@@ -135,10 +134,9 @@ describe('DiscussionCounter component', () => {
toggleAllButton
.
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
allExpanded
).
toBe
(
true
);
expect
(
toggleAllButton
.
props
(
'
icon
'
)).
toBe
(
'
angle-up
'
);
});
});
});
});
spec/frontend/notes/components/discussion_filter_spec.js
View file @
8af0ee79
import
{
GlDropdown
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
AxiosMockAdapter
from
'
axios-mock-adapter
'
;
import
Vuex
from
'
vuex
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
...
...
@@ -151,13 +151,11 @@ describe('DiscussionFilter component', () => {
window
.
mrTabs
=
undefined
;
});
it
(
'
only renders when discussion tab is active
'
,
(
done
)
=>
{
it
(
'
only renders when discussion tab is active
'
,
async
(
)
=>
{
eventHub
.
$emit
(
'
MergeRequestTabChange
'
,
'
commit
'
);
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
html
()).
toBe
(
''
);
done
();
});
});
});
...
...
@@ -166,58 +164,48 @@ describe('DiscussionFilter component', () => {
window
.
location
.
hash
=
''
;
});
it
(
'
updates the filter when the URL links to a note
'
,
(
done
)
=>
{
it
(
'
updates the filter when the URL links to a note
'
,
async
(
)
=>
{
window
.
location
.
hash
=
`note_
${
discussionMock
.
notes
[
0
].
id
}
`
;
wrapper
.
vm
.
currentValue
=
discussionFiltersMock
[
2
].
value
;
wrapper
.
vm
.
handleLocationHash
();
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
currentValue
).
toBe
(
DISCUSSION_FILTERS_DEFAULT_VALUE
);
done
();
});
});
it
(
'
does not update the filter when the current filter is "Show all activity"
'
,
(
done
)
=>
{
it
(
'
does not update the filter when the current filter is "Show all activity"
'
,
async
(
)
=>
{
window
.
location
.
hash
=
`note_
${
discussionMock
.
notes
[
0
].
id
}
`
;
wrapper
.
vm
.
handleLocationHash
();
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
currentValue
).
toBe
(
DISCUSSION_FILTERS_DEFAULT_VALUE
);
done
();
});
});
it
(
'
only updates filter when the URL links to a note
'
,
(
done
)
=>
{
it
(
'
only updates filter when the URL links to a note
'
,
async
(
)
=>
{
window
.
location
.
hash
=
`testing123`
;
wrapper
.
vm
.
handleLocationHash
();
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
currentValue
).
toBe
(
DISCUSSION_FILTERS_DEFAULT_VALUE
);
done
();
});
});
it
(
'
fetches discussions when there is a hash
'
,
(
done
)
=>
{
it
(
'
fetches discussions when there is a hash
'
,
async
(
)
=>
{
window
.
location
.
hash
=
`note_
${
discussionMock
.
notes
[
0
].
id
}
`
;
wrapper
.
vm
.
currentValue
=
discussionFiltersMock
[
2
].
value
;
jest
.
spyOn
(
wrapper
.
vm
,
'
selectFilter
'
).
mockImplementation
(()
=>
{});
wrapper
.
vm
.
handleLocationHash
();
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
selectFilter
).
toHaveBeenCalled
();
done
();
});
});
it
(
'
does not fetch discussions when there is no hash
'
,
(
done
)
=>
{
it
(
'
does not fetch discussions when there is no hash
'
,
async
(
)
=>
{
window
.
location
.
hash
=
''
;
jest
.
spyOn
(
wrapper
.
vm
,
'
selectFilter
'
).
mockImplementation
(()
=>
{});
wrapper
.
vm
.
handleLocationHash
();
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
selectFilter
).
not
.
toHaveBeenCalled
();
done
();
});
});
});
});
spec/frontend/notes/components/discussion_notes_spec.js
View file @
8af0ee79
import
{
getByRole
}
from
'
@testing-library/dom
'
;
import
{
shallowMount
,
mount
}
from
'
@vue/test-utils
'
;
import
'
~/behaviors/markdown/render_gfm
'
;
import
{
nextTick
}
from
'
vue
'
;
import
DiscussionNotes
from
'
~/notes/components/discussion_notes.vue
'
;
import
NoteableNote
from
'
~/notes/components/noteable_note.vue
'
;
import
{
SYSTEM_NOTE
}
from
'
~/notes/constants
'
;
...
...
@@ -135,30 +136,27 @@ describe('DiscussionNotes', () => {
createComponent
({
shouldGroupReplies
:
true
,
isExpanded
:
true
});
});
it
(
'
emits deleteNote when first note emits handleDeleteNote
'
,
()
=>
{
it
(
'
emits deleteNote when first note emits handleDeleteNote
'
,
async
()
=>
{
findNoteAtIndex
(
0
).
vm
.
$emit
(
'
handleDeleteNote
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
().
deleteNote
).
toBeTruthy
();
});
});
it
(
'
emits startReplying when first note emits startReplying
'
,
()
=>
{
it
(
'
emits startReplying when first note emits startReplying
'
,
async
()
=>
{
findNoteAtIndex
(
0
).
vm
.
$emit
(
'
startReplying
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
().
startReplying
).
toBeTruthy
();
});
});
it
(
'
emits deleteNote when second note emits handleDeleteNote
'
,
()
=>
{
it
(
'
emits deleteNote when second note emits handleDeleteNote
'
,
async
()
=>
{
findNoteAtIndex
(
1
).
vm
.
$emit
(
'
handleDeleteNote
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
().
deleteNote
).
toBeTruthy
();
});
});
});
describe
(
'
with ungroupped notes
'
,
()
=>
{
let
note
;
...
...
@@ -167,15 +165,14 @@ describe('DiscussionNotes', () => {
note
=
wrapper
.
find
(
'
.notes > *
'
);
});
it
(
'
emits deleteNote when first note emits handleDeleteNote
'
,
()
=>
{
it
(
'
emits deleteNote when first note emits handleDeleteNote
'
,
async
()
=>
{
note
.
vm
.
$emit
(
'
handleDeleteNote
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
().
deleteNote
).
toBeTruthy
();
});
});
});
});
describe
.
each
`
desc | props | event | expectedCalls
...
...
spec/frontend/notes/components/discussion_resolve_button_spec.js
View file @
8af0ee79
import
{
GlButton
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
resolveDiscussionButton
from
'
~/notes/components/discussion_resolve_button.vue
'
;
const
buttonTitle
=
'
Resolve discussion
'
;
...
...
@@ -26,17 +27,16 @@ describe('resolveDiscussionButton', () => {
wrapper
.
destroy
();
});
it
(
'
should emit a onClick event on button click
'
,
()
=>
{
it
(
'
should emit a onClick event on button click
'
,
async
()
=>
{
const
button
=
wrapper
.
find
(
GlButton
);
button
.
vm
.
$emit
(
'
click
'
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
()).
toEqual
({
onClick
:
[[]],
});
});
});
it
(
'
should contain the provided button title
'
,
()
=>
{
const
button
=
wrapper
.
find
(
GlButton
);
...
...
@@ -57,7 +57,7 @@ describe('resolveDiscussionButton', () => {
expect
(
button
.
props
(
'
loading
'
)).
toEqual
(
true
);
});
it
(
'
should only show a loading spinner while resolving
'
,
()
=>
{
it
(
'
should only show a loading spinner while resolving
'
,
async
()
=>
{
factory
({
propsData
:
{
isResolving
:
false
,
...
...
@@ -67,8 +67,7 @@ describe('resolveDiscussionButton', () => {
const
button
=
wrapper
.
find
(
GlButton
);
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
button
.
props
(
'
loading
'
)).
toEqual
(
false
);
});
});
});
spec/frontend/notes/components/noteable_note_spec.js
View file @
8af0ee79
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
'
;
...
...
@@ -107,11 +107,11 @@ describe('issue_note', () => {
line
,
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findMultilineComment
().
text
()).
toBe
(
'
Comment on lines 1 to 2
'
);
});
it
(
'
should only render if it has everything it needs
'
,
()
=>
{
it
(
'
should only render if it has everything it needs
'
,
async
()
=>
{
const
position
=
{
line_range
:
{
start
:
{
...
...
@@ -140,12 +140,11 @@ describe('issue_note', () => {
line
,
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findMultilineComment
().
exists
()).
toBe
(
false
);
});
});
it
(
'
should not render if has single line comment
'
,
()
=>
{
it
(
'
should not render if has single line comment
'
,
async
()
=>
{
const
position
=
{
line_range
:
{
start
:
{
...
...
@@ -174,10 +173,9 @@ describe('issue_note', () => {
line
,
});
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
findMultilineComment
().
exists
()).
toBe
(
false
);
});
});
it
(
'
should not render if `line_range` is unavailable
'
,
()
=>
{
expect
(
findMultilineComment
().
exists
()).
toBe
(
false
);
...
...
@@ -204,7 +202,7 @@ describe('issue_note', () => {
line
,
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
findComponent
(
UserAvatarLink
).
props
(
'
imgSize
'
)).
toBe
(
24
);
});
...
...
@@ -318,13 +316,13 @@ describe('issue_note', () => {
callback
:
()
=>
{},
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
let
noteBodyProps
=
noteBody
.
props
();
expect
(
noteBodyProps
.
note
.
note_html
).
toBe
(
`<p>
${
updatedText
}
</p>\n`
);
noteBody
.
vm
.
$emit
(
'
cancelForm
'
,
{});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
noteBodyProps
=
noteBody
.
props
();
...
...
spec/frontend/notes/components/timeline_toggle_spec.js
View file @
8af0ee79
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
TimelineToggle
,
{
timelineEnabledTooltip
,
...
...
@@ -64,7 +64,7 @@ describe('Timeline toggle', () => {
it
(
'
should set correct UI state
'
,
async
()
=>
{
store
.
state
.
isTimelineEnabled
=
true
;
findGlButton
().
vm
.
$emit
(
'
click
'
,
mockEvent
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findGlButton
().
attributes
(
'
title
'
)).
toBe
(
timelineEnabledTooltip
);
expect
(
findGlButton
().
attributes
(
'
selected
'
)).
toBe
(
'
true
'
);
expect
(
mockEvent
.
currentTarget
.
blur
).
toHaveBeenCalled
();
...
...
@@ -72,7 +72,7 @@ describe('Timeline toggle', () => {
it
(
'
should track Snowplow event
'
,
async
()
=>
{
store
.
state
.
isTimelineEnabled
=
true
;
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
findGlButton
().
trigger
(
'
click
'
);
...
...
@@ -97,7 +97,7 @@ describe('Timeline toggle', () => {
it
(
'
should set correct UI state
'
,
async
()
=>
{
store
.
state
.
isTimelineEnabled
=
false
;
findGlButton
().
vm
.
$emit
(
'
click
'
,
mockEvent
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findGlButton
().
attributes
(
'
title
'
)).
toBe
(
timelineDisabledTooltip
);
expect
(
findGlButton
().
attributes
(
'
selected
'
)).
toBe
(
undefined
);
expect
(
mockEvent
.
currentTarget
.
blur
).
toHaveBeenCalled
();
...
...
@@ -105,7 +105,7 @@ describe('Timeline toggle', () => {
it
(
'
should track Snowplow event
'
,
async
()
=>
{
store
.
state
.
isTimelineEnabled
=
false
;
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
findGlButton
().
trigger
(
'
click
'
);
...
...
spec/frontend/notes/mixins/discussion_navigation_spec.js
View file @
8af0ee79
...
...
@@ -93,16 +93,15 @@ describe('Discussion navigation mixin', () => {
expect
(
store
.
dispatch
).
toHaveBeenCalledWith
(
'
setCurrentDiscussionId
'
,
null
);
});
it
(
'
triggers the jumpToNextDiscussion action when the previous store action succeeds
'
,
()
=>
{
it
(
'
triggers the jumpToNextDiscussion action when the previous store action succeeds
'
,
async
()
=>
{
store
.
dispatch
.
mockResolvedValue
();
vm
.
jumpToFirstUnresolvedDiscussion
();
return
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
vm
.
jumpToNextDiscussion
).
toHaveBeenCalled
();
});
});
});
describe
(
'
cycle through discussions
'
,
()
=>
{
beforeEach
(()
=>
{
...
...
@@ -126,11 +125,11 @@ describe('Discussion navigation mixin', () => {
});
describe
(
'
on `show` active tab
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
window
.
mrTabs
.
currentAction
=
'
show
'
;
wrapper
.
vm
[
fn
](...
args
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
sets current discussion
'
,
()
=>
{
...
...
@@ -150,11 +149,11 @@ describe('Discussion navigation mixin', () => {
});
describe
(
'
on `diffs` active tab
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
window
.
mrTabs
.
currentAction
=
'
diffs
'
;
wrapper
.
vm
[
fn
](...
args
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
sets current discussion
'
,
()
=>
{
...
...
@@ -178,11 +177,11 @@ describe('Discussion navigation mixin', () => {
});
describe
(
'
on `other` active tab
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(
async
()
=>
{
window
.
mrTabs
.
currentAction
=
'
other
'
;
wrapper
.
vm
[
fn
](...
args
);
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
sets current discussion
'
,
()
=>
{
...
...
spec/frontend/notifications/components/custom_notifications_modal_spec.js
View file @
8af0ee79
...
...
@@ -2,6 +2,7 @@ import { GlSprintf, GlModal, GlFormGroup, GlFormCheckbox, GlLoadingIcon } from '
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
axios
from
'
axios
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
httpStatus
from
'
~/lib/utils/http_status
'
;
...
...
@@ -97,7 +98,7 @@ describe('CustomNotificationsModal', () => {
],
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
.
each
`
...
...
@@ -222,7 +223,7 @@ describe('CustomNotificationsModal', () => {
],
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
findCheckboxAt
(
1
).
vm
.
$emit
(
'
change
'
,
true
);
...
...
@@ -252,7 +253,7 @@ describe('CustomNotificationsModal', () => {
],
});
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
findCheckboxAt
(
1
).
vm
.
$emit
(
'
change
'
,
true
);
...
...
spec/frontend/operation_settings/components/metrics_settings_spec.js
View file @
8af0ee79
import
{
GlButton
,
GlLink
,
GlFormGroup
,
GlFormInput
,
GlFormSelect
}
from
'
@gitlab/ui
'
;
import
{
mount
,
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
import
createFlash
from
'
~/flash
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
...
...
@@ -181,17 +182,18 @@ describe('operation settings external dashboard component', () => {
expect
(
submit
.
text
()).
toBe
(
'
Save Changes
'
);
});
it
(
'
submits form on click
'
,
()
=>
{
it
(
'
submits form on click
'
,
async
()
=>
{
mountComponent
(
false
);
axios
.
patch
.
mockResolvedValue
();
findSubmitButton
().
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
()
=>
{
mountComponent
(
false
);
const
message
=
'
mockErrorMessage
'
;
axios
.
patch
.
mockRejectedValue
({
response
:
{
data
:
{
message
}
}
});
...
...
@@ -199,14 +201,11 @@ describe('operation settings external dashboard component', () => {
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/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js
View file @
8af0ee79
import
{
GlDropdownItem
,
GlIcon
,
GlDropdown
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
VueApollo
from
'
vue-apollo
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
useFakeDate
}
from
'
helpers/fake_date
'
;
import
createMockApollo
from
'
helpers/mock_apollo_helper
'
;
import
{
createMockDirective
,
getBinding
}
from
'
helpers/vue_mock_directive
'
;
...
...
@@ -54,8 +55,8 @@ describe('Details Header', () => {
const
waitForMetadataItems
=
async
()
=>
{
// Metadata items are printed by a loop in the title-area and it takes two ticks for them to be available
await
wrapper
.
vm
.
$
nextTick
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
await
nextTick
();
};
const
mountComponent
=
({
...
...
spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/registry_header_spec.js
View file @
8af0ee79
import
{
GlSprintf
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
Component
from
'
~/packages_and_registries/container_registry/explorer/components/list_page/registry_header.vue
'
;
import
{
CONTAINER_REGISTRY_TITLE
,
...
...
@@ -21,7 +22,7 @@ describe('registry_header', () => {
const
findImagesCountSubHeader
=
()
=>
wrapper
.
find
(
'
[data-testid="images-count"]
'
);
const
findExpirationPolicySubHeader
=
()
=>
wrapper
.
find
(
'
[data-testid="expiration-policy"]
'
);
const
mountComponent
=
(
propsData
,
slots
)
=>
{
const
mountComponent
=
async
(
propsData
,
slots
)
=>
{
wrapper
=
shallowMount
(
Component
,
{
stubs
:
{
GlSprintf
,
...
...
@@ -30,7 +31,7 @@ describe('registry_header', () => {
propsData
,
slots
,
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
};
afterEach
(()
=>
{
...
...
spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/details_title_spec.js
View file @
8af0ee79
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
component
from
'
~/packages_and_registries/infrastructure_registry/details/components/details_title.vue
'
;
import
TitleArea
from
'
~/vue_shared/components/registry/title_area.vue
'
;
...
...
@@ -11,7 +11,10 @@ describe('PackageTitle', () => {
let
wrapper
;
let
store
;
function
createComponent
({
packageFiles
=
mavenFiles
,
packageEntity
=
terraformModule
}
=
{})
{
async
function
createComponent
({
packageFiles
=
mavenFiles
,
packageEntity
=
terraformModule
,
}
=
{})
{
store
=
new
Vuex
.
Store
({
state
:
{
packageEntity
,
...
...
@@ -28,7 +31,7 @@ describe('PackageTitle', () => {
TitleArea
,
},
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
}
const
findTitleArea
=
()
=>
wrapper
.
findComponent
(
TitleArea
);
...
...
spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
View file @
8af0ee79
import
{
GlTable
,
GlPagination
,
GlModal
}
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
stubChildren
from
'
helpers/stub_children
'
;
...
...
@@ -120,17 +120,16 @@ describe('packages_list', () => {
mountComponent
();
});
it
(
'
setItemToBeDeleted sets itemToBeDeleted and open the modal
'
,
()
=>
{
it
(
'
setItemToBeDeleted sets itemToBeDeleted and open the modal
'
,
async
()
=>
{
const
mockModalShow
=
jest
.
spyOn
(
wrapper
.
vm
.
$refs
.
packageListDeleteModal
,
'
show
'
);
const
item
=
last
(
wrapper
.
vm
.
list
);
findPackagesListRow
().
vm
.
$emit
(
'
packageToDelete
'
,
item
);
return
wrapper
.
vm
.
$nextTick
().
then
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
vm
.
itemToBeDeleted
).
toEqual
(
item
);
expect
(
mockModalShow
).
toHaveBeenCalled
();
});
});
it
(
'
deleteItemConfirmation resets itemToBeDeleted
'
,
()
=>
{
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
...
...
@@ -140,16 +139,15 @@ describe('packages_list', () => {
expect
(
wrapper
.
vm
.
itemToBeDeleted
).
toEqual
(
null
);
});
it
(
'
deleteItemConfirmation emit package:delete
'
,
()
=>
{
it
(
'
deleteItemConfirmation emit package:delete
'
,
async
()
=>
{
const
itemToBeDeleted
=
{
id
:
2
};
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
wrapper
.
setData
({
itemToBeDeleted
});
wrapper
.
vm
.
deleteItemConfirmation
();
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
emitted
(
'
package:delete
'
)[
0
]).
toEqual
([
itemToBeDeleted
]);
});
});
it
(
'
deleteItemCanceled resets itemToBeDeleted
'
,
()
=>
{
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
...
...
spec/frontend/packages_and_registries/infrastructure_registry/components/shared/package_list_row_spec.js
View file @
8af0ee79
import
{
GlLink
}
from
'
@gitlab/ui
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
{
createMockDirective
,
getBinding
}
from
'
helpers/vue_mock_directive
'
;
...
...
@@ -126,7 +127,7 @@ describe('packages_list_row', () => {
findDeleteButton
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
emitted
(
'
packageToDelete
'
)).
toBeTruthy
();
expect
(
wrapper
.
emitted
(
'
packageToDelete
'
)[
0
]).
toEqual
([
packageWithoutTags
]);
});
...
...
spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js
View file @
8af0ee79
import
{
GlIcon
,
GlSprintf
}
from
'
@gitlab/ui
'
;
import
{
GlBreakpointInstance
}
from
'
@gitlab/ui/dist/utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
createMockDirective
,
getBinding
}
from
'
helpers/vue_mock_directive
'
;
import
{
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
PackageTags
from
'
~/packages_and_registries/shared/components/package_tags.vue
'
;
...
...
@@ -24,7 +25,7 @@ const packageWithTags = {
describe
(
'
PackageTitle
'
,
()
=>
{
let
wrapper
;
function
createComponent
(
packageEntity
=
packageWithTags
)
{
async
function
createComponent
(
packageEntity
=
packageWithTags
)
{
wrapper
=
shallowMountExtended
(
PackageTitle
,
{
propsData
:
{
packageEntity
},
stubs
:
{
...
...
@@ -35,7 +36,7 @@ describe('PackageTitle', () => {
GlResizeObserver
:
createMockDirective
(),
},
});
return
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
}
const
findTitleArea
=
()
=>
wrapper
.
findComponent
(
TitleArea
);
...
...
@@ -71,7 +72,7 @@ describe('PackageTitle', () => {
await
createComponent
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findPackageBadges
()).
toHaveLength
(
packageTags
().
length
);
});
...
...
@@ -85,7 +86,7 @@ describe('PackageTitle', () => {
const
{
value
}
=
getBinding
(
wrapper
.
element
,
'
gl-resize-observer
'
);
value
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findPackageBadges
()).
toHaveLength
(
packageTags
().
length
);
});
});
...
...
spec/frontend/packages_and_registries/package_registry/components/list/package_list_row_spec.js
View file @
8af0ee79
import
{
GlSprintf
}
from
'
@gitlab/ui
'
;
import
Vue
from
'
vue
'
;
import
Vue
,
{
nextTick
}
from
'
vue
'
;
import
VueRouter
from
'
vue-router
'
;
import
{
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
{
createMockDirective
,
getBinding
}
from
'
helpers/vue_mock_directive
'
;
...
...
@@ -119,7 +119,7 @@ describe('packages_list_row', () => {
findDeleteButton
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
emitted
(
'
packageToDelete
'
)).
toBeTruthy
();
expect
(
wrapper
.
emitted
(
'
packageToDelete
'
)[
0
]).
toEqual
([
packageWithoutTags
]);
});
...
...
spec/frontend/packages_and_registries/settings/group/components/package_settings_spec.js
View file @
8af0ee79
import
{
GlSprintf
,
GlLink
}
from
'
@gitlab/ui
'
;
import
{
createLocalVue
}
from
'
@vue/test-utils
'
;
import
VueApollo
from
'
vue-apollo
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
createMockApollo
from
'
helpers/mock_apollo_helper
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
...
...
@@ -252,7 +253,7 @@ describe('Packages Settings', () => {
emitMavenSettingsUpdate
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
// errors are reset on mutation call
expect
(
findMavenDuplicatedSettings
().
props
(
'
duplicateExceptionRegexError
'
)).
toBe
(
''
);
...
...
spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js
View file @
8af0ee79
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
{
GlCard
,
GlLoadingIcon
}
from
'
jest/packages_and_registries/shared/stubs
'
;
...
...
@@ -201,7 +202,7 @@ describe('Settings Form', () => {
finder
().
vm
.
$emit
(
'
input
'
,
'
foo
'
);
expect
(
finder
().
props
(
'
error
'
)).
toEqual
(
'
bar
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
finder
().
props
(
'
error
'
)).
toEqual
(
''
);
});
...
...
@@ -213,7 +214,7 @@ describe('Settings Form', () => {
finder
().
vm
.
$emit
(
'
validation
'
,
false
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findSaveButton
().
props
(
'
disabled
'
)).
toBe
(
true
);
});
...
...
@@ -252,7 +253,7 @@ describe('Settings Form', () => {
findForm
().
trigger
(
'
reset
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findKeepRegexInput
().
props
(
'
error
'
)).
toBe
(
''
);
expect
(
findRemoveRegexInput
().
props
(
'
error
'
)).
toBe
(
''
);
...
...
@@ -319,7 +320,7 @@ describe('Settings Form', () => {
findForm
().
trigger
(
'
submit
'
);
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
vm
.
$toast
.
show
).
toHaveBeenCalledWith
(
UPDATE_SETTINGS_SUCCESS_MESSAGE
);
});
...
...
@@ -335,7 +336,7 @@ describe('Settings Form', () => {
findForm
().
trigger
(
'
submit
'
);
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
vm
.
$toast
.
show
).
toHaveBeenCalledWith
(
'
foo
'
);
});
...
...
@@ -349,7 +350,7 @@ describe('Settings Form', () => {
findForm
().
trigger
(
'
submit
'
);
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
vm
.
$toast
.
show
).
toHaveBeenCalledWith
(
UPDATE_SETTINGS_ERROR_MESSAGE
);
});
...
...
@@ -368,7 +369,7 @@ describe('Settings Form', () => {
findForm
().
trigger
(
'
submit
'
);
await
waitForPromises
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findKeepRegexInput
().
props
(
'
error
'
)).
toEqual
(
'
baz
'
);
});
...
...
spec/frontend/pages/admin/projects/components/namespace_select_spec.js
View file @
8af0ee79
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
Api
from
'
~/api
'
;
import
NamespaceSelect
from
'
~/pages/admin/projects/components/namespace_select.vue
'
;
...
...
@@ -55,14 +56,14 @@ describe('Dropdown select component', () => {
mountDropdown
({
fieldName
:
'
namespace-input
'
});
// wait for dropdown options to populate
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findDropdownOption
(
'
user: Administrator
'
).
exists
()).
toBe
(
true
);
expect
(
findDropdownOption
(
'
group: GitLab Org
'
).
exists
()).
toBe
(
true
);
expect
(
findDropdownOption
(
'
group: Foobar
'
).
exists
()).
toBe
(
false
);
findDropdownOption
(
'
user: Administrator
'
).
trigger
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findNamespaceInput
().
attributes
(
'
value
'
)).
toBe
(
'
10
'
);
expect
(
findDropdownToggle
().
text
()).
toBe
(
'
user: Administrator
'
);
...
...
@@ -72,7 +73,7 @@ describe('Dropdown select component', () => {
mountDropdown
();
// wait for dropdown options to populate
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
findDropdownOption
(
'
group: GitLab Org
'
).
trigger
(
'
click
'
);
...
...
spec/frontend/pages/profiles/password_prompt/password_prompt_modal_spec.js
View file @
8af0ee79
import
{
GlModal
}
from
'
@gitlab/ui
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
import
{
I18N_PASSWORD_PROMPT_CANCEL_BUTTON
,
...
...
@@ -62,7 +63,7 @@ describe('Password prompt modal', () => {
setPassword
(
mockPassword
);
submitModal
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
handleConfirmPasswordSpy
).
toHaveBeenCalledTimes
(
1
);
expect
(
handleConfirmPasswordSpy
).
toHaveBeenCalledWith
(
mockPassword
);
...
...
@@ -73,7 +74,7 @@ describe('Password prompt modal', () => {
expect
(
findConfirmBtnDisabledState
()).
toBe
(
true
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findConfirmBtnDisabledState
()).
toBe
(
false
);
});
...
...
@@ -84,7 +85,7 @@ describe('Password prompt modal', () => {
expect
(
findConfirmBtnDisabledState
()).
toBe
(
true
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findConfirmBtnDisabledState
()).
toBe
(
true
);
});
...
...
spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
View file @
8af0ee79
...
...
@@ -4,6 +4,7 @@ import { mount, shallowMount } from '@vue/test-utils';
import
axios
from
'
axios
'
;
import
AxiosMockAdapter
from
'
axios-mock-adapter
'
;
import
{
kebabCase
}
from
'
lodash
'
;
import
{
nextTick
}
from
'
vue
'
;
import
createFlash
from
'
~/flash
'
;
import
httpStatus
from
'
~/lib/utils/http_status
'
;
import
*
as
urlUtility
from
'
~/lib/utils/url_utility
'
;
...
...
@@ -217,7 +218,7 @@ describe('ForkForm component', () => {
it
(
'
changes to kebab case when project name changes
'
,
async
()
=>
{
const
newInput
=
`
${
projectPath
}
1`
;
findForkNameInput
().
vm
.
$emit
(
'
input
'
,
newInput
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findForkSlugInput
().
attributes
(
'
value
'
)).
toBe
(
kebabCase
(
newInput
));
});
...
...
@@ -225,7 +226,7 @@ describe('ForkForm component', () => {
it
(
'
does not change to kebab case when project slug is changed manually
'
,
async
()
=>
{
const
newInput
=
`
${
projectPath
}
1`
;
findForkSlugInput
().
vm
.
$emit
(
'
input
'
,
newInput
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findForkSlugInput
().
attributes
(
'
value
'
)).
toBe
(
newInput
);
});
...
...
@@ -273,7 +274,7 @@ describe('ForkForm component', () => {
expect
(
wrapper
.
vm
.
form
.
fields
.
visibility
.
value
).
toBe
(
'
public
'
);
await
findFormSelectOptions
().
at
(
1
).
setSelected
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
getByRole
(
wrapper
.
element
,
'
radio
'
,
{
name
:
/private/i
}).
checked
).
toBe
(
true
);
});
...
...
@@ -283,7 +284,7 @@ describe('ForkForm component', () => {
await
findFormSelectOptions
().
at
(
1
).
setSelected
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
const
container
=
getByRole
(
wrapper
.
element
,
'
radiogroup
'
,
{
name
:
/visibility/i
});
const
visibilityRadios
=
getAllByRole
(
container
,
'
radio
'
);
...
...
@@ -419,7 +420,7 @@ describe('ForkForm component', () => {
const
form
=
wrapper
.
find
(
GlForm
);
await
form
.
trigger
(
'
submit
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
};
describe
(
'
with invalid form
'
,
()
=>
{
...
...
spec/frontend/pages/projects/graphs/code_coverage_spec.js
View file @
8af0ee79
...
...
@@ -3,6 +3,7 @@ import { GlAreaChart } from '@gitlab/ui/dist/charts';
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
{
nextTick
}
from
'
vue
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
httpStatusCodes
from
'
~/lib/utils/http_status
'
;
...
...
@@ -143,7 +144,7 @@ describe('Code Coverage', () => {
it
(
'
updates the selected dropdown option with an icon
'
,
async
()
=>
{
findSecondDropdownItem
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findFirstDropdownItem
().
attributes
(
'
ischecked
'
)).
toBeFalsy
();
expect
(
findSecondDropdownItem
().
attributes
(
'
ischecked
'
)).
toBeTruthy
();
...
...
@@ -155,7 +156,7 @@ describe('Code Coverage', () => {
findSecondDropdownItem
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
wrapper
.
vm
.
selectedDailyCoverage
).
not
.
toBe
(
originalSelectedData
);
expect
(
wrapper
.
vm
.
selectedDailyCoverage
).
toBe
(
expectedData
);
...
...
spec/frontend/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js
View file @
8af0ee79
import
{
GlIcon
}
from
'
@gitlab/ui
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
{
trimText
}
from
'
helpers/text_helper
'
;
import
IntervalPatternInput
from
'
~/pages/projects/pipeline_schedules/shared/components/interval_pattern_input.vue
'
;
...
...
@@ -98,7 +99,7 @@ describe('Interval Pattern Input Component', () => {
it
(
'
when a default option is selected
'
,
async
()
=>
{
selectEveryDayRadio
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findCustomInput
().
attributes
(
'
disabled
'
)).
toBeUndefined
();
});
...
...
@@ -106,7 +107,7 @@ describe('Interval Pattern Input Component', () => {
it
(
'
when the custom option is selected
'
,
async
()
=>
{
selectCustomRadio
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findCustomInput
().
attributes
(
'
disabled
'
)).
toBeUndefined
();
});
...
...
@@ -150,11 +151,11 @@ describe('Interval Pattern Input Component', () => {
it
(
'
when everyday is selected, update value
'
,
async
()
=>
{
selectEveryWeekRadio
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findCustomInput
().
element
.
value
).
toBe
(
cronIntervalPresets
.
everyWeek
);
selectEveryDayRadio
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findCustomInput
().
element
.
value
).
toBe
(
cronIntervalPresets
.
everyDay
);
});
});
...
...
@@ -170,7 +171,7 @@ describe('Interval Pattern Input Component', () => {
act
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findCustomInput
().
element
.
value
).
toBe
(
expectedValue
);
});
...
...
@@ -189,7 +190,7 @@ describe('Interval Pattern Input Component', () => {
findCustomInput
().
setValue
(
newValue
);
await
wrapper
.
vm
.
$
nextTick
;
await
nextTick
;
expect
(
findSelectedRadioKey
()).
toBe
(
customKey
);
});
...
...
spec/frontend/pages/projects/pipeline_schedules/shared/components/pipeline_schedule_callout_spec.js
View file @
8af0ee79
import
{
GlButton
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Cookies
from
'
js-cookie
'
;
import
{
nextTick
}
from
'
vue
'
;
import
PipelineSchedulesCallout
from
'
~/pages/projects/pipeline_schedules/shared/components/pipeline_schedules_callout.vue
'
;
const
cookieKey
=
'
pipeline_schedules_callout_dismissed
'
;
...
...
@@ -27,7 +28,7 @@ describe('Pipeline Schedule Callout', () => {
Cookies
.
set
(
cookieKey
,
true
);
createComponent
();
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
afterEach
(()
=>
{
...
...
@@ -71,7 +72,7 @@ describe('Pipeline Schedule Callout', () => {
findDismissCalloutBtn
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findInnerContentOfCallout
().
exists
()).
toBe
(
false
);
});
...
...
@@ -90,7 +91,7 @@ describe('Pipeline Schedule Callout', () => {
it
(
'
is hidden when close button is clicked
'
,
async
()
=>
{
findDismissCalloutBtn
().
vm
.
$emit
(
'
click
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
expect
(
findInnerContentOfCallout
().
exists
()).
toBe
(
false
);
});
...
...
spec/frontend/pages/projects/shared/permissions/components/project_setting_row_spec.js
View file @
8af0ee79
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
nextTick
}
from
'
vue
'
;
import
projectSettingRow
from
'
~/pages/projects/shared/permissions/components/project_setting_row.vue
'
;
describe
(
'
Project Setting Row
'
,
()
=>
{
...
...
@@ -18,44 +19,40 @@ describe('Project Setting Row', () => {
wrapper
.
destroy
();
});
it
(
'
should show the label if it is set
'
,
()
=>
{
it
(
'
should show the label if it is set
'
,
async
()
=>
{
wrapper
.
setProps
({
label
:
'
Test label
'
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
'
label
'
).
text
()).
toEqual
(
'
Test label
'
);
});
});
it
(
'
should hide the label if it is not set
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
label
'
).
exists
()).
toBe
(
false
);
});
it
(
'
should show the help icon with the correct help path if it is set
'
,
()
=>
{
it
(
'
should show the help icon with the correct help path if it is set
'
,
async
()
=>
{
wrapper
.
setProps
({
label
:
'
Test label
'
,
helpPath
:
'
/123
'
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
const
link
=
wrapper
.
find
(
'
a
'
);
expect
(
link
.
exists
()).
toBe
(
true
);
expect
(
link
.
attributes
().
href
).
toEqual
(
'
/123
'
);
});
});
it
(
'
should hide the help icon if no help path is set
'
,
()
=>
{
it
(
'
should hide the help icon if no help path is set
'
,
async
()
=>
{
wrapper
.
setProps
({
label
:
'
Test label
'
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
'
a
'
).
exists
()).
toBe
(
false
);
});
});
it
(
'
should show the help text if it is set
'
,
()
=>
{
it
(
'
should show the help text if it is set
'
,
async
()
=>
{
wrapper
.
setProps
({
helpText
:
'
Test text
'
});
return
wrapper
.
vm
.
$nextTick
(()
=>
{
await
nextTick
();
expect
(
wrapper
.
find
(
'
span
'
).
text
()).
toEqual
(
'
Test text
'
);
});
});
it
(
'
should hide the help text if it is set
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
span
'
).
exists
()).
toBe
(
false
);
...
...
spec/frontend/pages/shared/wikis/components/wiki_form_spec.js
View file @
8af0ee79
...
...
@@ -48,10 +48,10 @@ describe('WikiForm', () => {
return
format
.
find
(
`option[value=
${
value
}
]`
).
setSelected
();
};
const
triggerFormSubmit
=
()
=>
{
const
triggerFormSubmit
=
async
()
=>
{
findForm
().
element
.
dispatchEvent
(
new
Event
(
'
submit
'
));
return
nextTick
();
await
nextTick
();
};
const
dispatchBeforeUnload
=
()
=>
{
...
...
@@ -574,7 +574,7 @@ describe('WikiForm', () => {
wrapper
.
findComponent
(
GlModal
).
vm
.
$emit
(
'
primary
'
);
await
wrapper
.
vm
.
$
nextTick
();
await
nextTick
();
});
it
(
'
switches to classic editor
'
,
()
=>
{
...
...
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