From 9f46488805e86b1bc341ea1620b866016c2ce5ed Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 20 May 2020 14:34:42 +0000 Subject: Add latest changes from gitlab-org/gitlab@13-0-stable-ee --- spec/frontend/.eslintrc.yml | 17 +- .../__mocks__/@toast-ui/vue-editor/index.js | 29 + spec/frontend/ajax_loading_spinner_spec.js | 57 + .../components/alert_management_detail_spec.js | 242 ++ .../components/alert_management_list_spec.js | 325 ++ spec/frontend/alert_management/mocks/alerts.json | 29 + spec/frontend/api_spec.js | 2 +- spec/frontend/autosave_spec.js | 90 +- spec/frontend/avatar_helper_spec.js | 110 + .../markdown/paste_markdown_table_spec.js | 12 + .../behaviors/markdown/render_metrics_spec.js | 36 +- .../__snapshots__/blob_edit_header_spec.js.snap | 2 +- .../blob_header_filepath_spec.js.snap | 11 +- .../__snapshots__/blob_header_spec.js.snap | 2 +- .../blob/components/blob_content_error_spec.js | 51 +- spec/frontend/blob/components/blob_content_spec.js | 36 +- .../blob/components/blob_header_filepath_spec.js | 10 +- spec/frontend/blob/components/blob_header_spec.js | 2 +- spec/frontend/blob/components/mock_data.js | 2 +- .../blob/pipeline_tour_success_modal_spec.js | 2 +- .../components/popover_spec.js | 9 +- spec/frontend/blob/utils_spec.js | 42 - spec/frontend/boards/board_list_spec.js | 2 +- spec/frontend/boards/boards_store_spec.js | 137 + spec/frontend/boards/issue_spec.js | 22 +- spec/frontend/bootstrap_linked_tabs_spec.js | 67 + spec/frontend/broadcast_notification_spec.js | 35 + .../ci_variable_list/ajax_variable_list_spec.js | 203 ++ .../ci_variable_list/ci_variable_list_spec.js | 282 ++ .../native_form_variable_list_spec.js | 37 + .../components/ci_variable_modal_spec.js | 7 + .../ci_variable_list/services/mock_data.js | 12 +- .../ci_variable_list/store/actions_spec.js | 10 + .../ci_variable_list/store/mutations_spec.js | 10 +- spec/frontend/close_reopen_report_toggle_spec.js | 288 ++ .../clusters/components/applications_spec.js | 33 + .../components/fluentd_output_settings_spec.js | 186 + .../components/knative_domain_editor_spec.js | 2 +- spec/frontend/clusters/services/mock_data.js | 1 + .../clusters/stores/clusters_store_spec.js | 18 + .../clusters_list/components/clusters_spec.js | 110 +- spec/frontend/clusters_list/mock_data.js | 18 +- spec/frontend/clusters_list/store/actions_spec.js | 29 +- .../components/__snapshots__/popover_spec.js.snap | 11 +- .../code_navigation/components/app_spec.js | 1 + .../code_navigation/components/popover_spec.js | 41 +- .../frontend/code_navigation/store/actions_spec.js | 28 +- spec/frontend/commit/pipelines/pipelines_spec.js | 44 +- spec/frontend/commit_merge_requests_spec.js | 69 + spec/frontend/commits_spec.js | 98 + spec/frontend/contributors/store/actions_spec.js | 3 - spec/frontend/contributors/store/getters_spec.js | 3 - .../services/aws_services_facade_spec.js | 14 +- spec/frontend/create_item_dropdown_spec.js | 195 ++ .../components/custom_metrics_form_fields_spec.js | 1 - .../deploy_keys/components/action_btn_spec.js | 54 + spec/frontend/deploy_keys/components/app_spec.js | 142 + spec/frontend/deploy_keys/components/key_spec.js | 161 + .../deploy_keys/components/keys_panel_spec.js | 63 + .../__snapshots__/design_note_pin_spec.js.snap | 42 + .../__snapshots__/design_presentation_spec.js.snap | 104 + .../__snapshots__/design_scaler_spec.js.snap | 115 + .../components/__snapshots__/image_spec.js.snap | 68 + .../components/delete_button_spec.js | 51 + .../components/design_note_pin_spec.js | 49 + .../__snapshots__/design_note_spec.js.snap | 61 + .../__snapshots__/design_reply_form_spec.js.snap | 15 + .../design_notes/design_discussion_spec.js | 133 + .../components/design_notes/design_note_spec.js | 170 + .../design_notes/design_reply_form_spec.js | 182 + .../components/design_overlay_spec.js | 393 +++ .../components/design_presentation_spec.js | 546 +++ .../components/design_scaler_spec.js | 67 + .../design_management/components/image_spec.js | 133 + .../list/__snapshots__/item_spec.js.snap | 472 +++ .../design_management/components/list/item_spec.js | 168 + .../toolbar/__snapshots__/index_spec.js.snap | 61 + .../__snapshots__/pagination_button_spec.js.snap | 28 + .../toolbar/__snapshots__/pagination_spec.js.snap | 29 + .../components/toolbar/index_spec.js | 123 + .../components/toolbar/pagination_button_spec.js | 61 + .../components/toolbar/pagination_spec.js | 79 + .../upload/__snapshots__/button_spec.js.snap | 79 + .../__snapshots__/design_dropzone_spec.js.snap | 455 +++ .../design_version_dropdown_spec.js.snap | 111 + .../components/upload/button_spec.js | 59 + .../components/upload/design_dropzone_spec.js | 132 + .../upload/design_version_dropdown_spec.js | 114 + .../components/upload/mock_data/all_versions.js | 14 + .../design_management/mock_data/all_versions.js | 8 + .../frontend/design_management/mock_data/design.js | 54 + .../design_management/mock_data/designs.js | 17 + .../design_management/mock_data/no_designs.js | 11 + spec/frontend/design_management/mock_data/notes.js | 32 + .../pages/__snapshots__/index_spec.js.snap | 263 ++ .../pages/design/__snapshots__/index_spec.js.snap | 184 + .../design_management/pages/design/index_spec.js | 301 ++ .../frontend/design_management/pages/index_spec.js | 533 +++ spec/frontend/design_management/router_spec.js | 81 + .../design_management/utils/cache_update_spec.js | 44 + .../utils/design_management_utils_spec.js | 176 + .../design_management/utils/error_messages_spec.js | 62 + .../design_management/utils/tracking_spec.js | 53 + spec/frontend/diff_comments_store_spec.js | 136 + spec/frontend/diffs/components/app_spec.js | 212 +- spec/frontend/diffs/components/commit_item_spec.js | 144 +- .../frontend/diffs/components/diff_content_spec.js | 2 +- .../diffs/components/diff_discussions_spec.js | 2 +- .../diffs/components/diff_expansion_cell_spec.js | 2 +- .../diffs/components/diff_gutter_avatars_spec.js | 2 +- .../diffs/components/diff_line_note_form_spec.js | 2 +- spec/frontend/diffs/components/edit_button_spec.js | 19 +- .../components/inline_diff_expansion_row_spec.js | 2 +- .../diffs/components/inline_diff_view_spec.js | 4 +- .../components/parallel_diff_expansion_row_spec.js | 2 +- .../diffs/components/parallel_diff_view_spec.js | 2 +- spec/frontend/diffs/store/actions_spec.js | 184 +- spec/frontend/diffs/store/getters_spec.js | 4 +- .../diffs/store/getters_versions_dropdowns_spec.js | 9 - spec/frontend/diffs/store/mutations_spec.js | 30 + spec/frontend/diffs/store/utils_spec.js | 84 +- .../dirty_submit/dirty_submit_collection_spec.js | 22 + .../dirty_submit/dirty_submit_factory_spec.js | 18 + .../dirty_submit/dirty_submit_form_spec.js | 97 + spec/frontend/dirty_submit/helper.js | 43 + spec/frontend/editor/editor_lite_spec.js | 177 + spec/frontend/emoji_spec.js | 485 +++ .../feature_highlight_helper_spec.js | 62 + .../feature_highlight_options_spec.js | 44 +- .../feature_highlight/feature_highlight_spec.js | 120 + .../filtered_search/dropdown_utils_spec.js | 374 +++ .../filtered_search_manager_spec.js | 587 ++++ .../filtered_search_tokenizer_spec.js | 152 + .../issues_filtered_search_token_keys_spec.js | 148 + .../filtered_search/recent_searches_root_spec.js | 32 + .../services/recent_searches_service_spec.js | 161 + .../filtered_search/visual_token_value_spec.js | 389 +++ spec/frontend/fixtures/test_report.rb | 2 +- spec/frontend/flash_spec.js | 233 ++ .../frontend/frequent_items/components/app_spec.js | 251 ++ spec/frontend/frequent_items/mock_data.js | 127 +- spec/frontend/frequent_items/store/actions_spec.js | 228 ++ .../frequent_items/store/mutations_spec.js | 117 + spec/frontend/frequent_items/utils_spec.js | 130 + spec/frontend/groups/components/app_spec.js | 507 +++ .../groups/components/group_folder_spec.js | 65 + spec/frontend/groups/components/group_item_spec.js | 215 ++ spec/frontend/groups/components/groups_spec.js | 72 + .../groups/components/item_actions_spec.js | 84 + spec/frontend/groups/components/item_caret_spec.js | 38 + spec/frontend/groups/components/item_stats_spec.js | 119 + .../groups/components/item_stats_value_spec.js | 82 + .../groups/components/item_type_icon_spec.js | 53 + spec/frontend/groups/mock_data.js | 398 +++ .../frontend/groups/service/groups_service_spec.js | 42 + spec/frontend/groups/store/groups_store_spec.js | 123 + spec/frontend/header_spec.js | 16 +- spec/frontend/helpers/class_spec_helper.js | 1 + spec/frontend/helpers/event_hub_factory_spec.js | 94 + .../helpers/filtered_search_spec_helper.js | 69 + spec/frontend/helpers/fixtures.js | 5 +- .../frontend/helpers/set_window_location_helper.js | 40 + .../helpers/set_window_location_helper_spec.js | 40 + .../frontend/helpers/vue_mount_component_helper.js | 25 + spec/frontend/helpers/web_worker_mock.js | 10 + spec/frontend/ide/components/activity_bar_spec.js | 72 + .../commit_sidebar/editor_header_spec.js | 50 +- .../ide/components/commit_sidebar/form_spec.js | 111 +- .../ide/components/commit_sidebar/list_spec.js | 2 - .../components/commit_sidebar/radio_group_spec.js | 134 + .../frontend/ide/components/file_row_extra_spec.js | 170 + .../ide/components/file_templates/bar_spec.js | 117 + spec/frontend/ide/components/ide_review_spec.js | 73 + spec/frontend/ide/components/ide_side_bar_spec.js | 57 + spec/frontend/ide/components/ide_spec.js | 125 + .../frontend/ide/components/ide_status_bar_spec.js | 127 + spec/frontend/ide/components/ide_tree_list_spec.js | 77 + spec/frontend/ide/components/ide_tree_spec.js | 34 + .../ide/components/jobs/detail/description_spec.js | 28 + spec/frontend/ide/components/jobs/item_spec.js | 39 + .../ide/components/merge_requests/item_spec.js | 63 + .../ide/components/nav_dropdown_button_spec.js | 93 + spec/frontend/ide/components/nav_dropdown_spec.js | 102 + .../ide/components/new_dropdown/button_spec.js | 65 + .../ide/components/new_dropdown/index_spec.js | 84 + .../ide/components/new_dropdown/modal_spec.js | 175 + .../ide/components/new_dropdown/upload_spec.js | 112 + .../frontend/ide/components/pipelines/list_spec.js | 17 +- .../ide/components/preview/clientside_spec.js | 8 - .../ide/components/repo_commit_section_spec.js | 1 - spec/frontend/ide/components/repo_tab_spec.js | 185 + spec/frontend/ide/components/repo_tabs_spec.js | 35 + .../ide/components/shared/tokened_input_spec.js | 133 + spec/frontend/ide/lib/common/model_manager_spec.js | 126 + spec/frontend/ide/lib/common/model_spec.js | 137 + .../ide/lib/decorations/controller_spec.js | 143 + spec/frontend/ide/lib/diff/controller_spec.js | 215 ++ spec/frontend/ide/lib/editor_spec.js | 302 ++ spec/frontend/ide/lib/languages/vue_spec.js | 92 + spec/frontend/ide/services/index_spec.js | 63 + spec/frontend/ide/stores/mutations_spec.js | 41 - spec/frontend/ide/stores/utils_spec.js | 71 + spec/frontend/ide/utils_spec.js | 92 +- .../image_diff/helpers/badge_helper_spec.js | 130 + .../helpers/comment_indicator_helper_spec.js | 144 + .../frontend/image_diff/helpers/dom_helper_spec.js | 120 + .../image_diff/helpers/utils_helper_spec.js | 152 + spec/frontend/image_diff/image_badge_spec.js | 84 + spec/frontend/image_diff/image_diff_spec.js | 361 ++ spec/frontend/image_diff/mock_data.js | 28 + .../image_diff/replaced_image_diff_spec.js | 356 ++ .../components/import_projects_table_spec.js | 5 +- .../components/provider_repo_table_row_spec.js | 4 +- .../edit/components/active_toggle_spec.js | 8 +- .../edit/components/integration_form_spec.js | 99 + .../edit/components/jira_trigger_fields_spec.js | 97 + .../edit/components/trigger_fields_spec.js | 136 + .../integrations/integration_settings_form_spec.js | 268 ++ spec/frontend/issuable_spec.js | 64 + .../components/issuable_list_root_app_spec.js | 121 + spec/frontend/issue_show/components/app_spec.js | 497 +++ .../issue_show/components/description_spec.js | 188 ++ spec/frontend/issue_show/components/edited_spec.js | 49 + .../components/fields/description_template_spec.js | 41 + spec/frontend/issue_show/components/form_spec.js | 99 + spec/frontend/issue_show/components/title_spec.js | 95 + .../jira_import/components/jira_import_app_spec.js | 102 +- .../components/jira_import_form_spec.js | 31 +- .../components/jira_import_progress_spec.js | 21 +- .../components/jira_import_setup_spec.js | 18 +- spec/frontend/jira_import/utils_spec.js | 65 +- .../jobs/components/artifacts_block_spec.js | 119 + spec/frontend/jobs/components/commit_block_spec.js | 89 + spec/frontend/jobs/components/empty_state_spec.js | 141 + .../jobs/components/environments_block_spec.js | 261 ++ .../jobs/components/job_container_item_spec.js | 101 + spec/frontend/jobs/components/job_log_spec.js | 65 + .../jobs/components/jobs_container_spec.js | 131 + .../jobs/components/log/line_header_spec.js | 2 +- .../jobs/components/manual_variables_form_spec.js | 103 + spec/frontend/jobs/components/sidebar_spec.js | 166 + .../jobs/components/stages_dropdown_spec.js | 163 + .../frontend/jobs/components/trigger_block_spec.js | 100 + .../components/unmet_prerequisites_block_spec.js | 37 + .../frontend/jobs/mixins/delayed_job_mixin_spec.js | 79 + spec/frontend/jobs/store/actions_spec.js | 512 +++ spec/frontend/jobs/store/helpers.js | 6 + spec/frontend/jobs/store/mutations_spec.js | 2 +- spec/frontend/labels_select_spec.js | 15 - spec/frontend/landing_spec.js | 184 + spec/frontend/lib/utils/axios_utils_spec.js | 1 + spec/frontend/lib/utils/common_utils_spec.js | 2 +- spec/frontend/lib/utils/csrf_token_spec.js | 57 + spec/frontend/lib/utils/downloader_spec.js | 40 + spec/frontend/lib/utils/navigation_utility_spec.js | 23 + spec/frontend/lib/utils/poll_spec.js | 225 ++ spec/frontend/lib/utils/sticky_spec.js | 77 + spec/frontend/lib/utils/text_markdown_spec.js | 8 +- spec/frontend/lib/utils/url_utility_spec.js | 147 +- spec/frontend/milestones/mock_data.js | 82 + .../milestones/project_milestone_combobox_spec.js | 150 + .../frontend/mocks/ce/diffs/workers/tree_worker.js | 9 +- spec/frontend/mocks/ce/ide/lib/diff/diff_worker.js | 1 + spec/frontend/mocks_spec.js | 13 +- .../__snapshots__/alert_widget_spec.js.snap | 43 + spec/frontend/monitoring/alert_widget_spec.js | 422 +++ .../__snapshots__/dashboard_template_spec.js.snap | 25 +- .../components/alert_widget_form_spec.js | 220 ++ .../components/charts/single_stat_spec.js | 14 +- .../components/charts/time_series_spec.js | 43 +- .../monitoring/components/dashboard_panel_spec.js | 576 ++++ .../monitoring/components/dashboard_spec.js | 549 ++- .../components/dashboard_template_spec.js | 15 +- .../components/dashboard_url_time_spec.js | 2 +- .../components/dashboards_dropdown_spec.js | 127 +- .../components/duplicate_dashboard_form_spec.js | 26 +- .../components/embeds/metric_embed_spec.js | 10 +- .../monitoring/components/panel_type_spec.js | 408 --- .../components/variables/custom_variable_spec.js | 52 + .../components/variables/text_variable_spec.js | 59 + .../components/variables_section_spec.js | 126 + spec/frontend/monitoring/mock_data.js | 231 +- spec/frontend/monitoring/store/actions_spec.js | 180 +- spec/frontend/monitoring/store/getters_spec.js | 84 +- spec/frontend/monitoring/store/mutations_spec.js | 92 + spec/frontend/monitoring/store/utils_spec.js | 6 + .../monitoring/store/variable_mapping_spec.js | 22 + spec/frontend/monitoring/store_utils.js | 43 +- spec/frontend/monitoring/stubs/modal_stub.js | 11 + spec/frontend/monitoring/utils_spec.js | 302 +- spec/frontend/monitoring/validators_spec.js | 80 + spec/frontend/notebook/cells/code_spec.js | 90 + spec/frontend/notebook/cells/markdown_spec.js | 167 + .../notebook/cells/output/html_sanitize_tests.js | 68 + spec/frontend/notebook/cells/output/html_spec.js | 31 + spec/frontend/notebook/cells/output/index_spec.js | 115 + spec/frontend/notebook/cells/prompt_spec.js | 56 + spec/frontend/notebook/index_spec.js | 100 + .../frontend/notes/components/comment_form_spec.js | 7 +- .../notes/components/discussion_actions_spec.js | 2 +- .../notes/components/discussion_counter_spec.js | 9 +- .../notes/components/discussion_filter_spec.js | 4 +- .../notes/components/discussion_notes_spec.js | 2 +- spec/frontend/notes/components/note_form_spec.js | 8 +- spec/frontend/notes/components/note_header_spec.js | 94 +- .../notes/components/noteable_discussion_spec.js | 2 +- spec/frontend/notes/components/notes_app_spec.js | 2 +- .../notes/mixins/discussion_navigation_spec.js | 4 +- spec/frontend/notes/mock_data.js | 1 + spec/frontend/notes/old_notes_spec.js | 52 +- spec/frontend/notes/stores/actions_spec.js | 31 +- spec/frontend/notes/stores/collapse_utils_spec.js | 4 +- spec/frontend/notes/stores/mutation_spec.js | 56 +- spec/frontend/oauth_remember_me_spec.js | 39 + .../account_and_limits_spec.js | 36 + .../jobs/index/components/stop_jobs_modal_spec.js | 64 + .../__snapshots__/delete_user_modal_spec.js.snap | 1 - spec/frontend/pages/admin/users/new/index_spec.js | 43 + .../labels/components/promote_label_modal_spec.js | 103 + .../components/delete_milestone_modal_spec.js | 109 + .../components/promote_milestone_modal_spec.js | 98 + .../components/interval_pattern_input_spec.js | 154 + .../components/pipeline_schedule_callout_spec.js | 114 + .../permissions/components/settings_panel_spec.js | 29 +- .../sessions/new/preserve_url_fragment_spec.js | 61 + .../components/pipelines_filtered_search_spec.js | 97 + .../pipelines/graph/stage_column_component_spec.js | 2 +- spec/frontend/pipelines/header_component_spec.js | 116 + spec/frontend/pipelines/linked_pipelines_mock.json | 3536 ++++++++++++++++++++ spec/frontend/pipelines/mock_data.js | 568 ++++ .../pipelines/pipeline_details_mediator_spec.js | 36 + spec/frontend/pipelines/pipelines_actions_spec.js | 142 + .../frontend/pipelines/pipelines_artifacts_spec.js | 46 + spec/frontend/pipelines/pipelines_spec.js | 710 ++++ .../frontend/pipelines/pipelines_table_row_spec.js | 2 +- spec/frontend/pipelines/pipelines_table_spec.js | 66 + spec/frontend/pipelines/stage_spec.js | 156 + .../pipelines/stores/pipeline_store_spec.js | 135 + .../test_reports/stores/mutations_spec.js | 6 +- .../pipelines/test_reports/test_summary_spec.js | 18 +- .../test_reports/test_summary_table_spec.js | 36 + spec/frontend/pipelines/time_ago_spec.js | 67 + .../tokens/pipeline_branch_name_token_spec.js | 89 + .../tokens/pipeline_trigger_author_token_spec.js | 98 + spec/frontend/pipelines_spec.js | 19 + .../prometheus_metrics/custom_metrics_spec.js | 2 +- spec/frontend/prometheus_metrics/mock_data.js | 44 +- .../prometheus_metrics/prometheus_metrics_spec.js | 178 + .../explorer/components/image_list_spec.js | 74 + spec/frontend/registry/explorer/mock_data.js | 8 + .../registry/explorer/pages/details_spec.js | 198 +- .../frontend/registry/explorer/pages/index_spec.js | 36 - spec/frontend/registry/explorer/pages/list_spec.js | 269 +- .../registry/explorer/stores/actions_spec.js | 20 +- spec/frontend/registry/explorer/stubs.js | 5 + .../registry/settings/store/getters_spec.js | 14 + .../expiration_policy_fields_spec.js.snap | 18 +- .../components/expiration_policy_fields_spec.js | 37 +- .../components/related_merge_requests_spec.js | 94 + .../related_merge_requests/store/actions_spec.js | 111 + .../related_merge_requests/store/mutations_spec.js | 49 + spec/frontend/releases/components/app_edit_spec.js | 9 +- .../components/release_block_footer_spec.js | 81 +- .../components/release_block_metadata_spec.js | 67 + .../release_block_milestone_info_spec.js | 4 +- .../releases/components/release_block_spec.js | 13 +- .../releases/stores/modules/detail/actions_spec.js | 12 +- .../stores/modules/detail/mutations_spec.js | 31 +- .../grouped_accessibility_reports_app_spec.js | 126 + .../reports/accessibility_report/mock_data.js | 55 + .../accessibility_report/store/actions_spec.js | 121 + .../accessibility_report/store/getters_spec.js | 149 + .../accessibility_report/store/mutations_spec.js | 64 + .../__snapshots__/grouped_issues_list_spec.js.snap | 25 + .../__snapshots__/issue_status_icon_spec.js.snap | 37 + .../reports/components/grouped_issues_list_spec.js | 86 + .../components/grouped_test_reports_app_spec.js | 260 ++ .../reports/components/issue_status_icon_spec.js | 29 + .../reports/components/modal_open_name_spec.js | 47 + spec/frontend/reports/components/modal_spec.js | 54 + .../reports/components/summary_row_spec.js | 37 + .../reports/components/test_issue_body_spec.js | 72 + spec/frontend/reports/mock_data/mock_data.js | 24 + .../mock_data/new_and_fixed_failures_report.json | 55 + .../reports/mock_data/new_errors_report.json | 38 + .../reports/mock_data/new_failures_report.json | 38 + .../reports/mock_data/no_failures_report.json | 28 + .../reports/mock_data/resolved_failures.json | 58 + spec/frontend/reports/store/actions_spec.js | 171 + spec/frontend/reports/store/mutations_spec.js | 126 + .../__snapshots__/last_commit_spec.js.snap | 8 +- .../repository/components/last_commit_spec.js | 1 + spec/frontend/repository/utils/commit_spec.js | 2 + spec/frontend/settings_panels_spec.js | 45 + .../confidential_issue_sidebar_spec.js.snap | 12 +- spec/frontend/sidebar/assignees_realtime_spec.js | 102 + .../components/time_tracking/time_tracker_spec.js | 279 ++ .../sidebar/confidential/edit_form_buttons_spec.js | 41 + .../sidebar/confidential/edit_form_spec.js | 45 + .../sidebar/confidential_edit_buttons_spec.js | 35 - .../sidebar/confidential_edit_form_buttons_spec.js | 35 - .../sidebar/confidential_issue_sidebar_spec.js | 25 +- .../sidebar/lock/edit_form_buttons_spec.js | 31 + .../sidebar/lock/lock_issue_sidebar_spec.js | 99 + spec/frontend/sidebar/participants_spec.js | 206 ++ spec/frontend/sidebar/sidebar_assignees_spec.js | 46 +- spec/frontend/sidebar/sidebar_mediator_spec.js | 135 + spec/frontend/sidebar/sidebar_move_issue_spec.js | 167 + .../frontend/sidebar/sidebar_subscriptions_spec.js | 36 + spec/frontend/sidebar/subscriptions_spec.js | 106 + spec/frontend/smart_interval_spec.js | 2 - spec/frontend/snippet/snippet_bundle_spec.js | 141 +- .../__snapshots__/snippet_blob_edit_spec.js.snap | 1 + .../snippet_description_edit_spec.js.snap | 4 +- .../snippet_description_view_spec.js.snap | 16 + spec/frontend/snippets/components/edit_spec.js | 16 + .../snippets/components/snippet_blob_view_spec.js | 38 +- .../components/snippet_description_view_spec.js | 27 + .../snippets/components/snippet_header_spec.js | 86 +- .../snippets/components/snippet_title_spec.js | 6 +- .../components/edit_area_spec.js | 76 + .../components/publish_toolbar_spec.js | 17 +- .../components/saved_changes_message_spec.js | 7 +- .../components/static_site_editor_spec.js | 247 -- .../graphql/resolvers/file_spec.js | 25 + .../resolvers/submit_content_changes_spec.js | 37 + spec/frontend/static_site_editor/mock_data.js | 5 + .../frontend/static_site_editor/pages/home_spec.js | 211 ++ .../static_site_editor/pages/success_spec.js | 78 + .../services/submit_content_changes_spec.js | 32 +- .../static_site_editor/store/actions_spec.js | 152 - .../static_site_editor/store/getters_spec.js | 19 - .../static_site_editor/store/mutations_spec.js | 54 - spec/frontend/tracking_spec.js | 57 +- spec/frontend/users_select/utils_spec.js | 33 + .../components/mr_collapsible_extension_spec.js | 4 +- .../mr_widget_pipeline_container_spec.js | 100 + .../components/mr_widget_terraform_plan_spec.js | 18 + .../stores/artifacts_list/actions_spec.js | 165 + .../vue_mr_widget/stores/get_state_key_spec.js | 24 + .../vue_mr_widget/stores/mr_widget_store_spec.js | 112 + .../__snapshots__/clone_dropdown_spec.js.snap | 38 +- .../__snapshots__/code_block_spec.js.snap | 16 +- .../__snapshots__/identicon_spec.js.snap | 12 +- .../vue_shared/components/awards_list_spec.js | 42 + .../__snapshots__/simple_viewer_spec.js.snap | 3 +- .../components/blob_viewers/rich_viewer_spec.js | 5 + .../vue_shared/components/ci_badge_link_spec.js | 100 + .../frontend/vue_shared/components/ci_icon_spec.js | 122 + .../vue_shared/components/code_block_spec.js | 29 +- .../content_viewer/content_viewer_spec.js | 21 + .../content_viewer/lib/viewer_utils_spec.js | 20 + .../content_viewer/viewers/download_viewer_spec.js | 28 + .../content_viewer/viewers/image_viewer_spec.js | 59 +- .../content_viewer/viewers/markdown_viewer_spec.js | 114 + .../date_time_picker/date_time_picker_lib_spec.js | 9 +- .../components/diff_viewer/diff_viewer_spec.js | 98 + .../components/dropdown/dropdown_button_spec.js | 81 + .../dropdown/dropdown_hidden_input_spec.js | 36 + .../vue_shared/components/dropdown/mock_data.js | 11 + .../vue_shared/components/file_finder/item_spec.js | 140 + .../vue_shared/components/file_row_spec.js | 8 +- .../components/filtered_search_dropdown_spec.js | 190 ++ .../vue_shared/components/gl_countdown_spec.js | 83 + .../components/header_ci_component_spec.js | 93 + .../vue_shared/components/identicon_spec.js | 37 +- .../components/issue/issue_milestone_spec.js | 44 +- .../components/issue/related_issuable_item_spec.js | 5 +- .../vue_shared/components/markdown/field_spec.js | 34 +- .../components/markdown/field_view_spec.js | 26 + .../components/markdown/suggestions_spec.js | 102 + .../vue_shared/components/markdown/toolbar_spec.js | 35 + .../vue_shared/components/navigation_tabs_spec.js | 64 + .../frontend/vue_shared/components/pikaday_spec.js | 30 + .../components/project_avatar/default_spec.js | 58 + .../project_selector/project_list_item_spec.js | 109 + .../project_selector/project_selector_spec.js | 112 + .../rich_content_editor_spec.js | 59 + .../rich_content_editor/toolbar_item_spec.js | 44 + .../rich_content_editor/toolbar_service_spec.js | 29 + .../components/sidebar/labels_select/base_spec.js | 5 +- .../sidebar/labels_select/dropdown_button_spec.js | 20 +- .../labels_select/dropdown_create_label_spec.js | 2 +- .../sidebar/labels_select/dropdown_footer_spec.js | 2 +- .../labels_select/dropdown_value_collapsed_spec.js | 2 +- .../sidebar/labels_select/dropdown_value_spec.js | 5 +- .../components/sidebar/labels_select/mock_data.js | 57 + .../labels_select_vue/dropdown_button_spec.js | 25 +- .../dropdown_contents_create_view_spec.js | 14 +- .../dropdown_contents_labels_view_spec.js | 91 +- .../sidebar/labels_select_vue/label_item_spec.js | 111 + .../labels_select_vue/labels_select_root_spec.js | 24 +- .../sidebar/labels_select_vue/mock_data.js | 3 +- .../labels_select_vue/store/actions_spec.js | 2 +- .../labels_select_vue/store/getters_spec.js | 24 +- .../labels_select_vue/store/mutations_spec.js | 5 +- .../components/stacked_progress_bar_spec.js | 104 + .../vue_shared/components/tabs/tab_spec.js | 32 + .../vue_shared/components/tabs/tabs_spec.js | 61 + .../vue_shared/components/toggle_button_spec.js | 101 + spec/frontend/wikis_spec.js | 26 + 501 files changed, 44616 insertions(+), 2547 deletions(-) create mode 100644 spec/frontend/__mocks__/@toast-ui/vue-editor/index.js create mode 100644 spec/frontend/ajax_loading_spinner_spec.js create mode 100644 spec/frontend/alert_management/components/alert_management_detail_spec.js create mode 100644 spec/frontend/alert_management/components/alert_management_list_spec.js create mode 100644 spec/frontend/alert_management/mocks/alerts.json create mode 100644 spec/frontend/avatar_helper_spec.js create mode 100644 spec/frontend/bootstrap_linked_tabs_spec.js create mode 100644 spec/frontend/broadcast_notification_spec.js create mode 100644 spec/frontend/ci_variable_list/ci_variable_list/ajax_variable_list_spec.js create mode 100644 spec/frontend/ci_variable_list/ci_variable_list/ci_variable_list_spec.js create mode 100644 spec/frontend/ci_variable_list/ci_variable_list/native_form_variable_list_spec.js create mode 100644 spec/frontend/close_reopen_report_toggle_spec.js create mode 100644 spec/frontend/clusters/components/fluentd_output_settings_spec.js create mode 100644 spec/frontend/commit_merge_requests_spec.js create mode 100644 spec/frontend/commits_spec.js create mode 100644 spec/frontend/create_item_dropdown_spec.js create mode 100644 spec/frontend/deploy_keys/components/action_btn_spec.js create mode 100644 spec/frontend/deploy_keys/components/app_spec.js create mode 100644 spec/frontend/deploy_keys/components/key_spec.js create mode 100644 spec/frontend/deploy_keys/components/keys_panel_spec.js create mode 100644 spec/frontend/design_management/components/__snapshots__/design_note_pin_spec.js.snap create mode 100644 spec/frontend/design_management/components/__snapshots__/design_presentation_spec.js.snap create mode 100644 spec/frontend/design_management/components/__snapshots__/design_scaler_spec.js.snap create mode 100644 spec/frontend/design_management/components/__snapshots__/image_spec.js.snap create mode 100644 spec/frontend/design_management/components/delete_button_spec.js create mode 100644 spec/frontend/design_management/components/design_note_pin_spec.js create mode 100644 spec/frontend/design_management/components/design_notes/__snapshots__/design_note_spec.js.snap create mode 100644 spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap create mode 100644 spec/frontend/design_management/components/design_notes/design_discussion_spec.js create mode 100644 spec/frontend/design_management/components/design_notes/design_note_spec.js create mode 100644 spec/frontend/design_management/components/design_notes/design_reply_form_spec.js create mode 100644 spec/frontend/design_management/components/design_overlay_spec.js create mode 100644 spec/frontend/design_management/components/design_presentation_spec.js create mode 100644 spec/frontend/design_management/components/design_scaler_spec.js create mode 100644 spec/frontend/design_management/components/image_spec.js create mode 100644 spec/frontend/design_management/components/list/__snapshots__/item_spec.js.snap create mode 100644 spec/frontend/design_management/components/list/item_spec.js create mode 100644 spec/frontend/design_management/components/toolbar/__snapshots__/index_spec.js.snap create mode 100644 spec/frontend/design_management/components/toolbar/__snapshots__/pagination_button_spec.js.snap create mode 100644 spec/frontend/design_management/components/toolbar/__snapshots__/pagination_spec.js.snap create mode 100644 spec/frontend/design_management/components/toolbar/index_spec.js create mode 100644 spec/frontend/design_management/components/toolbar/pagination_button_spec.js create mode 100644 spec/frontend/design_management/components/toolbar/pagination_spec.js create mode 100644 spec/frontend/design_management/components/upload/__snapshots__/button_spec.js.snap create mode 100644 spec/frontend/design_management/components/upload/__snapshots__/design_dropzone_spec.js.snap create mode 100644 spec/frontend/design_management/components/upload/__snapshots__/design_version_dropdown_spec.js.snap create mode 100644 spec/frontend/design_management/components/upload/button_spec.js create mode 100644 spec/frontend/design_management/components/upload/design_dropzone_spec.js create mode 100644 spec/frontend/design_management/components/upload/design_version_dropdown_spec.js create mode 100644 spec/frontend/design_management/components/upload/mock_data/all_versions.js create mode 100644 spec/frontend/design_management/mock_data/all_versions.js create mode 100644 spec/frontend/design_management/mock_data/design.js create mode 100644 spec/frontend/design_management/mock_data/designs.js create mode 100644 spec/frontend/design_management/mock_data/no_designs.js create mode 100644 spec/frontend/design_management/mock_data/notes.js create mode 100644 spec/frontend/design_management/pages/__snapshots__/index_spec.js.snap create mode 100644 spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap create mode 100644 spec/frontend/design_management/pages/design/index_spec.js create mode 100644 spec/frontend/design_management/pages/index_spec.js create mode 100644 spec/frontend/design_management/router_spec.js create mode 100644 spec/frontend/design_management/utils/cache_update_spec.js create mode 100644 spec/frontend/design_management/utils/design_management_utils_spec.js create mode 100644 spec/frontend/design_management/utils/error_messages_spec.js create mode 100644 spec/frontend/design_management/utils/tracking_spec.js create mode 100644 spec/frontend/diff_comments_store_spec.js create mode 100644 spec/frontend/dirty_submit/dirty_submit_collection_spec.js create mode 100644 spec/frontend/dirty_submit/dirty_submit_factory_spec.js create mode 100644 spec/frontend/dirty_submit/dirty_submit_form_spec.js create mode 100644 spec/frontend/dirty_submit/helper.js create mode 100644 spec/frontend/editor/editor_lite_spec.js create mode 100644 spec/frontend/emoji_spec.js create mode 100644 spec/frontend/feature_highlight/feature_highlight_helper_spec.js create mode 100644 spec/frontend/feature_highlight/feature_highlight_spec.js create mode 100644 spec/frontend/filtered_search/dropdown_utils_spec.js create mode 100644 spec/frontend/filtered_search/filtered_search_manager_spec.js create mode 100644 spec/frontend/filtered_search/filtered_search_tokenizer_spec.js create mode 100644 spec/frontend/filtered_search/issues_filtered_search_token_keys_spec.js create mode 100644 spec/frontend/filtered_search/recent_searches_root_spec.js create mode 100644 spec/frontend/filtered_search/services/recent_searches_service_spec.js create mode 100644 spec/frontend/filtered_search/visual_token_value_spec.js create mode 100644 spec/frontend/flash_spec.js create mode 100644 spec/frontend/frequent_items/components/app_spec.js create mode 100644 spec/frontend/frequent_items/store/actions_spec.js create mode 100644 spec/frontend/frequent_items/store/mutations_spec.js create mode 100644 spec/frontend/frequent_items/utils_spec.js create mode 100644 spec/frontend/groups/components/app_spec.js create mode 100644 spec/frontend/groups/components/group_folder_spec.js create mode 100644 spec/frontend/groups/components/group_item_spec.js create mode 100644 spec/frontend/groups/components/groups_spec.js create mode 100644 spec/frontend/groups/components/item_actions_spec.js create mode 100644 spec/frontend/groups/components/item_caret_spec.js create mode 100644 spec/frontend/groups/components/item_stats_spec.js create mode 100644 spec/frontend/groups/components/item_stats_value_spec.js create mode 100644 spec/frontend/groups/components/item_type_icon_spec.js create mode 100644 spec/frontend/groups/mock_data.js create mode 100644 spec/frontend/groups/service/groups_service_spec.js create mode 100644 spec/frontend/groups/store/groups_store_spec.js create mode 100644 spec/frontend/helpers/event_hub_factory_spec.js create mode 100644 spec/frontend/helpers/filtered_search_spec_helper.js create mode 100644 spec/frontend/helpers/set_window_location_helper.js create mode 100644 spec/frontend/helpers/set_window_location_helper_spec.js create mode 100644 spec/frontend/helpers/web_worker_mock.js create mode 100644 spec/frontend/ide/components/activity_bar_spec.js create mode 100644 spec/frontend/ide/components/commit_sidebar/radio_group_spec.js create mode 100644 spec/frontend/ide/components/file_row_extra_spec.js create mode 100644 spec/frontend/ide/components/file_templates/bar_spec.js create mode 100644 spec/frontend/ide/components/ide_review_spec.js create mode 100644 spec/frontend/ide/components/ide_side_bar_spec.js create mode 100644 spec/frontend/ide/components/ide_spec.js create mode 100644 spec/frontend/ide/components/ide_status_bar_spec.js create mode 100644 spec/frontend/ide/components/ide_tree_list_spec.js create mode 100644 spec/frontend/ide/components/ide_tree_spec.js create mode 100644 spec/frontend/ide/components/jobs/detail/description_spec.js create mode 100644 spec/frontend/ide/components/jobs/item_spec.js create mode 100644 spec/frontend/ide/components/merge_requests/item_spec.js create mode 100644 spec/frontend/ide/components/nav_dropdown_button_spec.js create mode 100644 spec/frontend/ide/components/nav_dropdown_spec.js create mode 100644 spec/frontend/ide/components/new_dropdown/button_spec.js create mode 100644 spec/frontend/ide/components/new_dropdown/index_spec.js create mode 100644 spec/frontend/ide/components/new_dropdown/modal_spec.js create mode 100644 spec/frontend/ide/components/new_dropdown/upload_spec.js create mode 100644 spec/frontend/ide/components/repo_tab_spec.js create mode 100644 spec/frontend/ide/components/repo_tabs_spec.js create mode 100644 spec/frontend/ide/components/shared/tokened_input_spec.js create mode 100644 spec/frontend/ide/lib/common/model_manager_spec.js create mode 100644 spec/frontend/ide/lib/common/model_spec.js create mode 100644 spec/frontend/ide/lib/decorations/controller_spec.js create mode 100644 spec/frontend/ide/lib/diff/controller_spec.js create mode 100644 spec/frontend/ide/lib/editor_spec.js create mode 100644 spec/frontend/ide/lib/languages/vue_spec.js create mode 100644 spec/frontend/image_diff/helpers/badge_helper_spec.js create mode 100644 spec/frontend/image_diff/helpers/comment_indicator_helper_spec.js create mode 100644 spec/frontend/image_diff/helpers/dom_helper_spec.js create mode 100644 spec/frontend/image_diff/helpers/utils_helper_spec.js create mode 100644 spec/frontend/image_diff/image_badge_spec.js create mode 100644 spec/frontend/image_diff/image_diff_spec.js create mode 100644 spec/frontend/image_diff/mock_data.js create mode 100644 spec/frontend/image_diff/replaced_image_diff_spec.js create mode 100644 spec/frontend/integrations/edit/components/integration_form_spec.js create mode 100644 spec/frontend/integrations/edit/components/jira_trigger_fields_spec.js create mode 100644 spec/frontend/integrations/edit/components/trigger_fields_spec.js create mode 100644 spec/frontend/integrations/integration_settings_form_spec.js create mode 100644 spec/frontend/issuable_spec.js create mode 100644 spec/frontend/issuables_list/components/issuable_list_root_app_spec.js create mode 100644 spec/frontend/issue_show/components/app_spec.js create mode 100644 spec/frontend/issue_show/components/description_spec.js create mode 100644 spec/frontend/issue_show/components/edited_spec.js create mode 100644 spec/frontend/issue_show/components/fields/description_template_spec.js create mode 100644 spec/frontend/issue_show/components/form_spec.js create mode 100644 spec/frontend/issue_show/components/title_spec.js create mode 100644 spec/frontend/jobs/components/artifacts_block_spec.js create mode 100644 spec/frontend/jobs/components/commit_block_spec.js create mode 100644 spec/frontend/jobs/components/empty_state_spec.js create mode 100644 spec/frontend/jobs/components/environments_block_spec.js create mode 100644 spec/frontend/jobs/components/job_container_item_spec.js create mode 100644 spec/frontend/jobs/components/job_log_spec.js create mode 100644 spec/frontend/jobs/components/jobs_container_spec.js create mode 100644 spec/frontend/jobs/components/manual_variables_form_spec.js create mode 100644 spec/frontend/jobs/components/sidebar_spec.js create mode 100644 spec/frontend/jobs/components/stages_dropdown_spec.js create mode 100644 spec/frontend/jobs/components/trigger_block_spec.js create mode 100644 spec/frontend/jobs/components/unmet_prerequisites_block_spec.js create mode 100644 spec/frontend/jobs/mixins/delayed_job_mixin_spec.js create mode 100644 spec/frontend/jobs/store/actions_spec.js create mode 100644 spec/frontend/jobs/store/helpers.js create mode 100644 spec/frontend/landing_spec.js create mode 100644 spec/frontend/lib/utils/csrf_token_spec.js create mode 100644 spec/frontend/lib/utils/downloader_spec.js create mode 100644 spec/frontend/lib/utils/navigation_utility_spec.js create mode 100644 spec/frontend/lib/utils/poll_spec.js create mode 100644 spec/frontend/lib/utils/sticky_spec.js create mode 100644 spec/frontend/milestones/mock_data.js create mode 100644 spec/frontend/milestones/project_milestone_combobox_spec.js create mode 100644 spec/frontend/mocks/ce/ide/lib/diff/diff_worker.js create mode 100644 spec/frontend/monitoring/__snapshots__/alert_widget_spec.js.snap create mode 100644 spec/frontend/monitoring/alert_widget_spec.js create mode 100644 spec/frontend/monitoring/components/alert_widget_form_spec.js create mode 100644 spec/frontend/monitoring/components/dashboard_panel_spec.js delete mode 100644 spec/frontend/monitoring/components/panel_type_spec.js create mode 100644 spec/frontend/monitoring/components/variables/custom_variable_spec.js create mode 100644 spec/frontend/monitoring/components/variables/text_variable_spec.js create mode 100644 spec/frontend/monitoring/components/variables_section_spec.js create mode 100644 spec/frontend/monitoring/store/variable_mapping_spec.js create mode 100644 spec/frontend/monitoring/stubs/modal_stub.js create mode 100644 spec/frontend/monitoring/validators_spec.js create mode 100644 spec/frontend/notebook/cells/code_spec.js create mode 100644 spec/frontend/notebook/cells/markdown_spec.js create mode 100644 spec/frontend/notebook/cells/output/html_sanitize_tests.js create mode 100644 spec/frontend/notebook/cells/output/html_spec.js create mode 100644 spec/frontend/notebook/cells/output/index_spec.js create mode 100644 spec/frontend/notebook/cells/prompt_spec.js create mode 100644 spec/frontend/notebook/index_spec.js create mode 100644 spec/frontend/oauth_remember_me_spec.js create mode 100644 spec/frontend/pages/admin/application_settings/account_and_limits_spec.js create mode 100644 spec/frontend/pages/admin/jobs/index/components/stop_jobs_modal_spec.js create mode 100644 spec/frontend/pages/admin/users/new/index_spec.js create mode 100644 spec/frontend/pages/labels/components/promote_label_modal_spec.js create mode 100644 spec/frontend/pages/milestones/shared/components/delete_milestone_modal_spec.js create mode 100644 spec/frontend/pages/milestones/shared/components/promote_milestone_modal_spec.js create mode 100644 spec/frontend/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js create mode 100644 spec/frontend/pages/projects/pipeline_schedules/shared/components/pipeline_schedule_callout_spec.js create mode 100644 spec/frontend/pages/sessions/new/preserve_url_fragment_spec.js create mode 100644 spec/frontend/pipelines/components/pipelines_filtered_search_spec.js create mode 100644 spec/frontend/pipelines/header_component_spec.js create mode 100644 spec/frontend/pipelines/linked_pipelines_mock.json create mode 100644 spec/frontend/pipelines/mock_data.js create mode 100644 spec/frontend/pipelines/pipeline_details_mediator_spec.js create mode 100644 spec/frontend/pipelines/pipelines_actions_spec.js create mode 100644 spec/frontend/pipelines/pipelines_artifacts_spec.js create mode 100644 spec/frontend/pipelines/pipelines_spec.js create mode 100644 spec/frontend/pipelines/pipelines_table_spec.js create mode 100644 spec/frontend/pipelines/stage_spec.js create mode 100644 spec/frontend/pipelines/stores/pipeline_store_spec.js create mode 100644 spec/frontend/pipelines/time_ago_spec.js create mode 100644 spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js create mode 100644 spec/frontend/pipelines/tokens/pipeline_trigger_author_token_spec.js create mode 100644 spec/frontend/pipelines_spec.js create mode 100644 spec/frontend/prometheus_metrics/prometheus_metrics_spec.js create mode 100644 spec/frontend/registry/explorer/components/image_list_spec.js create mode 100644 spec/frontend/related_merge_requests/components/related_merge_requests_spec.js create mode 100644 spec/frontend/related_merge_requests/store/actions_spec.js create mode 100644 spec/frontend/related_merge_requests/store/mutations_spec.js create mode 100644 spec/frontend/releases/components/release_block_metadata_spec.js create mode 100644 spec/frontend/reports/accessibility_report/grouped_accessibility_reports_app_spec.js create mode 100644 spec/frontend/reports/accessibility_report/mock_data.js create mode 100644 spec/frontend/reports/accessibility_report/store/actions_spec.js create mode 100644 spec/frontend/reports/accessibility_report/store/getters_spec.js create mode 100644 spec/frontend/reports/accessibility_report/store/mutations_spec.js create mode 100644 spec/frontend/reports/components/__snapshots__/grouped_issues_list_spec.js.snap create mode 100644 spec/frontend/reports/components/__snapshots__/issue_status_icon_spec.js.snap create mode 100644 spec/frontend/reports/components/grouped_issues_list_spec.js create mode 100644 spec/frontend/reports/components/grouped_test_reports_app_spec.js create mode 100644 spec/frontend/reports/components/issue_status_icon_spec.js create mode 100644 spec/frontend/reports/components/modal_open_name_spec.js create mode 100644 spec/frontend/reports/components/modal_spec.js create mode 100644 spec/frontend/reports/components/summary_row_spec.js create mode 100644 spec/frontend/reports/components/test_issue_body_spec.js create mode 100644 spec/frontend/reports/mock_data/mock_data.js create mode 100644 spec/frontend/reports/mock_data/new_and_fixed_failures_report.json create mode 100644 spec/frontend/reports/mock_data/new_errors_report.json create mode 100644 spec/frontend/reports/mock_data/new_failures_report.json create mode 100644 spec/frontend/reports/mock_data/no_failures_report.json create mode 100644 spec/frontend/reports/mock_data/resolved_failures.json create mode 100644 spec/frontend/reports/store/actions_spec.js create mode 100644 spec/frontend/reports/store/mutations_spec.js create mode 100644 spec/frontend/settings_panels_spec.js create mode 100644 spec/frontend/sidebar/assignees_realtime_spec.js create mode 100644 spec/frontend/sidebar/components/time_tracking/time_tracker_spec.js create mode 100644 spec/frontend/sidebar/confidential/edit_form_buttons_spec.js create mode 100644 spec/frontend/sidebar/confidential/edit_form_spec.js delete mode 100644 spec/frontend/sidebar/confidential_edit_buttons_spec.js delete mode 100644 spec/frontend/sidebar/confidential_edit_form_buttons_spec.js create mode 100644 spec/frontend/sidebar/lock/edit_form_buttons_spec.js create mode 100644 spec/frontend/sidebar/lock/lock_issue_sidebar_spec.js create mode 100644 spec/frontend/sidebar/participants_spec.js create mode 100644 spec/frontend/sidebar/sidebar_mediator_spec.js create mode 100644 spec/frontend/sidebar/sidebar_move_issue_spec.js create mode 100644 spec/frontend/sidebar/sidebar_subscriptions_spec.js create mode 100644 spec/frontend/sidebar/subscriptions_spec.js create mode 100644 spec/frontend/snippets/components/__snapshots__/snippet_description_view_spec.js.snap create mode 100644 spec/frontend/snippets/components/snippet_description_view_spec.js create mode 100644 spec/frontend/static_site_editor/components/edit_area_spec.js delete mode 100644 spec/frontend/static_site_editor/components/static_site_editor_spec.js create mode 100644 spec/frontend/static_site_editor/graphql/resolvers/file_spec.js create mode 100644 spec/frontend/static_site_editor/graphql/resolvers/submit_content_changes_spec.js create mode 100644 spec/frontend/static_site_editor/pages/home_spec.js create mode 100644 spec/frontend/static_site_editor/pages/success_spec.js delete mode 100644 spec/frontend/static_site_editor/store/actions_spec.js delete mode 100644 spec/frontend/static_site_editor/store/getters_spec.js delete mode 100644 spec/frontend/static_site_editor/store/mutations_spec.js create mode 100644 spec/frontend/users_select/utils_spec.js create mode 100644 spec/frontend/vue_mr_widget/components/mr_widget_pipeline_container_spec.js create mode 100644 spec/frontend/vue_mr_widget/stores/artifacts_list/actions_spec.js create mode 100644 spec/frontend/vue_mr_widget/stores/mr_widget_store_spec.js create mode 100644 spec/frontend/vue_shared/components/ci_badge_link_spec.js create mode 100644 spec/frontend/vue_shared/components/ci_icon_spec.js create mode 100644 spec/frontend/vue_shared/components/content_viewer/content_viewer_spec.js create mode 100644 spec/frontend/vue_shared/components/content_viewer/lib/viewer_utils_spec.js create mode 100644 spec/frontend/vue_shared/components/content_viewer/viewers/download_viewer_spec.js create mode 100644 spec/frontend/vue_shared/components/content_viewer/viewers/markdown_viewer_spec.js create mode 100644 spec/frontend/vue_shared/components/diff_viewer/diff_viewer_spec.js create mode 100644 spec/frontend/vue_shared/components/dropdown/dropdown_button_spec.js create mode 100644 spec/frontend/vue_shared/components/dropdown/dropdown_hidden_input_spec.js create mode 100644 spec/frontend/vue_shared/components/dropdown/mock_data.js create mode 100644 spec/frontend/vue_shared/components/file_finder/item_spec.js create mode 100644 spec/frontend/vue_shared/components/filtered_search_dropdown_spec.js create mode 100644 spec/frontend/vue_shared/components/gl_countdown_spec.js create mode 100644 spec/frontend/vue_shared/components/header_ci_component_spec.js create mode 100644 spec/frontend/vue_shared/components/markdown/field_view_spec.js create mode 100644 spec/frontend/vue_shared/components/markdown/suggestions_spec.js create mode 100644 spec/frontend/vue_shared/components/markdown/toolbar_spec.js create mode 100644 spec/frontend/vue_shared/components/navigation_tabs_spec.js create mode 100644 spec/frontend/vue_shared/components/pikaday_spec.js create mode 100644 spec/frontend/vue_shared/components/project_avatar/default_spec.js create mode 100644 spec/frontend/vue_shared/components/project_selector/project_list_item_spec.js create mode 100644 spec/frontend/vue_shared/components/project_selector/project_selector_spec.js create mode 100644 spec/frontend/vue_shared/components/rich_content_editor/rich_content_editor_spec.js create mode 100644 spec/frontend/vue_shared/components/rich_content_editor/toolbar_item_spec.js create mode 100644 spec/frontend/vue_shared/components/rich_content_editor/toolbar_service_spec.js create mode 100644 spec/frontend/vue_shared/components/sidebar/labels_select/mock_data.js create mode 100644 spec/frontend/vue_shared/components/sidebar/labels_select_vue/label_item_spec.js create mode 100644 spec/frontend/vue_shared/components/stacked_progress_bar_spec.js create mode 100644 spec/frontend/vue_shared/components/tabs/tab_spec.js create mode 100644 spec/frontend/vue_shared/components/tabs/tabs_spec.js create mode 100644 spec/frontend/vue_shared/components/toggle_button_spec.js (limited to 'spec/frontend') diff --git a/spec/frontend/.eslintrc.yml b/spec/frontend/.eslintrc.yml index c8aacca5ef2..b9159191114 100644 --- a/spec/frontend/.eslintrc.yml +++ b/spec/frontend/.eslintrc.yml @@ -1,10 +1,6 @@ --- -env: - jest/globals: true -plugins: - - jest extends: - - 'plugin:jest/recommended' + - 'plugin:@gitlab/jest' settings: # We have to teach eslint-plugin-import what node modules we use # otherwise there is an error when it tries to resolve them @@ -14,9 +10,18 @@ settings: - path import/resolver: jest: - jestConfigFile: 'jest.config.js' + jestConfigFile: 'jest.config.unit.js' globals: getJSONFixture: false loadFixtures: false preloadFixtures: false setFixtures: false +rules: + jest/expect-expect: + - off + - assertFunctionNames: + - 'expect*' + - 'assert*' + - 'testAction' + jest/no-test-callback: + - off diff --git a/spec/frontend/__mocks__/@toast-ui/vue-editor/index.js b/spec/frontend/__mocks__/@toast-ui/vue-editor/index.js new file mode 100644 index 00000000000..726ed0fa030 --- /dev/null +++ b/spec/frontend/__mocks__/@toast-ui/vue-editor/index.js @@ -0,0 +1,29 @@ +export const Editor = { + props: { + initialValue: { + type: String, + required: true, + }, + options: { + type: Object, + }, + initialEditType: { + type: String, + }, + height: { + type: String, + }, + previewStyle: { + type: String, + }, + }, + render(h) { + return h('div'); + }, +}; + +export const Viewer = { + render(h) { + return h('div'); + }, +}; diff --git a/spec/frontend/ajax_loading_spinner_spec.js b/spec/frontend/ajax_loading_spinner_spec.js new file mode 100644 index 00000000000..8ed2ee49ff8 --- /dev/null +++ b/spec/frontend/ajax_loading_spinner_spec.js @@ -0,0 +1,57 @@ +import $ from 'jquery'; +import AjaxLoadingSpinner from '~/ajax_loading_spinner'; + +describe('Ajax Loading Spinner', () => { + const fixtureTemplate = 'static/ajax_loading_spinner.html'; + preloadFixtures(fixtureTemplate); + + beforeEach(() => { + loadFixtures(fixtureTemplate); + AjaxLoadingSpinner.init(); + }); + + it('change current icon with spinner icon and disable link while waiting ajax response', done => { + jest.spyOn($, 'ajax').mockImplementation(req => { + const xhr = new XMLHttpRequest(); + const ajaxLoadingSpinner = document.querySelector('.js-ajax-loading-spinner'); + const icon = ajaxLoadingSpinner.querySelector('i'); + + req.beforeSend(xhr, { dataType: 'text/html' }); + + expect(icon).not.toHaveClass('fa-trash-o'); + expect(icon).toHaveClass('fa-spinner'); + expect(icon).toHaveClass('fa-spin'); + expect(icon.dataset.icon).toEqual('fa-trash-o'); + expect(ajaxLoadingSpinner.getAttribute('disabled')).toEqual(''); + + req.complete({}); + + done(); + const deferred = $.Deferred(); + return deferred.promise(); + }); + document.querySelector('.js-ajax-loading-spinner').click(); + }); + + it('use original icon again and enabled the link after complete the ajax request', done => { + jest.spyOn($, 'ajax').mockImplementation(req => { + const xhr = new XMLHttpRequest(); + const ajaxLoadingSpinner = document.querySelector('.js-ajax-loading-spinner'); + + req.beforeSend(xhr, { dataType: 'text/html' }); + req.complete({}); + + const icon = ajaxLoadingSpinner.querySelector('i'); + + expect(icon).toHaveClass('fa-trash-o'); + expect(icon).not.toHaveClass('fa-spinner'); + expect(icon).not.toHaveClass('fa-spin'); + expect(ajaxLoadingSpinner.getAttribute('disabled')).toEqual(null); + + done(); + const deferred = $.Deferred(); + return deferred.promise(); + }); + document.querySelector('.js-ajax-loading-spinner').click(); + }); +}); diff --git a/spec/frontend/alert_management/components/alert_management_detail_spec.js b/spec/frontend/alert_management/components/alert_management_detail_spec.js new file mode 100644 index 00000000000..1e4c2e24ccb --- /dev/null +++ b/spec/frontend/alert_management/components/alert_management_detail_spec.js @@ -0,0 +1,242 @@ +import { mount, shallowMount } from '@vue/test-utils'; +import { GlAlert, GlLoadingIcon, GlDropdownItem, GlTable } from '@gitlab/ui'; +import AlertDetails from '~/alert_management/components/alert_details.vue'; +import updateAlertStatus from '~/alert_management/graphql/mutations/update_alert_status.graphql'; +import createFlash from '~/flash'; + +import mockAlerts from '../mocks/alerts.json'; + +const mockAlert = mockAlerts[0]; +jest.mock('~/flash'); + +describe('AlertDetails', () => { + let wrapper; + const newIssuePath = 'root/alerts/-/issues/new'; + const findStatusDropdownItem = () => wrapper.find(GlDropdownItem); + const findDetailsTable = () => wrapper.find(GlTable); + + function mountComponent({ + data, + createIssueFromAlertEnabled = false, + loading = false, + mountMethod = shallowMount, + stubs = {}, + } = {}) { + wrapper = mountMethod(AlertDetails, { + propsData: { + alertId: 'alertId', + projectPath: 'projectPath', + newIssuePath, + }, + data() { + return { alert: { ...mockAlert }, ...data }; + }, + provide: { + glFeatures: { createIssueFromAlertEnabled }, + }, + mocks: { + $apollo: { + mutate: jest.fn(), + queries: { + alert: { + loading, + }, + }, + }, + }, + stubs, + }); + } + + afterEach(() => { + if (wrapper) { + wrapper.destroy(); + } + }); + + const findCreatedIssueBtn = () => wrapper.find('[data-testid="createIssueBtn"]'); + + describe('Alert details', () => { + describe('when alert is null', () => { + beforeEach(() => { + mountComponent({ data: { alert: null } }); + }); + + it('shows an empty state', () => { + expect(wrapper.find('[data-testid="alertDetailsTabs"]').exists()).toBe(false); + }); + }); + + describe('when alert is present', () => { + beforeEach(() => { + mountComponent({ data: { alert: mockAlert } }); + }); + + it('renders a tab with overview information', () => { + expect(wrapper.find('[data-testid="overviewTab"]').exists()).toBe(true); + }); + + it('renders a tab with full alert information', () => { + expect(wrapper.find('[data-testid="fullDetailsTab"]').exists()).toBe(true); + }); + + it('renders a title', () => { + expect(wrapper.find('[data-testid="title"]').text()).toBe(mockAlert.title); + }); + + it('renders a start time', () => { + expect(wrapper.find('[data-testid="startTimeItem"]').exists()).toBe(true); + expect(wrapper.find('[data-testid="startTimeItem"]').props().time).toBe( + mockAlert.startedAt, + ); + }); + }); + + describe('individual alert fields', () => { + describe.each` + field | data | isShown + ${'eventCount'} | ${1} | ${true} + ${'eventCount'} | ${undefined} | ${false} + ${'monitoringTool'} | ${'New Relic'} | ${true} + ${'monitoringTool'} | ${undefined} | ${false} + ${'service'} | ${'Prometheus'} | ${true} + ${'service'} | ${undefined} | ${false} + `(`$desc`, ({ field, data, isShown }) => { + beforeEach(() => { + mountComponent({ data: { alert: { ...mockAlert, [field]: data } } }); + }); + + it(`${field} is ${isShown ? 'displayed' : 'hidden'} correctly`, () => { + if (isShown) { + expect(wrapper.find(`[data-testid="${field}"]`).text()).toBe(data.toString()); + } else { + expect(wrapper.find(`[data-testid="${field}"]`).exists()).toBe(false); + } + }); + }); + }); + + describe('Create issue from alert', () => { + describe('createIssueFromAlertEnabled feature flag enabled', () => { + it('should display a button that links to new issue page', () => { + mountComponent({ createIssueFromAlertEnabled: true }); + expect(findCreatedIssueBtn().exists()).toBe(true); + expect(findCreatedIssueBtn().attributes('href')).toBe(newIssuePath); + }); + }); + + describe('createIssueFromAlertEnabled feature flag disabled', () => { + it('should display a button that links to a new issue page', () => { + mountComponent({ createIssueFromAlertEnabled: false }); + expect(findCreatedIssueBtn().exists()).toBe(false); + }); + }); + }); + + describe('View full alert details', () => { + beforeEach(() => { + mountComponent({ data: { alert: mockAlert } }); + }); + it('should display a table of raw alert details data', () => { + wrapper.find('[data-testid="fullDetailsTab"]').trigger('click'); + expect(findDetailsTable().exists()).toBe(true); + }); + }); + + describe('loading state', () => { + beforeEach(() => { + mountComponent({ loading: true }); + }); + + it('displays a loading state when loading', () => { + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); + }); + }); + + describe('error state', () => { + it('displays a error state correctly', () => { + mountComponent({ data: { errored: true } }); + expect(wrapper.find(GlAlert).exists()).toBe(true); + }); + + it('does not display an error when dismissed', () => { + mountComponent({ data: { errored: true, isErrorDismissed: true } }); + expect(wrapper.find(GlAlert).exists()).toBe(false); + }); + }); + + describe('header', () => { + const findHeader = () => wrapper.find('[data-testid="alert-header"]'); + const stubs = { TimeAgoTooltip: 'now' }; + + describe('individual header fields', () => { + describe.each` + severity | createdAt | monitoringTool | result + ${'MEDIUM'} | ${'2020-04-17T23:18:14.996Z'} | ${null} | ${'Medium • Reported now'} + ${'INFO'} | ${'2020-04-17T23:18:14.996Z'} | ${'Datadog'} | ${'Info • Reported now by Datadog'} + `( + `When severity=$severity, createdAt=$createdAt, monitoringTool=$monitoringTool`, + ({ severity, createdAt, monitoringTool, result }) => { + beforeEach(() => { + mountComponent({ + data: { alert: { ...mockAlert, severity, createdAt, monitoringTool } }, + mountMethod: mount, + stubs, + }); + }); + + it('header text is shown correctly', () => { + expect(findHeader().text()).toBe(result); + }); + }, + ); + }); + }); + }); + + describe('updating the alert status', () => { + const mockUpdatedMutationResult = { + data: { + updateAlertStatus: { + errors: [], + alert: { + status: 'acknowledged', + }, + }, + }, + }; + + beforeEach(() => { + mountComponent({ + props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, + data: { alert: mockAlert }, + loading: false, + }); + }); + + it('calls `$apollo.mutate` with `updateAlertStatus` mutation and variables containing `iid`, `status`, & `projectPath`', () => { + jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockUpdatedMutationResult); + findStatusDropdownItem().vm.$emit('click'); + + expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ + mutation: updateAlertStatus, + variables: { + iid: 'alertId', + status: 'TRIGGERED', + projectPath: 'projectPath', + }, + }); + }); + + it('calls `createFlash` when request fails', () => { + jest.spyOn(wrapper.vm.$apollo, 'mutate').mockReturnValue(Promise.reject(new Error())); + findStatusDropdownItem().vm.$emit('click'); + + setImmediate(() => { + expect(createFlash).toHaveBeenCalledWith( + 'There was an error while updating the status of the alert. Please try again.', + ); + }); + }); + }); +}); diff --git a/spec/frontend/alert_management/components/alert_management_list_spec.js b/spec/frontend/alert_management/components/alert_management_list_spec.js new file mode 100644 index 00000000000..c4630ac57fe --- /dev/null +++ b/spec/frontend/alert_management/components/alert_management_list_spec.js @@ -0,0 +1,325 @@ +import { mount } from '@vue/test-utils'; +import { + GlEmptyState, + GlTable, + GlAlert, + GlLoadingIcon, + GlDropdown, + GlDropdownItem, + GlIcon, + GlTab, +} from '@gitlab/ui'; +import { visitUrl } from '~/lib/utils/url_utility'; +import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; +import createFlash from '~/flash'; +import AlertManagementList from '~/alert_management/components/alert_management_list.vue'; +import { ALERTS_STATUS_TABS } from '../../../../app/assets/javascripts/alert_management/constants'; +import updateAlertStatus from '~/alert_management/graphql/mutations/update_alert_status.graphql'; +import mockAlerts from '../mocks/alerts.json'; + +jest.mock('~/flash'); + +jest.mock('~/lib/utils/url_utility', () => ({ + visitUrl: jest.fn().mockName('visitUrlMock'), + joinPaths: jest.requireActual('~/lib/utils/url_utility').joinPaths, +})); + +describe('AlertManagementList', () => { + let wrapper; + + const findAlertsTable = () => wrapper.find(GlTable); + const findAlerts = () => wrapper.findAll('table tbody tr'); + const findAlert = () => wrapper.find(GlAlert); + const findLoader = () => wrapper.find(GlLoadingIcon); + const findStatusDropdown = () => wrapper.find(GlDropdown); + const findStatusFilterTabs = () => wrapper.findAll(GlTab); + const findDateFields = () => wrapper.findAll(TimeAgo); + const findFirstStatusOption = () => findStatusDropdown().find(GlDropdownItem); + const findSeverityFields = () => wrapper.findAll('[data-testid="severityField"]'); + + function mountComponent({ + props = { + alertManagementEnabled: false, + userCanEnableAlertManagement: false, + }, + data = {}, + loading = false, + alertListStatusFilteringEnabled = false, + stubs = {}, + } = {}) { + wrapper = mount(AlertManagementList, { + propsData: { + projectPath: 'gitlab-org/gitlab', + enableAlertManagementPath: '/link', + emptyAlertSvgPath: 'illustration/path', + ...props, + }, + provide: { + glFeatures: { + alertListStatusFilteringEnabled, + }, + }, + data() { + return data; + }, + mocks: { + $apollo: { + mutate: jest.fn(), + queries: { + alerts: { + loading, + }, + }, + }, + }, + stubs, + }); + } + + beforeEach(() => { + mountComponent(); + }); + + afterEach(() => { + if (wrapper) { + wrapper.destroy(); + } + }); + + describe('alert management feature renders empty state', () => { + it('shows empty state', () => { + expect(wrapper.find(GlEmptyState).exists()).toBe(true); + }); + }); + + describe('Status Filter Tabs', () => { + describe('alertListStatusFilteringEnabled feature flag enabled', () => { + beforeEach(() => { + mountComponent({ + props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, + data: { alerts: mockAlerts }, + loading: false, + alertListStatusFilteringEnabled: true, + stubs: { + GlTab: true, + }, + }); + }); + + it('should display filter tabs for all statuses', () => { + const tabs = findStatusFilterTabs().wrappers; + tabs.forEach((tab, i) => { + expect(tab.text()).toContain(ALERTS_STATUS_TABS[i].title); + }); + }); + }); + + describe('alertListStatusFilteringEnabled feature flag disabled', () => { + beforeEach(() => { + mountComponent({ + props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, + data: { alerts: mockAlerts }, + loading: false, + alertListStatusFilteringEnabled: false, + stubs: { + GlTab: true, + }, + }); + }); + + it('should NOT display tabs', () => { + expect(findStatusFilterTabs()).not.toExist(); + }); + }); + }); + + describe('Alerts table', () => { + it('loading state', () => { + mountComponent({ + props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, + data: { alerts: null }, + loading: true, + }); + expect(findAlertsTable().exists()).toBe(true); + expect(findLoader().exists()).toBe(true); + }); + + it('error state', () => { + mountComponent({ + props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, + data: { alerts: null, errored: true }, + loading: false, + }); + expect(findAlertsTable().exists()).toBe(true); + expect(findAlertsTable().text()).toContain('No alerts to display'); + expect(findLoader().exists()).toBe(false); + expect(findAlert().props().variant).toBe('danger'); + }); + + it('empty state', () => { + mountComponent({ + props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, + data: { alerts: [], errored: false }, + loading: false, + }); + expect(findAlertsTable().exists()).toBe(true); + expect(findAlertsTable().text()).toContain('No alerts to display'); + expect(findLoader().exists()).toBe(false); + expect(findAlert().props().variant).toBe('info'); + }); + + it('has data state', () => { + mountComponent({ + props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, + data: { alerts: mockAlerts, errored: false }, + loading: false, + }); + expect(findLoader().exists()).toBe(false); + expect(findAlertsTable().exists()).toBe(true); + expect(findAlerts()).toHaveLength(mockAlerts.length); + }); + + it('displays status dropdown', () => { + mountComponent({ + props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, + data: { alerts: mockAlerts, errored: false }, + loading: false, + }); + expect(findStatusDropdown().exists()).toBe(true); + }); + + it('shows correct severity icons', () => { + mountComponent({ + props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, + data: { alerts: mockAlerts, errored: false }, + loading: false, + }); + + return wrapper.vm.$nextTick().then(() => { + expect(wrapper.find(GlTable).exists()).toBe(true); + expect( + findAlertsTable() + .find(GlIcon) + .classes('icon-critical'), + ).toBe(true); + }); + }); + + it('renders severity text', () => { + mountComponent({ + props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, + data: { alerts: mockAlerts, errored: false }, + loading: false, + }); + + expect( + findSeverityFields() + .at(0) + .text(), + ).toBe('Critical'); + }); + + it('navigates to the detail page when alert row is clicked', () => { + mountComponent({ + props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, + data: { alerts: mockAlerts, errored: false }, + loading: false, + }); + + findAlerts() + .at(0) + .trigger('click'); + expect(visitUrl).toHaveBeenCalledWith('/1527542/details'); + }); + + describe('handle date fields', () => { + it('should display time ago dates when values provided', () => { + mountComponent({ + props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, + data: { + alerts: [ + { + iid: 1, + status: 'acknowledged', + startedAt: '2020-03-17T23:18:14.996Z', + endedAt: '2020-04-17T23:18:14.996Z', + severity: 'high', + }, + ], + errored: false, + }, + loading: false, + }); + expect(findDateFields().length).toBe(2); + }); + + it('should not display time ago dates when values not provided', () => { + mountComponent({ + props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, + data: { + alerts: [ + { + iid: 1, + status: 'acknowledged', + startedAt: null, + endedAt: null, + severity: 'high', + }, + ], + errored: false, + }, + loading: false, + }); + expect(findDateFields().exists()).toBe(false); + }); + }); + }); + + describe('updating the alert status', () => { + const iid = '1527542'; + const mockUpdatedMutationResult = { + data: { + updateAlertStatus: { + errors: [], + alert: { + iid, + status: 'acknowledged', + }, + }, + }, + }; + + beforeEach(() => { + mountComponent({ + props: { alertManagementEnabled: true, userCanEnableAlertManagement: true }, + data: { alerts: mockAlerts, errored: false }, + loading: false, + }); + }); + + it('calls `$apollo.mutate` with `updateAlertStatus` mutation and variables containing `iid`, `status`, & `projectPath`', () => { + jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(mockUpdatedMutationResult); + findFirstStatusOption().vm.$emit('click'); + + expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({ + mutation: updateAlertStatus, + variables: { + iid, + status: 'TRIGGERED', + projectPath: 'gitlab-org/gitlab', + }, + }); + }); + + it('calls `createFlash` when request fails', () => { + jest.spyOn(wrapper.vm.$apollo, 'mutate').mockReturnValue(Promise.reject(new Error())); + findFirstStatusOption().vm.$emit('click'); + + setImmediate(() => { + expect(createFlash).toHaveBeenCalledWith( + 'There was an error while updating the status of the alert. Please try again.', + ); + }); + }); + }); +}); diff --git a/spec/frontend/alert_management/mocks/alerts.json b/spec/frontend/alert_management/mocks/alerts.json new file mode 100644 index 00000000000..b67e2cfc52e --- /dev/null +++ b/spec/frontend/alert_management/mocks/alerts.json @@ -0,0 +1,29 @@ +[ + { + "iid": "1527542", + "title": "SyntaxError: Invalid or unexpected token", + "severity": "CRITICAL", + "eventCount": 7, + "startedAt": "2020-04-17T23:18:14.996Z", + "endedAt": "2020-04-17T23:18:14.996Z", + "status": "TRIGGERED" + }, + { + "iid": "1527543", + "title": "Some other alert Some other alert Some other alert Some other alert Some other alert Some other alert", + "severity": "MEDIUM", + "eventCount": 1, + "startedAt": "2020-04-17T23:18:14.996Z", + "endedAt": "2020-04-17T23:18:14.996Z", + "status": "ACKNOWLEDGED" + }, + { + "iid": "1527544", + "title": "SyntaxError: Invalid or unexpected token", + "severity": "LOW", + "eventCount": 4, + "startedAt": "2020-04-17T23:18:14.996Z", + "endedAt": "2020-04-17T23:18:14.996Z", + "status": "RESOLVED" + } + ] diff --git a/spec/frontend/api_spec.js b/spec/frontend/api_spec.js index f34c2fb69eb..d365048ab0b 100644 --- a/spec/frontend/api_spec.js +++ b/spec/frontend/api_spec.js @@ -15,7 +15,7 @@ describe('Api', () => { beforeEach(() => { mock = new MockAdapter(axios); originalGon = window.gon; - window.gon = Object.assign({}, dummyGon); + window.gon = { ...dummyGon }; }); afterEach(() => { diff --git a/spec/frontend/autosave_spec.js b/spec/frontend/autosave_spec.js index 3119477f385..bbdf3c6f91d 100644 --- a/spec/frontend/autosave_spec.js +++ b/spec/frontend/autosave_spec.js @@ -10,6 +10,8 @@ describe('Autosave', () => { const field = $(''); const key = 'key'; const fallbackKey = 'fallbackKey'; + const lockVersionKey = 'lockVersionKey'; + const lockVersion = 1; describe('class constructor', () => { beforeEach(() => { @@ -30,6 +32,13 @@ describe('Autosave', () => { expect(AccessorUtilities.isLocalStorageAccessSafe).toHaveBeenCalled(); expect(autosave.isLocalStorageAvailable).toBe(true); }); + + it('should set .isLocalStorageAvailable if lockVersion is passed', () => { + autosave = new Autosave(field, key, null, lockVersion); + + expect(AccessorUtilities.isLocalStorageAccessSafe).toHaveBeenCalled(); + expect(autosave.isLocalStorageAvailable).toBe(true); + }); }); describe('restore', () => { @@ -96,6 +105,40 @@ describe('Autosave', () => { }); }); + describe('getSavedLockVersion', () => { + beforeEach(() => { + autosave = { + field, + key, + lockVersionKey, + }; + }); + + describe('if .isLocalStorageAvailable is `false`', () => { + beforeEach(() => { + autosave.isLocalStorageAvailable = false; + + Autosave.prototype.getSavedLockVersion.call(autosave); + }); + + it('should not call .getItem', () => { + expect(window.localStorage.getItem).not.toHaveBeenCalled(); + }); + }); + + describe('if .isLocalStorageAvailable is `true`', () => { + beforeEach(() => { + autosave.isLocalStorageAvailable = true; + }); + + it('should call .getItem', () => { + Autosave.prototype.getSavedLockVersion.call(autosave); + + expect(window.localStorage.getItem).toHaveBeenCalledWith(lockVersionKey); + }); + }); + }); + describe('save', () => { beforeEach(() => { autosave = { reset: jest.fn() }; @@ -128,10 +171,51 @@ describe('Autosave', () => { }); }); + describe('save with lockVersion', () => { + beforeEach(() => { + autosave = { + field, + key, + lockVersionKey, + lockVersion, + isLocalStorageAvailable: true, + }; + }); + + describe('lockVersion is valid', () => { + it('should call .setItem', () => { + Autosave.prototype.save.call(autosave); + expect(window.localStorage.setItem).toHaveBeenCalledWith(lockVersionKey, lockVersion); + }); + + it('should call .setItem when version is 0', () => { + autosave.lockVersion = 0; + Autosave.prototype.save.call(autosave); + expect(window.localStorage.setItem).toHaveBeenCalledWith( + lockVersionKey, + autosave.lockVersion, + ); + }); + }); + + describe('lockVersion is invalid', () => { + it('should not call .setItem with lockVersion', () => { + delete autosave.lockVersion; + Autosave.prototype.save.call(autosave); + + expect(window.localStorage.setItem).not.toHaveBeenCalledWith( + lockVersionKey, + autosave.lockVersion, + ); + }); + }); + }); + describe('reset', () => { beforeEach(() => { autosave = { key, + lockVersionKey, }; }); @@ -156,6 +240,7 @@ describe('Autosave', () => { it('should call .removeItem', () => { expect(window.localStorage.removeItem).toHaveBeenCalledWith(key); + expect(window.localStorage.removeItem).toHaveBeenCalledWith(lockVersionKey); }); }); }); @@ -166,8 +251,8 @@ describe('Autosave', () => { field, key, fallbackKey, + isLocalStorageAvailable: true, }; - autosave.isLocalStorageAvailable = true; }); it('should call .getItem', () => { @@ -185,7 +270,8 @@ describe('Autosave', () => { it('should call .removeItem for key and fallbackKey', () => { Autosave.prototype.reset.call(autosave); - expect(window.localStorage.removeItem).toHaveBeenCalledTimes(2); + expect(window.localStorage.removeItem).toHaveBeenCalledWith(fallbackKey); + expect(window.localStorage.removeItem).toHaveBeenCalledWith(key); }); }); }); diff --git a/spec/frontend/avatar_helper_spec.js b/spec/frontend/avatar_helper_spec.js new file mode 100644 index 00000000000..c4da7189751 --- /dev/null +++ b/spec/frontend/avatar_helper_spec.js @@ -0,0 +1,110 @@ +import { TEST_HOST } from 'spec/test_constants'; +import { getFirstCharacterCapitalized } from '~/lib/utils/text_utility'; +import { + DEFAULT_SIZE_CLASS, + IDENTICON_BG_COUNT, + renderAvatar, + renderIdenticon, + getIdenticonBackgroundClass, + getIdenticonTitle, +} from '~/helpers/avatar_helper'; + +function matchAll(str) { + return new RegExp(`^${str}$`); +} + +describe('avatar_helper', () => { + describe('getIdenticonBackgroundClass', () => { + it('returns identicon bg class from id that is a number', () => { + expect(getIdenticonBackgroundClass(1)).toEqual('bg2'); + }); + + it('returns identicon bg class from id that is a string', () => { + expect(getIdenticonBackgroundClass('1')).toEqual('bg2'); + }); + + it('returns identicon bg class from id that is a GraphQL string id', () => { + expect(getIdenticonBackgroundClass('gid://gitlab/Project/1')).toEqual('bg2'); + }); + + it('returns identicon bg class from unparsable string', () => { + expect(getIdenticonBackgroundClass('gid://gitlab/')).toEqual('bg1'); + }); + + it(`wraps around if id is bigger than ${IDENTICON_BG_COUNT}`, () => { + expect(getIdenticonBackgroundClass(IDENTICON_BG_COUNT + 4)).toEqual('bg5'); + expect(getIdenticonBackgroundClass(IDENTICON_BG_COUNT * 5 + 6)).toEqual('bg7'); + }); + }); + + describe('getIdenticonTitle', () => { + it('returns identicon title from name', () => { + expect(getIdenticonTitle('Lorem')).toEqual('L'); + expect(getIdenticonTitle('dolar-sit-amit')).toEqual('D'); + expect(getIdenticonTitle('%-with-special-chars')).toEqual('%'); + }); + + it('returns space if name is falsey', () => { + expect(getIdenticonTitle('')).toEqual(' '); + expect(getIdenticonTitle(null)).toEqual(' '); + }); + }); + + describe('renderIdenticon', () => { + it('renders with the first letter as title and bg based on id', () => { + const entity = { + id: IDENTICON_BG_COUNT + 3, + name: 'Xavior', + }; + const options = { + sizeClass: 's32', + }; + + const result = renderIdenticon(entity, options); + + expect(result).toHaveClass(`identicon ${options.sizeClass} bg4`); + expect(result).toHaveText(matchAll(getFirstCharacterCapitalized(entity.name))); + }); + + it('renders with defaults, if no options are given', () => { + const entity = { + id: 1, + name: 'tanuki', + }; + + const result = renderIdenticon(entity); + + expect(result).toHaveClass(`identicon ${DEFAULT_SIZE_CLASS} bg2`); + expect(result).toHaveText(matchAll(getFirstCharacterCapitalized(entity.name))); + }); + }); + + describe('renderAvatar', () => { + it('renders an image with the avatarUrl', () => { + const avatarUrl = `${TEST_HOST}/not-real-assets/test.png`; + + const result = renderAvatar({ + avatar_url: avatarUrl, + }); + + expect(result).toBeMatchedBy('img'); + expect(result).toHaveAttr('src', avatarUrl); + expect(result).toHaveClass(DEFAULT_SIZE_CLASS); + }); + + it('renders an identicon if no avatarUrl', () => { + const entity = { + id: 1, + name: 'walrus', + }; + const options = { + sizeClass: 's16', + }; + + const result = renderAvatar(entity, options); + + expect(result).toHaveClass(`identicon ${options.sizeClass} bg2`); + expect(result).toHaveText(matchAll(getFirstCharacterCapitalized(entity.name))); + }); + }); +}); diff --git a/spec/frontend/behaviors/markdown/paste_markdown_table_spec.js b/spec/frontend/behaviors/markdown/paste_markdown_table_spec.js index a98919e2113..eab805382bd 100644 --- a/spec/frontend/behaviors/markdown/paste_markdown_table_spec.js +++ b/spec/frontend/behaviors/markdown/paste_markdown_table_spec.js @@ -57,6 +57,18 @@ describe('PasteMarkdownTable', () => { expect(new PasteMarkdownTable(data).isTable()).toBe(false); }); + + it('returns false when the table copy comes from a diff', () => { + data.types = ['text/html', 'text/plain']; + data.getData = jest.fn().mockImplementation(mimeType => { + if (mimeType === 'text/html') { + return '
FirstSecond
'; + } + return 'First\tSecond'; + }); + + expect(new PasteMarkdownTable(data).isTable()).toBe(false); + }); }); describe('convertToTableMarkdown', () => { diff --git a/spec/frontend/behaviors/markdown/render_metrics_spec.js b/spec/frontend/behaviors/markdown/render_metrics_spec.js index 3f7beeb817b..ab81ed6b8f0 100644 --- a/spec/frontend/behaviors/markdown/render_metrics_spec.js +++ b/spec/frontend/behaviors/markdown/render_metrics_spec.js @@ -11,20 +11,20 @@ const getElements = () => Array.from(document.getElementsByClassName('js-render- describe('Render metrics for Gitlab Flavoured Markdown', () => { it('does nothing when no elements are found', () => { - renderMetrics([]); - - expect(mockEmbedGroup).not.toHaveBeenCalled(); + return renderMetrics([]).then(() => { + expect(mockEmbedGroup).not.toHaveBeenCalled(); + }); }); it('renders a vue component when elements are found', () => { document.body.innerHTML = `
`; - renderMetrics(getElements()); - - expect(mockEmbedGroup).toHaveBeenCalledTimes(1); - expect(mockEmbedGroup).toHaveBeenCalledWith( - expect.objectContaining({ propsData: { urls: [`${TEST_HOST}`] } }), - ); + return renderMetrics(getElements()).then(() => { + expect(mockEmbedGroup).toHaveBeenCalledTimes(1); + expect(mockEmbedGroup).toHaveBeenCalledWith( + expect.objectContaining({ propsData: { urls: [`${TEST_HOST}`] } }), + ); + }); }); it('takes sibling metrics and groups them under a shared parent', () => { @@ -36,14 +36,14 @@ describe('Render metrics for Gitlab Flavoured Markdown', () => {
`; - renderMetrics(getElements()); - - expect(mockEmbedGroup).toHaveBeenCalledTimes(2); - expect(mockEmbedGroup).toHaveBeenCalledWith( - expect.objectContaining({ propsData: { urls: [`${TEST_HOST}/1`, `${TEST_HOST}/2`] } }), - ); - expect(mockEmbedGroup).toHaveBeenCalledWith( - expect.objectContaining({ propsData: { urls: [`${TEST_HOST}/3`] } }), - ); + return renderMetrics(getElements()).then(() => { + expect(mockEmbedGroup).toHaveBeenCalledTimes(2); + expect(mockEmbedGroup).toHaveBeenCalledWith( + expect.objectContaining({ propsData: { urls: [`${TEST_HOST}/1`, `${TEST_HOST}/2`] } }), + ); + expect(mockEmbedGroup).toHaveBeenCalledWith( + expect.objectContaining({ propsData: { urls: [`${TEST_HOST}/3`] } }), + ); + }); }); }); diff --git a/spec/frontend/blob/components/__snapshots__/blob_edit_header_spec.js.snap b/spec/frontend/blob/components/__snapshots__/blob_edit_header_spec.js.snap index e47a7dcfa2a..1e639f91797 100644 --- a/spec/frontend/blob/components/__snapshots__/blob_edit_header_spec.js.snap +++ b/spec/frontend/blob/components/__snapshots__/blob_edit_header_spec.js.snap @@ -5,7 +5,7 @@ exports[`Blob Header Editing rendering matches the snapshot 1`] = ` class="js-file-title file-title-flex-parent" >