summaryrefslogtreecommitdiff
path: root/spec/javascripts
diff options
context:
space:
mode:
Diffstat (limited to 'spec/javascripts')
-rw-r--r--spec/javascripts/.eslintrc.yml4
-rw-r--r--spec/javascripts/ajax_loading_spinner_spec.js9
-rw-r--r--spec/javascripts/avatar_helper_spec.js2
-rw-r--r--spec/javascripts/awards_handler_spec.js692
-rw-r--r--spec/javascripts/badges/components/badge_form_spec.js11
-rw-r--r--spec/javascripts/badges/components/badge_list_row_spec.js5
-rw-r--r--spec/javascripts/badges/components/badge_list_spec.js3
-rw-r--r--spec/javascripts/badges/components/badge_settings_spec.js9
-rw-r--r--spec/javascripts/badges/components/badge_spec.js3
-rw-r--r--spec/javascripts/badges/store/actions_spec.js7
-rw-r--r--spec/javascripts/behaviors/autosize_spec.js1
-rw-r--r--spec/javascripts/behaviors/bind_in_out_spec.js113
-rw-r--r--spec/javascripts/behaviors/copy_as_gfm_spec.js6
-rw-r--r--spec/javascripts/behaviors/gl_emoji/unicode_support_map_spec.js4
-rw-r--r--spec/javascripts/behaviors/quick_submit_spec.js19
-rw-r--r--spec/javascripts/behaviors/requires_input_spec.js30
-rw-r--r--spec/javascripts/behaviors/secret_values_spec.js36
-rw-r--r--spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js3
-rw-r--r--spec/javascripts/blob/3d_viewer/mesh_object_spec.js20
-rw-r--r--spec/javascripts/blob/balsamiq/balsamiq_viewer_integration_spec.js14
-rw-r--r--spec/javascripts/blob/balsamiq/balsamiq_viewer_spec.js18
-rw-r--r--spec/javascripts/blob/blob_file_dropzone_spec.js2
-rw-r--r--spec/javascripts/blob/blob_fork_suggestion_spec.js5
-rw-r--r--spec/javascripts/blob/notebook/index_spec.js86
-rw-r--r--spec/javascripts/blob/pdf/index_spec.js32
-rw-r--r--spec/javascripts/blob/sketch/index_spec.js108
-rw-r--r--spec/javascripts/blob/viewer/index_spec.js48
-rw-r--r--spec/javascripts/boards/board_blank_state_spec.js64
-rw-r--r--spec/javascripts/boards/board_card_spec.js43
-rw-r--r--spec/javascripts/boards/board_new_issue_spec.js24
-rw-r--r--spec/javascripts/boards/boards_store_spec.js35
-rw-r--r--spec/javascripts/boards/components/board_spec.js2
-rw-r--r--spec/javascripts/boards/issue_spec.js47
-rw-r--r--spec/javascripts/boards/list_spec.js94
-rw-r--r--spec/javascripts/bootstrap_jquery_spec.js74
-rw-r--r--spec/javascripts/bootstrap_linked_tabs_spec.js87
-rw-r--r--spec/javascripts/breakpoints_spec.js6
-rw-r--r--spec/javascripts/ci_variable_list/ajax_variable_list_spec.js60
-rw-r--r--spec/javascripts/ci_variable_list/ci_variable_list_spec.js26
-rw-r--r--spec/javascripts/ci_variable_list/native_form_variable_list_spec.js10
-rw-r--r--spec/javascripts/close_reopen_report_toggle_spec.js8
-rw-r--r--spec/javascripts/clusters/clusters_bundle_spec.js213
-rw-r--r--spec/javascripts/clusters/components/application_row_spec.js41
-rw-r--r--spec/javascripts/clusters/services/mock_data.js117
-rw-r--r--spec/javascripts/clusters/stores/clusters_store_spec.js12
-rw-r--r--spec/javascripts/collapsed_sidebar_todo_spec.js50
-rw-r--r--spec/javascripts/comment_type_toggle_spec.js114
-rw-r--r--spec/javascripts/commit/commit_pipeline_status_component_spec.js31
-rw-r--r--spec/javascripts/commit/pipelines/pipelines_spec.js14
-rw-r--r--spec/javascripts/commit_merge_requests_spec.js11
-rw-r--r--spec/javascripts/create_item_dropdown_spec.js49
-rw-r--r--spec/javascripts/create_merge_request_dropdown_spec.js1
-rw-r--r--spec/javascripts/cycle_analytics/banner_spec.js23
-rw-r--r--spec/javascripts/datetime_utility_spec.js183
-rw-r--r--spec/javascripts/deploy_keys/components/app_spec.js5
-rw-r--r--spec/javascripts/deploy_keys/components/key_spec.js3
-rw-r--r--spec/javascripts/diff_comments_store_spec.js10
-rw-r--r--spec/javascripts/diffs/components/app_spec.js9
-rw-r--r--spec/javascripts/diffs/components/commit_item_spec.js3
-rw-r--r--spec/javascripts/diffs/components/diff_file_header_spec.js24
-rw-r--r--spec/javascripts/diffs/components/diff_file_spec.js11
-rw-r--r--spec/javascripts/diffs/components/diff_gutter_avatars_spec.js2
-rw-r--r--spec/javascripts/diffs/components/diff_line_gutter_content_spec.js5
-rw-r--r--spec/javascripts/diffs/components/diff_line_note_form_spec.js4
-rw-r--r--spec/javascripts/diffs/components/inline_diff_view_spec.js4
-rw-r--r--spec/javascripts/diffs/components/tree_list_spec.js72
-rw-r--r--spec/javascripts/diffs/mock_data/diff_with_commit.js5
-rw-r--r--spec/javascripts/diffs/store/actions_spec.js9
-rw-r--r--spec/javascripts/diffs/store/getters_spec.js4
-rw-r--r--spec/javascripts/diffs/store/mutations_spec.js81
-rw-r--r--spec/javascripts/diffs/store/utils_spec.js31
-rw-r--r--spec/javascripts/dirty_submit/dirty_submit_collection_spec.js29
-rw-r--r--spec/javascripts/dirty_submit/dirty_submit_factory_spec.js18
-rw-r--r--spec/javascripts/dirty_submit/dirty_submit_form_spec.js24
-rw-r--r--spec/javascripts/dirty_submit/helper.js31
-rw-r--r--spec/javascripts/droplab/drop_down_spec.js251
-rw-r--r--spec/javascripts/droplab/hook_spec.js34
-rw-r--r--spec/javascripts/droplab/plugins/ajax_filter_spec.js10
-rw-r--r--spec/javascripts/droplab/plugins/ajax_spec.js7
-rw-r--r--spec/javascripts/droplab/plugins/input_setter_spec.js98
-rw-r--r--spec/javascripts/dropzone_input_spec.js6
-rw-r--r--spec/javascripts/emoji_spec.js62
-rw-r--r--spec/javascripts/environments/emtpy_state_spec.js4
-rw-r--r--spec/javascripts/environments/environment_actions_spec.js19
-rw-r--r--spec/javascripts/environments/environments_app_spec.js19
-rw-r--r--spec/javascripts/environments/environments_store_spec.js15
-rw-r--r--spec/javascripts/feature_highlight/feature_highlight_helper_spec.js17
-rw-r--r--spec/javascripts/feature_highlight/feature_highlight_spec.js8
-rw-r--r--spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js26
-rw-r--r--spec/javascripts/filtered_search/dropdown_user_spec.js9
-rw-r--r--spec/javascripts/filtered_search/dropdown_utils_spec.js108
-rw-r--r--spec/javascripts/filtered_search/filtered_search_manager_spec.js48
-rw-r--r--spec/javascripts/filtered_search/filtered_search_token_keys_spec.js83
-rw-r--r--spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js38
-rw-r--r--spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js205
-rw-r--r--spec/javascripts/filtered_search/recent_searches_root_spec.js2
-rw-r--r--spec/javascripts/filtered_search/services/recent_searches_service_spec.js27
-rw-r--r--spec/javascripts/filtered_search/stores/recent_searches_store_spec.js10
-rw-r--r--spec/javascripts/fixtures/groups.rb10
-rw-r--r--spec/javascripts/flash_spec.js149
-rw-r--r--spec/javascripts/fly_out_nav_spec.js127
-rw-r--r--spec/javascripts/frequent_items/components/app_spec.js3
-rw-r--r--spec/javascripts/frequent_items/components/frequent_items_list_item_spec.js6
-rw-r--r--spec/javascripts/frequent_items/components/frequent_items_list_spec.js6
-rw-r--r--spec/javascripts/frequent_items/components/frequent_items_search_input_spec.js1
-rw-r--r--spec/javascripts/gfm_auto_complete_spec.js96
-rw-r--r--spec/javascripts/gl_dropdown_spec.js104
-rw-r--r--spec/javascripts/gl_field_errors_spec.js41
-rw-r--r--spec/javascripts/gl_form_spec.js7
-rw-r--r--spec/javascripts/gpg_badges_spec.js2
-rw-r--r--spec/javascripts/graphs/stat_graph_contributors_graph_spec.js103
-rw-r--r--spec/javascripts/graphs/stat_graph_contributors_spec.js4
-rw-r--r--spec/javascripts/graphs/stat_graph_contributors_util_spec.js243
-rw-r--r--spec/javascripts/groups/components/app_spec.js25
-rw-r--r--spec/javascripts/groups/components/group_folder_spec.js3
-rw-r--r--spec/javascripts/groups/components/group_item_spec.js15
-rw-r--r--spec/javascripts/groups/components/groups_spec.js17
-rw-r--r--spec/javascripts/groups/components/item_actions_spec.js9
-rw-r--r--spec/javascripts/groups/components/item_caret_spec.js3
-rw-r--r--spec/javascripts/groups/components/item_stats_spec.js25
-rw-r--r--spec/javascripts/groups/components/item_stats_value_spec.js6
-rw-r--r--spec/javascripts/groups/components/item_type_icon_spec.js5
-rw-r--r--spec/javascripts/groups/mock_data.js3
-rw-r--r--spec/javascripts/groups/service/groups_service_spec.js3
-rw-r--r--spec/javascripts/groups/store/groups_store_spec.js29
-rw-r--r--spec/javascripts/header_spec.js5
-rw-r--r--spec/javascripts/helpers/class_spec_helper_spec.js6
-rw-r--r--spec/javascripts/helpers/locale_helper.js2
-rw-r--r--spec/javascripts/helpers/set_timeout_promise_helper.js7
-rw-r--r--spec/javascripts/helpers/user_mock_data_helper.js14
-rw-r--r--spec/javascripts/helpers/vue_resource_helper.js2
-rw-r--r--spec/javascripts/ide/components/branches/item_spec.js5
-rw-r--r--spec/javascripts/ide/components/branches/search_list_spec.js5
-rw-r--r--spec/javascripts/ide/components/commit_sidebar/message_field_spec.js23
-rw-r--r--spec/javascripts/ide/components/file_finder/index_spec.js9
-rw-r--r--spec/javascripts/ide/components/ide_spec.js9
-rw-r--r--spec/javascripts/ide/components/ide_status_bar_spec.js5
-rw-r--r--spec/javascripts/ide/components/jobs/detail_spec.js3
-rw-r--r--spec/javascripts/ide/components/merge_requests/item_spec.js5
-rw-r--r--spec/javascripts/ide/components/merge_requests/list_spec.js5
-rw-r--r--spec/javascripts/ide/components/new_dropdown/index_spec.js1
-rw-r--r--spec/javascripts/ide/components/new_dropdown/upload_spec.js40
-rw-r--r--spec/javascripts/ide/components/preview/clientside_spec.js3
-rw-r--r--spec/javascripts/ide/components/repo_editor_spec.js12
-rw-r--r--spec/javascripts/ide/components/shared/tokened_input_spec.js5
-rw-r--r--spec/javascripts/ide/stores/actions/merge_request_spec.js36
-rw-r--r--spec/javascripts/ide/stores/actions/project_spec.js5
-rw-r--r--spec/javascripts/ide/stores/actions/tree_spec.js1
-rw-r--r--spec/javascripts/ide/stores/actions_spec.js2
-rw-r--r--spec/javascripts/ide/stores/modules/branches/actions_spec.js1
-rw-r--r--spec/javascripts/ide/stores/modules/file_templates/mutations_spec.js8
-rw-r--r--spec/javascripts/ide/stores/modules/pane/actions_spec.js27
-rw-r--r--spec/javascripts/ide/stores/modules/pane/getters_spec.js10
-rw-r--r--spec/javascripts/ide/stores/mutations/merge_request_spec.js2
-rw-r--r--spec/javascripts/image_diff/helpers/badge_helper_spec.js1
-rw-r--r--spec/javascripts/image_diff/helpers/comment_indicator_helper_spec.js7
-rw-r--r--spec/javascripts/image_diff/helpers/dom_helper_spec.js2
-rw-r--r--spec/javascripts/image_diff/helpers/utils_helper_spec.js18
-rw-r--r--spec/javascripts/image_diff/image_badge_spec.js30
-rw-r--r--spec/javascripts/image_diff/image_diff_spec.js20
-rw-r--r--spec/javascripts/image_diff/init_discussion_tab_spec.js15
-rw-r--r--spec/javascripts/image_diff/replaced_image_diff_spec.js95
-rw-r--r--spec/javascripts/importer_status_spec.js64
-rw-r--r--spec/javascripts/integrations/integration_settings_form_spec.js82
-rw-r--r--spec/javascripts/issuable_spec.js5
-rw-r--r--spec/javascripts/issue_show/components/app_spec.js275
-rw-r--r--spec/javascripts/issue_show/components/description_spec.js49
-rw-r--r--spec/javascripts/issue_show/components/edit_actions_spec.js65
-rw-r--r--spec/javascripts/issue_show/components/fields/description_spec.js24
-rw-r--r--spec/javascripts/issue_show/components/fields/description_template_spec.js16
-rw-r--r--spec/javascripts/issue_show/components/fields/title_spec.js12
-rw-r--r--spec/javascripts/issue_show/components/form_spec.js22
-rw-r--r--spec/javascripts/issue_show/components/title_spec.js3
-rw-r--r--spec/javascripts/issue_spec.js18
-rw-r--r--spec/javascripts/job_spec.js560
-rw-r--r--spec/javascripts/jobs/components/commit_block_spec.js2
-rw-r--r--spec/javascripts/jobs/components/empty_state_spec.js2
-rw-r--r--spec/javascripts/jobs/components/environments_block_spec.js3
-rw-r--r--spec/javascripts/jobs/components/job_app_spec.js706
-rw-r--r--spec/javascripts/jobs/components/job_container_item_spec.js73
-rw-r--r--spec/javascripts/jobs/components/job_log_controllers_spec.js2
-rw-r--r--spec/javascripts/jobs/components/job_log_spec.js44
-rw-r--r--spec/javascripts/jobs/components/sidebar_detail_row_spec.js6
-rw-r--r--spec/javascripts/jobs/components/sidebar_spec.js27
-rw-r--r--spec/javascripts/jobs/components/stages_dropdown_spec.js20
-rw-r--r--spec/javascripts/jobs/components/trigger_block_spec.js13
-rw-r--r--spec/javascripts/jobs/mock_data.js6
-rw-r--r--spec/javascripts/jobs/store/actions_spec.js205
-rw-r--r--spec/javascripts/jobs/store/getters_spec.js45
-rw-r--r--spec/javascripts/jobs/store/helpers.js6
-rw-r--r--spec/javascripts/jobs/store/mutations_spec.js89
-rw-r--r--spec/javascripts/labels_issue_sidebar_spec.js134
-rw-r--r--spec/javascripts/labels_select_spec.js14
-rw-r--r--spec/javascripts/landing_spec.js70
-rw-r--r--spec/javascripts/lib/utils/accessor_spec.js14
-rw-r--r--spec/javascripts/lib/utils/ajax_cache_spec.js66
-rw-r--r--spec/javascripts/lib/utils/common_utils_spec.js29
-rw-r--r--spec/javascripts/lib/utils/csrf_token_spec.js5
-rw-r--r--spec/javascripts/lib/utils/datefix_spec.js27
-rw-r--r--spec/javascripts/lib/utils/datetime_utility_spec.js372
-rw-r--r--spec/javascripts/lib/utils/dom_utils_spec.js2
-rw-r--r--spec/javascripts/lib/utils/mock_data.js9
-rw-r--r--spec/javascripts/lib/utils/number_utility_spec.js4
-rw-r--r--spec/javascripts/lib/utils/poll_spec.js26
-rw-r--r--spec/javascripts/lib/utils/sticky_spec.js29
-rw-r--r--spec/javascripts/lib/utils/text_markdown_spec.js95
-rw-r--r--spec/javascripts/lib/utils/users_cache_spec.js52
-rw-r--r--spec/javascripts/line_highlighter_spec.js417
-rw-r--r--spec/javascripts/locale/ensure_single_line_spec.js3
-rw-r--r--spec/javascripts/merge_request_spec.js185
-rw-r--r--spec/javascripts/merge_request_tabs_spec.js8
-rw-r--r--spec/javascripts/mini_pipeline_graph_dropdown_spec.js12
-rw-r--r--spec/javascripts/monitoring/dashboard_spec.js18
-rw-r--r--spec/javascripts/monitoring/dashboard_state_spec.js28
-rw-r--r--spec/javascripts/monitoring/graph/deployment_spec.js6
-rw-r--r--spec/javascripts/monitoring/graph_path_spec.js4
-rw-r--r--spec/javascripts/monitoring/graph_spec.js3
-rw-r--r--spec/javascripts/monitoring/monitoring_store_spec.js4
-rw-r--r--spec/javascripts/new_branch_spec.js355
-rw-r--r--spec/javascripts/notebook/cells/code_spec.js4
-rw-r--r--spec/javascripts/notebook/cells/markdown_spec.js30
-rw-r--r--spec/javascripts/notebook/cells/output/html_sanitize_tests.js8
-rw-r--r--spec/javascripts/notebook/cells/output/html_spec.js2
-rw-r--r--spec/javascripts/notebook/cells/output/index_spec.js14
-rw-r--r--spec/javascripts/notebook/cells/prompt_spec.js4
-rw-r--r--spec/javascripts/notebook/index_spec.js10
-rw-r--r--spec/javascripts/notes/components/comment_form_spec.js12
-rw-r--r--spec/javascripts/notes/components/discussion_filter_spec.js60
-rw-r--r--spec/javascripts/notes/components/note_app_spec.js5
-rw-r--r--spec/javascripts/notes/components/note_form_spec.js2
-rw-r--r--spec/javascripts/notes/components/noteable_discussion_spec.js10
-rw-r--r--spec/javascripts/notes/components/noteable_note_spec.js1
-rw-r--r--spec/javascripts/notes/helpers.js2
-rw-r--r--spec/javascripts/notes/mock_data.js15
-rw-r--r--spec/javascripts/notes/stores/collapse_utils_spec.js13
-rw-r--r--spec/javascripts/notes/stores/getters_spec.js1
-rw-r--r--spec/javascripts/notes/stores/mutation_spec.js15
-rw-r--r--spec/javascripts/notes_spec.js1593
-rw-r--r--spec/javascripts/oauth_remember_me_spec.js9
-rw-r--r--spec/javascripts/pager_spec.js5
-rw-r--r--spec/javascripts/pages/admin/abuse_reports/abuse_reports_spec.js14
-rw-r--r--spec/javascripts/pages/admin/application_settings/account_and_limits_spec.js9
-rw-r--r--spec/javascripts/pages/admin/jobs/index/components/stop_jobs_modal_spec.js20
-rw-r--r--spec/javascripts/pages/admin/users/new/index_spec.js4
-rw-r--r--spec/javascripts/pages/labels/components/promote_label_modal_spec.js36
-rw-r--r--spec/javascripts/pages/milestones/shared/components/delete_milestone_modal_spec.js43
-rw-r--r--spec/javascripts/pages/milestones/shared/components/promote_milestone_modal_spec.js36
-rw-r--r--spec/javascripts/pages/profiles/show/emoji_menu_spec.js2
-rw-r--r--spec/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js74
-rw-r--r--spec/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedule_callout_spec.js8
-rw-r--r--spec/javascripts/pdf/index_spec.js6
-rw-r--r--spec/javascripts/pdf/page_spec.js1
-rw-r--r--spec/javascripts/performance_bar/components/detailed_metric_spec.js8
-rw-r--r--spec/javascripts/performance_bar/components/request_selector_spec.js3
-rw-r--r--spec/javascripts/performance_bar/index_spec.js5
-rw-r--r--spec/javascripts/performance_bar/services/performance_bar_service_spec.js37
-rw-r--r--spec/javascripts/pipelines/blank_state_spec.js14
-rw-r--r--spec/javascripts/pipelines/empty_state_spec.js25
-rw-r--r--spec/javascripts/pipelines/graph/action_component_spec.js16
-rw-r--r--spec/javascripts/pipelines/graph/job_group_dropdown_spec.js (renamed from spec/javascripts/pipelines/graph/dropdown_job_component_spec.js)18
-rw-r--r--spec/javascripts/pipelines/graph/job_item_spec.js (renamed from spec/javascripts/pipelines/graph/job_component_spec.js)42
-rw-r--r--spec/javascripts/pipelines/graph/stage_column_component_spec.js17
-rw-r--r--spec/javascripts/pipelines/header_component_spec.js7
-rw-r--r--spec/javascripts/pipelines/nav_controls_spec.js12
-rw-r--r--spec/javascripts/pipelines/pipeline_store_spec.js1
-rw-r--r--spec/javascripts/pipelines/pipeline_url_spec.js3
-rw-r--r--spec/javascripts/pipelines/pipelines_actions_spec.js2
-rw-r--r--spec/javascripts/pipelines/pipelines_artifacts_spec.js16
-rw-r--r--spec/javascripts/pipelines/pipelines_spec.js202
-rw-r--r--spec/javascripts/pipelines/pipelines_store_spec.js5
-rw-r--r--spec/javascripts/pipelines/pipelines_table_row_spec.js7
-rw-r--r--spec/javascripts/pipelines/pipelines_table_spec.js20
-rw-r--r--spec/javascripts/pipelines/stage_spec.js14
-rw-r--r--spec/javascripts/pipelines_spec.js4
-rw-r--r--spec/javascripts/polyfills/element_spec.js2
-rw-r--r--spec/javascripts/pretty_time_spec.js133
-rw-r--r--spec/javascripts/profile/account/components/delete_account_modal_spec.js16
-rw-r--r--spec/javascripts/profile/account/components/update_username_spec.js7
-rw-r--r--spec/javascripts/project_select_combo_button_spec.js56
-rw-r--r--spec/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown_spec.js22
-rw-r--r--spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js62
-rw-r--r--spec/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown_spec.js22
-rw-r--r--spec/javascripts/projects/project_new_spec.js5
-rw-r--r--spec/javascripts/prometheus_metrics/prometheus_metrics_spec.js18
-rw-r--r--spec/javascripts/raven/raven_config_spec.js2
-rw-r--r--spec/javascripts/registry/components/app_spec.js53
-rw-r--r--spec/javascripts/registry/components/collapsible_container_spec.js16
-rw-r--r--spec/javascripts/registry/components/table_registry_spec.js14
-rw-r--r--spec/javascripts/registry/getters_spec.js41
-rw-r--r--spec/javascripts/registry/mock_data.js3
-rw-r--r--spec/javascripts/registry/stores/mutations_spec.js4
-rw-r--r--spec/javascripts/reports/components/grouped_test_reports_app_spec.js4
-rw-r--r--spec/javascripts/reports/components/modal_spec.js17
-rw-r--r--spec/javascripts/reports/components/report_link_spec.js6
-rw-r--r--spec/javascripts/reports/components/report_section_spec.js3
-rw-r--r--spec/javascripts/reports/components/test_issue_body_spec.js1
-rw-r--r--spec/javascripts/reports/store/mutations_spec.js2
-rw-r--r--spec/javascripts/right_sidebar_spec.js169
-rw-r--r--spec/javascripts/search_autocomplete_spec.js11
-rw-r--r--spec/javascripts/search_spec.js10
-rw-r--r--spec/javascripts/settings_panels_spec.js30
-rw-r--r--spec/javascripts/shared/popover_spec.js34
-rw-r--r--spec/javascripts/sidebar/assignees_spec.js10
-rw-r--r--spec/javascripts/sidebar/components/time_tracking/time_tracker_spec.js23
-rw-r--r--spec/javascripts/sidebar/confidential_edit_buttons_spec.js12
-rw-r--r--spec/javascripts/sidebar/confidential_edit_form_buttons_spec.js12
-rw-r--r--spec/javascripts/sidebar/confidential_issue_sidebar_spec.js32
-rw-r--r--spec/javascripts/sidebar/lock/edit_form_buttons_spec.js12
-rw-r--r--spec/javascripts/sidebar/lock/edit_form_spec.js12
-rw-r--r--spec/javascripts/sidebar/lock/lock_issue_sidebar_spec.js28
-rw-r--r--spec/javascripts/sidebar/participants_spec.js17
-rw-r--r--spec/javascripts/sidebar/sidebar_assignees_spec.js16
-rw-r--r--spec/javascripts/sidebar/sidebar_mediator_spec.js33
-rw-r--r--spec/javascripts/sidebar/sidebar_move_issue_spec.js24
-rw-r--r--spec/javascripts/sidebar/sidebar_store_spec.js18
-rw-r--r--spec/javascripts/sidebar/sidebar_subscriptions_spec.js2
-rw-r--r--spec/javascripts/sidebar/subscriptions_spec.js16
-rw-r--r--spec/javascripts/sidebar/todo_spec.js15
-rw-r--r--spec/javascripts/signin_tabs_memoizer_spec.js240
-rw-r--r--spec/javascripts/smart_interval_spec.js43
-rw-r--r--spec/javascripts/syntax_highlight_spec.js25
-rw-r--r--spec/javascripts/todos_spec.js4
-rw-r--r--spec/javascripts/toggle_buttons_spec.js18
-rw-r--r--spec/javascripts/u2f/authenticate_spec.js36
-rw-r--r--spec/javascripts/u2f/mock_u2f_device.js12
-rw-r--r--spec/javascripts/u2f/register_spec.js29
-rw-r--r--spec/javascripts/u2f/util_spec.js32
-rw-r--r--spec/javascripts/version_check_image_spec.js14
-rw-r--r--spec/javascripts/vue_mr_widget/components/deployment_spec.js78
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_author_spec.js10
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_author_time_spec.js8
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js25
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js55
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_merge_help_spec.js32
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js13
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js5
-rw-r--r--spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js4
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js6
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js6
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js4
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_closed_spec.js55
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js10
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js2
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js56
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js58
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_merging_spec.js27
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js1
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js4
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js5
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js6
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js6
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js136
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js6
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js18
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js22
-rw-r--r--spec/javascripts/vue_mr_widget/mr_widget_options_spec.js106
-rw-r--r--spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js14
-rw-r--r--spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js10
-rw-r--r--spec/javascripts/vue_shared/components/bar_chart_spec.js6
-rw-r--r--spec/javascripts/vue_shared/components/ci_badge_link_spec.js6
-rw-r--r--spec/javascripts/vue_shared/components/clipboard_button_spec.js1
-rw-r--r--spec/javascripts/vue_shared/components/commit_spec.js3
-rw-r--r--spec/javascripts/vue_shared/components/deprecated_modal_spec.js12
-rw-r--r--spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js1
-rw-r--r--spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js2
-rw-r--r--spec/javascripts/vue_shared/components/dropdown/dropdown_button_spec.js10
-rw-r--r--spec/javascripts/vue_shared/components/file_icon_spec.js18
-rw-r--r--spec/javascripts/vue_shared/components/file_row_spec.js36
-rw-r--r--spec/javascripts/vue_shared/components/filtered_search_dropdown_spec.js91
-rw-r--r--spec/javascripts/vue_shared/components/gl_countdown_spec.js77
-rw-r--r--spec/javascripts/vue_shared/components/gl_modal_spec.js7
-rw-r--r--spec/javascripts/vue_shared/components/header_ci_component_spec.js10
-rw-r--r--spec/javascripts/vue_shared/components/icon_spec.js17
-rw-r--r--spec/javascripts/vue_shared/components/identicon_spec.js2
-rw-r--r--spec/javascripts/vue_shared/components/issue/issue_warning_spec.js17
-rw-r--r--spec/javascripts/vue_shared/components/loading_button_spec.js4
-rw-r--r--spec/javascripts/vue_shared/components/markdown/field_spec.js77
-rw-r--r--spec/javascripts/vue_shared/components/markdown/header_spec.js23
-rw-r--r--spec/javascripts/vue_shared/components/markdown/toolbar_spec.js9
-rw-r--r--spec/javascripts/vue_shared/components/memory_graph_spec.js16
-rw-r--r--spec/javascripts/vue_shared/components/navigation_tabs_spec.js5
-rw-r--r--spec/javascripts/vue_shared/components/notes/placeholder_note_spec.js2
-rw-r--r--spec/javascripts/vue_shared/components/notes/placeholder_system_note_spec.js4
-rw-r--r--spec/javascripts/vue_shared/components/pagination_links_spec.js35
-rw-r--r--spec/javascripts/vue_shared/components/panel_resizer_spec.js27
-rw-r--r--spec/javascripts/vue_shared/components/pikaday_spec.js1
-rw-r--r--spec/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon_spec.js1
-rw-r--r--spec/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker_spec.js6
-rw-r--r--spec/javascripts/vue_shared/components/sidebar/date_picker_spec.js4
-rw-r--r--spec/javascripts/vue_shared/components/sidebar/labels_select/base_spec.js7
-rw-r--r--spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js4
-rw-r--r--spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js22
-rw-r--r--spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js12
-rw-r--r--spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_header_spec.js6
-rw-r--r--spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_search_input_spec.js5
-rw-r--r--spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title_spec.js1
-rw-r--r--spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js4
-rw-r--r--spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js23
-rw-r--r--spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js23
-rw-r--r--spec/javascripts/vue_shared/components/table_pagination_spec.js7
-rw-r--r--spec/javascripts/vue_shared/components/time_ago_tooltip_spec.js7
-rw-r--r--spec/javascripts/vue_shared/components/toggle_button_spec.js2
-rw-r--r--spec/javascripts/vue_shared/components/tooltip_on_truncate_spec.js16
-rw-r--r--spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js51
-rw-r--r--spec/javascripts/vue_shared/components/user_avatar/user_avatar_svg_spec.js10
-rw-r--r--spec/javascripts/vue_shared/directives/tooltip_spec.js45
-rw-r--r--spec/javascripts/zen_mode_spec.js7
407 files changed, 9173 insertions, 6586 deletions
diff --git a/spec/javascripts/.eslintrc.yml b/spec/javascripts/.eslintrc.yml
index 9b2c84ce9f5..b863156b57c 100644
--- a/spec/javascripts/.eslintrc.yml
+++ b/spec/javascripts/.eslintrc.yml
@@ -36,8 +36,4 @@ rules:
- ignore:
- 'fixtures/blob'
# Temporarily disabled to facilitate an upgrade to eslint-plugin-jasmine
- jasmine/new-line-before-expect: off
- jasmine/new-line-between-declarations: off
- jasmine/no-promise-without-done-fail: off
- jasmine/prefer-jasmine-matcher: off
jasmine/prefer-toHaveBeenCalledWith: off
diff --git a/spec/javascripts/ajax_loading_spinner_spec.js b/spec/javascripts/ajax_loading_spinner_spec.js
index 261375d3a0e..9389fc94f17 100644
--- a/spec/javascripts/ajax_loading_spinner_spec.js
+++ b/spec/javascripts/ajax_loading_spinner_spec.js
@@ -10,8 +10,8 @@ describe('Ajax Loading Spinner', () => {
AjaxLoadingSpinner.init();
});
- it('change current icon with spinner icon and disable link while waiting ajax response', (done) => {
- spyOn($, 'ajax').and.callFake((req) => {
+ it('change current icon with spinner icon and disable link while waiting ajax response', done => {
+ spyOn($, 'ajax').and.callFake(req => {
const xhr = new XMLHttpRequest();
const ajaxLoadingSpinner = document.querySelector('.js-ajax-loading-spinner');
const icon = ajaxLoadingSpinner.querySelector('i');
@@ -33,8 +33,8 @@ describe('Ajax Loading Spinner', () => {
document.querySelector('.js-ajax-loading-spinner').click();
});
- it('use original icon again and enabled the link after complete the ajax request', (done) => {
- spyOn($, 'ajax').and.callFake((req) => {
+ it('use original icon again and enabled the link after complete the ajax request', done => {
+ spyOn($, 'ajax').and.callFake(req => {
const xhr = new XMLHttpRequest();
const ajaxLoadingSpinner = document.querySelector('.js-ajax-loading-spinner');
@@ -42,6 +42,7 @@ describe('Ajax Loading Spinner', () => {
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');
diff --git a/spec/javascripts/avatar_helper_spec.js b/spec/javascripts/avatar_helper_spec.js
index b2f80678ae7..c1ef08e0f1b 100644
--- a/spec/javascripts/avatar_helper_spec.js
+++ b/spec/javascripts/avatar_helper_spec.js
@@ -21,7 +21,7 @@ describe('avatar_helper', () => {
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');
+ expect(getIdenticonBackgroundClass(IDENTICON_BG_COUNT * 5 + 6)).toEqual('bg7');
});
});
diff --git a/spec/javascripts/awards_handler_spec.js b/spec/javascripts/awards_handler_spec.js
index 0c5d68990d5..b0689fc7cfe 100644
--- a/spec/javascripts/awards_handler_spec.js
+++ b/spec/javascripts/awards_handler_spec.js
@@ -1,382 +1,400 @@
-/* eslint-disable no-var, one-var, no-unused-expressions, no-unused-vars, prefer-template */
-
import $ from 'jquery';
import Cookies from 'js-cookie';
import loadAwardsHandler from '~/awards_handler';
-
import '~/lib/utils/common_utils';
-(function() {
- var awardsHandler, lazyAssert, urlRoot, openAndWaitForEmojiMenu;
+window.gl = window.gl || {};
+window.gon = window.gon || {};
- awardsHandler = null;
+let openAndWaitForEmojiMenu;
+let awardsHandler = null;
+const urlRoot = gon.relative_url_root;
- window.gl || (window.gl = {});
+const lazyAssert = function(done, assertFn) {
+ setTimeout(function() {
+ assertFn();
+ done();
+ // Maybe jasmine.clock here?
+ }, 333);
+};
- window.gon || (window.gon = {});
+describe('AwardsHandler', function() {
+ preloadFixtures('snippets/show.html.raw');
+ beforeEach(function(done) {
+ loadFixtures('snippets/show.html.raw');
+ loadAwardsHandler(true)
+ .then(obj => {
+ awardsHandler = obj;
+ spyOn(awardsHandler, 'postEmoji').and.callFake((button, url, emoji, cb) => cb());
+ done();
+ })
+ .catch(fail);
- urlRoot = gon.relative_url_root;
+ let isEmojiMenuBuilt = false;
+ openAndWaitForEmojiMenu = function() {
+ return new Promise(resolve => {
+ if (isEmojiMenuBuilt) {
+ resolve();
+ } else {
+ $('.js-add-award')
+ .eq(0)
+ .click();
+ const $menu = $('.emoji-menu');
+ $menu.one('build-emoji-menu-finish', () => {
+ isEmojiMenuBuilt = true;
+ resolve();
+ });
+ }
+ });
+ };
+ });
- lazyAssert = function(done, assertFn) {
- return setTimeout(function() {
- assertFn();
- return done();
- // Maybe jasmine.clock here?
- }, 333);
- };
+ afterEach(function() {
+ // restore original url root value
+ gon.relative_url_root = urlRoot;
- describe('AwardsHandler', function() {
- preloadFixtures('snippets/show.html.raw');
- beforeEach(function(done) {
- loadFixtures('snippets/show.html.raw');
- loadAwardsHandler(true)
- .then(obj => {
- awardsHandler = obj;
- spyOn(awardsHandler, 'postEmoji').and.callFake((button, url, emoji, cb) => cb());
- done();
- })
- .catch(fail);
+ // Undo what we did to the shared <body>
+ $('body').removeAttr('data-page');
- let isEmojiMenuBuilt = false;
- openAndWaitForEmojiMenu = function() {
- return new Promise((resolve, reject) => {
- if (isEmojiMenuBuilt) {
- resolve();
- } else {
- $('.js-add-award')
- .eq(0)
- .click();
- const $menu = $('.emoji-menu');
- $menu.one('build-emoji-menu-finish', () => {
- isEmojiMenuBuilt = true;
- resolve();
- });
- }
- });
- };
- });
- afterEach(function() {
- // restore original url root value
- gon.relative_url_root = urlRoot;
+ awardsHandler.destroy();
+ });
- // Undo what we did to the shared <body>
- $('body').removeAttr('data-page');
+ describe('::showEmojiMenu', function() {
+ it('should show emoji menu when Add emoji button clicked', function(done) {
+ $('.js-add-award')
+ .eq(0)
+ .click();
+ lazyAssert(done, function() {
+ const $emojiMenu = $('.emoji-menu');
- awardsHandler.destroy();
- });
- describe('::showEmojiMenu', function() {
- it('should show emoji menu when Add emoji button clicked', function(done) {
- $('.js-add-award')
- .eq(0)
- .click();
- return lazyAssert(done, function() {
- var $emojiMenu;
- $emojiMenu = $('.emoji-menu');
- expect($emojiMenu.length).toBe(1);
- expect($emojiMenu.hasClass('is-visible')).toBe(true);
- expect($emojiMenu.find('.js-emoji-menu-search').length).toBe(1);
- return expect($('.js-awards-block.current').length).toBe(1);
- });
- });
- it('should also show emoji menu for the smiley icon in notes', function(done) {
- $('.js-add-award.note-action-button').click();
- return lazyAssert(done, function() {
- var $emojiMenu = $('.emoji-menu');
- return expect($emojiMenu.length).toBe(1);
- });
- });
- it('should remove emoji menu when body is clicked', function(done) {
- $('.js-add-award')
- .eq(0)
- .click();
- return lazyAssert(done, function() {
- var $emojiMenu;
- $emojiMenu = $('.emoji-menu');
- $('body').click();
- expect($emojiMenu.length).toBe(1);
- expect($emojiMenu.hasClass('is-visible')).toBe(false);
- return expect($('.js-awards-block.current').length).toBe(0);
- });
- });
- it('should not remove emoji menu when search is clicked', function(done) {
- $('.js-add-award')
- .eq(0)
- .click();
- return lazyAssert(done, function() {
- var $emojiMenu;
- $emojiMenu = $('.emoji-menu');
- $('.emoji-search').click();
- expect($emojiMenu.length).toBe(1);
- expect($emojiMenu.hasClass('is-visible')).toBe(true);
- return expect($('.js-awards-block.current').length).toBe(1);
- });
+ expect($emojiMenu.length).toBe(1);
+ expect($emojiMenu.hasClass('is-visible')).toBe(true);
+ expect($emojiMenu.find('.js-emoji-menu-search').length).toBe(1);
+ expect($('.js-awards-block.current').length).toBe(1);
});
});
- describe('::addAwardToEmojiBar', function() {
- it('should add emoji to votes block', function() {
- var $emojiButton, $votesBlock;
- $votesBlock = $('.js-awards-block').eq(0);
- awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
- $emojiButton = $votesBlock.find('[data-name=heart]');
- expect($emojiButton.length).toBe(1);
- expect($emojiButton.next('.js-counter').text()).toBe('1');
- return expect($votesBlock.hasClass('hidden')).toBe(false);
- });
- it('should remove the emoji when we click again', function() {
- var $emojiButton, $votesBlock;
- $votesBlock = $('.js-awards-block').eq(0);
- awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
- awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
- $emojiButton = $votesBlock.find('[data-name=heart]');
- return expect($emojiButton.length).toBe(0);
- });
- return it('should decrement the emoji counter', function() {
- var $emojiButton, $votesBlock;
- $votesBlock = $('.js-awards-block').eq(0);
- awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
- $emojiButton = $votesBlock.find('[data-name=heart]');
- $emojiButton.next('.js-counter').text(5);
- awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
- expect($emojiButton.length).toBe(1);
- return expect($emojiButton.next('.js-counter').text()).toBe('4');
+ it('should also show emoji menu for the smiley icon in notes', function(done) {
+ $('.js-add-award.note-action-button').click();
+ lazyAssert(done, function() {
+ const $emojiMenu = $('.emoji-menu');
+
+ expect($emojiMenu.length).toBe(1);
});
});
- describe('::userAuthored', function() {
- it('should update tooltip to user authored title', function() {
- var $thumbsUpEmoji, $votesBlock;
- $votesBlock = $('.js-awards-block').eq(0);
- $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
- $thumbsUpEmoji.attr('data-title', 'sam');
- awardsHandler.userAuthored($thumbsUpEmoji);
- return expect($thumbsUpEmoji.data('originalTitle')).toBe(
- 'You cannot vote on your own issue, MR and note',
- );
- });
- it('should restore tooltip back to initial vote list', function() {
- var $thumbsUpEmoji, $votesBlock;
- jasmine.clock().install();
- $votesBlock = $('.js-awards-block').eq(0);
- $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
- $thumbsUpEmoji.attr('data-title', 'sam');
- awardsHandler.userAuthored($thumbsUpEmoji);
- jasmine.clock().tick(2801);
- jasmine.clock().uninstall();
- return expect($thumbsUpEmoji.data('originalTitle')).toBe('sam');
+
+ it('should remove emoji menu when body is clicked', function(done) {
+ $('.js-add-award')
+ .eq(0)
+ .click();
+ lazyAssert(done, function() {
+ const $emojiMenu = $('.emoji-menu');
+ $('body').click();
+
+ expect($emojiMenu.length).toBe(1);
+ expect($emojiMenu.hasClass('is-visible')).toBe(false);
+ expect($('.js-awards-block.current').length).toBe(0);
});
});
- describe('::getAwardUrl', function() {
- return it('returns the url for request', function() {
- return expect(awardsHandler.getAwardUrl()).toBe(
- 'http://test.host/snippets/1/toggle_award_emoji',
- );
+
+ it('should not remove emoji menu when search is clicked', function(done) {
+ $('.js-add-award')
+ .eq(0)
+ .click();
+ lazyAssert(done, function() {
+ const $emojiMenu = $('.emoji-menu');
+ $('.emoji-search').click();
+
+ expect($emojiMenu.length).toBe(1);
+ expect($emojiMenu.hasClass('is-visible')).toBe(true);
+ expect($('.js-awards-block.current').length).toBe(1);
});
});
- describe('::addAward and ::checkMutuality', function() {
- return it('should handle :+1: and :-1: mutuality', function() {
- var $thumbsDownEmoji, $thumbsUpEmoji, $votesBlock, awardUrl;
- awardUrl = awardsHandler.getAwardUrl();
- $votesBlock = $('.js-awards-block').eq(0);
- $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
- $thumbsDownEmoji = $votesBlock.find('[data-name=thumbsdown]').parent();
- awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
- expect($thumbsUpEmoji.hasClass('active')).toBe(true);
- expect($thumbsDownEmoji.hasClass('active')).toBe(false);
- $thumbsUpEmoji.tooltip();
- $thumbsDownEmoji.tooltip();
- awardsHandler.addAward($votesBlock, awardUrl, 'thumbsdown', true);
- expect($thumbsUpEmoji.hasClass('active')).toBe(false);
- return expect($thumbsDownEmoji.hasClass('active')).toBe(true);
- });
+ });
+
+ describe('::addAwardToEmojiBar', function() {
+ it('should add emoji to votes block', function() {
+ const $votesBlock = $('.js-awards-block').eq(0);
+ awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
+ const $emojiButton = $votesBlock.find('[data-name=heart]');
+
+ expect($emojiButton.length).toBe(1);
+ expect($emojiButton.next('.js-counter').text()).toBe('1');
+ expect($votesBlock.hasClass('hidden')).toBe(false);
});
- describe('::removeEmoji', function() {
- return it('should remove emoji', function() {
- var $votesBlock, awardUrl;
- awardUrl = awardsHandler.getAwardUrl();
- $votesBlock = $('.js-awards-block').eq(0);
- awardsHandler.addAward($votesBlock, awardUrl, 'fire', false);
- expect($votesBlock.find('[data-name=fire]').length).toBe(1);
- awardsHandler.removeEmoji($votesBlock.find('[data-name=fire]').closest('button'));
- return expect($votesBlock.find('[data-name=fire]').length).toBe(0);
- });
+
+ it('should remove the emoji when we click again', function() {
+ const $votesBlock = $('.js-awards-block').eq(0);
+ awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
+ awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
+ const $emojiButton = $votesBlock.find('[data-name=heart]');
+
+ expect($emojiButton.length).toBe(0);
});
- describe('::addYouToUserList', function() {
- it('should prepend "You" to the award tooltip', function() {
- var $thumbsUpEmoji, $votesBlock, awardUrl;
- awardUrl = awardsHandler.getAwardUrl();
- $votesBlock = $('.js-awards-block').eq(0);
- $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
- $thumbsUpEmoji.attr('data-title', 'sam, jerry, max, and andy');
- awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
- $thumbsUpEmoji.tooltip();
- return expect($thumbsUpEmoji.data('originalTitle')).toBe('You, sam, jerry, max, and andy');
- });
- return it('handles the special case where "You" is not cleanly comma seperated', function() {
- var $thumbsUpEmoji, $votesBlock, awardUrl;
- awardUrl = awardsHandler.getAwardUrl();
- $votesBlock = $('.js-awards-block').eq(0);
- $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
- $thumbsUpEmoji.attr('data-title', 'sam');
- awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
- $thumbsUpEmoji.tooltip();
- return expect($thumbsUpEmoji.data('originalTitle')).toBe('You and sam');
- });
+
+ it('should decrement the emoji counter', function() {
+ const $votesBlock = $('.js-awards-block').eq(0);
+ awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
+ const $emojiButton = $votesBlock.find('[data-name=heart]');
+ $emojiButton.next('.js-counter').text(5);
+ awardsHandler.addAwardToEmojiBar($votesBlock, 'heart', false);
+
+ expect($emojiButton.length).toBe(1);
+ expect($emojiButton.next('.js-counter').text()).toBe('4');
});
- describe('::removeYouToUserList', function() {
- it('removes "You" from the front of the tooltip', function() {
- var $thumbsUpEmoji, $votesBlock, awardUrl;
- awardUrl = awardsHandler.getAwardUrl();
- $votesBlock = $('.js-awards-block').eq(0);
- $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
- $thumbsUpEmoji.attr('data-title', 'You, sam, jerry, max, and andy');
- $thumbsUpEmoji.addClass('active');
- awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
- $thumbsUpEmoji.tooltip();
- return expect($thumbsUpEmoji.data('originalTitle')).toBe('sam, jerry, max, and andy');
- });
- return it('handles the special case where "You" is not cleanly comma seperated', function() {
- var $thumbsUpEmoji, $votesBlock, awardUrl;
- awardUrl = awardsHandler.getAwardUrl();
- $votesBlock = $('.js-awards-block').eq(0);
- $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
- $thumbsUpEmoji.attr('data-title', 'You and sam');
- $thumbsUpEmoji.addClass('active');
- awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
- $thumbsUpEmoji.tooltip();
- return expect($thumbsUpEmoji.data('originalTitle')).toBe('sam');
- });
+ });
+
+ describe('::userAuthored', function() {
+ it('should update tooltip to user authored title', function() {
+ const $votesBlock = $('.js-awards-block').eq(0);
+ const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ $thumbsUpEmoji.attr('data-title', 'sam');
+ awardsHandler.userAuthored($thumbsUpEmoji);
+
+ expect($thumbsUpEmoji.data('originalTitle')).toBe(
+ 'You cannot vote on your own issue, MR and note',
+ );
});
- describe('::searchEmojis', () => {
- it('should filter the emoji', function(done) {
- return openAndWaitForEmojiMenu()
- .then(() => {
- expect($('[data-name=angel]').is(':visible')).toBe(true);
- expect($('[data-name=anger]').is(':visible')).toBe(true);
- awardsHandler.searchEmojis('ali');
- expect($('[data-name=angel]').is(':visible')).toBe(false);
- expect($('[data-name=anger]').is(':visible')).toBe(false);
- expect($('[data-name=alien]').is(':visible')).toBe(true);
- expect($('.js-emoji-menu-search').val()).toBe('ali');
- })
- .then(done)
- .catch(err => {
- done.fail(`Failed to open and build emoji menu: ${err.message}`);
- });
- });
- it('should clear the search when searching for nothing', function(done) {
- return openAndWaitForEmojiMenu()
- .then(() => {
- awardsHandler.searchEmojis('ali');
- expect($('[data-name=angel]').is(':visible')).toBe(false);
- expect($('[data-name=anger]').is(':visible')).toBe(false);
- expect($('[data-name=alien]').is(':visible')).toBe(true);
- awardsHandler.searchEmojis('');
- expect($('[data-name=angel]').is(':visible')).toBe(true);
- expect($('[data-name=anger]').is(':visible')).toBe(true);
- expect($('[data-name=alien]').is(':visible')).toBe(true);
- expect($('.js-emoji-menu-search').val()).toBe('');
- })
- .then(done)
- .catch(err => {
- done.fail(`Failed to open and build emoji menu: ${err.message}`);
- });
+
+ it('should restore tooltip back to initial vote list', function() {
+ jasmine.clock().install();
+ const $votesBlock = $('.js-awards-block').eq(0);
+ const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ $thumbsUpEmoji.attr('data-title', 'sam');
+ awardsHandler.userAuthored($thumbsUpEmoji);
+ jasmine.clock().tick(2801);
+ jasmine.clock().uninstall();
+
+ expect($thumbsUpEmoji.data('originalTitle')).toBe('sam');
+ });
+ });
+
+ describe('::getAwardUrl', function() {
+ it('returns the url for request', function() {
+ expect(awardsHandler.getAwardUrl()).toBe('http://test.host/snippets/1/toggle_award_emoji');
+ });
+ });
+
+ describe('::addAward and ::checkMutuality', function() {
+ it('should handle :+1: and :-1: mutuality', function() {
+ const awardUrl = awardsHandler.getAwardUrl();
+ const $votesBlock = $('.js-awards-block').eq(0);
+ const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ const $thumbsDownEmoji = $votesBlock.find('[data-name=thumbsdown]').parent();
+ awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
+
+ expect($thumbsUpEmoji.hasClass('active')).toBe(true);
+ expect($thumbsDownEmoji.hasClass('active')).toBe(false);
+ $thumbsUpEmoji.tooltip();
+ $thumbsDownEmoji.tooltip();
+ awardsHandler.addAward($votesBlock, awardUrl, 'thumbsdown', true);
+
+ expect($thumbsUpEmoji.hasClass('active')).toBe(false);
+ expect($thumbsDownEmoji.hasClass('active')).toBe(true);
+ });
+ });
+
+ describe('::removeEmoji', function() {
+ it('should remove emoji', function() {
+ const awardUrl = awardsHandler.getAwardUrl();
+ const $votesBlock = $('.js-awards-block').eq(0);
+ awardsHandler.addAward($votesBlock, awardUrl, 'fire', false);
+
+ expect($votesBlock.find('[data-name=fire]').length).toBe(1);
+ awardsHandler.removeEmoji($votesBlock.find('[data-name=fire]').closest('button'));
+
+ expect($votesBlock.find('[data-name=fire]').length).toBe(0);
+ });
+ });
+
+ describe('::addYouToUserList', function() {
+ it('should prepend "You" to the award tooltip', function() {
+ const awardUrl = awardsHandler.getAwardUrl();
+ const $votesBlock = $('.js-awards-block').eq(0);
+ const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ $thumbsUpEmoji.attr('data-title', 'sam, jerry, max, and andy');
+ awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
+ $thumbsUpEmoji.tooltip();
+
+ expect($thumbsUpEmoji.data('originalTitle')).toBe('You, sam, jerry, max, and andy');
+ });
+
+ it('handles the special case where "You" is not cleanly comma seperated', function() {
+ const awardUrl = awardsHandler.getAwardUrl();
+ const $votesBlock = $('.js-awards-block').eq(0);
+ const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ $thumbsUpEmoji.attr('data-title', 'sam');
+ awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
+ $thumbsUpEmoji.tooltip();
+
+ expect($thumbsUpEmoji.data('originalTitle')).toBe('You and sam');
+ });
+ });
+
+ describe('::removeYouToUserList', function() {
+ it('removes "You" from the front of the tooltip', function() {
+ const awardUrl = awardsHandler.getAwardUrl();
+ const $votesBlock = $('.js-awards-block').eq(0);
+ const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ $thumbsUpEmoji.attr('data-title', 'You, sam, jerry, max, and andy');
+ $thumbsUpEmoji.addClass('active');
+ awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
+ $thumbsUpEmoji.tooltip();
+
+ expect($thumbsUpEmoji.data('originalTitle')).toBe('sam, jerry, max, and andy');
+ });
+
+ it('handles the special case where "You" is not cleanly comma seperated', function() {
+ const awardUrl = awardsHandler.getAwardUrl();
+ const $votesBlock = $('.js-awards-block').eq(0);
+ const $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ $thumbsUpEmoji.attr('data-title', 'You and sam');
+ $thumbsUpEmoji.addClass('active');
+ awardsHandler.addAward($votesBlock, awardUrl, 'thumbsup', false);
+ $thumbsUpEmoji.tooltip();
+
+ expect($thumbsUpEmoji.data('originalTitle')).toBe('sam');
+ });
+ });
+
+ describe('::searchEmojis', () => {
+ it('should filter the emoji', function(done) {
+ openAndWaitForEmojiMenu()
+ .then(() => {
+ expect($('[data-name=angel]').is(':visible')).toBe(true);
+ expect($('[data-name=anger]').is(':visible')).toBe(true);
+ awardsHandler.searchEmojis('ali');
+
+ expect($('[data-name=angel]').is(':visible')).toBe(false);
+ expect($('[data-name=anger]').is(':visible')).toBe(false);
+ expect($('[data-name=alien]').is(':visible')).toBe(true);
+ expect($('.js-emoji-menu-search').val()).toBe('ali');
+ })
+ .then(done)
+ .catch(err => {
+ done.fail(`Failed to open and build emoji menu: ${err.message}`);
+ });
+ });
+
+ it('should clear the search when searching for nothing', function(done) {
+ openAndWaitForEmojiMenu()
+ .then(() => {
+ awardsHandler.searchEmojis('ali');
+
+ expect($('[data-name=angel]').is(':visible')).toBe(false);
+ expect($('[data-name=anger]').is(':visible')).toBe(false);
+ expect($('[data-name=alien]').is(':visible')).toBe(true);
+ awardsHandler.searchEmojis('');
+
+ expect($('[data-name=angel]').is(':visible')).toBe(true);
+ expect($('[data-name=anger]').is(':visible')).toBe(true);
+ expect($('[data-name=alien]').is(':visible')).toBe(true);
+ expect($('.js-emoji-menu-search').val()).toBe('');
+ })
+ .then(done)
+ .catch(err => {
+ done.fail(`Failed to open and build emoji menu: ${err.message}`);
+ });
+ });
+ });
+
+ describe('emoji menu', function() {
+ const emojiSelector = '[data-name="sunglasses"]';
+ const openEmojiMenuAndAddEmoji = function() {
+ return openAndWaitForEmojiMenu().then(() => {
+ const $menu = $('.emoji-menu');
+ const $block = $('.js-awards-block');
+ const $emoji = $menu.find(`.emoji-menu-list:not(.frequent-emojis) ${emojiSelector}`);
+
+ expect($emoji.length).toBe(1);
+ expect($block.find(emojiSelector).length).toBe(0);
+ $emoji.click();
+
+ expect($menu.hasClass('.is-visible')).toBe(false);
+ expect($block.find(emojiSelector).length).toBe(1);
});
+ };
+
+ it('should add selected emoji to awards block', function(done) {
+ openEmojiMenuAndAddEmoji()
+ .then(done)
+ .catch(err => {
+ done.fail(`Failed to open and build emoji menu: ${err.message}`);
+ });
});
- describe('emoji menu', function() {
- const emojiSelector = '[data-name="sunglasses"]';
- const openEmojiMenuAndAddEmoji = function() {
- return openAndWaitForEmojiMenu().then(() => {
- const $menu = $('.emoji-menu');
+ it('should remove already selected emoji', function(done) {
+ openEmojiMenuAndAddEmoji()
+ .then(() => {
+ $('.js-add-award')
+ .eq(0)
+ .click();
const $block = $('.js-awards-block');
- const $emoji = $menu.find('.emoji-menu-list:not(.frequent-emojis) ' + emojiSelector);
+ const $emoji = $('.emoji-menu').find(
+ `.emoji-menu-list:not(.frequent-emojis) ${emojiSelector}`,
+ );
+ $emoji.click();
- expect($emoji.length).toBe(1);
expect($block.find(emojiSelector).length).toBe(0);
- $emoji.click();
- expect($menu.hasClass('.is-visible')).toBe(false);
- expect($block.find(emojiSelector).length).toBe(1);
+ })
+ .then(done)
+ .catch(err => {
+ done.fail(`Failed to open and build emoji menu: ${err.message}`);
});
- };
- it('should add selected emoji to awards block', function(done) {
- return openEmojiMenuAndAddEmoji()
- .then(done)
- .catch(err => {
- done.fail(`Failed to open and build emoji menu: ${err.message}`);
- });
- });
- it('should remove already selected emoji', function(done) {
- return openEmojiMenuAndAddEmoji()
- .then(() => {
- $('.js-add-award')
- .eq(0)
- .click();
- const $block = $('.js-awards-block');
- const $emoji = $('.emoji-menu').find(
- `.emoji-menu-list:not(.frequent-emojis) ${emojiSelector}`,
- );
- $emoji.click();
- expect($block.find(emojiSelector).length).toBe(0);
- })
- .then(done)
- .catch(err => {
- done.fail(`Failed to open and build emoji menu: ${err.message}`);
- });
- });
});
+ });
- describe('frequently used emojis', function() {
- beforeEach(() => {
- // Clear it out
- Cookies.set('frequently_used_emojis', '');
- });
+ describe('frequently used emojis', function() {
+ beforeEach(() => {
+ // Clear it out
+ Cookies.set('frequently_used_emojis', '');
+ });
- it('shouldn\'t have any "Frequently used" heading if no frequently used emojis', function(done) {
- return openAndWaitForEmojiMenu()
- .then(() => {
- const emojiMenu = document.querySelector('.emoji-menu');
- Array.prototype.forEach.call(emojiMenu.querySelectorAll('.emoji-menu-title'), title => {
- expect(title.textContent.trim().toLowerCase()).not.toBe('frequently used');
- });
- })
- .then(done)
- .catch(err => {
- done.fail(`Failed to open and build emoji menu: ${err.message}`);
+ it('shouldn\'t have any "Frequently used" heading if no frequently used emojis', function(done) {
+ return openAndWaitForEmojiMenu()
+ .then(() => {
+ const emojiMenu = document.querySelector('.emoji-menu');
+ Array.prototype.forEach.call(emojiMenu.querySelectorAll('.emoji-menu-title'), title => {
+ expect(title.textContent.trim().toLowerCase()).not.toBe('frequently used');
});
- });
+ })
+ .then(done)
+ .catch(err => {
+ done.fail(`Failed to open and build emoji menu: ${err.message}`);
+ });
+ });
- it('should have any frequently used section when there are frequently used emojis', function(done) {
- awardsHandler.addEmojiToFrequentlyUsedList('8ball');
-
- return openAndWaitForEmojiMenu()
- .then(() => {
- const emojiMenu = document.querySelector('.emoji-menu');
- const hasFrequentlyUsedHeading = Array.prototype.some.call(
- emojiMenu.querySelectorAll('.emoji-menu-title'),
- title => title.textContent.trim().toLowerCase() === 'frequently used',
- );
-
- expect(hasFrequentlyUsedHeading).toBe(true);
- })
- .then(done)
- .catch(err => {
- done.fail(`Failed to open and build emoji menu: ${err.message}`);
- });
- });
+ it('should have any frequently used section when there are frequently used emojis', function(done) {
+ awardsHandler.addEmojiToFrequentlyUsedList('8ball');
- it('should disregard invalid frequently used emoji that are being attempted to be added', function() {
- awardsHandler.addEmojiToFrequentlyUsedList('8ball');
- awardsHandler.addEmojiToFrequentlyUsedList('invalid_emoji');
- awardsHandler.addEmojiToFrequentlyUsedList('grinning');
+ return openAndWaitForEmojiMenu()
+ .then(() => {
+ const emojiMenu = document.querySelector('.emoji-menu');
+ const hasFrequentlyUsedHeading = Array.prototype.some.call(
+ emojiMenu.querySelectorAll('.emoji-menu-title'),
+ title => title.textContent.trim().toLowerCase() === 'frequently used',
+ );
- expect(awardsHandler.getFrequentlyUsedEmojis()).toEqual(['8ball', 'grinning']);
- });
+ expect(hasFrequentlyUsedHeading).toBe(true);
+ })
+ .then(done)
+ .catch(err => {
+ done.fail(`Failed to open and build emoji menu: ${err.message}`);
+ });
+ });
- it('should disregard invalid frequently used emoji already set in cookie', function() {
- Cookies.set('frequently_used_emojis', '8ball,invalid_emoji,grinning');
+ it('should disregard invalid frequently used emoji that are being attempted to be added', function() {
+ awardsHandler.addEmojiToFrequentlyUsedList('8ball');
+ awardsHandler.addEmojiToFrequentlyUsedList('invalid_emoji');
+ awardsHandler.addEmojiToFrequentlyUsedList('grinning');
- expect(awardsHandler.getFrequentlyUsedEmojis()).toEqual(['8ball', 'grinning']);
- });
+ expect(awardsHandler.getFrequentlyUsedEmojis()).toEqual(['8ball', 'grinning']);
+ });
+
+ it('should disregard invalid frequently used emoji already set in cookie', function() {
+ Cookies.set('frequently_used_emojis', '8ball,invalid_emoji,grinning');
+
+ expect(awardsHandler.getFrequentlyUsedEmojis()).toEqual(['8ball', 'grinning']);
});
});
-}.call(window));
+});
diff --git a/spec/javascripts/badges/components/badge_form_spec.js b/spec/javascripts/badges/components/badge_form_spec.js
index 31195bd762b..651ac3ba3f9 100644
--- a/spec/javascripts/badges/components/badge_form_spec.js
+++ b/spec/javascripts/badges/components/badge_form_spec.js
@@ -66,8 +66,10 @@ describe('BadgeForm component', () => {
};
const expectInvalidInput = inputElementSelector => {
const inputElement = vm.$el.querySelector(inputElementSelector);
+
expect(inputElement).toBeMatchedBy(':invalid');
const feedbackElement = vm.$el.querySelector(`${inputElementSelector} + .invalid-feedback`);
+
expect(feedbackElement).toBeVisible();
};
@@ -90,6 +92,7 @@ describe('BadgeForm component', () => {
submitForm();
expectInvalidInput(imageUrlSelector);
+
expect(vm[submitAction]).not.toHaveBeenCalled();
});
@@ -99,6 +102,7 @@ describe('BadgeForm component', () => {
submitForm();
expectInvalidInput(imageUrlSelector);
+
expect(vm[submitAction]).not.toHaveBeenCalled();
});
@@ -108,6 +112,7 @@ describe('BadgeForm component', () => {
submitForm();
expectInvalidInput(linkUrlSelector);
+
expect(vm[submitAction]).not.toHaveBeenCalled();
});
@@ -117,6 +122,7 @@ describe('BadgeForm component', () => {
submitForm();
expectInvalidInput(linkUrlSelector);
+
expect(vm[submitAction]).not.toHaveBeenCalled();
});
@@ -143,8 +149,10 @@ describe('BadgeForm component', () => {
it('renders one button', () => {
expect(vm.$el.querySelector('.row-content-block')).toBeNull();
const buttons = vm.$el.querySelectorAll('.form-group:last-of-type button');
+
expect(buttons.length).toBe(1);
const buttonAddElement = buttons[0];
+
expect(buttonAddElement).toBeVisible();
expect(buttonAddElement).toHaveText('Add badge');
});
@@ -165,11 +173,14 @@ describe('BadgeForm component', () => {
it('renders two buttons', () => {
const buttons = vm.$el.querySelectorAll('.row-content-block button');
+
expect(buttons.length).toBe(2);
const buttonSaveElement = buttons[0];
+
expect(buttonSaveElement).toBeVisible();
expect(buttonSaveElement).toHaveText('Save changes');
const buttonCancelElement = buttons[1];
+
expect(buttonCancelElement).toBeVisible();
expect(buttonCancelElement).toHaveText('Cancel');
});
diff --git a/spec/javascripts/badges/components/badge_list_row_spec.js b/spec/javascripts/badges/components/badge_list_row_spec.js
index 21bd00d82f0..a5b47cc5f32 100644
--- a/spec/javascripts/badges/components/badge_list_row_spec.js
+++ b/spec/javascripts/badges/components/badge_list_row_spec.js
@@ -34,6 +34,7 @@ describe('BadgeListRow component', () => {
it('renders the badge', () => {
const badgeElement = vm.$el.querySelector('.project-badge');
+
expect(badgeElement).not.toBeNull();
expect(badgeElement.getAttribute('src')).toBe(badge.renderedImageUrl);
});
@@ -48,11 +49,14 @@ describe('BadgeListRow component', () => {
it('shows edit and delete buttons', () => {
const buttons = vm.$el.querySelectorAll('.table-button-footer button');
+
expect(buttons).toHaveLength(2);
const buttonEditElement = buttons[0];
+
expect(buttonEditElement).toBeVisible();
expect(buttonEditElement).toHaveSpriteIcon('pencil');
const buttonDeleteElement = buttons[1];
+
expect(buttonDeleteElement).toBeVisible();
expect(buttonDeleteElement).toHaveSpriteIcon('remove');
});
@@ -91,6 +95,7 @@ describe('BadgeListRow component', () => {
it('hides edit and delete buttons', () => {
const buttons = vm.$el.querySelectorAll('.table-button-footer button');
+
expect(buttons).toHaveLength(0);
});
});
diff --git a/spec/javascripts/badges/components/badge_list_spec.js b/spec/javascripts/badges/components/badge_list_spec.js
index 02e59ae0843..536671db377 100644
--- a/spec/javascripts/badges/components/badge_list_spec.js
+++ b/spec/javascripts/badges/components/badge_list_spec.js
@@ -34,11 +34,13 @@ describe('BadgeList component', () => {
it('renders a header with the badge count', () => {
const header = vm.$el.querySelector('.card-header');
+
expect(header).toHaveText(new RegExp(`Your badges\\s+${numberOfDummyBadges}`));
});
it('renders a row for each badge', () => {
const rows = vm.$el.querySelectorAll('.gl-responsive-table-row');
+
expect(rows).toHaveLength(numberOfDummyBadges);
});
@@ -59,6 +61,7 @@ describe('BadgeList component', () => {
Vue.nextTick()
.then(() => {
const loadingIcon = vm.$el.querySelector('.fa-spinner');
+
expect(loadingIcon).toBeVisible();
})
.then(done)
diff --git a/spec/javascripts/badges/components/badge_settings_spec.js b/spec/javascripts/badges/components/badge_settings_spec.js
index 59367c85125..aca26b736ca 100644
--- a/spec/javascripts/badges/components/badge_settings_spec.js
+++ b/spec/javascripts/badges/components/badge_settings_spec.js
@@ -38,6 +38,7 @@ describe('BadgeSettings component', () => {
$(modal).on('shown.bs.modal', () => {
expect(modal).toContainText('Delete badge?');
const badgeElement = modal.querySelector('img.project-badge');
+
expect(badgeElement).not.toBe(null);
expect(badgeElement.getAttribute('src')).toBe(badge.renderedImageUrl);
@@ -53,14 +54,17 @@ describe('BadgeSettings component', () => {
it('displays a form to add a badge', () => {
const form = vm.$el.querySelector('form:nth-of-type(2)');
+
expect(form).not.toBe(null);
const button = form.querySelector('.btn-success');
+
expect(button).not.toBe(null);
expect(button).toHaveText(/Add badge/);
});
it('displays badge list', () => {
const badgeListElement = vm.$el.querySelector('.card');
+
expect(badgeListElement).not.toBe(null);
expect(badgeListElement).toBeVisible();
expect(badgeListElement).toContainText('Your badges');
@@ -77,17 +81,21 @@ describe('BadgeSettings component', () => {
it('displays a form to edit a badge', () => {
const form = vm.$el.querySelector('form:nth-of-type(1)');
+
expect(form).not.toBe(null);
const submitButton = form.querySelector('.btn-success');
+
expect(submitButton).not.toBe(null);
expect(submitButton).toHaveText(/Save changes/);
const cancelButton = form.querySelector('.btn-cancel');
+
expect(cancelButton).not.toBe(null);
expect(cancelButton).toHaveText(/Cancel/);
});
it('displays no badge list', () => {
const badgeListElement = vm.$el.querySelector('.card');
+
expect(badgeListElement).toBeHidden();
});
});
@@ -102,6 +110,7 @@ describe('BadgeSettings component', () => {
deleteButton.click();
const badge = store.state.badgeInModal;
+
expect(vm.deleteBadge).toHaveBeenCalledWith(badge);
});
});
diff --git a/spec/javascripts/badges/components/badge_spec.js b/spec/javascripts/badges/components/badge_spec.js
index fd1ecc9cdd8..29805408bcf 100644
--- a/spec/javascripts/badges/components/badge_spec.js
+++ b/spec/javascripts/badges/components/badge_spec.js
@@ -107,6 +107,7 @@ describe('Badge component', () => {
expect(vm.isLoading).toBe(false);
expect(vm.hasError).toBe(false);
const { badgeImage, loadingIcon, reloadButton } = findElements();
+
expect(badgeImage).toBeVisible();
expect(loadingIcon).toBeHidden();
expect(reloadButton).toBeHidden();
@@ -119,6 +120,7 @@ describe('Badge component', () => {
Vue.nextTick()
.then(() => {
const { badgeImage, loadingIcon, reloadButton } = findElements();
+
expect(badgeImage).toBeHidden();
expect(loadingIcon).toBeVisible();
expect(reloadButton).toBeHidden();
@@ -134,6 +136,7 @@ describe('Badge component', () => {
Vue.nextTick()
.then(() => {
const { badgeImage, loadingIcon, reloadButton } = findElements();
+
expect(badgeImage).toBeHidden();
expect(loadingIcon).toBeHidden();
expect(reloadButton).toBeVisible();
diff --git a/spec/javascripts/badges/store/actions_spec.js b/spec/javascripts/badges/store/actions_spec.js
index bb6263c6de4..2623465ebd6 100644
--- a/spec/javascripts/badges/store/actions_spec.js
+++ b/spec/javascripts/badges/store/actions_spec.js
@@ -94,6 +94,7 @@ describe('Badges store actions', () => {
link_url: badgeInAddForm.linkUrl,
}),
);
+
expect(dispatch.calls.allArgs()).toEqual([['requestNewBadge']]);
dispatch.calls.reset();
return [200, dummyResponse];
@@ -117,6 +118,7 @@ describe('Badges store actions', () => {
link_url: badgeInAddForm.linkUrl,
}),
);
+
expect(dispatch.calls.allArgs()).toEqual([['requestNewBadge']]);
dispatch.calls.reset();
return [500, ''];
@@ -296,6 +298,7 @@ describe('Badges store actions', () => {
.loadBadges({ state, dispatch }, dummyData)
.then(() => {
const badges = dummyReponse.map(transformBackendBadge);
+
expect(dispatch.calls.allArgs()).toEqual([['receiveLoadBadges', badges]]);
})
.then(done)
@@ -416,6 +419,7 @@ describe('Badges store actions', () => {
.then(() => {
expect(axios.get.calls.count()).toBe(1);
const url = axios.get.calls.argsFor(0)[0];
+
expect(url).toMatch(`^${dummyEndpointUrl}/render?`);
expect(url).toMatch('\\?link_url=%3Cscript%3EI%20am%20dangerous!%3C%2Fscript%3E&');
expect(url).toMatch('&image_url=%26make-sandwhich%3Dtrue$');
@@ -436,6 +440,7 @@ describe('Badges store actions', () => {
.renderBadge({ state, dispatch })
.then(() => {
const renderedBadge = transformBackendBadge(dummyReponse);
+
expect(dispatch.calls.allArgs()).toEqual([['receiveRenderedBadge', renderedBadge]]);
})
.then(done)
@@ -525,6 +530,7 @@ describe('Badges store actions', () => {
link_url: badgeInEditForm.linkUrl,
}),
);
+
expect(dispatch.calls.allArgs()).toEqual([['requestUpdatedBadge']]);
dispatch.calls.reset();
return [200, dummyResponse];
@@ -548,6 +554,7 @@ describe('Badges store actions', () => {
link_url: badgeInEditForm.linkUrl,
}),
);
+
expect(dispatch.calls.allArgs()).toEqual([['requestUpdatedBadge']]);
dispatch.calls.reset();
return [500, ''];
diff --git a/spec/javascripts/behaviors/autosize_spec.js b/spec/javascripts/behaviors/autosize_spec.js
index c411c5174fb..59abae479d4 100644
--- a/spec/javascripts/behaviors/autosize_spec.js
+++ b/spec/javascripts/behaviors/autosize_spec.js
@@ -12,6 +12,7 @@ describe('Autosize behavior', () => {
it('does not overwrite the resize property', () => {
load();
+
expect($('textarea')).toHaveCss({
resize: 'vertical',
});
diff --git a/spec/javascripts/behaviors/bind_in_out_spec.js b/spec/javascripts/behaviors/bind_in_out_spec.js
index 5ff66167718..0c214f5886a 100644
--- a/spec/javascripts/behaviors/bind_in_out_spec.js
+++ b/spec/javascripts/behaviors/bind_in_out_spec.js
@@ -1,60 +1,60 @@
import BindInOut from '~/behaviors/bind_in_out';
import ClassSpecHelper from '../helpers/class_spec_helper';
-describe('BindInOut', function () {
- describe('constructor', function () {
- beforeEach(function () {
+describe('BindInOut', function() {
+ describe('constructor', function() {
+ beforeEach(function() {
this.in = {};
this.out = {};
this.bindInOut = new BindInOut(this.in, this.out);
});
- it('should set .in', function () {
+ it('should set .in', function() {
expect(this.bindInOut.in).toBe(this.in);
});
- it('should set .out', function () {
+ it('should set .out', function() {
expect(this.bindInOut.out).toBe(this.out);
});
- it('should set .eventWrapper', function () {
+ it('should set .eventWrapper', function() {
expect(this.bindInOut.eventWrapper).toEqual({});
});
- describe('if .in is an input', function () {
- beforeEach(function () {
+ describe('if .in is an input', function() {
+ beforeEach(function() {
this.bindInOut = new BindInOut({ tagName: 'INPUT' });
});
- it('should set .eventType to keyup ', function () {
+ it('should set .eventType to keyup ', function() {
expect(this.bindInOut.eventType).toEqual('keyup');
});
});
- describe('if .in is a textarea', function () {
- beforeEach(function () {
+ describe('if .in is a textarea', function() {
+ beforeEach(function() {
this.bindInOut = new BindInOut({ tagName: 'TEXTAREA' });
});
- it('should set .eventType to keyup ', function () {
+ it('should set .eventType to keyup ', function() {
expect(this.bindInOut.eventType).toEqual('keyup');
});
});
- describe('if .in is not an input or textarea', function () {
- beforeEach(function () {
+ describe('if .in is not an input or textarea', function() {
+ beforeEach(function() {
this.bindInOut = new BindInOut({ tagName: 'SELECT' });
});
- it('should set .eventType to change ', function () {
+ it('should set .eventType to change ', function() {
expect(this.bindInOut.eventType).toEqual('change');
});
});
});
- describe('addEvents', function () {
- beforeEach(function () {
+ describe('addEvents', function() {
+ beforeEach(function() {
this.in = jasmine.createSpyObj('in', ['addEventListener']);
this.bindInOut = new BindInOut(this.in);
@@ -62,25 +62,24 @@ describe('BindInOut', function () {
this.addEvents = this.bindInOut.addEvents();
});
- it('should set .eventWrapper.updateOut', function () {
+ it('should set .eventWrapper.updateOut', function() {
expect(this.bindInOut.eventWrapper.updateOut).toEqual(jasmine.any(Function));
});
- it('should call .addEventListener', function () {
- expect(this.in.addEventListener)
- .toHaveBeenCalledWith(
- this.bindInOut.eventType,
- this.bindInOut.eventWrapper.updateOut,
- );
+ it('should call .addEventListener', function() {
+ expect(this.in.addEventListener).toHaveBeenCalledWith(
+ this.bindInOut.eventType,
+ this.bindInOut.eventWrapper.updateOut,
+ );
});
- it('should return the instance', function () {
+ it('should return the instance', function() {
expect(this.addEvents).toBe(this.bindInOut);
});
});
- describe('updateOut', function () {
- beforeEach(function () {
+ describe('updateOut', function() {
+ beforeEach(function() {
this.in = { value: 'the-value' };
this.out = { textContent: 'not-the-value' };
@@ -89,17 +88,17 @@ describe('BindInOut', function () {
this.updateOut = this.bindInOut.updateOut();
});
- it('should set .out.textContent to .in.value', function () {
+ it('should set .out.textContent to .in.value', function() {
expect(this.out.textContent).toBe(this.in.value);
});
- it('should return the instance', function () {
+ it('should return the instance', function() {
expect(this.updateOut).toBe(this.bindInOut);
});
});
- describe('removeEvents', function () {
- beforeEach(function () {
+ describe('removeEvents', function() {
+ beforeEach(function() {
this.in = jasmine.createSpyObj('in', ['removeEventListener']);
this.updateOut = () => {};
@@ -109,21 +108,20 @@ describe('BindInOut', function () {
this.removeEvents = this.bindInOut.removeEvents();
});
- it('should call .removeEventListener', function () {
- expect(this.in.removeEventListener)
- .toHaveBeenCalledWith(
- this.bindInOut.eventType,
- this.updateOut,
- );
+ it('should call .removeEventListener', function() {
+ expect(this.in.removeEventListener).toHaveBeenCalledWith(
+ this.bindInOut.eventType,
+ this.updateOut,
+ );
});
- it('should return the instance', function () {
+ it('should return the instance', function() {
expect(this.removeEvents).toBe(this.bindInOut);
});
});
- describe('initAll', function () {
- beforeEach(function () {
+ describe('initAll', function() {
+ beforeEach(function() {
this.ins = [0, 1, 2];
this.instances = [];
@@ -136,43 +134,47 @@ describe('BindInOut', function () {
ClassSpecHelper.itShouldBeAStaticMethod(BindInOut, 'initAll');
- it('should call .querySelectorAll', function () {
+ it('should call .querySelectorAll', function() {
expect(document.querySelectorAll).toHaveBeenCalledWith('*[data-bind-in]');
});
- it('should call .map', function () {
+ it('should call .map', function() {
expect(Array.prototype.map).toHaveBeenCalledWith(jasmine.any(Function));
});
- it('should call .init for each element', function () {
+ it('should call .init for each element', function() {
expect(BindInOut.init.calls.count()).toEqual(3);
});
- it('should return an array of instances', function () {
+ it('should return an array of instances', function() {
expect(this.initAll).toEqual(jasmine.any(Array));
});
});
- describe('init', function () {
- beforeEach(function () {
- spyOn(BindInOut.prototype, 'addEvents').and.callFake(function () { return this; });
- spyOn(BindInOut.prototype, 'updateOut').and.callFake(function () { return this; });
+ describe('init', function() {
+ beforeEach(function() {
+ spyOn(BindInOut.prototype, 'addEvents').and.callFake(function() {
+ return this;
+ });
+ spyOn(BindInOut.prototype, 'updateOut').and.callFake(function() {
+ return this;
+ });
this.init = BindInOut.init({}, {});
});
ClassSpecHelper.itShouldBeAStaticMethod(BindInOut, 'init');
- it('should call .addEvents', function () {
+ it('should call .addEvents', function() {
expect(BindInOut.prototype.addEvents).toHaveBeenCalled();
});
- it('should call .updateOut', function () {
+ it('should call .updateOut', function() {
expect(BindInOut.prototype.updateOut).toHaveBeenCalled();
});
- describe('if no anOut is provided', function () {
- beforeEach(function () {
+ describe('if no anOut is provided', function() {
+ beforeEach(function() {
this.anIn = { dataset: { bindIn: 'the-data-bind-in' } };
spyOn(document, 'querySelector');
@@ -180,9 +182,10 @@ describe('BindInOut', function () {
BindInOut.init(this.anIn);
});
- it('should call .querySelector', function () {
- expect(document.querySelector)
- .toHaveBeenCalledWith(`*[data-bind-out="${this.anIn.dataset.bindIn}"]`);
+ it('should call .querySelector', function() {
+ expect(document.querySelector).toHaveBeenCalledWith(
+ `*[data-bind-out="${this.anIn.dataset.bindIn}"]`,
+ );
});
});
});
diff --git a/spec/javascripts/behaviors/copy_as_gfm_spec.js b/spec/javascripts/behaviors/copy_as_gfm_spec.js
index c2db81c6ce4..cf8c1b77861 100644
--- a/spec/javascripts/behaviors/copy_as_gfm_spec.js
+++ b/spec/javascripts/behaviors/copy_as_gfm_spec.js
@@ -29,6 +29,7 @@ describe('CopyAsGFM', () => {
it('wraps pasted code when not already in code tags', () => {
spyOn(window.gl.utils, 'insertText').and.callFake((el, textFunc) => {
const insertedText = textFunc('This is code: ', '');
+
expect(insertedText).toEqual('`code`');
});
@@ -38,6 +39,7 @@ describe('CopyAsGFM', () => {
it('does not wrap pasted code when already in code tags', () => {
spyOn(window.gl.utils, 'insertText').and.callFake((el, textFunc) => {
const insertedText = textFunc('This is code: `', '`');
+
expect(insertedText).toEqual('code');
});
@@ -54,7 +56,7 @@ describe('CopyAsGFM', () => {
const fragment = document.createDocumentFragment();
const node = document.createElement('div');
node.innerHTML = html;
- Array.from(node.childNodes).forEach((item) => fragment.appendChild(item));
+ Array.from(node.childNodes).forEach(item => fragment.appendChild(item));
return fragment;
},
}),
@@ -86,6 +88,7 @@ describe('CopyAsGFM', () => {
simulateCopy();
const expectedGFM = '- List Item1\n- List Item2';
+
expect(clipboardData.setData).toHaveBeenCalledWith('text/x-gfm', expectedGFM);
});
@@ -95,6 +98,7 @@ describe('CopyAsGFM', () => {
simulateCopy();
const expectedGFM = '1. List Item1\n1. List Item2';
+
expect(clipboardData.setData).toHaveBeenCalledWith('text/x-gfm', expectedGFM);
});
});
diff --git a/spec/javascripts/behaviors/gl_emoji/unicode_support_map_spec.js b/spec/javascripts/behaviors/gl_emoji/unicode_support_map_spec.js
index f96f20ed4a5..f656b97fec2 100644
--- a/spec/javascripts/behaviors/gl_emoji/unicode_support_map_spec.js
+++ b/spec/javascripts/behaviors/gl_emoji/unicode_support_map_spec.js
@@ -13,7 +13,7 @@ describe('Unicode Support Map', () => {
spyOn(JSON, 'stringify').and.returnValue(stringSupportMap);
});
- describe('if isLocalStorageAvailable is `true`', function () {
+ describe('if isLocalStorageAvailable is `true`', function() {
beforeEach(() => {
AccessorUtilities.isLocalStorageAccessSafe.and.returnValue(true);
@@ -36,7 +36,7 @@ describe('Unicode Support Map', () => {
});
});
- describe('if isLocalStorageAvailable is `false`', function () {
+ describe('if isLocalStorageAvailable is `false`', function() {
beforeEach(() => {
AccessorUtilities.isLocalStorageAccessSafe.and.returnValue(false);
diff --git a/spec/javascripts/behaviors/quick_submit_spec.js b/spec/javascripts/behaviors/quick_submit_spec.js
index d8aa5c636da..681463aab66 100644
--- a/spec/javascripts/behaviors/quick_submit_spec.js
+++ b/spec/javascripts/behaviors/quick_submit_spec.js
@@ -1,7 +1,7 @@
import $ from 'jquery';
import '~/behaviors/quick_submit';
-describe('Quick Submit behavior', function () {
+describe('Quick Submit behavior', function() {
const keydownEvent = (options = { keyCode: 13, metaKey: true }) => $.Event('keydown', options);
preloadFixtures('snippets/show.html.raw');
@@ -30,6 +30,7 @@ describe('Quick Submit behavior', function () {
keyCode: 32,
}),
);
+
expect(this.spies.submit).not.toHaveBeenTriggered();
});
@@ -40,6 +41,7 @@ describe('Quick Submit behavior', function () {
metaKey: false,
}),
);
+
expect(this.spies.submit).not.toHaveBeenTriggered();
});
@@ -49,6 +51,7 @@ describe('Quick Submit behavior', function () {
repeat: true,
}),
);
+
expect(this.spies.submit).not.toHaveBeenTriggered();
});
@@ -58,12 +61,14 @@ describe('Quick Submit behavior', function () {
expect(submitButton).toBeDisabled();
});
+
it('disables button of type submit', () => {
const submitButton = $('.js-quick-submit input[type=submit]');
this.textarea.trigger(keydownEvent());
expect(submitButton).toBeDisabled();
});
+
it('only clicks one submit', () => {
const existingSubmit = $('.js-quick-submit input[type=submit]');
// Add an extra submit button
@@ -84,7 +89,8 @@ describe('Quick Submit behavior', function () {
describe('In Macintosh', () => {
it('responds to Meta+Enter', () => {
this.textarea.trigger(keydownEvent());
- return expect(this.spies.submit).toHaveBeenTriggered();
+
+ expect(this.spies.submit).toHaveBeenTriggered();
});
it('excludes other modifier keys', () => {
@@ -103,13 +109,15 @@ describe('Quick Submit behavior', function () {
shiftKey: true,
}),
);
- return expect(this.spies.submit).not.toHaveBeenTriggered();
+
+ expect(this.spies.submit).not.toHaveBeenTriggered();
});
});
} else {
it('responds to Ctrl+Enter', () => {
this.textarea.trigger(keydownEvent());
- return expect(this.spies.submit).toHaveBeenTriggered();
+
+ expect(this.spies.submit).toHaveBeenTriggered();
});
it('excludes other modifier keys', () => {
@@ -128,7 +136,8 @@ describe('Quick Submit behavior', function () {
shiftKey: true,
}),
);
- return expect(this.spies.submit).not.toHaveBeenTriggered();
+
+ expect(this.spies.submit).not.toHaveBeenTriggered();
});
}
});
diff --git a/spec/javascripts/behaviors/requires_input_spec.js b/spec/javascripts/behaviors/requires_input_spec.js
index a434949b9da..1bde2bb3024 100644
--- a/spec/javascripts/behaviors/requires_input_spec.js
+++ b/spec/javascripts/behaviors/requires_input_spec.js
@@ -12,33 +12,51 @@ describe('requiresInput', () => {
it('disables submit when any field is required', () => {
$('.js-requires-input').requiresInput();
+
expect(submitButton).toBeDisabled();
});
it('enables submit when no field is required', () => {
$('*[required=required]').prop('required', false);
$('.js-requires-input').requiresInput();
+
expect(submitButton).not.toBeDisabled();
});
it('enables submit when all required fields are pre-filled', () => {
$('*[required=required]').remove();
$('.js-requires-input').requiresInput();
+
expect($('.submit')).not.toBeDisabled();
});
it('enables submit when all required fields receive input', () => {
$('.js-requires-input').requiresInput();
- $('#required1').val('input1').change();
+ $('#required1')
+ .val('input1')
+ .change();
+
expect(submitButton).toBeDisabled();
- $('#optional1').val('input1').change();
+ $('#optional1')
+ .val('input1')
+ .change();
+
expect(submitButton).toBeDisabled();
- $('#required2').val('input2').change();
- $('#required3').val('input3').change();
- $('#required4').val('input4').change();
- $('#required5').val('1').change();
+ $('#required2')
+ .val('input2')
+ .change();
+ $('#required3')
+ .val('input3')
+ .change();
+ $('#required4')
+ .val('input4')
+ .change();
+ $('#required5')
+ .val('1')
+ .change();
+
expect($('.submit')).not.toBeDisabled();
});
});
diff --git a/spec/javascripts/behaviors/secret_values_spec.js b/spec/javascripts/behaviors/secret_values_spec.js
index 95122fcf30f..5aaab093c0c 100644
--- a/spec/javascripts/behaviors/secret_values_spec.js
+++ b/spec/javascripts/behaviors/secret_values_spec.js
@@ -36,12 +36,7 @@ function setupSecretFixture(
placeholderClass = 'js-secret-value-placeholder',
) {
const wrapper = document.createElement('div');
- wrapper.innerHTML = generateFixtureMarkup(
- secrets,
- isRevealed,
- valueClass,
- placeholderClass,
- );
+ wrapper.innerHTML = generateFixtureMarkup(secrets, isRevealed, valueClass, placeholderClass);
const secretValues = new SecretValues({
container: wrapper.querySelector('.js-secret-container'),
@@ -127,11 +122,12 @@ describe('setupSecretValues', () => {
const placeholders = wrapper.querySelectorAll('.js-secret-value-placeholder');
expect(values.length).toEqual(3);
- values.forEach((value) => {
+ values.forEach(value => {
expect(value.classList.contains('hide')).toEqual(true);
});
+
expect(placeholders.length).toEqual(3);
- placeholders.forEach((placeholder) => {
+ placeholders.forEach(placeholder => {
expect(placeholder.classList.contains('hide')).toEqual(false);
});
});
@@ -145,22 +141,24 @@ describe('setupSecretValues', () => {
revealButton.click();
expect(values.length).toEqual(3);
- values.forEach((value) => {
+ values.forEach(value => {
expect(value.classList.contains('hide')).toEqual(false);
});
+
expect(placeholders.length).toEqual(3);
- placeholders.forEach((placeholder) => {
+ placeholders.forEach(placeholder => {
expect(placeholder.classList.contains('hide')).toEqual(true);
});
revealButton.click();
expect(values.length).toEqual(3);
- values.forEach((value) => {
+ values.forEach(value => {
expect(value.classList.contains('hide')).toEqual(true);
});
+
expect(placeholders.length).toEqual(3);
- placeholders.forEach((placeholder) => {
+ placeholders.forEach(placeholder => {
expect(placeholder.classList.contains('hide')).toEqual(false);
});
});
@@ -172,7 +170,9 @@ describe('setupSecretValues', () => {
it('should toggle values and placeholders', () => {
const wrapper = setupSecretFixture(secrets, false);
// Insert the new dynamic row
- wrapper.querySelector('.js-secret-container').insertAdjacentHTML('afterbegin', generateValueMarkup('foobarbazdynamic'));
+ wrapper
+ .querySelector('.js-secret-container')
+ .insertAdjacentHTML('afterbegin', generateValueMarkup('foobarbazdynamic'));
const revealButton = wrapper.querySelector('.js-secret-value-reveal-button');
const values = wrapper.querySelectorAll('.js-secret-value');
@@ -181,22 +181,24 @@ describe('setupSecretValues', () => {
revealButton.click();
expect(values.length).toEqual(4);
- values.forEach((value) => {
+ values.forEach(value => {
expect(value.classList.contains('hide')).toEqual(false);
});
+
expect(placeholders.length).toEqual(4);
- placeholders.forEach((placeholder) => {
+ placeholders.forEach(placeholder => {
expect(placeholder.classList.contains('hide')).toEqual(true);
});
revealButton.click();
expect(values.length).toEqual(4);
- values.forEach((value) => {
+ values.forEach(value => {
expect(value.classList.contains('hide')).toEqual(true);
});
+
expect(placeholders.length).toEqual(4);
- placeholders.forEach((placeholder) => {
+ placeholders.forEach(placeholder => {
expect(placeholder.classList.contains('hide')).toEqual(false);
});
});
diff --git a/spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js b/spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js
index 01b5bc112b2..bc25549cbed 100644
--- a/spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js
+++ b/spec/javascripts/behaviors/shortcuts/shortcuts_issuable_spec.js
@@ -57,9 +57,11 @@ describe('ShortcutsIssuable', function() {
it('leaves existing input intact', () => {
$(FORM_SELECTOR).val('This text was already here.');
+
expect($(FORM_SELECTOR).val()).toBe('This text was already here.');
ShortcutsIssuable.replyWithSelectedText(true);
+
expect($(FORM_SELECTOR).val()).toBe('This text was already here.\n\n> Selected text.\n\n');
});
@@ -70,6 +72,7 @@ describe('ShortcutsIssuable', function() {
});
ShortcutsIssuable.replyWithSelectedText(true);
+
expect(triggered).toBe(true);
});
diff --git a/spec/javascripts/blob/3d_viewer/mesh_object_spec.js b/spec/javascripts/blob/3d_viewer/mesh_object_spec.js
index 7651792be2e..60be285039f 100644
--- a/spec/javascripts/blob/3d_viewer/mesh_object_spec.js
+++ b/spec/javascripts/blob/3d_viewer/mesh_object_spec.js
@@ -1,21 +1,15 @@
-import {
- BoxGeometry,
-} from 'three/build/three.module';
+import { BoxGeometry } from 'three/build/three.module';
import MeshObject from '~/blob/3d_viewer/mesh_object';
describe('Mesh object', () => {
it('defaults to non-wireframe material', () => {
- const object = new MeshObject(
- new BoxGeometry(10, 10, 10),
- );
+ const object = new MeshObject(new BoxGeometry(10, 10, 10));
expect(object.material.wireframe).toBeFalsy();
});
it('changes to wirefame material', () => {
- const object = new MeshObject(
- new BoxGeometry(10, 10, 10),
- );
+ const object = new MeshObject(new BoxGeometry(10, 10, 10));
object.changeMaterial('wireframe');
@@ -23,18 +17,14 @@ describe('Mesh object', () => {
});
it('scales object down', () => {
- const object = new MeshObject(
- new BoxGeometry(10, 10, 10),
- );
+ const object = new MeshObject(new BoxGeometry(10, 10, 10));
const { radius } = object.geometry.boundingSphere;
expect(radius).not.toBeGreaterThan(4);
});
it('does not scale object down', () => {
- const object = new MeshObject(
- new BoxGeometry(1, 1, 1),
- );
+ const object = new MeshObject(new BoxGeometry(1, 1, 1));
const { radius } = object.geometry.boundingSphere;
expect(radius).toBeLessThan(1);
diff --git a/spec/javascripts/blob/balsamiq/balsamiq_viewer_integration_spec.js b/spec/javascripts/blob/balsamiq/balsamiq_viewer_integration_spec.js
index c726fa8e428..5f027f59fcf 100644
--- a/spec/javascripts/blob/balsamiq/balsamiq_viewer_integration_spec.js
+++ b/spec/javascripts/blob/balsamiq/balsamiq_viewer_integration_spec.js
@@ -16,10 +16,13 @@ describe('Balsamiq integration spec', () => {
});
describe('successful response', () => {
- beforeEach((done) => {
+ beforeEach(done => {
endpoint = bmprPath;
- balsamiqViewer.loadFile(endpoint).then(done).catch(done.fail);
+ balsamiqViewer
+ .loadFile(endpoint)
+ .then(done)
+ .catch(done.fail);
});
it('does not show loading icon', () => {
@@ -32,10 +35,13 @@ describe('Balsamiq integration spec', () => {
});
describe('error getting file', () => {
- beforeEach((done) => {
+ beforeEach(done => {
endpoint = 'invalid/path/to/file.bmpr';
- balsamiqViewer.loadFile(endpoint).then(done.fail, null).catch(done);
+ balsamiqViewer
+ .loadFile(endpoint)
+ .then(done.fail, null)
+ .catch(done);
});
it('does not show loading icon', () => {
diff --git a/spec/javascripts/blob/balsamiq/balsamiq_viewer_spec.js b/spec/javascripts/blob/balsamiq/balsamiq_viewer_spec.js
index cb0f2ba686d..fd73fb4bfcc 100644
--- a/spec/javascripts/blob/balsamiq/balsamiq_viewer_spec.js
+++ b/spec/javascripts/blob/balsamiq/balsamiq_viewer_spec.js
@@ -18,10 +18,6 @@ describe('BalsamiqViewer', () => {
});
});
- describe('fileLoaded', () => {
-
- });
-
describe('loadFile', () => {
let xhr;
let loadFile;
@@ -64,12 +60,16 @@ describe('BalsamiqViewer', () => {
viewer = jasmine.createSpyObj('viewer', ['appendChild']);
previews = [document.createElement('ul'), document.createElement('ul')];
- balsamiqViewer = jasmine.createSpyObj('balsamiqViewer', ['initDatabase', 'getPreviews', 'renderPreview']);
+ balsamiqViewer = jasmine.createSpyObj('balsamiqViewer', [
+ 'initDatabase',
+ 'getPreviews',
+ 'renderPreview',
+ ]);
balsamiqViewer.viewer = viewer;
balsamiqViewer.getPreviews.and.returnValue(previews);
balsamiqViewer.renderPreview.and.callFake(preview => preview);
- viewer.appendChild.and.callFake((containerElement) => {
+ viewer.appendChild.and.callFake(containerElement => {
container = containerElement;
});
@@ -198,7 +198,9 @@ describe('BalsamiqViewer', () => {
});
it('should call database.exec', () => {
- expect(database.exec).toHaveBeenCalledWith(`SELECT * FROM resources WHERE id = '${resourceID}'`);
+ expect(database.exec).toHaveBeenCalledWith(
+ `SELECT * FROM resources WHERE id = '${resourceID}'`,
+ );
});
it('should return the selected resource', () => {
@@ -281,7 +283,7 @@ describe('BalsamiqViewer', () => {
expect(BalsamiqViewer.parseTitle).toHaveBeenCalledWith(resource);
});
- it('should return the template string', function () {
+ it('should return the template string', function() {
expect(renderTemplate.replace(/\s/g, '')).toEqual(template.replace(/\s/g, ''));
});
});
diff --git a/spec/javascripts/blob/blob_file_dropzone_spec.js b/spec/javascripts/blob/blob_file_dropzone_spec.js
index 346f795c3f5..432d8a65b0a 100644
--- a/spec/javascripts/blob/blob_file_dropzone_spec.js
+++ b/spec/javascripts/blob/blob_file_dropzone_spec.js
@@ -1,7 +1,7 @@
import $ from 'jquery';
import BlobFileDropzone from '~/blob/blob_file_dropzone';
-describe('BlobFileDropzone', function () {
+describe('BlobFileDropzone', function() {
preloadFixtures('blob/show.html.raw');
beforeEach(() => {
diff --git a/spec/javascripts/blob/blob_fork_suggestion_spec.js b/spec/javascripts/blob/blob_fork_suggestion_spec.js
index d1ab0a32f85..9b81b7e6f92 100644
--- a/spec/javascripts/blob/blob_fork_suggestion_spec.js
+++ b/spec/javascripts/blob/blob_fork_suggestion_spec.js
@@ -16,8 +16,7 @@ describe('BlobForkSuggestion', () => {
cancelButtons: cancelButton,
suggestionSections: suggestionSection,
actionTextPieces: actionTextPiece,
- })
- .init();
+ }).init();
});
afterEach(() => {
@@ -26,6 +25,7 @@ describe('BlobForkSuggestion', () => {
it('showSuggestionSection', () => {
blobForkSuggestion.showSuggestionSection('/foo', 'foo');
+
expect(suggestionSection.classList.contains('hidden')).toEqual(false);
expect(forkButton.getAttribute('href')).toEqual('/foo');
expect(actionTextPiece.textContent).toEqual('foo');
@@ -33,6 +33,7 @@ describe('BlobForkSuggestion', () => {
it('hideSuggestionSection', () => {
blobForkSuggestion.hideSuggestionSection();
+
expect(suggestionSection.classList.contains('hidden')).toEqual(true);
});
});
diff --git a/spec/javascripts/blob/notebook/index_spec.js b/spec/javascripts/blob/notebook/index_spec.js
index 80c09a544d6..28d3b2f5ea3 100644
--- a/spec/javascripts/blob/notebook/index_spec.js
+++ b/spec/javascripts/blob/notebook/index_spec.js
@@ -12,29 +12,27 @@ describe('iPython notebook renderer', () => {
it('shows loading icon', () => {
renderNotebook();
- expect(
- document.querySelector('.loading'),
- ).not.toBeNull();
+ expect(document.querySelector('.loading')).not.toBeNull();
});
describe('successful response', () => {
let mock;
- beforeEach((done) => {
+ beforeEach(done => {
mock = new MockAdapter(axios);
mock.onGet('/test').reply(200, {
- cells: [{
- cell_type: 'markdown',
- source: ['# test'],
- }, {
- cell_type: 'code',
- execution_count: 1,
- source: [
- 'def test(str)',
- ' return str',
- ],
- outputs: [],
- }],
+ cells: [
+ {
+ cell_type: 'markdown',
+ source: ['# test'],
+ },
+ {
+ cell_type: 'code',
+ execution_count: 1,
+ source: ['def test(str)', ' return str'],
+ outputs: [],
+ },
+ ],
});
renderNotebook();
@@ -49,35 +47,23 @@ describe('iPython notebook renderer', () => {
});
it('does not show loading icon', () => {
- expect(
- document.querySelector('.loading'),
- ).toBeNull();
+ expect(document.querySelector('.loading')).toBeNull();
});
it('renders the notebook', () => {
- expect(
- document.querySelector('.md'),
- ).not.toBeNull();
+ expect(document.querySelector('.md')).not.toBeNull();
});
it('renders the markdown cell', () => {
- expect(
- document.querySelector('h1'),
- ).not.toBeNull();
+ expect(document.querySelector('h1')).not.toBeNull();
- expect(
- document.querySelector('h1').textContent.trim(),
- ).toBe('test');
+ expect(document.querySelector('h1').textContent.trim()).toBe('test');
});
it('highlights code', () => {
- expect(
- document.querySelector('.token'),
- ).not.toBeNull();
+ expect(document.querySelector('.token')).not.toBeNull();
- expect(
- document.querySelector('.language-python'),
- ).not.toBeNull();
+ expect(document.querySelector('.language-python')).not.toBeNull();
});
});
@@ -86,12 +72,10 @@ describe('iPython notebook renderer', () => {
beforeEach(done => {
mock = new MockAdapter(axios);
- mock
- .onGet('/test')
- .reply(() =>
- // eslint-disable-next-line prefer-promise-reject-errors
- Promise.reject({ status: 200, data: '{ "cells": [{"cell_type": "markdown"} }' }),
- );
+ mock.onGet('/test').reply(() =>
+ // eslint-disable-next-line prefer-promise-reject-errors
+ Promise.reject({ status: 200, data: '{ "cells": [{"cell_type": "markdown"} }' }),
+ );
renderNotebook();
@@ -105,22 +89,20 @@ describe('iPython notebook renderer', () => {
});
it('does not show loading icon', () => {
- expect(
- document.querySelector('.loading'),
- ).toBeNull();
+ expect(document.querySelector('.loading')).toBeNull();
});
it('shows error message', () => {
- expect(
- document.querySelector('.md').textContent.trim(),
- ).toBe('An error occurred whilst parsing the file.');
+ expect(document.querySelector('.md').textContent.trim()).toBe(
+ 'An error occurred whilst parsing the file.',
+ );
});
});
describe('error getting file', () => {
let mock;
- beforeEach((done) => {
+ beforeEach(done => {
mock = new MockAdapter(axios);
mock.onGet('/test').reply(500, '');
@@ -136,15 +118,13 @@ describe('iPython notebook renderer', () => {
});
it('does not show loading icon', () => {
- expect(
- document.querySelector('.loading'),
- ).toBeNull();
+ expect(document.querySelector('.loading')).toBeNull();
});
it('shows error message', () => {
- expect(
- document.querySelector('.md').textContent.trim(),
- ).toBe('An error occurred whilst loading the file. Please try again later.');
+ expect(document.querySelector('.md').textContent.trim()).toBe(
+ 'An error occurred whilst loading the file. Please try again later.',
+ );
});
});
});
diff --git a/spec/javascripts/blob/pdf/index_spec.js b/spec/javascripts/blob/pdf/index_spec.js
index bbe2500f8e3..be917a0613f 100644
--- a/spec/javascripts/blob/pdf/index_spec.js
+++ b/spec/javascripts/blob/pdf/index_spec.js
@@ -5,7 +5,7 @@ describe('PDF renderer', () => {
let viewer;
let app;
- const checkLoaded = (done) => {
+ const checkLoaded = done => {
if (app.loading) {
setTimeout(() => {
checkLoaded(done);
@@ -26,39 +26,31 @@ describe('PDF renderer', () => {
it('shows loading icon', () => {
renderPDF();
- expect(
- document.querySelector('.loading'),
- ).not.toBeNull();
+ expect(document.querySelector('.loading')).not.toBeNull();
});
describe('successful response', () => {
- beforeEach((done) => {
+ beforeEach(done => {
app = renderPDF();
checkLoaded(done);
});
it('does not show loading icon', () => {
- expect(
- document.querySelector('.loading'),
- ).toBeNull();
+ expect(document.querySelector('.loading')).toBeNull();
});
it('renders the PDF', () => {
- expect(
- document.querySelector('.pdf-viewer'),
- ).not.toBeNull();
+ expect(document.querySelector('.pdf-viewer')).not.toBeNull();
});
it('renders the PDF page', () => {
- expect(
- document.querySelector('.pdf-page'),
- ).not.toBeNull();
+ expect(document.querySelector('.pdf-page')).not.toBeNull();
});
});
describe('error getting file', () => {
- beforeEach((done) => {
+ beforeEach(done => {
viewer.dataset.endpoint = 'invalid/path/to/file.pdf';
app = renderPDF();
@@ -66,15 +58,13 @@ describe('PDF renderer', () => {
});
it('does not show loading icon', () => {
- expect(
- document.querySelector('.loading'),
- ).toBeNull();
+ expect(document.querySelector('.loading')).toBeNull();
});
it('shows error message', () => {
- expect(
- document.querySelector('.md').textContent.trim(),
- ).toBe('An error occurred whilst loading the file. Please try again later.');
+ expect(document.querySelector('.md').textContent.trim()).toBe(
+ 'An error occurred whilst loading the file. Please try again later.',
+ );
});
});
});
diff --git a/spec/javascripts/blob/sketch/index_spec.js b/spec/javascripts/blob/sketch/index_spec.js
index e062a068a92..2b1e81e9cbc 100644
--- a/spec/javascripts/blob/sketch/index_spec.js
+++ b/spec/javascripts/blob/sketch/index_spec.js
@@ -4,15 +4,13 @@ import SketchLoader from '~/blob/sketch';
describe('Sketch viewer', () => {
const generateZipFileArrayBuffer = (zipFile, resolve, done) => {
- zipFile
- .generateAsync({ type: 'arrayBuffer' })
- .then((content) => {
- resolve(content);
-
- setTimeout(() => {
- done();
- }, 100);
- });
+ zipFile.generateAsync({ type: 'arrayBuffer' }).then(content => {
+ resolve(content);
+
+ setTimeout(() => {
+ done();
+ }, 100);
+ });
};
preloadFixtures('static/sketch_viewer.html.raw');
@@ -22,60 +20,63 @@ describe('Sketch viewer', () => {
});
describe('with error message', () => {
- beforeEach((done) => {
- spyOn(SketchLoader.prototype, 'getZipFile').and.callFake(() => new Promise((resolve, reject) => {
- reject();
-
- setTimeout(() => {
- done();
- });
- }));
+ beforeEach(done => {
+ spyOn(SketchLoader.prototype, 'getZipFile').and.callFake(
+ () =>
+ new Promise((resolve, reject) => {
+ reject();
+
+ setTimeout(() => {
+ done();
+ });
+ }),
+ );
new SketchLoader(document.getElementById('js-sketch-viewer'));
});
it('renders error message', () => {
- expect(
- document.querySelector('#js-sketch-viewer p'),
- ).not.toBeNull();
+ expect(document.querySelector('#js-sketch-viewer p')).not.toBeNull();
- expect(
- document.querySelector('#js-sketch-viewer p').textContent.trim(),
- ).toContain('Cannot show preview.');
+ expect(document.querySelector('#js-sketch-viewer p').textContent.trim()).toContain(
+ 'Cannot show preview.',
+ );
});
it('removes render the loading icon', () => {
- expect(
- document.querySelector('.js-loading-icon'),
- ).toBeNull();
+ expect(document.querySelector('.js-loading-icon')).toBeNull();
});
});
describe('success', () => {
- beforeEach((done) => {
- spyOn(SketchLoader.prototype, 'getZipFile').and.callFake(() => new Promise((resolve) => {
- const zipFile = new JSZip();
- zipFile.folder('previews')
- .file('preview.png', 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAMAAAAoyzS7AAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAA1JREFUeNoBAgD9/wAAAAIAAVMrnDAAAAAASUVORK5CYII=', {
- base64: true,
- });
-
- generateZipFileArrayBuffer(zipFile, resolve, done);
- }));
+ beforeEach(done => {
+ spyOn(SketchLoader.prototype, 'getZipFile').and.callFake(
+ () =>
+ new Promise(resolve => {
+ const zipFile = new JSZip();
+ zipFile
+ .folder('previews')
+ .file(
+ 'preview.png',
+ 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAMAAAAoyzS7AAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAA1JREFUeNoBAgD9/wAAAAIAAVMrnDAAAAAASUVORK5CYII=',
+ {
+ base64: true,
+ },
+ );
+
+ generateZipFileArrayBuffer(zipFile, resolve, done);
+ }),
+ );
new SketchLoader(document.getElementById('js-sketch-viewer'));
});
it('does not render error message', () => {
- expect(
- document.querySelector('#js-sketch-viewer p'),
- ).toBeNull();
+ expect(document.querySelector('#js-sketch-viewer p')).toBeNull();
});
it('removes render the loading icon', () => {
- expect(
- document.querySelector('.js-loading-icon'),
- ).toBeNull();
+ expect(document.querySelector('.js-loading-icon')).toBeNull();
});
it('renders preview img', () => {
@@ -95,24 +96,25 @@ describe('Sketch viewer', () => {
});
describe('incorrect file', () => {
- beforeEach((done) => {
- spyOn(SketchLoader.prototype, 'getZipFile').and.callFake(() => new Promise((resolve) => {
- const zipFile = new JSZip();
+ beforeEach(done => {
+ spyOn(SketchLoader.prototype, 'getZipFile').and.callFake(
+ () =>
+ new Promise(resolve => {
+ const zipFile = new JSZip();
- generateZipFileArrayBuffer(zipFile, resolve, done);
- }));
+ generateZipFileArrayBuffer(zipFile, resolve, done);
+ }),
+ );
new SketchLoader(document.getElementById('js-sketch-viewer'));
});
it('renders error message', () => {
- expect(
- document.querySelector('#js-sketch-viewer p'),
- ).not.toBeNull();
+ expect(document.querySelector('#js-sketch-viewer p')).not.toBeNull();
- expect(
- document.querySelector('#js-sketch-viewer p').textContent.trim(),
- ).toContain('Cannot show preview.');
+ expect(document.querySelector('#js-sketch-viewer p').textContent.trim()).toContain(
+ 'Cannot show preview.',
+ );
});
});
});
diff --git a/spec/javascripts/blob/viewer/index_spec.js b/spec/javascripts/blob/viewer/index_spec.js
index 8b79624d9f4..93a942fe8d4 100644
--- a/spec/javascripts/blob/viewer/index_spec.js
+++ b/spec/javascripts/blob/viewer/index_spec.js
@@ -35,12 +35,13 @@ describe('Blob viewer', () => {
window.location.hash = '';
});
- it('loads source file after switching views', (done) => {
+ it('loads source file after switching views', done => {
document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
setTimeout(() => {
expect(
- document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]')
+ document
+ .querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]')
.classList.contains('hidden'),
).toBeFalsy();
@@ -48,14 +49,15 @@ describe('Blob viewer', () => {
});
});
- it('loads source file when line number is in hash', (done) => {
+ it('loads source file when line number is in hash', done => {
window.location.hash = '#L1';
new BlobViewer();
setTimeout(() => {
expect(
- document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]')
+ document
+ .querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]')
.classList.contains('hidden'),
).toBeFalsy();
@@ -63,12 +65,13 @@ describe('Blob viewer', () => {
});
});
- it('doesnt reload file if already loaded', (done) => {
- const asyncClick = () => new Promise((resolve) => {
- document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
+ it('doesnt reload file if already loaded', done => {
+ const asyncClick = () =>
+ new Promise(resolve => {
+ document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
- setTimeout(resolve);
- });
+ setTimeout(resolve);
+ });
asyncClick()
.then(() => asyncClick())
@@ -93,15 +96,13 @@ describe('Blob viewer', () => {
});
it('disabled on load', () => {
- expect(
- copyButton.classList.contains('disabled'),
- ).toBeTruthy();
+ expect(copyButton.classList.contains('disabled')).toBeTruthy();
});
it('has tooltip when disabled', () => {
- expect(
- copyButton.getAttribute('data-original-title'),
- ).toBe('Switch to the source to copy it to the clipboard');
+ expect(copyButton.getAttribute('data-original-title')).toBe(
+ 'Switch to the source to copy it to the clipboard',
+ );
});
it('is blurred when clicked and disabled', () => {
@@ -121,25 +122,21 @@ describe('Blob viewer', () => {
expect(copyButton.blur).not.toHaveBeenCalled();
});
- it('enables after switching to simple view', (done) => {
+ it('enables after switching to simple view', done => {
document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
setTimeout(() => {
- expect(
- copyButton.classList.contains('disabled'),
- ).toBeFalsy();
+ expect(copyButton.classList.contains('disabled')).toBeFalsy();
done();
});
});
- it('updates tooltip after switching to simple view', (done) => {
+ it('updates tooltip after switching to simple view', done => {
document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
setTimeout(() => {
- expect(
- copyButton.getAttribute('data-original-title'),
- ).toBe('Copy source to clipboard');
+ expect(copyButton.getAttribute('data-original-title')).toBe('Copy source to clipboard');
done();
});
@@ -162,9 +159,8 @@ describe('Blob viewer', () => {
blob.switchToViewer('simple');
- expect(
- simpleBtn.classList.contains('active'),
- ).toBeTruthy();
+ expect(simpleBtn.classList.contains('active')).toBeTruthy();
+
expect(simpleBtn.blur).toHaveBeenCalled();
});
diff --git a/spec/javascripts/boards/board_blank_state_spec.js b/spec/javascripts/boards/board_blank_state_spec.js
index 50505b41313..8e2a947b0dd 100644
--- a/spec/javascripts/boards/board_blank_state_spec.js
+++ b/spec/javascripts/boards/board_blank_state_spec.js
@@ -7,29 +7,35 @@ describe('Boards blank state', () => {
let vm;
let fail = false;
- beforeEach((done) => {
+ beforeEach(done => {
const Comp = Vue.extend(BoardBlankState);
boardsStore.create();
gl.boardService = mockBoardService();
- spyOn(gl.boardService, 'generateDefaultLists').and.callFake(() => new Promise((resolve, reject) => {
- if (fail) {
- reject();
- } else {
- resolve({
- data: [{
- id: 1,
- title: 'To Do',
- label: { id: 1 },
- }, {
- id: 2,
- title: 'Doing',
- label: { id: 2 },
- }],
- });
- }
- }));
+ spyOn(gl.boardService, 'generateDefaultLists').and.callFake(
+ () =>
+ new Promise((resolve, reject) => {
+ if (fail) {
+ reject();
+ } else {
+ resolve({
+ data: [
+ {
+ id: 1,
+ title: 'To Do',
+ label: { id: 1 },
+ },
+ {
+ id: 2,
+ title: 'Doing',
+ label: { id: 2 },
+ },
+ ],
+ });
+ }
+ }),
+ );
vm = new Comp();
@@ -40,20 +46,18 @@ describe('Boards blank state', () => {
});
it('renders pre-defined labels', () => {
- expect(
- vm.$el.querySelectorAll('.board-blank-state-list li').length,
- ).toBe(2);
+ expect(vm.$el.querySelectorAll('.board-blank-state-list li').length).toBe(2);
- expect(
- vm.$el.querySelectorAll('.board-blank-state-list li')[0].textContent.trim(),
- ).toEqual('To Do');
+ expect(vm.$el.querySelectorAll('.board-blank-state-list li')[0].textContent.trim()).toEqual(
+ 'To Do',
+ );
- expect(
- vm.$el.querySelectorAll('.board-blank-state-list li')[1].textContent.trim(),
- ).toEqual('Doing');
+ expect(vm.$el.querySelectorAll('.board-blank-state-list li')[1].textContent.trim()).toEqual(
+ 'Doing',
+ );
});
- it('clears blank state', (done) => {
+ it('clears blank state', done => {
vm.$el.querySelector('.btn-default').click();
setTimeout(() => {
@@ -63,7 +67,7 @@ describe('Boards blank state', () => {
});
});
- it('creates pre-defined labels', (done) => {
+ it('creates pre-defined labels', done => {
vm.$el.querySelector('.btn-success').click();
setTimeout(() => {
@@ -75,7 +79,7 @@ describe('Boards blank state', () => {
});
});
- it('resets the store if request fails', (done) => {
+ it('resets the store if request fails', done => {
fail = true;
vm.$el.querySelector('.btn-success').click();
diff --git a/spec/javascripts/boards/board_card_spec.js b/spec/javascripts/boards/board_card_spec.js
index 20cfe426807..e1017130bed 100644
--- a/spec/javascripts/boards/board_card_spec.js
+++ b/spec/javascripts/boards/board_card_spec.js
@@ -18,7 +18,7 @@ describe('Board card', () => {
let vm;
let mock;
- beforeEach((done) => {
+ beforeEach(done => {
mock = new MockAdapter(axios);
mock.onAny().reply(boardsMockInterceptor);
@@ -71,7 +71,7 @@ describe('Board card', () => {
expect(vm.$el.classList.contains('user-can-drag')).toBe(true);
});
- it('does not add user-can-drag class disabled', (done) => {
+ it('does not add user-can-drag class disabled', done => {
vm.disabled = true;
setTimeout(() => {
@@ -84,7 +84,7 @@ describe('Board card', () => {
expect(vm.$el.classList.contains('is-disabled')).toBe(false);
});
- it('adds disabled class is disabled is true', (done) => {
+ it('adds disabled class is disabled is true', done => {
vm.disabled = true;
setTimeout(() => {
@@ -96,8 +96,23 @@ describe('Board card', () => {
describe('mouse events', () => {
const triggerEvent = (eventName, el = vm.$el) => {
const event = document.createEvent('MouseEvents');
- event.initMouseEvent(eventName, true, true, window, 1, 0, 0, 0, 0, false, false,
- false, false, 0, null);
+ event.initMouseEvent(
+ eventName,
+ true,
+ true,
+ window,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ false,
+ false,
+ false,
+ false,
+ 0,
+ null,
+ );
el.dispatchEvent(event);
};
@@ -134,13 +149,15 @@ describe('Board card', () => {
expect(boardsStore.detail.issue).toEqual({});
});
- it('does not set detail issue if img is clicked', (done) => {
- vm.issue.assignees = [new ListAssignee({
- id: 1,
- name: 'testing 123',
- username: 'test',
- avatar: 'test_image',
- })];
+ it('does not set detail issue if img is clicked', done => {
+ vm.issue.assignees = [
+ new ListAssignee({
+ id: 1,
+ name: 'testing 123',
+ username: 'test',
+ avatar: 'test_image',
+ }),
+ ];
Vue.nextTick(() => {
triggerEvent('mouseup', vm.$el.querySelector('img'));
@@ -167,7 +184,7 @@ describe('Board card', () => {
expect(boardsStore.detail.list).toEqual(vm.list);
});
- it('adds active class if detail issue is set', (done) => {
+ it('adds active class if detail issue is set', done => {
vm.detailIssue.issue = vm.issue;
Vue.nextTick()
diff --git a/spec/javascripts/boards/board_new_issue_spec.js b/spec/javascripts/boards/board_new_issue_spec.js
index 9fea625a4ac..721d0b8172d 100644
--- a/spec/javascripts/boards/board_new_issue_spec.js
+++ b/spec/javascripts/boards/board_new_issue_spec.js
@@ -28,7 +28,7 @@ describe('Issue boards new issue form', () => {
return vm.submit(dummySubmitEvent);
};
- beforeEach((done) => {
+ beforeEach(done => {
setFixtures('<div class="test-container"></div>');
const BoardNewIssueComp = Vue.extend(boardNewIssue);
@@ -60,7 +60,7 @@ describe('Issue boards new issue form', () => {
mock.restore();
});
- it('calls submit if submit button is clicked', (done) => {
+ it('calls submit if submit button is clicked', done => {
spyOn(vm, 'submit').and.callFake(e => e.preventDefault());
vm.title = 'Testing Title';
@@ -78,7 +78,7 @@ describe('Issue boards new issue form', () => {
expect(vm.$el.querySelector('.btn-success').disabled).toBe(true);
});
- it('enables submit button if title is not empty', (done) => {
+ it('enables submit button if title is not empty', done => {
vm.title = 'Testing Title';
Vue.nextTick()
@@ -90,7 +90,7 @@ describe('Issue boards new issue form', () => {
.catch(done.fail);
});
- it('clears title after clicking cancel', (done) => {
+ it('clears title after clicking cancel', done => {
vm.$el.querySelector('.btn-default').click();
Vue.nextTick()
@@ -101,7 +101,7 @@ describe('Issue boards new issue form', () => {
.catch(done.fail);
});
- it('does not create new issue if title is empty', (done) => {
+ it('does not create new issue if title is empty', done => {
submitIssue()
.then(() => {
expect(list.newIssue).not.toHaveBeenCalled();
@@ -111,7 +111,7 @@ describe('Issue boards new issue form', () => {
});
describe('submit success', () => {
- it('creates new issue', (done) => {
+ it('creates new issue', done => {
vm.title = 'submit title';
Vue.nextTick()
@@ -123,7 +123,7 @@ describe('Issue boards new issue form', () => {
.catch(done.fail);
});
- it('enables button after submit', (done) => {
+ it('enables button after submit', done => {
vm.title = 'submit issue';
Vue.nextTick()
@@ -135,7 +135,7 @@ describe('Issue boards new issue form', () => {
.catch(done.fail);
});
- it('clears title after submit', (done) => {
+ it('clears title after submit', done => {
vm.title = 'submit issue';
Vue.nextTick()
@@ -147,7 +147,7 @@ describe('Issue boards new issue form', () => {
.catch(done.fail);
});
- it('sets detail issue after submit', (done) => {
+ it('sets detail issue after submit', done => {
expect(boardsStore.detail.issue.title).toBe(undefined);
vm.title = 'submit issue';
@@ -160,7 +160,7 @@ describe('Issue boards new issue form', () => {
.catch(done.fail);
});
- it('sets detail list after submit', (done) => {
+ it('sets detail list after submit', done => {
vm.title = 'submit issue';
Vue.nextTick()
@@ -179,7 +179,7 @@ describe('Issue boards new issue form', () => {
vm.title = 'error';
});
- it('removes issue', (done) => {
+ it('removes issue', done => {
Vue.nextTick()
.then(submitIssue)
.then(() => {
@@ -189,7 +189,7 @@ describe('Issue boards new issue form', () => {
.catch(done.fail);
});
- it('shows error', (done) => {
+ it('shows error', done => {
Vue.nextTick()
.then(submitIssue)
.then(() => {
diff --git a/spec/javascripts/boards/boards_store_spec.js b/spec/javascripts/boards/boards_store_spec.js
index dfd3ea0db66..54f1edfb1f9 100644
--- a/spec/javascripts/boards/boards_store_spec.js
+++ b/spec/javascripts/boards/boards_store_spec.js
@@ -23,13 +23,16 @@ describe('Store', () => {
gl.boardService = mockBoardService();
boardsStore.create();
- spyOn(gl.boardService, 'moveIssue').and.callFake(() => new Promise((resolve) => {
- resolve();
- }));
+ spyOn(gl.boardService, 'moveIssue').and.callFake(
+ () =>
+ new Promise(resolve => {
+ resolve();
+ }),
+ );
Cookies.set('issue_board_welcome_hidden', 'false', {
expires: 365 * 10,
- path: ''
+ path: '',
});
});
@@ -62,7 +65,7 @@ describe('Store', () => {
expect(list).toBeDefined();
});
- it('gets issue when new list added', (done) => {
+ it('gets issue when new list added', done => {
boardsStore.addList(listObj);
const list = boardsStore.findList('id', listObj.id);
@@ -75,7 +78,7 @@ describe('Store', () => {
}, 0);
});
- it('persists new list', (done) => {
+ it('persists new list', done => {
boardsStore.new({
title: 'Test',
list_type: 'label',
@@ -83,13 +86,15 @@ describe('Store', () => {
id: 1,
title: 'Testing',
color: 'red',
- description: 'testing;'
- }
+ description: 'testing;',
+ },
});
+
expect(boardsStore.state.lists.length).toBe(1);
setTimeout(() => {
const list = boardsStore.findList('id', listObj.id);
+
expect(list).toBeDefined();
expect(list.id).toBe(listObj.id);
expect(list.position).toBe(0);
@@ -103,12 +108,13 @@ describe('Store', () => {
it('check for blank state not adding', () => {
boardsStore.addList(listObj);
+
expect(boardsStore.shouldAddBlankState()).toBe(false);
});
it('check for blank state adding when closed list exist', () => {
boardsStore.addList({
- list_type: 'closed'
+ list_type: 'closed',
});
expect(boardsStore.shouldAddBlankState()).toBe(true);
@@ -118,6 +124,7 @@ describe('Store', () => {
boardsStore.addBlankState();
const list = boardsStore.findList('type', 'blank', 'blank');
+
expect(list).toBeDefined();
});
@@ -142,7 +149,7 @@ describe('Store', () => {
expect(listOne.position).toBe(1);
});
- it('moves an issue from one list to another', (done) => {
+ it('moves an issue from one list to another', done => {
const listOne = boardsStore.addList(listObj);
const listTwo = boardsStore.addList(listObjDuplicate);
@@ -161,7 +168,7 @@ describe('Store', () => {
}, 0);
});
- it('moves an issue from backlog to a list', (done) => {
+ it('moves an issue from backlog to a list', done => {
const backlog = boardsStore.addList({
...listObj,
list_type: 'backlog',
@@ -183,7 +190,7 @@ describe('Store', () => {
}, 0);
});
- it('moves issue to top of another list', (done) => {
+ it('moves issue to top of another list', done => {
const listOne = boardsStore.addList(listObj);
const listTwo = boardsStore.addList(listObjDuplicate);
@@ -206,7 +213,7 @@ describe('Store', () => {
}, 0);
});
- it('moves issue to bottom of another list', (done) => {
+ it('moves issue to bottom of another list', done => {
const listOne = boardsStore.addList(listObj);
const listTwo = boardsStore.addList(listObjDuplicate);
@@ -229,7 +236,7 @@ describe('Store', () => {
}, 0);
});
- it('moves issue in list', (done) => {
+ it('moves issue in list', done => {
const issue = new ListIssue({
title: 'Testing',
id: 2,
diff --git a/spec/javascripts/boards/components/board_spec.js b/spec/javascripts/boards/components/board_spec.js
index 4ebd4cecc08..d4c53bd5a7d 100644
--- a/spec/javascripts/boards/components/board_spec.js
+++ b/spec/javascripts/boards/components/board_spec.js
@@ -112,6 +112,6 @@ describe('Board component', () => {
).toBe(true);
done();
- });
+ }).catch(done.fail);
});
});
diff --git a/spec/javascripts/boards/issue_spec.js b/spec/javascripts/boards/issue_spec.js
index e8387068831..437ab4bb3df 100644
--- a/spec/javascripts/boards/issue_spec.js
+++ b/spec/javascripts/boards/issue_spec.js
@@ -21,18 +21,22 @@ describe('Issue model', () => {
id: 1,
iid: 1,
confidential: false,
- labels: [{
- id: 1,
- title: 'test',
- color: 'red',
- description: 'testing'
- }],
- assignees: [{
- id: 1,
- name: 'name',
- username: 'username',
- avatar_url: 'http://avatar_url',
- }],
+ labels: [
+ {
+ id: 1,
+ title: 'test',
+ color: 'red',
+ description: 'testing',
+ },
+ ],
+ assignees: [
+ {
+ id: 1,
+ name: 'name',
+ username: 'username',
+ avatar_url: 'http://avatar_url',
+ },
+ ],
});
});
@@ -45,8 +49,9 @@ describe('Issue model', () => {
id: 2,
title: 'bug',
color: 'blue',
- description: 'bugs!'
+ description: 'bugs!',
});
+
expect(issue.labels.length).toBe(2);
});
@@ -55,7 +60,7 @@ describe('Issue model', () => {
id: 2,
title: 'test',
color: 'blue',
- description: 'bugs!'
+ description: 'bugs!',
});
expect(issue.labels.length).toBe(1);
@@ -63,12 +68,14 @@ describe('Issue model', () => {
it('finds label', () => {
const label = issue.findLabel(issue.labels[0]);
+
expect(label).toBeDefined();
});
it('removes label', () => {
const label = issue.findLabel(issue.labels[0]);
issue.removeLabel(label);
+
expect(issue.labels.length).toBe(0);
});
@@ -77,11 +84,13 @@ describe('Issue model', () => {
id: 2,
title: 'bug',
color: 'blue',
- description: 'bugs!'
+ description: 'bugs!',
});
+
expect(issue.labels.length).toBe(2);
issue.removeLabels([issue.labels[0], issue.labels[1]]);
+
expect(issue.labels.length).toBe(0);
});
@@ -98,17 +107,20 @@ describe('Issue model', () => {
it('finds assignee', () => {
const assignee = issue.findAssignee(issue.assignees[0]);
+
expect(assignee).toBeDefined();
});
it('removes assignee', () => {
const assignee = issue.findAssignee(issue.assignees[0]);
issue.removeAssignee(assignee);
+
expect(issue.assignees.length).toBe(0);
});
it('removes all assignees', () => {
issue.removeAllAssignees();
+
expect(issue.assignees.length).toBe(0);
});
@@ -131,6 +143,7 @@ describe('Issue model', () => {
it('updates data', () => {
issue.updateData({ subscribed: true });
+
expect(issue.subscribed).toBe(true);
});
@@ -149,7 +162,7 @@ describe('Issue model', () => {
});
describe('update', () => {
- it('passes assignee ids when there are assignees', (done) => {
+ it('passes assignee ids when there are assignees', done => {
spyOn(Vue.http, 'patch').and.callFake((url, data) => {
expect(data.issue.assignee_ids).toEqual([1]);
done();
@@ -158,7 +171,7 @@ describe('Issue model', () => {
issue.update('url');
});
- it('passes assignee ids of [0] when there are no assignees', (done) => {
+ it('passes assignee ids of [0] when there are no assignees', done => {
spyOn(Vue.http, 'patch').and.callFake((url, data) => {
expect(data.issue.assignee_ids).toEqual([0]);
done();
diff --git a/spec/javascripts/boards/list_spec.js b/spec/javascripts/boards/list_spec.js
index ba6e81a29a9..0d462a6f872 100644
--- a/spec/javascripts/boards/list_spec.js
+++ b/spec/javascripts/boards/list_spec.js
@@ -31,21 +31,21 @@ describe('List model', () => {
mock.restore();
});
- it('gets issues when created', (done) => {
+ it('gets issues when created', done => {
setTimeout(() => {
expect(list.issues.length).toBe(1);
done();
}, 0);
});
- it('saves list and returns ID', (done) => {
+ it('saves list and returns ID', done => {
list = new List({
title: 'test',
label: {
id: _.random(10000),
title: 'test',
- color: 'red'
- }
+ color: 'red',
+ },
});
list.save();
@@ -57,9 +57,10 @@ describe('List model', () => {
}, 0);
});
- it('destroys the list', (done) => {
+ it('destroys the list', done => {
boardsStore.addList(listObj);
list = boardsStore.findList('id', listObj.id);
+
expect(boardsStore.state.lists.length).toBe(1);
list.destroy();
@@ -69,19 +70,22 @@ describe('List model', () => {
}, 0);
});
- it('gets issue from list', (done) => {
+ it('gets issue from list', done => {
setTimeout(() => {
const issue = list.findIssue(1);
+
expect(issue).toBeDefined();
done();
}, 0);
});
- it('removes issue', (done) => {
+ it('removes issue', done => {
setTimeout(() => {
const issue = list.findIssue(1);
+
expect(list.issues.length).toBe(1);
list.removeIssue(issue);
+
expect(list.issues.length).toBe(0);
done();
}, 0);
@@ -105,8 +109,13 @@ describe('List model', () => {
listDup.updateIssueLabel(issue, list);
- expect(gl.boardService.moveIssue)
- .toHaveBeenCalledWith(issue.id, list.id, listDup.id, undefined, undefined);
+ expect(gl.boardService.moveIssue).toHaveBeenCalledWith(
+ issue.id,
+ list.id,
+ listDup.id,
+ undefined,
+ undefined,
+ );
});
describe('page number', () => {
@@ -116,14 +125,16 @@ describe('List model', () => {
it('increase page number if current issue count is more than the page size', () => {
for (let i = 0; i < 30; i += 1) {
- list.issues.push(new ListIssue({
- title: 'Testing',
- id: _.random(10000) + i,
- iid: _.random(10000) + i,
- confidential: false,
- labels: [list.label],
- assignees: [],
- }));
+ list.issues.push(
+ new ListIssue({
+ title: 'Testing',
+ id: _.random(10000) + i,
+ iid: _.random(10000) + i,
+ confidential: false,
+ labels: [list.label],
+ assignees: [],
+ }),
+ );
}
list.issuesSize = 50;
@@ -136,13 +147,15 @@ describe('List model', () => {
});
it('does not increase page number if issue count is less than the page size', () => {
- list.issues.push(new ListIssue({
- title: 'Testing',
- id: _.random(10000),
- confidential: false,
- labels: [list.label],
- assignees: [],
- }));
+ list.issues.push(
+ new ListIssue({
+ title: 'Testing',
+ id: _.random(10000),
+ confidential: false,
+ labels: [list.label],
+ assignees: [],
+ }),
+ );
list.issuesSize = 2;
list.nextPage();
@@ -154,21 +167,25 @@ describe('List model', () => {
describe('newIssue', () => {
beforeEach(() => {
- spyOn(gl.boardService, 'newIssue').and.returnValue(Promise.resolve({
- data: {
- id: 42,
- },
- }));
+ spyOn(gl.boardService, 'newIssue').and.returnValue(
+ Promise.resolve({
+ data: {
+ id: 42,
+ },
+ }),
+ );
});
- it('adds new issue to top of list', (done) => {
- list.issues.push(new ListIssue({
- title: 'Testing',
- id: _.random(10000),
- confidential: false,
- labels: [list.label],
- assignees: [],
- }));
+ it('adds new issue to top of list', done => {
+ list.issues.push(
+ new ListIssue({
+ title: 'Testing',
+ id: _.random(10000),
+ confidential: false,
+ labels: [list.label],
+ assignees: [],
+ }),
+ );
const dummyIssue = new ListIssue({
title: 'new issue',
id: _.random(10000),
@@ -177,7 +194,8 @@ describe('List model', () => {
assignees: [],
});
- list.newIssue(dummyIssue)
+ list
+ .newIssue(dummyIssue)
.then(() => {
expect(list.issues.length).toBe(2);
expect(list.issues[0]).toBe(dummyIssue);
diff --git a/spec/javascripts/bootstrap_jquery_spec.js b/spec/javascripts/bootstrap_jquery_spec.js
index 052465d8d88..35340a3bc42 100644
--- a/spec/javascripts/bootstrap_jquery_spec.js
+++ b/spec/javascripts/bootstrap_jquery_spec.js
@@ -3,41 +3,45 @@
import $ from 'jquery';
import '~/commons/bootstrap';
-(function() {
- describe('Bootstrap jQuery extensions', function() {
- describe('disable', function() {
- beforeEach(function() {
- return setFixtures('<input type="text" />');
- });
- it('adds the disabled attribute', function() {
- var $input;
- $input = $('input').first();
- $input.disable();
- return expect($input).toHaveAttr('disabled', 'disabled');
- });
- return it('adds the disabled class', function() {
- var $input;
- $input = $('input').first();
- $input.disable();
- return expect($input).toHaveClass('disabled');
- });
+describe('Bootstrap jQuery extensions', function() {
+ describe('disable', function() {
+ beforeEach(function() {
+ return setFixtures('<input type="text" />');
});
- return describe('enable', function() {
- beforeEach(function() {
- return setFixtures('<input type="text" disabled="disabled" class="disabled" />');
- });
- it('removes the disabled attribute', function() {
- var $input;
- $input = $('input').first();
- $input.enable();
- return expect($input).not.toHaveAttr('disabled');
- });
- return it('removes the disabled class', function() {
- var $input;
- $input = $('input').first();
- $input.enable();
- return expect($input).not.toHaveClass('disabled');
- });
+
+ it('adds the disabled attribute', function() {
+ var $input;
+ $input = $('input').first();
+ $input.disable();
+
+ expect($input).toHaveAttr('disabled', 'disabled');
+ });
+ return it('adds the disabled class', function() {
+ var $input;
+ $input = $('input').first();
+ $input.disable();
+
+ expect($input).toHaveClass('disabled');
+ });
+ });
+ return describe('enable', function() {
+ beforeEach(function() {
+ return setFixtures('<input type="text" disabled="disabled" class="disabled" />');
+ });
+
+ it('removes the disabled attribute', function() {
+ var $input;
+ $input = $('input').first();
+ $input.enable();
+
+ expect($input).not.toHaveAttr('disabled');
+ });
+ return it('removes the disabled class', function() {
+ var $input;
+ $input = $('input').first();
+ $input.enable();
+
+ expect($input).not.toHaveClass('disabled');
});
});
-}).call(window);
+});
diff --git a/spec/javascripts/bootstrap_linked_tabs_spec.js b/spec/javascripts/bootstrap_linked_tabs_spec.js
index 6f679369289..c3e3d78ff63 100644
--- a/spec/javascripts/bootstrap_linked_tabs_spec.js
+++ b/spec/javascripts/bootstrap_linked_tabs_spec.js
@@ -1,60 +1,67 @@
import LinkedTabs from '~/lib/utils/bootstrap_linked_tabs';
-(() => {
- describe('Linked Tabs', () => {
- preloadFixtures('static/linked_tabs.html.raw');
+describe('Linked Tabs', () => {
+ preloadFixtures('static/linked_tabs.html.raw');
+ beforeEach(() => {
+ loadFixtures('static/linked_tabs.html.raw');
+ });
+
+ describe('when is initialized', () => {
beforeEach(() => {
- loadFixtures('static/linked_tabs.html.raw');
+ spyOn(window.history, 'replaceState').and.callFake(function() {});
});
- describe('when is initialized', () => {
- beforeEach(() => {
- spyOn(window.history, 'replaceState').and.callFake(function () {});
+ it('should activate the tab correspondent to the given action', () => {
+ // eslint-disable-next-line no-new
+ new LinkedTabs({
+ action: 'tab1',
+ defaultAction: 'tab1',
+ parentEl: '.linked-tabs',
});
- it('should activate the tab correspondent to the given action', () => {
- const linkedTabs = new LinkedTabs({ // eslint-disable-line
- action: 'tab1',
- defaultAction: 'tab1',
- parentEl: '.linked-tabs',
- });
+ expect(document.querySelector('#tab1').classList).toContain('active');
+ });
- expect(document.querySelector('#tab1').classList).toContain('active');
+ it('should active the default tab action when the action is show', () => {
+ // eslint-disable-next-line no-new
+ new LinkedTabs({
+ action: 'show',
+ defaultAction: 'tab1',
+ parentEl: '.linked-tabs',
});
- it('should active the default tab action when the action is show', () => {
- const linkedTabs = new LinkedTabs({ // eslint-disable-line
- action: 'show',
- defaultAction: 'tab1',
- parentEl: '.linked-tabs',
- });
-
- expect(document.querySelector('#tab1').classList).toContain('active');
- });
+ expect(document.querySelector('#tab1').classList).toContain('active');
});
+ });
- describe('on click', () => {
- it('should change the url according to the clicked tab', () => {
- const historySpy = spyOn(window.history, 'replaceState').and.callFake(() => {});
+ describe('on click', () => {
+ it('should change the url according to the clicked tab', () => {
+ const historySpy = spyOn(window.history, 'replaceState').and.callFake(() => {});
- const linkedTabs = new LinkedTabs({
- action: 'show',
- defaultAction: 'tab1',
- parentEl: '.linked-tabs',
- });
+ const linkedTabs = new LinkedTabs({
+ action: 'show',
+ defaultAction: 'tab1',
+ parentEl: '.linked-tabs',
+ });
- const secondTab = document.querySelector('.linked-tabs li:nth-child(2) a');
- const newState = secondTab.getAttribute('href') + linkedTabs.currentLocation.search + linkedTabs.currentLocation.hash;
+ const secondTab = document.querySelector('.linked-tabs li:nth-child(2) a');
+ const newState =
+ secondTab.getAttribute('href') +
+ linkedTabs.currentLocation.search +
+ linkedTabs.currentLocation.hash;
- secondTab.click();
+ secondTab.click();
- if (historySpy) {
- expect(historySpy).toHaveBeenCalledWith({
+ if (historySpy) {
+ expect(historySpy).toHaveBeenCalledWith(
+ {
url: newState,
- }, document.title, newState);
- }
- });
+ },
+ document.title,
+ newState,
+ );
+ }
});
});
-})();
+});
diff --git a/spec/javascripts/breakpoints_spec.js b/spec/javascripts/breakpoints_spec.js
index b1b5d36c1fb..5ee777fee3f 100644
--- a/spec/javascripts/breakpoints_spec.js
+++ b/spec/javascripts/breakpoints_spec.js
@@ -1,9 +1,7 @@
-import bp, {
- breakpoints,
-} from '~/breakpoints';
+import bp, { breakpoints } from '~/breakpoints';
describe('breakpoints', () => {
- Object.keys(breakpoints).forEach((key) => {
+ Object.keys(breakpoints).forEach(key => {
const size = breakpoints[key];
it(`returns ${key} when larger than ${size}`, () => {
diff --git a/spec/javascripts/ci_variable_list/ajax_variable_list_spec.js b/spec/javascripts/ci_variable_list/ajax_variable_list_spec.js
index ee457a9c48c..4f8701bae01 100644
--- a/spec/javascripts/ci_variable_list/ajax_variable_list_spec.js
+++ b/spec/javascripts/ci_variable_list/ajax_variable_list_spec.js
@@ -43,7 +43,7 @@ describe('AjaxFormVariableList', () => {
});
describe('onSaveClicked', () => {
- it('shows loading spinner while waiting for the request', (done) => {
+ it('shows loading spinner while waiting for the request', done => {
const loadingIcon = saveButton.querySelector('.js-secret-variables-save-loading-icon');
mock.onPatch(VARIABLE_PATCH_ENDPOINT).reply(() => {
@@ -54,7 +54,8 @@ describe('AjaxFormVariableList', () => {
expect(loadingIcon.classList.contains(HIDE_CLASS)).toEqual(true);
- ajaxVariableList.onSaveClicked()
+ ajaxVariableList
+ .onSaveClicked()
.then(() => {
expect(loadingIcon.classList.contains(HIDE_CLASS)).toEqual(true);
})
@@ -62,27 +63,30 @@ describe('AjaxFormVariableList', () => {
.catch(done.fail);
});
- it('calls `updateRowsWithPersistedVariables` with the persisted variables', (done) => {
+ it('calls `updateRowsWithPersistedVariables` with the persisted variables', done => {
const variablesResponse = [{ id: 1, key: 'foo', value: 'bar' }];
mock.onPatch(VARIABLE_PATCH_ENDPOINT).reply(200, {
variables: variablesResponse,
});
- ajaxVariableList.onSaveClicked()
+ ajaxVariableList
+ .onSaveClicked()
.then(() => {
- expect(ajaxVariableList.updateRowsWithPersistedVariables)
- .toHaveBeenCalledWith(variablesResponse);
+ expect(ajaxVariableList.updateRowsWithPersistedVariables).toHaveBeenCalledWith(
+ variablesResponse,
+ );
})
.then(done)
.catch(done.fail);
});
- it('hides any previous error box', (done) => {
+ it('hides any previous error box', done => {
mock.onPatch(VARIABLE_PATCH_ENDPOINT).reply(200);
expect(errorBox.classList.contains(HIDE_CLASS)).toEqual(true);
- ajaxVariableList.onSaveClicked()
+ ajaxVariableList
+ .onSaveClicked()
.then(() => {
expect(errorBox.classList.contains(HIDE_CLASS)).toEqual(true);
})
@@ -90,14 +94,15 @@ describe('AjaxFormVariableList', () => {
.catch(done.fail);
});
- it('disables remove buttons while waiting for the request', (done) => {
+ it('disables remove buttons while waiting for the request', done => {
mock.onPatch(VARIABLE_PATCH_ENDPOINT).reply(() => {
expect(ajaxVariableList.variableList.toggleEnableRow).toHaveBeenCalledWith(false);
return [200, {}];
});
- ajaxVariableList.onSaveClicked()
+ ajaxVariableList
+ .onSaveClicked()
.then(() => {
expect(ajaxVariableList.variableList.toggleEnableRow).toHaveBeenCalledWith(true);
})
@@ -105,7 +110,7 @@ describe('AjaxFormVariableList', () => {
.catch(done.fail);
});
- it('hides secret values', (done) => {
+ it('hides secret values', done => {
mock.onPatch(VARIABLE_PATCH_ENDPOINT).reply(200, {});
const row = container.querySelector('.js-row:first-child');
@@ -118,7 +123,8 @@ describe('AjaxFormVariableList', () => {
expect(valuePlaceholder.classList.contains(HIDE_CLASS)).toBe(true);
expect(valueInput.classList.contains(HIDE_CLASS)).toBe(false);
- ajaxVariableList.onSaveClicked()
+ ajaxVariableList
+ .onSaveClicked()
.then(() => {
expect(valuePlaceholder.classList.contains(HIDE_CLASS)).toBe(false);
expect(valueInput.classList.contains(HIDE_CLASS)).toBe(true);
@@ -127,29 +133,31 @@ describe('AjaxFormVariableList', () => {
.catch(done.fail);
});
- it('shows error box with validation errors', (done) => {
+ it('shows error box with validation errors', done => {
const validationError = 'some validation error';
- mock.onPatch(VARIABLE_PATCH_ENDPOINT).reply(400, [
- validationError,
- ]);
+ mock.onPatch(VARIABLE_PATCH_ENDPOINT).reply(400, [validationError]);
expect(errorBox.classList.contains(HIDE_CLASS)).toEqual(true);
- ajaxVariableList.onSaveClicked()
+ ajaxVariableList
+ .onSaveClicked()
.then(() => {
expect(errorBox.classList.contains(HIDE_CLASS)).toEqual(false);
- expect(errorBox.textContent.trim().replace(/\n+\s+/m, ' ')).toEqual(`Validation failed ${validationError}`);
+ expect(errorBox.textContent.trim().replace(/\n+\s+/m, ' ')).toEqual(
+ `Validation failed ${validationError}`,
+ );
})
.then(done)
.catch(done.fail);
});
- it('shows flash message when request fails', (done) => {
+ it('shows flash message when request fails', done => {
mock.onPatch(VARIABLE_PATCH_ENDPOINT).reply(500);
expect(errorBox.classList.contains(HIDE_CLASS)).toEqual(true);
- ajaxVariableList.onSaveClicked()
+ ajaxVariableList
+ .onSaveClicked()
.then(() => {
expect(errorBox.classList.contains(HIDE_CLASS)).toEqual(true);
})
@@ -200,11 +208,13 @@ describe('AjaxFormVariableList', () => {
expect(idInput.value).toEqual('');
- ajaxVariableList.updateRowsWithPersistedVariables([{
- id: 3,
- key: 'foo',
- value: 'bar',
- }]);
+ ajaxVariableList.updateRowsWithPersistedVariables([
+ {
+ id: 3,
+ key: 'foo',
+ value: 'bar',
+ },
+ ]);
expect(idInput.value).toEqual('3');
expect(row.dataset.isPersisted).toEqual('true');
diff --git a/spec/javascripts/ci_variable_list/ci_variable_list_spec.js b/spec/javascripts/ci_variable_list/ci_variable_list_spec.js
index 2fa50975f0f..30b15011def 100644
--- a/spec/javascripts/ci_variable_list/ci_variable_list_spec.js
+++ b/spec/javascripts/ci_variable_list/ci_variable_list_spec.js
@@ -33,7 +33,8 @@ describe('VariableList', () => {
it('should add another row when editing the last rows key input', () => {
const $row = $wrapper.find('.js-row');
- $row.find('.js-ci-variable-input-key')
+ $row
+ .find('.js-ci-variable-input-key')
.val('foo')
.trigger('input');
@@ -41,12 +42,14 @@ describe('VariableList', () => {
// Check for the correct default in the new row
const $keyInput = $wrapper.find('.js-row:last-child').find('.js-ci-variable-input-key');
+
expect($keyInput.val()).toBe('');
});
it('should add another row when editing the last rows value textarea', () => {
const $row = $wrapper.find('.js-row');
- $row.find('.js-ci-variable-input-value')
+ $row
+ .find('.js-ci-variable-input-value')
.val('foo')
.trigger('input');
@@ -54,18 +57,21 @@ describe('VariableList', () => {
// Check for the correct default in the new row
const $valueInput = $wrapper.find('.js-row:last-child').find('.js-ci-variable-input-key');
+
expect($valueInput.val()).toBe('');
});
it('should remove empty row after blurring', () => {
const $row = $wrapper.find('.js-row');
- $row.find('.js-ci-variable-input-key')
+ $row
+ .find('.js-ci-variable-input-key')
.val('foo')
.trigger('input');
expect($wrapper.find('.js-row').length).toBe(2);
- $row.find('.js-ci-variable-input-key')
+ $row
+ .find('.js-ci-variable-input-key')
.val('')
.trigger('input')
.trigger('blur');
@@ -119,7 +125,7 @@ describe('VariableList', () => {
variableList.init();
});
- it('should add another row when editing the last rows protected checkbox', (done) => {
+ it('should add another row when editing the last rows protected checkbox', done => {
const $row = $wrapper.find('.js-row:last-child');
$row.find('.ci-variable-protected-item .js-project-feature-toggle').click();
@@ -128,7 +134,10 @@ describe('VariableList', () => {
expect($wrapper.find('.js-row').length).toBe(2);
// Check for the correct default in the new row
- const $protectedInput = $wrapper.find('.js-row:last-child').find('.js-ci-variable-input-protected');
+ const $protectedInput = $wrapper
+ .find('.js-row:last-child')
+ .find('.js-ci-variable-input-protected');
+
expect($protectedInput.val()).toBe('false');
})
.then(done)
@@ -166,6 +175,7 @@ describe('VariableList', () => {
it('should enable all remove buttons', () => {
variableList.toggleEnableRow(false);
+
expect($wrapper.find('.js-row-remove-button[disabled]').length).toBe(3);
variableList.toggleEnableRow(true);
@@ -175,6 +185,7 @@ describe('VariableList', () => {
it('should enable all key inputs', () => {
variableList.toggleEnableRow(false);
+
expect($wrapper.find('.js-ci-variable-input-key[disabled]').length).toBe(3);
variableList.toggleEnableRow(true);
@@ -200,7 +211,8 @@ describe('VariableList', () => {
const $inputValue = $row.find('.js-ci-variable-input-value');
const $placeholder = $row.find('.js-secret-value-placeholder');
- $row.find('.js-ci-variable-input-value')
+ $row
+ .find('.js-ci-variable-input-value')
.val('foo')
.trigger('input');
diff --git a/spec/javascripts/ci_variable_list/native_form_variable_list_spec.js b/spec/javascripts/ci_variable_list/native_form_variable_list_spec.js
index 94a0c999d66..997d0d54d79 100644
--- a/spec/javascripts/ci_variable_list/native_form_variable_list_spec.js
+++ b/spec/javascripts/ci_variable_list/native_form_variable_list_spec.js
@@ -19,8 +19,14 @@ describe('NativeFormVariableList', () => {
describe('onFormSubmit', () => {
it('should clear out the `name` attribute on the inputs for the last empty row on form submission (avoid BE validation)', () => {
const $row = $wrapper.find('.js-row');
- expect($row.find('.js-ci-variable-input-key').attr('name')).toBe('schedule[variables_attributes][][key]');
- expect($row.find('.js-ci-variable-input-value').attr('name')).toBe('schedule[variables_attributes][][secret_value]');
+
+ expect($row.find('.js-ci-variable-input-key').attr('name')).toBe(
+ 'schedule[variables_attributes][][key]',
+ );
+
+ expect($row.find('.js-ci-variable-input-value').attr('name')).toBe(
+ 'schedule[variables_attributes][][secret_value]',
+ );
$wrapper.closest('form').trigger('trigger-submit');
diff --git a/spec/javascripts/close_reopen_report_toggle_spec.js b/spec/javascripts/close_reopen_report_toggle_spec.js
index 412abe2cbf8..04a7ae7f429 100644
--- a/spec/javascripts/close_reopen_report_toggle_spec.js
+++ b/spec/javascripts/close_reopen_report_toggle_spec.js
@@ -10,7 +10,7 @@ describe('CloseReopenReportToggle', () => {
const button = {};
let commentTypeToggle;
- beforeEach(function () {
+ beforeEach(function() {
commentTypeToggle = new CloseReopenReportToggle({
dropdownTrigger,
dropdownList,
@@ -18,15 +18,15 @@ describe('CloseReopenReportToggle', () => {
});
});
- it('sets .dropdownTrigger', function () {
+ it('sets .dropdownTrigger', function() {
expect(commentTypeToggle.dropdownTrigger).toBe(dropdownTrigger);
});
- it('sets .dropdownList', function () {
+ it('sets .dropdownList', function() {
expect(commentTypeToggle.dropdownList).toBe(dropdownList);
});
- it('sets .button', function () {
+ it('sets .button', function() {
expect(commentTypeToggle.button).toBe(button);
});
});
diff --git a/spec/javascripts/clusters/clusters_bundle_spec.js b/spec/javascripts/clusters/clusters_bundle_spec.js
index d0e0b214509..880b469284b 100644
--- a/spec/javascripts/clusters/clusters_bundle_spec.js
+++ b/spec/javascripts/clusters/clusters_bundle_spec.js
@@ -21,21 +21,21 @@ describe('Clusters', () => {
});
describe('toggle', () => {
- it('should update the button and the input field on click', (done) => {
- const toggleButton = document.querySelector('.js-cluster-enable-toggle-area .js-project-feature-toggle');
- const toggleInput = document.querySelector('.js-cluster-enable-toggle-area .js-project-feature-toggle-input');
+ it('should update the button and the input field on click', done => {
+ const toggleButton = document.querySelector(
+ '.js-cluster-enable-toggle-area .js-project-feature-toggle',
+ );
+ const toggleInput = document.querySelector(
+ '.js-cluster-enable-toggle-area .js-project-feature-toggle-input',
+ );
toggleButton.click();
getSetTimeoutPromise()
.then(() => {
- expect(
- toggleButton.classList,
- ).not.toContain('is-checked');
+ expect(toggleButton.classList).not.toContain('is-checked');
- expect(
- toggleInput.getAttribute('value'),
- ).toEqual('false');
+ expect(toggleInput.getAttribute('value')).toEqual('false');
})
.then(done)
.catch(done.fail);
@@ -46,29 +46,21 @@ describe('Clusters', () => {
it('should update token field type', () => {
cluster.showTokenButton.click();
- expect(
- cluster.tokenField.getAttribute('type'),
- ).toEqual('text');
+ expect(cluster.tokenField.getAttribute('type')).toEqual('text');
cluster.showTokenButton.click();
- expect(
- cluster.tokenField.getAttribute('type'),
- ).toEqual('password');
+ expect(cluster.tokenField.getAttribute('type')).toEqual('password');
});
it('should update show token button text', () => {
cluster.showTokenButton.click();
- expect(
- cluster.showTokenButton.textContent,
- ).toEqual('Hide');
+ expect(cluster.showTokenButton.textContent).toEqual('Hide');
cluster.showTokenButton.click();
- expect(
- cluster.showTokenButton.textContent,
- ).toEqual('Show');
+ expect(cluster.showTokenButton.textContent).toEqual('Show');
});
});
@@ -86,37 +78,50 @@ describe('Clusters', () => {
});
const flashMessage = document.querySelector('.js-cluster-application-notice .flash-text');
+
expect(flashMessage).toBeNull();
});
it('shows an alert when something gets newly installed', () => {
- cluster.checkForNewInstalls({
- ...INITIAL_APP_MAP,
- helm: { status: APPLICATION_STATUS.INSTALLING, title: 'Helm Tiller' },
- }, {
- ...INITIAL_APP_MAP,
- helm: { status: APPLICATION_STATUS.INSTALLED, title: 'Helm Tiller' },
- });
+ cluster.checkForNewInstalls(
+ {
+ ...INITIAL_APP_MAP,
+ helm: { status: APPLICATION_STATUS.INSTALLING, title: 'Helm Tiller' },
+ },
+ {
+ ...INITIAL_APP_MAP,
+ helm: { status: APPLICATION_STATUS.INSTALLED, title: 'Helm Tiller' },
+ },
+ );
const flashMessage = document.querySelector('.js-cluster-application-notice .flash-text');
+
expect(flashMessage).not.toBeNull();
- expect(flashMessage.textContent.trim()).toEqual('Helm Tiller was successfully installed on your Kubernetes cluster');
+ expect(flashMessage.textContent.trim()).toEqual(
+ 'Helm Tiller was successfully installed on your Kubernetes cluster',
+ );
});
it('shows an alert when multiple things gets newly installed', () => {
- cluster.checkForNewInstalls({
- ...INITIAL_APP_MAP,
- helm: { status: APPLICATION_STATUS.INSTALLING, title: 'Helm Tiller' },
- ingress: { status: APPLICATION_STATUS.INSTALLABLE, title: 'Ingress' },
- }, {
- ...INITIAL_APP_MAP,
- helm: { status: APPLICATION_STATUS.INSTALLED, title: 'Helm Tiller' },
- ingress: { status: APPLICATION_STATUS.INSTALLED, title: 'Ingress' },
- });
+ cluster.checkForNewInstalls(
+ {
+ ...INITIAL_APP_MAP,
+ helm: { status: APPLICATION_STATUS.INSTALLING, title: 'Helm Tiller' },
+ ingress: { status: APPLICATION_STATUS.INSTALLABLE, title: 'Ingress' },
+ },
+ {
+ ...INITIAL_APP_MAP,
+ helm: { status: APPLICATION_STATUS.INSTALLED, title: 'Helm Tiller' },
+ ingress: { status: APPLICATION_STATUS.INSTALLED, title: 'Ingress' },
+ },
+ );
const flashMessage = document.querySelector('.js-cluster-application-notice .flash-text');
+
expect(flashMessage).not.toBeNull();
- expect(flashMessage.textContent.trim()).toEqual('Helm Tiller, Ingress was successfully installed on your Kubernetes cluster');
+ expect(flashMessage.textContent.trim()).toEqual(
+ 'Helm Tiller, Ingress was successfully installed on your Kubernetes cluster',
+ );
});
});
@@ -125,29 +130,21 @@ describe('Clusters', () => {
it('should show the creating container', () => {
cluster.updateContainer(null, 'creating');
- expect(
- cluster.creatingContainer.classList.contains('hidden'),
- ).toBeFalsy();
- expect(
- cluster.successContainer.classList.contains('hidden'),
- ).toBeTruthy();
- expect(
- cluster.errorContainer.classList.contains('hidden'),
- ).toBeTruthy();
+ expect(cluster.creatingContainer.classList.contains('hidden')).toBeFalsy();
+
+ expect(cluster.successContainer.classList.contains('hidden')).toBeTruthy();
+
+ expect(cluster.errorContainer.classList.contains('hidden')).toBeTruthy();
});
it('should continue to show `creating` banner with subsequent updates of the same status', () => {
cluster.updateContainer('creating', 'creating');
- expect(
- cluster.creatingContainer.classList.contains('hidden'),
- ).toBeFalsy();
- expect(
- cluster.successContainer.classList.contains('hidden'),
- ).toBeTruthy();
- expect(
- cluster.errorContainer.classList.contains('hidden'),
- ).toBeTruthy();
+ expect(cluster.creatingContainer.classList.contains('hidden')).toBeFalsy();
+
+ expect(cluster.successContainer.classList.contains('hidden')).toBeTruthy();
+
+ expect(cluster.errorContainer.classList.contains('hidden')).toBeTruthy();
});
});
@@ -155,29 +152,21 @@ describe('Clusters', () => {
it('should show the success container and fresh the page', () => {
cluster.updateContainer(null, 'created');
- expect(
- cluster.creatingContainer.classList.contains('hidden'),
- ).toBeTruthy();
- expect(
- cluster.successContainer.classList.contains('hidden'),
- ).toBeFalsy();
- expect(
- cluster.errorContainer.classList.contains('hidden'),
- ).toBeTruthy();
+ expect(cluster.creatingContainer.classList.contains('hidden')).toBeTruthy();
+
+ expect(cluster.successContainer.classList.contains('hidden')).toBeFalsy();
+
+ expect(cluster.errorContainer.classList.contains('hidden')).toBeTruthy();
});
it('should not show a banner when status is already `created`', () => {
cluster.updateContainer('created', 'created');
- expect(
- cluster.creatingContainer.classList.contains('hidden'),
- ).toBeTruthy();
- expect(
- cluster.successContainer.classList.contains('hidden'),
- ).toBeTruthy();
- expect(
- cluster.errorContainer.classList.contains('hidden'),
- ).toBeTruthy();
+ expect(cluster.creatingContainer.classList.contains('hidden')).toBeTruthy();
+
+ expect(cluster.successContainer.classList.contains('hidden')).toBeTruthy();
+
+ expect(cluster.errorContainer.classList.contains('hidden')).toBeTruthy();
});
});
@@ -185,40 +174,31 @@ describe('Clusters', () => {
it('should show the error container', () => {
cluster.updateContainer(null, 'errored', 'this is an error');
- expect(
- cluster.creatingContainer.classList.contains('hidden'),
- ).toBeTruthy();
- expect(
- cluster.successContainer.classList.contains('hidden'),
- ).toBeTruthy();
- expect(
- cluster.errorContainer.classList.contains('hidden'),
- ).toBeFalsy();
-
- expect(
- cluster.errorReasonContainer.textContent,
- ).toContain('this is an error');
+ expect(cluster.creatingContainer.classList.contains('hidden')).toBeTruthy();
+
+ expect(cluster.successContainer.classList.contains('hidden')).toBeTruthy();
+
+ expect(cluster.errorContainer.classList.contains('hidden')).toBeFalsy();
+
+ expect(cluster.errorReasonContainer.textContent).toContain('this is an error');
});
it('should show `error` banner when previously `creating`', () => {
cluster.updateContainer('creating', 'errored');
- expect(
- cluster.creatingContainer.classList.contains('hidden'),
- ).toBeTruthy();
- expect(
- cluster.successContainer.classList.contains('hidden'),
- ).toBeTruthy();
- expect(
- cluster.errorContainer.classList.contains('hidden'),
- ).toBeFalsy();
+ expect(cluster.creatingContainer.classList.contains('hidden')).toBeTruthy();
+
+ expect(cluster.successContainer.classList.contains('hidden')).toBeTruthy();
+
+ expect(cluster.errorContainer.classList.contains('hidden')).toBeFalsy();
});
});
});
describe('installApplication', () => {
- it('tries to install helm', (done) => {
+ it('tries to install helm', done => {
spyOn(cluster.service, 'installApplication').and.returnValue(Promise.resolve());
+
expect(cluster.store.state.applications.helm.requestStatus).toEqual(null);
cluster.installApplication({ id: 'helm' });
@@ -236,8 +216,9 @@ describe('Clusters', () => {
.catch(done.fail);
});
- it('tries to install ingress', (done) => {
+ it('tries to install ingress', done => {
spyOn(cluster.service, 'installApplication').and.returnValue(Promise.resolve());
+
expect(cluster.store.state.applications.ingress.requestStatus).toEqual(null);
cluster.installApplication({ id: 'ingress' });
@@ -255,8 +236,9 @@ describe('Clusters', () => {
.catch(done.fail);
});
- it('tries to install runner', (done) => {
+ it('tries to install runner', done => {
spyOn(cluster.service, 'installApplication').and.returnValue(Promise.resolve());
+
expect(cluster.store.state.applications.runner.requestStatus).toEqual(null);
cluster.installApplication({ id: 'runner' });
@@ -274,26 +256,35 @@ describe('Clusters', () => {
.catch(done.fail);
});
- it('tries to install jupyter', (done) => {
+ it('tries to install jupyter', done => {
spyOn(cluster.service, 'installApplication').and.returnValue(Promise.resolve());
+
expect(cluster.store.state.applications.jupyter.requestStatus).toEqual(null);
- cluster.installApplication({ id: 'jupyter', params: { hostname: cluster.store.state.applications.jupyter.hostname } });
+ cluster.installApplication({
+ id: 'jupyter',
+ params: { hostname: cluster.store.state.applications.jupyter.hostname },
+ });
expect(cluster.store.state.applications.jupyter.requestStatus).toEqual(REQUEST_LOADING);
expect(cluster.store.state.applications.jupyter.requestReason).toEqual(null);
- expect(cluster.service.installApplication).toHaveBeenCalledWith('jupyter', { hostname: cluster.store.state.applications.jupyter.hostname });
+ expect(cluster.service.installApplication).toHaveBeenCalledWith('jupyter', {
+ hostname: cluster.store.state.applications.jupyter.hostname,
+ });
getSetTimeoutPromise()
- .then(() => {
- expect(cluster.store.state.applications.jupyter.requestStatus).toEqual(REQUEST_SUCCESS);
- expect(cluster.store.state.applications.jupyter.requestReason).toEqual(null);
- })
- .then(done)
- .catch(done.fail);
+ .then(() => {
+ expect(cluster.store.state.applications.jupyter.requestStatus).toEqual(REQUEST_SUCCESS);
+ expect(cluster.store.state.applications.jupyter.requestReason).toEqual(null);
+ })
+ .then(done)
+ .catch(done.fail);
});
- it('sets error request status when the request fails', (done) => {
- spyOn(cluster.service, 'installApplication').and.returnValue(Promise.reject(new Error('STUBBED ERROR')));
+ it('sets error request status when the request fails', done => {
+ spyOn(cluster.service, 'installApplication').and.returnValue(
+ Promise.reject(new Error('STUBBED ERROR')),
+ );
+
expect(cluster.store.state.applications.helm.requestStatus).toEqual(null);
cluster.installApplication({ id: 'helm' });
diff --git a/spec/javascripts/clusters/components/application_row_spec.js b/spec/javascripts/clusters/components/application_row_spec.js
index 9da5c248371..45d56514930 100644
--- a/spec/javascripts/clusters/components/application_row_spec.js
+++ b/spec/javascripts/clusters/components/application_row_spec.js
@@ -112,6 +112,17 @@ describe('Application Row', () => {
expect(vm.installButtonDisabled).toEqual(true);
});
+ it('has disabled "Installed" when APPLICATION_STATUS.UPDATING', () => {
+ vm = mountComponent(ApplicationRow, {
+ ...DEFAULT_APPLICATION_STATE,
+ status: APPLICATION_STATUS.UPDATING,
+ });
+
+ expect(vm.installButtonLabel).toEqual('Installed');
+ expect(vm.installButtonLoading).toEqual(false);
+ expect(vm.installButtonDisabled).toEqual(true);
+ });
+
it('has enabled "Install" when APPLICATION_STATUS.ERROR', () => {
vm = mountComponent(ApplicationRow, {
...DEFAULT_APPLICATION_STATE,
@@ -215,7 +226,9 @@ describe('Application Row', () => {
status: null,
requestStatus: null,
});
- const generalErrorMessage = vm.$el.querySelector('.js-cluster-application-general-error-message');
+ const generalErrorMessage = vm.$el.querySelector(
+ '.js-cluster-application-general-error-message',
+ );
expect(generalErrorMessage).toBeNull();
});
@@ -227,10 +240,17 @@ describe('Application Row', () => {
status: APPLICATION_STATUS.ERROR,
statusReason,
});
- const generalErrorMessage = vm.$el.querySelector('.js-cluster-application-general-error-message');
- const statusErrorMessage = vm.$el.querySelector('.js-cluster-application-status-error-message');
+ const generalErrorMessage = vm.$el.querySelector(
+ '.js-cluster-application-general-error-message',
+ );
+ const statusErrorMessage = vm.$el.querySelector(
+ '.js-cluster-application-status-error-message',
+ );
+
+ expect(generalErrorMessage.textContent.trim()).toEqual(
+ `Something went wrong while installing ${DEFAULT_APPLICATION_STATE.title}`,
+ );
- expect(generalErrorMessage.textContent.trim()).toEqual(`Something went wrong while installing ${DEFAULT_APPLICATION_STATE.title}`);
expect(statusErrorMessage.textContent.trim()).toEqual(statusReason);
});
@@ -242,10 +262,17 @@ describe('Application Row', () => {
requestStatus: REQUEST_FAILURE,
requestReason,
});
- const generalErrorMessage = vm.$el.querySelector('.js-cluster-application-general-error-message');
- const requestErrorMessage = vm.$el.querySelector('.js-cluster-application-request-error-message');
+ const generalErrorMessage = vm.$el.querySelector(
+ '.js-cluster-application-general-error-message',
+ );
+ const requestErrorMessage = vm.$el.querySelector(
+ '.js-cluster-application-request-error-message',
+ );
+
+ expect(generalErrorMessage.textContent.trim()).toEqual(
+ `Something went wrong while installing ${DEFAULT_APPLICATION_STATE.title}`,
+ );
- expect(generalErrorMessage.textContent.trim()).toEqual(`Something went wrong while installing ${DEFAULT_APPLICATION_STATE.title}`);
expect(requestErrorMessage.textContent.trim()).toEqual(requestReason);
});
});
diff --git a/spec/javascripts/clusters/services/mock_data.js b/spec/javascripts/clusters/services/mock_data.js
index c7c1412e1c6..4e6ad11cd92 100644
--- a/spec/javascripts/clusters/services/mock_data.js
+++ b/spec/javascripts/clusters/services/mock_data.js
@@ -6,67 +6,77 @@ const CLUSTERS_MOCK_DATA = {
data: {
status: 'errored',
status_reason: 'Failed to request to CloudPlatform.',
- applications: [{
- name: 'helm',
- status: APPLICATION_STATUS.INSTALLABLE,
- status_reason: null,
- }, {
- name: 'ingress',
- status: APPLICATION_STATUS.ERROR,
- status_reason: 'Cannot connect',
- external_ip: null,
- }, {
- name: 'runner',
- status: APPLICATION_STATUS.INSTALLING,
- status_reason: null,
- },
- {
- name: 'prometheus',
- status: APPLICATION_STATUS.ERROR,
- status_reason: 'Cannot connect',
- }, {
- name: 'jupyter',
- status: APPLICATION_STATUS.INSTALLING,
- status_reason: 'Cannot connect',
- }],
+ applications: [
+ {
+ name: 'helm',
+ status: APPLICATION_STATUS.INSTALLABLE,
+ status_reason: null,
+ },
+ {
+ name: 'ingress',
+ status: APPLICATION_STATUS.ERROR,
+ status_reason: 'Cannot connect',
+ external_ip: null,
+ },
+ {
+ name: 'runner',
+ status: APPLICATION_STATUS.INSTALLING,
+ status_reason: null,
+ },
+ {
+ name: 'prometheus',
+ status: APPLICATION_STATUS.ERROR,
+ status_reason: 'Cannot connect',
+ },
+ {
+ name: 'jupyter',
+ status: APPLICATION_STATUS.INSTALLING,
+ status_reason: 'Cannot connect',
+ },
+ ],
},
},
'/gitlab-org/gitlab-shell/clusters/2/status.json': {
data: {
status: 'errored',
status_reason: 'Failed to request to CloudPlatform.',
- applications: [{
- name: 'helm',
- status: APPLICATION_STATUS.INSTALLED,
- status_reason: null,
- }, {
- name: 'ingress',
- status: APPLICATION_STATUS.INSTALLED,
- status_reason: 'Cannot connect',
- external_ip: '1.1.1.1',
- }, {
- name: 'runner',
- status: APPLICATION_STATUS.INSTALLING,
- status_reason: null,
- },
- {
- name: 'prometheus',
- status: APPLICATION_STATUS.ERROR,
- status_reason: 'Cannot connect',
- }, {
- name: 'jupyter',
- status: APPLICATION_STATUS.INSTALLABLE,
- status_reason: 'Cannot connect',
- }],
+ applications: [
+ {
+ name: 'helm',
+ status: APPLICATION_STATUS.INSTALLED,
+ status_reason: null,
+ },
+ {
+ name: 'ingress',
+ status: APPLICATION_STATUS.INSTALLED,
+ status_reason: 'Cannot connect',
+ external_ip: '1.1.1.1',
+ },
+ {
+ name: 'runner',
+ status: APPLICATION_STATUS.INSTALLING,
+ status_reason: null,
+ },
+ {
+ name: 'prometheus',
+ status: APPLICATION_STATUS.ERROR,
+ status_reason: 'Cannot connect',
+ },
+ {
+ name: 'jupyter',
+ status: APPLICATION_STATUS.INSTALLABLE,
+ status_reason: 'Cannot connect',
+ },
+ ],
},
},
},
POST: {
- '/gitlab-org/gitlab-shell/clusters/1/applications/helm': { },
- '/gitlab-org/gitlab-shell/clusters/1/applications/ingress': { },
- '/gitlab-org/gitlab-shell/clusters/1/applications/runner': { },
- '/gitlab-org/gitlab-shell/clusters/1/applications/prometheus': { },
- '/gitlab-org/gitlab-shell/clusters/1/applications/jupyter': { },
+ '/gitlab-org/gitlab-shell/clusters/1/applications/helm': {},
+ '/gitlab-org/gitlab-shell/clusters/1/applications/ingress': {},
+ '/gitlab-org/gitlab-shell/clusters/1/applications/runner': {},
+ '/gitlab-org/gitlab-shell/clusters/1/applications/prometheus': {},
+ '/gitlab-org/gitlab-shell/clusters/1/applications/jupyter': {},
},
};
@@ -81,7 +91,4 @@ const DEFAULT_APPLICATION_STATE = {
requestReason: null,
};
-export {
- CLUSTERS_MOCK_DATA,
- DEFAULT_APPLICATION_STATE,
-};
+export { CLUSTERS_MOCK_DATA, DEFAULT_APPLICATION_STATE };
diff --git a/spec/javascripts/clusters/stores/clusters_store_spec.js b/spec/javascripts/clusters/stores/clusters_store_spec.js
index 104a064bdd3..e0f55a12fca 100644
--- a/spec/javascripts/clusters/stores/clusters_store_spec.js
+++ b/spec/javascripts/clusters/stores/clusters_store_spec.js
@@ -53,7 +53,8 @@ describe('Clusters Store', () => {
describe('updateStateFromServer', () => {
it('should store new polling data from server', () => {
- const mockResponseData = CLUSTERS_MOCK_DATA.GET['/gitlab-org/gitlab-shell/clusters/1/status.json'].data;
+ const mockResponseData =
+ CLUSTERS_MOCK_DATA.GET['/gitlab-org/gitlab-shell/clusters/1/status.json'].data;
store.updateStateFromServer(mockResponseData);
expect(store.state).toEqual({
@@ -104,13 +105,14 @@ describe('Clusters Store', () => {
});
it('sets default hostname for jupyter when ingress has a ip address', () => {
- const mockResponseData = CLUSTERS_MOCK_DATA.GET['/gitlab-org/gitlab-shell/clusters/2/status.json'].data;
+ const mockResponseData =
+ CLUSTERS_MOCK_DATA.GET['/gitlab-org/gitlab-shell/clusters/2/status.json'].data;
store.updateStateFromServer(mockResponseData);
- expect(
- store.state.applications.jupyter.hostname,
- ).toEqual(`jupyter.${store.state.applications.ingress.externalIp}.nip.io`);
+ expect(store.state.applications.jupyter.hostname).toEqual(
+ `jupyter.${store.state.applications.ingress.externalIp}.nip.io`,
+ );
});
});
});
diff --git a/spec/javascripts/collapsed_sidebar_todo_spec.js b/spec/javascripts/collapsed_sidebar_todo_spec.js
index 8427e8a0ba7..dc5737558c0 100644
--- a/spec/javascripts/collapsed_sidebar_todo_spec.js
+++ b/spec/javascripts/collapsed_sidebar_todo_spec.js
@@ -18,10 +18,8 @@ describe('Issuable right sidebar collapsed todo toggle', () => {
new Sidebar();
loadFixtures(fixtureName);
- document.querySelector('.js-right-sidebar')
- .classList.toggle('right-sidebar-expanded');
- document.querySelector('.js-right-sidebar')
- .classList.toggle('right-sidebar-collapsed');
+ document.querySelector('.js-right-sidebar').classList.toggle('right-sidebar-expanded');
+ document.querySelector('.js-right-sidebar').classList.toggle('right-sidebar-collapsed');
mock = new MockAdapter(axios);
@@ -44,13 +42,13 @@ describe('Issuable right sidebar collapsed todo toggle', () => {
});
it('shows add todo button', () => {
- expect(
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon'),
- ).not.toBeNull();
+ expect(document.querySelector('.js-issuable-todo.sidebar-collapsed-icon')).not.toBeNull();
expect(
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .fa-plus-square'),
- ).not.toBeNull();
+ document
+ .querySelector('.js-issuable-todo.sidebar-collapsed-icon svg use')
+ .getAttribute('xlink:href'),
+ ).toContain('todo-add');
expect(
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .todo-undone'),
@@ -63,7 +61,7 @@ describe('Issuable right sidebar collapsed todo toggle', () => {
).toBe('Add todo');
});
- it('toggle todo state', (done) => {
+ it('toggle todo state', done => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
setTimeout(() => {
@@ -72,14 +70,16 @@ describe('Issuable right sidebar collapsed todo toggle', () => {
).not.toBeNull();
expect(
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon .fa-check-square'),
- ).not.toBeNull();
+ document
+ .querySelector('.js-issuable-todo.sidebar-collapsed-icon svg.todo-undone use')
+ .getAttribute('xlink:href'),
+ ).toContain('todo-done');
done();
});
});
- it('toggle todo state of expanded todo toggle', (done) => {
+ it('toggle todo state of expanded todo toggle', done => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
setTimeout(() => {
@@ -91,19 +91,21 @@ describe('Issuable right sidebar collapsed todo toggle', () => {
});
});
- it('toggles todo button tooltip', (done) => {
+ it('toggles todo button tooltip', done => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
setTimeout(() => {
expect(
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('data-original-title'),
+ document
+ .querySelector('.js-issuable-todo.sidebar-collapsed-icon')
+ .getAttribute('data-original-title'),
).toBe('Mark todo as done');
done();
});
});
- it('marks todo as done', (done) => {
+ it('marks todo as done', done => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
timeoutPromise()
@@ -128,25 +130,29 @@ describe('Issuable right sidebar collapsed todo toggle', () => {
.catch(done.fail);
});
- it('updates aria-label to mark todo as done', (done) => {
+ it('updates aria-label to mark todo as done', done => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
setTimeout(() => {
expect(
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('aria-label'),
+ document
+ .querySelector('.js-issuable-todo.sidebar-collapsed-icon')
+ .getAttribute('aria-label'),
).toBe('Mark todo as done');
done();
});
});
- it('updates aria-label to add todo', (done) => {
+ it('updates aria-label to add todo', done => {
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
timeoutPromise()
.then(() => {
expect(
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('aria-label'),
+ document
+ .querySelector('.js-issuable-todo.sidebar-collapsed-icon')
+ .getAttribute('aria-label'),
).toBe('Mark todo as done');
document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').click();
@@ -154,7 +160,9 @@ describe('Issuable right sidebar collapsed todo toggle', () => {
.then(timeoutPromise)
.then(() => {
expect(
- document.querySelector('.js-issuable-todo.sidebar-collapsed-icon').getAttribute('aria-label'),
+ document
+ .querySelector('.js-issuable-todo.sidebar-collapsed-icon')
+ .getAttribute('aria-label'),
).toBe('Add todo');
})
.then(done)
diff --git a/spec/javascripts/comment_type_toggle_spec.js b/spec/javascripts/comment_type_toggle_spec.js
index 0ba709298c5..8b1217a000f 100644
--- a/spec/javascripts/comment_type_toggle_spec.js
+++ b/spec/javascripts/comment_type_toggle_spec.js
@@ -1,9 +1,9 @@
import CommentTypeToggle from '~/comment_type_toggle';
import InputSetter from '~/droplab/plugins/input_setter';
-describe('CommentTypeToggle', function () {
- describe('class constructor', function () {
- beforeEach(function () {
+describe('CommentTypeToggle', function() {
+ describe('class constructor', function() {
+ beforeEach(function() {
this.dropdownTrigger = {};
this.dropdownList = {};
this.noteTypeInput = {};
@@ -19,33 +19,33 @@ describe('CommentTypeToggle', function () {
});
});
- it('should set .dropdownTrigger', function () {
+ it('should set .dropdownTrigger', function() {
expect(this.commentTypeToggle.dropdownTrigger).toBe(this.dropdownTrigger);
});
- it('should set .dropdownList', function () {
+ it('should set .dropdownList', function() {
expect(this.commentTypeToggle.dropdownList).toBe(this.dropdownList);
});
- it('should set .noteTypeInput', function () {
+ it('should set .noteTypeInput', function() {
expect(this.commentTypeToggle.noteTypeInput).toBe(this.noteTypeInput);
});
- it('should set .submitButton', function () {
+ it('should set .submitButton', function() {
expect(this.commentTypeToggle.submitButton).toBe(this.submitButton);
});
- it('should set .closeButton', function () {
+ it('should set .closeButton', function() {
expect(this.commentTypeToggle.closeButton).toBe(this.closeButton);
});
- it('should set .reopenButton', function () {
+ it('should set .reopenButton', function() {
expect(this.commentTypeToggle.reopenButton).toBe(this.reopenButton);
});
});
- describe('initDroplab', function () {
- beforeEach(function () {
+ describe('initDroplab', function() {
+ beforeEach(function() {
this.commentTypeToggle = {
dropdownTrigger: {},
dropdownList: {},
@@ -58,25 +58,27 @@ describe('CommentTypeToggle', function () {
this.droplab = jasmine.createSpyObj('droplab', ['init']);
- this.droplabConstructor = spyOnDependency(CommentTypeToggle, 'DropLab').and.returnValue(this.droplab);
+ this.droplabConstructor = spyOnDependency(CommentTypeToggle, 'DropLab').and.returnValue(
+ this.droplab,
+ );
spyOn(this.commentTypeToggle, 'setConfig').and.returnValue(this.config);
CommentTypeToggle.prototype.initDroplab.call(this.commentTypeToggle);
});
- it('should instantiate a DropLab instance', function () {
+ it('should instantiate a DropLab instance', function() {
expect(this.droplabConstructor).toHaveBeenCalled();
});
- it('should set .droplab', function () {
+ it('should set .droplab', function() {
expect(this.commentTypeToggle.droplab).toBe(this.droplab);
});
- it('should call .setConfig', function () {
+ it('should call .setConfig', function() {
expect(this.commentTypeToggle.setConfig).toHaveBeenCalled();
});
- it('should call DropLab.prototype.init', function () {
+ it('should call DropLab.prototype.init', function() {
expect(this.droplab.init).toHaveBeenCalledWith(
this.commentTypeToggle.dropdownTrigger,
this.commentTypeToggle.dropdownList,
@@ -86,9 +88,9 @@ describe('CommentTypeToggle', function () {
});
});
- describe('setConfig', function () {
- describe('if no .closeButton is provided', function () {
- beforeEach(function () {
+ describe('setConfig', function() {
+ describe('if no .closeButton is provided', function() {
+ beforeEach(function() {
this.commentTypeToggle = {
dropdownTrigger: {},
dropdownList: {},
@@ -100,28 +102,33 @@ describe('CommentTypeToggle', function () {
this.setConfig = CommentTypeToggle.prototype.setConfig.call(this.commentTypeToggle);
});
- it('should not add .closeButton related InputSetter config', function () {
+ it('should not add .closeButton related InputSetter config', function() {
expect(this.setConfig).toEqual({
- InputSetter: [{
- input: this.commentTypeToggle.noteTypeInput,
- valueAttribute: 'data-value',
- }, {
- input: this.commentTypeToggle.submitButton,
- valueAttribute: 'data-submit-text',
- }, {
- input: this.commentTypeToggle.reopenButton,
- valueAttribute: 'data-reopen-text',
- }, {
- input: this.commentTypeToggle.reopenButton,
- valueAttribute: 'data-reopen-text',
- inputAttribute: 'data-alternative-text',
- }],
+ InputSetter: [
+ {
+ input: this.commentTypeToggle.noteTypeInput,
+ valueAttribute: 'data-value',
+ },
+ {
+ input: this.commentTypeToggle.submitButton,
+ valueAttribute: 'data-submit-text',
+ },
+ {
+ input: this.commentTypeToggle.reopenButton,
+ valueAttribute: 'data-reopen-text',
+ },
+ {
+ input: this.commentTypeToggle.reopenButton,
+ valueAttribute: 'data-reopen-text',
+ inputAttribute: 'data-alternative-text',
+ },
+ ],
});
});
});
- describe('if no .reopenButton is provided', function () {
- beforeEach(function () {
+ describe('if no .reopenButton is provided', function() {
+ beforeEach(function() {
this.commentTypeToggle = {
dropdownTrigger: {},
dropdownList: {},
@@ -133,22 +140,27 @@ describe('CommentTypeToggle', function () {
this.setConfig = CommentTypeToggle.prototype.setConfig.call(this.commentTypeToggle);
});
- it('should not add .reopenButton related InputSetter config', function () {
+ it('should not add .reopenButton related InputSetter config', function() {
expect(this.setConfig).toEqual({
- InputSetter: [{
- input: this.commentTypeToggle.noteTypeInput,
- valueAttribute: 'data-value',
- }, {
- input: this.commentTypeToggle.submitButton,
- valueAttribute: 'data-submit-text',
- }, {
- input: this.commentTypeToggle.closeButton,
- valueAttribute: 'data-close-text',
- }, {
- input: this.commentTypeToggle.closeButton,
- valueAttribute: 'data-close-text',
- inputAttribute: 'data-alternative-text',
- }],
+ InputSetter: [
+ {
+ input: this.commentTypeToggle.noteTypeInput,
+ valueAttribute: 'data-value',
+ },
+ {
+ input: this.commentTypeToggle.submitButton,
+ valueAttribute: 'data-submit-text',
+ },
+ {
+ input: this.commentTypeToggle.closeButton,
+ valueAttribute: 'data-close-text',
+ },
+ {
+ input: this.commentTypeToggle.closeButton,
+ valueAttribute: 'data-close-text',
+ inputAttribute: 'data-alternative-text',
+ },
+ ],
});
});
});
diff --git a/spec/javascripts/commit/commit_pipeline_status_component_spec.js b/spec/javascripts/commit/commit_pipeline_status_component_spec.js
index d3776d0c3cf..4fc56fd9a27 100644
--- a/spec/javascripts/commit/commit_pipeline_status_component_spec.js
+++ b/spec/javascripts/commit/commit_pipeline_status_component_spec.js
@@ -26,15 +26,18 @@ describe('Commit pipeline status component', () => {
beforeEach(() => {
mock = new MockAdapter(axios);
mock.onGet('/dummy/endpoint').reply(() => {
- const res = Promise.resolve([200, {
- pipelines: [
- {
- details: {
- status: mockCiStatus,
+ const res = Promise.resolve([
+ 200,
+ {
+ pipelines: [
+ {
+ details: {
+ status: mockCiStatus,
+ },
},
- },
- ],
- }]);
+ ],
+ },
+ ]);
return res;
});
vm = mountComponent(Component, {
@@ -48,7 +51,7 @@ describe('Commit pipeline status component', () => {
mock.restore();
});
- it('shows the loading icon when polling is starting', (done) => {
+ it('shows the loading icon when polling is starting', done => {
expect(vm.$el.querySelector('.loading-container')).not.toBe(null);
setTimeout(() => {
expect(vm.$el.querySelector('.loading-container')).toBe(null);
@@ -56,17 +59,19 @@ describe('Commit pipeline status component', () => {
});
});
- it('contains a ciStatus when the polling is succesful ', (done) => {
+ it('contains a ciStatus when the polling is succesful ', done => {
setTimeout(() => {
expect(vm.ciStatus).toEqual(mockCiStatus);
done();
});
});
- it('contains a ci-status icon when polling is succesful', (done) => {
+ it('contains a ci-status icon when polling is succesful', done => {
setTimeout(() => {
expect(vm.$el.querySelector('.ci-status-icon')).not.toBe(null);
- expect(vm.$el.querySelector('.ci-status-icon').classList).toContain(`ci-status-icon-${mockCiStatus.group}`);
+ expect(vm.$el.querySelector('.ci-status-icon').classList).toContain(
+ `ci-status-icon-${mockCiStatus.group}`,
+ );
done();
});
});
@@ -89,7 +94,7 @@ describe('Commit pipeline status component', () => {
mock.restore();
});
- it('calls an errorCallback', (done) => {
+ it('calls an errorCallback', done => {
spyOn(vm, 'errorCallback').and.callThrough();
vm.$mount();
setTimeout(() => {
diff --git a/spec/javascripts/commit/pipelines/pipelines_spec.js b/spec/javascripts/commit/pipelines/pipelines_spec.js
index a18e09da50a..b797cc44ae7 100644
--- a/spec/javascripts/commit/pipelines/pipelines_spec.js
+++ b/spec/javascripts/commit/pipelines/pipelines_spec.js
@@ -4,7 +4,7 @@ import axios from '~/lib/utils/axios_utils';
import pipelinesTable from '~/commit/pipelines/pipelines_table.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
-describe('Pipelines table in Commits and Merge requests', function () {
+describe('Pipelines table in Commits and Merge requests', function() {
const jsonFixtureName = 'pipelines/pipelines.json';
let pipeline;
let PipelinesTable;
@@ -29,7 +29,7 @@ describe('Pipelines table in Commits and Merge requests', function () {
describe('successful request', () => {
describe('without pipelines', () => {
- beforeEach(function () {
+ beforeEach(function() {
mock.onGet('endpoint.json').reply(200, []);
vm = mountComponent(PipelinesTable, {
@@ -41,7 +41,7 @@ describe('Pipelines table in Commits and Merge requests', function () {
});
});
- it('should render the empty state', function (done) {
+ it('should render the empty state', function(done) {
setTimeout(() => {
expect(vm.$el.querySelector('.empty-state')).toBeDefined();
expect(vm.$el.querySelector('.realtime-loading')).toBe(null);
@@ -63,7 +63,7 @@ describe('Pipelines table in Commits and Merge requests', function () {
});
});
- it('should render a table with the received pipelines', (done) => {
+ it('should render a table with the received pipelines', done => {
setTimeout(() => {
expect(vm.$el.querySelectorAll('.ci-table .commit').length).toEqual(1);
expect(vm.$el.querySelector('.realtime-loading')).toBe(null);
@@ -79,11 +79,11 @@ describe('Pipelines table in Commits and Merge requests', function () {
mock.onGet('endpoint.json').reply(200, [pipeline]);
});
- it('should receive update-pipelines-count event', (done) => {
+ it('should receive update-pipelines-count event', done => {
const element = document.createElement('div');
document.body.appendChild(element);
- element.addEventListener('update-pipelines-count', (event) => {
+ element.addEventListener('update-pipelines-count', event => {
expect(event.detail.pipelines).toEqual([pipeline]);
done();
});
@@ -114,7 +114,7 @@ describe('Pipelines table in Commits and Merge requests', function () {
});
});
- it('should render error state', function (done) {
+ it('should render error state', function(done) {
setTimeout(() => {
expect(vm.$el.querySelector('.js-pipelines-error-state')).toBeDefined();
expect(vm.$el.querySelector('.realtime-loading')).toBe(null);
diff --git a/spec/javascripts/commit_merge_requests_spec.js b/spec/javascripts/commit_merge_requests_spec.js
index 3466ef51ea8..82968e028d1 100644
--- a/spec/javascripts/commit_merge_requests_spec.js
+++ b/spec/javascripts/commit_merge_requests_spec.js
@@ -3,11 +3,16 @@ import * as CommitMergeRequests from '~/commit_merge_requests';
describe('CommitMergeRequests', () => {
describe('createContent', () => {
it('should return created content', () => {
- const content1 = CommitMergeRequests.createContent([{ iid: 1, path: '/path1', title: 'foo' }, { iid: 2, path: '/path2', title: 'baz' }])[0];
+ const content1 = CommitMergeRequests.createContent([
+ { iid: 1, path: '/path1', title: 'foo' },
+ { iid: 2, path: '/path2', title: 'baz' },
+ ])[0];
+
expect(content1.tagName).toEqual('SPAN');
expect(content1.childElementCount).toEqual(4);
const content2 = CommitMergeRequests.createContent([])[0];
+
expect(content2.tagName).toEqual('SPAN');
expect(content2.childElementCount).toEqual(0);
expect(content2.innerText).toEqual('No related merge requests found');
@@ -26,6 +31,7 @@ describe('CommitMergeRequests', () => {
describe('createHeader', () => {
it('should return created header', () => {
const header = CommitMergeRequests.createHeader(0, 1)[0];
+
expect(header.tagName).toEqual('SPAN');
expect(header.innerText).toEqual('1 merge request');
});
@@ -34,6 +40,7 @@ describe('CommitMergeRequests', () => {
describe('createItem', () => {
it('should return created item', () => {
const item = CommitMergeRequests.createItem({ iid: 1, path: '/path', title: 'foo' })[0];
+
expect(item.tagName).toEqual('SPAN');
expect(item.childElementCount).toEqual(2);
expect(item.children[0].tagName).toEqual('A');
@@ -44,6 +51,7 @@ describe('CommitMergeRequests', () => {
describe('createLink', () => {
it('should return created link', () => {
const link = CommitMergeRequests.createLink({ iid: 1, path: '/path', title: 'foo' })[0];
+
expect(link.tagName).toEqual('A');
expect(link.href).toMatch(/\/path$/);
expect(link.innerText).toEqual('!1');
@@ -53,6 +61,7 @@ describe('CommitMergeRequests', () => {
describe('createTitle', () => {
it('should return created title', () => {
const title = CommitMergeRequests.createTitle({ iid: 1, path: '/path', title: 'foo' })[0];
+
expect(title.tagName).toEqual('SPAN');
expect(title.innerText).toEqual('foo');
});
diff --git a/spec/javascripts/create_item_dropdown_spec.js b/spec/javascripts/create_item_dropdown_spec.js
index ee26122be12..9cf72d7c55b 100644
--- a/spec/javascripts/create_item_dropdown_spec.js
+++ b/spec/javascripts/create_item_dropdown_spec.js
@@ -1,19 +1,23 @@
import $ from 'jquery';
import CreateItemDropdown from '~/create_item_dropdown';
-const DROPDOWN_ITEM_DATA = [{
- title: 'one',
- id: 'one',
- text: 'one',
-}, {
- title: 'two',
- id: 'two',
- text: 'two',
-}, {
- title: 'three',
- id: 'three',
- text: 'three',
-}];
+const DROPDOWN_ITEM_DATA = [
+ {
+ title: 'one',
+ id: 'one',
+ text: 'one',
+ },
+ {
+ title: 'two',
+ id: 'two',
+ text: 'two',
+ },
+ {
+ title: 'three',
+ id: 'three',
+ text: 'three',
+ },
+];
describe('CreateItemDropdown', () => {
preloadFixtures('static/create_item_dropdown.html.raw');
@@ -23,7 +27,8 @@ describe('CreateItemDropdown', () => {
function createItemAndClearInput(text) {
// Filter for the new item
- $wrapperEl.find('.dropdown-input-field')
+ $wrapperEl
+ .find('.dropdown-input-field')
.val(text)
.trigger('input');
@@ -32,7 +37,8 @@ describe('CreateItemDropdown', () => {
$createButton.click();
// Clear out the filter
- $wrapperEl.find('.dropdown-input-field')
+ $wrapperEl
+ .find('.dropdown-input-field')
.val('')
.trigger('input');
}
@@ -63,6 +69,7 @@ describe('CreateItemDropdown', () => {
$('.js-dropdown-menu-toggle').click();
const $itemEls = $wrapperEl.find('.js-dropdown-content a');
+
expect($itemEls.length).toEqual(DROPDOWN_ITEM_DATA.length);
});
});
@@ -84,7 +91,8 @@ describe('CreateItemDropdown', () => {
$('.js-dropdown-menu-toggle').click();
// Filter for the new item
- $wrapperEl.find('.dropdown-input-field')
+ $wrapperEl
+ .find('.dropdown-input-field')
.val(NEW_ITEM_TEXT)
.trigger('input');
});
@@ -106,6 +114,7 @@ describe('CreateItemDropdown', () => {
createItemAndClearInput(NEW_ITEM_TEXT);
const $itemEls = $wrapperEl.find('.js-dropdown-content a');
+
expect($itemEls.length).toEqual(1 + DROPDOWN_ITEM_DATA.length);
expect($($itemEls.get(DROPDOWN_ITEM_DATA.length)).text()).toEqual(NEW_ITEM_TEXT);
});
@@ -114,6 +123,7 @@ describe('CreateItemDropdown', () => {
createItemAndClearInput(DROPDOWN_ITEM_DATA[0].text);
const $itemEls = $wrapperEl.find('.js-dropdown-content a');
+
expect($itemEls.length).toEqual(DROPDOWN_ITEM_DATA.length);
});
});
@@ -137,16 +147,16 @@ describe('CreateItemDropdown', () => {
$('.js-dropdown-menu-toggle').click();
// Filter for an item
- filterInput
- .val('one')
- .trigger('input');
+ filterInput.val('one').trigger('input');
const $itemElsAfterFilter = $wrapperEl.find('.js-dropdown-content a');
+
expect($itemElsAfterFilter.length).toEqual(1);
createItemDropdown.clearDropdown();
const $itemElsAfterClear = $wrapperEl.find('.js-dropdown-content a');
+
expect($itemElsAfterClear.length).toEqual(0);
expect(filterInput.val()).toEqual('');
});
@@ -176,6 +186,7 @@ describe('CreateItemDropdown', () => {
createItemAndClearInput('new-item');
const $itemEls = $wrapperEl.find('.js-dropdown-content a');
+
expect($itemEls.length).toEqual(1 + DROPDOWN_ITEM_DATA.length);
expect($($itemEls[3]).text()).toEqual('new-item-text');
expect($wrapperEl.find('.dropdown-toggle-text').text()).toEqual('new-item-title');
diff --git a/spec/javascripts/create_merge_request_dropdown_spec.js b/spec/javascripts/create_merge_request_dropdown_spec.js
index b229765a8c5..00fe3f451f5 100644
--- a/spec/javascripts/create_merge_request_dropdown_spec.js
+++ b/spec/javascripts/create_merge_request_dropdown_spec.js
@@ -59,6 +59,7 @@ describe('CreateMergeRequestDropdown', () => {
expect(dropdown.createBranchPath).toBe(
`${TEST_HOST}/branches?branch_name=contains%23hash&issue=42`,
);
+
expect(dropdown.createMrPath).toBe(
`${TEST_HOST}/create_merge_request?branch_name=contains%23hash&ref=master`,
);
diff --git a/spec/javascripts/cycle_analytics/banner_spec.js b/spec/javascripts/cycle_analytics/banner_spec.js
index 2815bdba0c2..3ce2c3c4f06 100644
--- a/spec/javascripts/cycle_analytics/banner_spec.js
+++ b/spec/javascripts/cycle_analytics/banner_spec.js
@@ -17,19 +17,20 @@ describe('Cycle analytics banner', () => {
});
it('should render cycle analytics information', () => {
- expect(
- vm.$el.querySelector('h4').textContent.trim(),
- ).toEqual('Introducing Cycle Analytics');
+ expect(vm.$el.querySelector('h4').textContent.trim()).toEqual('Introducing Cycle Analytics');
expect(
- vm.$el.querySelector('p').textContent.trim().replace(/[\r\n]+/g, ' '),
- ).toContain('Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.');
- expect(
- vm.$el.querySelector('a').textContent.trim(),
- ).toEqual('Read more');
- expect(
- vm.$el.querySelector('a').getAttribute('href'),
- ).toEqual('path');
+ vm.$el
+ .querySelector('p')
+ .textContent.trim()
+ .replace(/[\r\n]+/g, ' '),
+ ).toContain(
+ 'Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.',
+ );
+
+ expect(vm.$el.querySelector('a').textContent.trim()).toEqual('Read more');
+
+ expect(vm.$el.querySelector('a').getAttribute('href')).toEqual('path');
});
it('should emit an event when close button is clicked', () => {
diff --git a/spec/javascripts/datetime_utility_spec.js b/spec/javascripts/datetime_utility_spec.js
deleted file mode 100644
index 6c3e73f134e..00000000000
--- a/spec/javascripts/datetime_utility_spec.js
+++ /dev/null
@@ -1,183 +0,0 @@
-import * as datetimeUtility from '~/lib/utils/datetime_utility';
-
-describe('Date time utils', () => {
- describe('timeFor', () => {
- it('returns `past due` when in past', () => {
- const date = new Date();
- date.setFullYear(date.getFullYear() - 1);
-
- expect(datetimeUtility.timeFor(date)).toBe('Past due');
- });
-
- it('returns remaining time when in the future', () => {
- const date = new Date();
- date.setFullYear(date.getFullYear() + 1);
-
- // Add a day to prevent a transient error. If date is even 1 second
- // short of a full year, timeFor will return '11 months remaining'
- date.setDate(date.getDate() + 1);
-
- expect(datetimeUtility.timeFor(date)).toBe('1 year remaining');
- });
- });
-
- describe('get day name', () => {
- it('should return Sunday', () => {
- const day = datetimeUtility.getDayName(new Date('07/17/2016'));
- expect(day).toBe('Sunday');
- });
-
- it('should return Monday', () => {
- const day = datetimeUtility.getDayName(new Date('07/18/2016'));
- expect(day).toBe('Monday');
- });
-
- it('should return Tuesday', () => {
- const day = datetimeUtility.getDayName(new Date('07/19/2016'));
- expect(day).toBe('Tuesday');
- });
-
- it('should return Wednesday', () => {
- const day = datetimeUtility.getDayName(new Date('07/20/2016'));
- expect(day).toBe('Wednesday');
- });
-
- it('should return Thursday', () => {
- const day = datetimeUtility.getDayName(new Date('07/21/2016'));
- expect(day).toBe('Thursday');
- });
-
- it('should return Friday', () => {
- const day = datetimeUtility.getDayName(new Date('07/22/2016'));
- expect(day).toBe('Friday');
- });
-
- it('should return Saturday', () => {
- const day = datetimeUtility.getDayName(new Date('07/23/2016'));
- expect(day).toBe('Saturday');
- });
- });
-
- describe('get day difference', () => {
- it('should return 7', () => {
- const firstDay = new Date('07/01/2016');
- const secondDay = new Date('07/08/2016');
- const difference = datetimeUtility.getDayDifference(firstDay, secondDay);
- expect(difference).toBe(7);
- });
-
- it('should return 31', () => {
- const firstDay = new Date('07/01/2016');
- const secondDay = new Date('08/01/2016');
- const difference = datetimeUtility.getDayDifference(firstDay, secondDay);
- expect(difference).toBe(31);
- });
-
- it('should return 365', () => {
- const firstDay = new Date('07/02/2015');
- const secondDay = new Date('07/01/2016');
- const difference = datetimeUtility.getDayDifference(firstDay, secondDay);
- expect(difference).toBe(365);
- });
- });
-});
-
-describe('timeIntervalInWords', () => {
- it('should return string with number of minutes and seconds', () => {
- expect(datetimeUtility.timeIntervalInWords(9.54)).toEqual('9 seconds');
- expect(datetimeUtility.timeIntervalInWords(1)).toEqual('1 second');
- expect(datetimeUtility.timeIntervalInWords(200)).toEqual('3 minutes 20 seconds');
- expect(datetimeUtility.timeIntervalInWords(6008)).toEqual('100 minutes 8 seconds');
- });
-});
-
-describe('dateInWords', () => {
- const date = new Date('07/01/2016');
-
- it('should return date in words', () => {
- expect(datetimeUtility.dateInWords(date)).toEqual('July 1, 2016');
- });
-
- it('should return abbreviated month name', () => {
- expect(datetimeUtility.dateInWords(date, true)).toEqual('Jul 1, 2016');
- });
-
- it('should return date in words without year', () => {
- expect(datetimeUtility.dateInWords(date, true, true)).toEqual('Jul 1');
- });
-});
-
-describe('monthInWords', () => {
- const date = new Date('2017-01-20');
-
- it('returns month name from provided date', () => {
- expect(datetimeUtility.monthInWords(date)).toBe('January');
- });
-
- it('returns abbreviated month name from provided date', () => {
- expect(datetimeUtility.monthInWords(date, true)).toBe('Jan');
- });
-});
-
-describe('totalDaysInMonth', () => {
- it('returns number of days in a month for given date', () => {
- // 1st Feb, 2016 (leap year)
- expect(datetimeUtility.totalDaysInMonth(new Date(2016, 1, 1))).toBe(29);
-
- // 1st Feb, 2017
- expect(datetimeUtility.totalDaysInMonth(new Date(2017, 1, 1))).toBe(28);
-
- // 1st Jan, 2017
- expect(datetimeUtility.totalDaysInMonth(new Date(2017, 0, 1))).toBe(31);
- });
-});
-
-describe('getSundays', () => {
- it('returns array of dates representing all Sundays of the month', () => {
- // December, 2017 (it has 5 Sundays)
- const dateOfSundays = [3, 10, 17, 24, 31];
- const sundays = datetimeUtility.getSundays(new Date(2017, 11, 1));
-
- expect(sundays.length).toBe(5);
- sundays.forEach((sunday, index) => {
- expect(sunday.getDate()).toBe(dateOfSundays[index]);
- });
- });
-});
-
-describe('getTimeframeWindowFrom', () => {
- it('returns array of date objects upto provided length start with provided startDate', () => {
- const startDate = new Date(2018, 0, 1);
- const mockTimeframe = [
- new Date(2018, 0, 1),
- new Date(2018, 1, 1),
- new Date(2018, 2, 1),
- new Date(2018, 3, 1),
- new Date(2018, 4, 31),
- ];
- const timeframe = datetimeUtility.getTimeframeWindowFrom(startDate, 5);
- expect(timeframe.length).toBe(5);
- timeframe.forEach((timeframeItem, index) => {
- expect(timeframeItem.getFullYear() === mockTimeframe[index].getFullYear()).toBe(true);
- expect(timeframeItem.getMonth() === mockTimeframe[index].getMonth()).toBe(true);
- expect(timeframeItem.getDate() === mockTimeframe[index].getDate()).toBeTruthy();
- });
- });
-});
-
-describe('formatTime', () => {
- const expectedTimestamps = [
- [0, '00:00:00'],
- [1000, '00:00:01'],
- [42000, '00:00:42'],
- [121000, '00:02:01'],
- [10921000, '03:02:01'],
- [108000000, '30:00:00'],
- ];
-
- expectedTimestamps.forEach(([milliseconds, expectedTimestamp]) => {
- it(`formats ${milliseconds}ms as ${expectedTimestamp}`, () => {
- expect(datetimeUtility.formatTime(milliseconds)).toBe(expectedTimestamp);
- });
- });
-});
diff --git a/spec/javascripts/deploy_keys/components/app_spec.js b/spec/javascripts/deploy_keys/components/app_spec.js
index cd147bb2935..f81c0cb7124 100644
--- a/spec/javascripts/deploy_keys/components/app_spec.js
+++ b/spec/javascripts/deploy_keys/components/app_spec.js
@@ -10,7 +10,7 @@ describe('Deploy keys app component', () => {
let vm;
let mock;
- beforeEach((done) => {
+ beforeEach(done => {
// set up axios mock before component
mock = new MockAdapter(axios);
mock.onGet(`${TEST_HOST}/dummy/`).replyOnce(200, data);
@@ -60,6 +60,7 @@ describe('Deploy keys app component', () => {
expect(textContent('.js-deployKeys-tab-available_project_keys')).toContain(
'Privately accessible deploy keys',
);
+
expect(textContent('.js-deployKeys-tab-public_keys')).toContain(
'Publicly accessible deploy keys',
);
@@ -67,9 +68,11 @@ describe('Deploy keys app component', () => {
expect(textContent('.js-deployKeys-tab-enabled_keys .badge')).toBe(
`${vm.store.keys.enabled_keys.length}`,
);
+
expect(textContent('.js-deployKeys-tab-available_project_keys .badge')).toBe(
`${vm.store.keys.available_project_keys.length}`,
);
+
expect(textContent('.js-deployKeys-tab-public_keys .badge')).toBe(
`${vm.store.keys.public_keys.length}`,
);
diff --git a/spec/javascripts/deploy_keys/components/key_spec.js b/spec/javascripts/deploy_keys/components/key_spec.js
index d1de9d132b8..7117dc4a9ee 100644
--- a/spec/javascripts/deploy_keys/components/key_spec.js
+++ b/spec/javascripts/deploy_keys/components/key_spec.js
@@ -82,6 +82,7 @@ describe('Deploy keys key', () => {
it('shows expandable button if more than two projects', () => {
const labels = vm.$el.querySelectorAll('.deploy-project-label');
+
expect(labels.length).toBe(2);
expect(labels[1].textContent).toContain('others');
expect(labels[1].getAttribute('data-original-title')).toContain('Expand');
@@ -93,6 +94,7 @@ describe('Deploy keys key', () => {
Vue.nextTick(() => {
const labels = vm.$el.querySelectorAll('.deploy-project-label');
+
expect(labels.length).toBe(length);
expect(labels[1].textContent).not.toContain(`+${length} others`);
expect(labels[1].getAttribute('data-original-title')).not.toContain('Expand');
@@ -105,6 +107,7 @@ describe('Deploy keys key', () => {
Vue.nextTick(() => {
const labels = vm.$el.querySelectorAll('.deploy-project-label');
+
expect(labels.length).toBe(2);
expect(labels[1].textContent).toContain(
vm.deployKey.deploy_keys_projects[1].project.full_name,
diff --git a/spec/javascripts/diff_comments_store_spec.js b/spec/javascripts/diff_comments_store_spec.js
index c6f2e66cebd..a6d363ce88e 100644
--- a/spec/javascripts/diff_comments_store_spec.js
+++ b/spec/javascripts/diff_comments_store_spec.js
@@ -26,6 +26,7 @@ describe('New discussion', () => {
it('creates new discussion', () => {
expect(Object.keys(CommentsStore.state).length).toBe(0);
createDiscussion();
+
expect(Object.keys(CommentsStore.state).length).toBe(1);
});
@@ -34,6 +35,7 @@ describe('New discussion', () => {
createDiscussion(2);
const discussion = CommentsStore.state['a'];
+
expect(Object.keys(discussion.notes).length).toBe(2);
});
});
@@ -46,6 +48,7 @@ describe('Get note', () => {
it('gets note by ID', () => {
const note = CommentsStore.get('a', 1);
+
expect(note).toBeDefined();
expect(note.id).toBe(1);
});
@@ -59,17 +62,20 @@ describe('Delete discussion', () => {
it('deletes discussion by ID', () => {
CommentsStore.delete('a', 1);
+
expect(Object.keys(CommentsStore.state).length).toBe(0);
});
it('deletes discussion when no more notes', () => {
createDiscussion();
createDiscussion(2);
+
expect(Object.keys(CommentsStore.state).length).toBe(1);
expect(Object.keys(CommentsStore.state['a'].notes).length).toBe(2);
CommentsStore.delete('a', 1);
CommentsStore.delete('a', 2);
+
expect(Object.keys(CommentsStore.state).length).toBe(0);
});
});
@@ -84,6 +90,7 @@ describe('Update note', () => {
CommentsStore.update('a', 1, false, 'test');
const note = CommentsStore.get('a', 1);
+
expect(note.resolved).toBe(false);
});
});
@@ -96,6 +103,7 @@ describe('Discussion resolved', () => {
it('is resolved with single note', () => {
const discussion = CommentsStore.state['a'];
+
expect(discussion.isResolved()).toBe(true);
});
@@ -118,6 +126,7 @@ describe('Discussion resolved', () => {
createDiscussion(2, false);
discussion.resolveAllNotes();
+
expect(discussion.isResolved()).toBe(true);
});
@@ -126,6 +135,7 @@ describe('Discussion resolved', () => {
createDiscussion(2);
discussion.unResolveAllNotes();
+
expect(discussion.isResolved()).toBe(false);
});
});
diff --git a/spec/javascripts/diffs/components/app_spec.js b/spec/javascripts/diffs/components/app_spec.js
index a3a714678af..3c9b5ee0176 100644
--- a/spec/javascripts/diffs/components/app_spec.js
+++ b/spec/javascripts/diffs/components/app_spec.js
@@ -44,8 +44,7 @@ describe('diffs/components/app', () => {
it('shows comments message, with commit', done => {
vm.$store.state.diffs.commit = getDiffWithCommit().commit;
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
expect(vm.$el).toContainText('Only comments from the following commit are shown below');
expect(vm.$el).toContainElement('.blob-commit-info');
@@ -58,8 +57,7 @@ describe('diffs/components/app', () => {
vm.$store.state.diffs.mergeRequestDiff = { latest: false };
vm.$store.state.diffs.targetBranch = 'master';
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
expect(vm.$el).toContainText(
"Not all comments are displayed because you're viewing an old version of the diff.",
@@ -72,8 +70,7 @@ describe('diffs/components/app', () => {
it('shows comments message, with startVersion', done => {
vm.$store.state.diffs.startVersion = 'test';
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
expect(vm.$el).toContainText(
"Not all comments are displayed because you're comparing two versions of the diff.",
diff --git a/spec/javascripts/diffs/components/commit_item_spec.js b/spec/javascripts/diffs/components/commit_item_spec.js
index 8c3376c0eb3..7606847ada9 100644
--- a/spec/javascripts/diffs/components/commit_item_spec.js
+++ b/spec/javascripts/diffs/components/commit_item_spec.js
@@ -14,7 +14,8 @@ const TEST_PIPELINE_STATUS_PATH = `${TEST_HOST}/pipeline/status`;
const getTitleElement = vm => vm.$el.querySelector('.commit-row-message.item-title');
const getDescElement = vm => vm.$el.querySelector('pre.commit-row-description');
-const getDescExpandElement = vm => vm.$el.querySelector('.commit-content .text-expander.js-toggle-button');
+const getDescExpandElement = vm =>
+ vm.$el.querySelector('.commit-content .text-expander.js-toggle-button');
const getShaElement = vm => vm.$el.querySelector('.commit-sha-group');
const getAvatarElement = vm => vm.$el.querySelector('.user-avatar-link');
const getCommitterElement = vm => vm.$el.querySelector('.commiter');
diff --git a/spec/javascripts/diffs/components/diff_file_header_spec.js b/spec/javascripts/diffs/components/diff_file_header_spec.js
index c986ea604b2..0192d583c6c 100644
--- a/spec/javascripts/diffs/components/diff_file_header_spec.js
+++ b/spec/javascripts/diffs/components/diff_file_header_spec.js
@@ -6,6 +6,8 @@ import DiffFileHeader from '~/diffs/components/diff_file_header.vue';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+Vue.use(Vuex);
+
const discussionFixture = 'merge_requests/diff_discussion.json';
describe('diff_file_header', () => {
@@ -58,19 +60,19 @@ describe('diff_file_header', () => {
describe('titleLink', () => {
beforeEach(() => {
+ props.discussionPath = 'link://to/discussion';
Object.assign(props.diffFile, {
- fileHash: 'badc0ffee',
submoduleLink: 'link://to/submodule',
submoduleTreeUrl: 'some://tree/url',
});
});
- it('returns the fileHash for files', () => {
+ it('returns the discussionPath for files', () => {
props.diffFile.submodule = false;
vm = mountComponentWithStore(Component, { props, store });
- expect(vm.titleLink).toBe(`#${props.diffFile.fileHash}`);
+ expect(vm.titleLink).toBe(props.discussionPath);
});
it('returns the submoduleTreeUrl for submodules', () => {
@@ -91,6 +93,14 @@ describe('diff_file_header', () => {
expect(vm.titleLink).toBe(props.diffFile.submoduleLink);
});
+
+ it('sets the correct path to the discussion', () => {
+ props.discussionPath = 'link://to/discussion';
+ vm = mountComponentWithStore(Component, { props, store });
+ const href = vm.$el.querySelector('.js-title-wrapper').getAttribute('href');
+
+ expect(href).toBe(vm.discussionPath);
+ });
});
describe('filePath', () => {
@@ -261,6 +271,7 @@ describe('diff_file_header', () => {
it('displays an file icon in the title', () => {
vm = mountComponentWithStore(Component, { props, store });
+
expect(vm.$el.querySelector('svg.js-file-icon use').getAttribute('xlink:href')).toContain(
'ruby',
);
@@ -303,8 +314,11 @@ describe('diff_file_header', () => {
vm = mountComponentWithStore(Component, { props, store });
const button = vm.$el.querySelector('.btn-clipboard');
+
expect(button).not.toBe(null);
- expect(button.dataset.clipboardText).toBe('{"text":"files/ruby/popen.rb","gfm":"`files/ruby/popen.rb`"}');
+ expect(button.dataset.clipboardText).toBe(
+ '{"text":"files/ruby/popen.rb","gfm":"`files/ruby/popen.rb`"}',
+ );
});
describe('file mode', () => {
@@ -314,6 +328,7 @@ describe('diff_file_header', () => {
vm = mountComponentWithStore(Component, { props, store });
const { fileMode } = vm.$refs;
+
expect(fileMode).not.toBe(undefined);
expect(fileMode).toContainText(props.diffFile.aMode);
expect(fileMode).toContainText(props.diffFile.bMode);
@@ -325,6 +340,7 @@ describe('diff_file_header', () => {
vm = mountComponentWithStore(Component, { props, store });
const { fileMode } = vm.$refs;
+
expect(fileMode).toBe(undefined);
});
});
diff --git a/spec/javascripts/diffs/components/diff_file_spec.js b/spec/javascripts/diffs/components/diff_file_spec.js
index 13859f43e98..882ad3685a2 100644
--- a/spec/javascripts/diffs/components/diff_file_spec.js
+++ b/spec/javascripts/diffs/components/diff_file_spec.js
@@ -24,14 +24,14 @@ describe('DiffFile', () => {
expect(el.querySelectorAll('.diff-content.hidden').length).toEqual(0);
expect(el.querySelector('.js-file-title')).toBeDefined();
- expect(el.querySelector('.file-title-name').innerText.indexOf(filePath) > -1).toEqual(true);
+ expect(el.querySelector('.file-title-name').innerText.indexOf(filePath)).toBeGreaterThan(-1);
expect(el.querySelector('.js-syntax-highlight')).toBeDefined();
expect(vm.file.renderIt).toEqual(false);
vm.file.renderIt = true;
vm.$nextTick(() => {
- expect(el.querySelectorAll('.line_content').length > 5).toEqual(true);
+ expect(el.querySelectorAll('.line_content').length).toBeGreaterThan(5);
});
});
@@ -97,10 +97,11 @@ describe('DiffFile', () => {
expect(vm.$el.innerText).toContain(
'This source diff could not be displayed because it is too large',
);
+
expect(vm.$el.querySelector('.js-too-large-diff')).toBeDefined();
- expect(vm.$el.querySelector('.js-too-large-diff a').href.indexOf(BLOB_LINK) > -1).toEqual(
- true,
- );
+ expect(
+ vm.$el.querySelector('.js-too-large-diff a').href.indexOf(BLOB_LINK),
+ ).toBeGreaterThan(-1);
done();
});
diff --git a/spec/javascripts/diffs/components/diff_gutter_avatars_spec.js b/spec/javascripts/diffs/components/diff_gutter_avatars_spec.js
index 0085a16815a..ad2605a5c5c 100644
--- a/spec/javascripts/diffs/components/diff_gutter_avatars_spec.js
+++ b/spec/javascripts/diffs/components/diff_gutter_avatars_spec.js
@@ -23,6 +23,7 @@ describe('DiffGutterAvatars', () => {
it('should return false when all discussions are not expanded', () => {
component.discussions[0].expanded = false;
+
expect(component.discussionsExpanded).toEqual(false);
});
});
@@ -56,6 +57,7 @@ describe('DiffGutterAvatars', () => {
it('should return empty string if there is no discussion', () => {
component.discussions = [];
+
expect(component.moreText).toEqual('');
});
});
diff --git a/spec/javascripts/diffs/components/diff_line_gutter_content_spec.js b/spec/javascripts/diffs/components/diff_line_gutter_content_spec.js
index 663c0680845..6972e0ee913 100644
--- a/spec/javascripts/diffs/components/diff_line_gutter_content_spec.js
+++ b/spec/javascripts/diffs/components/diff_line_gutter_content_spec.js
@@ -31,12 +31,14 @@ describe('DiffLineGutterContent', () => {
it('should prepend # to lineCode', () => {
const lineCode = 'LC_42';
const component = createComponent();
+
expect(component.lineHref).toEqual(`#${lineCode}`);
});
it('should return # if there is no lineCode', () => {
const component = createComponent();
component.line.lineCode = '';
+
expect(component.lineHref).toEqual('#');
});
});
@@ -44,6 +46,7 @@ describe('DiffLineGutterContent', () => {
describe('discussions, hasDiscussions, shouldShowAvatarsOnGutter', () => {
it('should return empty array when there is no discussion', () => {
const component = createComponent();
+
expect(component.hasDiscussions).toEqual(false);
expect(component.shouldShowAvatarsOnGutter).toEqual(false);
});
@@ -94,7 +97,7 @@ describe('DiffLineGutterContent', () => {
const component = createComponent({ lineNumber, lineCode });
const link = component.$el.querySelector('a');
- expect(link.href.indexOf(`#${lineCode}`) > -1).toEqual(true);
+ expect(link.href.indexOf(`#${lineCode}`)).toBeGreaterThan(-1);
expect(link.dataset.linenumber).toEqual(lineNumber.toString());
});
diff --git a/spec/javascripts/diffs/components/diff_line_note_form_spec.js b/spec/javascripts/diffs/components/diff_line_note_form_spec.js
index f31fc1f0e2b..c39b54d9cc9 100644
--- a/spec/javascripts/diffs/components/diff_line_note_form_spec.js
+++ b/spec/javascripts/diffs/components/diff_line_note_form_spec.js
@@ -36,6 +36,7 @@ describe('DiffLineNoteForm', () => {
spyOn(window, 'confirm').and.returnValue(false);
component.handleCancelCommentForm(true, true);
+
expect(window.confirm).toHaveBeenCalled();
});
@@ -43,9 +44,11 @@ describe('DiffLineNoteForm', () => {
spyOn(window, 'confirm').and.returnValue(false);
component.handleCancelCommentForm(true, false);
+
expect(window.confirm).not.toHaveBeenCalled();
component.handleCancelCommentForm(false, true);
+
expect(window.confirm).not.toHaveBeenCalled();
});
@@ -60,6 +63,7 @@ describe('DiffLineNoteForm', () => {
expect(component.cancelCommentForm).toHaveBeenCalledWith({
lineCode: diffLines[0].lineCode,
});
+
expect(component.resetAutoSave).toHaveBeenCalled();
done();
diff --git a/spec/javascripts/diffs/components/inline_diff_view_spec.js b/spec/javascripts/diffs/components/inline_diff_view_spec.js
index b02328dd359..705558e860b 100644
--- a/spec/javascripts/diffs/components/inline_diff_view_spec.js
+++ b/spec/javascripts/diffs/components/inline_diff_view_spec.js
@@ -27,7 +27,7 @@ describe('InlineDiffView', () => {
expect(el.querySelectorAll('tr.line_holder').length).toEqual(6);
expect(el.querySelectorAll('tr.line_holder.new').length).toEqual(2);
expect(el.querySelectorAll('tr.line_holder.match').length).toEqual(1);
- expect(el.textContent.indexOf('Bad dates') > -1).toEqual(true);
+ expect(el.textContent.indexOf('Bad dates')).toBeGreaterThan(-1);
});
it('should render discussions', done => {
@@ -37,7 +37,7 @@ describe('InlineDiffView', () => {
Vue.nextTick(() => {
expect(el.querySelectorAll('.notes_holder').length).toEqual(1);
expect(el.querySelectorAll('.notes_holder .note-discussion li').length).toEqual(5);
- expect(el.innerText.indexOf('comment 5') > -1).toEqual(true);
+ expect(el.innerText.indexOf('comment 5')).toBeGreaterThan(-1);
component.$store.dispatch('setInitialNotes', []);
done();
diff --git a/spec/javascripts/diffs/components/tree_list_spec.js b/spec/javascripts/diffs/components/tree_list_spec.js
index 08e25d2004e..fc94d0bab5b 100644
--- a/spec/javascripts/diffs/components/tree_list_spec.js
+++ b/spec/javascripts/diffs/components/tree_list_spec.js
@@ -53,7 +53,7 @@ describe('Diffs tree list component', () => {
fileHash: 'test',
key: 'index.js',
name: 'index.js',
- path: 'index.js',
+ path: 'app/index.js',
removedLines: 0,
tempFile: true,
type: 'blob',
@@ -104,7 +104,55 @@ describe('Diffs tree list component', () => {
vm.$el.querySelector('.file-row').click();
- expect(vm.$store.dispatch).toHaveBeenCalledWith('diffs/scrollToFile', 'index.js');
+ expect(vm.$store.dispatch).toHaveBeenCalledWith('diffs/scrollToFile', 'app/index.js');
+ });
+
+ it('renders as file list when renderTreeList is false', done => {
+ vm.renderTreeList = false;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelectorAll('.file-row').length).toBe(1);
+
+ done();
+ });
+ });
+
+ it('renders file paths when renderTreeList is false', done => {
+ vm.renderTreeList = false;
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.file-row').textContent).toContain('app/index.js');
+
+ done();
+ });
+ });
+
+ it('hides render buttons when input is focused', done => {
+ const focusEvent = new Event('focus');
+
+ vm.$el.querySelector('.form-control').dispatchEvent(focusEvent);
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.tree-list-view-toggle').style.display).toBe('none');
+
+ done();
+ });
+ });
+
+ it('shows render buttons when input is blurred', done => {
+ const blurEvent = new Event('blur');
+ vm.focusSearch = true;
+
+ vm.$nextTick()
+ .then(() => {
+ vm.$el.querySelector('.form-control').dispatchEvent(blurEvent);
+ })
+ .then(vm.$nextTick)
+ .then(() => {
+ expect(vm.$el.querySelector('.tree-list-view-toggle').style.display).not.toBe('none');
+ })
+ .then(done)
+ .catch(done.fail);
});
});
@@ -117,4 +165,24 @@ describe('Diffs tree list component', () => {
expect(vm.search).toBe('');
});
});
+
+ describe('toggleRenderTreeList', () => {
+ it('updates renderTreeList', () => {
+ expect(vm.renderTreeList).toBe(true);
+
+ vm.toggleRenderTreeList(false);
+
+ expect(vm.renderTreeList).toBe(false);
+ });
+ });
+
+ describe('toggleFocusSearch', () => {
+ it('updates focusSearch', () => {
+ expect(vm.focusSearch).toBe(false);
+
+ vm.toggleFocusSearch(true);
+
+ expect(vm.focusSearch).toBe(true);
+ });
+ });
});
diff --git a/spec/javascripts/diffs/mock_data/diff_with_commit.js b/spec/javascripts/diffs/mock_data/diff_with_commit.js
index 98393a20583..bee04fa4932 100644
--- a/spec/javascripts/diffs/mock_data/diff_with_commit.js
+++ b/spec/javascripts/diffs/mock_data/diff_with_commit.js
@@ -5,8 +5,5 @@ const FIXTURE = 'merge_request_diffs/with_commit.json';
preloadFixtures(FIXTURE);
export default function getDiffWithCommit() {
- return convertObjectPropsToCamelCase(
- getJSONFixture(FIXTURE),
- { deep: true },
- );
+ return convertObjectPropsToCamelCase(getJSONFixture(FIXTURE), { deep: true });
}
diff --git a/spec/javascripts/diffs/store/actions_spec.js b/spec/javascripts/diffs/store/actions_spec.js
index 85c1926fcb1..bb623953710 100644
--- a/spec/javascripts/diffs/store/actions_spec.js
+++ b/spec/javascripts/diffs/store/actions_spec.js
@@ -27,7 +27,6 @@ import actions, {
toggleShowTreeList,
} from '~/diffs/store/actions';
import * as types from '~/diffs/store/mutation_types';
-import { reduceDiscussionsToLineCodes } from '~/notes/stores/utils';
import axios from '~/lib/utils/axios_utils';
import testAction from '../../helpers/vuex_action_helper';
@@ -152,7 +151,7 @@ describe('DiffsStoreActions', () => {
original_position: diffPosition,
};
- const discussions = reduceDiscussionsToLineCodes([singleDiscussion]);
+ const discussions = [singleDiscussion];
testAction(
assignDiscussionsToDiff,
@@ -162,8 +161,7 @@ describe('DiffsStoreActions', () => {
{
type: types.SET_LINE_DISCUSSIONS_FOR_FILE,
payload: {
- fileHash: 'ABC',
- discussions: [singleDiscussion],
+ discussion: singleDiscussion,
diffPositionByLineCode: {
ABC_1_1: {
baseSha: 'abc',
@@ -581,7 +579,6 @@ describe('DiffsStoreActions', () => {
describe('saveDiffDiscussion', () => {
beforeEach(() => {
spyOnDependency(actions, 'getNoteFormData').and.returnValue('testData');
- spyOnDependency(actions, 'reduceDiscussionsToLineCodes').and.returnValue('discussions');
});
it('dispatches actions', done => {
@@ -602,7 +599,7 @@ describe('DiffsStoreActions', () => {
.then(() => {
expect(dispatch.calls.argsFor(0)).toEqual(['saveNote', 'testData', { root: true }]);
expect(dispatch.calls.argsFor(1)).toEqual(['updateDiscussion', 'test', { root: true }]);
- expect(dispatch.calls.argsFor(2)).toEqual(['assignDiscussionsToDiff', 'discussions']);
+ expect(dispatch.calls.argsFor(2)).toEqual(['assignDiscussionsToDiff', ['discussion']]);
})
.then(done)
.catch(done.fail);
diff --git a/spec/javascripts/diffs/store/getters_spec.js b/spec/javascripts/diffs/store/getters_spec.js
index cfeaaec6980..807a9e3baf0 100644
--- a/spec/javascripts/diffs/store/getters_spec.js
+++ b/spec/javascripts/diffs/store/getters_spec.js
@@ -52,11 +52,13 @@ describe('Diffs Module Getters', () => {
describe('areAllFilesCollapsed', () => {
it('returns true when all files are collapsed', () => {
localState.diffFiles = [{ collapsed: true }, { collapsed: true }];
+
expect(getters.areAllFilesCollapsed(localState)).toEqual(true);
});
it('returns false when at least one file is not collapsed', () => {
localState.diffFiles = [{ collapsed: false }, { collapsed: true }];
+
expect(getters.areAllFilesCollapsed(localState)).toEqual(false);
});
});
@@ -244,6 +246,7 @@ describe('Diffs Module Getters', () => {
it('returns false when no line discussions were found', () => {
line.discussions = [];
+
expect(getters.shouldRenderInlineCommentRow(localState)(line)).toEqual(false);
});
@@ -288,6 +291,7 @@ describe('Diffs Module Getters', () => {
it('returns null if no matching file is found', () => {
localState.diffFiles = [];
+
expect(getters.getDiffFileByHash(localState)('123')).toBeUndefined();
});
});
diff --git a/spec/javascripts/diffs/store/mutations_spec.js b/spec/javascripts/diffs/store/mutations_spec.js
index 0b712055956..4b6d3d5bcba 100644
--- a/spec/javascripts/diffs/store/mutations_spec.js
+++ b/spec/javascripts/diffs/store/mutations_spec.js
@@ -12,6 +12,7 @@ describe('DiffsStoreMutations', () => {
const projectPath = '/root/project';
mutations[types.SET_BASE_CONFIG](state, { endpoint, projectPath });
+
expect(state.endpoint).toEqual(endpoint);
expect(state.projectPath).toEqual(projectPath);
});
@@ -22,6 +23,7 @@ describe('DiffsStoreMutations', () => {
const state = {};
mutations[types.SET_LOADING](state, false);
+
expect(state.isLoading).toEqual(false);
});
});
@@ -48,6 +50,7 @@ describe('DiffsStoreMutations', () => {
const state = {};
mutations[types.SET_DIFF_VIEW_TYPE](state, INLINE_DIFF_VIEW_TYPE);
+
expect(state.diffViewType).toEqual(INLINE_DIFF_VIEW_TYPE);
});
});
@@ -58,6 +61,7 @@ describe('DiffsStoreMutations', () => {
const lineCode = 'FDE';
mutations[types.ADD_COMMENT_FORM_LINE](state, { lineCode });
+
expect(state.diffLineCommentForms[lineCode]).toBeTruthy();
});
});
@@ -68,9 +72,11 @@ describe('DiffsStoreMutations', () => {
const lineCode = 'FDE';
mutations[types.ADD_COMMENT_FORM_LINE](state, { lineCode });
+
expect(state.diffLineCommentForms[lineCode]).toBeTruthy();
mutations[types.REMOVE_COMMENT_FORM_LINE](state, { lineCode });
+
expect(state.diffLineCommentForms[lineCode]).toBeUndefined();
});
});
@@ -83,6 +89,7 @@ describe('DiffsStoreMutations', () => {
const state = { expandAllFiles: true, diffFiles: [diffFile] };
mutations[types.EXPAND_ALL_FILES](state);
+
expect(state.diffFiles[0].collapsed).toEqual(false);
});
});
@@ -118,11 +125,13 @@ describe('DiffsStoreMutations', () => {
options.lineNumbers,
options.params.bottom,
);
+
expect(lineRefSpy).toHaveBeenCalledWith(
options.contextLines,
options.lineNumbers,
options.params.bottom,
);
+
expect(addContextLinesSpy).toHaveBeenCalledWith({
inlineLines: diffFile.highlightedDiffLines,
parallelLines: diffFile.parallelDiffLines,
@@ -142,6 +151,7 @@ describe('DiffsStoreMutations', () => {
const data = { diff_files: [{ file_hash: fileHash, extra_field: 1, existingField: 1 }] };
mutations[types.ADD_COLLAPSED_DIFFS](state, { file: state.diffFiles[1], data });
+
expect(spy).toHaveBeenCalledWith(data, { deep: true });
expect(state.diffFiles[1].fileHash).toEqual(fileHash);
@@ -188,40 +198,32 @@ describe('DiffsStoreMutations', () => {
},
],
};
- const discussions = [
- {
- id: 1,
- line_code: 'ABC_1',
- diff_discussion: true,
- resolvable: true,
- original_position: diffPosition,
- position: diffPosition,
- },
- {
- id: 2,
- line_code: 'ABC_1',
- diff_discussion: true,
- resolvable: true,
- original_position: diffPosition,
- position: diffPosition,
+ const discussion = {
+ id: 1,
+ line_code: 'ABC_1',
+ diff_discussion: true,
+ resolvable: true,
+ original_position: diffPosition,
+ position: diffPosition,
+ diff_file: {
+ file_hash: state.diffFiles[0].fileHash,
},
- ];
+ };
const diffPositionByLineCode = {
ABC_1: diffPosition,
};
mutations[types.SET_LINE_DISCUSSIONS_FOR_FILE](state, {
- fileHash: 'ABC',
- discussions,
+ discussion,
diffPositionByLineCode,
});
- expect(state.diffFiles[0].parallelDiffLines[0].left.discussions.length).toEqual(2);
- expect(state.diffFiles[0].parallelDiffLines[0].left.discussions[1].id).toEqual(2);
+ expect(state.diffFiles[0].parallelDiffLines[0].left.discussions.length).toEqual(1);
+ expect(state.diffFiles[0].parallelDiffLines[0].left.discussions[0].id).toEqual(1);
- expect(state.diffFiles[0].highlightedDiffLines[0].discussions.length).toEqual(2);
- expect(state.diffFiles[0].highlightedDiffLines[0].discussions[1].id).toEqual(2);
+ expect(state.diffFiles[0].highlightedDiffLines[0].discussions.length).toEqual(1);
+ expect(state.diffFiles[0].highlightedDiffLines[0].discussions[0].id).toEqual(1);
});
it('should add legacy discussions to the given line', () => {
@@ -262,36 +264,30 @@ describe('DiffsStoreMutations', () => {
},
],
};
- const discussions = [
- {
- id: 1,
- line_code: 'ABC_1',
- diff_discussion: true,
- active: true,
+ const discussion = {
+ id: 1,
+ line_code: 'ABC_1',
+ diff_discussion: true,
+ active: true,
+ diff_file: {
+ file_hash: state.diffFiles[0].fileHash,
},
- {
- id: 2,
- line_code: 'ABC_1',
- diff_discussion: true,
- active: true,
- },
- ];
+ };
const diffPositionByLineCode = {
ABC_1: diffPosition,
};
mutations[types.SET_LINE_DISCUSSIONS_FOR_FILE](state, {
- fileHash: 'ABC',
- discussions,
+ discussion,
diffPositionByLineCode,
});
- expect(state.diffFiles[0].parallelDiffLines[0].left.discussions.length).toEqual(2);
- expect(state.diffFiles[0].parallelDiffLines[0].left.discussions[1].id).toEqual(2);
+ expect(state.diffFiles[0].parallelDiffLines[0].left.discussions.length).toEqual(1);
+ expect(state.diffFiles[0].parallelDiffLines[0].left.discussions[0].id).toEqual(1);
- expect(state.diffFiles[0].highlightedDiffLines[0].discussions.length).toEqual(2);
- expect(state.diffFiles[0].highlightedDiffLines[0].discussions[1].id).toEqual(2);
+ expect(state.diffFiles[0].highlightedDiffLines[0].discussions.length).toEqual(1);
+ expect(state.diffFiles[0].highlightedDiffLines[0].discussions[0].id).toEqual(1);
});
});
@@ -345,6 +341,7 @@ describe('DiffsStoreMutations', () => {
fileHash: 'ABC',
lineCode: 'ABC_1',
});
+
expect(state.diffFiles[0].parallelDiffLines[0].left.discussions.length).toEqual(0);
expect(state.diffFiles[0].highlightedDiffLines[0].discussions.length).toEqual(0);
});
diff --git a/spec/javascripts/diffs/store/utils_spec.js b/spec/javascripts/diffs/store/utils_spec.js
index 257270a91ec..f49dee3696d 100644
--- a/spec/javascripts/diffs/store/utils_spec.js
+++ b/spec/javascripts/diffs/store/utils_spec.js
@@ -62,10 +62,12 @@ describe('DiffsStoreUtils', () => {
const atParallelIndex = diffFile.parallelDiffLines[parallelIndex];
utils.removeMatchLine(diffFile, lineNumbers, false);
+
expect(diffFile.highlightedDiffLines[inlineIndex]).not.toEqual(atInlineIndex);
expect(diffFile.parallelDiffLines[parallelIndex]).not.toEqual(atParallelIndex);
utils.removeMatchLine(diffFile, lineNumbers, true);
+
expect(diffFile.highlightedDiffLines[inlineIndex + 1]).not.toEqual(atInlineIndex);
expect(diffFile.parallelDiffLines[parallelIndex + 1]).not.toEqual(atParallelIndex);
});
@@ -87,11 +89,13 @@ describe('DiffsStoreUtils', () => {
};
utils.addContextLines(options);
+
expect(inlineLines[inlineLines.length - 1]).toEqual(contextLines[0]);
expect(parallelLines[parallelLines.length - 1]).toEqual(normalizedParallelLine);
delete options.bottom;
utils.addContextLines(options);
+
expect(inlineLines[inlineIndex]).toEqual(contextLines[0]);
expect(parallelLines[parallelIndex]).toEqual(normalizedParallelLine);
});
@@ -274,6 +278,7 @@ describe('DiffsStoreUtils', () => {
};
utils.trimFirstCharOfLineContent(lineObj);
+
expect(lineObj).toEqual({ discussions: [], richText: ' diff' });
});
@@ -288,19 +293,23 @@ describe('DiffsStoreUtils', () => {
utils.prepareDiffData(preparedDiff);
const firstParallelDiffLine = preparedDiff.diffFiles[0].parallelDiffLines[2];
+
expect(firstParallelDiffLine.left.discussions.length).toBe(0);
expect(firstParallelDiffLine.left).not.toHaveAttr('text');
expect(firstParallelDiffLine.right.discussions.length).toBe(0);
expect(firstParallelDiffLine.right).not.toHaveAttr('text');
const firstParallelChar = firstParallelDiffLine.right.richText.charAt(0);
+
expect(firstParallelChar).not.toBe(' ');
expect(firstParallelChar).not.toBe('+');
expect(firstParallelChar).not.toBe('-');
const checkLine = preparedDiff.diffFiles[0].highlightedDiffLines[0];
+
expect(checkLine.discussions.length).toBe(0);
expect(checkLine).not.toHaveAttr('text');
const firstChar = checkLine.richText.charAt(0);
+
expect(firstChar).not.toBe(' ');
expect(firstChar).not.toBe('+');
expect(firstChar).not.toBe('-');
@@ -436,6 +445,14 @@ describe('DiffsStoreUtils', () => {
fileHash: 'test',
},
{
+ newPath: 'app/test/filepathneedstruncating.js',
+ deletedFile: false,
+ newFile: true,
+ removedLines: 0,
+ addedLines: 0,
+ fileHash: 'test',
+ },
+ {
newPath: 'package.json',
deletedFile: true,
newFile: false,
@@ -489,6 +506,19 @@ describe('DiffsStoreUtils', () => {
type: 'blob',
tree: [],
},
+ {
+ addedLines: 0,
+ changed: true,
+ deleted: false,
+ fileHash: 'test',
+ key: 'app/test/filepathneedstruncating.js',
+ name: 'filepathneedstruncating.js',
+ path: 'app/test/filepathneedstruncating.js',
+ removedLines: 0,
+ tempFile: true,
+ type: 'blob',
+ tree: [],
+ },
],
},
],
@@ -518,6 +548,7 @@ describe('DiffsStoreUtils', () => {
'app/index.js',
'app/test',
'app/test/index.js',
+ 'app/test/filepathneedstruncating.js',
'package.json',
]);
});
diff --git a/spec/javascripts/dirty_submit/dirty_submit_collection_spec.js b/spec/javascripts/dirty_submit/dirty_submit_collection_spec.js
new file mode 100644
index 00000000000..08ffc44605f
--- /dev/null
+++ b/spec/javascripts/dirty_submit/dirty_submit_collection_spec.js
@@ -0,0 +1,29 @@
+import DirtySubmitCollection from '~/dirty_submit/dirty_submit_collection';
+import { setInput, createForm } from './helper';
+
+describe('DirtySubmitCollection', () => {
+ it('disables submits until there are changes', done => {
+ const testElementsCollection = [createForm(), createForm()];
+ const forms = testElementsCollection.map(testElements => testElements.form);
+
+ new DirtySubmitCollection(forms); // eslint-disable-line no-new
+
+ testElementsCollection.forEach(testElements => {
+ const { input, submit } = testElements;
+ const originalValue = input.value;
+
+ expect(submit.disabled).toBe(true);
+
+ return setInput(input, `${originalValue} changes`)
+ .then(() => {
+ expect(submit.disabled).toBe(false);
+ })
+ .then(() => setInput(input, originalValue))
+ .then(() => {
+ expect(submit.disabled).toBe(true);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+});
diff --git a/spec/javascripts/dirty_submit/dirty_submit_factory_spec.js b/spec/javascripts/dirty_submit/dirty_submit_factory_spec.js
new file mode 100644
index 00000000000..40843a68582
--- /dev/null
+++ b/spec/javascripts/dirty_submit/dirty_submit_factory_spec.js
@@ -0,0 +1,18 @@
+import dirtySubmitFactory from '~/dirty_submit/dirty_submit_factory';
+import DirtySubmitForm from '~/dirty_submit/dirty_submit_form';
+import DirtySubmitCollection from '~/dirty_submit/dirty_submit_collection';
+import { createForm } from './helper';
+
+describe('DirtySubmitCollection', () => {
+ it('returns a DirtySubmitForm instance for single form elements', () => {
+ const { form } = createForm();
+
+ expect(dirtySubmitFactory(form) instanceof DirtySubmitForm).toBe(true);
+ });
+
+ it('returns a DirtySubmitCollection instance for a collection of form elements', () => {
+ const forms = [createForm().form, createForm().form];
+
+ expect(dirtySubmitFactory(forms) instanceof DirtySubmitCollection).toBe(true);
+ });
+});
diff --git a/spec/javascripts/dirty_submit/dirty_submit_form_spec.js b/spec/javascripts/dirty_submit/dirty_submit_form_spec.js
new file mode 100644
index 00000000000..b7b29190c31
--- /dev/null
+++ b/spec/javascripts/dirty_submit/dirty_submit_form_spec.js
@@ -0,0 +1,24 @@
+import DirtySubmitForm from '~/dirty_submit/dirty_submit_form';
+import { setInput, createForm } from './helper';
+
+describe('DirtySubmitForm', () => {
+ it('disables submit until there are changes', done => {
+ const { form, input, submit } = createForm();
+ const originalValue = input.value;
+
+ new DirtySubmitForm(form); // eslint-disable-line no-new
+
+ expect(submit.disabled).toBe(true);
+
+ return setInput(input, `${originalValue} changes`)
+ .then(() => {
+ expect(submit.disabled).toBe(false);
+ })
+ .then(() => setInput(input, originalValue))
+ .then(() => {
+ expect(submit.disabled).toBe(true);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+});
diff --git a/spec/javascripts/dirty_submit/helper.js b/spec/javascripts/dirty_submit/helper.js
new file mode 100644
index 00000000000..6d1e643553c
--- /dev/null
+++ b/spec/javascripts/dirty_submit/helper.js
@@ -0,0 +1,31 @@
+import DirtySubmitForm from '~/dirty_submit/dirty_submit_form';
+import setTimeoutPromiseHelper from '../helpers/set_timeout_promise_helper';
+
+export function setInput(element, value) {
+ element.value = value;
+
+ element.dispatchEvent(
+ new Event('input', {
+ bubbles: true,
+ cancelable: true,
+ }),
+ );
+
+ return setTimeoutPromiseHelper(DirtySubmitForm.THROTTLE_DURATION);
+}
+
+export function createForm() {
+ const form = document.createElement('form');
+ form.innerHTML = `
+ <input type="text" value="original" class="js-input" name="input" />
+ <button type="submit" class="js-dirty-submit"></button>
+ `;
+ const input = form.querySelector('.js-input');
+ const submit = form.querySelector('.js-dirty-submit');
+
+ return {
+ form,
+ input,
+ submit,
+ };
+}
diff --git a/spec/javascripts/droplab/drop_down_spec.js b/spec/javascripts/droplab/drop_down_spec.js
index 896a04a1a07..18ab03653f4 100644
--- a/spec/javascripts/droplab/drop_down_spec.js
+++ b/spec/javascripts/droplab/drop_down_spec.js
@@ -2,9 +2,9 @@ import DropDown from '~/droplab/drop_down';
import utils from '~/droplab/utils';
import { SELECTED_CLASS } from '~/droplab/constants';
-describe('DropLab DropDown', function () {
- describe('class constructor', function () {
- beforeEach(function () {
+describe('DropLab DropDown', function() {
+ describe('class constructor', function() {
+ beforeEach(function() {
spyOn(DropDown.prototype, 'getItems');
spyOn(DropDown.prototype, 'initTemplateString');
spyOn(DropDown.prototype, 'addEvents');
@@ -13,32 +13,32 @@ describe('DropLab DropDown', function () {
this.dropdown = new DropDown(this.list);
});
- it('sets the .hidden property to true', function () {
+ it('sets the .hidden property to true', function() {
expect(this.dropdown.hidden).toBe(true);
});
- it('sets the .list property', function () {
+ it('sets the .list property', function() {
expect(this.dropdown.list).toBe(this.list);
});
- it('calls .getItems', function () {
+ it('calls .getItems', function() {
expect(DropDown.prototype.getItems).toHaveBeenCalled();
});
- it('calls .initTemplateString', function () {
+ it('calls .initTemplateString', function() {
expect(DropDown.prototype.initTemplateString).toHaveBeenCalled();
});
- it('calls .addEvents', function () {
+ it('calls .addEvents', function() {
expect(DropDown.prototype.addEvents).toHaveBeenCalled();
});
- it('sets the .initialState property to the .list.innerHTML', function () {
+ it('sets the .initialState property to the .list.innerHTML', function() {
expect(this.dropdown.initialState).toBe(this.list.innerHTML);
});
- describe('if the list argument is a string', function () {
- beforeEach(function () {
+ describe('if the list argument is a string', function() {
+ beforeEach(function() {
this.element = {};
this.selector = '.selector';
@@ -47,18 +47,18 @@ describe('DropLab DropDown', function () {
this.dropdown = new DropDown(this.selector);
});
- it('calls .querySelector with the selector string', function () {
+ it('calls .querySelector with the selector string', function() {
expect(Document.prototype.querySelector).toHaveBeenCalledWith(this.selector);
});
- it('sets the .list property element', function () {
+ it('sets the .list property element', function() {
expect(this.dropdown.list).toBe(this.element);
});
});
});
- describe('getItems', function () {
- beforeEach(function () {
+ describe('getItems', function() {
+ beforeEach(function() {
this.list = { querySelectorAll: () => {} };
this.dropdown = { list: this.list };
this.nodeList = [];
@@ -68,37 +68,37 @@ describe('DropLab DropDown', function () {
this.getItems = DropDown.prototype.getItems.call(this.dropdown);
});
- it('calls .querySelectorAll with a list item query', function () {
+ it('calls .querySelectorAll with a list item query', function() {
expect(this.list.querySelectorAll).toHaveBeenCalledWith('li');
});
- it('sets the .items property to the returned list items', function () {
+ it('sets the .items property to the returned list items', function() {
expect(this.dropdown.items).toEqual(jasmine.any(Array));
});
- it('returns the .items', function () {
+ it('returns the .items', function() {
expect(this.getItems).toEqual(jasmine.any(Array));
});
});
- describe('initTemplateString', function () {
- beforeEach(function () {
+ describe('initTemplateString', function() {
+ beforeEach(function() {
this.items = [{ outerHTML: '<a></a>' }, { outerHTML: '<img>' }];
this.dropdown = { items: this.items };
DropDown.prototype.initTemplateString.call(this.dropdown);
});
- it('should set .templateString to the last items .outerHTML', function () {
+ it('should set .templateString to the last items .outerHTML', function() {
expect(this.dropdown.templateString).toBe(this.items[1].outerHTML);
});
- it('should not set .templateString to a non-last items .outerHTML', function () {
+ it('should not set .templateString to a non-last items .outerHTML', function() {
expect(this.dropdown.templateString).not.toBe(this.items[0].outerHTML);
});
- describe('if .items is not set', function () {
- beforeEach(function () {
+ describe('if .items is not set', function() {
+ beforeEach(function() {
this.dropdown = { getItems: () => {} };
spyOn(this.dropdown, 'getItems').and.returnValue([]);
@@ -106,26 +106,26 @@ describe('DropLab DropDown', function () {
DropDown.prototype.initTemplateString.call(this.dropdown);
});
- it('should call .getItems', function () {
+ it('should call .getItems', function() {
expect(this.dropdown.getItems).toHaveBeenCalled();
});
});
- describe('if items array is empty', function () {
- beforeEach(function () {
+ describe('if items array is empty', function() {
+ beforeEach(function() {
this.dropdown = { items: [] };
DropDown.prototype.initTemplateString.call(this.dropdown);
});
- it('should set .templateString to an empty string', function () {
+ it('should set .templateString to an empty string', function() {
expect(this.dropdown.templateString).toBe('');
});
});
});
- describe('clickEvent', function () {
- beforeEach(function () {
+ describe('clickEvent', function() {
+ beforeEach(function() {
this.classList = jasmine.createSpyObj('classList', ['contains']);
this.list = { dispatchEvent: () => {} };
this.dropdown = {
@@ -143,7 +143,7 @@ describe('DropLab DropDown', function () {
};
this.customEvent = {};
this.dummyListItem = document.createElement('li');
- spyOn(this.event.target, 'closest').and.callFake((selector) => {
+ spyOn(this.event.target, 'closest').and.callFake(selector => {
if (selector === 'li') {
return this.dummyListItem;
}
@@ -159,51 +159,51 @@ describe('DropLab DropDown', function () {
this.classList.contains.and.returnValue(false);
});
- it('should call event.target.closest', function () {
+ it('should call event.target.closest', function() {
DropDown.prototype.clickEvent.call(this.dropdown, this.event);
expect(this.event.target.closest).toHaveBeenCalledWith('.droplab-item-ignore');
expect(this.event.target.closest).toHaveBeenCalledWith('li');
});
- it('should call addSelectedClass', function () {
+ it('should call addSelectedClass', function() {
DropDown.prototype.clickEvent.call(this.dropdown, this.event);
expect(this.dropdown.addSelectedClass).toHaveBeenCalledWith(this.dummyListItem);
});
- it('should call .preventDefault', function () {
+ it('should call .preventDefault', function() {
DropDown.prototype.clickEvent.call(this.dropdown, this.event);
expect(this.event.preventDefault).toHaveBeenCalled();
});
- it('should call .hide', function () {
+ it('should call .hide', function() {
DropDown.prototype.clickEvent.call(this.dropdown, this.event);
expect(this.dropdown.hide).toHaveBeenCalled();
});
- it('should construct CustomEvent', function () {
+ it('should construct CustomEvent', function() {
DropDown.prototype.clickEvent.call(this.dropdown, this.event);
expect(window.CustomEvent).toHaveBeenCalledWith('click.dl', jasmine.any(Object));
});
- it('should call .dispatchEvent with the customEvent', function () {
+ it('should call .dispatchEvent with the customEvent', function() {
DropDown.prototype.clickEvent.call(this.dropdown, this.event);
expect(this.list.dispatchEvent).toHaveBeenCalledWith(this.customEvent);
});
- describe('if the target is a UL element', function () {
- beforeEach(function () {
+ describe('if the target is a UL element', function() {
+ beforeEach(function() {
this.event.target = document.createElement('ul');
spyOn(this.event.target, 'closest');
});
- it('should return immediately', function () {
+ it('should return immediately', function() {
DropDown.prototype.clickEvent.call(this.dropdown, this.event);
expect(this.event.target.closest).not.toHaveBeenCalled();
@@ -211,8 +211,8 @@ describe('DropLab DropDown', function () {
});
});
- describe('if the target has the droplab-item-ignore class', function () {
- beforeEach(function () {
+ describe('if the target has the droplab-item-ignore class', function() {
+ beforeEach(function() {
this.ignoredButton = document.createElement('button');
this.ignoredButton.classList.add('droplab-item-ignore');
this.event.target = this.ignoredButton;
@@ -220,7 +220,7 @@ describe('DropLab DropDown', function () {
spyOn(this.ignoredButton, 'closest').and.callThrough();
});
- it('does not select element', function () {
+ it('does not select element', function() {
DropDown.prototype.clickEvent.call(this.dropdown, this.event);
expect(this.ignoredButton.closest.calls.count()).toBe(1);
@@ -229,13 +229,13 @@ describe('DropLab DropDown', function () {
});
});
- describe('if no selected element exists', function () {
- beforeEach(function () {
+ describe('if no selected element exists', function() {
+ beforeEach(function() {
this.event.preventDefault.calls.reset();
this.dummyListItem = null;
});
- it('should return before .preventDefault is called', function () {
+ it('should return before .preventDefault is called', function() {
DropDown.prototype.clickEvent.call(this.dropdown, this.event);
expect(this.event.preventDefault).not.toHaveBeenCalled();
@@ -244,12 +244,12 @@ describe('DropLab DropDown', function () {
});
describe('if hideOnClick is false', () => {
- beforeEach(function () {
+ beforeEach(function() {
this.dropdown.hideOnClick = false;
this.dropdown.hide.calls.reset();
});
- it('should not call .hide', function () {
+ it('should not call .hide', function() {
DropDown.prototype.clickEvent.call(this.dropdown, this.event);
expect(this.dropdown.hide).not.toHaveBeenCalled();
@@ -257,8 +257,8 @@ describe('DropLab DropDown', function () {
});
});
- describe('addSelectedClass', function () {
- beforeEach(function () {
+ describe('addSelectedClass', function() {
+ beforeEach(function() {
this.items = Array(4).forEach((item, i) => {
this.items[i] = { classList: { add: () => {} } };
spyOn(this.items[i].classList, 'add');
@@ -272,17 +272,17 @@ describe('DropLab DropDown', function () {
DropDown.prototype.addSelectedClass.call(this.dropdown, this.selected);
});
- it('should call .removeSelectedClasses', function () {
+ it('should call .removeSelectedClasses', function() {
expect(this.dropdown.removeSelectedClasses).toHaveBeenCalled();
});
- it('should call .classList.add', function () {
+ it('should call .classList.add', function() {
expect(this.selected.classList.add).toHaveBeenCalledWith(SELECTED_CLASS);
});
});
- describe('removeSelectedClasses', function () {
- beforeEach(function () {
+ describe('removeSelectedClasses', function() {
+ beforeEach(function() {
this.items = Array(4);
this.items.forEach((item, i) => {
this.items[i] = { classList: { add: () => {} } };
@@ -293,14 +293,14 @@ describe('DropLab DropDown', function () {
DropDown.prototype.removeSelectedClasses.call(this.dropdown);
});
- it('should call .classList.remove for all items', function () {
+ it('should call .classList.remove for all items', function() {
this.items.forEach((item, i) => {
expect(this.items[i].classList.add).toHaveBeenCalledWith(SELECTED_CLASS);
});
});
- describe('if .items is not set', function () {
- beforeEach(function () {
+ describe('if .items is not set', function() {
+ beforeEach(function() {
this.dropdown = { getItems: () => {} };
spyOn(this.dropdown, 'getItems').and.returnValue([]);
@@ -308,14 +308,14 @@ describe('DropLab DropDown', function () {
DropDown.prototype.removeSelectedClasses.call(this.dropdown);
});
- it('should call .getItems', function () {
+ it('should call .getItems', function() {
expect(this.dropdown.getItems).toHaveBeenCalled();
});
});
});
- describe('addEvents', function () {
- beforeEach(function () {
+ describe('addEvents', function() {
+ beforeEach(function() {
this.list = {
addEventListener: () => {},
querySelectorAll: () => [],
@@ -328,7 +328,7 @@ describe('DropLab DropDown', function () {
};
});
- it('should call .addEventListener', function () {
+ it('should call .addEventListener', function() {
spyOn(this.list, 'addEventListener');
DropDown.prototype.addEvents.call(this.dropdown);
@@ -338,8 +338,8 @@ describe('DropLab DropDown', function () {
});
});
- describe('setData', function () {
- beforeEach(function () {
+ describe('setData', function() {
+ beforeEach(function() {
this.dropdown = { render: () => {} };
this.data = ['data'];
@@ -348,17 +348,17 @@ describe('DropLab DropDown', function () {
DropDown.prototype.setData.call(this.dropdown, this.data);
});
- it('should set .data', function () {
+ it('should set .data', function() {
expect(this.dropdown.data).toBe(this.data);
});
- it('should call .render with the .data', function () {
+ it('should call .render with the .data', function() {
expect(this.dropdown.render).toHaveBeenCalledWith(this.data);
});
});
- describe('addData', function () {
- beforeEach(function () {
+ describe('addData', function() {
+ beforeEach(function() {
this.dropdown = { render: () => {}, data: ['data1'] };
this.data = ['data2'];
@@ -368,20 +368,20 @@ describe('DropLab DropDown', function () {
DropDown.prototype.addData.call(this.dropdown, this.data);
});
- it('should call .concat with data', function () {
+ it('should call .concat with data', function() {
expect(Array.prototype.concat).toHaveBeenCalledWith(this.data);
});
- it('should set .data with concatination', function () {
+ it('should set .data with concatination', function() {
expect(this.dropdown.data).toEqual(['data1', 'data2']);
});
- it('should call .render with the .data', function () {
+ it('should call .render with the .data', function() {
expect(this.dropdown.render).toHaveBeenCalledWith(['data1', 'data2']);
});
- describe('if .data is undefined', function () {
- beforeEach(function () {
+ describe('if .data is undefined', function() {
+ beforeEach(function() {
this.dropdown = { render: () => {}, data: undefined };
this.data = ['data2'];
@@ -390,14 +390,14 @@ describe('DropLab DropDown', function () {
DropDown.prototype.addData.call(this.dropdown, this.data);
});
- it('should set .data with concatination', function () {
+ it('should set .data with concatination', function() {
expect(this.dropdown.data).toEqual(['data2']);
});
});
});
- describe('render', function () {
- beforeEach(function () {
+ describe('render', function() {
+ beforeEach(function() {
this.list = { querySelector: () => {}, dispatchEvent: () => {} };
this.dropdown = { renderChildren: () => {}, list: this.list };
this.renderableList = {};
@@ -413,45 +413,45 @@ describe('DropLab DropDown', function () {
DropDown.prototype.render.call(this.dropdown, this.data);
});
- it('should call .map', function () {
+ it('should call .map', function() {
expect(this.data.map).toHaveBeenCalledWith(jasmine.any(Function));
});
- it('should call .renderChildren for each data item', function () {
+ it('should call .renderChildren for each data item', function() {
expect(this.dropdown.renderChildren.calls.count()).toBe(this.data.length);
});
- it('sets the renderableList .innerHTML', function () {
+ it('sets the renderableList .innerHTML', function() {
expect(this.renderableList.innerHTML).toBe('01');
});
- it('should call render.dl', function () {
+ it('should call render.dl', function() {
expect(window.CustomEvent).toHaveBeenCalledWith('render.dl', jasmine.any(Object));
});
- it('should call dispatchEvent with the customEvent', function () {
+ it('should call dispatchEvent with the customEvent', function() {
expect(this.list.dispatchEvent).toHaveBeenCalledWith(this.customEvent);
});
- describe('if no data argument is passed', function () {
- beforeEach(function () {
+ describe('if no data argument is passed', function() {
+ beforeEach(function() {
this.data.map.calls.reset();
this.dropdown.renderChildren.calls.reset();
DropDown.prototype.render.call(this.dropdown, undefined);
});
- it('should not call .map', function () {
+ it('should not call .map', function() {
expect(this.data.map).not.toHaveBeenCalled();
});
- it('should not call .renderChildren', function () {
+ it('should not call .renderChildren', function() {
expect(this.dropdown.renderChildren).not.toHaveBeenCalled();
});
});
- describe('if no dynamic list is present', function () {
- beforeEach(function () {
+ describe('if no dynamic list is present', function() {
+ beforeEach(function() {
this.list = { querySelector: () => {}, dispatchEvent: () => {} };
this.dropdown = { renderChildren: () => {}, list: this.list };
this.data = [0, 1];
@@ -463,14 +463,14 @@ describe('DropLab DropDown', function () {
DropDown.prototype.render.call(this.dropdown, this.data);
});
- it('sets the .list .innerHTML', function () {
+ it('sets the .list .innerHTML', function() {
expect(this.list.innerHTML).toBe('01');
});
});
});
- describe('renderChildren', function () {
- beforeEach(function () {
+ describe('renderChildren', function() {
+ beforeEach(function() {
this.templateString = 'templateString';
this.dropdown = { templateString: this.templateString };
this.data = { droplab_hidden: true };
@@ -484,44 +484,44 @@ describe('DropLab DropDown', function () {
this.renderChildren = DropDown.prototype.renderChildren.call(this.dropdown, this.data);
});
- it('should call utils.t with .templateString and data', function () {
+ it('should call utils.t with .templateString and data', function() {
expect(utils.template).toHaveBeenCalledWith(this.templateString, this.data);
});
- it('should call document.createElement', function () {
+ it('should call document.createElement', function() {
expect(document.createElement).toHaveBeenCalledWith('div');
});
- it('should set the templates .innerHTML to the HTML', function () {
+ it('should set the templates .innerHTML to the HTML', function() {
expect(this.template.innerHTML).toBe(this.html);
});
- it('should call .setImagesSrc with the template', function () {
+ it('should call .setImagesSrc with the template', function() {
expect(DropDown.setImagesSrc).toHaveBeenCalledWith(this.template);
});
- it('should set the template display to none', function () {
+ it('should set the template display to none', function() {
expect(this.template.firstChild.style.display).toBe('none');
});
- it('should return the templates .firstChild.outerHTML', function () {
+ it('should return the templates .firstChild.outerHTML', function() {
expect(this.renderChildren).toBe(this.template.firstChild.outerHTML);
});
- describe('if droplab_hidden is false', function () {
- beforeEach(function () {
+ describe('if droplab_hidden is false', function() {
+ beforeEach(function() {
this.data = { droplab_hidden: false };
this.renderChildren = DropDown.prototype.renderChildren.call(this.dropdown, this.data);
});
- it('should set the template display to block', function () {
+ it('should set the template display to block', function() {
expect(this.template.firstChild.style.display).toBe('block');
});
});
});
- describe('setImagesSrc', function () {
- beforeEach(function () {
+ describe('setImagesSrc', function() {
+ beforeEach(function() {
this.template = { querySelectorAll: () => {} };
spyOn(this.template, 'querySelectorAll').and.returnValue([]);
@@ -529,64 +529,64 @@ describe('DropLab DropDown', function () {
DropDown.setImagesSrc(this.template);
});
- it('should call .querySelectorAll', function () {
+ it('should call .querySelectorAll', function() {
expect(this.template.querySelectorAll).toHaveBeenCalledWith('img[data-src]');
});
});
- describe('show', function () {
- beforeEach(function () {
+ describe('show', function() {
+ beforeEach(function() {
this.list = { style: {} };
this.dropdown = { list: this.list, hidden: true };
DropDown.prototype.show.call(this.dropdown);
});
- it('it should set .list display to block', function () {
+ it('it should set .list display to block', function() {
expect(this.list.style.display).toBe('block');
});
- it('it should set .hidden to false', function () {
+ it('it should set .hidden to false', function() {
expect(this.dropdown.hidden).toBe(false);
});
- describe('if .hidden is false', function () {
- beforeEach(function () {
+ describe('if .hidden is false', function() {
+ beforeEach(function() {
this.list = { style: {} };
this.dropdown = { list: this.list, hidden: false };
this.show = DropDown.prototype.show.call(this.dropdown);
});
- it('should return undefined', function () {
+ it('should return undefined', function() {
expect(this.show).toEqual(undefined);
});
- it('should not set .list display to block', function () {
+ it('should not set .list display to block', function() {
expect(this.list.style.display).not.toEqual('block');
});
});
});
- describe('hide', function () {
- beforeEach(function () {
+ describe('hide', function() {
+ beforeEach(function() {
this.list = { style: {} };
this.dropdown = { list: this.list };
DropDown.prototype.hide.call(this.dropdown);
});
- it('it should set .list display to none', function () {
+ it('it should set .list display to none', function() {
expect(this.list.style.display).toBe('none');
});
- it('it should set .hidden to true', function () {
+ it('it should set .hidden to true', function() {
expect(this.dropdown.hidden).toBe(true);
});
});
- describe('toggle', function () {
- beforeEach(function () {
+ describe('toggle', function() {
+ beforeEach(function() {
this.hidden = true;
this.dropdown = { hidden: this.hidden, show: () => {}, hide: () => {} };
@@ -596,12 +596,12 @@ describe('DropLab DropDown', function () {
DropDown.prototype.toggle.call(this.dropdown);
});
- it('should call .show', function () {
+ it('should call .show', function() {
expect(this.dropdown.show).toHaveBeenCalled();
});
- describe('if .hidden is false', function () {
- beforeEach(function () {
+ describe('if .hidden is false', function() {
+ beforeEach(function() {
this.hidden = false;
this.dropdown = { hidden: this.hidden, show: () => {}, hide: () => {} };
@@ -611,14 +611,14 @@ describe('DropLab DropDown', function () {
DropDown.prototype.toggle.call(this.dropdown);
});
- it('should call .hide', function () {
+ it('should call .hide', function() {
expect(this.dropdown.hide).toHaveBeenCalled();
});
});
});
- describe('destroy', function () {
- beforeEach(function () {
+ describe('destroy', function() {
+ beforeEach(function() {
this.list = { removeEventListener: () => {} };
this.eventWrapper = { clickEvent: 'clickEvent' };
this.dropdown = { list: this.list, hide: () => {}, eventWrapper: this.eventWrapper };
@@ -629,12 +629,15 @@ describe('DropLab DropDown', function () {
DropDown.prototype.destroy.call(this.dropdown);
});
- it('it should call .hide', function () {
+ it('it should call .hide', function() {
expect(this.dropdown.hide).toHaveBeenCalled();
});
- it('it should call .removeEventListener', function () {
- expect(this.list.removeEventListener).toHaveBeenCalledWith('click', this.eventWrapper.clickEvent);
+ it('it should call .removeEventListener', function() {
+ expect(this.list.removeEventListener).toHaveBeenCalledWith(
+ 'click',
+ this.eventWrapper.clickEvent,
+ );
});
});
});
diff --git a/spec/javascripts/droplab/hook_spec.js b/spec/javascripts/droplab/hook_spec.js
index 5eed1db2750..40470436f19 100644
--- a/spec/javascripts/droplab/hook_spec.js
+++ b/spec/javascripts/droplab/hook_spec.js
@@ -1,8 +1,8 @@
import Hook from '~/droplab/hook';
-describe('Hook', function () {
- describe('class constructor', function () {
- beforeEach(function () {
+describe('Hook', function() {
+ describe('class constructor', function() {
+ beforeEach(function() {
this.trigger = { id: 'id' };
this.list = {};
this.plugins = {};
@@ -14,58 +14,58 @@ describe('Hook', function () {
this.hook = new Hook(this.trigger, this.list, this.plugins, this.config);
});
- it('should set .trigger', function () {
+ it('should set .trigger', function() {
expect(this.hook.trigger).toBe(this.trigger);
});
- it('should set .list', function () {
+ it('should set .list', function() {
expect(this.hook.list).toBe(this.dropdown);
});
- it('should call DropDown constructor', function () {
+ it('should call DropDown constructor', function() {
expect(this.dropdownConstructor).toHaveBeenCalledWith(this.list, this.config);
});
- it('should set .type', function () {
+ it('should set .type', function() {
expect(this.hook.type).toBe('Hook');
});
- it('should set .event', function () {
+ it('should set .event', function() {
expect(this.hook.event).toBe('click');
});
- it('should set .plugins', function () {
+ it('should set .plugins', function() {
expect(this.hook.plugins).toBe(this.plugins);
});
- it('should set .config', function () {
+ it('should set .config', function() {
expect(this.hook.config).toBe(this.config);
});
- it('should set .id', function () {
+ it('should set .id', function() {
expect(this.hook.id).toBe(this.trigger.id);
});
- describe('if config argument is undefined', function () {
- beforeEach(function () {
+ describe('if config argument is undefined', function() {
+ beforeEach(function() {
this.config = undefined;
this.hook = new Hook(this.trigger, this.list, this.plugins, this.config);
});
- it('should set .config to an empty object', function () {
+ it('should set .config to an empty object', function() {
expect(this.hook.config).toEqual({});
});
});
- describe('if plugins argument is undefined', function () {
- beforeEach(function () {
+ describe('if plugins argument is undefined', function() {
+ beforeEach(function() {
this.plugins = undefined;
this.hook = new Hook(this.trigger, this.list, this.plugins, this.config);
});
- it('should set .plugins to an empty array', function () {
+ it('should set .plugins to an empty array', function() {
expect(this.hook.plugins).toEqual([]);
});
});
diff --git a/spec/javascripts/droplab/plugins/ajax_filter_spec.js b/spec/javascripts/droplab/plugins/ajax_filter_spec.js
index 8155d98b543..5dbe50af07f 100644
--- a/spec/javascripts/droplab/plugins/ajax_filter_spec.js
+++ b/spec/javascripts/droplab/plugins/ajax_filter_spec.js
@@ -38,8 +38,8 @@ describe('AjaxFilter', () => {
dummyList.list.appendChild(dynamicList);
});
- it('calls onLoadingFinished after loading data', (done) => {
- ajaxSpy = (url) => {
+ it('calls onLoadingFinished after loading data', done => {
+ ajaxSpy = url => {
expect(url).toBe('dummy endpoint?dummy search key=');
return Promise.resolve(dummyData);
};
@@ -52,16 +52,16 @@ describe('AjaxFilter', () => {
.catch(done.fail);
});
- it('does not call onLoadingFinished if Ajax call fails', (done) => {
+ it('does not call onLoadingFinished if Ajax call fails', done => {
const dummyError = new Error('My dummy is sick! :-(');
- ajaxSpy = (url) => {
+ ajaxSpy = url => {
expect(url).toBe('dummy endpoint?dummy search key=');
return Promise.reject(dummyError);
};
AjaxFilter.trigger()
.then(done.fail)
- .catch((error) => {
+ .catch(error => {
expect(error).toBe(dummyError);
expect(dummyConfig.onLoadingFinished.calls.count()).toBe(0);
})
diff --git a/spec/javascripts/droplab/plugins/ajax_spec.js b/spec/javascripts/droplab/plugins/ajax_spec.js
index 085f25764fe..2f492d00c0a 100644
--- a/spec/javascripts/droplab/plugins/ajax_spec.js
+++ b/spec/javascripts/droplab/plugins/ajax_spec.js
@@ -8,6 +8,7 @@ describe('Ajax', () => {
describe('is not configured', () => {
it('passes the data through', () => {
const data = ['data'];
+
expect(Ajax.preprocessing(config, data)).toEqual(data);
});
});
@@ -22,13 +23,17 @@ describe('Ajax', () => {
it('calls preprocessing', () => {
Ajax.preprocessing(config, []);
+
expect(config.preprocessing.calls.count()).toBe(1);
});
it('overrides AjaxCache', () => {
- spyOn(AjaxCache, 'override').and.callFake((endpoint, results) => expect(results).toEqual(processedArray));
+ spyOn(AjaxCache, 'override').and.callFake((endpoint, results) => {
+ expect(results).toEqual(processedArray);
+ });
Ajax.preprocessing(config, []);
+
expect(AjaxCache.override.calls.count()).toBe(1);
});
});
diff --git a/spec/javascripts/droplab/plugins/input_setter_spec.js b/spec/javascripts/droplab/plugins/input_setter_spec.js
index 1988811a305..711e0486bff 100644
--- a/spec/javascripts/droplab/plugins/input_setter_spec.js
+++ b/spec/javascripts/droplab/plugins/input_setter_spec.js
@@ -1,8 +1,8 @@
import InputSetter from '~/droplab/plugins/input_setter';
-describe('InputSetter', function () {
- describe('init', function () {
- beforeEach(function () {
+describe('InputSetter', function() {
+ describe('init', function() {
+ beforeEach(function() {
this.config = { InputSetter: {} };
this.hook = { config: this.config };
this.inputSetter = jasmine.createSpyObj('inputSetter', ['addEvents']);
@@ -10,60 +10,62 @@ describe('InputSetter', function () {
InputSetter.init.call(this.inputSetter, this.hook);
});
- it('should set .hook', function () {
+ it('should set .hook', function() {
expect(this.inputSetter.hook).toBe(this.hook);
});
- it('should set .config', function () {
+ it('should set .config', function() {
expect(this.inputSetter.config).toBe(this.config.InputSetter);
});
- it('should set .eventWrapper', function () {
+ it('should set .eventWrapper', function() {
expect(this.inputSetter.eventWrapper).toEqual({});
});
- it('should call .addEvents', function () {
+ it('should call .addEvents', function() {
expect(this.inputSetter.addEvents).toHaveBeenCalled();
});
- describe('if config.InputSetter is not set', function () {
- beforeEach(function () {
+ describe('if config.InputSetter is not set', function() {
+ beforeEach(function() {
this.config = { InputSetter: undefined };
this.hook = { config: this.config };
InputSetter.init.call(this.inputSetter, this.hook);
});
- it('should set .config to an empty object', function () {
+ it('should set .config to an empty object', function() {
expect(this.inputSetter.config).toEqual({});
});
- it('should set hook.config to an empty object', function () {
+ it('should set hook.config to an empty object', function() {
expect(this.hook.config.InputSetter).toEqual({});
});
- })
+ });
});
- describe('addEvents', function () {
- beforeEach(function () {
+ describe('addEvents', function() {
+ beforeEach(function() {
this.hook = { list: { list: jasmine.createSpyObj('list', ['addEventListener']) } };
this.inputSetter = { eventWrapper: {}, hook: this.hook, setInputs: () => {} };
InputSetter.addEvents.call(this.inputSetter);
});
- it('should set .eventWrapper.setInputs', function () {
+ it('should set .eventWrapper.setInputs', function() {
expect(this.inputSetter.eventWrapper.setInputs).toEqual(jasmine.any(Function));
});
- it('should call .addEventListener', function () {
- expect(this.hook.list.list.addEventListener)
- .toHaveBeenCalledWith('click.dl', this.inputSetter.eventWrapper.setInputs);
+ it('should call .addEventListener', function() {
+ expect(this.hook.list.list.addEventListener).toHaveBeenCalledWith(
+ 'click.dl',
+ this.inputSetter.eventWrapper.setInputs,
+ );
});
});
- describe('removeEvents', function () {
- beforeEach(function () {
+ describe('removeEvents', function() {
+ beforeEach(function() {
this.hook = { list: { list: jasmine.createSpyObj('list', ['removeEventListener']) } };
this.eventWrapper = jasmine.createSpyObj('eventWrapper', ['setInputs']);
this.inputSetter = { eventWrapper: this.eventWrapper, hook: this.hook };
@@ -71,14 +73,16 @@ describe('InputSetter', function () {
InputSetter.removeEvents.call(this.inputSetter);
});
- it('should call .removeEventListener', function () {
- expect(this.hook.list.list.removeEventListener)
- .toHaveBeenCalledWith('click.dl', this.eventWrapper.setInputs);
+ it('should call .removeEventListener', function() {
+ expect(this.hook.list.list.removeEventListener).toHaveBeenCalledWith(
+ 'click.dl',
+ this.eventWrapper.setInputs,
+ );
});
});
- describe('setInputs', function () {
- beforeEach(function () {
+ describe('setInputs', function() {
+ beforeEach(function() {
this.event = { detail: { selected: {} } };
this.config = [0, 1];
this.inputSetter = { config: this.config, setInput: () => {} };
@@ -88,7 +92,7 @@ describe('InputSetter', function () {
InputSetter.setInputs.call(this.inputSetter, this.event);
});
- it('should call .setInput for each config element', function () {
+ it('should call .setInput for each config element', function() {
const allArgs = this.inputSetter.setInput.calls.allArgs();
expect(allArgs.length).toEqual(2);
@@ -99,21 +103,21 @@ describe('InputSetter', function () {
});
});
- describe('if config isnt an array', function () {
- beforeEach(function () {
+ describe('if config isnt an array', function() {
+ beforeEach(function() {
this.inputSetter = { config: {}, setInput: () => {} };
InputSetter.setInputs.call(this.inputSetter, this.event);
});
- it('should set .config to an array with .config as the first element', function () {
+ it('should set .config to an array with .config as the first element', function() {
expect(this.inputSetter.config).toEqual([{}]);
});
});
});
- describe('setInput', function () {
- beforeEach(function () {
+ describe('setInput', function() {
+ beforeEach(function() {
this.selectedItem = { getAttribute: () => {} };
this.input = { value: 'oldValue', tagName: 'INPUT', hasAttribute: () => {} };
this.config = { valueAttribute: {}, input: this.input };
@@ -126,20 +130,20 @@ describe('InputSetter', function () {
InputSetter.setInput.call(this.inputSetter, this.config, this.selectedItem);
});
- it('should call .getAttribute', function () {
+ it('should call .getAttribute', function() {
expect(this.selectedItem.getAttribute).toHaveBeenCalledWith(this.config.valueAttribute);
});
- it('should call .hasAttribute', function () {
+ it('should call .hasAttribute', function() {
expect(this.input.hasAttribute).toHaveBeenCalledWith(undefined);
});
- it('should set the value of the input', function () {
+ it('should set the value of the input', function() {
expect(this.input.value).toBe(this.newValue);
});
- describe('if no config.input is provided', function () {
- beforeEach(function () {
+ describe('if no config.input is provided', function() {
+ beforeEach(function() {
this.config = { valueAttribute: {} };
this.trigger = { value: 'oldValue', tagName: 'INPUT', hasAttribute: () => {} };
this.inputSetter = { hook: { trigger: this.trigger } };
@@ -147,26 +151,26 @@ describe('InputSetter', function () {
InputSetter.setInput.call(this.inputSetter, this.config, this.selectedItem);
});
- it('should set the value of the hook.trigger', function () {
+ it('should set the value of the hook.trigger', function() {
expect(this.trigger.value).toBe(this.newValue);
});
});
- describe('if the input tag is not INPUT', function () {
- beforeEach(function () {
+ describe('if the input tag is not INPUT', function() {
+ beforeEach(function() {
this.input = { textContent: 'oldValue', tagName: 'SPAN', hasAttribute: () => {} };
this.config = { valueAttribute: {}, input: this.input };
InputSetter.setInput.call(this.inputSetter, this.config, this.selectedItem);
});
- it('should set the textContent of the input', function () {
+ it('should set the textContent of the input', function() {
expect(this.input.textContent).toBe(this.newValue);
});
});
- describe('if there is an inputAttribute', function () {
- beforeEach(function () {
+ describe('if there is an inputAttribute', function() {
+ beforeEach(function() {
this.selectedItem = { getAttribute: () => {} };
this.input = { id: 'oldValue', hasAttribute: () => {}, setAttribute: () => {} };
this.inputSetter = { hook: { trigger: {} } };
@@ -185,25 +189,25 @@ describe('InputSetter', function () {
InputSetter.setInput.call(this.inputSetter, this.config, this.selectedItem);
});
- it('should call setAttribute', function () {
+ it('should call setAttribute', function() {
expect(this.input.setAttribute).toHaveBeenCalledWith(this.inputAttribute, this.newValue);
});
- it('should not set the value or textContent of the input', function () {
+ it('should not set the value or textContent of the input', function() {
expect(this.input.value).not.toBe('newValue');
expect(this.input.textContent).not.toBe('newValue');
});
});
});
- describe('destroy', function () {
- beforeEach(function () {
+ describe('destroy', function() {
+ beforeEach(function() {
this.inputSetter = jasmine.createSpyObj('inputSetter', ['removeEvents']);
InputSetter.destroy.call(this.inputSetter);
});
- it('should call .removeEvents', function () {
+ it('should call .removeEvents', function() {
expect(this.inputSetter.removeEvents).toHaveBeenCalled();
});
});
diff --git a/spec/javascripts/dropzone_input_spec.js b/spec/javascripts/dropzone_input_spec.js
index 0c6b1a8946d..326b2c029fb 100644
--- a/spec/javascripts/dropzone_input_spec.js
+++ b/spec/javascripts/dropzone_input_spec.js
@@ -7,12 +7,10 @@ const TEST_FILE = {
};
const TEST_UPLOAD_PATH = `${TEST_HOST}/upload/file`;
const TEST_ERROR_MESSAGE = 'A big error occurred!';
-const TEMPLATE = (
-`<form class="gfm-form" data-uploads-path="${TEST_UPLOAD_PATH}">
+const TEMPLATE = `<form class="gfm-form" data-uploads-path="${TEST_UPLOAD_PATH}">
<textarea class="js-gfm-input"></textarea>
<div class="uploading-error-message"></div>
-</form>`
-);
+</form>`;
describe('dropzone_input', () => {
let form;
diff --git a/spec/javascripts/emoji_spec.js b/spec/javascripts/emoji_spec.js
index 124d91f4477..3db4d9800f1 100644
--- a/spec/javascripts/emoji_spec.js
+++ b/spec/javascripts/emoji_spec.js
@@ -140,6 +140,7 @@ describe('gl_emoji', () => {
},
);
});
+
it('bomb emoji with sprite fallback', () => {
const emojiKey = 'bomb';
const markup = glEmojiTag(emojiFixtureMap[emojiKey].name, {
@@ -195,24 +196,31 @@ describe('gl_emoji', () => {
it('should gracefully handle empty string', () => {
expect(isFlagEmoji('')).toBeFalsy();
});
+
it('should detect flag_ac', () => {
expect(isFlagEmoji('🇦🇨')).toBeTruthy();
});
+
it('should detect flag_us', () => {
expect(isFlagEmoji('🇺🇸')).toBeTruthy();
});
+
it('should detect flag_zw', () => {
expect(isFlagEmoji('🇿🇼')).toBeTruthy();
});
+
it('should not detect flags', () => {
expect(isFlagEmoji('🎏')).toBeFalsy();
});
+
it('should not detect triangular_flag_on_post', () => {
expect(isFlagEmoji('🚩')).toBeFalsy();
});
+
it('should not detect single letter', () => {
expect(isFlagEmoji('🇦')).toBeFalsy();
});
+
it('should not detect >2 letters', () => {
expect(isFlagEmoji('🇦🇧🇨')).toBeFalsy();
});
@@ -222,15 +230,19 @@ describe('gl_emoji', () => {
it('should gracefully handle empty string', () => {
expect(isRainbowFlagEmoji('')).toBeFalsy();
});
+
it('should detect rainbow_flag', () => {
expect(isRainbowFlagEmoji('🏳🌈')).toBeTruthy();
});
- it('should not detect flag_white on its\' own', () => {
+
+ it("should not detect flag_white on its' own", () => {
expect(isRainbowFlagEmoji('🏳')).toBeFalsy();
});
- it('should not detect rainbow on its\' own', () => {
+
+ it("should not detect rainbow on its' own", () => {
expect(isRainbowFlagEmoji('🌈')).toBeFalsy();
});
+
it('should not detect flag_white with something else', () => {
expect(isRainbowFlagEmoji('🏳🔵')).toBeFalsy();
});
@@ -240,15 +252,19 @@ describe('gl_emoji', () => {
it('should gracefully handle empty string', () => {
expect(isKeycapEmoji('')).toBeFalsy();
});
+
it('should detect one(keycap)', () => {
expect(isKeycapEmoji('1️⃣')).toBeTruthy();
});
+
it('should detect nine(keycap)', () => {
expect(isKeycapEmoji('9️⃣')).toBeTruthy();
});
+
it('should not detect ten(keycap)', () => {
expect(isKeycapEmoji('🔟')).toBeFalsy();
});
+
it('should not detect hash(keycap)', () => {
expect(isKeycapEmoji('#⃣')).toBeFalsy();
});
@@ -258,24 +274,31 @@ describe('gl_emoji', () => {
it('should gracefully handle empty string', () => {
expect(isSkinToneComboEmoji('')).toBeFalsy();
});
+
it('should detect hand_splayed_tone5', () => {
expect(isSkinToneComboEmoji('🖐🏿')).toBeTruthy();
});
+
it('should not detect hand_splayed', () => {
expect(isSkinToneComboEmoji('🖐')).toBeFalsy();
});
+
it('should detect lifter_tone1', () => {
expect(isSkinToneComboEmoji('🏋🏻')).toBeTruthy();
});
+
it('should not detect lifter', () => {
expect(isSkinToneComboEmoji('🏋')).toBeFalsy();
});
+
it('should detect rowboat_tone4', () => {
expect(isSkinToneComboEmoji('🚣🏾')).toBeTruthy();
});
+
it('should not detect rowboat', () => {
expect(isSkinToneComboEmoji('🚣')).toBeFalsy();
});
+
it('should not detect individual tone emoji', () => {
expect(isSkinToneComboEmoji('🏻')).toBeFalsy();
});
@@ -285,9 +308,11 @@ describe('gl_emoji', () => {
it('should gracefully handle empty string', () => {
expect(isHorceRacingSkinToneComboEmoji('')).toBeFalsy();
});
+
it('should detect horse_racing_tone2', () => {
expect(isHorceRacingSkinToneComboEmoji('🏇🏼')).toBeTruthy();
});
+
it('should not detect horse_racing', () => {
expect(isHorceRacingSkinToneComboEmoji('🏇')).toBeFalsy();
});
@@ -297,36 +322,47 @@ describe('gl_emoji', () => {
it('should gracefully handle empty string', () => {
expect(isPersonZwjEmoji('')).toBeFalsy();
});
+
it('should detect couple_mm', () => {
expect(isPersonZwjEmoji('👨‍❤️‍👨')).toBeTruthy();
});
+
it('should not detect couple_with_heart', () => {
expect(isPersonZwjEmoji('💑')).toBeFalsy();
});
+
it('should not detect couplekiss', () => {
expect(isPersonZwjEmoji('💏')).toBeFalsy();
});
+
it('should detect family_mmb', () => {
expect(isPersonZwjEmoji('👨‍👨‍👦')).toBeTruthy();
});
+
it('should detect family_mwgb', () => {
expect(isPersonZwjEmoji('👨‍👩‍👧‍👦')).toBeTruthy();
});
+
it('should not detect family', () => {
expect(isPersonZwjEmoji('👪')).toBeFalsy();
});
+
it('should detect kiss_ww', () => {
expect(isPersonZwjEmoji('👩‍❤️‍💋‍👩')).toBeTruthy();
});
+
it('should not detect girl', () => {
expect(isPersonZwjEmoji('👧')).toBeFalsy();
});
+
it('should not detect girl_tone5', () => {
expect(isPersonZwjEmoji('👧🏿')).toBeFalsy();
});
+
it('should not detect man', () => {
expect(isPersonZwjEmoji('👨')).toBeFalsy();
});
+
it('should not detect woman', () => {
expect(isPersonZwjEmoji('👩')).toBeFalsy();
});
@@ -334,21 +370,17 @@ describe('gl_emoji', () => {
describe('isEmojiUnicodeSupported', () => {
it('should gracefully handle empty string with unicode support', () => {
- const isSupported = isEmojiUnicodeSupported(
- { '1.0': true },
- '',
- '1.0',
- );
+ const isSupported = isEmojiUnicodeSupported({ '1.0': true }, '', '1.0');
+
expect(isSupported).toBeTruthy();
});
+
it('should gracefully handle empty string without unicode support', () => {
- const isSupported = isEmojiUnicodeSupported(
- {},
- '',
- '1.0',
- );
+ const isSupported = isEmojiUnicodeSupported({}, '', '1.0');
+
expect(isSupported).toBeFalsy();
});
+
it('bomb(6.0) with 6.0 support', () => {
const emojiKey = 'bomb';
const unicodeSupportMap = Object.assign({}, emptySupportMap, {
@@ -359,6 +391,7 @@ describe('gl_emoji', () => {
emojiFixtureMap[emojiKey].moji,
emojiFixtureMap[emojiKey].unicodeVersion,
);
+
expect(isSupported).toBeTruthy();
});
@@ -370,6 +403,7 @@ describe('gl_emoji', () => {
emojiFixtureMap[emojiKey].moji,
emojiFixtureMap[emojiKey].unicodeVersion,
);
+
expect(isSupported).toBeFalsy();
});
@@ -383,6 +417,7 @@ describe('gl_emoji', () => {
emojiFixtureMap[emojiKey].moji,
emojiFixtureMap[emojiKey].unicodeVersion,
);
+
expect(isSupported).toBeFalsy();
});
@@ -408,6 +443,7 @@ describe('gl_emoji', () => {
emojiFixtureMap[emojiKey].moji,
emojiFixtureMap[emojiKey].unicodeVersion,
);
+
expect(isSupported).toBeFalsy();
});
@@ -425,6 +461,7 @@ describe('gl_emoji', () => {
emojiFixtureMap[emojiKey].moji,
emojiFixtureMap[emojiKey].unicodeVersion,
);
+
expect(isSupported).toBeTruthy();
});
@@ -442,6 +479,7 @@ describe('gl_emoji', () => {
emojiFixtureMap[emojiKey].moji,
emojiFixtureMap[emojiKey].unicodeVersion,
);
+
expect(isSupported).toBeFalsy();
});
});
diff --git a/spec/javascripts/environments/emtpy_state_spec.js b/spec/javascripts/environments/emtpy_state_spec.js
index 10a19af4175..d71dfe8197e 100644
--- a/spec/javascripts/environments/emtpy_state_spec.js
+++ b/spec/javascripts/environments/emtpy_state_spec.js
@@ -27,7 +27,7 @@ describe('environments empty state', () => {
it('renders empty state and new environment button', () => {
expect(
vm.$el.querySelector('.js-blank-state-title').textContent.trim(),
- ).toEqual('You don\'t have any environments right now.');
+ ).toEqual('You don\'t have any environments right now');
expect(
vm.$el.querySelector('.js-new-environment-button').getAttribute('href'),
@@ -47,7 +47,7 @@ describe('environments empty state', () => {
it('renders empty state without new button', () => {
expect(
vm.$el.querySelector('.js-blank-state-title').textContent.trim(),
- ).toEqual('You don\'t have any environments right now.');
+ ).toEqual('You don\'t have any environments right now');
expect(
vm.$el.querySelector('.js-new-environment-button'),
diff --git a/spec/javascripts/environments/environment_actions_spec.js b/spec/javascripts/environments/environment_actions_spec.js
index ea40a1fcd4b..223153d4e31 100644
--- a/spec/javascripts/environments/environment_actions_spec.js
+++ b/spec/javascripts/environments/environment_actions_spec.js
@@ -40,23 +40,28 @@ describe('Actions Component', () => {
it('should render a dropdown button with icon and title attribute', () => {
expect(component.$el.querySelector('.fa-caret-down')).toBeDefined();
- expect(component.$el.querySelector('.dropdown-new').getAttribute('data-original-title')).toEqual('Deploy to...');
- expect(component.$el.querySelector('.dropdown-new').getAttribute('aria-label')).toEqual('Deploy to...');
+ expect(
+ component.$el.querySelector('.dropdown-new').getAttribute('data-original-title'),
+ ).toEqual('Deploy to...');
+
+ expect(component.$el.querySelector('.dropdown-new').getAttribute('aria-label')).toEqual(
+ 'Deploy to...',
+ );
});
it('should render a dropdown with the provided list of actions', () => {
- expect(
- component.$el.querySelectorAll('.dropdown-menu li').length,
- ).toEqual(actionsMock.length);
+ expect(component.$el.querySelectorAll('.dropdown-menu li').length).toEqual(actionsMock.length);
});
- it('should render a disabled action when it\'s not playable', () => {
+ it("should render a disabled action when it's not playable", () => {
expect(
component.$el.querySelector('.dropdown-menu li:last-child button').getAttribute('disabled'),
).toEqual('disabled');
expect(
- component.$el.querySelector('.dropdown-menu li:last-child button').classList.contains('disabled'),
+ component.$el
+ .querySelector('.dropdown-menu li:last-child button')
+ .classList.contains('disabled'),
).toEqual(true);
});
});
diff --git a/spec/javascripts/environments/environments_app_spec.js b/spec/javascripts/environments/environments_app_spec.js
index 6968fbc7ce7..7edc0ccac0b 100644
--- a/spec/javascripts/environments/environments_app_spec.js
+++ b/spec/javascripts/environments/environments_app_spec.js
@@ -50,7 +50,7 @@ describe('Environment', () => {
expect(
component.$el.querySelector('.js-blank-state-title').textContent,
- ).toContain('You don\'t have any environments right now.');
+ ).toContain('You don\'t have any environments right now');
});
});
@@ -94,6 +94,7 @@ describe('Environment', () => {
spyOn(component, 'updateContent');
setTimeout(() => {
component.$el.querySelector('.gl-pagination li:nth-child(5) a').click();
+
expect(component.updateContent).toHaveBeenCalledWith({ scope: 'available', page: '2' });
done();
}, 0);
@@ -126,7 +127,7 @@ describe('Environment', () => {
it('should render empty state', () => {
expect(
component.$el.querySelector('.js-blank-state-title').textContent,
- ).toContain('You don\'t have any environments right now.');
+ ).toContain('You don\'t have any environments right now');
});
});
@@ -158,12 +159,7 @@ describe('Environment', () => {
component.$el.querySelector('.folder-name').click();
Vue.nextTick(() => {
- expect(
- component.$el.querySelector('.folder-icon i.fa-caret-right').getAttribute('style'),
- ).toContain('display: none');
- expect(
- component.$el.querySelector('.folder-icon i.fa-caret-down').getAttribute('style'),
- ).not.toContain('display: none');
+ expect(component.$el.querySelector('.folder-icon.ic-chevron-right')).toBe(null);
done();
});
}, 0);
@@ -179,12 +175,7 @@ describe('Environment', () => {
component.$el.querySelector('.folder-name').click();
Vue.nextTick(() => {
- expect(
- component.$el.querySelector('.folder-icon i.fa-caret-down').getAttribute('style'),
- ).toContain('display: none');
- expect(
- component.$el.querySelector('.folder-icon i.fa-caret-right').getAttribute('style'),
- ).not.toContain('display: none');
+ expect(component.$el.querySelector('.folder-icon.ic-chevron-down')).toBe(null);
done();
});
});
diff --git a/spec/javascripts/environments/environments_store_spec.js b/spec/javascripts/environments/environments_store_spec.js
index f2c6ec24dd7..c3d16f10d72 100644
--- a/spec/javascripts/environments/environments_store_spec.js
+++ b/spec/javascripts/environments/environments_store_spec.js
@@ -17,23 +17,27 @@ describe('Store', () => {
it('should store environments', () => {
store.storeEnvironments(serverData);
+
expect(store.state.environments.length).toEqual(serverData.length);
expect(store.state.environments[0]).toEqual(environmentsList[0]);
});
it('should store available count', () => {
store.storeAvailableCount(2);
+
expect(store.state.availableCounter).toEqual(2);
});
it('should store stopped count', () => {
store.storeStoppedCount(2);
+
expect(store.state.stoppedCounter).toEqual(2);
});
describe('store environments', () => {
it('should store environments', () => {
store.storeEnvironments(serverData);
+
expect(store.state.environments.length).toEqual(serverData.length);
});
@@ -45,6 +49,7 @@ describe('Store', () => {
};
store.storeEnvironments([environment]);
+
expect(store.state.environments[0].isFolder).toEqual(true);
expect(store.state.environments[0].folderName).toEqual('bar');
});
@@ -61,17 +66,20 @@ describe('Store', () => {
};
store.storeEnvironments([environment]);
+
expect(store.state.environments[0].last_deployment).toEqual({});
expect(store.state.environments[0].isStoppable).toEqual(true);
});
it('should store latest.name when the environment is not a folder', () => {
store.storeEnvironments(serverData);
+
expect(store.state.environments[0].name).toEqual(serverData[0].latest.name);
});
it('should store root level name when environment is a folder', () => {
store.storeEnvironments(serverData);
+
expect(store.state.environments[1].folderName).toEqual(serverData[1].name);
});
});
@@ -81,9 +89,11 @@ describe('Store', () => {
store.storeEnvironments(serverData);
store.toggleFolder(store.state.environments[1]);
+
expect(store.state.environments[1].isOpen).toEqual(true);
store.toggleFolder(store.state.environments[1]);
+
expect(store.state.environments[1].isOpen).toEqual(false);
});
@@ -91,9 +101,11 @@ describe('Store', () => {
store.storeEnvironments(serverData);
store.toggleFolder(store.state.environments[1]);
+
expect(store.state.environments[1].isOpen).toEqual(true);
store.storeEnvironments(serverData);
+
expect(store.state.environments[1].isOpen).toEqual(true);
});
});
@@ -116,6 +128,7 @@ describe('Store', () => {
expect(store.state.environments[1].children.length).toEqual(serverData.length);
// poll
store.storeEnvironments(serverData);
+
expect(store.state.environments[1].children.length).toEqual(serverData.length);
});
});
@@ -141,6 +154,7 @@ describe('Store', () => {
};
store.setPagination(pagination);
+
expect(store.state.paginationInformation).toEqual(expectedResult);
});
});
@@ -150,6 +164,7 @@ describe('Store', () => {
store.storeEnvironments(serverData);
store.toggleFolder(store.state.environments[1]);
+
expect(store.getOpenFolders()[0]).toEqual(store.state.environments[1]);
});
});
diff --git a/spec/javascripts/feature_highlight/feature_highlight_helper_spec.js b/spec/javascripts/feature_highlight/feature_highlight_helper_spec.js
index 2ab6a0077b5..e5795d4cbb1 100644
--- a/spec/javascripts/feature_highlight/feature_highlight_helper_spec.js
+++ b/spec/javascripts/feature_highlight/feature_highlight_helper_spec.js
@@ -1,11 +1,7 @@
import $ from 'jquery';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
-import {
- getSelector,
- dismiss,
- inserted,
-} from '~/feature_highlight/feature_highlight_helper';
+import { getSelector, dismiss, inserted } from '~/feature_highlight/feature_highlight_helper';
import { togglePopover } from '~/shared/popover';
import getSetTimeoutPromise from 'spec/helpers/set_timeout_promise_helper';
@@ -14,7 +10,10 @@ describe('feature highlight helper', () => {
describe('getSelector', () => {
it('returns js-feature-highlight selector', () => {
const highlightId = 'highlightId';
- expect(getSelector(highlightId)).toEqual(`.js-feature-highlight[data-highlight=${highlightId}]`);
+
+ expect(getSelector(highlightId)).toEqual(
+ `.js-feature-highlight[data-highlight=${highlightId}]`,
+ );
});
});
@@ -37,7 +36,7 @@ describe('feature highlight helper', () => {
mock.restore();
});
- it('calls persistent dismissal endpoint', (done) => {
+ it('calls persistent dismissal endpoint', done => {
const spy = jasmine.createSpy('dismiss-endpoint-hit');
mock.onPost('/-/callouts/dismiss').reply(spy);
@@ -59,7 +58,7 @@ describe('feature highlight helper', () => {
});
describe('inserted', () => {
- it('registers click event callback', (done) => {
+ it('registers click event callback', done => {
const context = {
getAttribute: () => 'popoverId',
dataset: {
@@ -67,7 +66,7 @@ describe('feature highlight helper', () => {
},
};
- spyOn($.fn, 'on').and.callFake((event) => {
+ spyOn($.fn, 'on').and.callFake(event => {
expect(event).toEqual('click');
done();
});
diff --git a/spec/javascripts/feature_highlight/feature_highlight_spec.js b/spec/javascripts/feature_highlight/feature_highlight_spec.js
index ec46d4f905a..0a9fba789c3 100644
--- a/spec/javascripts/feature_highlight/feature_highlight_spec.js
+++ b/spec/javascripts/feature_highlight/feature_highlight_spec.js
@@ -50,7 +50,7 @@ describe('feature highlight', () => {
expect(toggleSpy).toHaveBeenCalledWith(jasmine.any(Object), true);
});
- it('setup debounced mouseleave', (done) => {
+ it('setup debounced mouseleave', done => {
const toggleSpy = spyOn(popover.togglePopover, 'call');
$(selector).trigger('mouseleave');
@@ -63,7 +63,10 @@ describe('feature highlight', () => {
it('setup show.bs.popover', () => {
$(selector).trigger('show.bs.popover');
- expect(window.addEventListener).toHaveBeenCalledWith('scroll', jasmine.any(Function), { once: true });
+
+ expect(window.addEventListener).toHaveBeenCalledWith('scroll', jasmine.any(Function), {
+ once: true,
+ });
});
it('removes disabled attribute', () => {
@@ -73,6 +76,7 @@ describe('feature highlight', () => {
it('displays popover', () => {
expect(document.querySelector(selector).getAttribute('aria-describedby')).toBeFalsy();
$(selector).trigger('mouseenter');
+
expect(document.querySelector(selector).getAttribute('aria-describedby')).toBeTruthy();
});
diff --git a/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js b/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js
index 9d670afe206..d1742dcedfa 100644
--- a/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js
+++ b/spec/javascripts/filtered_search/components/recent_searches_dropdown_content_spec.js
@@ -3,7 +3,7 @@ import eventHub from '~/filtered_search/event_hub';
import RecentSearchesDropdownContent from '~/filtered_search/components/recent_searches_dropdown_content.vue';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
-const createComponent = (propsData) => {
+const createComponent = propsData => {
const Component = Vue.extend(RecentSearchesDropdownContent);
return new Component({
@@ -21,10 +21,7 @@ describe('RecentSearchesDropdownContent', () => {
allowedKeys: IssuableFilteredSearchTokenKeys.getKeys(),
};
const propsDataWithItems = {
- items: [
- 'foo',
- 'author:@root label:~foo bar',
- ],
+ items: ['foo', 'author:@root label:~foo bar'],
allowedKeys: IssuableFilteredSearchTokenKeys.getKeys(),
};
@@ -47,6 +44,7 @@ describe('RecentSearchesDropdownContent', () => {
expect(el.querySelector('.dropdown-info-note')).toBeDefined();
const items = el.querySelectorAll('.filtered-search-history-dropdown-item');
+
expect(items.length).toEqual(propsDataWithoutItems.items.length);
});
});
@@ -65,17 +63,27 @@ describe('RecentSearchesDropdownContent', () => {
it('should render recent search items', () => {
const items = el.querySelectorAll('.filtered-search-history-dropdown-item');
+
expect(items.length).toEqual(propsDataWithItems.items.length);
- expect(trimMarkupWhitespace(items[0].querySelector('.filtered-search-history-dropdown-search-token').textContent)).toEqual('foo');
+ expect(
+ trimMarkupWhitespace(
+ items[0].querySelector('.filtered-search-history-dropdown-search-token').textContent,
+ ),
+ ).toEqual('foo');
const item1Tokens = items[1].querySelectorAll('.filtered-search-history-dropdown-token');
+
expect(item1Tokens.length).toEqual(2);
expect(item1Tokens[0].querySelector('.name').textContent).toEqual('author:');
expect(item1Tokens[0].querySelector('.value').textContent).toEqual('@root');
expect(item1Tokens[1].querySelector('.name').textContent).toEqual('label:');
expect(item1Tokens[1].querySelector('.value').textContent).toEqual('~foo');
- expect(trimMarkupWhitespace(items[1].querySelector('.filtered-search-history-dropdown-search-token').textContent)).toEqual('bar');
+ expect(
+ trimMarkupWhitespace(
+ items[1].querySelector('.filtered-search-history-dropdown-search-token').textContent,
+ ),
+ ).toEqual('bar');
});
});
@@ -132,12 +140,14 @@ describe('RecentSearchesDropdownContent', () => {
it('with items', () => {
vm = createComponent(propsDataWithItems);
const { hasItems } = vm;
+
expect(hasItems).toEqual(true);
});
it('with no items', () => {
vm = createComponent(propsDataWithoutItems);
const { hasItems } = vm;
+
expect(hasItems).toEqual(false);
});
});
@@ -161,6 +171,7 @@ describe('RecentSearchesDropdownContent', () => {
it('emits event', () => {
expect(onRecentSearchesItemSelectedSpy).not.toHaveBeenCalled();
vm.onItemActivated('something');
+
expect(onRecentSearchesItemSelectedSpy).toHaveBeenCalledWith('something');
});
});
@@ -182,6 +193,7 @@ describe('RecentSearchesDropdownContent', () => {
it('emits event', () => {
expect(onRequestClearRecentSearchesSpy).not.toHaveBeenCalled();
vm.onRequestClearRecentSearches({ stopPropagation: () => {} });
+
expect(onRequestClearRecentSearchesSpy).toHaveBeenCalled();
});
});
diff --git a/spec/javascripts/filtered_search/dropdown_user_spec.js b/spec/javascripts/filtered_search/dropdown_user_spec.js
index b48b1456eff..e8fcc8592eb 100644
--- a/spec/javascripts/filtered_search/dropdown_user_spec.js
+++ b/spec/javascripts/filtered_search/dropdown_user_spec.js
@@ -28,14 +28,14 @@ describe('Dropdown User', () => {
it('should not return the single quote found in value', () => {
spyOn(FilteredSearchTokenizer, 'processTokens').and.returnValue({
- lastToken: '\'larry boy',
+ lastToken: "'larry boy",
});
expect(dropdownUser.getSearchInput()).toBe('larry boy');
});
});
- describe('config AjaxFilter\'s endpoint', () => {
+ describe("config AjaxFilter's endpoint", () => {
beforeEach(() => {
spyOn(DropdownUser.prototype, 'bindEvents').and.callFake(() => {});
spyOn(DropdownUser.prototype, 'getProjectId').and.callFake(() => {});
@@ -88,10 +88,12 @@ describe('Dropdown User', () => {
});
});
- const findCurrentUserElement = () => authorFilterDropdownElement.querySelector('.js-current-user');
+ const findCurrentUserElement = () =>
+ authorFilterDropdownElement.querySelector('.js-current-user');
it('hides the current user from dropdown', () => {
const currentUserElement = findCurrentUserElement();
+
expect(currentUserElement).not.toBe(null);
dropdown.hideCurrentUser();
@@ -102,6 +104,7 @@ describe('Dropdown User', () => {
it('does nothing if no user is logged in', () => {
const currentUserElement = findCurrentUserElement();
currentUserElement.parentNode.removeChild(currentUserElement);
+
expect(findCurrentUserElement()).toBe(null);
dropdown.hideCurrentUser();
diff --git a/spec/javascripts/filtered_search/dropdown_utils_spec.js b/spec/javascripts/filtered_search/dropdown_utils_spec.js
index 68bbbf838da..6605b0a30d7 100644
--- a/spec/javascripts/filtered_search/dropdown_utils_spec.js
+++ b/spec/javascripts/filtered_search/dropdown_utils_spec.js
@@ -10,25 +10,30 @@ describe('Dropdown Utils', () => {
describe('getEscapedText', () => {
it('should return same word when it has no space', () => {
const escaped = DropdownUtils.getEscapedText('textWithoutSpace');
+
expect(escaped).toBe('textWithoutSpace');
});
it('should escape with double quotes', () => {
let escaped = DropdownUtils.getEscapedText('text with space');
+
expect(escaped).toBe('"text with space"');
- escaped = DropdownUtils.getEscapedText('won\'t fix');
+ escaped = DropdownUtils.getEscapedText("won't fix");
+
expect(escaped).toBe('"won\'t fix"');
});
it('should escape with single quotes', () => {
const escaped = DropdownUtils.getEscapedText('won"t fix');
- expect(escaped).toBe('\'won"t fix\'');
+
+ expect(escaped).toBe("'won\"t fix'");
});
it('should escape with single quotes by default', () => {
const escaped = DropdownUtils.getEscapedText('won"t\' fix');
- expect(escaped).toBe('\'won"t\' fix\'');
+
+ expect(escaped).toBe("'won\"t' fix'");
});
});
@@ -50,6 +55,7 @@ describe('Dropdown Utils', () => {
input.value = 'roo';
const updatedItem = DropdownUtils.filterWithSymbol('@', input, item);
+
expect(updatedItem.droplab_hidden).toBe(false);
});
@@ -57,6 +63,7 @@ describe('Dropdown Utils', () => {
input.value = '@roo';
const updatedItem = DropdownUtils.filterWithSymbol('@', input, item);
+
expect(updatedItem.droplab_hidden).toBe(false);
});
@@ -69,6 +76,7 @@ describe('Dropdown Utils', () => {
input.value = '"';
const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+
expect(updatedItem.droplab_hidden).toBe(false);
});
@@ -76,6 +84,7 @@ describe('Dropdown Utils', () => {
input.value = '~"';
const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+
expect(updatedItem.droplab_hidden).toBe(false);
});
@@ -83,6 +92,7 @@ describe('Dropdown Utils', () => {
input.value = '"community con';
const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+
expect(updatedItem.droplab_hidden).toBe(false);
});
@@ -90,34 +100,39 @@ describe('Dropdown Utils', () => {
input.value = '~"community con';
const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+
expect(updatedItem.droplab_hidden).toBe(false);
});
it('should filter with single quote', () => {
- input.value = '\'';
+ input.value = "'";
const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+
expect(updatedItem.droplab_hidden).toBe(false);
});
it('should filter with single quote and symbol', () => {
- input.value = '~\'';
+ input.value = "~'";
const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+
expect(updatedItem.droplab_hidden).toBe(false);
});
it('should filter with single quote and multiple words', () => {
- input.value = '\'community con';
+ input.value = "'community con";
const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+
expect(updatedItem.droplab_hidden).toBe(false);
});
it('should filter with single quote, symbol and multiple words', () => {
- input.value = '~\'community con';
+ input.value = "~'community con";
const updatedItem = DropdownUtils.filterWithSymbol('~', input, multipleWordItem);
+
expect(updatedItem.droplab_hidden).toBe(false);
});
});
@@ -152,17 +167,20 @@ describe('Dropdown Utils', () => {
let updatedItem = DropdownUtils.filterHint(config(), {
hint: 'label',
});
+
expect(updatedItem.droplab_hidden).toBe(false);
input.value = 'o';
updatedItem = DropdownUtils.filterHint(config(), {
hint: 'label',
});
+
expect(updatedItem.droplab_hidden).toBe(true);
});
it('should return droplab_hidden false when item has no hint', () => {
const updatedItem = DropdownUtils.filterHint(config(), {}, '');
+
expect(updatedItem.droplab_hidden).toBe(false);
});
@@ -172,6 +190,7 @@ describe('Dropdown Utils', () => {
hint: 'label',
type: 'array',
});
+
expect(updatedItem.droplab_hidden).toBe(false);
});
@@ -180,12 +199,14 @@ describe('Dropdown Utils', () => {
let updatedItem = DropdownUtils.filterHint(config(), {
hint: 'milestone',
});
+
expect(updatedItem.droplab_hidden).toBe(true);
updatedItem = DropdownUtils.filterHint(config(), {
hint: 'milestone',
type: 'string',
});
+
expect(updatedItem.droplab_hidden).toBe(true);
});
});
@@ -205,6 +226,7 @@ describe('Dropdown Utils', () => {
};
const updated = DropdownUtils.mergeDuplicateLabels(dataMap, newLabel);
+
expect(updated[newLabel.title]).toEqual(newLabel);
});
@@ -215,6 +237,7 @@ describe('Dropdown Utils', () => {
};
const updated = DropdownUtils.mergeDuplicateLabels(dataMap, duplicate);
+
expect(updated.label.multipleColors).toEqual([dataMap.label.color, duplicate.color]);
});
});
@@ -222,39 +245,64 @@ describe('Dropdown Utils', () => {
describe('duplicateLabelColor', () => {
it('should linear-gradient 2 colors', () => {
const gradient = DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000']);
- expect(gradient).toEqual('linear-gradient(#FFFFFF 0%, #FFFFFF 50%, #000000 50%, #000000 100%)');
+
+ expect(gradient).toEqual(
+ 'linear-gradient(#FFFFFF 0%, #FFFFFF 50%, #000000 50%, #000000 100%)',
+ );
});
it('should linear-gradient 3 colors', () => {
const gradient = DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000', '#333333']);
- expect(gradient).toEqual('linear-gradient(#FFFFFF 0%, #FFFFFF 33%, #000000 33%, #000000 66%, #333333 66%, #333333 100%)');
+
+ expect(gradient).toEqual(
+ 'linear-gradient(#FFFFFF 0%, #FFFFFF 33%, #000000 33%, #000000 66%, #333333 66%, #333333 100%)',
+ );
});
it('should linear-gradient 4 colors', () => {
- const gradient = DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000', '#333333', '#DDDDDD']);
- expect(gradient).toEqual('linear-gradient(#FFFFFF 0%, #FFFFFF 25%, #000000 25%, #000000 50%, #333333 50%, #333333 75%, #DDDDDD 75%, #DDDDDD 100%)');
+ const gradient = DropdownUtils.duplicateLabelColor([
+ '#FFFFFF',
+ '#000000',
+ '#333333',
+ '#DDDDDD',
+ ]);
+
+ expect(gradient).toEqual(
+ 'linear-gradient(#FFFFFF 0%, #FFFFFF 25%, #000000 25%, #000000 50%, #333333 50%, #333333 75%, #DDDDDD 75%, #DDDDDD 100%)',
+ );
});
it('should not linear-gradient more than 4 colors', () => {
- const gradient = DropdownUtils.duplicateLabelColor(['#FFFFFF', '#000000', '#333333', '#DDDDDD', '#EEEEEE']);
- expect(gradient.indexOf('#EEEEEE') === -1).toEqual(true);
+ const gradient = DropdownUtils.duplicateLabelColor([
+ '#FFFFFF',
+ '#000000',
+ '#333333',
+ '#DDDDDD',
+ '#EEEEEE',
+ ]);
+
+ expect(gradient.indexOf('#EEEEEE')).toBe(-1);
});
});
describe('duplicateLabelPreprocessing', () => {
it('should set preprocessed to true', () => {
const results = DropdownUtils.duplicateLabelPreprocessing([]);
+
expect(results.preprocessed).toEqual(true);
});
it('should not mutate existing data if there are no duplicates', () => {
- const data = [{
- title: 'label1',
- color: '#FFFFFF',
- }, {
- title: 'label2',
- color: '#000000',
- }];
+ const data = [
+ {
+ title: 'label1',
+ color: '#FFFFFF',
+ },
+ {
+ title: 'label2',
+ color: '#000000',
+ },
+ ];
const results = DropdownUtils.duplicateLabelPreprocessing(data);
expect(results.length).toEqual(2);
@@ -263,13 +311,16 @@ describe('Dropdown Utils', () => {
});
describe('duplicate labels', () => {
- const data = [{
- title: 'label',
- color: '#FFFFFF',
- }, {
- title: 'label',
- color: '#000000',
- }];
+ const data = [
+ {
+ title: 'label',
+ color: '#FFFFFF',
+ },
+ {
+ title: 'label',
+ color: '#000000',
+ },
+ ];
const results = DropdownUtils.duplicateLabelPreprocessing(data);
it('should merge duplicate labels', () => {
@@ -298,6 +349,7 @@ describe('Dropdown Utils', () => {
};
DropdownUtils.setDataValueIfSelected(null, selected);
+
expect(FilteredSearchDropdownManager.addWordToInput.calls.count()).toEqual(1);
});
@@ -308,6 +360,7 @@ describe('Dropdown Utils', () => {
};
const result = DropdownUtils.setDataValueIfSelected(null, selected);
+
expect(result).toBe(true);
});
@@ -317,6 +370,7 @@ describe('Dropdown Utils', () => {
};
const result = DropdownUtils.setDataValueIfSelected(null, selected);
+
expect(result).toBe(false);
});
});
diff --git a/spec/javascripts/filtered_search/filtered_search_manager_spec.js b/spec/javascripts/filtered_search/filtered_search_manager_spec.js
index a03d5a31b41..e076120f5cc 100644
--- a/spec/javascripts/filtered_search/filtered_search_manager_spec.js
+++ b/spec/javascripts/filtered_search/filtered_search_manager_spec.js
@@ -9,7 +9,7 @@ import FilteredSearchDropdownManager from '~/filtered_search/filtered_search_dro
import FilteredSearchManager from '~/filtered_search/filtered_search_manager';
import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper';
-describe('Filtered Search Manager', function () {
+describe('Filtered Search Manager', function() {
let input;
let manager;
let tokensContainer;
@@ -97,7 +97,9 @@ describe('Filtered Search Manager', function () {
});
it('should not instantiate Flash if an RecentSearchesServiceError is caught', () => {
- spyOn(RecentSearchesService.prototype, 'fetch').and.callFake(() => Promise.reject(new RecentSearchesServiceError()));
+ spyOn(RecentSearchesService.prototype, 'fetch').and.callFake(() =>
+ Promise.reject(new RecentSearchesServiceError()),
+ );
spyOn(window, 'Flash');
manager.setup();
@@ -134,6 +136,7 @@ describe('Filtered Search Manager', function () {
};
manager.searchState(e);
+
expect(FilteredSearchManager.prototype.search).not.toHaveBeenCalled();
});
@@ -149,6 +152,7 @@ describe('Filtered Search Manager', function () {
};
manager.searchState(e);
+
expect(FilteredSearchManager.prototype.search).toHaveBeenCalledWith('opened');
});
});
@@ -160,10 +164,10 @@ describe('Filtered Search Manager', function () {
initializeManager();
});
- it('should search with a single word', (done) => {
+ it('should search with a single word', done => {
input.value = 'searchTerm';
- spyOnDependency(FilteredSearchManager, 'visitUrl').and.callFake((url) => {
+ spyOnDependency(FilteredSearchManager, 'visitUrl').and.callFake(url => {
expect(url).toEqual(`${defaultParams}&search=searchTerm`);
done();
});
@@ -171,10 +175,10 @@ describe('Filtered Search Manager', function () {
manager.search();
});
- it('should search with multiple words', (done) => {
+ it('should search with multiple words', done => {
input.value = 'awesome search terms';
- spyOnDependency(FilteredSearchManager, 'visitUrl').and.callFake((url) => {
+ spyOnDependency(FilteredSearchManager, 'visitUrl').and.callFake(url => {
expect(url).toEqual(`${defaultParams}&search=awesome+search+terms`);
done();
});
@@ -182,24 +186,26 @@ describe('Filtered Search Manager', function () {
manager.search();
});
- it('should search with special characters', (done) => {
+ it('should search with special characters', done => {
input.value = '~!@#$%^&*()_+{}:<>,.?/';
- spyOnDependency(FilteredSearchManager, 'visitUrl').and.callFake((url) => {
- expect(url).toEqual(`${defaultParams}&search=~!%40%23%24%25%5E%26*()_%2B%7B%7D%3A%3C%3E%2C.%3F%2F`);
+ spyOnDependency(FilteredSearchManager, 'visitUrl').and.callFake(url => {
+ expect(url).toEqual(
+ `${defaultParams}&search=~!%40%23%24%25%5E%26*()_%2B%7B%7D%3A%3C%3E%2C.%3F%2F`,
+ );
done();
});
manager.search();
});
- it('removes duplicated tokens', (done) => {
+ it('removes duplicated tokens', done => {
tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '~bug')}
${FilteredSearchSpecHelper.createFilterVisualTokenHTML('label', '~bug')}
`);
- spyOnDependency(FilteredSearchManager, 'visitUrl').and.callFake((url) => {
+ spyOnDependency(FilteredSearchManager, 'visitUrl').and.callFake(url => {
expect(url).toEqual(`${defaultParams}&label_name[]=bug`);
done();
});
@@ -304,6 +310,7 @@ describe('Filtered Search Manager', function () {
);
tokensContainer.querySelector('.js-visual-token .remove-token').click();
+
expect(tokensContainer.querySelector('.js-visual-token')).toEqual(null);
});
@@ -437,12 +444,18 @@ describe('Filtered Search Manager', function () {
it('toggles on focus', () => {
input.focus();
- expect(document.querySelector('.filtered-search-box').classList.contains('focus')).toEqual(true);
+
+ expect(document.querySelector('.filtered-search-box').classList.contains('focus')).toEqual(
+ true,
+ );
});
it('toggles on blur', () => {
input.blur();
- expect(document.querySelector('.filtered-search-box').classList.contains('focus')).toEqual(false);
+
+ expect(document.querySelector('.filtered-search-box').classList.contains('focus')).toEqual(
+ false,
+ );
});
});
@@ -454,9 +467,12 @@ describe('Filtered Search Manager', function () {
});
it('correctly modifies params when custom modifier is passed', () => {
- const modifedParams = manager.getAllParams.call({
- modifyUrlParams: paramsArr => paramsArr.reverse(),
- }, [].concat(this.paramsArr));
+ const modifedParams = manager.getAllParams.call(
+ {
+ modifyUrlParams: paramsArr => paramsArr.reverse(),
+ },
+ [].concat(this.paramsArr),
+ );
expect(modifedParams[0]).toBe(this.paramsArr[1]);
});
diff --git a/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js b/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js
index ab0ab72720e..d1fea18dea8 100644
--- a/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js
+++ b/spec/javascripts/filtered_search/filtered_search_token_keys_spec.js
@@ -1,25 +1,28 @@
import FilteredSearchTokenKeys from '~/filtered_search/filtered_search_token_keys';
describe('Filtered Search Token Keys', () => {
- const tokenKeys = [{
- key: 'author',
- type: 'string',
- param: 'username',
- symbol: '@',
- icon: 'pencil',
- tag: '@author',
- }];
-
- const conditions = [{
- url: 'assignee_id=0',
- tokenKey: 'assignee',
- value: 'none',
- }];
+ const tokenKeys = [
+ {
+ key: 'author',
+ type: 'string',
+ param: 'username',
+ symbol: '@',
+ icon: 'pencil',
+ tag: '@author',
+ },
+ ];
+
+ const conditions = [
+ {
+ url: 'assignee_id=0',
+ tokenKey: 'assignee',
+ value: 'none',
+ },
+ ];
describe('get', () => {
-
it('should return tokenKeys', () => {
- expect(new FilteredSearchTokenKeys().get() !== null).toBe(true);
+ expect(new FilteredSearchTokenKeys().get()).not.toBeNull();
});
it('should return tokenKeys as an array', () => {
@@ -40,7 +43,7 @@ describe('Filtered Search Token Keys', () => {
describe('getConditions', () => {
it('should return conditions', () => {
- expect(new FilteredSearchTokenKeys().getConditions() !== null).toBe(true);
+ expect(new FilteredSearchTokenKeys().getConditions()).not.toBeNull();
});
it('should return conditions as an array', () => {
@@ -51,11 +54,13 @@ describe('Filtered Search Token Keys', () => {
describe('searchByKey', () => {
it('should return null when key not found', () => {
const tokenKey = new FilteredSearchTokenKeys(tokenKeys).searchByKey('notakey');
- expect(tokenKey === null).toBe(true);
+
+ expect(tokenKey).toBeNull();
});
it('should return tokenKey when found by key', () => {
const result = new FilteredSearchTokenKeys(tokenKeys).searchByKey(tokenKeys[0].key);
+
expect(result).toEqual(tokenKeys[0]);
});
});
@@ -63,11 +68,13 @@ describe('Filtered Search Token Keys', () => {
describe('searchBySymbol', () => {
it('should return null when symbol not found', () => {
const tokenKey = new FilteredSearchTokenKeys(tokenKeys).searchBySymbol('notasymbol');
- expect(tokenKey === null).toBe(true);
+
+ expect(tokenKey).toBeNull();
});
it('should return tokenKey when found by symbol', () => {
const result = new FilteredSearchTokenKeys(tokenKeys).searchBySymbol(tokenKeys[0].symbol);
+
expect(result).toEqual(tokenKeys[0]);
});
});
@@ -75,16 +82,23 @@ describe('Filtered Search Token Keys', () => {
describe('searchByKeyParam', () => {
it('should return null when key param not found', () => {
const tokenKey = new FilteredSearchTokenKeys(tokenKeys).searchByKeyParam('notakeyparam');
- expect(tokenKey === null).toBe(true);
+
+ expect(tokenKey).toBeNull();
});
it('should return tokenKey when found by key param', () => {
- const result = new FilteredSearchTokenKeys(tokenKeys).searchByKeyParam(`${tokenKeys[0].key}_${tokenKeys[0].param}`);
+ const result = new FilteredSearchTokenKeys(tokenKeys).searchByKeyParam(
+ `${tokenKeys[0].key}_${tokenKeys[0].param}`,
+ );
+
expect(result).toEqual(tokenKeys[0]);
});
it('should return alternative tokenKey when found by key param', () => {
- const result = new FilteredSearchTokenKeys(tokenKeys).searchByKeyParam(`${tokenKeys[0].key}_${tokenKeys[0].param}`);
+ const result = new FilteredSearchTokenKeys(tokenKeys).searchByKeyParam(
+ `${tokenKeys[0].key}_${tokenKeys[0].param}`,
+ );
+
expect(result).toEqual(tokenKeys[0]);
});
});
@@ -92,26 +106,35 @@ describe('Filtered Search Token Keys', () => {
describe('searchByConditionUrl', () => {
it('should return null when condition url not found', () => {
const condition = new FilteredSearchTokenKeys([], [], conditions).searchByConditionUrl(null);
- expect(condition === null).toBe(true);
+
+ expect(condition).toBeNull();
});
it('should return condition when found by url', () => {
- const result = new FilteredSearchTokenKeys([], [], conditions)
- .searchByConditionUrl(conditions[0].url);
+ const result = new FilteredSearchTokenKeys([], [], conditions).searchByConditionUrl(
+ conditions[0].url,
+ );
+
expect(result).toBe(conditions[0]);
});
});
describe('searchByConditionKeyValue', () => {
it('should return null when condition tokenKey and value not found', () => {
- const condition = new FilteredSearchTokenKeys([], [], conditions)
- .searchByConditionKeyValue(null, null);
- expect(condition === null).toBe(true);
+ const condition = new FilteredSearchTokenKeys([], [], conditions).searchByConditionKeyValue(
+ null,
+ null,
+ );
+
+ expect(condition).toBeNull();
});
it('should return condition when found by tokenKey and value', () => {
- const result = new FilteredSearchTokenKeys([], [], conditions)
- .searchByConditionKeyValue(conditions[0].tokenKey, conditions[0].value);
+ const result = new FilteredSearchTokenKeys([], [], conditions).searchByConditionKeyValue(
+ conditions[0].tokenKey,
+ conditions[0].value,
+ );
+
expect(result).toEqual(conditions[0]);
});
});
diff --git a/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js b/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js
index 4f9f546cbb5..dec03e5ab93 100644
--- a/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js
+++ b/spec/javascripts/filtered_search/filtered_search_tokenizer_spec.js
@@ -7,14 +7,18 @@ describe('Filtered Search Tokenizer', () => {
describe('processTokens', () => {
it('returns for input containing only search value', () => {
const results = FilteredSearchTokenizer.processTokens('searchTerm', allowedKeys);
+
expect(results.searchToken).toBe('searchTerm');
expect(results.tokens.length).toBe(0);
expect(results.lastToken).toBe(results.searchToken);
});
it('returns for input containing only tokens', () => {
- const results = FilteredSearchTokenizer
- .processTokens('author:@root label:~"Very Important" milestone:%v1.0 assignee:none', allowedKeys);
+ const results = FilteredSearchTokenizer.processTokens(
+ 'author:@root label:~"Very Important" milestone:%v1.0 assignee:none',
+ allowedKeys,
+ );
+
expect(results.searchToken).toBe('');
expect(results.tokens.length).toBe(4);
expect(results.tokens[3]).toBe(results.lastToken);
@@ -37,8 +41,11 @@ describe('Filtered Search Tokenizer', () => {
});
it('returns for input starting with search value and ending with tokens', () => {
- const results = FilteredSearchTokenizer
- .processTokens('searchTerm anotherSearchTerm milestone:none', allowedKeys);
+ const results = FilteredSearchTokenizer.processTokens(
+ 'searchTerm anotherSearchTerm milestone:none',
+ allowedKeys,
+ );
+
expect(results.searchToken).toBe('searchTerm anotherSearchTerm');
expect(results.tokens.length).toBe(1);
expect(results.tokens[0]).toBe(results.lastToken);
@@ -48,8 +55,10 @@ describe('Filtered Search Tokenizer', () => {
});
it('returns for input starting with tokens and ending with search value', () => {
- const results = FilteredSearchTokenizer
- .processTokens('assignee:@user searchTerm', allowedKeys);
+ const results = FilteredSearchTokenizer.processTokens(
+ 'assignee:@user searchTerm',
+ allowedKeys,
+ );
expect(results.searchToken).toBe('searchTerm');
expect(results.tokens.length).toBe(1);
@@ -60,8 +69,10 @@ describe('Filtered Search Tokenizer', () => {
});
it('returns for input containing search value wrapped between tokens', () => {
- const results = FilteredSearchTokenizer
- .processTokens('author:@root label:~"Won\'t fix" searchTerm anotherSearchTerm milestone:none', allowedKeys);
+ const results = FilteredSearchTokenizer.processTokens(
+ 'author:@root label:~"Won\'t fix" searchTerm anotherSearchTerm milestone:none',
+ allowedKeys,
+ );
expect(results.searchToken).toBe('searchTerm anotherSearchTerm');
expect(results.tokens.length).toBe(3);
@@ -81,8 +92,11 @@ describe('Filtered Search Tokenizer', () => {
});
it('returns for input containing search value in between tokens', () => {
- const results = FilteredSearchTokenizer
- .processTokens('author:@root searchTerm assignee:none anotherSearchTerm label:~Doing', allowedKeys);
+ const results = FilteredSearchTokenizer.processTokens(
+ 'author:@root searchTerm assignee:none anotherSearchTerm label:~Doing',
+ allowedKeys,
+ );
+
expect(results.searchToken).toBe('searchTerm anotherSearchTerm');
expect(results.tokens.length).toBe(3);
expect(results.tokens[2]).toBe(results.lastToken);
@@ -102,6 +116,7 @@ describe('Filtered Search Tokenizer', () => {
it('returns search value for invalid tokens', () => {
const results = FilteredSearchTokenizer.processTokens('fake:token', allowedKeys);
+
expect(results.lastToken).toBe('fake:token');
expect(results.searchToken).toBe('fake:token');
expect(results.tokens.length).toEqual(0);
@@ -109,6 +124,7 @@ describe('Filtered Search Tokenizer', () => {
it('returns search value and token for mix of valid and invalid tokens', () => {
const results = FilteredSearchTokenizer.processTokens('label:real fake:token', allowedKeys);
+
expect(results.tokens.length).toEqual(1);
expect(results.tokens[0].key).toBe('label');
expect(results.tokens[0].value).toBe('real');
@@ -119,12 +135,14 @@ describe('Filtered Search Tokenizer', () => {
it('returns search value for invalid symbols', () => {
const results = FilteredSearchTokenizer.processTokens('std::includes', allowedKeys);
+
expect(results.lastToken).toBe('std::includes');
expect(results.searchToken).toBe('std::includes');
});
it('removes duplicated values', () => {
const results = FilteredSearchTokenizer.processTokens('label:~foo label:~foo', allowedKeys);
+
expect(results.tokens.length).toBe(1);
expect(results.tokens[0].key).toBe('label');
expect(results.tokens[0].value).toBe('foo');
diff --git a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js
index 53a6d1d62b0..0c1d5f5b0b4 100644
--- a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js
+++ b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js
@@ -9,7 +9,7 @@ import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper';
describe('Filtered Search Visual Tokens', () => {
const subject = FilteredSearchVisualTokens;
- const findElements = (tokenElement) => {
+ const findElements = tokenElement => {
const tokenNameElement = tokenElement.querySelector('.name');
const tokenValueContainer = tokenElement.querySelector('.value-container');
const tokenValueElement = tokenValueContainer.querySelector('.value');
@@ -34,8 +34,7 @@ describe('Filtered Search Visual Tokens', () => {
describe('getLastVisualTokenBeforeInput', () => {
it('returns when there are no visual tokens', () => {
- const { lastVisualToken, isLastVisualTokenValid }
- = subject.getLastVisualTokenBeforeInput();
+ const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
expect(lastVisualToken).toEqual(null);
expect(isLastVisualTokenValid).toEqual(true);
@@ -47,8 +46,7 @@ describe('Filtered Search Visual Tokens', () => {
bugLabelToken.outerHTML,
);
- const { lastVisualToken, isLastVisualTokenValid }
- = subject.getLastVisualTokenBeforeInput();
+ const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
expect(lastVisualToken).toEqual(document.querySelector('.filtered-search-token'));
expect(isLastVisualTokenValid).toEqual(true);
@@ -59,8 +57,7 @@ describe('Filtered Search Visual Tokens', () => {
FilteredSearchSpecHelper.createNameFilterVisualTokenHTML('Author'),
);
- const { lastVisualToken, isLastVisualTokenValid }
- = subject.getLastVisualTokenBeforeInput();
+ const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
expect(lastVisualToken).toEqual(document.querySelector('.filtered-search-token'));
expect(isLastVisualTokenValid).toEqual(false);
@@ -73,8 +70,7 @@ describe('Filtered Search Visual Tokens', () => {
${FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '@root')}
`);
- const { lastVisualToken, isLastVisualTokenValid }
- = subject.getLastVisualTokenBeforeInput();
+ const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
const items = document.querySelectorAll('.tokens-container .js-visual-token');
expect(lastVisualToken.isEqualNode(items[items.length - 1])).toEqual(true);
@@ -88,8 +84,7 @@ describe('Filtered Search Visual Tokens', () => {
${FilteredSearchSpecHelper.createNameFilterVisualTokenHTML('assignee')}
`);
- const { lastVisualToken, isLastVisualTokenValid }
- = subject.getLastVisualTokenBeforeInput();
+ const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
const items = document.querySelectorAll('.tokens-container .js-visual-token');
expect(lastVisualToken.isEqualNode(items[items.length - 1])).toEqual(true);
@@ -105,8 +100,7 @@ describe('Filtered Search Visual Tokens', () => {
${FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '@root')}
`);
- const { lastVisualToken, isLastVisualTokenValid }
- = subject.getLastVisualTokenBeforeInput();
+ const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
expect(lastVisualToken).toEqual(document.querySelector('.filtered-search-token'));
expect(isLastVisualTokenValid).toEqual(true);
@@ -119,8 +113,7 @@ describe('Filtered Search Visual Tokens', () => {
${FilteredSearchSpecHelper.createFilterVisualTokenHTML('author', '@root')}
`);
- const { lastVisualToken, isLastVisualTokenValid }
- = subject.getLastVisualTokenBeforeInput();
+ const { lastVisualToken, isLastVisualTokenValid } = subject.getLastVisualTokenBeforeInput();
expect(lastVisualToken).toEqual(document.querySelector('.filtered-search-token'));
expect(isLastVisualTokenValid).toEqual(false);
@@ -131,6 +124,7 @@ describe('Filtered Search Visual Tokens', () => {
describe('getEndpointWithQueryParams', () => {
it('returns `endpoint` string as is when second param `endpointQueryParams` is undefined, null or empty string', () => {
const endpoint = 'foo/bar/labels.json';
+
expect(subject.getEndpointWithQueryParams(endpoint)).toBe(endpoint);
expect(subject.getEndpointWithQueryParams(endpoint, null)).toBe(endpoint);
expect(subject.getEndpointWithQueryParams(endpoint, '')).toBe(endpoint);
@@ -141,8 +135,13 @@ describe('Filtered Search Visual Tokens', () => {
const singleQueryParams = '{"foo":"true"}';
const multipleQueryParams = '{"foo":"true","bar":"true"}';
- expect(subject.getEndpointWithQueryParams(endpoint, singleQueryParams)).toBe(`${endpoint}?foo=true`);
- expect(subject.getEndpointWithQueryParams(endpoint, multipleQueryParams)).toBe(`${endpoint}?foo=true&bar=true`);
+ expect(subject.getEndpointWithQueryParams(endpoint, singleQueryParams)).toBe(
+ `${endpoint}?foo=true`,
+ );
+
+ expect(subject.getEndpointWithQueryParams(endpoint, multipleQueryParams)).toBe(
+ `${endpoint}?foo=true&bar=true`,
+ );
});
});
@@ -161,6 +160,7 @@ describe('Filtered Search Visual Tokens', () => {
`);
const selected = tokensContainer.querySelector('.js-visual-token .selected');
+
expect(selected.classList.contains('selected')).toEqual(true);
subject.unselectTokens();
@@ -273,7 +273,9 @@ describe('Filtered Search Visual Tokens', () => {
describe('remove token', () => {
it('contains remove-token button', () => {
- expect(tokenElement.querySelector('.value-container .remove-token')).toEqual(jasmine.anything());
+ expect(tokenElement.querySelector('.value-container .remove-token')).toEqual(
+ jasmine.anything(),
+ );
});
it('contains fa-close icon', () => {
@@ -311,7 +313,9 @@ describe('Filtered Search Visual Tokens', () => {
});
it('inserts visual token before input', () => {
- tokensContainer.appendChild(FilteredSearchSpecHelper.createFilterVisualToken('assignee', '@root'));
+ tokensContainer.appendChild(
+ FilteredSearchSpecHelper.createFilterVisualToken('assignee', '@root'),
+ );
subject.addVisualTokenElement('label', 'Frontend');
const tokens = tokensContainer.querySelectorAll('.js-visual-token');
@@ -550,7 +554,7 @@ describe('Filtered Search Visual Tokens', () => {
token = document.querySelector('.js-visual-token');
});
- it('tokenize\'s existing input', () => {
+ it("tokenize's existing input", () => {
input.value = 'some text';
spyOn(subject, 'tokenizeInput').and.callThrough();
@@ -623,7 +627,7 @@ describe('Filtered Search Visual Tokens', () => {
expect(subject.getLastVisualTokenBeforeInput).not.toHaveBeenCalled();
});
- it('tokenize\'s input', () => {
+ it("tokenize's input", () => {
tokensContainer.innerHTML = `
${FilteredSearchSpecHelper.createNameFilterVisualTokenHTML('label')}
${FilteredSearchSpecHelper.createInputHTML()}
@@ -675,13 +679,17 @@ describe('Filtered Search Visual Tokens', () => {
subject.moveInputToTheRight();
const token = tokensContainer.children[1];
+
expect(token.querySelector('.value').innerText).toEqual('~bug');
});
});
describe('renderVisualTokenValue', () => {
const keywordToken = FilteredSearchSpecHelper.createFilterVisualToken('search');
- const milestoneToken = FilteredSearchSpecHelper.createFilterVisualToken('milestone', 'upcoming');
+ const milestoneToken = FilteredSearchSpecHelper.createFilterVisualToken(
+ 'milestone',
+ 'upcoming',
+ );
let updateLabelTokenColorSpy;
let updateUserTokenAppearanceSpy;
@@ -702,8 +710,9 @@ describe('Filtered Search Visual Tokens', () => {
});
it('renders a author token value element', () => {
- const { tokenNameElement, tokenValueContainer, tokenValueElement } =
- findElements(authorToken);
+ const { tokenNameElement, tokenValueContainer, tokenValueElement } = findElements(
+ authorToken,
+ );
const tokenName = tokenNameElement.innerText;
const tokenValue = 'new value';
@@ -712,13 +721,15 @@ describe('Filtered Search Visual Tokens', () => {
expect(tokenValueElement.innerText).toBe(tokenValue);
expect(updateUserTokenAppearanceSpy.calls.count()).toBe(1);
const expectedArgs = [tokenValueContainer, tokenValueElement, tokenValue];
+
expect(updateUserTokenAppearanceSpy.calls.argsFor(0)).toEqual(expectedArgs);
expect(updateLabelTokenColorSpy.calls.count()).toBe(0);
});
it('renders a label token value element', () => {
- const { tokenNameElement, tokenValueContainer, tokenValueElement } =
- findElements(bugLabelToken);
+ const { tokenNameElement, tokenValueContainer, tokenValueElement } = findElements(
+ bugLabelToken,
+ );
const tokenName = tokenNameElement.innerText;
const tokenValue = 'new value';
@@ -727,6 +738,7 @@ describe('Filtered Search Visual Tokens', () => {
expect(tokenValueElement.innerText).toBe(tokenValue);
expect(updateLabelTokenColorSpy.calls.count()).toBe(1);
const expectedArgs = [tokenValueContainer, tokenValue];
+
expect(updateLabelTokenColorSpy.calls.argsFor(0)).toEqual(expectedArgs);
expect(updateUserTokenAppearanceSpy.calls.count()).toBe(0);
});
@@ -751,96 +763,103 @@ describe('Filtered Search Visual Tokens', () => {
spyOn(UsersCache, 'retrieve').and.callFake(username => usersCacheSpy(username));
});
- it('ignores special value "none"', (done) => {
- usersCacheSpy = (username) => {
+ it('ignores special value "none"', done => {
+ usersCacheSpy = username => {
expect(username).toBe('none');
done.fail('Should not resolve "none"!');
};
const { tokenValueContainer, tokenValueElement } = findElements(authorToken);
- subject.updateUserTokenAppearance(tokenValueContainer, tokenValueElement, 'none')
- .then(done)
- .catch(done.fail);
+ subject
+ .updateUserTokenAppearance(tokenValueContainer, tokenValueElement, 'none')
+ .then(done)
+ .catch(done.fail);
});
- it('ignores error if UsersCache throws', (done) => {
+ it('ignores error if UsersCache throws', done => {
spyOn(window, 'Flash');
const dummyError = new Error('Earth rotated backwards');
const { tokenValueContainer, tokenValueElement } = findElements(authorToken);
const tokenValue = tokenValueElement.innerText;
- usersCacheSpy = (username) => {
+ usersCacheSpy = username => {
expect(`@${username}`).toBe(tokenValue);
return Promise.reject(dummyError);
};
- subject.updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue)
- .then(() => {
- expect(window.Flash.calls.count()).toBe(0);
- })
- .then(done)
- .catch(done.fail);
+ subject
+ .updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue)
+ .then(() => {
+ expect(window.Flash.calls.count()).toBe(0);
+ })
+ .then(done)
+ .catch(done.fail);
});
- it('does nothing if user cannot be found', (done) => {
+ it('does nothing if user cannot be found', done => {
const { tokenValueContainer, tokenValueElement } = findElements(authorToken);
const tokenValue = tokenValueElement.innerText;
- usersCacheSpy = (username) => {
+ usersCacheSpy = username => {
expect(`@${username}`).toBe(tokenValue);
return Promise.resolve(undefined);
};
- subject.updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue)
- .then(() => {
- expect(tokenValueElement.innerText).toBe(tokenValue);
- })
- .then(done)
- .catch(done.fail);
+ subject
+ .updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue)
+ .then(() => {
+ expect(tokenValueElement.innerText).toBe(tokenValue);
+ })
+ .then(done)
+ .catch(done.fail);
});
- it('replaces author token with avatar and display name', (done) => {
+ it('replaces author token with avatar and display name', done => {
const dummyUser = {
name: 'Important Person',
avatar_url: 'https://host.invalid/mypics/avatar.png',
};
const { tokenValueContainer, tokenValueElement } = findElements(authorToken);
const tokenValue = tokenValueElement.innerText;
- usersCacheSpy = (username) => {
+ usersCacheSpy = username => {
expect(`@${username}`).toBe(tokenValue);
return Promise.resolve(dummyUser);
};
- subject.updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue)
- .then(() => {
- expect(tokenValueContainer.dataset.originalValue).toBe(tokenValue);
- expect(tokenValueElement.innerText.trim()).toBe(dummyUser.name);
- const avatar = tokenValueElement.querySelector('img.avatar');
- expect(avatar.src).toBe(dummyUser.avatar_url);
- expect(avatar.alt).toBe('');
- })
- .then(done)
- .catch(done.fail);
+ subject
+ .updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue)
+ .then(() => {
+ expect(tokenValueContainer.dataset.originalValue).toBe(tokenValue);
+ expect(tokenValueElement.innerText.trim()).toBe(dummyUser.name);
+ const avatar = tokenValueElement.querySelector('img.avatar');
+
+ expect(avatar.src).toBe(dummyUser.avatar_url);
+ expect(avatar.alt).toBe('');
+ })
+ .then(done)
+ .catch(done.fail);
});
- it('escapes user name when creating token', (done) => {
+ it('escapes user name when creating token', done => {
const dummyUser = {
name: '<script>',
avatar_url: `${gl.TEST_HOST}/mypics/avatar.png`,
};
const { tokenValueContainer, tokenValueElement } = findElements(authorToken);
const tokenValue = tokenValueElement.innerText;
- usersCacheSpy = (username) => {
+ usersCacheSpy = username => {
expect(`@${username}`).toBe(tokenValue);
return Promise.resolve(dummyUser);
};
- subject.updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue)
- .then(() => {
- expect(tokenValueElement.innerText.trim()).toBe(dummyUser.name);
- tokenValueElement.querySelector('.avatar').remove();
- expect(tokenValueElement.innerHTML.trim()).toBe(_.escape(dummyUser.name));
- })
- .then(done)
- .catch(done.fail);
+ subject
+ .updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue)
+ .then(() => {
+ expect(tokenValueElement.innerText.trim()).toBe(dummyUser.name);
+ tokenValueElement.querySelector('.avatar').remove();
+
+ expect(tokenValueElement.innerHTML.trim()).toBe(_.escape(dummyUser.name));
+ })
+ .then(done)
+ .catch(done.fail);
});
});
@@ -854,23 +873,31 @@ describe('Filtered Search Visual Tokens', () => {
it('should set backgroundColor', () => {
const originalBackgroundColor = bugLabelToken.style.backgroundColor;
const token = subject.setTokenStyle(bugLabelToken, 'blue', 'white');
+
expect(token.style.backgroundColor).toEqual('blue');
expect(token.style.backgroundColor).not.toEqual(originalBackgroundColor);
});
it('should not set backgroundColor when it is a linear-gradient', () => {
- const token = subject.setTokenStyle(bugLabelToken, 'linear-gradient(135deg, red, blue)', 'white');
+ const token = subject.setTokenStyle(
+ bugLabelToken,
+ 'linear-gradient(135deg, red, blue)',
+ 'white',
+ );
+
expect(token.style.backgroundColor).toEqual(bugLabelToken.style.backgroundColor);
});
it('should set textColor', () => {
const token = subject.setTokenStyle(bugLabelToken, 'white', 'black');
+
expect(token.style.color).toEqual('black');
expect(token.style.color).not.toEqual(originalTextColor);
});
it('should add inverted class when textColor is #FFFFFF', () => {
const token = subject.setTokenStyle(bugLabelToken, 'black', '#FFFFFF');
+
expect(token.style.color).toEqual('rgb(255, 255, 255)');
expect(token.style.color).not.toEqual(originalTextColor);
expect(token.querySelector('.remove-token').classList.contains('inverted')).toEqual(true);
@@ -894,14 +921,17 @@ describe('Filtered Search Visual Tokens', () => {
describe('not preprocessed before', () => {
it('returns preprocessed labels', () => {
let labels = [];
+
expect(labels.preprocessed).not.toEqual(true);
labels = FilteredSearchVisualTokens.preprocessLabel(endpoint, labels);
+
expect(labels.preprocessed).toEqual(true);
});
it('overrides AjaxCache with preprocessed results', () => {
spyOn(AjaxCache, 'override').and.callFake(() => {});
FilteredSearchVisualTokens.preprocessLabel(endpoint, []);
+
expect(AjaxCache.override.calls.count()).toEqual(1);
});
});
@@ -919,8 +949,14 @@ describe('Filtered Search Visual Tokens', () => {
labelData = getJSONFixture(jsonFixtureName);
});
- const missingLabelToken = FilteredSearchSpecHelper.createFilterVisualToken('label', '~doesnotexist');
- const spaceLabelToken = FilteredSearchSpecHelper.createFilterVisualToken('label', '~"some space"');
+ const missingLabelToken = FilteredSearchSpecHelper.createFilterVisualToken(
+ 'label',
+ '~doesnotexist',
+ );
+ const spaceLabelToken = FilteredSearchSpecHelper.createFilterVisualToken(
+ 'label',
+ '~"some space"',
+ );
beforeEach(() => {
tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(`
@@ -932,11 +968,11 @@ describe('Filtered Search Visual Tokens', () => {
const filteredSearchInput = document.querySelector('.filtered-search');
filteredSearchInput.dataset.baseEndpoint = dummyEndpoint;
- AjaxCache.internalStorage = { };
+ AjaxCache.internalStorage = {};
AjaxCache.internalStorage[`${dummyEndpoint}/labels.json`] = labelData;
});
- const parseColor = (color) => {
+ const parseColor = color => {
const dummyElement = document.createElement('div');
dummyElement.style.color = color;
return dummyElement.style.color;
@@ -948,16 +984,16 @@ describe('Filtered Search Visual Tokens', () => {
expect(tokenValueContainer.style.color).toBe(parseColor(label.text_color));
};
- const findLabel = tokenValue => labelData.find(
- label => tokenValue === `~${DropdownUtils.getEscapedText(label.title)}`,
- );
+ const findLabel = tokenValue =>
+ labelData.find(label => tokenValue === `~${DropdownUtils.getEscapedText(label.title)}`);
- it('updates the color of a label token', (done) => {
+ it('updates the color of a label token', done => {
const { tokenValueContainer, tokenValueElement } = findElements(bugLabelToken);
const tokenValue = tokenValueElement.innerText;
const matchingLabel = findLabel(tokenValue);
- subject.updateLabelTokenColor(tokenValueContainer, tokenValue)
+ subject
+ .updateLabelTokenColor(tokenValueContainer, tokenValue)
.then(() => {
expectValueContainerStyle(tokenValueContainer, matchingLabel);
})
@@ -965,12 +1001,13 @@ describe('Filtered Search Visual Tokens', () => {
.catch(done.fail);
});
- it('updates the color of a label token with spaces', (done) => {
+ it('updates the color of a label token with spaces', done => {
const { tokenValueContainer, tokenValueElement } = findElements(spaceLabelToken);
const tokenValue = tokenValueElement.innerText;
const matchingLabel = findLabel(tokenValue);
- subject.updateLabelTokenColor(tokenValueContainer, tokenValue)
+ subject
+ .updateLabelTokenColor(tokenValueContainer, tokenValue)
.then(() => {
expectValueContainerStyle(tokenValueContainer, matchingLabel);
})
@@ -978,13 +1015,15 @@ describe('Filtered Search Visual Tokens', () => {
.catch(done.fail);
});
- it('does not change color of a missing label', (done) => {
+ it('does not change color of a missing label', done => {
const { tokenValueContainer, tokenValueElement } = findElements(missingLabelToken);
const tokenValue = tokenValueElement.innerText;
const matchingLabel = findLabel(tokenValue);
+
expect(matchingLabel).toBe(undefined);
- subject.updateLabelTokenColor(tokenValueContainer, tokenValue)
+ subject
+ .updateLabelTokenColor(tokenValueContainer, tokenValue)
.then(() => {
expect(tokenValueContainer.getAttribute('style')).toBe(null);
})
diff --git a/spec/javascripts/filtered_search/recent_searches_root_spec.js b/spec/javascripts/filtered_search/recent_searches_root_spec.js
index d063fcf4f2d..70dd4e9570d 100644
--- a/spec/javascripts/filtered_search/recent_searches_root_spec.js
+++ b/spec/javascripts/filtered_search/recent_searches_root_spec.js
@@ -14,7 +14,7 @@ describe('RecentSearchesRoot', () => {
},
};
- VueSpy = spyOnDependency(RecentSearchesRoot, 'Vue').and.callFake((options) => {
+ VueSpy = spyOnDependency(RecentSearchesRoot, 'Vue').and.callFake(options => {
({ data, template } = options);
});
diff --git a/spec/javascripts/filtered_search/services/recent_searches_service_spec.js b/spec/javascripts/filtered_search/services/recent_searches_service_spec.js
index c293c0afa97..188f83eca16 100644
--- a/spec/javascripts/filtered_search/services/recent_searches_service_spec.js
+++ b/spec/javascripts/filtered_search/services/recent_searches_service_spec.js
@@ -15,48 +15,49 @@ describe('RecentSearchesService', () => {
spyOn(RecentSearchesService, 'isAvailable').and.returnValue(true);
});
- it('should default to empty array', (done) => {
+ it('should default to empty array', done => {
const fetchItemsPromise = service.fetch();
fetchItemsPromise
- .then((items) => {
+ .then(items => {
expect(items).toEqual([]);
})
.then(done)
.catch(done.fail);
});
- it('should reject when unable to parse', (done) => {
+ it('should reject when unable to parse', done => {
window.localStorage.setItem(service.localStorageKey, 'fail');
const fetchItemsPromise = service.fetch();
fetchItemsPromise
.then(done.fail)
- .catch((error) => {
+ .catch(error => {
expect(error).toEqual(jasmine.any(SyntaxError));
})
.then(done)
.catch(done.fail);
});
- it('should reject when service is unavailable', (done) => {
+ it('should reject when service is unavailable', done => {
RecentSearchesService.isAvailable.and.returnValue(false);
- service.fetch()
+ service
+ .fetch()
.then(done.fail)
- .catch((error) => {
+ .catch(error => {
expect(error).toEqual(jasmine.any(Error));
})
.then(done)
.catch(done.fail);
});
- it('should return items from localStorage', (done) => {
+ it('should return items from localStorage', done => {
window.localStorage.setItem(service.localStorageKey, '["foo", "bar"]');
const fetchItemsPromise = service.fetch();
fetchItemsPromise
- .then((items) => {
+ .then(items => {
expect(items).toEqual(['foo', 'bar']);
})
.then(done)
@@ -70,10 +71,11 @@ describe('RecentSearchesService', () => {
spyOn(window.localStorage, 'getItem');
});
- it('should not call .getItem', (done) => {
- RecentSearchesService.prototype.fetch()
+ it('should not call .getItem', done => {
+ RecentSearchesService.prototype
+ .fetch()
.then(done.fail)
- .catch((err) => {
+ .catch(err => {
expect(err).toEqual(new RecentSearchesServiceError());
expect(window.localStorage.getItem).not.toHaveBeenCalled();
})
@@ -92,6 +94,7 @@ describe('RecentSearchesService', () => {
const items = ['foo', 'bar'];
service.save(items);
const newLocalStorageValue = window.localStorage.getItem(service.localStorageKey);
+
expect(JSON.parse(newLocalStorageValue)).toEqual(items);
});
});
diff --git a/spec/javascripts/filtered_search/stores/recent_searches_store_spec.js b/spec/javascripts/filtered_search/stores/recent_searches_store_spec.js
index 1eebc6f2367..56bb82ae941 100644
--- a/spec/javascripts/filtered_search/stores/recent_searches_store_spec.js
+++ b/spec/javascripts/filtered_search/stores/recent_searches_store_spec.js
@@ -38,14 +38,8 @@ describe('RecentSearchesStore', () => {
describe('setRecentSearches', () => {
it('should override list', () => {
- store.setRecentSearches([
- 'foo',
- 'bar',
- ]);
- store.setRecentSearches([
- 'baz',
- 'qux',
- ]);
+ store.setRecentSearches(['foo', 'bar']);
+ store.setRecentSearches(['baz', 'qux']);
expect(store.state.recentSearches).toEqual(['baz', 'qux']);
});
diff --git a/spec/javascripts/fixtures/groups.rb b/spec/javascripts/fixtures/groups.rb
index a2035ceae15..b42f442557c 100644
--- a/spec/javascripts/fixtures/groups.rb
+++ b/spec/javascripts/fixtures/groups.rb
@@ -17,6 +17,16 @@ describe 'Groups (JavaScript fixtures)', type: :controller do
sign_in(admin)
end
+ describe GroupsController, '(JavaScript fixtures)', type: :controller do
+ it 'groups/edit.html.raw' do |example|
+ get :edit,
+ id: group
+
+ expect(response).to be_success
+ store_frontend_fixture(response, example.description)
+ end
+ end
+
describe Groups::Settings::CiCdController, '(JavaScript fixtures)', type: :controller do
it 'groups/ci_cd_settings.html.raw' do |example|
get :show,
diff --git a/spec/javascripts/flash_spec.js b/spec/javascripts/flash_spec.js
index 0a8e5a628c0..aecab331ead 100644
--- a/spec/javascripts/flash_spec.js
+++ b/spec/javascripts/flash_spec.js
@@ -1,9 +1,4 @@
-import flash, {
- createFlashEl,
- createAction,
- hideFlash,
- removeFlashClickListener,
-} from '~/flash';
+import flash, { createFlashEl, createAction, hideFlash, removeFlashClickListener } from '~/flash';
describe('Flash', () => {
describe('createFlashEl', () => {
@@ -20,28 +15,23 @@ describe('Flash', () => {
it('creates flash element with type', () => {
el.innerHTML = createFlashEl('testing', 'alert');
- expect(
- el.querySelector('.flash-alert'),
- ).not.toBeNull();
+ expect(el.querySelector('.flash-alert')).not.toBeNull();
});
it('escapes text', () => {
el.innerHTML = createFlashEl('<script>alert("a");</script>', 'alert');
- expect(
- el.querySelector('.flash-text').textContent.trim(),
- ).toBe('<script>alert("a");</script>');
+ expect(el.querySelector('.flash-text').textContent.trim()).toBe(
+ '<script>alert("a");</script>',
+ );
});
it('adds container classes when inside content wrapper', () => {
el.innerHTML = createFlashEl('testing', 'alert', true);
- expect(
- el.querySelector('.flash-text').classList.contains('container-fluid'),
- ).toBeTruthy();
- expect(
- el.querySelector('.flash-text').classList.contains('container-limited'),
- ).toBeTruthy();
+ expect(el.querySelector('.flash-text').classList.contains('container-fluid')).toBeTruthy();
+
+ expect(el.querySelector('.flash-text').classList.contains('container-limited')).toBeTruthy();
});
});
@@ -56,31 +46,23 @@ describe('Flash', () => {
it('sets transition style', () => {
hideFlash(el);
- expect(
- el.style['transition-property'],
- ).toBe('opacity');
- expect(
- el.style['transition-duration'],
- ).toBe('0.3s');
+ expect(el.style['transition-property']).toBe('opacity');
+
+ expect(el.style['transition-duration']).toBe('0.3s');
});
it('sets opacity style', () => {
hideFlash(el);
- expect(
- el.style.opacity,
- ).toBe('0');
+ expect(el.style.opacity).toBe('0');
});
it('does not set styles when fadeTransition is false', () => {
hideFlash(el, false);
- expect(
- el.style.opacity,
- ).toBe('');
- expect(
- el.style.transition,
- ).toBe('');
+ expect(el.style.opacity).toBe('');
+
+ expect(el.style.transition).toBe('');
});
it('removes element after transitionend', () => {
@@ -89,9 +71,7 @@ describe('Flash', () => {
hideFlash(el);
el.dispatchEvent(new Event('transitionend'));
- expect(
- document.querySelector('.js-testing'),
- ).toBeNull();
+ expect(document.querySelector('.js-testing')).toBeNull();
});
it('calls event listener callback once', () => {
@@ -103,9 +83,7 @@ describe('Flash', () => {
el.dispatchEvent(new Event('transitionend'));
el.dispatchEvent(new Event('transitionend'));
- expect(
- el.remove.calls.count(),
- ).toBe(1);
+ expect(el.remove.calls.count()).toBe(1);
});
});
@@ -122,9 +100,7 @@ describe('Flash', () => {
title: 'test',
});
- expect(
- el.querySelector('.flash-action').href,
- ).toContain('testing');
+ expect(el.querySelector('.flash-action').href).toContain('testing');
});
it('uses hash as href when no href is present', () => {
@@ -132,9 +108,7 @@ describe('Flash', () => {
title: 'test',
});
- expect(
- el.querySelector('.flash-action').href,
- ).toContain('#');
+ expect(el.querySelector('.flash-action').href).toContain('#');
});
it('adds role when no href is present', () => {
@@ -142,9 +116,7 @@ describe('Flash', () => {
title: 'test',
});
- expect(
- el.querySelector('.flash-action').getAttribute('role'),
- ).toBe('button');
+ expect(el.querySelector('.flash-action').getAttribute('role')).toBe('button');
});
it('escapes the title text', () => {
@@ -152,9 +124,9 @@ describe('Flash', () => {
title: '<script>alert("a")</script>',
});
- expect(
- el.querySelector('.flash-action').textContent.trim(),
- ).toBe('<script>alert("a")</script>');
+ expect(el.querySelector('.flash-action').textContent.trim()).toBe(
+ '<script>alert("a")</script>',
+ );
});
});
@@ -163,12 +135,9 @@ describe('Flash', () => {
it('does not add to the DOM', () => {
const flashEl = flash('testing');
- expect(
- flashEl,
- ).toBeNull();
- expect(
- document.querySelector('.flash-alert'),
- ).toBeNull();
+ expect(flashEl).toBeNull();
+
+ expect(document.querySelector('.flash-alert')).toBeNull();
});
});
@@ -188,42 +157,30 @@ describe('Flash', () => {
it('adds flash element into container', () => {
flash('test', 'alert', document, null, false, true);
- expect(
- document.querySelector('.flash-alert'),
- ).not.toBeNull();
+ expect(document.querySelector('.flash-alert')).not.toBeNull();
- expect(
- document.body.className,
- ).toContain('flash-shown');
+ expect(document.body.className).toContain('flash-shown');
});
it('adds flash into specified parent', () => {
- flash(
- 'test',
- 'alert',
- document.querySelector('.content-wrapper'),
- );
+ flash('test', 'alert', document.querySelector('.content-wrapper'));
- expect(
- document.querySelector('.content-wrapper .flash-alert'),
- ).not.toBeNull();
+ expect(document.querySelector('.content-wrapper .flash-alert')).not.toBeNull();
});
it('adds container classes when inside content-wrapper', () => {
flash('test');
- expect(
- document.querySelector('.flash-text').className,
- ).toBe('flash-text container-fluid container-limited');
+ expect(document.querySelector('.flash-text').className).toBe(
+ 'flash-text container-fluid container-limited limit-container-width',
+ );
});
it('does not add container when outside of content-wrapper', () => {
document.querySelector('.content-wrapper').className = 'js-content-wrapper';
flash('test');
- expect(
- document.querySelector('.flash-text').className.trim(),
- ).toBe('flash-text');
+ expect(document.querySelector('.flash-text').className.trim()).toContain('flash-text');
});
it('removes element after clicking', () => {
@@ -231,29 +188,18 @@ describe('Flash', () => {
document.querySelector('.flash-alert').click();
- expect(
- document.querySelector('.flash-alert'),
- ).toBeNull();
+ expect(document.querySelector('.flash-alert')).toBeNull();
- expect(
- document.body.className,
- ).not.toContain('flash-shown');
+ expect(document.body.className).not.toContain('flash-shown');
});
describe('with actionConfig', () => {
it('adds action link', () => {
- flash(
- 'test',
- 'alert',
- document,
- {
- title: 'test',
- },
- );
-
- expect(
- document.querySelector('.flash-action'),
- ).not.toBeNull();
+ flash('test', 'alert', document, {
+ title: 'test',
+ });
+
+ expect(document.querySelector('.flash-action')).not.toBeNull();
});
it('calls actionConfig clickHandler on click', () => {
@@ -262,18 +208,11 @@ describe('Flash', () => {
clickHandler: jasmine.createSpy('actionConfig'),
};
- flash(
- 'test',
- 'alert',
- document,
- actionConfig,
- );
+ flash('test', 'alert', document, actionConfig);
document.querySelector('.flash-action').click();
- expect(
- actionConfig.clickHandler,
- ).toHaveBeenCalled();
+ expect(actionConfig.clickHandler).toHaveBeenCalled();
});
});
});
@@ -284,7 +223,7 @@ describe('Flash', () => {
document.body.innerHTML += '<div class="flash-container"><div class="flash"></div></div>';
});
- it('removes global flash on click', (done) => {
+ it('removes global flash on click', done => {
const flashEl = document.querySelector('.flash');
removeFlashClickListener(flashEl, false);
diff --git a/spec/javascripts/fly_out_nav_spec.js b/spec/javascripts/fly_out_nav_spec.js
index eb9330f5e5b..7ef44f29c5b 100644
--- a/spec/javascripts/fly_out_nav_spec.js
+++ b/spec/javascripts/fly_out_nav_spec.js
@@ -45,9 +45,7 @@ describe('Fly out sidebar navigation', () => {
height: 100,
};
- expect(
- calculateTop(boundingRect, 100),
- ).toBe(100);
+ expect(calculateTop(boundingRect, 100)).toBe(100);
});
it('returns boundingRect - bottomOverflow', () => {
@@ -56,27 +54,22 @@ describe('Fly out sidebar navigation', () => {
height: 100,
};
- expect(
- calculateTop(boundingRect, 100),
- ).toBe(window.innerHeight - 50);
+ expect(calculateTop(boundingRect, 100)).toBe(window.innerHeight - 50);
});
});
describe('getHideSubItemsInterval', () => {
beforeEach(() => {
- el.innerHTML = '<div class="sidebar-sub-level-items" style="position: fixed; top: 0; left: 100px; height: 150px;"></div>';
+ el.innerHTML =
+ '<div class="sidebar-sub-level-items" style="position: fixed; top: 0; left: 100px; height: 150px;"></div>';
});
it('returns 0 if currentOpenMenu is nil', () => {
- expect(
- getHideSubItemsInterval(),
- ).toBe(0);
+ expect(getHideSubItemsInterval()).toBe(0);
});
it('returns 0 if mousePos is empty', () => {
- expect(
- getHideSubItemsInterval(),
- ).toBe(0);
+ expect(getHideSubItemsInterval()).toBe(0);
});
it('returns 0 when mouse above sub-items', () => {
@@ -90,9 +83,7 @@ describe('Fly out sidebar navigation', () => {
clientY: el.getBoundingClientRect().top - 50,
});
- expect(
- getHideSubItemsInterval(),
- ).toBe(0);
+ expect(getHideSubItemsInterval()).toBe(0);
});
it('returns 0 when mouse is below sub-items', () => {
@@ -105,12 +96,10 @@ describe('Fly out sidebar navigation', () => {
});
documentMouseMove({
clientX: el.getBoundingClientRect().left,
- clientY: (el.getBoundingClientRect().top - subItems.getBoundingClientRect().height) + 50,
+ clientY: el.getBoundingClientRect().top - subItems.getBoundingClientRect().height + 50,
});
- expect(
- getHideSubItemsInterval(),
- ).toBe(0);
+ expect(getHideSubItemsInterval()).toBe(0);
});
it('returns 300 when mouse is moved towards sub-items', () => {
@@ -124,9 +113,7 @@ describe('Fly out sidebar navigation', () => {
clientY: el.getBoundingClientRect().top + 10,
});
- expect(
- getHideSubItemsInterval(),
- ).toBe(300);
+ expect(getHideSubItemsInterval()).toBe(300);
});
});
@@ -138,9 +125,7 @@ describe('Fly out sidebar navigation', () => {
it('removes is-over class if currentOpenMenu is null', () => {
mouseLeaveTopItem(el);
- expect(
- el.classList.remove,
- ).toHaveBeenCalledWith('is-over');
+ expect(el.classList.remove).toHaveBeenCalledWith('is-over');
});
it('removes is-over class if currentOpenMenu is null & there are sub-items', () => {
@@ -148,9 +133,7 @@ describe('Fly out sidebar navigation', () => {
mouseLeaveTopItem(el);
- expect(
- el.classList.remove,
- ).toHaveBeenCalledWith('is-over');
+ expect(el.classList.remove).toHaveBeenCalledWith('is-over');
});
it('does not remove is-over class if currentOpenMenu is the passed in sub-items', () => {
@@ -159,34 +142,29 @@ describe('Fly out sidebar navigation', () => {
setOpenMenu(el.querySelector('.sidebar-sub-level-items'));
mouseLeaveTopItem(el);
- expect(
- el.classList.remove,
- ).not.toHaveBeenCalled();
+ expect(el.classList.remove).not.toHaveBeenCalled();
});
});
describe('mouseEnterTopItems', () => {
beforeEach(() => {
- el.innerHTML = '<div class="sidebar-sub-level-items" style="position: absolute; top: 0; left: 100px; height: 200px;"></div>';
+ el.innerHTML =
+ '<div class="sidebar-sub-level-items" style="position: absolute; top: 0; left: 100px; height: 200px;"></div>';
});
- it('shows sub-items after 0ms if no menu is open', (done) => {
+ it('shows sub-items after 0ms if no menu is open', done => {
mouseEnterTopItems(el);
- expect(
- getHideSubItemsInterval(),
- ).toBe(0);
+ expect(getHideSubItemsInterval()).toBe(0);
setTimeout(() => {
- expect(
- el.querySelector('.sidebar-sub-level-items').style.display,
- ).toBe('block');
+ expect(el.querySelector('.sidebar-sub-level-items').style.display).toBe('block');
done();
});
});
- it('shows sub-items after 300ms if a menu is currently open', (done) => {
+ it('shows sub-items after 300ms if a menu is currently open', done => {
documentMouseMove({
clientX: el.getBoundingClientRect().left,
clientY: el.getBoundingClientRect().top,
@@ -201,14 +179,10 @@ describe('Fly out sidebar navigation', () => {
mouseEnterTopItems(el, 0);
- expect(
- getHideSubItemsInterval(),
- ).toBe(300);
+ expect(getHideSubItemsInterval()).toBe(300);
setTimeout(() => {
- expect(
- el.querySelector('.sidebar-sub-level-items').style.display,
- ).toBe('block');
+ expect(el.querySelector('.sidebar-sub-level-items').style.display).toBe('block');
done();
});
@@ -225,9 +199,7 @@ describe('Fly out sidebar navigation', () => {
showSubLevelItems(el);
- expect(
- el.classList.add,
- ).toHaveBeenCalledWith('is-over');
+ expect(el.classList.add).toHaveBeenCalledWith('is-over');
});
it('does not show sub-items on mobile', () => {
@@ -235,17 +207,13 @@ describe('Fly out sidebar navigation', () => {
showSubLevelItems(el);
- expect(
- el.querySelector('.sidebar-sub-level-items').style.display,
- ).not.toBe('block');
+ expect(el.querySelector('.sidebar-sub-level-items').style.display).not.toBe('block');
});
it('shows sub-items', () => {
showSubLevelItems(el);
- expect(
- el.querySelector('.sidebar-sub-level-items').style.display,
- ).toBe('block');
+ expect(el.querySelector('.sidebar-sub-level-items').style.display).toBe('block');
});
it('shows collapsed only sub-items if icon only sidebar', () => {
@@ -258,9 +226,7 @@ describe('Fly out sidebar navigation', () => {
showSubLevelItems(el);
- expect(
- el.querySelector('.sidebar-sub-level-items').style.display,
- ).toBe('block');
+ expect(el.querySelector('.sidebar-sub-level-items').style.display).toBe('block');
});
it('does not show collapsed only sub-items if icon only sidebar', () => {
@@ -269,9 +235,7 @@ describe('Fly out sidebar navigation', () => {
showSubLevelItems(el);
- expect(
- subItems.style.display,
- ).not.toBe('block');
+ expect(subItems.style.display).not.toBe('block');
});
it('sets transform of sub-items', () => {
@@ -285,9 +249,10 @@ describe('Fly out sidebar navigation', () => {
setSidebar(sidebar);
showSubLevelItems(el);
- expect(
- subItems.style.transform,
- ).toBe(`translate3d(200px, ${Math.floor(el.getBoundingClientRect().top) - getHeaderHeight()}px, 0px)`);
+ expect(subItems.style.transform).toBe(
+ `translate3d(200px, ${Math.floor(el.getBoundingClientRect().top) -
+ getHeaderHeight()}px, 0px)`,
+ );
});
it('sets is-above when element is above', () => {
@@ -299,33 +264,25 @@ describe('Fly out sidebar navigation', () => {
showSubLevelItems(el);
- expect(
- subItems.classList.add,
- ).toHaveBeenCalledWith('is-above');
+ expect(subItems.classList.add).toHaveBeenCalledWith('is-above');
});
});
describe('canShowSubItems', () => {
it('returns true if on desktop size', () => {
- expect(
- canShowSubItems(),
- ).toBeTruthy();
+ expect(canShowSubItems()).toBeTruthy();
});
it('returns false if on mobile size', () => {
breakpointSize = 'xs';
- expect(
- canShowSubItems(),
- ).toBeFalsy();
+ expect(canShowSubItems()).toBeFalsy();
});
});
describe('canShowActiveSubItems', () => {
it('returns true by default', () => {
- expect(
- canShowActiveSubItems(el),
- ).toBeTruthy();
+ expect(canShowActiveSubItems(el)).toBeTruthy();
});
it('returns false when active & expanded sidebar', () => {
@@ -334,9 +291,7 @@ describe('Fly out sidebar navigation', () => {
setSidebar(sidebar);
- expect(
- canShowActiveSubItems(el),
- ).toBeFalsy();
+ expect(canShowActiveSubItems(el)).toBeFalsy();
});
it('returns true when active & collapsed sidebar', () => {
@@ -346,9 +301,7 @@ describe('Fly out sidebar navigation', () => {
setSidebar(sidebar);
- expect(
- canShowActiveSubItems(el),
- ).toBeTruthy();
+ expect(canShowActiveSubItems(el)).toBeTruthy();
});
});
@@ -362,18 +315,14 @@ describe('Fly out sidebar navigation', () => {
it('hides subMenu if element is not hovered', () => {
subItemsMouseLeave(el);
- expect(
- getOpenMenu(),
- ).toBeNull();
+ expect(getOpenMenu()).toBeNull();
});
it('does not hide subMenu if element is hovered', () => {
el.classList.add('is-over');
subItemsMouseLeave(el);
- expect(
- getOpenMenu(),
- ).not.toBeNull();
+ expect(getOpenMenu()).not.toBeNull();
});
});
});
diff --git a/spec/javascripts/frequent_items/components/app_spec.js b/spec/javascripts/frequent_items/components/app_spec.js
index 834f919524d..b1cc4d8dc8d 100644
--- a/spec/javascripts/frequent_items/components/app_spec.js
+++ b/spec/javascripts/frequent_items/components/app_spec.js
@@ -232,8 +232,7 @@ describe('Frequent Items App Component', () => {
expect(vm.$el.querySelectorAll('.frequent-items-list-container li').length).toBe(1);
vm.$store.dispatch('setSearchQuery', 'gitlab');
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
expect(vm.$el.querySelector('.loading-animation')).toBeDefined();
})
diff --git a/spec/javascripts/frequent_items/components/frequent_items_list_item_spec.js b/spec/javascripts/frequent_items/components/frequent_items_list_item_spec.js
index 201aca77b10..7deed985219 100644
--- a/spec/javascripts/frequent_items/components/frequent_items_list_item_spec.js
+++ b/spec/javascripts/frequent_items/components/frequent_items_list_item_spec.js
@@ -30,9 +30,11 @@ describe('FrequentItemsListItemComponent', () => {
describe('hasAvatar', () => {
it('should return `true` or `false` if whether avatar is present or not', () => {
vm.avatarUrl = 'path/to/avatar.png';
+
expect(vm.hasAvatar).toBe(true);
vm.avatarUrl = null;
+
expect(vm.hasAvatar).toBe(false);
});
});
@@ -40,11 +42,13 @@ describe('FrequentItemsListItemComponent', () => {
describe('highlightedItemName', () => {
it('should enclose part of project name in <b> & </b> which matches with `matcher` prop', () => {
vm.matcher = 'lab';
+
expect(vm.highlightedItemName).toContain('<b>Lab</b>');
});
it('should return project name as it is if `matcher` is not available', () => {
vm.matcher = null;
+
expect(vm.highlightedItemName).toBe(mockProject.name);
});
});
@@ -52,11 +56,13 @@ describe('FrequentItemsListItemComponent', () => {
describe('truncatedNamespace', () => {
it('should truncate project name from namespace string', () => {
vm.namespace = 'platform / nokia-3310';
+
expect(vm.truncatedNamespace).toBe('platform');
});
it('should truncate namespace string from the middle if it includes more than two groups in path', () => {
vm.namespace = 'platform / hardware / broadcom / Wifi Group / Mobile Chipset / nokia-3310';
+
expect(vm.truncatedNamespace).toBe('platform / ... / Mobile Chipset');
});
});
diff --git a/spec/javascripts/frequent_items/components/frequent_items_list_spec.js b/spec/javascripts/frequent_items/components/frequent_items_list_spec.js
index 3003b7ee000..8518a681a26 100644
--- a/spec/javascripts/frequent_items/components/frequent_items_list_spec.js
+++ b/spec/javascripts/frequent_items/components/frequent_items_list_spec.js
@@ -30,9 +30,11 @@ describe('FrequentItemsListComponent', () => {
describe('isListEmpty', () => {
it('should return `true` or `false` representing whether if `items` is empty or not with projects', () => {
vm.items = [];
+
expect(vm.isListEmpty).toBe(true);
vm.items = mockFrequentProjects;
+
expect(vm.isListEmpty).toBe(false);
});
});
@@ -40,9 +42,11 @@ describe('FrequentItemsListComponent', () => {
describe('fetched item messages', () => {
it('should return appropriate empty list message based on value of `localStorageFailed` prop with projects', () => {
vm.isFetchFailed = true;
+
expect(vm.listEmptyMessage).toBe('This feature requires browser localStorage support');
vm.isFetchFailed = false;
+
expect(vm.listEmptyMessage).toBe('Projects you visit often will appear here');
});
});
@@ -51,9 +55,11 @@ describe('FrequentItemsListComponent', () => {
it('should return appropriate empty list message based on value of `searchFailed` prop with projects', () => {
vm.hasSearchQuery = true;
vm.isFetchFailed = true;
+
expect(vm.listEmptyMessage).toBe('Something went wrong on our end.');
vm.isFetchFailed = false;
+
expect(vm.listEmptyMessage).toBe('Sorry, no projects matched your search');
});
});
diff --git a/spec/javascripts/frequent_items/components/frequent_items_search_input_spec.js b/spec/javascripts/frequent_items/components/frequent_items_search_input_spec.js
index 6a11038e70a..d564292f1ba 100644
--- a/spec/javascripts/frequent_items/components/frequent_items_search_input_spec.js
+++ b/spec/javascripts/frequent_items/components/frequent_items_search_input_spec.js
@@ -26,6 +26,7 @@ describe('FrequentItemsSearchInputComponent', () => {
spyOn(vm.$refs.search, 'focus');
vm.setFocus();
+
expect(vm.$refs.search.focus).toHaveBeenCalled();
});
});
diff --git a/spec/javascripts/gfm_auto_complete_spec.js b/spec/javascripts/gfm_auto_complete_spec.js
index b57c4943c01..6f414c8ccf1 100644
--- a/spec/javascripts/gfm_auto_complete_spec.js
+++ b/spec/javascripts/gfm_auto_complete_spec.js
@@ -6,39 +6,38 @@ import GfmAutoComplete from '~/gfm_auto_complete';
import 'vendor/jquery.caret';
import 'vendor/jquery.atwho';
-describe('GfmAutoComplete', function () {
+describe('GfmAutoComplete', function() {
const gfmAutoCompleteCallbacks = GfmAutoComplete.prototype.getDefaultCallbacks.call({
fetchData: () => {},
});
- describe('DefaultOptions.sorter', function () {
- describe('assets loading', function () {
- beforeEach(function () {
+ describe('DefaultOptions.sorter', function() {
+ describe('assets loading', function() {
+ beforeEach(function() {
spyOn(GfmAutoComplete, 'isLoading').and.returnValue(true);
this.atwhoInstance = { setting: {} };
this.items = [];
- this.sorterValue = gfmAutoCompleteCallbacks.sorter
- .call(this.atwhoInstance, '', this.items);
+ this.sorterValue = gfmAutoCompleteCallbacks.sorter.call(this.atwhoInstance, '', this.items);
});
- it('should disable highlightFirst', function () {
+ it('should disable highlightFirst', function() {
expect(this.atwhoInstance.setting.highlightFirst).toBe(false);
});
- it('should return the passed unfiltered items', function () {
+ it('should return the passed unfiltered items', function() {
expect(this.sorterValue).toEqual(this.items);
});
});
- describe('assets finished loading', function () {
- beforeEach(function () {
+ describe('assets finished loading', function() {
+ beforeEach(function() {
spyOn(GfmAutoComplete, 'isLoading').and.returnValue(false);
spyOn($.fn.atwho.default.callbacks, 'sorter');
});
- it('should enable highlightFirst if alwaysHighlightFirst is set', function () {
+ it('should enable highlightFirst if alwaysHighlightFirst is set', function() {
const atwhoInstance = { setting: { alwaysHighlightFirst: true } };
gfmAutoCompleteCallbacks.sorter.call(atwhoInstance);
@@ -46,7 +45,7 @@ describe('GfmAutoComplete', function () {
expect(atwhoInstance.setting.highlightFirst).toBe(true);
});
- it('should enable highlightFirst if a query is present', function () {
+ it('should enable highlightFirst if a query is present', function() {
const atwhoInstance = { setting: {} };
gfmAutoCompleteCallbacks.sorter.call(atwhoInstance, 'query');
@@ -54,7 +53,7 @@ describe('GfmAutoComplete', function () {
expect(atwhoInstance.setting.highlightFirst).toBe(true);
});
- it('should call the default atwho sorter', function () {
+ it('should call the default atwho sorter', function() {
const atwhoInstance = { setting: {} };
const query = 'query';
@@ -69,9 +68,8 @@ describe('GfmAutoComplete', function () {
});
describe('DefaultOptions.beforeInsert', () => {
- const beforeInsert = (context, value) => (
- gfmAutoCompleteCallbacks.beforeInsert.call(context, value)
- );
+ const beforeInsert = (context, value) =>
+ gfmAutoCompleteCallbacks.beforeInsert.call(context, value);
const atwhoInstance = { setting: { skipSpecialCharacterTest: false } };
@@ -98,29 +96,51 @@ describe('GfmAutoComplete', function () {
});
});
- describe('DefaultOptions.matcher', function () {
- const defaultMatcher = (context, flag, subtext) => (
- gfmAutoCompleteCallbacks.matcher.call(context, flag, subtext)
- );
+ describe('DefaultOptions.matcher', function() {
+ const defaultMatcher = (context, flag, subtext) =>
+ gfmAutoCompleteCallbacks.matcher.call(context, flag, subtext);
const flagsUseDefaultMatcher = ['@', '#', '!', '~', '%', '$'];
const otherFlags = ['/', ':'];
const flags = flagsUseDefaultMatcher.concat(otherFlags);
- const flagsHash = flags.reduce((hash, el) => { hash[el] = null; return hash; }, {});
+ const flagsHash = flags.reduce((hash, el) => {
+ hash[el] = null;
+ return hash;
+ }, {});
const atwhoInstance = { setting: {}, app: { controllers: flagsHash } };
const minLen = 1;
const maxLen = 20;
const argumentSize = [minLen, maxLen / 2, maxLen];
- const allowedSymbols = ['', 'a', 'n', 'z', 'A', 'Z', 'N', '0', '5', '9', 'А', 'а', 'Я', 'я', '.', '\'', '+', '-', '_'];
+ const allowedSymbols = [
+ '',
+ 'a',
+ 'n',
+ 'z',
+ 'A',
+ 'Z',
+ 'N',
+ '0',
+ '5',
+ '9',
+ 'А',
+ 'а',
+ 'Я',
+ 'я',
+ '.',
+ "'",
+ '+',
+ '-',
+ '_',
+ ];
const jointAllowedSymbols = allowedSymbols.join('');
describe('should match regular symbols', () => {
- flagsUseDefaultMatcher.forEach((flag) => {
- allowedSymbols.forEach((symbol) => {
- argumentSize.forEach((size) => {
+ flagsUseDefaultMatcher.forEach(flag => {
+ allowedSymbols.forEach(symbol => {
+ argumentSize.forEach(size => {
const query = new Array(size + 1).join(symbol);
const subtext = flag + query;
@@ -142,8 +162,8 @@ describe('GfmAutoComplete', function () {
const shouldNotBeFollowedBy = flags.concat(['\x00', '\x10', '\x3f', '\n', ' ']);
const shouldNotBePrependedBy = ['`'];
- flagsUseDefaultMatcher.forEach((atSign) => {
- shouldNotBeFollowedBy.forEach((followedSymbol) => {
+ flagsUseDefaultMatcher.forEach(atSign => {
+ shouldNotBeFollowedBy.forEach(followedSymbol => {
const seq = atSign + followedSymbol;
it(`should not match ${JSON.stringify(seq)}`, () => {
@@ -151,7 +171,7 @@ describe('GfmAutoComplete', function () {
});
});
- shouldNotBePrependedBy.forEach((prependedSymbol) => {
+ shouldNotBePrependedBy.forEach(prependedSymbol => {
const seq = prependedSymbol + atSign;
it(`should not match "${seq}"`, () => {
@@ -162,28 +182,26 @@ describe('GfmAutoComplete', function () {
});
});
- describe('isLoading', function () {
- it('should be true with loading data object item', function () {
+ describe('isLoading', function() {
+ it('should be true with loading data object item', function() {
expect(GfmAutoComplete.isLoading({ name: 'loading' })).toBe(true);
});
- it('should be true with loading data array', function () {
+ it('should be true with loading data array', function() {
expect(GfmAutoComplete.isLoading(['loading'])).toBe(true);
});
- it('should be true with loading data object array', function () {
+ it('should be true with loading data object array', function() {
expect(GfmAutoComplete.isLoading([{ name: 'loading' }])).toBe(true);
});
- it('should be false with actual array data', function () {
- expect(GfmAutoComplete.isLoading([
- { title: 'Foo' },
- { title: 'Bar' },
- { title: 'Qux' },
- ])).toBe(false);
+ it('should be false with actual array data', function() {
+ expect(
+ GfmAutoComplete.isLoading([{ title: 'Foo' }, { title: 'Bar' }, { title: 'Qux' }]),
+ ).toBe(false);
});
- it('should be false with actual data item', function () {
+ it('should be false with actual data item', function() {
expect(GfmAutoComplete.isLoading({ title: 'Foo' })).toBe(false);
});
});
diff --git a/spec/javascripts/gl_dropdown_spec.js b/spec/javascripts/gl_dropdown_spec.js
index 25b819543da..85083653db8 100644
--- a/spec/javascripts/gl_dropdown_spec.js
+++ b/spec/javascripts/gl_dropdown_spec.js
@@ -8,7 +8,8 @@ describe('glDropdown', function describeDropdown() {
preloadFixtures('static/gl_dropdown.html.raw');
loadJSONFixtures('projects.json');
- const NON_SELECTABLE_CLASSES = '.divider, .separator, .dropdown-header, .dropdown-menu-empty-item';
+ const NON_SELECTABLE_CLASSES =
+ '.divider, .separator, .dropdown-header, .dropdown-menu-empty-item';
const SEARCH_INPUT_SELECTOR = '.dropdown-input-field';
const ITEM_SELECTOR = `.dropdown-content li:not(${NON_SELECTABLE_CLASSES})`;
const FOCUSED_ITEM_SELECTOR = `${ITEM_SELECTOR} a.is-focused`;
@@ -17,7 +18,7 @@ describe('glDropdown', function describeDropdown() {
DOWN: 40,
UP: 38,
ENTER: 13,
- ESC: 27
+ ESC: 27,
};
let remoteCallback;
@@ -28,7 +29,7 @@ describe('glDropdown', function describeDropdown() {
$('body').trigger({
type: 'keydown',
which: ARROW_KEYS[direction],
- keyCode: ARROW_KEYS[direction]
+ keyCode: ARROW_KEYS[direction],
});
i += 1;
if (i <= steps) {
@@ -43,17 +44,23 @@ describe('glDropdown', function describeDropdown() {
};
function initDropDown(hasRemote, isFilterable, extraOpts = {}) {
- const options = Object.assign({
- selectable: true,
- filterable: isFilterable,
- data: hasRemote ? remoteMock.bind({}, this.projectsData) : this.projectsData,
- search: {
- fields: ['name']
+ const options = Object.assign(
+ {
+ selectable: true,
+ filterable: isFilterable,
+ data: hasRemote ? remoteMock.bind({}, this.projectsData) : this.projectsData,
+ search: {
+ fields: ['name'],
+ },
+ text: project => project.name_with_namespace || project.name,
+ id: project => project.id,
},
- text: project => (project.name_with_namespace || project.name),
- id: project => project.id,
- }, extraOpts);
- this.dropdownButtonElement = $('#js-project-dropdown', this.dropdownContainerElement).glDropdown(options);
+ extraOpts,
+ );
+ this.dropdownButtonElement = $(
+ '#js-project-dropdown',
+ this.dropdownContainerElement,
+ ).glDropdown(options);
}
beforeEach(() => {
@@ -70,8 +77,10 @@ describe('glDropdown', function describeDropdown() {
it('should open on click', () => {
initDropDown.call(this, false);
+
expect(this.dropdownContainerElement).not.toHaveClass('show');
this.dropdownButtonElement.click();
+
expect(this.dropdownContainerElement).toHaveClass('show');
});
@@ -82,9 +91,7 @@ describe('glDropdown', function describeDropdown() {
this.dropdownButtonElement.click();
- expect(
- $('.dropdown-content li:first-child').text(),
- ).toBe('<script>alert("testing");</script>');
+ expect($('.dropdown-content li:first-child').text()).toBe('<script>alert("testing");</script>');
});
it('should output HTML when highlighting', () => {
@@ -97,13 +104,11 @@ describe('glDropdown', function describeDropdown() {
this.dropdownButtonElement.click();
- expect(
- $('.dropdown-content li:first-child').text(),
- ).toBe('testing');
+ expect($('.dropdown-content li:first-child').text()).toBe('testing');
- expect(
- $('.dropdown-content li:first-child a').html(),
- ).toBe('<b>t</b><b>e</b><b>s</b><b>t</b>ing');
+ expect($('.dropdown-content li:first-child a').html()).toBe(
+ '<b>t</b><b>e</b><b>s</b><b>t</b>ing',
+ );
});
describe('that is open', () => {
@@ -114,21 +119,28 @@ describe('glDropdown', function describeDropdown() {
it('should select a following item on DOWN keypress', () => {
expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(0);
- const randomIndex = (Math.floor(Math.random() * (this.projectsData.length - 1)) + 0);
+ const randomIndex = Math.floor(Math.random() * (this.projectsData.length - 1)) + 0;
navigateWithKeys('down', randomIndex, () => {
expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(1);
- expect($(`${ITEM_SELECTOR}:eq(${randomIndex}) a`, this.$dropdownMenuElement)).toHaveClass('is-focused');
+ expect($(`${ITEM_SELECTOR}:eq(${randomIndex}) a`, this.$dropdownMenuElement)).toHaveClass(
+ 'is-focused',
+ );
});
});
it('should select a previous item on UP keypress', () => {
expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(0);
- navigateWithKeys('down', (this.projectsData.length - 1), () => {
+ navigateWithKeys('down', this.projectsData.length - 1, () => {
expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(1);
- const randomIndex = (Math.floor(Math.random() * (this.projectsData.length - 2)) + 0);
+ const randomIndex = Math.floor(Math.random() * (this.projectsData.length - 2)) + 0;
navigateWithKeys('up', randomIndex, () => {
expect($(FOCUSED_ITEM_SELECTOR, this.$dropdownMenuElement).length).toBe(1);
- expect($(`${ITEM_SELECTOR}:eq(${((this.projectsData.length - 2) - randomIndex)}) a`, this.$dropdownMenuElement)).toHaveClass('is-focused');
+ expect(
+ $(
+ `${ITEM_SELECTOR}:eq(${this.projectsData.length - 2 - randomIndex}) a`,
+ this.$dropdownMenuElement,
+ ),
+ ).toHaveClass('is-focused');
});
});
});
@@ -141,9 +153,12 @@ describe('glDropdown', function describeDropdown() {
navigateWithKeys('enter', null, () => {
expect(this.dropdownContainerElement).not.toHaveClass('show');
const link = $(`${ITEM_SELECTOR}:eq(${randomIndex}) a`, this.$dropdownMenuElement);
+
expect(link).toHaveClass('is-active');
const linkedLocation = link.attr('href');
- if (linkedLocation && linkedLocation !== '#') expect(visitUrl).toHaveBeenCalledWith(linkedLocation);
+ if (linkedLocation && linkedLocation !== '#') {
+ expect(visitUrl).toHaveBeenCalledWith(linkedLocation);
+ }
});
});
});
@@ -153,8 +168,9 @@ describe('glDropdown', function describeDropdown() {
this.dropdownContainerElement.trigger({
type: 'keyup',
which: ARROW_KEYS.ESC,
- keyCode: ARROW_KEYS.ESC
+ keyCode: ARROW_KEYS.ESC,
});
+
expect(this.dropdownContainerElement).not.toHaveClass('show');
});
});
@@ -168,19 +184,22 @@ describe('glDropdown', function describeDropdown() {
it('should show loading indicator while search results are being fetched by backend', () => {
const dropdownMenu = document.querySelector('.dropdown-menu');
- expect(dropdownMenu.className.indexOf('is-loading') !== -1).toEqual(true);
+ expect(dropdownMenu.className.indexOf('is-loading')).not.toBe(-1);
remoteCallback();
- expect(dropdownMenu.className.indexOf('is-loading') !== -1).toEqual(false);
+
+ expect(dropdownMenu.className.indexOf('is-loading')).toBe(-1);
});
it('should not focus search input while remote task is not complete', () => {
expect($(document.activeElement)).not.toEqual($(SEARCH_INPUT_SELECTOR));
remoteCallback();
+
expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR));
});
it('should focus search input after remote task is complete', () => {
remoteCallback();
+
expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR));
});
@@ -189,10 +208,11 @@ describe('glDropdown', function describeDropdown() {
this.dropdownContainerElement.trigger({
type: 'keyup',
which: ARROW_KEYS.ESC,
- keyCode: ARROW_KEYS.ESC
+ keyCode: ARROW_KEYS.ESC,
});
this.dropdownButtonElement.click();
this.dropdownContainerElement.trigger('transitionend');
+
expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR));
});
});
@@ -202,6 +222,7 @@ describe('glDropdown', function describeDropdown() {
initDropDown.call(this, false, true);
this.dropdownButtonElement.click();
this.dropdownContainerElement.trigger('transitionend');
+
expect($(document.activeElement)).toEqual($(SEARCH_INPUT_SELECTOR));
});
});
@@ -213,11 +234,11 @@ describe('glDropdown', function describeDropdown() {
.trigger('focus')
.val('g')
.trigger('input');
+
expect($searchInput.val()).toEqual('g');
this.dropdownButtonElement.trigger('hidden.bs.dropdown');
- $searchInput
- .trigger('blur')
- .trigger('focus');
+ $searchInput.trigger('blur').trigger('focus');
+
expect($searchInput.val()).toEqual('g');
});
@@ -226,31 +247,31 @@ describe('glDropdown', function describeDropdown() {
let dropdown;
beforeEach(() => {
- const dropdownOptions = {
-
- };
+ const dropdownOptions = {};
const $dropdownDiv = $('<div />');
$dropdownDiv.glDropdown(dropdownOptions);
dropdown = $dropdownDiv.data('glDropdown');
});
it('marks items without ID as active', () => {
- const dummyData = { };
+ const dummyData = {};
const html = dropdown.renderItem(dummyData, null, null);
const link = html.querySelector('a');
+
expect(link).toHaveClass('is-active');
});
it('does not mark items with ID as active', () => {
const dummyData = {
- id: 'ea'
+ id: 'ea',
};
const html = dropdown.renderItem(dummyData, null, null);
const link = html.querySelector('a');
+
expect(link).not.toHaveClass('is-active');
});
});
@@ -271,13 +292,14 @@ describe('glDropdown', function describeDropdown() {
// select item the first time
this.dropdownButtonElement.click();
$item.click();
+
expect($item).toHaveClass('is-active');
// select item the second time
this.dropdownButtonElement.click();
$item.click();
+
expect($item).toHaveClass('is-active');
expect($('.dropdown-toggle-text')).toHaveText(this.projectsData[0].id.toString());
});
});
-
diff --git a/spec/javascripts/gl_field_errors_spec.js b/spec/javascripts/gl_field_errors_spec.js
index 21c462cd040..b463c9afbee 100644
--- a/spec/javascripts/gl_field_errors_spec.js
+++ b/spec/javascripts/gl_field_errors_spec.js
@@ -19,6 +19,7 @@ describe('GL Style Field Errors', function() {
expect(this.$form.length).toBe(1);
expect(this.fieldErrors).toBeDefined();
const { inputs } = this.fieldErrors.state;
+
expect(inputs.length).toBe(4);
});
@@ -28,29 +29,50 @@ describe('GL Style Field Errors', function() {
expect(customErrorElem.length).toBe(1);
- const customErrors = this.fieldErrors.state.inputs.filter((input) => {
+ const customErrors = this.fieldErrors.state.inputs.filter(input => {
return input.inputElement.hasClass(customErrorFlag);
});
+
expect(customErrors.length).toBe(0);
});
it('should not show any errors before submit attempt', function() {
- this.$form.find('.email').val('not-a-valid-email').keyup();
- this.$form.find('.text-required').val('').keyup();
- this.$form.find('.alphanumberic').val('?---*').keyup();
+ this.$form
+ .find('.email')
+ .val('not-a-valid-email')
+ .keyup();
+ this.$form
+ .find('.text-required')
+ .val('')
+ .keyup();
+ this.$form
+ .find('.alphanumberic')
+ .val('?---*')
+ .keyup();
const errorsShown = this.$form.find('.gl-field-error-outline');
+
expect(errorsShown.length).toBe(0);
});
it('should show errors when input valid is submitted', function() {
- this.$form.find('.email').val('not-a-valid-email').keyup();
- this.$form.find('.text-required').val('').keyup();
- this.$form.find('.alphanumberic').val('?---*').keyup();
+ this.$form
+ .find('.email')
+ .val('not-a-valid-email')
+ .keyup();
+ this.$form
+ .find('.text-required')
+ .val('')
+ .keyup();
+ this.$form
+ .find('.alphanumberic')
+ .val('?---*')
+ .keyup();
this.$form.submit();
const errorsShown = this.$form.find('.gl-field-error-outline');
+
expect(errorsShown.length).toBe(4);
});
@@ -68,30 +90,35 @@ describe('GL Style Field Errors', function() {
// Then invalid input
emailInputElement.val('not-a-valid-email').keyup();
+
expect(emailInputElement).toHaveClass('gl-field-error-outline');
expect(fieldState.empty).toBe(false);
expect(fieldState.valid).toBe(false);
// Then valid input
emailInputElement.val('email@gitlab.com').keyup();
+
expect(emailInputElement).not.toHaveClass('gl-field-error-outline');
expect(fieldState.empty).toBe(false);
expect(fieldState.valid).toBe(true);
// Then invalid input
emailInputElement.val('not-a-valid-email').keyup();
+
expect(emailInputElement).toHaveClass('gl-field-error-outline');
expect(fieldState.empty).toBe(false);
expect(fieldState.valid).toBe(false);
// Then empty input
emailInputElement.val('').keyup();
+
expect(emailInputElement).toHaveClass('gl-field-error-outline');
expect(fieldState.empty).toBe(true);
expect(fieldState.valid).toBe(false);
// Then valid input
emailInputElement.val('email@gitlab.com').keyup();
+
expect(emailInputElement).not.toHaveClass('gl-field-error-outline');
expect(fieldState.empty).toBe(false);
expect(fieldState.valid).toBe(true);
diff --git a/spec/javascripts/gl_form_spec.js b/spec/javascripts/gl_form_spec.js
index 74383f901b2..69b3dae743a 100644
--- a/spec/javascripts/gl_form_spec.js
+++ b/spec/javascripts/gl_form_spec.js
@@ -5,8 +5,8 @@ import '~/lib/utils/text_utility';
import '~/lib/utils/common_utils';
describe('GLForm', () => {
- describe('when instantiated', function () {
- beforeEach((done) => {
+ describe('when instantiated', function() {
+ beforeEach(done => {
this.form = $('<form class="gfm-form"><textarea class="js-gfm-input"></form>');
this.textarea = this.form.find('textarea');
spyOn($.prototype, 'off').and.returnValue(this.textarea);
@@ -23,7 +23,7 @@ describe('GLForm', () => {
});
describe('setupAutosize', () => {
- beforeEach((done) => {
+ beforeEach(done => {
this.glForm.setupAutosize();
setTimeout(() => {
done();
@@ -101,6 +101,7 @@ describe('GLForm', () => {
spyOn($.prototype, 'outerHeight').and.returnValue(200);
spyOn($.prototype, 'data').and.returnValue(200);
spyOn(autosize, 'destroy');
+
expect(this.glForm.destroyAutosize()).toBeUndefined();
expect(autosize.destroy).not.toHaveBeenCalled();
});
diff --git a/spec/javascripts/gpg_badges_spec.js b/spec/javascripts/gpg_badges_spec.js
index 78330dd9633..e73f6d3909e 100644
--- a/spec/javascripts/gpg_badges_spec.js
+++ b/spec/javascripts/gpg_badges_spec.js
@@ -69,6 +69,7 @@ describe('GpgBadges', () => {
.then(() => {
expect(document.querySelector('.js-loading-gpg-badge:empty')).toBe(null);
const spinners = document.querySelectorAll('.js-loading-gpg-badge i.fa.fa-spinner.fa-spin');
+
expect(spinners.length).toBe(1);
done();
})
@@ -82,6 +83,7 @@ describe('GpgBadges', () => {
.then(() => {
expect(document.querySelector('.js-loading-gpg-badge')).toBe(null);
const parentContainer = document.querySelector('.parent-container');
+
expect(parentContainer.innerHTML.trim()).toEqual(dummyBadgeHtml);
done();
})
diff --git a/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js b/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js
index 4a4d6969e86..563d134ca81 100644
--- a/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js
+++ b/spec/javascripts/graphs/stat_graph_contributors_graph_spec.js
@@ -2,99 +2,118 @@
import { scaleLinear, scaleTime } from 'd3-scale';
import { timeParse } from 'd3-time-format';
-import { ContributorsGraph, ContributorsMasterGraph } from '~/pages/projects/graphs/show/stat_graph_contributors_graph';
+import {
+ ContributorsGraph,
+ ContributorsMasterGraph,
+} from '~/pages/projects/graphs/show/stat_graph_contributors_graph';
const d3 = { scaleLinear, scaleTime, timeParse };
-describe("ContributorsGraph", function () {
- describe("#set_x_domain", function () {
- it("set the x_domain", function () {
+describe('ContributorsGraph', function() {
+ describe('#set_x_domain', function() {
+ it('set the x_domain', function() {
ContributorsGraph.set_x_domain(20);
+
expect(ContributorsGraph.prototype.x_domain).toEqual(20);
});
});
- describe("#set_y_domain", function () {
- it("sets the y_domain", function () {
+ describe('#set_y_domain', function() {
+ it('sets the y_domain', function() {
ContributorsGraph.set_y_domain([{ commits: 30 }]);
+
expect(ContributorsGraph.prototype.y_domain).toEqual([0, 30]);
});
});
- describe("#init_x_domain", function () {
- it("sets the initial x_domain", function () {
- ContributorsGraph.init_x_domain([{ date: "2013-01-31" }, { date: "2012-01-31" }]);
- expect(ContributorsGraph.prototype.x_domain).toEqual(["2012-01-31", "2013-01-31"]);
+ describe('#init_x_domain', function() {
+ it('sets the initial x_domain', function() {
+ ContributorsGraph.init_x_domain([{ date: '2013-01-31' }, { date: '2012-01-31' }]);
+
+ expect(ContributorsGraph.prototype.x_domain).toEqual(['2012-01-31', '2013-01-31']);
});
});
- describe("#init_y_domain", function () {
- it("sets the initial y_domain", function () {
+ describe('#init_y_domain', function() {
+ it('sets the initial y_domain', function() {
ContributorsGraph.init_y_domain([{ commits: 30 }]);
+
expect(ContributorsGraph.prototype.y_domain).toEqual([0, 30]);
});
});
- describe("#init_domain", function () {
- it("calls init_x_domain and init_y_domain", function () {
- spyOn(ContributorsGraph, "init_x_domain");
- spyOn(ContributorsGraph, "init_y_domain");
+ describe('#init_domain', function() {
+ it('calls init_x_domain and init_y_domain', function() {
+ spyOn(ContributorsGraph, 'init_x_domain');
+ spyOn(ContributorsGraph, 'init_y_domain');
ContributorsGraph.init_domain();
+
expect(ContributorsGraph.init_x_domain).toHaveBeenCalled();
expect(ContributorsGraph.init_y_domain).toHaveBeenCalled();
});
});
- describe("#set_dates", function () {
- it("sets the dates", function () {
- ContributorsGraph.set_dates("2013-12-01");
- expect(ContributorsGraph.prototype.dates).toEqual("2013-12-01");
+ describe('#set_dates', function() {
+ it('sets the dates', function() {
+ ContributorsGraph.set_dates('2013-12-01');
+
+ expect(ContributorsGraph.prototype.dates).toEqual('2013-12-01');
});
});
- describe("#set_x_domain", function () {
- it("sets the instance's x domain using the prototype's x_domain", function () {
+ describe('#set_x_domain', function() {
+ it("sets the instance's x domain using the prototype's x_domain", function() {
ContributorsGraph.prototype.x_domain = 20;
var instance = new ContributorsGraph();
- instance.x = d3.scaleTime().range([0, 100]).clamp(true);
+ instance.x = d3
+ .scaleTime()
+ .range([0, 100])
+ .clamp(true);
spyOn(instance.x, 'domain');
instance.set_x_domain();
+
expect(instance.x.domain).toHaveBeenCalledWith(20);
});
});
- describe("#set_y_domain", function () {
- it("sets the instance's y domain using the prototype's y_domain", function () {
+ describe('#set_y_domain', function() {
+ it("sets the instance's y domain using the prototype's y_domain", function() {
ContributorsGraph.prototype.y_domain = 30;
var instance = new ContributorsGraph();
- instance.y = d3.scaleLinear().range([100, 0]).nice();
+ instance.y = d3
+ .scaleLinear()
+ .range([100, 0])
+ .nice();
spyOn(instance.y, 'domain');
instance.set_y_domain();
+
expect(instance.y.domain).toHaveBeenCalledWith(30);
});
});
- describe("#set_domain", function () {
- it("calls set_x_domain and set_y_domain", function () {
+ describe('#set_domain', function() {
+ it('calls set_x_domain and set_y_domain', function() {
var instance = new ContributorsGraph();
spyOn(instance, 'set_x_domain');
spyOn(instance, 'set_y_domain');
instance.set_domain();
+
expect(instance.set_x_domain).toHaveBeenCalled();
expect(instance.set_y_domain).toHaveBeenCalled();
});
});
- describe("#set_data", function () {
- it("sets the data", function () {
+ describe('#set_data', function() {
+ it('sets the data', function() {
var instance = new ContributorsGraph();
- instance.set_data("20");
- expect(instance.data).toEqual("20");
+ instance.set_data('20');
+
+ expect(instance.data).toEqual('20');
});
});
});
-describe("ContributorsMasterGraph", function () {
+describe('ContributorsMasterGraph', function() {
// TODO: fix or remove
// describe("#process_dates", function () {
// it("gets and parses dates", function () {
@@ -110,21 +129,23 @@ describe("ContributorsMasterGraph", function () {
// });
// });
- describe("#get_dates", function () {
- it("plucks the date field from data collection", function () {
+ describe('#get_dates', function() {
+ it('plucks the date field from data collection', function() {
var graph = new ContributorsMasterGraph();
- var data = [{ date: "2013-01-01" }, { date: "2012-12-15" }];
- expect(graph.get_dates(data)).toEqual(["2013-01-01", "2012-12-15"]);
+ var data = [{ date: '2013-01-01' }, { date: '2012-12-15' }];
+
+ expect(graph.get_dates(data)).toEqual(['2013-01-01', '2012-12-15']);
});
});
- describe("#parse_dates", function () {
- it("parses the dates", function () {
+ describe('#parse_dates', function() {
+ it('parses the dates', function() {
var graph = new ContributorsMasterGraph();
- var parseDate = d3.timeParse("%Y-%m-%d");
- var data = [{ date: "2013-01-01" }, { date: "2012-12-15" }];
+ var parseDate = d3.timeParse('%Y-%m-%d');
+ var data = [{ date: '2013-01-01' }, { date: '2012-12-15' }];
var correct = [{ date: parseDate(data[0].date) }, { date: parseDate(data[1].date) }];
graph.parse_dates(data);
+
expect(data).toEqual(correct);
});
});
diff --git a/spec/javascripts/graphs/stat_graph_contributors_spec.js b/spec/javascripts/graphs/stat_graph_contributors_spec.js
index e03114c1cc5..2ebb6845a8b 100644
--- a/spec/javascripts/graphs/stat_graph_contributors_spec.js
+++ b/spec/javascripts/graphs/stat_graph_contributors_spec.js
@@ -20,7 +20,9 @@ describe('ContributorsStatGraph', () => {
graph.change_date_header();
- expect(document.getElementById('date_header').innerText).toBe('31. Januar 2012 – 31. Januar 2013');
+ expect(document.getElementById('date_header').innerText).toBe(
+ '31. Januar 2012 – 31. Januar 2013',
+ );
});
});
});
diff --git a/spec/javascripts/graphs/stat_graph_contributors_util_spec.js b/spec/javascripts/graphs/stat_graph_contributors_util_spec.js
index 02d1ca1cc3b..511b660c671 100644
--- a/spec/javascripts/graphs/stat_graph_contributors_util_spec.js
+++ b/spec/javascripts/graphs/stat_graph_contributors_util_spec.js
@@ -2,56 +2,85 @@
import ContributorsStatGraphUtil from '~/pages/projects/graphs/show/stat_graph_contributors_util';
-describe("ContributorsStatGraphUtil", function () {
- describe("#parse_log", function () {
- it("returns a correctly parsed log", function () {
+describe('ContributorsStatGraphUtil', function() {
+ describe('#parse_log', function() {
+ it('returns a correctly parsed log', function() {
var fake_log = [
- { author_email: "karlo@email.com", author_name: "Karlo Soriano", date: "2013-05-09", additions: 471 },
- { author_email: "dzaporozhets@email.com", author_name: "Dmitriy Zaporozhets", date: "2013-05-08", additions: 6, deletions: 1 },
- { author_email: "dzaporozhets@email.com", author_name: "Dmitriy Zaporozhets", date: "2013-05-08", additions: 19, deletions: 3 },
- { author_email: "dzaporozhets@email.com", author_name: "Dmitriy Zaporozhets", date: "2013-05-08", additions: 29, deletions: 3 }
+ {
+ author_email: 'karlo@email.com',
+ author_name: 'Karlo Soriano',
+ date: '2013-05-09',
+ additions: 471,
+ },
+ {
+ author_email: 'dzaporozhets@email.com',
+ author_name: 'Dmitriy Zaporozhets',
+ date: '2013-05-08',
+ additions: 6,
+ deletions: 1,
+ },
+ {
+ author_email: 'dzaporozhets@email.com',
+ author_name: 'Dmitriy Zaporozhets',
+ date: '2013-05-08',
+ additions: 19,
+ deletions: 3,
+ },
+ {
+ author_email: 'dzaporozhets@email.com',
+ author_name: 'Dmitriy Zaporozhets',
+ date: '2013-05-08',
+ additions: 29,
+ deletions: 3,
+ },
];
var correct_parsed_log = {
total: [
- { date: "2013-05-09", additions: 471, deletions: 0, commits: 1 },
- { date: "2013-05-08", additions: 54, deletions: 7, commits: 3 }
+ { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
+ { date: '2013-05-08', additions: 54, deletions: 7, commits: 3 },
],
by_author: [
{
- author_name: "Karlo Soriano", author_email: "karlo@email.com",
- "2013-05-09": { date: "2013-05-09", additions: 471, deletions: 0, commits: 1 }
+ author_name: 'Karlo Soriano',
+ author_email: 'karlo@email.com',
+ '2013-05-09': { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
},
{
- author_name: "Dmitriy Zaporozhets", author_email: "dzaporozhets@email.com",
- "2013-05-08": { date: "2013-05-08", additions: 54, deletions: 7, commits: 3 }
- }
- ]
+ author_name: 'Dmitriy Zaporozhets',
+ author_email: 'dzaporozhets@email.com',
+ '2013-05-08': { date: '2013-05-08', additions: 54, deletions: 7, commits: 3 },
+ },
+ ],
};
+
expect(ContributorsStatGraphUtil.parse_log(fake_log)).toEqual(correct_parsed_log);
});
});
- describe("#store_data", function () {
- var fake_entry = { author: "Karlo Soriano", date: "2013-05-09", additions: 471 };
+ describe('#store_data', function() {
+ var fake_entry = { author: 'Karlo Soriano', date: '2013-05-09', additions: 471 };
var fake_total = {};
var fake_by_author = {};
- it("calls #store_commits", function () {
+ it('calls #store_commits', function() {
spyOn(ContributorsStatGraphUtil, 'store_commits');
ContributorsStatGraphUtil.store_data(fake_entry, fake_total, fake_by_author);
+
expect(ContributorsStatGraphUtil.store_commits).toHaveBeenCalled();
});
- it("calls #store_additions", function () {
+ it('calls #store_additions', function() {
spyOn(ContributorsStatGraphUtil, 'store_additions');
ContributorsStatGraphUtil.store_data(fake_entry, fake_total, fake_by_author);
+
expect(ContributorsStatGraphUtil.store_additions).toHaveBeenCalled();
});
- it("calls #store_deletions", function () {
+ it('calls #store_deletions', function() {
spyOn(ContributorsStatGraphUtil, 'store_deletions');
ContributorsStatGraphUtil.store_data(fake_entry, fake_total, fake_by_author);
+
expect(ContributorsStatGraphUtil.store_deletions).toHaveBeenCalled();
});
});
@@ -68,16 +97,18 @@ describe("ContributorsStatGraphUtil", function () {
// });
// });
- describe("#add", function () {
- it("adds 1 to current test_field in collection", function () {
+ describe('#add', function() {
+ it('adds 1 to current test_field in collection', function() {
var fake_collection = { test_field: 10 };
- ContributorsStatGraphUtil.add(fake_collection, "test_field", 1);
+ ContributorsStatGraphUtil.add(fake_collection, 'test_field', 1);
+
expect(fake_collection.test_field).toEqual(11);
});
- it("inits and adds 1 if test_field in collection is not defined", function () {
+ it('inits and adds 1 if test_field in collection is not defined', function() {
var fake_collection = {};
- ContributorsStatGraphUtil.add(fake_collection, "test_field", 1);
+ ContributorsStatGraphUtil.add(fake_collection, 'test_field', 1);
+
expect(fake_collection.test_field).toEqual(1);
});
});
@@ -106,111 +137,161 @@ describe("ContributorsStatGraphUtil", function () {
// });
// });
- describe("#add_date", function () {
- it("adds a date field to the collection", function () {
- var fake_date = "2013-10-02";
+ describe('#add_date', function() {
+ it('adds a date field to the collection', function() {
+ var fake_date = '2013-10-02';
var fake_collection = {};
ContributorsStatGraphUtil.add_date(fake_date, fake_collection);
- expect(fake_collection[fake_date].date).toEqual("2013-10-02");
+
+ expect(fake_collection[fake_date].date).toEqual('2013-10-02');
});
});
- describe("#add_author", function () {
- it("adds an author field to the collection", function () {
- var fake_author = { author_name: "Author", author_email: 'fake@email.com' };
+ describe('#add_author', function() {
+ it('adds an author field to the collection', function() {
+ var fake_author = { author_name: 'Author', author_email: 'fake@email.com' };
var fake_author_collection = {};
var fake_email_collection = {};
- ContributorsStatGraphUtil.add_author(fake_author, fake_author_collection, fake_email_collection);
- expect(fake_author_collection[fake_author.author_name].author_name).toEqual("Author");
- expect(fake_email_collection[fake_author.author_email].author_name).toEqual("Author");
+ ContributorsStatGraphUtil.add_author(
+ fake_author,
+ fake_author_collection,
+ fake_email_collection,
+ );
+
+ expect(fake_author_collection[fake_author.author_name].author_name).toEqual('Author');
+ expect(fake_email_collection[fake_author.author_email].author_name).toEqual('Author');
});
});
- describe("#get_total_data", function () {
- it("returns the collection sorted via specified field", function () {
+ describe('#get_total_data', function() {
+ it('returns the collection sorted via specified field', function() {
var fake_parsed_log = {
total: [
- { date: "2013-05-09", additions: 471, deletions: 0, commits: 1 },
- { date: "2013-05-08", additions: 54, deletions: 7, commits: 3 }
+ { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
+ { date: '2013-05-08', additions: 54, deletions: 7, commits: 3 },
],
by_author: [
{
- author: "Karlo Soriano",
- "2013-05-09": { date: "2013-05-09", additions: 471, deletions: 0, commits: 1 }
+ author: 'Karlo Soriano',
+ '2013-05-09': { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
},
{
- author: "Dmitriy Zaporozhets",
- "2013-05-08": { date: "2013-05-08", additions: 54, deletions: 7, commits: 3 }
- }
- ]
+ author: 'Dmitriy Zaporozhets',
+ '2013-05-08': { date: '2013-05-08', additions: 54, deletions: 7, commits: 3 },
+ },
+ ],
};
var correct_total_data = [
- { date: "2013-05-08", commits: 3 },
- { date: "2013-05-09", commits: 1 }
+ { date: '2013-05-08', commits: 3 },
+ { date: '2013-05-09', commits: 1 },
];
- expect(ContributorsStatGraphUtil.get_total_data(fake_parsed_log, "commits")).toEqual(correct_total_data);
+
+ expect(ContributorsStatGraphUtil.get_total_data(fake_parsed_log, 'commits')).toEqual(
+ correct_total_data,
+ );
});
});
- describe("#pick_field", function () {
- it("returns the collection with only the specified field and date", function () {
+ describe('#pick_field', function() {
+ it('returns the collection with only the specified field and date', function() {
var fake_parsed_log_total = [
- { date: "2013-05-09", additions: 471, deletions: 0, commits: 1 },
- { date: "2013-05-08", additions: 54, deletions: 7, commits: 3 }
+ { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
+ { date: '2013-05-08', additions: 54, deletions: 7, commits: 3 },
];
- ContributorsStatGraphUtil.pick_field(fake_parsed_log_total, "commits");
- var correct_pick_field_data = [{ date: "2013-05-09", commits: 1 }, { date: "2013-05-08", commits: 3 }];
- expect(ContributorsStatGraphUtil.pick_field(fake_parsed_log_total, "commits")).toEqual(correct_pick_field_data);
+ ContributorsStatGraphUtil.pick_field(fake_parsed_log_total, 'commits');
+ var correct_pick_field_data = [
+ { date: '2013-05-09', commits: 1 },
+ { date: '2013-05-08', commits: 3 },
+ ];
+
+ expect(ContributorsStatGraphUtil.pick_field(fake_parsed_log_total, 'commits')).toEqual(
+ correct_pick_field_data,
+ );
});
});
- describe("#get_author_data", function () {
- it("returns the log by author sorted by specified field", function () {
+ describe('#get_author_data', function() {
+ it('returns the log by author sorted by specified field', function() {
var fake_parsed_log = {
total: [
- { date: "2013-05-09", additions: 471, deletions: 0, commits: 1 },
- { date: "2013-05-08", additions: 54, deletions: 7, commits: 3 }
+ { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
+ { date: '2013-05-08', additions: 54, deletions: 7, commits: 3 },
],
by_author: [
{
- author_name: "Karlo Soriano", author_email: "karlo@email.com",
- "2013-05-09": { date: "2013-05-09", additions: 471, deletions: 0, commits: 1 }
+ author_name: 'Karlo Soriano',
+ author_email: 'karlo@email.com',
+ '2013-05-09': { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
},
{
- author_name: "Dmitriy Zaporozhets", author_email: "dzaporozhets@email.com",
- "2013-05-08": { date: "2013-05-08", additions: 54, deletions: 7, commits: 3 }
- }
- ]
+ author_name: 'Dmitriy Zaporozhets',
+ author_email: 'dzaporozhets@email.com',
+ '2013-05-08': { date: '2013-05-08', additions: 54, deletions: 7, commits: 3 },
+ },
+ ],
};
var correct_author_data = [
- { author_name: "Dmitriy Zaporozhets", author_email: "dzaporozhets@email.com", dates: { "2013-05-08": 3 }, deletions: 7, additions: 54, "commits": 3 },
- { author_name: "Karlo Soriano", author_email: "karlo@email.com", dates: { "2013-05-09": 1 }, deletions: 0, additions: 471, commits: 1 }
+ {
+ author_name: 'Dmitriy Zaporozhets',
+ author_email: 'dzaporozhets@email.com',
+ dates: { '2013-05-08': 3 },
+ deletions: 7,
+ additions: 54,
+ commits: 3,
+ },
+ {
+ author_name: 'Karlo Soriano',
+ author_email: 'karlo@email.com',
+ dates: { '2013-05-09': 1 },
+ deletions: 0,
+ additions: 471,
+ commits: 1,
+ },
];
- expect(ContributorsStatGraphUtil.get_author_data(fake_parsed_log, "commits")).toEqual(correct_author_data);
+
+ expect(ContributorsStatGraphUtil.get_author_data(fake_parsed_log, 'commits')).toEqual(
+ correct_author_data,
+ );
});
});
- describe("#parse_log_entry", function () {
- it("adds the corresponding info from the log entry to the author", function () {
- var fake_log_entry = { author_name: "Karlo Soriano", author_email: "karlo@email.com",
- "2013-05-09": { date: "2013-05-09", additions: 471, deletions: 0, commits: 1 }
+ describe('#parse_log_entry', function() {
+ it('adds the corresponding info from the log entry to the author', function() {
+ var fake_log_entry = {
+ author_name: 'Karlo Soriano',
+ author_email: 'karlo@email.com',
+ '2013-05-09': { date: '2013-05-09', additions: 471, deletions: 0, commits: 1 },
+ };
+ var correct_parsed_log = {
+ author_name: 'Karlo Soriano',
+ author_email: 'karlo@email.com',
+ dates: { '2013-05-09': 1 },
+ deletions: 0,
+ additions: 471,
+ commits: 1,
};
- var correct_parsed_log = { author_name: "Karlo Soriano", author_email: "karlo@email.com", dates: { "2013-05-09": 1 }, deletions: 0, additions: 471, commits: 1 };
- expect(ContributorsStatGraphUtil.parse_log_entry(fake_log_entry, 'commits', null)).toEqual(correct_parsed_log);
+
+ expect(ContributorsStatGraphUtil.parse_log_entry(fake_log_entry, 'commits', null)).toEqual(
+ correct_parsed_log,
+ );
});
});
- describe("#in_range", function () {
- var date = "2013-05-09";
- it("returns true if date_range is null", function () {
+ describe('#in_range', function() {
+ var date = '2013-05-09';
+ it('returns true if date_range is null', function() {
expect(ContributorsStatGraphUtil.in_range(date, null)).toEqual(true);
});
- it("returns true if date is in range", function () {
- var date_range = [new Date("2013-01-01"), new Date("2013-12-12")];
+
+ it('returns true if date is in range', function() {
+ var date_range = [new Date('2013-01-01'), new Date('2013-12-12')];
+
expect(ContributorsStatGraphUtil.in_range(date, date_range)).toEqual(true);
});
- it("returns false if date is not in range", function () {
- var date_range = [new Date("1999-12-01"), new Date("2000-12-01")];
+
+ it('returns false if date is not in range', function() {
+ var date_range = [new Date('1999-12-01'), new Date('2000-12-01')];
+
expect(ContributorsStatGraphUtil.in_range(date, date_range)).toEqual(false);
});
});
diff --git a/spec/javascripts/groups/components/app_spec.js b/spec/javascripts/groups/components/app_spec.js
index 89c07d1f06d..d832441dc93 100644
--- a/spec/javascripts/groups/components/app_spec.js
+++ b/spec/javascripts/groups/components/app_spec.js
@@ -76,6 +76,7 @@ describe('AppComponent', () => {
spyOn(vm.store, 'getGroups');
const { groups } = vm;
+
expect(vm.store.getGroups).toHaveBeenCalled();
expect(groups).not.toBeDefined();
});
@@ -86,6 +87,7 @@ describe('AppComponent', () => {
spyOn(vm.store, 'getPaginationInfo');
const { pageInfo } = vm;
+
expect(vm.store.getPaginationInfo).toHaveBeenCalled();
expect(pageInfo).not.toBeDefined();
});
@@ -154,6 +156,7 @@ describe('AppComponent', () => {
spyOn(vm, 'updateGroups').and.callThrough();
vm.fetchAllGroups();
+
expect(vm.isLoading).toBe(true);
expect(vm.fetchGroups).toHaveBeenCalled();
setTimeout(() => {
@@ -168,6 +171,7 @@ describe('AppComponent', () => {
spyOn(vm, 'updateGroups').and.callThrough();
vm.fetchAllGroups();
+
expect(vm.fetchGroups).toHaveBeenCalledWith({
page: null,
filterGroupsBy: null,
@@ -191,6 +195,7 @@ describe('AppComponent', () => {
spyOn($, 'scrollTo');
vm.fetchPage(2, null, null, true);
+
expect(vm.isLoading).toBe(true);
expect(vm.fetchGroups).toHaveBeenCalledWith({
page: 2,
@@ -210,6 +215,7 @@ describe('AppComponent', () => {
jasmine.any(String),
jasmine.any(String),
);
+
expect(vm.updateGroups).toHaveBeenCalled();
done();
}, 0);
@@ -230,6 +236,7 @@ describe('AppComponent', () => {
spyOn(vm.store, 'setGroupChildren');
vm.toggleChildren(groupItem);
+
expect(groupItem.isChildrenLoading).toBe(true);
expect(vm.fetchGroups).toHaveBeenCalledWith({
parentId: groupItem.id,
@@ -245,6 +252,7 @@ describe('AppComponent', () => {
groupItem.children = mockRawChildren;
vm.toggleChildren(groupItem);
+
expect(vm.fetchGroups).not.toHaveBeenCalled();
expect(groupItem.isOpen).toBe(true);
});
@@ -254,6 +262,7 @@ describe('AppComponent', () => {
groupItem.isOpen = true;
vm.toggleChildren(groupItem);
+
expect(vm.fetchGroups).not.toHaveBeenCalled();
expect(groupItem.isOpen).toBe(false);
});
@@ -262,6 +271,7 @@ describe('AppComponent', () => {
spyOn(vm, 'fetchGroups').and.returnValue(returnServicePromise({}, true));
vm.toggleChildren(groupItem);
+
expect(groupItem.isChildrenLoading).toBe(true);
setTimeout(() => {
expect(groupItem.isChildrenLoading).toBe(false);
@@ -273,18 +283,22 @@ describe('AppComponent', () => {
describe('showLeaveGroupModal', () => {
it('caches candidate group (as props) which is to be left', () => {
const group = Object.assign({}, mockParentGroupItem);
+
expect(vm.targetGroup).toBe(null);
expect(vm.targetParentGroup).toBe(null);
vm.showLeaveGroupModal(group, mockParentGroupItem);
+
expect(vm.targetGroup).not.toBe(null);
expect(vm.targetParentGroup).not.toBe(null);
});
it('updates props which show modal confirmation dialog', () => {
const group = Object.assign({}, mockParentGroupItem);
+
expect(vm.showModal).toBe(false);
expect(vm.groupLeaveConfirmationMessage).toBe('');
vm.showLeaveGroupModal(group, mockParentGroupItem);
+
expect(vm.showModal).toBe(true);
expect(vm.groupLeaveConfirmationMessage).toBe(
`Are you sure you want to leave the "${group.fullName}" group?`,
@@ -296,8 +310,10 @@ describe('AppComponent', () => {
it('hides modal confirmation which is shown before leaving the group', () => {
const group = Object.assign({}, mockParentGroupItem);
vm.showLeaveGroupModal(group, mockParentGroupItem);
+
expect(vm.showModal).toBe(true);
vm.hideLeaveGroupModal();
+
expect(vm.showModal).toBe(false);
});
});
@@ -323,6 +339,7 @@ describe('AppComponent', () => {
spyOn($, 'scrollTo');
vm.leaveGroup();
+
expect(vm.showModal).toBe(false);
expect(vm.targetGroup.isBeingRemoved).toBe(true);
expect(vm.service.leaveGroup).toHaveBeenCalledWith(vm.targetGroup.leavePath);
@@ -343,6 +360,7 @@ describe('AppComponent', () => {
spyOn(window, 'Flash');
vm.leaveGroup();
+
expect(vm.targetGroup.isBeingRemoved).toBe(true);
expect(vm.service.leaveGroup).toHaveBeenCalledWith(childGroupItem.leavePath);
setTimeout(() => {
@@ -362,6 +380,7 @@ describe('AppComponent', () => {
spyOn(window, 'Flash');
vm.leaveGroup(childGroupItem, groupItem);
+
expect(vm.targetGroup.isBeingRemoved).toBe(true);
expect(vm.service.leaveGroup).toHaveBeenCalledWith(childGroupItem.leavePath);
setTimeout(() => {
@@ -378,6 +397,7 @@ describe('AppComponent', () => {
spyOn(vm.store, 'setPaginationInfo');
vm.updatePagination(mockRawPageInfo);
+
expect(vm.store.setPaginationInfo).toHaveBeenCalledWith(mockRawPageInfo);
});
});
@@ -387,6 +407,7 @@ describe('AppComponent', () => {
spyOn(vm.store, 'setGroups');
vm.updateGroups(mockGroups);
+
expect(vm.store.setGroups).toHaveBeenCalledWith(mockGroups);
});
@@ -394,14 +415,17 @@ describe('AppComponent', () => {
spyOn(vm.store, 'setSearchedGroups');
vm.updateGroups(mockGroups, true);
+
expect(vm.store.setSearchedGroups).toHaveBeenCalledWith(mockGroups);
});
it('should set `isSearchEmpty` prop based on groups count', () => {
vm.updateGroups(mockGroups);
+
expect(vm.isSearchEmpty).toBe(false);
vm.updateGroups([]);
+
expect(vm.isSearchEmpty).toBe(true);
});
});
@@ -497,6 +521,7 @@ describe('AppComponent', () => {
vm.showModal = true;
Vue.nextTick(() => {
const modalDialogEl = vm.$el.querySelector('.modal');
+
expect(modalDialogEl).not.toBe(null);
expect(modalDialogEl.querySelector('.modal-title').innerText.trim()).toBe('Are you sure?');
expect(modalDialogEl.querySelector('.btn.btn-warning').innerText.trim()).toBe('Leave');
diff --git a/spec/javascripts/groups/components/group_folder_spec.js b/spec/javascripts/groups/components/group_folder_spec.js
index 4eb198595fb..fdfd1b82bd8 100644
--- a/spec/javascripts/groups/components/group_folder_spec.js
+++ b/spec/javascripts/groups/components/group_folder_spec.js
@@ -18,7 +18,7 @@ const createComponent = (groups = mockGroups, parentGroup = mockParentGroupItem)
describe('GroupFolderComponent', () => {
let vm;
- beforeEach((done) => {
+ beforeEach(done => {
Vue.component('group-item', groupItemComponent);
vm = createComponent();
@@ -59,6 +59,7 @@ describe('GroupFolderComponent', () => {
const newVm = createComponent(mockGroups, parentGroup);
newVm.$mount();
+
expect(newVm.$el.querySelector('li.group-row a.has-more-items')).toBeDefined();
newVm.$destroy();
});
diff --git a/spec/javascripts/groups/components/group_item_spec.js b/spec/javascripts/groups/components/group_item_spec.js
index d0cac5efc40..4d6d0c895b6 100644
--- a/spec/javascripts/groups/components/group_item_spec.js
+++ b/spec/javascripts/groups/components/group_item_spec.js
@@ -17,7 +17,7 @@ const createComponent = (group = mockParentGroupItem, parentGroup = mockChildren
describe('GroupItemComponent', () => {
let vm;
- beforeEach((done) => {
+ beforeEach(done => {
Vue.component('group-folder', groupFolderComponent);
vm = createComponent();
@@ -44,8 +44,8 @@ describe('GroupItemComponent', () => {
const { rowClass } = vm;
expect(Object.keys(rowClass).length).toBe(classes.length);
- Object.keys(rowClass).forEach((className) => {
- expect(classes.indexOf(className) > -1).toBeTruthy();
+ Object.keys(rowClass).forEach(className => {
+ expect(classes.indexOf(className)).toBeGreaterThan(-1);
});
});
});
@@ -57,11 +57,13 @@ describe('GroupItemComponent', () => {
group.childrenCount = 5;
newVm = createComponent(group);
+
expect(newVm.hasChildren).toBeTruthy();
newVm.$destroy();
group.childrenCount = 0;
newVm = createComponent(group);
+
expect(newVm.hasChildren).toBeFalsy();
newVm.$destroy();
});
@@ -74,11 +76,13 @@ describe('GroupItemComponent', () => {
group.avatarUrl = null;
newVm = createComponent(group);
+
expect(newVm.hasAvatar).toBeFalsy();
newVm.$destroy();
group.avatarUrl = '/uploads/group_avatar.png';
newVm = createComponent(group);
+
expect(newVm.hasAvatar).toBeTruthy();
newVm.$destroy();
});
@@ -91,11 +95,13 @@ describe('GroupItemComponent', () => {
group.type = 'group';
newVm = createComponent(group);
+
expect(newVm.isGroup).toBeTruthy();
newVm.$destroy();
group.type = 'project';
newVm = createComponent(group);
+
expect(newVm.isGroup).toBeFalsy();
newVm.$destroy();
});
@@ -127,10 +133,11 @@ describe('GroupItemComponent', () => {
spyOn(eventHub, '$emit');
vm.onClickRowGroup(event);
+
expect(eventHub.$emit).toHaveBeenCalledWith('toggleChildren', vm.group);
});
- it('should navigate page to group homepage if group does not have any children present', (done) => {
+ it('should navigate page to group homepage if group does not have any children present', done => {
const group = Object.assign({}, mockParentGroupItem);
group.childrenCount = 0;
const newVm = createComponent(group);
diff --git a/spec/javascripts/groups/components/groups_spec.js b/spec/javascripts/groups/components/groups_spec.js
index 793c4909d89..6ba4fe23a69 100644
--- a/spec/javascripts/groups/components/groups_spec.js
+++ b/spec/javascripts/groups/components/groups_spec.js
@@ -21,7 +21,7 @@ const createComponent = (searchEmpty = false) => {
describe('GroupsComponent', () => {
let vm;
- beforeEach((done) => {
+ beforeEach(done => {
Vue.component('group-folder', groupFolderComponent);
Vue.component('group-item', groupItemComponent);
@@ -42,23 +42,30 @@ describe('GroupsComponent', () => {
spyOn(eventHub, '$emit').and.stub();
vm.change(2);
- expect(eventHub.$emit).toHaveBeenCalledWith('fetchPage', 2, jasmine.any(Object), jasmine.any(Object), jasmine.any(Object));
+
+ expect(eventHub.$emit).toHaveBeenCalledWith(
+ 'fetchPage',
+ 2,
+ jasmine.any(Object),
+ jasmine.any(Object),
+ jasmine.any(Object),
+ );
});
});
});
describe('template', () => {
- it('should render component template correctly', (done) => {
+ it('should render component template correctly', done => {
Vue.nextTick(() => {
expect(vm.$el.querySelector('.groups-list-tree-container')).toBeDefined();
expect(vm.$el.querySelector('.group-list-tree')).toBeDefined();
expect(vm.$el.querySelector('.gl-pagination')).toBeDefined();
- expect(vm.$el.querySelectorAll('.has-no-search-results').length === 0).toBeTruthy();
+ expect(vm.$el.querySelectorAll('.has-no-search-results').length).toBe(0);
done();
});
});
- it('should render empty search message when `searchEmpty` is `true`', (done) => {
+ it('should render empty search message when `searchEmpty` is `true`', done => {
vm.searchEmpty = true;
Vue.nextTick(() => {
expect(vm.$el.querySelector('.has-no-search-results')).toBeDefined();
diff --git a/spec/javascripts/groups/components/item_actions_spec.js b/spec/javascripts/groups/components/item_actions_spec.js
index 15fd37ebcd2..3f66e7fd6f2 100644
--- a/spec/javascripts/groups/components/item_actions_spec.js
+++ b/spec/javascripts/groups/components/item_actions_spec.js
@@ -30,7 +30,12 @@ describe('ItemActionsComponent', () => {
it('emits `showLeaveGroupModal` event with `group` and `parentGroup` props', () => {
spyOn(eventHub, '$emit');
vm.onLeaveGroup();
- expect(eventHub.$emit).toHaveBeenCalledWith('showLeaveGroupModal', vm.group, vm.parentGroup);
+
+ expect(eventHub.$emit).toHaveBeenCalledWith(
+ 'showLeaveGroupModal',
+ vm.group,
+ vm.parentGroup,
+ );
});
});
});
@@ -46,6 +51,7 @@ describe('ItemActionsComponent', () => {
const newVm = createComponent(group);
const editBtn = newVm.$el.querySelector('a.edit-group');
+
expect(editBtn).toBeDefined();
expect(editBtn.classList.contains('no-expand')).toBeTruthy();
expect(editBtn.getAttribute('href')).toBe(group.editPath);
@@ -63,6 +69,7 @@ describe('ItemActionsComponent', () => {
const newVm = createComponent(group);
const leaveBtn = newVm.$el.querySelector('a.leave-group');
+
expect(leaveBtn).toBeDefined();
expect(leaveBtn.classList.contains('no-expand')).toBeTruthy();
expect(leaveBtn.getAttribute('href')).toBe(group.leavePath);
diff --git a/spec/javascripts/groups/components/item_caret_spec.js b/spec/javascripts/groups/components/item_caret_spec.js
index 36f838a104f..6e430dbcdb2 100644
--- a/spec/javascripts/groups/components/item_caret_spec.js
+++ b/spec/javascripts/groups/components/item_caret_spec.js
@@ -16,6 +16,7 @@ describe('ItemCaretComponent', () => {
describe('template', () => {
it('should render component template correctly', () => {
const vm = createComponent();
+
expect(vm.$el.classList.contains('folder-caret')).toBeTruthy();
expect(vm.$el.querySelectorAll('svg').length).toBe(1);
vm.$destroy();
@@ -23,12 +24,14 @@ describe('ItemCaretComponent', () => {
it('should render caret down icon if `isGroupOpen` prop is `true`', () => {
const vm = createComponent(true);
+
expect(vm.$el.querySelector('svg use').getAttribute('xlink:href')).toContain('angle-down');
vm.$destroy();
});
it('should render caret right icon if `isGroupOpen` prop is `false`', () => {
const vm = createComponent();
+
expect(vm.$el.querySelector('svg use').getAttribute('xlink:href')).toContain('angle-right');
vm.$destroy();
});
diff --git a/spec/javascripts/groups/components/item_stats_spec.js b/spec/javascripts/groups/components/item_stats_spec.js
index ee7ee18259e..00d6a4817d7 100644
--- a/spec/javascripts/groups/components/item_stats_spec.js
+++ b/spec/javascripts/groups/components/item_stats_spec.js
@@ -22,9 +22,10 @@ describe('ItemStatsComponent', () => {
describe('computed', () => {
describe('visibilityIcon', () => {
it('should return icon class based on `item.visibility` value', () => {
- Object.keys(VISIBILITY_TYPE_ICON).forEach((visibility) => {
+ Object.keys(VISIBILITY_TYPE_ICON).forEach(visibility => {
const item = Object.assign({}, mockParentGroupItem, { visibility });
const vm = createComponent(item);
+
expect(vm.visibilityIcon).toBe(VISIBILITY_TYPE_ICON[visibility]);
vm.$destroy();
});
@@ -33,24 +34,26 @@ describe('ItemStatsComponent', () => {
describe('visibilityTooltip', () => {
it('should return tooltip string for Group based on `item.visibility` value', () => {
- Object.keys(GROUP_VISIBILITY_TYPE).forEach((visibility) => {
+ Object.keys(GROUP_VISIBILITY_TYPE).forEach(visibility => {
const item = Object.assign({}, mockParentGroupItem, {
visibility,
type: ITEM_TYPE.GROUP,
});
const vm = createComponent(item);
+
expect(vm.visibilityTooltip).toBe(GROUP_VISIBILITY_TYPE[visibility]);
vm.$destroy();
});
});
it('should return tooltip string for Project based on `item.visibility` value', () => {
- Object.keys(PROJECT_VISIBILITY_TYPE).forEach((visibility) => {
+ Object.keys(PROJECT_VISIBILITY_TYPE).forEach(visibility => {
const item = Object.assign({}, mockParentGroupItem, {
visibility,
type: ITEM_TYPE.PROJECT,
});
const vm = createComponent(item);
+
expect(vm.visibilityTooltip).toBe(PROJECT_VISIBILITY_TYPE[visibility]);
vm.$destroy();
});
@@ -64,11 +67,13 @@ describe('ItemStatsComponent', () => {
item = Object.assign({}, mockParentGroupItem, { type: ITEM_TYPE.PROJECT });
vm = createComponent(item);
+
expect(vm.isProject).toBeTruthy();
vm.$destroy();
item = Object.assign({}, mockParentGroupItem, { type: ITEM_TYPE.GROUP });
vm = createComponent(item);
+
expect(vm.isProject).toBeFalsy();
vm.$destroy();
});
@@ -81,11 +86,13 @@ describe('ItemStatsComponent', () => {
item = Object.assign({}, mockParentGroupItem, { type: ITEM_TYPE.GROUP });
vm = createComponent(item);
+
expect(vm.isGroup).toBeTruthy();
vm.$destroy();
item = Object.assign({}, mockParentGroupItem, { type: ITEM_TYPE.PROJECT });
vm = createComponent(item);
+
expect(vm.isGroup).toBeFalsy();
vm.$destroy();
});
@@ -105,9 +112,10 @@ describe('ItemStatsComponent', () => {
const vm = createComponent();
const visibilityIconEl = vm.$el.querySelector('.item-visibility');
+
expect(visibilityIconEl).not.toBe(null);
expect(visibilityIconEl.dataset.originalTitle).toBe(vm.visibilityTooltip);
- expect(visibilityIconEl.querySelectorAll('svg').length > 0).toBeTruthy();
+ expect(visibilityIconEl.querySelectorAll('svg').length).toBeGreaterThan(0);
vm.$destroy();
});
@@ -120,10 +128,11 @@ describe('ItemStatsComponent', () => {
const vm = createComponent(item);
const projectStarIconEl = vm.$el.querySelector('.project-stars');
- expect(projectStarIconEl).not.toBe(null);
- expect(projectStarIconEl.querySelectorAll('svg').length > 0).toBeTruthy();
- expect(projectStarIconEl.querySelectorAll('.stat-value').length > 0).toBeTruthy();
- expect(vm.$el.querySelectorAll('.last-updated').length > 0).toBeTruthy();
+
+ expect(projectStarIconEl).not.toBeNull();
+ expect(projectStarIconEl.querySelectorAll('svg').length).toBeGreaterThan(0);
+ expect(projectStarIconEl.querySelectorAll('.stat-value').length).toBeGreaterThan(0);
+ expect(vm.$el.querySelectorAll('.last-updated').length).toBeGreaterThan(0);
vm.$destroy();
});
diff --git a/spec/javascripts/groups/components/item_stats_value_spec.js b/spec/javascripts/groups/components/item_stats_value_spec.js
index 5e35ae4d36c..ea8edcf49cd 100644
--- a/spec/javascripts/groups/components/item_stats_value_spec.js
+++ b/spec/javascripts/groups/components/item_stats_value_spec.js
@@ -29,11 +29,13 @@ describe('ItemStatsValueComponent', () => {
describe('isValuePresent', () => {
it('returns true if non-empty `value` is present', () => {
vm = createComponent(Object.assign({}, itemConfig, { value: 10 }));
+
expect(vm.isValuePresent).toBeTruthy();
});
it('returns false if empty `value` is present', () => {
vm = createComponent(itemConfig);
+
expect(vm.isValuePresent).toBeFalsy();
});
@@ -57,8 +59,8 @@ describe('ItemStatsValueComponent', () => {
it('renders component element correctly', () => {
expect(vm.$el.classList.contains('number-subgroups')).toBeTruthy();
- expect(vm.$el.querySelectorAll('svg').length > 0).toBeTruthy();
- expect(vm.$el.querySelectorAll('.stat-value').length > 0).toBeTruthy();
+ expect(vm.$el.querySelectorAll('svg').length).toBeGreaterThan(0);
+ expect(vm.$el.querySelectorAll('.stat-value').length).toBeGreaterThan(0);
});
it('renders element tooltip correctly', () => {
diff --git a/spec/javascripts/groups/components/item_type_icon_spec.js b/spec/javascripts/groups/components/item_type_icon_spec.js
index 24380689b29..73108512222 100644
--- a/spec/javascripts/groups/components/item_type_icon_spec.js
+++ b/spec/javascripts/groups/components/item_type_icon_spec.js
@@ -18,6 +18,7 @@ describe('ItemTypeIconComponent', () => {
it('should render component template correctly', () => {
const vm = createComponent();
vm.$mount();
+
expect(vm.$el.classList.contains('item-type-icon')).toBeTruthy();
vm.$destroy();
});
@@ -27,11 +28,13 @@ describe('ItemTypeIconComponent', () => {
vm = createComponent(ITEM_TYPE.GROUP, true);
vm.$mount();
+
expect(vm.$el.querySelector('use').getAttribute('xlink:href')).toContain('folder-open');
vm.$destroy();
vm = createComponent(ITEM_TYPE.GROUP);
vm.$mount();
+
expect(vm.$el.querySelector('use').getAttribute('xlink:href')).toContain('folder');
vm.$destroy();
});
@@ -41,11 +44,13 @@ describe('ItemTypeIconComponent', () => {
vm = createComponent(ITEM_TYPE.PROJECT);
vm.$mount();
+
expect(vm.$el.querySelector('use').getAttribute('xlink:href')).toContain('bookmark');
vm.$destroy();
vm = createComponent(ITEM_TYPE.GROUP);
vm.$mount();
+
expect(vm.$el.querySelector('use').getAttribute('xlink:href')).not.toContain('bookmark');
vm.$destroy();
});
diff --git a/spec/javascripts/groups/mock_data.js b/spec/javascripts/groups/mock_data.js
index 8bf6417487d..2fdc844f3d9 100644
--- a/spec/javascripts/groups/mock_data.js
+++ b/spec/javascripts/groups/mock_data.js
@@ -340,7 +340,8 @@ export const mockSearchedGroups = [
{
id: 17,
name: 'v4.4',
- description: 'Voluptatem qui ea error aperiam veritatis doloremque consequatur temporibus.',
+ description:
+ 'Voluptatem qui ea error aperiam veritatis doloremque consequatur temporibus.',
visibility: 'public',
full_name: 'platform / hardware / bsp / kernel / common / v4.4',
relative_path: '/platform/hardware/bsp/kernel/common/v4.4',
diff --git a/spec/javascripts/groups/service/groups_service_spec.js b/spec/javascripts/groups/service/groups_service_spec.js
index 20bb63687f7..339e5131615 100644
--- a/spec/javascripts/groups/service/groups_service_spec.js
+++ b/spec/javascripts/groups/service/groups_service_spec.js
@@ -24,9 +24,11 @@ describe('GroupsService', () => {
};
service.getGroups(55, 2, 'git', 'created_asc', true);
+
expect(service.groups.get).toHaveBeenCalledWith({ parent_id: 55 });
service.getGroups(null, 2, 'git', 'created_asc', true);
+
expect(service.groups.get).toHaveBeenCalledWith(queryParams);
});
});
@@ -36,6 +38,7 @@ describe('GroupsService', () => {
spyOn(Vue.http, 'delete').and.stub();
service.leaveGroup(mockParentGroupItem.leavePath);
+
expect(Vue.http.delete).toHaveBeenCalledWith(mockParentGroupItem.leavePath);
});
});
diff --git a/spec/javascripts/groups/store/groups_store_spec.js b/spec/javascripts/groups/store/groups_store_spec.js
index d74f38f476e..38de4b89f31 100644
--- a/spec/javascripts/groups/store/groups_store_spec.js
+++ b/spec/javascripts/groups/store/groups_store_spec.js
@@ -1,7 +1,9 @@
import GroupsStore from '~/groups/store/groups_store';
import {
- mockGroups, mockSearchedGroups,
- mockParentGroupItem, mockRawChildren,
+ mockGroups,
+ mockSearchedGroups,
+ mockParentGroupItem,
+ mockRawChildren,
mockRawPageInfo,
} from '../mock_data';
@@ -11,12 +13,14 @@ describe('ProjectsStore', () => {
let store;
store = new GroupsStore();
+
expect(Object.keys(store.state).length).toBe(2);
expect(Array.isArray(store.state.groups)).toBeTruthy();
expect(Object.keys(store.state.pageInfo).length).toBe(0);
expect(store.hideProjects).not.toBeDefined();
store = new GroupsStore(true);
+
expect(store.hideProjects).toBeTruthy();
});
});
@@ -27,9 +31,10 @@ describe('ProjectsStore', () => {
spyOn(store, 'formatGroupItem').and.callThrough();
store.setGroups(mockGroups);
+
expect(store.state.groups.length).toBe(mockGroups.length);
expect(store.formatGroupItem).toHaveBeenCalledWith(jasmine.any(Object));
- expect(Object.keys(store.state.groups[0]).indexOf('fullName') > -1).toBeTruthy();
+ expect(Object.keys(store.state.groups[0]).indexOf('fullName')).toBeGreaterThan(-1);
});
});
@@ -39,10 +44,13 @@ describe('ProjectsStore', () => {
spyOn(store, 'formatGroupItem').and.callThrough();
store.setSearchedGroups(mockSearchedGroups);
+
expect(store.state.groups.length).toBe(mockSearchedGroups.length);
expect(store.formatGroupItem).toHaveBeenCalledWith(jasmine.any(Object));
- expect(Object.keys(store.state.groups[0]).indexOf('fullName') > -1).toBeTruthy();
- expect(Object.keys(store.state.groups[0].children[0]).indexOf('fullName') > -1).toBeTruthy();
+ expect(Object.keys(store.state.groups[0]).indexOf('fullName')).toBeGreaterThan(-1);
+ expect(Object.keys(store.state.groups[0].children[0]).indexOf('fullName')).toBeGreaterThan(
+ -1,
+ );
});
});
@@ -52,9 +60,10 @@ describe('ProjectsStore', () => {
spyOn(store, 'formatGroupItem').and.callThrough();
store.setGroupChildren(mockParentGroupItem, mockRawChildren);
+
expect(store.formatGroupItem).toHaveBeenCalledWith(jasmine.any(Object));
expect(mockParentGroupItem.children.length).toBe(1);
- expect(Object.keys(mockParentGroupItem.children[0]).indexOf('fullName') > -1).toBeTruthy();
+ expect(Object.keys(mockParentGroupItem.children[0]).indexOf('fullName')).toBeGreaterThan(-1);
expect(mockParentGroupItem.isOpen).toBeTruthy();
expect(mockParentGroupItem.isChildrenLoading).toBeFalsy();
});
@@ -65,6 +74,7 @@ describe('ProjectsStore', () => {
const store = new GroupsStore();
store.setPaginationInfo(mockRawPageInfo);
+
expect(store.state.pageInfo.perPage).toBe(10);
expect(store.state.pageInfo.page).toBe(10);
expect(store.state.pageInfo.total).toBe(10);
@@ -81,14 +91,16 @@ describe('ProjectsStore', () => {
store = new GroupsStore();
updatedGroupItem = store.formatGroupItem(mockRawChildren[0]);
- expect(Object.keys(updatedGroupItem).indexOf('fullName') > -1).toBeTruthy();
+
+ expect(Object.keys(updatedGroupItem).indexOf('fullName')).toBeGreaterThan(-1);
expect(updatedGroupItem.childrenCount).toBe(mockRawChildren[0].children_count);
expect(updatedGroupItem.isChildrenLoading).toBe(false);
expect(updatedGroupItem.isBeingRemoved).toBe(false);
store = new GroupsStore(true);
updatedGroupItem = store.formatGroupItem(mockRawChildren[0]);
- expect(Object.keys(updatedGroupItem).indexOf('fullName') > -1).toBeTruthy();
+
+ expect(Object.keys(updatedGroupItem).indexOf('fullName')).toBeGreaterThan(-1);
expect(updatedGroupItem.childrenCount).toBe(mockRawChildren[0].subgroup_count);
});
});
@@ -104,6 +116,7 @@ describe('ProjectsStore', () => {
const childItem = store.state.groups[0].children[0];
store.removeGroup(childItem, store.state.groups[0]);
+
expect(store.state.groups[0].children.length).toBe(0);
});
});
diff --git a/spec/javascripts/header_spec.js b/spec/javascripts/header_spec.js
index 16ac438f7ac..2fe34e5a76f 100644
--- a/spec/javascripts/header_spec.js
+++ b/spec/javascripts/header_spec.js
@@ -1,7 +1,7 @@
import $ from 'jquery';
import initTodoToggle from '~/header';
-describe('Header', function () {
+describe('Header', function() {
const todosPendingCount = '.todos-count';
const fixtureTemplate = 'issues/open-issue.html.raw';
@@ -21,16 +21,19 @@ describe('Header', function () {
it('should update todos-count after receiving the todo:toggle event', () => {
triggerToggle('5');
+
expect($(todosPendingCount).text()).toEqual('5');
});
it('should hide todos-count when it is 0', () => {
triggerToggle('0');
+
expect(isTodosCountHidden()).toEqual(true);
});
it('should show todos-count when it is more than 0', () => {
triggerToggle('10');
+
expect(isTodosCountHidden()).toEqual(false);
});
diff --git a/spec/javascripts/helpers/class_spec_helper_spec.js b/spec/javascripts/helpers/class_spec_helper_spec.js
index fa104ae5bcd..f6268b0fb6d 100644
--- a/spec/javascripts/helpers/class_spec_helper_spec.js
+++ b/spec/javascripts/helpers/class_spec_helper_spec.js
@@ -2,11 +2,13 @@
import './class_spec_helper';
-describe('ClassSpecHelper', function () {
+describe('ClassSpecHelper', function() {
describe('itShouldBeAStaticMethod', () => {
beforeEach(() => {
class TestClass {
- instanceMethod() { this.prop = 'val'; }
+ instanceMethod() {
+ this.prop = 'val';
+ }
static staticMethod() {}
}
diff --git a/spec/javascripts/helpers/locale_helper.js b/spec/javascripts/helpers/locale_helper.js
index 99e6ce61234..80047b06003 100644
--- a/spec/javascripts/helpers/locale_helper.js
+++ b/spec/javascripts/helpers/locale_helper.js
@@ -1,6 +1,6 @@
/* eslint-disable import/prefer-default-export */
-export const setLanguage = (languageCode) => {
+export const setLanguage = languageCode => {
const htmlElement = document.querySelector('html');
if (languageCode) {
diff --git a/spec/javascripts/helpers/set_timeout_promise_helper.js b/spec/javascripts/helpers/set_timeout_promise_helper.js
index 1478073413c..47087619187 100644
--- a/spec/javascripts/helpers/set_timeout_promise_helper.js
+++ b/spec/javascripts/helpers/set_timeout_promise_helper.js
@@ -1,3 +1,4 @@
-export default (time = 0) => new Promise((resolve) => {
- setTimeout(resolve, time);
-});
+export default (time = 0) =>
+ new Promise(resolve => {
+ setTimeout(resolve, time);
+ });
diff --git a/spec/javascripts/helpers/user_mock_data_helper.js b/spec/javascripts/helpers/user_mock_data_helper.js
index f6c3ce5aecc..6999fa1f8a1 100644
--- a/spec/javascripts/helpers/user_mock_data_helper.js
+++ b/spec/javascripts/helpers/user_mock_data_helper.js
@@ -2,14 +2,12 @@ export default {
createNumberRandomUsers(numberUsers) {
const users = [];
for (let i = 0; i < numberUsers; i += 1) {
- users.push(
- {
- avatar: 'https://gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- id: (i + 1),
- name: `GitLab User ${i}`,
- username: `gitlab${i}`,
- },
- );
+ users.push({
+ avatar: 'https://gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ id: i + 1,
+ name: `GitLab User ${i}`,
+ username: `gitlab${i}`,
+ });
}
return users;
},
diff --git a/spec/javascripts/helpers/vue_resource_helper.js b/spec/javascripts/helpers/vue_resource_helper.js
index 0d1bf5e2e80..0f58af09933 100644
--- a/spec/javascripts/helpers/vue_resource_helper.js
+++ b/spec/javascripts/helpers/vue_resource_helper.js
@@ -1,6 +1,6 @@
// eslint-disable-next-line import/prefer-default-export
export const headersInterceptor = (request, next) => {
- next((response) => {
+ next(response => {
const headers = {};
response.headers.forEach((value, key) => {
headers[key] = value;
diff --git a/spec/javascripts/ide/components/branches/item_spec.js b/spec/javascripts/ide/components/branches/item_spec.js
index 8b756c8f168..36b6736bfd4 100644
--- a/spec/javascripts/ide/components/branches/item_spec.js
+++ b/spec/javascripts/ide/components/branches/item_spec.js
@@ -29,13 +29,16 @@ describe('IDE branch item', () => {
it('renders branch name and timeago', () => {
const timeText = getTimeago().format(TEST_BRANCH.committedDate);
+
expect(vm.$el).toContainText(TEST_BRANCH.name);
expect(vm.$el.querySelector('time')).toHaveText(timeText);
expect(vm.$el.querySelector('.ic-mobile-issue-close')).toBe(null);
});
it('renders link to branch', () => {
- const expectedHref = router.resolve(`/project/${TEST_PROJECT_ID}/edit/${TEST_BRANCH.name}`).href;
+ const expectedHref = router.resolve(`/project/${TEST_PROJECT_ID}/edit/${TEST_BRANCH.name}`)
+ .href;
+
expect(vm.$el).toMatch('a');
expect(vm.$el).toHaveAttr('href', expectedHref);
});
diff --git a/spec/javascripts/ide/components/branches/search_list_spec.js b/spec/javascripts/ide/components/branches/search_list_spec.js
index c3f84ba1c24..72a3c2d5dcd 100644
--- a/spec/javascripts/ide/components/branches/search_list_spec.js
+++ b/spec/javascripts/ide/components/branches/search_list_spec.js
@@ -62,8 +62,9 @@ describe('IDE branches search list', () => {
});
it('renders list', () => {
- const elementText = Array.from(vm.$el.querySelectorAll('li strong'))
- .map(x => x.textContent.trim());
+ const elementText = Array.from(vm.$el.querySelectorAll('li strong')).map(x =>
+ x.textContent.trim(),
+ );
expect(elementText).toEqual(testBranches.map(x => x.name));
});
diff --git a/spec/javascripts/ide/components/commit_sidebar/message_field_spec.js b/spec/javascripts/ide/components/commit_sidebar/message_field_spec.js
index 942cc19f46d..af67991eadd 100644
--- a/spec/javascripts/ide/components/commit_sidebar/message_field_spec.js
+++ b/spec/javascripts/ide/components/commit_sidebar/message_field_spec.js
@@ -36,8 +36,7 @@ describe('IDE commit message field', () => {
it('removed is-focused class on blur', done => {
vm.$el.querySelector('textarea').focus();
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
expect(vm.$el.querySelector('.is-focused')).not.toBeNull();
@@ -70,12 +69,12 @@ describe('IDE commit message field', () => {
it('does not highlight less than 50 characters', done => {
vm.text = 'text less than 50 chars';
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
expect(vm.$el.querySelector('.highlights span').textContent).toContain(
'text less than 50 chars',
);
+
expect(vm.$el.querySelector('mark').style.display).toBe('none');
})
.then(done)
@@ -86,12 +85,12 @@ describe('IDE commit message field', () => {
vm.text =
'text less than 50 chars that should not highlighted. text more than 50 should be highlighted';
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
expect(vm.$el.querySelector('.highlights span').textContent).toContain(
'text less than 50 chars that should not highlighte',
);
+
expect(vm.$el.querySelector('mark').style.display).not.toBe('none');
expect(vm.$el.querySelector('mark').textContent).toBe(
'd. text more than 50 should be highlighted',
@@ -106,8 +105,7 @@ describe('IDE commit message field', () => {
it('does not highlight body text less tan 72 characters', done => {
vm.text = 'subject line\nbody content';
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2);
expect(vm.$el.querySelectorAll('mark')[1].style.display).toBe('none');
@@ -120,8 +118,7 @@ describe('IDE commit message field', () => {
vm.text =
'subject line\nbody content that will be highlighted when it is more than 72 characters in length';
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2);
expect(vm.$el.querySelectorAll('mark')[1].style.display).not.toBe('none');
@@ -135,8 +132,7 @@ describe('IDE commit message field', () => {
vm.text =
'text less than 50 chars that should not highlighted\nbody content that will be highlighted when it is more than 72 characters in length';
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2);
expect(vm.$el.querySelectorAll('mark').length).toBe(2);
@@ -154,8 +150,7 @@ describe('IDE commit message field', () => {
it('updates transform of highlights', done => {
vm.text = 'subject line\n\n\n\n\n\n\n\n\n\n\nbody content';
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
vm.$el.querySelector('textarea').scrollTo(0, 50);
diff --git a/spec/javascripts/ide/components/file_finder/index_spec.js b/spec/javascripts/ide/components/file_finder/index_spec.js
index 4f208e946d2..4d934f92f72 100644
--- a/spec/javascripts/ide/components/file_finder/index_spec.js
+++ b/spec/javascripts/ide/components/file_finder/index_spec.js
@@ -85,8 +85,7 @@ describe('IDE File finder item spec', () => {
it('clear button resets searchText', done => {
vm.searchText = 'index';
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
vm.$el.querySelector('.dropdown-input-clear').click();
})
@@ -102,8 +101,7 @@ describe('IDE File finder item spec', () => {
spyOn(vm.$refs.searchInput, 'focus');
vm.searchText = 'index';
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
vm.$el.querySelector('.dropdown-input-clear').click();
})
@@ -178,8 +176,7 @@ describe('IDE File finder item spec', () => {
vm.searchText = 'test';
vm.$store.state.fileFindVisible = true;
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
vm.$store.state.fileFindVisible = false;
})
diff --git a/spec/javascripts/ide/components/ide_spec.js b/spec/javascripts/ide/components/ide_spec.js
index 49b8e934cdd..c02a1ad246c 100644
--- a/spec/javascripts/ide/components/ide_spec.js
+++ b/spec/javascripts/ide/components/ide_spec.js
@@ -84,8 +84,7 @@ describe('ide component', () => {
it('calls toggleFileFinder on `t` key press', done => {
Mousetrap.trigger('t');
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
expect(vm.toggleFileFinder).toHaveBeenCalled();
})
@@ -96,8 +95,7 @@ describe('ide component', () => {
it('calls toggleFileFinder on `command+p` key press', done => {
Mousetrap.trigger('command+p');
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
expect(vm.toggleFileFinder).toHaveBeenCalled();
})
@@ -108,8 +106,7 @@ describe('ide component', () => {
it('calls toggleFileFinder on `ctrl+p` key press', done => {
Mousetrap.trigger('ctrl+p');
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
expect(vm.toggleFileFinder).toHaveBeenCalled();
})
diff --git a/spec/javascripts/ide/components/ide_status_bar_spec.js b/spec/javascripts/ide/components/ide_status_bar_spec.js
index 47d6492a7a6..ab032b4cb98 100644
--- a/spec/javascripts/ide/components/ide_status_bar_spec.js
+++ b/spec/javascripts/ide/components/ide_status_bar_spec.js
@@ -50,9 +50,11 @@ describe('ideStatusBar', () => {
expect(vm.commitAgeUpdate).not.toHaveBeenCalled();
jasmine.clock().tick(1100);
+
expect(vm.commitAgeUpdate.calls.count()).toEqual(1);
jasmine.clock().tick(1000);
+
expect(vm.commitAgeUpdate.calls.count()).toEqual(2);
});
});
@@ -76,8 +78,7 @@ describe('ideStatusBar', () => {
},
});
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
vm.$el.querySelector('.ide-status-pipeline button').click();
diff --git a/spec/javascripts/ide/components/jobs/detail_spec.js b/spec/javascripts/ide/components/jobs/detail_spec.js
index 8f8d4b9709e..a4e6b81acba 100644
--- a/spec/javascripts/ide/components/jobs/detail_spec.js
+++ b/spec/javascripts/ide/components/jobs/detail_spec.js
@@ -109,8 +109,7 @@ describe('IDE jobs detail view', () => {
vm.scrollPos = 1;
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => vm.$el.querySelector('.btn-scroll').click())
.then(() => vm.$nextTick())
.then(() => {
diff --git a/spec/javascripts/ide/components/merge_requests/item_spec.js b/spec/javascripts/ide/components/merge_requests/item_spec.js
index 750948cae3c..155a247defb 100644
--- a/spec/javascripts/ide/components/merge_requests/item_spec.js
+++ b/spec/javascripts/ide/components/merge_requests/item_spec.js
@@ -29,7 +29,10 @@ describe('IDE merge request item', () => {
});
it('renders link with href', () => {
- const expectedHref = router.resolve(`/project/${vm.item.projectPathWithNamespace}/merge_requests/${vm.item.iid}`).href;
+ const expectedHref = router.resolve(
+ `/project/${vm.item.projectPathWithNamespace}/merge_requests/${vm.item.iid}`,
+ ).href;
+
expect(vm.$el).toMatch('a');
expect(vm.$el).toHaveAttr('href', expectedHref);
});
diff --git a/spec/javascripts/ide/components/merge_requests/list_spec.js b/spec/javascripts/ide/components/merge_requests/list_spec.js
index c761315444c..55e4f46d9ca 100644
--- a/spec/javascripts/ide/components/merge_requests/list_spec.js
+++ b/spec/javascripts/ide/components/merge_requests/list_spec.js
@@ -118,8 +118,9 @@ describe('IDE merge requests list', () => {
vm.$nextTick()
.then(() => {
const expectedSearchTypes = vm.$options.searchTypes.map(x => x.label);
- const renderedSearchTypes = Array.from(vm.$el.querySelectorAll('li'))
- .map(x => x.textContent.trim());
+ const renderedSearchTypes = Array.from(vm.$el.querySelectorAll('li')).map(x =>
+ x.textContent.trim(),
+ );
expect(renderedSearchTypes).toEqual(expectedSearchTypes);
})
diff --git a/spec/javascripts/ide/components/new_dropdown/index_spec.js b/spec/javascripts/ide/components/new_dropdown/index_spec.js
index 8a8cbd2cee4..83e530f0a6a 100644
--- a/spec/javascripts/ide/components/new_dropdown/index_spec.js
+++ b/spec/javascripts/ide/components/new_dropdown/index_spec.js
@@ -36,6 +36,7 @@ describe('new dropdown component', () => {
it('renders new file, upload and new directory links', () => {
const buttons = vm.$el.querySelectorAll('.dropdown-menu button');
+
expect(buttons[0].textContent.trim()).toBe('New file');
expect(buttons[1].textContent.trim()).toBe('Upload file');
expect(buttons[2].textContent.trim()).toBe('New directory');
diff --git a/spec/javascripts/ide/components/new_dropdown/upload_spec.js b/spec/javascripts/ide/components/new_dropdown/upload_spec.js
index 70b885ede26..878e17ac805 100644
--- a/spec/javascripts/ide/components/new_dropdown/upload_spec.js
+++ b/spec/javascripts/ide/components/new_dropdown/upload_spec.js
@@ -40,21 +40,10 @@ describe('new dropdown upload', () => {
describe('readFile', () => {
beforeEach(() => {
- spyOn(FileReader.prototype, 'readAsText');
spyOn(FileReader.prototype, 'readAsDataURL');
});
- it('calls readAsText for text files', () => {
- const file = {
- type: 'text/html',
- };
-
- vm.readFile(file);
-
- expect(FileReader.prototype.readAsText).toHaveBeenCalledWith(file);
- });
-
- it('calls readAsDataURL for non-text files', () => {
+ it('calls readAsDataURL for all files', () => {
const file = {
type: 'images/png',
};
@@ -66,32 +55,37 @@ describe('new dropdown upload', () => {
});
describe('createFile', () => {
- const target = {
- result: 'content',
+ const textTarget = {
+ result: 'base64,cGxhaW4gdGV4dA==',
};
const binaryTarget = {
- result: 'base64,base64content',
+ result: 'base64,w4I=',
+ };
+ const textFile = {
+ name: 'textFile',
+ type: 'text/plain',
};
- const file = {
- name: 'file',
+ const binaryFile = {
+ name: 'binaryFile',
+ type: 'image/png',
};
- it('creates new file', () => {
- vm.createFile(target, file, true);
+ it('creates file in plain text (without encoding) if the file content is plain text', () => {
+ vm.createFile(textTarget, textFile);
expect(vm.$emit).toHaveBeenCalledWith('create', {
- name: file.name,
+ name: textFile.name,
type: 'blob',
- content: target.result,
+ content: 'plain text',
base64: false,
});
});
it('splits content on base64 if binary', () => {
- vm.createFile(binaryTarget, file, false);
+ vm.createFile(binaryTarget, binaryFile);
expect(vm.$emit).toHaveBeenCalledWith('create', {
- name: file.name,
+ name: binaryFile.name,
type: 'blob',
content: binaryTarget.result.split('base64,')[1],
base64: true,
diff --git a/spec/javascripts/ide/components/preview/clientside_spec.js b/spec/javascripts/ide/components/preview/clientside_spec.js
index d6983f5a3b8..b9bf5c51ffe 100644
--- a/spec/javascripts/ide/components/preview/clientside_spec.js
+++ b/spec/javascripts/ide/components/preview/clientside_spec.js
@@ -59,8 +59,7 @@ describe('IDE clientside preview', () => {
}),
);
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => vm.initPreview())
.then(vm.$nextTick)
.then(done)
diff --git a/spec/javascripts/ide/components/repo_editor_spec.js b/spec/javascripts/ide/components/repo_editor_spec.js
index 991fb750876..002b5a005b8 100644
--- a/spec/javascripts/ide/components/repo_editor_spec.js
+++ b/spec/javascripts/ide/components/repo_editor_spec.js
@@ -52,6 +52,7 @@ describe('RepoEditor', () => {
it('renders only an edit tab', done => {
Vue.nextTick(() => {
const tabs = vm.$el.querySelectorAll('.ide-mode-tabs .nav-links li');
+
expect(tabs.length).toBe(1);
expect(tabs[0].textContent.trim()).toBe('Edit');
@@ -72,6 +73,7 @@ describe('RepoEditor', () => {
it('renders an Edit and a Preview Tab', done => {
Vue.nextTick(() => {
const tabs = vm.$el.querySelectorAll('.ide-mode-tabs .nav-links li');
+
expect(tabs.length).toBe(2);
expect(tabs[0].textContent.trim()).toBe('Edit');
expect(tabs[1].textContent.trim()).toBe('Preview Markdown');
@@ -109,6 +111,7 @@ describe('RepoEditor', () => {
it('renders an Edit and a Preview Tab', done => {
Vue.nextTick(() => {
const tabs = vm.$el.querySelectorAll('.ide-mode-tabs .nav-links li');
+
expect(tabs.length).toBe(2);
expect(tabs[0].textContent.trim()).toBe('Review');
expect(tabs[1].textContent.trim()).toBe('Preview Markdown');
@@ -122,8 +125,7 @@ describe('RepoEditor', () => {
vm.file.path = `${vm.file.path}.md`;
vm.$store.state.entries[vm.file.path] = vm.file;
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
vm.$el.querySelectorAll('.ide-mode-tabs .nav-links a')[1].click();
})
@@ -294,8 +296,7 @@ describe('RepoEditor', () => {
it('calls updateDimensions when panelResizing is false', done => {
vm.$store.state.panelResizing = true;
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
vm.$store.state.panelResizing = false;
})
@@ -363,8 +364,7 @@ describe('RepoEditor', () => {
vm.file.pending = true;
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
vm.file = file('testing');
diff --git a/spec/javascripts/ide/components/shared/tokened_input_spec.js b/spec/javascripts/ide/components/shared/tokened_input_spec.js
index 09940fe8c6a..b09bf760543 100644
--- a/spec/javascripts/ide/components/shared/tokened_input_spec.js
+++ b/spec/javascripts/ide/components/shared/tokened_input_spec.js
@@ -44,8 +44,7 @@ describe('IDE shared/TokenedInput', () => {
});
it('renders tokens', () => {
- const renderedTokens = getTokenElements(vm)
- .map(x => x.textContent.trim());
+ const renderedTokens = getTokenElements(vm).map(x => x.textContent.trim());
expect(renderedTokens).toEqual(TEST_TOKENS.map(x => x.label));
});
@@ -85,10 +84,12 @@ describe('IDE shared/TokenedInput', () => {
vm.value = '';
vm.onBackspace();
+
expect(vm.$emit).not.toHaveBeenCalled();
expect(vm.backspaceCount).toEqual(1);
vm.onBackspace();
+
expect(vm.$emit).toHaveBeenCalledWith('removeToken', TEST_TOKENS[TEST_TOKENS.length - 1]);
expect(vm.backspaceCount).toEqual(0);
});
diff --git a/spec/javascripts/ide/stores/actions/merge_request_spec.js b/spec/javascripts/ide/stores/actions/merge_request_spec.js
index 8564f04ce8a..3a4e0d7507f 100644
--- a/spec/javascripts/ide/stores/actions/merge_request_spec.js
+++ b/spec/javascripts/ide/stores/actions/merge_request_spec.js
@@ -262,7 +262,7 @@ describe('IDE store merge request actions', () => {
bar: {},
};
- spyOn(store, 'dispatch').and.callFake((type) => {
+ spyOn(store, 'dispatch').and.callFake(type => {
switch (type) {
case 'getMergeRequestData':
return Promise.resolve(testMergeRequest);
@@ -280,14 +280,20 @@ describe('IDE store merge request actions', () => {
expect(store.dispatch.calls.allArgs()).toEqual([
['getMergeRequestData', mr],
['setCurrentBranchId', testMergeRequest.source_branch],
- ['getBranchData', {
- projectId: mr.projectId,
- branchId: testMergeRequest.source_branch,
- }],
- ['getFiles', {
- projectId: mr.projectId,
- branchId: testMergeRequest.source_branch,
- }],
+ [
+ 'getBranchData',
+ {
+ projectId: mr.projectId,
+ branchId: testMergeRequest.source_branch,
+ },
+ ],
+ [
+ 'getFiles',
+ {
+ projectId: mr.projectId,
+ branchId: testMergeRequest.source_branch,
+ },
+ ],
['getMergeRequestVersions', mr],
['getMergeRequestChanges', mr],
]);
@@ -297,20 +303,21 @@ describe('IDE store merge request actions', () => {
});
it('updates activity bar view and gets file data, if changes are found', done => {
- testMergeRequestChanges.changes = [
- { new_path: 'foo' },
- { new_path: 'bar' },
- ];
+ testMergeRequestChanges.changes = [{ new_path: 'foo' }, { new_path: 'bar' }];
openMergeRequest(store, mr)
.then(() => {
- expect(store.dispatch).toHaveBeenCalledWith('updateActivityBarView', activityBarViews.review);
+ expect(store.dispatch).toHaveBeenCalledWith(
+ 'updateActivityBarView',
+ activityBarViews.review,
+ );
testMergeRequestChanges.changes.forEach((change, i) => {
expect(store.dispatch).toHaveBeenCalledWith('setFileMrChange', {
file: store.state.entries[change.new_path],
mrChange: change,
});
+
expect(store.dispatch).toHaveBeenCalledWith('getFileData', {
path: change.new_path,
makeFileActive: i === 0,
@@ -334,7 +341,6 @@ describe('IDE store merge request actions', () => {
})
.then(done)
.catch(done.fail);
-
});
});
});
diff --git a/spec/javascripts/ide/stores/actions/project_spec.js b/spec/javascripts/ide/stores/actions/project_spec.js
index 667e3e0a7ef..7d8c9edd965 100644
--- a/spec/javascripts/ide/stores/actions/project_spec.js
+++ b/spec/javascripts/ide/stores/actions/project_spec.js
@@ -270,7 +270,10 @@ describe('IDE store project actions', () => {
it('does not handle tree entry action, if entry is pending', done => {
openBranch(store, { ...branch, basePath: 'foo/bar-pending' })
.then(() => {
- expect(store.dispatch).not.toHaveBeenCalledWith('handleTreeEntryAction', jasmine.anything());
+ expect(store.dispatch).not.toHaveBeenCalledWith(
+ 'handleTreeEntryAction',
+ jasmine.anything(),
+ );
})
.then(done)
.catch(done.fail);
diff --git a/spec/javascripts/ide/stores/actions/tree_spec.js b/spec/javascripts/ide/stores/actions/tree_spec.js
index 9f098eded08..d47c60dc581 100644
--- a/spec/javascripts/ide/stores/actions/tree_spec.js
+++ b/spec/javascripts/ide/stores/actions/tree_spec.js
@@ -71,6 +71,7 @@ describe('Multi-file store tree actions', () => {
.dispatch('getFiles', basicCallParameters)
.then(() => {
projectTree = store.state.trees['abcproject/master'];
+
expect(projectTree.tree.length).toBe(2);
expect(projectTree.tree[0].type).toBe('tree');
expect(projectTree.tree[0].tree[1].name).toBe('fileinfolder.js');
diff --git a/spec/javascripts/ide/stores/actions_spec.js b/spec/javascripts/ide/stores/actions_spec.js
index c9a1158a14e..df291ade3f7 100644
--- a/spec/javascripts/ide/stores/actions_spec.js
+++ b/spec/javascripts/ide/stores/actions_spec.js
@@ -279,8 +279,6 @@ describe('Multi-file store actions', () => {
});
});
- describe('popHistoryState', () => {});
-
describe('scrollToTab', () => {
it('focuses the current active element', done => {
document.body.innerHTML +=
diff --git a/spec/javascripts/ide/stores/modules/branches/actions_spec.js b/spec/javascripts/ide/stores/modules/branches/actions_spec.js
index 010f56af03b..2b3eac282f6 100644
--- a/spec/javascripts/ide/stores/modules/branches/actions_spec.js
+++ b/spec/javascripts/ide/stores/modules/branches/actions_spec.js
@@ -60,7 +60,6 @@ describe('IDE branches actions', () => {
describe('receiveBranchesError', () => {
it('should should commit error', done => {
-
testAction(
receiveBranchesError,
{ search: TEST_SEARCH },
diff --git a/spec/javascripts/ide/stores/modules/file_templates/mutations_spec.js b/spec/javascripts/ide/stores/modules/file_templates/mutations_spec.js
index a51527d699f..8e0e3ae99a1 100644
--- a/spec/javascripts/ide/stores/modules/file_templates/mutations_spec.js
+++ b/spec/javascripts/ide/stores/modules/file_templates/mutations_spec.js
@@ -49,6 +49,14 @@ describe('IDE file templates mutations', () => {
expect(state.selectedTemplateType).toBe('type');
});
+
+ it('clears templates', () => {
+ state.templates = ['test'];
+
+ mutations[types.SET_SELECTED_TEMPLATE_TYPE](state, 'type');
+
+ expect(state.templates).toEqual([]);
+ });
});
describe(types.SET_UPDATE_SUCCESS, () => {
diff --git a/spec/javascripts/ide/stores/modules/pane/actions_spec.js b/spec/javascripts/ide/stores/modules/pane/actions_spec.js
index f150ded6df5..799bc89a0c3 100644
--- a/spec/javascripts/ide/stores/modules/pane/actions_spec.js
+++ b/spec/javascripts/ide/stores/modules/pane/actions_spec.js
@@ -19,27 +19,13 @@ describe('IDE pane module actions', () => {
});
it('dispatches close if opened', done => {
- testAction(
- actions.toggleOpen,
- TEST_VIEW,
- { isOpen: true },
- [],
- [{ type: 'close' }],
- done,
- );
+ testAction(actions.toggleOpen, TEST_VIEW, { isOpen: true }, [], [{ type: 'close' }], done);
});
});
describe('open', () => {
it('commits SET_OPEN', done => {
- testAction(
- actions.open,
- null,
- {},
- [{ type: types.SET_OPEN, payload: true }],
- [],
- done,
- );
+ testAction(actions.open, null, {}, [{ type: types.SET_OPEN, payload: true }], [], done);
});
it('commits SET_CURRENT_VIEW if view is given', done => {
@@ -74,14 +60,7 @@ describe('IDE pane module actions', () => {
describe('close', () => {
it('commits SET_OPEN', done => {
- testAction(
- actions.close,
- null,
- {},
- [{ type: types.SET_OPEN, payload: false }],
- [],
- done,
- );
+ testAction(actions.close, null, {}, [{ type: types.SET_OPEN, payload: false }], [], done);
});
});
});
diff --git a/spec/javascripts/ide/stores/modules/pane/getters_spec.js b/spec/javascripts/ide/stores/modules/pane/getters_spec.js
index 2060863b5d6..8a213323de0 100644
--- a/spec/javascripts/ide/stores/modules/pane/getters_spec.js
+++ b/spec/javascripts/ide/stores/modules/pane/getters_spec.js
@@ -23,10 +23,7 @@ describe('IDE pane module getters', () => {
describe('isAliveView', () => {
it('returns true if given view is in keepAliveViews', () => {
- const result = getters.isAliveView(
- { keepAliveViews: TEST_KEEP_ALIVE_VIEWS },
- {},
- )(TEST_VIEW);
+ const result = getters.isAliveView({ keepAliveViews: TEST_KEEP_ALIVE_VIEWS }, {})(TEST_VIEW);
expect(result).toBe(true);
});
@@ -41,10 +38,7 @@ describe('IDE pane module getters', () => {
});
it('returns false if given view is active view and closed', () => {
- const result = getters.isAliveView(
- state(),
- { isActiveView: () => true },
- )(TEST_VIEW);
+ const result = getters.isAliveView(state(), { isActiveView: () => true })(TEST_VIEW);
expect(result).toBe(false);
});
diff --git a/spec/javascripts/ide/stores/mutations/merge_request_spec.js b/spec/javascripts/ide/stores/mutations/merge_request_spec.js
index f724bf464f5..e30ca22022f 100644
--- a/spec/javascripts/ide/stores/mutations/merge_request_spec.js
+++ b/spec/javascripts/ide/stores/mutations/merge_request_spec.js
@@ -45,6 +45,7 @@ describe('IDE store merge request mutations', () => {
});
const newMr = localState.projects.abcproject.mergeRequests[1];
+
expect(newMr.changes.diff).toBe('abc');
});
});
@@ -58,6 +59,7 @@ describe('IDE store merge request mutations', () => {
});
const newMr = localState.projects.abcproject.mergeRequests[1];
+
expect(newMr.versions.length).toBe(1);
expect(newMr.versions[0].id).toBe(123);
});
diff --git a/spec/javascripts/image_diff/helpers/badge_helper_spec.js b/spec/javascripts/image_diff/helpers/badge_helper_spec.js
index ce3add1fd90..8ea05203d00 100644
--- a/spec/javascripts/image_diff/helpers/badge_helper_spec.js
+++ b/spec/javascripts/image_diff/helpers/badge_helper_spec.js
@@ -90,6 +90,7 @@ describe('badge helper', () => {
it('should create icon comment button', () => {
const iconEl = buttonEl.querySelector('svg');
+
expect(iconEl).toBeDefined();
});
});
diff --git a/spec/javascripts/image_diff/helpers/comment_indicator_helper_spec.js b/spec/javascripts/image_diff/helpers/comment_indicator_helper_spec.js
index a284b981d2a..8e3e7f1222e 100644
--- a/spec/javascripts/image_diff/helpers/comment_indicator_helper_spec.js
+++ b/spec/javascripts/image_diff/helpers/comment_indicator_helper_spec.js
@@ -29,10 +29,12 @@ describe('commentIndicatorHelper', () => {
it('should contain image-comment-dark svg', () => {
const svgEl = buttonEl.querySelector('svg');
+
expect(svgEl).toBeDefined();
const svgLink = svgEl.querySelector('use').getAttribute('xlink:href');
- expect(svgLink.indexOf('image-comment-dark') !== -1).toEqual(true);
+
+ expect(svgLink.indexOf('image-comment-dark')).not.toBe(-1);
});
});
});
@@ -40,6 +42,7 @@ describe('commentIndicatorHelper', () => {
describe('removeCommentIndicator', () => {
it('should return removed false if there is no comment-indicator', () => {
const result = commentIndicatorHelper.removeCommentIndicator(containerEl);
+
expect(result.removed).toEqual(false);
});
@@ -84,6 +87,7 @@ describe('commentIndicatorHelper', () => {
it('should set commentIndicator coordinates', () => {
const commentIndicatorEl = containerEl.querySelector('.comment-indicator');
+
expect(commentIndicatorEl.style.left).toEqual(`${coordinate.x}px`);
expect(commentIndicatorEl.style.top).toEqual(`${coordinate.y}px`);
});
@@ -96,6 +100,7 @@ describe('commentIndicatorHelper', () => {
it('should addCommentIndicator', () => {
const buttonEl = containerEl.querySelector('.comment-indicator');
+
expect(buttonEl).toBeDefined();
expect(buttonEl.style.left).toEqual(`${coordinate.x}px`);
expect(buttonEl.style.top).toEqual(`${coordinate.y}px`);
diff --git a/spec/javascripts/image_diff/helpers/dom_helper_spec.js b/spec/javascripts/image_diff/helpers/dom_helper_spec.js
index 8dde924e8ae..ffe712af2dd 100644
--- a/spec/javascripts/image_diff/helpers/dom_helper_spec.js
+++ b/spec/javascripts/image_diff/helpers/dom_helper_spec.js
@@ -92,6 +92,7 @@ describe('domHelper', () => {
it('should force formEl to display none', () => {
const formEl = element.querySelector('.discussion-form');
+
expect(formEl.style.display).toEqual('none');
});
});
@@ -111,6 +112,7 @@ describe('domHelper', () => {
it('should force formEl to display block', () => {
const formEl = element.querySelector('.discussion-form');
+
expect(formEl.style.display).toEqual('block');
});
});
diff --git a/spec/javascripts/image_diff/helpers/utils_helper_spec.js b/spec/javascripts/image_diff/helpers/utils_helper_spec.js
index 31949c39d9c..6f62ee3f93b 100644
--- a/spec/javascripts/image_diff/helpers/utils_helper_spec.js
+++ b/spec/javascripts/image_diff/helpers/utils_helper_spec.js
@@ -5,13 +5,7 @@ import ImageBadge from '~/image_diff/image_badge';
import * as mockData from '../mock_data';
describe('utilsHelper', () => {
- const {
- noteId,
- discussionId,
- image,
- imageProperties,
- imageMeta,
- } = mockData;
+ const { noteId, discussionId, image, imageProperties, imageMeta } = mockData;
describe('resizeCoordinatesToImageElement', () => {
let result;
@@ -57,6 +51,7 @@ describe('utilsHelper', () => {
it('should return actual image properties', () => {
const { actual } = result;
+
expect(actual.x).toEqual(imageMeta.x);
expect(actual.y).toEqual(imageMeta.y);
expect(actual.width).toEqual(imageMeta.width);
@@ -65,6 +60,7 @@ describe('utilsHelper', () => {
it('should return browser image properties', () => {
const { browser } = result;
+
expect(browser.x).toBeDefined();
expect(browser.y).toBeDefined();
expect(browser.width).toBeDefined();
@@ -106,6 +102,7 @@ describe('utilsHelper', () => {
const result = utilsHelper.getTargetSelection(event);
const { browser } = result;
+
expect(browser.x).toEqual(event.offsetX);
expect(browser.y).toEqual(event.offsetY);
expect(browser.width).toEqual(imageProperties.width);
@@ -117,6 +114,7 @@ describe('utilsHelper', () => {
const result = utilsHelper.getTargetSelection(event);
const { actual } = result;
+
expect(actual.x).toEqual(100);
expect(actual.y).toEqual(100);
expect(actual.width).toEqual(imageProperties.naturalWidth);
@@ -127,24 +125,28 @@ describe('utilsHelper', () => {
it('should return x = 0 if x < 0', () => {
const event = generateEvent(-5, 50);
const result = utilsHelper.getTargetSelection(event);
+
expect(result.browser.x).toEqual(0);
});
it('should return x = width if x > width', () => {
const event = generateEvent(1000, 50);
const result = utilsHelper.getTargetSelection(event);
+
expect(result.browser.x).toEqual(imageProperties.width);
});
it('should return y = 0 if y < 0', () => {
const event = generateEvent(50, -10);
const result = utilsHelper.getTargetSelection(event);
+
expect(result.browser.y).toEqual(0);
});
it('should return y = height if y > height', () => {
const event = generateEvent(50, 1000);
const result = utilsHelper.getTargetSelection(event);
+
expect(result.browser.y).toEqual(imageProperties.height);
});
});
@@ -178,6 +180,7 @@ describe('utilsHelper', () => {
`;
const imageDiff = utilsHelper.initImageDiff(fileEl, true, false);
+
expect(ImageDiff.prototype.init).toHaveBeenCalled();
expect(imageDiff.canCreateNote).toEqual(true);
expect(imageDiff.renderCommentBadge).toEqual(false);
@@ -191,6 +194,7 @@ describe('utilsHelper', () => {
`;
const replacedImageDiff = utilsHelper.initImageDiff(fileEl, false, true);
+
expect(ReplacedImageDiff.prototype.init).toHaveBeenCalled();
expect(replacedImageDiff.canCreateNote).toEqual(false);
expect(replacedImageDiff.renderCommentBadge).toEqual(true);
diff --git a/spec/javascripts/image_diff/image_badge_spec.js b/spec/javascripts/image_diff/image_badge_spec.js
index 87f98fc0926..2b23dce5d30 100644
--- a/spec/javascripts/image_diff/image_badge_spec.js
+++ b/spec/javascripts/image_diff/image_badge_spec.js
@@ -10,11 +10,14 @@ describe('ImageBadge', () => {
};
it('should save actual property', () => {
- const imageBadge = new ImageBadge(Object.assign({}, options, {
- actual: imageMeta,
- }));
+ const imageBadge = new ImageBadge(
+ Object.assign({}, options, {
+ actual: imageMeta,
+ }),
+ );
const { actual } = imageBadge;
+
expect(actual.x).toEqual(imageMeta.x);
expect(actual.y).toEqual(imageMeta.y);
expect(actual.width).toEqual(imageMeta.width);
@@ -22,11 +25,14 @@ describe('ImageBadge', () => {
});
it('should save browser property', () => {
- const imageBadge = new ImageBadge(Object.assign({}, options, {
- browser: imageMeta,
- }));
+ const imageBadge = new ImageBadge(
+ Object.assign({}, options, {
+ browser: imageMeta,
+ }),
+ );
const { browser } = imageBadge;
+
expect(browser.x).toEqual(imageMeta.x);
expect(browser.y).toEqual(imageMeta.y);
expect(browser.width).toEqual(imageMeta.width);
@@ -35,11 +41,13 @@ describe('ImageBadge', () => {
it('should save noteId', () => {
const imageBadge = new ImageBadge(options);
+
expect(imageBadge.noteId).toEqual(noteId);
});
it('should save discussionId', () => {
const imageBadge = new ImageBadge(options);
+
expect(imageBadge.discussionId).toEqual(discussionId);
});
@@ -52,6 +60,7 @@ describe('ImageBadge', () => {
it('should return defaultimageMeta if actual property is not provided', () => {
const { actual } = imageBadge;
+
expect(actual.x).toEqual(0);
expect(actual.y).toEqual(0);
expect(actual.width).toEqual(0);
@@ -60,6 +69,7 @@ describe('ImageBadge', () => {
it('should return defaultimageMeta if browser property is not provided', () => {
const { browser } = imageBadge;
+
expect(browser.x).toEqual(0);
expect(browser.y).toEqual(0);
expect(browser.width).toEqual(0);
@@ -73,9 +83,11 @@ describe('ImageBadge', () => {
});
it('should generate browser property', () => {
- const imageBadge = new ImageBadge(Object.assign({}, options, {
- imageEl: document.createElement('img'),
- }));
+ const imageBadge = new ImageBadge(
+ Object.assign({}, options, {
+ imageEl: document.createElement('img'),
+ }),
+ );
expect(imageDiffHelper.resizeCoordinatesToImageElement).toHaveBeenCalled();
expect(imageBadge.browser).toEqual(true);
diff --git a/spec/javascripts/image_diff/image_diff_spec.js b/spec/javascripts/image_diff/image_diff_spec.js
index 346282328c7..21e7b8e2e9b 100644
--- a/spec/javascripts/image_diff/image_diff_spec.js
+++ b/spec/javascripts/image_diff/image_diff_spec.js
@@ -117,23 +117,15 @@ describe('ImageDiff', () => {
it('should register click event delegation to js-diff-notes-toggle', () => {
element.querySelector('.js-diff-notes-toggle').click();
+
expect(imageDiffHelper.toggleCollapsed).toHaveBeenCalled();
});
it('should register click event delegation to comment-indicator', () => {
element.querySelector('.comment-indicator').click();
- expect(imageDiffHelper.commentIndicatorOnClick).toHaveBeenCalled();
- });
- });
- describe('image loaded', () => {
- beforeEach(() => {
- spyOn(imageUtility, 'isImageLoaded').and.returnValue(true);
- imageDiff = new ImageDiff(element);
- imageDiff.imageEl = imageEl;
+ expect(imageDiffHelper.commentIndicatorOnClick).toHaveBeenCalled();
});
-
- it('should renderBadges', () => {});
});
describe('image not loaded', () => {
@@ -147,6 +139,7 @@ describe('ImageDiff', () => {
it('should registers load eventListener', () => {
const loadEvent = new Event('load');
imageEl.dispatchEvent(loadEvent);
+
expect(imageDiff.renderBadges).toHaveBeenCalled();
});
});
@@ -164,24 +157,28 @@ describe('ImageDiff', () => {
it('should register click.imageDiff event', () => {
const event = new CustomEvent('click.imageDiff');
element.dispatchEvent(event);
+
expect(imageDiff.imageClicked).toHaveBeenCalled();
});
it('should register blur.imageDiff event', () => {
const event = new CustomEvent('blur.imageDiff');
element.dispatchEvent(event);
+
expect(imageDiffHelper.removeCommentIndicator).toHaveBeenCalled();
});
it('should register addBadge.imageDiff event', () => {
const event = new CustomEvent('addBadge.imageDiff');
element.dispatchEvent(event);
+
expect(imageDiff.addBadge).toHaveBeenCalled();
});
it('should register removeBadge.imageDiff event', () => {
const event = new CustomEvent('removeBadge.imageDiff');
element.dispatchEvent(event);
+
expect(imageDiff.removeBadge).toHaveBeenCalled();
});
});
@@ -197,6 +194,7 @@ describe('ImageDiff', () => {
it('should not register click.imageDiff event', () => {
const event = new CustomEvent('click.imageDiff');
element.dispatchEvent(event);
+
expect(imageDiff.imageClicked).not.toHaveBeenCalled();
});
});
@@ -240,6 +238,7 @@ describe('ImageDiff', () => {
it('should call renderBadge for each discussionEl', () => {
const discussionEls = element.querySelectorAll('.note-container .discussion-notes .notes');
+
expect(imageDiff.renderBadge.calls.count()).toEqual(discussionEls.length);
});
});
@@ -336,6 +335,7 @@ describe('ImageDiff', () => {
describe('cascade badge count', () => {
it('should update next imageBadgeEl value', () => {
const imageBadgeEls = imageDiff.imageFrameEl.querySelectorAll('.badge');
+
expect(imageBadgeEls[0].innerText).toEqual('1');
expect(imageBadgeEls[1].innerText).toEqual('2');
expect(imageBadgeEls.length).toEqual(2);
diff --git a/spec/javascripts/image_diff/init_discussion_tab_spec.js b/spec/javascripts/image_diff/init_discussion_tab_spec.js
index 7c447d6f70d..7cacc45ab62 100644
--- a/spec/javascripts/image_diff/init_discussion_tab_spec.js
+++ b/spec/javascripts/image_diff/init_discussion_tab_spec.js
@@ -11,7 +11,7 @@ describe('initDiscussionTab', () => {
`);
});
- it('should pass canCreateNote as false to initImageDiff', (done) => {
+ it('should pass canCreateNote as false to initImageDiff', done => {
spyOn(imageDiffHelper, 'initImageDiff').and.callFake((diffFileEl, canCreateNote) => {
expect(canCreateNote).toEqual(false);
done();
@@ -20,11 +20,13 @@ describe('initDiscussionTab', () => {
initDiscussionTab();
});
- it('should pass renderCommentBadge as true to initImageDiff', (done) => {
- spyOn(imageDiffHelper, 'initImageDiff').and.callFake((diffFileEl, canCreateNote, renderCommentBadge) => {
- expect(renderCommentBadge).toEqual(true);
- done();
- });
+ it('should pass renderCommentBadge as true to initImageDiff', done => {
+ spyOn(imageDiffHelper, 'initImageDiff').and.callFake(
+ (diffFileEl, canCreateNote, renderCommentBadge) => {
+ expect(renderCommentBadge).toEqual(true);
+ done();
+ },
+ );
initDiscussionTab();
});
@@ -32,6 +34,7 @@ describe('initDiscussionTab', () => {
it('should call initImageDiff for each diffFileEls', () => {
spyOn(imageDiffHelper, 'initImageDiff').and.callFake(() => {});
initDiscussionTab();
+
expect(imageDiffHelper.initImageDiff.calls.count()).toEqual(2);
});
});
diff --git a/spec/javascripts/image_diff/replaced_image_diff_spec.js b/spec/javascripts/image_diff/replaced_image_diff_spec.js
index 5f8cd7c531a..62e7c8b6c6a 100644
--- a/spec/javascripts/image_diff/replaced_image_diff_spec.js
+++ b/spec/javascripts/image_diff/replaced_image_diff_spec.js
@@ -37,16 +37,28 @@ describe('ReplacedImageDiff', () => {
function setupImageFrameEls() {
replacedImageDiff.imageFrameEls = [];
- replacedImageDiff.imageFrameEls[viewTypes.TWO_UP] = element.querySelector('.two-up .js-image-frame');
- replacedImageDiff.imageFrameEls[viewTypes.SWIPE] = element.querySelector('.swipe .js-image-frame');
- replacedImageDiff.imageFrameEls[viewTypes.ONION_SKIN] = element.querySelector('.onion-skin .js-image-frame');
+ replacedImageDiff.imageFrameEls[viewTypes.TWO_UP] = element.querySelector(
+ '.two-up .js-image-frame',
+ );
+ replacedImageDiff.imageFrameEls[viewTypes.SWIPE] = element.querySelector(
+ '.swipe .js-image-frame',
+ );
+ replacedImageDiff.imageFrameEls[viewTypes.ONION_SKIN] = element.querySelector(
+ '.onion-skin .js-image-frame',
+ );
}
function setupViewModesEls() {
replacedImageDiff.viewModesEls = [];
- replacedImageDiff.viewModesEls[viewTypes.TWO_UP] = element.querySelector('.view-modes-menu .two-up');
- replacedImageDiff.viewModesEls[viewTypes.SWIPE] = element.querySelector('.view-modes-menu .swipe');
- replacedImageDiff.viewModesEls[viewTypes.ONION_SKIN] = element.querySelector('.view-modes-menu .onion-skin');
+ replacedImageDiff.viewModesEls[viewTypes.TWO_UP] = element.querySelector(
+ '.view-modes-menu .two-up',
+ );
+ replacedImageDiff.viewModesEls[viewTypes.SWIPE] = element.querySelector(
+ '.view-modes-menu .swipe',
+ );
+ replacedImageDiff.viewModesEls[viewTypes.ONION_SKIN] = element.querySelector(
+ '.view-modes-menu .onion-skin',
+ );
}
function setupImageEls() {
@@ -58,6 +70,7 @@ describe('ReplacedImageDiff', () => {
it('should extend ImageDiff', () => {
replacedImageDiff = new ReplacedImageDiff(element);
+
expect(replacedImageDiff instanceof ImageDiff).toEqual(true);
});
@@ -72,18 +85,36 @@ describe('ReplacedImageDiff', () => {
it('should set imageFrameEls', () => {
const { imageFrameEls } = replacedImageDiff;
+
expect(imageFrameEls).toBeDefined();
- expect(imageFrameEls[viewTypes.TWO_UP]).toEqual(element.querySelector('.two-up .js-image-frame'));
- expect(imageFrameEls[viewTypes.SWIPE]).toEqual(element.querySelector('.swipe .js-image-frame'));
- expect(imageFrameEls[viewTypes.ONION_SKIN]).toEqual(element.querySelector('.onion-skin .js-image-frame'));
+ expect(imageFrameEls[viewTypes.TWO_UP]).toEqual(
+ element.querySelector('.two-up .js-image-frame'),
+ );
+
+ expect(imageFrameEls[viewTypes.SWIPE]).toEqual(
+ element.querySelector('.swipe .js-image-frame'),
+ );
+
+ expect(imageFrameEls[viewTypes.ONION_SKIN]).toEqual(
+ element.querySelector('.onion-skin .js-image-frame'),
+ );
});
it('should set viewModesEls', () => {
const { viewModesEls } = replacedImageDiff;
+
expect(viewModesEls).toBeDefined();
- expect(viewModesEls[viewTypes.TWO_UP]).toEqual(element.querySelector('.view-modes-menu .two-up'));
- expect(viewModesEls[viewTypes.SWIPE]).toEqual(element.querySelector('.view-modes-menu .swipe'));
- expect(viewModesEls[viewTypes.ONION_SKIN]).toEqual(element.querySelector('.view-modes-menu .onion-skin'));
+ expect(viewModesEls[viewTypes.TWO_UP]).toEqual(
+ element.querySelector('.view-modes-menu .two-up'),
+ );
+
+ expect(viewModesEls[viewTypes.SWIPE]).toEqual(
+ element.querySelector('.view-modes-menu .swipe'),
+ );
+
+ expect(viewModesEls[viewTypes.ONION_SKIN]).toEqual(
+ element.querySelector('.view-modes-menu .onion-skin'),
+ );
});
it('should generateImageEls', () => {
@@ -97,6 +128,7 @@ describe('ReplacedImageDiff', () => {
describe('currentView', () => {
it('should set currentView', () => {
replacedImageDiff.init(viewTypes.ONION_SKIN);
+
expect(replacedImageDiff.currentView).toEqual(viewTypes.ONION_SKIN);
});
@@ -121,6 +153,7 @@ describe('ReplacedImageDiff', () => {
it('should set imageEls', () => {
replacedImageDiff.generateImageEls();
const { imageEls } = replacedImageDiff;
+
expect(imageEls).toBeDefined();
expect(imageEls[viewTypes.TWO_UP]).toEqual(element.querySelector('.two-up img'));
expect(imageEls[viewTypes.SWIPE]).toEqual(element.querySelector('.swipe img'));
@@ -138,11 +171,12 @@ describe('ReplacedImageDiff', () => {
it('should call super.bindEvents', () => {
replacedImageDiff.bindEvents();
+
expect(ImageDiff.prototype.bindEvents).toHaveBeenCalled();
});
- it('should register click eventlistener to 2-up view mode', (done) => {
- spyOn(ReplacedImageDiff.prototype, 'changeView').and.callFake((viewMode) => {
+ it('should register click eventlistener to 2-up view mode', done => {
+ spyOn(ReplacedImageDiff.prototype, 'changeView').and.callFake(viewMode => {
expect(viewMode).toEqual(viewTypes.TWO_UP);
done();
});
@@ -151,8 +185,8 @@ describe('ReplacedImageDiff', () => {
replacedImageDiff.viewModesEls[viewTypes.TWO_UP].click();
});
- it('should register click eventlistener to swipe view mode', (done) => {
- spyOn(ReplacedImageDiff.prototype, 'changeView').and.callFake((viewMode) => {
+ it('should register click eventlistener to swipe view mode', done => {
+ spyOn(ReplacedImageDiff.prototype, 'changeView').and.callFake(viewMode => {
expect(viewMode).toEqual(viewTypes.SWIPE);
done();
});
@@ -161,8 +195,8 @@ describe('ReplacedImageDiff', () => {
replacedImageDiff.viewModesEls[viewTypes.SWIPE].click();
});
- it('should register click eventlistener to onion skin view mode', (done) => {
- spyOn(ReplacedImageDiff.prototype, 'changeView').and.callFake((viewMode) => {
+ it('should register click eventlistener to onion skin view mode', done => {
+ spyOn(ReplacedImageDiff.prototype, 'changeView').and.callFake(viewMode => {
expect(viewMode).toEqual(viewTypes.SWIPE);
done();
});
@@ -184,6 +218,7 @@ describe('ReplacedImageDiff', () => {
expect(replacedImageDiff.imageEl).toEqual(element.querySelector('.two-up img'));
replacedImageDiff.currentView = viewTypes.SWIPE;
+
expect(replacedImageDiff.imageEl).toEqual(element.querySelector('.swipe img'));
});
});
@@ -196,10 +231,15 @@ describe('ReplacedImageDiff', () => {
});
it('should return imageFrameEl based on currentView', () => {
- expect(replacedImageDiff.imageFrameEl).toEqual(element.querySelector('.two-up .js-image-frame'));
+ expect(replacedImageDiff.imageFrameEl).toEqual(
+ element.querySelector('.two-up .js-image-frame'),
+ );
replacedImageDiff.currentView = viewTypes.ONION_SKIN;
- expect(replacedImageDiff.imageFrameEl).toEqual(element.querySelector('.onion-skin .js-image-frame'));
+
+ expect(replacedImageDiff.imageFrameEl).toEqual(
+ element.querySelector('.onion-skin .js-image-frame'),
+ );
});
});
});
@@ -248,6 +288,7 @@ describe('ReplacedImageDiff', () => {
it('should call renderNewView', () => {
jasmine.clock().tick(251);
+
expect(replacedImageDiff.renderNewView).toHaveBeenCalled();
});
});
@@ -284,7 +325,7 @@ describe('ReplacedImageDiff', () => {
setupImageFrameEls();
});
- it('should pass showCommentIndicator normalized indicator values', (done) => {
+ it('should pass showCommentIndicator normalized indicator values', done => {
spyOn(imageDiffHelper, 'showCommentIndicator').and.callFake(() => {});
spyOn(imageDiffHelper, 'resizeCoordinatesToImageElement').and.callFake((imageEl, meta) => {
expect(meta.x).toEqual(indicator.x);
@@ -296,15 +337,17 @@ describe('ReplacedImageDiff', () => {
replacedImageDiff.renderNewView(indicator);
});
- it('should call showCommentIndicator', (done) => {
+ it('should call showCommentIndicator', done => {
const normalized = {
normalized: true,
};
spyOn(imageDiffHelper, 'resizeCoordinatesToImageElement').and.returnValue(normalized);
- spyOn(imageDiffHelper, 'showCommentIndicator').and.callFake((imageFrameEl, normalizedIndicator) => {
- expect(normalizedIndicator).toEqual(normalized);
- done();
- });
+ spyOn(imageDiffHelper, 'showCommentIndicator').and.callFake(
+ (imageFrameEl, normalizedIndicator) => {
+ expect(normalizedIndicator).toEqual(normalized);
+ done();
+ },
+ );
replacedImageDiff.renderNewView(indicator);
});
});
diff --git a/spec/javascripts/importer_status_spec.js b/spec/javascripts/importer_status_spec.js
index 63cdb3d5114..e7f195ed57c 100644
--- a/spec/javascripts/importer_status_spec.js
+++ b/spec/javascripts/importer_status_spec.js
@@ -35,38 +35,43 @@ describe('Importer Status', () => {
});
});
- it('sets table row to active after post request', (done) => {
+ it('sets table row to active after post request', done => {
mock.onPost(importUrl).reply(200, {
id: 1,
full_path: '/full_path',
});
- instance.addToImport({
- currentTarget: document.querySelector('.js-add-to-import'),
- })
- .then(() => {
- expect(document.querySelector('tr').classList.contains('table-active')).toEqual(true);
- done();
- })
- .catch(done.fail);
+ instance
+ .addToImport({
+ currentTarget: document.querySelector('.js-add-to-import'),
+ })
+ .then(() => {
+ expect(document.querySelector('tr').classList.contains('table-active')).toEqual(true);
+ done();
+ })
+ .catch(done.fail);
});
- it('shows error message after failed POST request', (done) => {
+ it('shows error message after failed POST request', done => {
appendSetFixtures('<div class="flash-container"></div>');
mock.onPost(importUrl).reply(422, {
errors: 'You forgot your lunch',
});
- instance.addToImport({
- currentTarget: document.querySelector('.js-add-to-import'),
- })
- .then(() => {
- const flashMessage = document.querySelector('.flash-text');
- expect(flashMessage.textContent.trim()).toEqual('An error occurred while importing project: You forgot your lunch');
- done();
- })
- .catch(done.fail);
+ instance
+ .addToImport({
+ currentTarget: document.querySelector('.js-add-to-import'),
+ })
+ .then(() => {
+ const flashMessage = document.querySelector('.flash-text');
+
+ expect(flashMessage.textContent.trim()).toEqual(
+ 'An error occurred while importing project: You forgot your lunch',
+ );
+ done();
+ })
+ .catch(done.fail);
});
});
@@ -92,14 +97,17 @@ describe('Importer Status', () => {
});
function setupMock(importStatus) {
- mock.onGet(jobsUrl).reply(200, [{
- id: 1,
- import_status: importStatus,
- }]);
+ mock.onGet(jobsUrl).reply(200, [
+ {
+ id: 1,
+ import_status: importStatus,
+ },
+ ]);
}
function expectJobStatus(done, status) {
- instance.autoUpdate()
+ instance
+ .autoUpdate()
.then(() => {
expect(document.querySelector('#project_1').innerText.trim()).toEqual(status);
done();
@@ -107,22 +115,22 @@ describe('Importer Status', () => {
.catch(done.fail);
}
- it('sets the job status to done', (done) => {
+ it('sets the job status to done', done => {
setupMock('finished');
expectJobStatus(done, 'Done');
});
- it('sets the job status to scheduled', (done) => {
+ it('sets the job status to scheduled', done => {
setupMock('scheduled');
expectJobStatus(done, 'Scheduled');
});
- it('sets the job status to started', (done) => {
+ it('sets the job status to started', done => {
setupMock('started');
expectJobStatus(done, 'Started');
});
- it('sets the job status to custom status', (done) => {
+ it('sets the job status to custom status', done => {
setupMock('custom status');
expectJobStatus(done, 'custom status');
});
diff --git a/spec/javascripts/integrations/integration_settings_form_spec.js b/spec/javascripts/integrations/integration_settings_form_spec.js
index e07343810d2..4f4c9a7b463 100644
--- a/spec/javascripts/integrations/integration_settings_form_spec.js
+++ b/spec/javascripts/integrations/integration_settings_form_spec.js
@@ -68,21 +68,27 @@ describe('IntegrationSettingsForm', () => {
integrationSettingsForm.canTestService = true;
integrationSettingsForm.toggleSubmitBtnLabel(true);
- expect(integrationSettingsForm.$submitBtnLabel.text()).toEqual('Test settings and save changes');
+
+ expect(integrationSettingsForm.$submitBtnLabel.text()).toEqual(
+ 'Test settings and save changes',
+ );
});
it('should set Save button label to "Save changes" when either serviceActive or canTestService (or both) is `false`', () => {
integrationSettingsForm.canTestService = false;
integrationSettingsForm.toggleSubmitBtnLabel(false);
+
expect(integrationSettingsForm.$submitBtnLabel.text()).toEqual('Save changes');
integrationSettingsForm.toggleSubmitBtnLabel(true);
+
expect(integrationSettingsForm.$submitBtnLabel.text()).toEqual('Save changes');
integrationSettingsForm.canTestService = true;
integrationSettingsForm.toggleSubmitBtnLabel(false);
+
expect(integrationSettingsForm.$submitBtnLabel.text()).toEqual('Save changes');
});
});
@@ -127,8 +133,9 @@ describe('IntegrationSettingsForm', () => {
mock.restore();
});
- it('should make an ajax request with provided `formData`', (done) => {
- integrationSettingsForm.testSettings(formData)
+ it('should make an ajax request with provided `formData`', done => {
+ integrationSettingsForm
+ .testSettings(formData)
.then(() => {
expect(axios.put).toHaveBeenCalledWith(integrationSettingsForm.testEndPoint, formData);
@@ -137,7 +144,7 @@ describe('IntegrationSettingsForm', () => {
.catch(done.fail);
});
- it('should show error Flash with `Save anyway` action if ajax request responds with error in test', (done) => {
+ it('should show error Flash with `Save anyway` action if ajax request responds with error in test', done => {
const errorMessage = 'Test failed.';
mock.onPut(integrationSettingsForm.testEndPoint).reply(200, {
error: true,
@@ -146,19 +153,32 @@ describe('IntegrationSettingsForm', () => {
test_failed: true,
});
- integrationSettingsForm.testSettings(formData)
+ integrationSettingsForm
+ .testSettings(formData)
.then(() => {
const $flashContainer = $('.flash-container');
- expect($flashContainer.find('.flash-text').text().trim()).toEqual('Test failed. some error');
+
+ expect(
+ $flashContainer
+ .find('.flash-text')
+ .text()
+ .trim(),
+ ).toEqual('Test failed. some error');
+
expect($flashContainer.find('.flash-action')).toBeDefined();
- expect($flashContainer.find('.flash-action').text().trim()).toEqual('Save anyway');
+ expect(
+ $flashContainer
+ .find('.flash-action')
+ .text()
+ .trim(),
+ ).toEqual('Save anyway');
done();
})
.catch(done.fail);
});
- it('should not show error Flash with `Save anyway` action if ajax request responds with error in validation', (done) => {
+ it('should not show error Flash with `Save anyway` action if ajax request responds with error in validation', done => {
const errorMessage = 'Validations failed.';
mock.onPut(integrationSettingsForm.testEndPoint).reply(200, {
error: true,
@@ -167,26 +187,40 @@ describe('IntegrationSettingsForm', () => {
test_failed: false,
});
- integrationSettingsForm.testSettings(formData)
+ integrationSettingsForm
+ .testSettings(formData)
.then(() => {
const $flashContainer = $('.flash-container');
- expect($flashContainer.find('.flash-text').text().trim()).toEqual('Validations failed. some error');
+
+ expect(
+ $flashContainer
+ .find('.flash-text')
+ .text()
+ .trim(),
+ ).toEqual('Validations failed. some error');
+
expect($flashContainer.find('.flash-action')).toBeDefined();
- expect($flashContainer.find('.flash-action').text().trim()).toEqual('');
+ expect(
+ $flashContainer
+ .find('.flash-action')
+ .text()
+ .trim(),
+ ).toEqual('');
done();
})
.catch(done.fail);
});
- it('should submit form if ajax request responds without any error in test', (done) => {
+ it('should submit form if ajax request responds without any error in test', done => {
spyOn(integrationSettingsForm.$form, 'submit');
mock.onPut(integrationSettingsForm.testEndPoint).reply(200, {
error: false,
});
- integrationSettingsForm.testSettings(formData)
+ integrationSettingsForm
+ .testSettings(formData)
.then(() => {
expect(integrationSettingsForm.$form.submit).toHaveBeenCalled();
@@ -195,7 +229,7 @@ describe('IntegrationSettingsForm', () => {
.catch(done.fail);
});
- it('should submit form when clicked on `Save anyway` action of error Flash', (done) => {
+ it('should submit form when clicked on `Save anyway` action of error Flash', done => {
spyOn(integrationSettingsForm.$form, 'submit');
const errorMessage = 'Test failed.';
@@ -205,9 +239,11 @@ describe('IntegrationSettingsForm', () => {
test_failed: true,
});
- integrationSettingsForm.testSettings(formData)
+ integrationSettingsForm
+ .testSettings(formData)
.then(() => {
const $flashAction = $('.flash-container .flash-action');
+
expect($flashAction).toBeDefined();
$flashAction.get(0).click();
@@ -220,26 +256,32 @@ describe('IntegrationSettingsForm', () => {
.catch(done.fail);
});
- it('should show error Flash if ajax request failed', (done) => {
+ it('should show error Flash if ajax request failed', done => {
const errorMessage = 'Something went wrong on our end.';
mock.onPut(integrationSettingsForm.testEndPoint).networkError();
- integrationSettingsForm.testSettings(formData)
+ integrationSettingsForm
+ .testSettings(formData)
.then(() => {
- expect($('.flash-container .flash-text').text().trim()).toEqual(errorMessage);
+ expect(
+ $('.flash-container .flash-text')
+ .text()
+ .trim(),
+ ).toEqual(errorMessage);
done();
})
.catch(done.fail);
});
- it('should always call `toggleSubmitBtnState` with `false` once request is completed', (done) => {
+ it('should always call `toggleSubmitBtnState` with `false` once request is completed', done => {
mock.onPut(integrationSettingsForm.testEndPoint).networkError();
spyOn(integrationSettingsForm, 'toggleSubmitBtnState');
- integrationSettingsForm.testSettings(formData)
+ integrationSettingsForm
+ .testSettings(formData)
.then(() => {
expect(integrationSettingsForm.toggleSubmitBtnState).toHaveBeenCalledWith(false);
diff --git a/spec/javascripts/issuable_spec.js b/spec/javascripts/issuable_spec.js
index 57bf746f080..25543053eba 100644
--- a/spec/javascripts/issuable_spec.js
+++ b/spec/javascripts/issuable_spec.js
@@ -8,6 +8,7 @@ describe('Issuable', () => {
describe('initBulkUpdate', () => {
it('should not set bulkUpdateSidebar', () => {
Issuable = new IssuableIndex('issue_');
+
expect(Issuable.bulkUpdateSidebar).not.toBeDefined();
});
@@ -17,6 +18,7 @@ describe('Issuable', () => {
document.body.appendChild(element);
Issuable = new IssuableIndex('issue_');
+
expect(Issuable.bulkUpdateSidebar).toBeDefined();
});
});
@@ -47,7 +49,7 @@ describe('Issuable', () => {
mock.restore();
});
- it('should send request to reset email token', (done) => {
+ it('should send request to reset email token', done => {
spyOn(axios, 'put').and.callThrough();
document.querySelector('.incoming-email-token-reset').click();
@@ -60,4 +62,3 @@ describe('Issuable', () => {
});
});
});
-
diff --git a/spec/javascripts/issue_show/components/app_spec.js b/spec/javascripts/issue_show/components/app_spec.js
index 36328382448..2bd1b3996dc 100644
--- a/spec/javascripts/issue_show/components/app_spec.js
+++ b/spec/javascripts/issue_show/components/app_spec.js
@@ -11,10 +11,7 @@ function formatText(text) {
return text.trim().replace(/\s\s+/g, ' ');
}
-const REALTIME_REQUEST_STACK = [
- issueShowData.initialRequest,
- issueShowData.secondRequest,
-];
+const REALTIME_REQUEST_STACK = [issueShowData.initialRequest, issueShowData.secondRequest];
describe('Issuable output', () => {
let mock;
@@ -23,7 +20,7 @@ describe('Issuable output', () => {
document.body.innerHTML = '<span id="task_status"></span>';
- beforeEach((done) => {
+ beforeEach(done => {
spyOn(eventHub, '$emit');
const IssuableDescriptionComponent = Vue.extend(issuableApp);
@@ -64,65 +61,67 @@ describe('Issuable output', () => {
vm.$destroy();
});
- it('should render a title/description/edited and update title/description/edited on update', (done) => {
+ it('should render a title/description/edited and update title/description/edited on update', done => {
let editedText;
Vue.nextTick()
- .then(() => {
- editedText = vm.$el.querySelector('.edited-text');
- })
- .then(() => {
- expect(document.querySelector('title').innerText).toContain('this is a title (#1)');
- expect(vm.$el.querySelector('.title').innerHTML).toContain('<p>this is a title</p>');
- expect(vm.$el.querySelector('.wiki').innerHTML).toContain('<p>this is a description!</p>');
- expect(vm.$el.querySelector('.js-task-list-field').value).toContain('this is a description');
- expect(formatText(editedText.innerText)).toMatch(/Edited[\s\S]+?by Some User/);
- expect(editedText.querySelector('.author-link').href).toMatch(/\/some_user$/);
- expect(editedText.querySelector('time')).toBeTruthy();
- })
- .then(() => {
- vm.poll.makeRequest();
- })
- .then(() => new Promise(resolve => setTimeout(resolve)))
- .then(() => {
- expect(document.querySelector('title').innerText).toContain('2 (#1)');
- expect(vm.$el.querySelector('.title').innerHTML).toContain('<p>2</p>');
- expect(vm.$el.querySelector('.wiki').innerHTML).toContain('<p>42</p>');
- expect(vm.$el.querySelector('.js-task-list-field').value).toContain('42');
- expect(vm.$el.querySelector('.edited-text')).toBeTruthy();
- expect(formatText(vm.$el.querySelector('.edited-text').innerText)).toMatch(/Edited[\s\S]+?by Other User/);
- expect(editedText.querySelector('.author-link').href).toMatch(/\/other_user$/);
- expect(editedText.querySelector('time')).toBeTruthy();
- })
- .then(done)
- .catch(done.fail);
+ .then(() => {
+ editedText = vm.$el.querySelector('.edited-text');
+ })
+ .then(() => {
+ expect(document.querySelector('title').innerText).toContain('this is a title (#1)');
+ expect(vm.$el.querySelector('.title').innerHTML).toContain('<p>this is a title</p>');
+ expect(vm.$el.querySelector('.wiki').innerHTML).toContain('<p>this is a description!</p>');
+ expect(vm.$el.querySelector('.js-task-list-field').value).toContain(
+ 'this is a description',
+ );
+
+ expect(formatText(editedText.innerText)).toMatch(/Edited[\s\S]+?by Some User/);
+ expect(editedText.querySelector('.author-link').href).toMatch(/\/some_user$/);
+ expect(editedText.querySelector('time')).toBeTruthy();
+ })
+ .then(() => {
+ vm.poll.makeRequest();
+ })
+ .then(() => new Promise(resolve => setTimeout(resolve)))
+ .then(() => {
+ expect(document.querySelector('title').innerText).toContain('2 (#1)');
+ expect(vm.$el.querySelector('.title').innerHTML).toContain('<p>2</p>');
+ expect(vm.$el.querySelector('.wiki').innerHTML).toContain('<p>42</p>');
+ expect(vm.$el.querySelector('.js-task-list-field').value).toContain('42');
+ expect(vm.$el.querySelector('.edited-text')).toBeTruthy();
+ expect(formatText(vm.$el.querySelector('.edited-text').innerText)).toMatch(
+ /Edited[\s\S]+?by Other User/,
+ );
+
+ expect(editedText.querySelector('.author-link').href).toMatch(/\/other_user$/);
+ expect(editedText.querySelector('time')).toBeTruthy();
+ })
+ .then(done)
+ .catch(done.fail);
});
- it('shows actions if permissions are correct', (done) => {
+ it('shows actions if permissions are correct', done => {
vm.showForm = true;
Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('.btn'),
- ).not.toBeNull();
+ expect(vm.$el.querySelector('.btn')).not.toBeNull();
done();
});
});
- it('does not show actions if permissions are incorrect', (done) => {
+ it('does not show actions if permissions are incorrect', done => {
vm.showForm = true;
vm.canUpdate = false;
Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('.btn'),
- ).toBeNull();
+ expect(vm.$el.querySelector('.btn')).toBeNull();
done();
});
});
- it('does not update formState if form is already open', (done) => {
+ it('does not update formState if form is already open', done => {
vm.openForm();
vm.state.titleText = 'testing 123';
@@ -130,25 +129,26 @@ describe('Issuable output', () => {
vm.openForm();
Vue.nextTick(() => {
- expect(
- vm.store.formState.title,
- ).not.toBe('testing 123');
+ expect(vm.store.formState.title).not.toBe('testing 123');
done();
});
});
describe('updateIssuable', () => {
- it('fetches new data after update', (done) => {
+ it('fetches new data after update', done => {
spyOn(vm.service, 'getData').and.callThrough();
- spyOn(vm.service, 'updateIssuable').and.callFake(() => new Promise((resolve) => {
- resolve({
- data: {
- confidential: false,
- web_url: window.location.pathname,
- },
- });
- }));
+ spyOn(vm.service, 'updateIssuable').and.callFake(
+ () =>
+ new Promise(resolve => {
+ resolve({
+ data: {
+ confidential: false,
+ web_url: window.location.pathname,
+ },
+ });
+ }),
+ );
vm.updateIssuable()
.then(() => {
@@ -158,10 +158,13 @@ describe('Issuable output', () => {
.catch(done.fail);
});
- it('correctly updates issuable data', (done) => {
- spyOn(vm.service, 'updateIssuable').and.callFake(() => new Promise((resolve) => {
- resolve();
- }));
+ it('correctly updates issuable data', done => {
+ spyOn(vm.service, 'updateIssuable').and.callFake(
+ () =>
+ new Promise(resolve => {
+ resolve();
+ }),
+ );
vm.updateIssuable()
.then(() => {
@@ -172,16 +175,19 @@ describe('Issuable output', () => {
.catch(done.fail);
});
- it('does not redirect if issue has not moved', (done) => {
+ it('does not redirect if issue has not moved', done => {
const visitUrl = spyOnDependency(issuableApp, 'visitUrl');
- spyOn(vm.service, 'updateIssuable').and.callFake(() => new Promise((resolve) => {
- resolve({
- data: {
- web_url: window.location.pathname,
- confidential: vm.isConfidential,
- },
- });
- }));
+ spyOn(vm.service, 'updateIssuable').and.callFake(
+ () =>
+ new Promise(resolve => {
+ resolve({
+ data: {
+ web_url: window.location.pathname,
+ confidential: vm.isConfidential,
+ },
+ });
+ }),
+ );
vm.updateIssuable();
@@ -191,16 +197,19 @@ describe('Issuable output', () => {
});
});
- it('redirects if returned web_url has changed', (done) => {
+ it('redirects if returned web_url has changed', done => {
const visitUrl = spyOnDependency(issuableApp, 'visitUrl');
- spyOn(vm.service, 'updateIssuable').and.callFake(() => new Promise((resolve) => {
- resolve({
- data: {
- web_url: '/testing-issue-move',
- confidential: vm.isConfidential,
- },
- });
- }));
+ spyOn(vm.service, 'updateIssuable').and.callFake(
+ () =>
+ new Promise(resolve => {
+ resolve({
+ data: {
+ web_url: '/testing-issue-move',
+ confidential: vm.isConfidential,
+ },
+ });
+ }),
+ );
vm.updateIssuable();
@@ -211,7 +220,7 @@ describe('Issuable output', () => {
});
describe('shows dialog when issue has unsaved changed', () => {
- it('confirms on title change', (done) => {
+ it('confirms on title change', done => {
vm.showForm = true;
vm.state.titleText = 'title has changed';
const e = { returnValue: null };
@@ -222,7 +231,7 @@ describe('Issuable output', () => {
});
});
- it('confirms on description change', (done) => {
+ it('confirms on description change', done => {
vm.showForm = true;
vm.state.descriptionText = 'description has changed';
const e = { returnValue: null };
@@ -233,7 +242,7 @@ describe('Issuable output', () => {
});
});
- it('does nothing when nothing has changed', (done) => {
+ it('does nothing when nothing has changed', done => {
const e = { returnValue: null };
vm.handleBeforeUnloadEvent(e);
Vue.nextTick(() => {
@@ -246,39 +255,36 @@ describe('Issuable output', () => {
describe('error when updating', () => {
beforeEach(() => {
spyOn(window, 'Flash').and.callThrough();
- spyOn(vm.service, 'updateIssuable').and.callFake(() => new Promise((resolve, reject) => {
- reject();
- }));
+ spyOn(vm.service, 'updateIssuable').and.callFake(
+ () =>
+ new Promise((resolve, reject) => {
+ reject();
+ }),
+ );
});
- it('closes form on error', (done) => {
+ it('closes form on error', done => {
vm.updateIssuable();
setTimeout(() => {
- expect(
- eventHub.$emit,
- ).toHaveBeenCalledWith('close.form');
- expect(
- window.Flash,
- ).toHaveBeenCalledWith('Error updating issue');
+ expect(eventHub.$emit).toHaveBeenCalledWith('close.form');
+
+ expect(window.Flash).toHaveBeenCalledWith('Error updating issue');
done();
});
});
- it('returns the correct error message for issuableType', (done) => {
+ it('returns the correct error message for issuableType', done => {
vm.issuableType = 'merge request';
Vue.nextTick(() => {
vm.updateIssuable();
setTimeout(() => {
- expect(
- eventHub.$emit,
- ).toHaveBeenCalledWith('close.form');
- expect(
- window.Flash,
- ).toHaveBeenCalledWith('Error updating merge request');
+ expect(eventHub.$emit).toHaveBeenCalledWith('close.form');
+
+ expect(window.Flash).toHaveBeenCalledWith('Error updating merge request');
done();
});
@@ -287,16 +293,18 @@ describe('Issuable output', () => {
});
});
- it('opens recaptcha modal if update rejected as spam', (done) => {
+ it('opens recaptcha modal if update rejected as spam', done => {
function mockScriptSrc() {
- const recaptchaChild = vm.$children
- .find(child => child.$options._componentTag === 'recaptcha-modal'); // eslint-disable-line no-underscore-dangle
+ const recaptchaChild = vm.$children.find(
+ // eslint-disable-next-line no-underscore-dangle
+ child => child.$options._componentTag === 'recaptcha-modal',
+ );
recaptchaChild.scriptSrc = '//scriptsrc';
}
let modal;
- const promise = new Promise((resolve) => {
+ const promise = new Promise(resolve => {
resolve({
data: {
recaptcha_html: '<div class="g-recaptcha">recaptcha_html</div>',
@@ -332,15 +340,18 @@ describe('Issuable output', () => {
});
describe('deleteIssuable', () => {
- it('changes URL when deleted', (done) => {
+ it('changes URL when deleted', done => {
const visitUrl = spyOnDependency(issuableApp, 'visitUrl');
- spyOn(vm.service, 'deleteIssuable').and.callFake(() => new Promise((resolve) => {
- resolve({
- data: {
- web_url: '/test',
- },
- });
- }));
+ spyOn(vm.service, 'deleteIssuable').and.callFake(
+ () =>
+ new Promise(resolve => {
+ resolve({
+ data: {
+ web_url: '/test',
+ },
+ });
+ }),
+ );
vm.deleteIssuable();
@@ -350,42 +361,43 @@ describe('Issuable output', () => {
});
});
- it('stops polling when deleting', (done) => {
+ it('stops polling when deleting', done => {
spyOnDependency(issuableApp, 'visitUrl');
spyOn(vm.poll, 'stop').and.callThrough();
- spyOn(vm.service, 'deleteIssuable').and.callFake(() => new Promise((resolve) => {
- resolve({
- data: {
- web_url: '/test',
- },
- });
- }));
+ spyOn(vm.service, 'deleteIssuable').and.callFake(
+ () =>
+ new Promise(resolve => {
+ resolve({
+ data: {
+ web_url: '/test',
+ },
+ });
+ }),
+ );
vm.deleteIssuable();
setTimeout(() => {
- expect(
- vm.poll.stop,
- ).toHaveBeenCalledWith();
+ expect(vm.poll.stop).toHaveBeenCalledWith();
done();
});
});
- it('closes form on error', (done) => {
+ it('closes form on error', done => {
spyOn(window, 'Flash').and.callThrough();
- spyOn(vm.service, 'deleteIssuable').and.callFake(() => new Promise((resolve, reject) => {
- reject();
- }));
+ spyOn(vm.service, 'deleteIssuable').and.callFake(
+ () =>
+ new Promise((resolve, reject) => {
+ reject();
+ }),
+ );
vm.deleteIssuable();
setTimeout(() => {
- expect(
- eventHub.$emit,
- ).toHaveBeenCalledWith('close.form');
- expect(
- window.Flash,
- ).toHaveBeenCalledWith('Error deleting issue');
+ expect(eventHub.$emit).toHaveBeenCalledWith('close.form');
+
+ expect(window.Flash).toHaveBeenCalledWith('Error deleting issue');
done();
});
@@ -393,7 +405,7 @@ describe('Issuable output', () => {
});
describe('open form', () => {
- it('shows locked warning if form is open & data is different', (done) => {
+ it('shows locked warning if form is open & data is different', done => {
vm.$nextTick()
.then(() => {
vm.openForm();
@@ -422,6 +434,7 @@ describe('Issuable output', () => {
it('should render if showInlineEditButton', () => {
vm.showInlineEditButton = true;
+
expect(vm.$el.querySelector('.title-container .note-action-button')).toBeDefined();
});
});
diff --git a/spec/javascripts/issue_show/components/description_spec.js b/spec/javascripts/issue_show/components/description_spec.js
index 889c8545faa..463f3c89926 100644
--- a/spec/javascripts/issue_show/components/description_spec.js
+++ b/spec/javascripts/issue_show/components/description_spec.js
@@ -33,7 +33,7 @@ describe('Description component', () => {
vm.$destroy();
});
- it('animates description changes', (done) => {
+ it('animates description changes', done => {
vm.descriptionHtml = 'changed';
Vue.nextTick(() => {
@@ -51,10 +51,12 @@ describe('Description component', () => {
});
});
- it('opens recaptcha dialog if update rejected as spam', (done) => {
+ it('opens recaptcha dialog if update rejected as spam', done => {
let modal;
- const recaptchaChild = vm.$children
- .find(child => child.$options._componentTag === 'recaptcha-modal'); // eslint-disable-line no-underscore-dangle
+ const recaptchaChild = vm.$children.find(
+ // eslint-disable-next-line no-underscore-dangle
+ child => child.$options._componentTag === 'recaptcha-modal',
+ );
recaptchaChild.scriptSrc = '//scriptsrc';
@@ -84,13 +86,16 @@ describe('Description component', () => {
let TaskList;
beforeEach(() => {
- vm = mountComponent(DescriptionComponent, Object.assign({}, props, {
- issuableType: 'issuableType',
- }));
+ vm = mountComponent(
+ DescriptionComponent,
+ Object.assign({}, props, {
+ issuableType: 'issuableType',
+ }),
+ );
TaskList = spyOnDependency(Description, 'TaskList');
});
- it('re-inits the TaskList when description changed', (done) => {
+ it('re-inits the TaskList when description changed', done => {
vm.descriptionHtml = 'changed';
setTimeout(() => {
@@ -99,7 +104,7 @@ describe('Description component', () => {
});
});
- it('does not re-init the TaskList when canUpdate is false', (done) => {
+ it('does not re-init the TaskList when canUpdate is false', done => {
vm.canUpdate = false;
vm.descriptionHtml = 'changed';
@@ -109,7 +114,7 @@ describe('Description component', () => {
});
});
- it('calls with issuableType dataType', (done) => {
+ it('calls with issuableType dataType', done => {
vm.descriptionHtml = 'changed';
setTimeout(() => {
@@ -125,44 +130,42 @@ describe('Description component', () => {
});
describe('taskStatus', () => {
- it('adds full taskStatus', (done) => {
+ it('adds full taskStatus', done => {
vm.taskStatus = '1 of 1';
setTimeout(() => {
- expect(
- document.querySelector('.issuable-meta #task_status').textContent.trim(),
- ).toBe('1 of 1');
+ expect(document.querySelector('.issuable-meta #task_status').textContent.trim()).toBe(
+ '1 of 1',
+ );
done();
});
});
- it('adds short taskStatus', (done) => {
+ it('adds short taskStatus', done => {
vm.taskStatus = '1 of 1';
setTimeout(() => {
- expect(
- document.querySelector('.issuable-meta #task_status_short').textContent.trim(),
- ).toBe('1/1 task');
+ expect(document.querySelector('.issuable-meta #task_status_short').textContent.trim()).toBe(
+ '1/1 task',
+ );
done();
});
});
- it('clears task status text when no tasks are present', (done) => {
+ it('clears task status text when no tasks are present', done => {
vm.taskStatus = '0 of 0';
setTimeout(() => {
- expect(
- document.querySelector('.issuable-meta #task_status').textContent.trim(),
- ).toBe('');
+ expect(document.querySelector('.issuable-meta #task_status').textContent.trim()).toBe('');
done();
});
});
});
- it('applies syntax highlighting and math when description changed', (done) => {
+ it('applies syntax highlighting and math when description changed', done => {
spyOn(vm, 'renderGFM').and.callThrough();
spyOn($.prototype, 'renderGFM').and.callThrough();
vm.descriptionHtml = 'changed';
diff --git a/spec/javascripts/issue_show/components/edit_actions_spec.js b/spec/javascripts/issue_show/components/edit_actions_spec.js
index 004621f488a..d92c54ea83f 100644
--- a/spec/javascripts/issue_show/components/edit_actions_spec.js
+++ b/spec/javascripts/issue_show/components/edit_actions_spec.js
@@ -6,7 +6,7 @@ import Store from '~/issue_show/stores';
describe('Edit Actions components', () => {
let vm;
- beforeEach((done) => {
+ beforeEach(done => {
const Component = Vue.extend(editActions);
const store = new Store({
titleHtml: '',
@@ -29,40 +29,32 @@ describe('Edit Actions components', () => {
});
it('renders all buttons as enabled', () => {
- expect(
- vm.$el.querySelectorAll('.disabled').length,
- ).toBe(0);
+ expect(vm.$el.querySelectorAll('.disabled').length).toBe(0);
- expect(
- vm.$el.querySelectorAll('[disabled]').length,
- ).toBe(0);
+ expect(vm.$el.querySelectorAll('[disabled]').length).toBe(0);
});
- it('does not render delete button if canUpdate is false', (done) => {
+ it('does not render delete button if canUpdate is false', done => {
vm.canDestroy = false;
Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('.btn-danger'),
- ).toBeNull();
+ expect(vm.$el.querySelector('.btn-danger')).toBeNull();
done();
});
});
- it('disables submit button when title is blank', (done) => {
+ it('disables submit button when title is blank', done => {
vm.formState.title = '';
Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('.btn-success').getAttribute('disabled'),
- ).toBe('disabled');
+ expect(vm.$el.querySelector('.btn-success').getAttribute('disabled')).toBe('disabled');
done();
});
});
- it('should not show delete button if showDeleteButton is false', (done) => {
+ it('should not show delete button if showDeleteButton is false', done => {
vm.showDeleteButton = false;
Vue.nextTick(() => {
@@ -75,30 +67,24 @@ describe('Edit Actions components', () => {
it('sends update.issauble event when clicking save button', () => {
vm.$el.querySelector('.btn-success').click();
- expect(
- eventHub.$emit,
- ).toHaveBeenCalledWith('update.issuable');
+ expect(eventHub.$emit).toHaveBeenCalledWith('update.issuable');
});
- it('shows loading icon after clicking save button', (done) => {
+ it('shows loading icon after clicking save button', done => {
vm.$el.querySelector('.btn-success').click();
Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('.btn-success .fa'),
- ).not.toBeNull();
+ expect(vm.$el.querySelector('.btn-success .fa')).not.toBeNull();
done();
});
});
- it('disabled button after clicking save button', (done) => {
+ it('disabled button after clicking save button', done => {
vm.$el.querySelector('.btn-success').click();
Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('.btn-success').getAttribute('disabled'),
- ).toBe('disabled');
+ expect(vm.$el.querySelector('.btn-success').getAttribute('disabled')).toBe('disabled');
done();
});
@@ -109,9 +95,7 @@ describe('Edit Actions components', () => {
it('emits close.form when clicking cancel', () => {
vm.$el.querySelector('.btn-default').click();
- expect(
- eventHub.$emit,
- ).toHaveBeenCalledWith('close.form');
+ expect(eventHub.$emit).toHaveBeenCalledWith('close.form');
});
});
@@ -120,35 +104,28 @@ describe('Edit Actions components', () => {
spyOn(window, 'confirm').and.returnValue(true);
vm.$el.querySelector('.btn-danger').click();
- expect(
- eventHub.$emit,
- ).toHaveBeenCalledWith('delete.issuable');
+ expect(eventHub.$emit).toHaveBeenCalledWith('delete.issuable');
});
- it('shows loading icon after clicking delete button', (done) => {
+ it('shows loading icon after clicking delete button', done => {
spyOn(window, 'confirm').and.returnValue(true);
vm.$el.querySelector('.btn-danger').click();
Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('.btn-danger .fa'),
- ).not.toBeNull();
+ expect(vm.$el.querySelector('.btn-danger .fa')).not.toBeNull();
done();
});
});
- it('does no actions when confirm is false', (done) => {
+ it('does no actions when confirm is false', done => {
spyOn(window, 'confirm').and.returnValue(false);
vm.$el.querySelector('.btn-danger').click();
Vue.nextTick(() => {
- expect(
- eventHub.$emit,
- ).not.toHaveBeenCalledWith('delete.issuable');
- expect(
- vm.$el.querySelector('.btn-danger .fa'),
- ).toBeNull();
+ expect(eventHub.$emit).not.toHaveBeenCalledWith('delete.issuable');
+
+ expect(vm.$el.querySelector('.btn-danger .fa')).toBeNull();
done();
});
diff --git a/spec/javascripts/issue_show/components/fields/description_spec.js b/spec/javascripts/issue_show/components/fields/description_spec.js
index 299f88e7778..2c3efc8d4d4 100644
--- a/spec/javascripts/issue_show/components/fields/description_spec.js
+++ b/spec/javascripts/issue_show/components/fields/description_spec.js
@@ -8,7 +8,7 @@ describe('Description field component', () => {
let vm;
let store;
- beforeEach((done) => {
+ beforeEach(done => {
const Component = Vue.extend(descriptionField);
const el = document.createElement('div');
store = new Store({
@@ -35,42 +35,32 @@ describe('Description field component', () => {
});
it('renders markdown field with description', () => {
- expect(
- vm.$el.querySelector('.md-area textarea').value,
- ).toBe('test');
+ expect(vm.$el.querySelector('.md-area textarea').value).toBe('test');
});
- it('renders markdown field with a markdown description', (done) => {
+ it('renders markdown field with a markdown description', done => {
store.formState.description = '**test**';
Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('.md-area textarea').value,
- ).toBe('**test**');
+ expect(vm.$el.querySelector('.md-area textarea').value).toBe('**test**');
done();
});
});
it('focuses field when mounted', () => {
- expect(
- document.activeElement,
- ).toBe(vm.$refs.textarea);
+ expect(document.activeElement).toBe(vm.$refs.textarea);
});
it('triggers update with meta+enter', () => {
vm.$el.querySelector('.md-area textarea').dispatchEvent(keyboardDownEvent(13, true));
- expect(
- eventHub.$emit,
- ).toHaveBeenCalled();
+ expect(eventHub.$emit).toHaveBeenCalled();
});
it('triggers update with ctrl+enter', () => {
vm.$el.querySelector('.md-area textarea').dispatchEvent(keyboardDownEvent(13, false, true));
- expect(
- eventHub.$emit,
- ).toHaveBeenCalled();
+ expect(eventHub.$emit).toHaveBeenCalled();
});
});
diff --git a/spec/javascripts/issue_show/components/fields/description_template_spec.js b/spec/javascripts/issue_show/components/fields/description_template_spec.js
index 30441faf844..8d77a620d76 100644
--- a/spec/javascripts/issue_show/components/fields/description_template_spec.js
+++ b/spec/javascripts/issue_show/components/fields/description_template_spec.js
@@ -5,7 +5,7 @@ describe('Issue description template component', () => {
let vm;
let formState;
- beforeEach((done) => {
+ beforeEach(done => {
const Component = Vue.extend(descriptionTemplate);
formState = {
description: 'test',
@@ -24,24 +24,20 @@ describe('Issue description template component', () => {
});
it('renders templates as JSON array in data attribute', () => {
- expect(
- vm.$el.querySelector('.js-issuable-selector').getAttribute('data-data'),
- ).toBe('[{"name":"test"}]');
+ expect(vm.$el.querySelector('.js-issuable-selector').getAttribute('data-data')).toBe(
+ '[{"name":"test"}]',
+ );
});
it('updates formState when changing template', () => {
vm.issuableTemplate.editor.setValue('test new template');
- expect(
- formState.description,
- ).toBe('test new template');
+ expect(formState.description).toBe('test new template');
});
it('returns formState description with editor getValue', () => {
formState.description = 'testing new template';
- expect(
- vm.issuableTemplate.editor.getValue(),
- ).toBe('testing new template');
+ expect(vm.issuableTemplate.editor.getValue()).toBe('testing new template');
});
});
diff --git a/spec/javascripts/issue_show/components/fields/title_spec.js b/spec/javascripts/issue_show/components/fields/title_spec.js
index a03b462689f..4b96a1feb29 100644
--- a/spec/javascripts/issue_show/components/fields/title_spec.js
+++ b/spec/javascripts/issue_show/components/fields/title_spec.js
@@ -27,24 +27,18 @@ describe('Title field component', () => {
});
it('renders form control with formState title', () => {
- expect(
- vm.$el.querySelector('.form-control').value,
- ).toBe('test');
+ expect(vm.$el.querySelector('.form-control').value).toBe('test');
});
it('triggers update with meta+enter', () => {
vm.$el.querySelector('.form-control').dispatchEvent(keyboardDownEvent(13, true));
- expect(
- eventHub.$emit,
- ).toHaveBeenCalled();
+ expect(eventHub.$emit).toHaveBeenCalled();
});
it('triggers update with ctrl+enter', () => {
vm.$el.querySelector('.form-control').dispatchEvent(keyboardDownEvent(13, false, true));
- expect(
- eventHub.$emit,
- ).toHaveBeenCalled();
+ expect(eventHub.$emit).toHaveBeenCalled();
});
});
diff --git a/spec/javascripts/issue_show/components/form_spec.js b/spec/javascripts/issue_show/components/form_spec.js
index eaac1e3536d..523954013cf 100644
--- a/spec/javascripts/issue_show/components/form_spec.js
+++ b/spec/javascripts/issue_show/components/form_spec.js
@@ -4,7 +4,7 @@ import formComponent from '~/issue_show/components/form.vue';
describe('Inline edit form component', () => {
let vm;
- beforeEach((done) => {
+ beforeEach(done => {
const Component = Vue.extend(formComponent);
vm = new Component({
@@ -27,36 +27,28 @@ describe('Inline edit form component', () => {
});
it('does not render template selector if no templates exist', () => {
- expect(
- vm.$el.querySelector('.js-issuable-selector-wrap'),
- ).toBeNull();
+ expect(vm.$el.querySelector('.js-issuable-selector-wrap')).toBeNull();
});
- it('renders template selector when templates exists', (done) => {
+ it('renders template selector when templates exists', done => {
vm.issuableTemplates = ['test'];
Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('.js-issuable-selector-wrap'),
- ).not.toBeNull();
+ expect(vm.$el.querySelector('.js-issuable-selector-wrap')).not.toBeNull();
done();
});
});
it('hides locked warning by default', () => {
- expect(
- vm.$el.querySelector('.alert'),
- ).toBeNull();
+ expect(vm.$el.querySelector('.alert')).toBeNull();
});
- it('shows locked warning if formState is different', (done) => {
+ it('shows locked warning if formState is different', done => {
vm.formState.lockedWarningVisible = true;
Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('.alert'),
- ).not.toBeNull();
+ expect(vm.$el.querySelector('.alert')).not.toBeNull();
done();
});
diff --git a/spec/javascripts/issue_show/components/title_spec.js b/spec/javascripts/issue_show/components/title_spec.js
index 5370f4e1fea..9e6f236b687 100644
--- a/spec/javascripts/issue_show/components/title_spec.js
+++ b/spec/javascripts/issue_show/components/title_spec.js
@@ -86,12 +86,14 @@ describe('Title component', () => {
it('should not show if canUpdate is false', () => {
vm.showInlineEditButton = true;
vm.canUpdate = false;
+
expect(vm.$el.querySelector('.btn-edit')).toBeNull();
});
it('should show if showInlineEditButton and canUpdate', () => {
vm.showInlineEditButton = true;
vm.canUpdate = true;
+
expect(vm.$el.querySelector('.btn-edit')).toBeDefined();
});
@@ -101,6 +103,7 @@ describe('Title component', () => {
Vue.nextTick(() => {
vm.$el.querySelector('.btn-edit').click();
+
expect(eventHub.$emit).toHaveBeenCalledWith('open.form');
});
});
diff --git a/spec/javascripts/issue_spec.js b/spec/javascripts/issue_spec.js
index 62c71e00334..7be495d1d35 100644
--- a/spec/javascripts/issue_spec.js
+++ b/spec/javascripts/issue_spec.js
@@ -15,6 +15,7 @@ describe('Issue', function() {
function expectErrorMessage() {
const $flashMessage = $('div.flash-alert');
+
expect($flashMessage).toExist();
expect($flashMessage).toBeVisible();
expect($flashMessage).toHaveText('Unable to update this issue at this time.');
@@ -23,6 +24,7 @@ describe('Issue', function() {
function expectIssueState(isIssueOpen) {
expectVisibility($boxClosed, !isIssueOpen);
expectVisibility($boxOpen, isIssueOpen);
+
expect($btn).toHaveText(isIssueOpen ? 'Close issue' : 'Reopen issue');
}
@@ -32,6 +34,7 @@ describe('Issue', function() {
}
const $available = Issue.$btnNewBranch.find('.available');
+
expect($available).toHaveText('New branch');
if (!isPending && canCreate) {
@@ -41,6 +44,7 @@ describe('Issue', function() {
}
const $unavailable = Issue.$btnNewBranch.find('.unavailable');
+
expect($unavailable).toHaveText('New branch unavailable');
if (!isPending && !canCreate) {
@@ -60,19 +64,22 @@ describe('Issue', function() {
function findElements(isIssueInitiallyOpen) {
$boxClosed = $('div.status-box-issue-closed');
+
expect($boxClosed).toExist();
expect($boxClosed).toHaveText('Closed');
$boxOpen = $('div.status-box-open');
+
expect($boxOpen).toExist();
expect($boxOpen).toHaveText('Open');
$btn = $('.js-issuable-close-button');
+
expect($btn).toExist();
expect($btn).toHaveText(isIssueInitiallyOpen ? 'Close issue' : 'Reopen issue');
}
- [true, false].forEach((isIssueInitiallyOpen) => {
+ [true, false].forEach(isIssueInitiallyOpen => {
describe(`with ${isIssueInitiallyOpen ? 'open' : 'closed'} issue`, function() {
const action = isIssueInitiallyOpen ? 'close' : 'reopen';
let mock;
@@ -127,7 +134,7 @@ describe('Issue', function() {
it(`${action}s the issue`, function(done) {
mockCloseButtonResponseSuccess(this.$triggeredButton.attr('href'), {
- id: 34
+ id: 34,
});
mockCanCreateBranch(!isIssueInitiallyOpen);
@@ -135,6 +142,7 @@ describe('Issue', function() {
setTimeout(() => {
expectIssueState(!isIssueInitiallyOpen);
+
expect(this.$triggeredButton.get(0).getAttribute('disabled')).toBeNull();
expect(this.$projectIssuesCounter.text()).toBe(isIssueInitiallyOpen ? '1,000' : '1,002');
expectNewBranchButtonState(false, !isIssueInitiallyOpen);
@@ -145,7 +153,7 @@ describe('Issue', function() {
it(`fails to ${action} the issue if saved:false`, function(done) {
mockCloseButtonResponseSuccess(this.$triggeredButton.attr('href'), {
- saved: false
+ saved: false,
});
mockCanCreateBranch(isIssueInitiallyOpen);
@@ -153,8 +161,10 @@ describe('Issue', function() {
setTimeout(() => {
expectIssueState(isIssueInitiallyOpen);
+
expect(this.$triggeredButton.get(0).getAttribute('disabled')).toBeNull();
expectErrorMessage();
+
expect(this.$projectIssuesCounter.text()).toBe('1,001');
expectNewBranchButtonState(false, isIssueInitiallyOpen);
@@ -170,8 +180,10 @@ describe('Issue', function() {
setTimeout(() => {
expectIssueState(isIssueInitiallyOpen);
+
expect(this.$triggeredButton.get(0).getAttribute('disabled')).toBeNull();
expectErrorMessage();
+
expect(this.$projectIssuesCounter.text()).toBe('1,001');
expectNewBranchButtonState(false, isIssueInitiallyOpen);
diff --git a/spec/javascripts/job_spec.js b/spec/javascripts/job_spec.js
index d6b5dec9e47..bc973407b25 100644
--- a/spec/javascripts/job_spec.js
+++ b/spec/javascripts/job_spec.js
@@ -1,295 +1,265 @@
-import $ from 'jquery';
-import MockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
-import { numberToHumanSize } from '~/lib/utils/number_utils';
-import '~/lib/utils/datetime_utility';
-import Job from '~/job';
-import '~/breakpoints';
-import waitForPromises from 'spec/helpers/wait_for_promises';
-
-describe('Job', () => {
- const JOB_URL = `${gl.TEST_HOST}/frontend-fixtures/builds-project/-/jobs/1`;
- let mock;
- let response;
- let job;
-
- preloadFixtures('builds/build-with-artifacts.html.raw');
-
- beforeEach(() => {
- loadFixtures('builds/build-with-artifacts.html.raw');
-
- spyOnDependency(Job, 'visitUrl');
-
- response = {};
-
- mock = new MockAdapter(axios);
-
- mock.onGet(new RegExp(`${JOB_URL}/trace.json?(.*)`)).reply(() => [200, response]);
- });
-
- afterEach(() => {
- mock.restore();
-
- clearTimeout(job.timeout);
- });
-
- describe('class constructor', () => {
- beforeEach(() => {
- jasmine.clock().install();
- });
-
- afterEach(() => {
- jasmine.clock().uninstall();
- });
-
- describe('setup', () => {
- beforeEach(function (done) {
- job = new Job();
-
- waitForPromises()
- .then(done)
- .catch(done.fail);
- });
-
- it('copies build options', function () {
- expect(job.pagePath).toBe(JOB_URL);
- expect(job.buildStatus).toBe('success');
- expect(job.buildStage).toBe('test');
- expect(job.state).toBe('');
- });
- });
-
- describe('running build', () => {
- it('updates the build trace on an interval', function (done) {
- response = {
- html: '<span>Update<span>',
- status: 'running',
- state: 'newstate',
- append: true,
- complete: false,
- };
-
- job = new Job();
-
- waitForPromises()
- .then(() => {
- expect($('#build-trace .js-build-output').text()).toMatch(/Update/);
- expect(job.state).toBe('newstate');
-
- response = {
- html: '<span>More</span>',
- status: 'running',
- state: 'finalstate',
- append: true,
- complete: true,
- };
- })
- .then(() => jasmine.clock().tick(4001))
- .then(waitForPromises)
- .then(() => {
- expect($('#build-trace .js-build-output').text()).toMatch(/UpdateMore/);
- expect(job.state).toBe('finalstate');
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('replaces the entire build trace', (done) => {
- response = {
- html: '<span>Update<span>',
- status: 'running',
- append: false,
- complete: false,
- };
-
- job = new Job();
-
- waitForPromises()
- .then(() => {
- expect($('#build-trace .js-build-output').text()).toMatch(/Update/);
-
- response = {
- html: '<span>Different</span>',
- status: 'running',
- append: false,
- };
- })
- .then(() => jasmine.clock().tick(4001))
- .then(waitForPromises)
- .then(() => {
- expect($('#build-trace .js-build-output').text()).not.toMatch(/Update/);
- expect($('#build-trace .js-build-output').text()).toMatch(/Different/);
- })
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('truncated information', () => {
- describe('when size is less than total', () => {
- it('shows information about truncated log', (done) => {
- response = {
- html: '<span>Update</span>',
- status: 'success',
- append: false,
- size: 50,
- total: 100,
- };
-
- job = new Job();
-
- waitForPromises()
- .then(() => {
- expect(document.querySelector('.js-truncated-info').classList).not.toContain('hidden');
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('shows the size in KiB', (done) => {
- const size = 50;
-
- response = {
- html: '<span>Update</span>',
- status: 'success',
- append: false,
- size,
- total: 100,
- };
-
- job = new Job();
-
- waitForPromises()
- .then(() => {
- expect(
- document.querySelector('.js-truncated-info-size').textContent.trim(),
- ).toEqual(`${numberToHumanSize(size)}`);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('shows incremented size', (done) => {
- response = {
- html: '<span>Update</span>',
- status: 'success',
- append: false,
- size: 50,
- total: 100,
- complete: false,
- };
-
- job = new Job();
-
- waitForPromises()
- .then(() => {
- expect(
- document.querySelector('.js-truncated-info-size').textContent.trim(),
- ).toEqual(`${numberToHumanSize(50)}`);
-
- response = {
- html: '<span>Update</span>',
- status: 'success',
- append: true,
- size: 10,
- total: 100,
- complete: true,
- };
- })
- .then(() => jasmine.clock().tick(4001))
- .then(waitForPromises)
- .then(() => {
- expect(
- document.querySelector('.js-truncated-info-size').textContent.trim(),
- ).toEqual(`${numberToHumanSize(60)}`);
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('renders the raw link', () => {
- response = {
- html: '<span>Update</span>',
- status: 'success',
- append: false,
- size: 50,
- total: 100,
- };
-
- job = new Job();
-
- expect(
- document.querySelector('.js-raw-link').textContent.trim(),
- ).toContain('Complete Raw');
- });
- });
-
- describe('when size is equal than total', () => {
- it('does not show the trunctated information', (done) => {
- response = {
- html: '<span>Update</span>',
- status: 'success',
- append: false,
- size: 100,
- total: 100,
- };
-
- job = new Job();
-
- waitForPromises()
- .then(() => {
- expect(document.querySelector('.js-truncated-info').classList).toContain('hidden');
- })
- .then(done)
- .catch(done.fail);
- });
- });
- });
-
- describe('output trace', () => {
- beforeEach((done) => {
- response = {
- html: '<span>Update</span>',
- status: 'success',
- append: false,
- size: 50,
- total: 100,
- };
-
- job = new Job();
-
- waitForPromises()
- .then(done)
- .catch(done.fail);
- });
-
- it('should render trace controls', () => {
- const controllers = document.querySelector('.controllers');
-
- expect(controllers.querySelector('.js-raw-link-controller')).not.toBeNull();
- expect(controllers.querySelector('.js-scroll-up')).not.toBeNull();
- expect(controllers.querySelector('.js-scroll-down')).not.toBeNull();
- });
-
- it('should render received output', () => {
- expect(
- document.querySelector('.js-build-output').innerHTML,
- ).toEqual('<span>Update</span>');
- });
- });
- });
-
- describe('getBuildTrace', () => {
- it('should request build trace with state parameter', (done) => {
- spyOn(axios, 'get').and.callThrough();
- job = new Job();
-
- setTimeout(() => {
- expect(axios.get).toHaveBeenCalledWith(
- `${JOB_URL}/trace.json`, { params: { state: '' } },
- );
- done();
- }, 0);
- });
- });
-});
+// import $ from 'jquery';
+// import MockAdapter from 'axios-mock-adapter';
+// import axios from '~/lib/utils/axios_utils';
+// import { numberToHumanSize } from '~/lib/utils/number_utils';
+// import '~/lib/utils/datetime_utility';
+// import Job from '~/job';
+// import '~/breakpoints';
+// import waitForPromises from 'spec/helpers/wait_for_promises';
+
+// describe('Job', () => {
+// const JOB_URL = `${gl.TEST_HOST}/frontend-fixtures/builds-project/-/jobs/1`;
+// let mock;
+// let response;
+// let job;
+
+// preloadFixtures('builds/build-with-artifacts.html.raw');
+
+// beforeEach(() => {
+// loadFixtures('builds/build-with-artifacts.html.raw');
+
+// spyOnDependency(Job, 'visitUrl');
+
+// response = {};
+
+// mock = new MockAdapter(axios);
+
+// mock.onGet(new RegExp(`${JOB_URL}/trace.json?(.*)`)).reply(() => [200, response]);
+// });
+
+// afterEach(() => {
+// mock.restore();
+
+// clearTimeout(job.timeout);
+// });
+
+// describe('class constructor', () => {
+// beforeEach(() => {
+// jasmine.clock().install();
+// });
+
+// afterEach(() => {
+// jasmine.clock().uninstall();
+// });
+
+// describe('running build', () => {
+// it('updates the build trace on an interval', function (done) {
+// response = {
+// html: '<span>Update<span>',
+// status: 'running',
+// state: 'newstate',
+// append: true,
+// complete: false,
+// };
+
+// job = new Job();
+
+// waitForPromises()
+// .then(() => {
+// expect($('#build-trace .js-build-output').text()).toMatch(/Update/);
+// expect(job.state).toBe('newstate');
+
+// response = {
+// html: '<span>More</span>',
+// status: 'running',
+// state: 'finalstate',
+// append: true,
+// complete: true,
+// };
+// })
+// .then(() => jasmine.clock().tick(4001))
+// .then(waitForPromises)
+// .then(() => {
+// expect($('#build-trace .js-build-output').text()).toMatch(/UpdateMore/);
+// expect(job.state).toBe('finalstate');
+// })
+// .then(done)
+// .catch(done.fail);
+// });
+
+// it('replaces the entire build trace', (done) => {
+// response = {
+// html: '<span>Update<span>',
+// status: 'running',
+// append: false,
+// complete: false,
+// };
+
+// job = new Job();
+
+// waitForPromises()
+// .then(() => {
+// expect($('#build-trace .js-build-output').text()).toMatch(/Update/);
+
+// response = {
+// html: '<span>Different</span>',
+// status: 'running',
+// append: false,
+// };
+// })
+// .then(() => jasmine.clock().tick(4001))
+// .then(waitForPromises)
+// .then(() => {
+// expect($('#build-trace .js-build-output').text()).not.toMatch(/Update/);
+// expect($('#build-trace .js-build-output').text()).toMatch(/Different/);
+// })
+// .then(done)
+// .catch(done.fail);
+// });
+// });
+
+// describe('truncated information', () => {
+// describe('when size is less than total', () => {
+// it('shows information about truncated log', (done) => {
+// response = {
+// html: '<span>Update</span>',
+// status: 'success',
+// append: false,
+// size: 50,
+// total: 100,
+// };
+
+// job = new Job();
+
+// waitForPromises()
+// .then(() => {
+// expect(document.querySelector('.js-truncated-info').classList).not.toContain('hidden');
+// })
+// .then(done)
+// .catch(done.fail);
+// });
+
+// it('shows the size in KiB', (done) => {
+// const size = 50;
+
+// response = {
+// html: '<span>Update</span>',
+// status: 'success',
+// append: false,
+// size,
+// total: 100,
+// };
+
+// job = new Job();
+
+// waitForPromises()
+// .then(() => {
+// expect(
+// document.querySelector('.js-truncated-info-size').textContent.trim(),
+// ).toEqual(`${numberToHumanSize(size)}`);
+// })
+// .then(done)
+// .catch(done.fail);
+// });
+
+// it('shows incremented size', (done) => {
+// response = {
+// html: '<span>Update</span>',
+// status: 'success',
+// append: false,
+// size: 50,
+// total: 100,
+// complete: false,
+// };
+
+// job = new Job();
+
+// waitForPromises()
+// .then(() => {
+// expect(
+// document.querySelector('.js-truncated-info-size').textContent.trim(),
+// ).toEqual(`${numberToHumanSize(50)}`);
+
+// response = {
+// html: '<span>Update</span>',
+// status: 'success',
+// append: true,
+// size: 10,
+// total: 100,
+// complete: true,
+// };
+// })
+// .then(() => jasmine.clock().tick(4001))
+// .then(waitForPromises)
+// .then(() => {
+// expect(
+// document.querySelector('.js-truncated-info-size').textContent.trim(),
+// ).toEqual(`${numberToHumanSize(60)}`);
+// })
+// .then(done)
+// .catch(done.fail);
+// });
+
+// it('renders the raw link', () => {
+// response = {
+// html: '<span>Update</span>',
+// status: 'success',
+// append: false,
+// size: 50,
+// total: 100,
+// };
+
+// job = new Job();
+
+// expect(
+// document.querySelector('.js-raw-link').textContent.trim(),
+// ).toContain('Complete Raw');
+// });
+// });
+
+// describe('when size is equal than total', () => {
+// it('does not show the trunctated information', (done) => {
+// response = {
+// html: '<span>Update</span>',
+// status: 'success',
+// append: false,
+// size: 100,
+// total: 100,
+// };
+
+// job = new Job();
+
+// waitForPromises()
+// .then(() => {
+// expect(document.querySelector('.js-truncated-info').classList).toContain('hidden');
+// })
+// .then(done)
+// .catch(done.fail);
+// });
+// });
+// });
+
+// describe('output trace', () => {
+// beforeEach((done) => {
+// response = {
+// html: '<span>Update</span>',
+// status: 'success',
+// append: false,
+// size: 50,
+// total: 100,
+// };
+
+// job = new Job();
+
+// waitForPromises()
+// .then(done)
+// .catch(done.fail);
+// });
+
+// it('should render trace controls', () => {
+// const controllers = document.querySelector('.controllers');
+
+// expect(controllers.querySelector('.js-raw-link-controller')).not.toBeNull();
+// expect(controllers.querySelector('.js-scroll-up')).not.toBeNull();
+// expect(controllers.querySelector('.js-scroll-down')).not.toBeNull();
+// });
+
+// it('should render received output', () => {
+// expect(
+// document.querySelector('.js-build-output').innerHTML,
+// ).toEqual('<span>Update</span>');
+// });
+// });
+// });
+
+// });
diff --git a/spec/javascripts/jobs/components/commit_block_spec.js b/spec/javascripts/jobs/components/commit_block_spec.js
index 0bcc4ff940f..98eba3ac976 100644
--- a/spec/javascripts/jobs/components/commit_block_spec.js
+++ b/spec/javascripts/jobs/components/commit_block_spec.js
@@ -34,6 +34,7 @@ describe('Commit block', () => {
expect(vm.$el.querySelector('.js-commit-sha').getAttribute('href')).toEqual(
props.commit.commit_path,
);
+
expect(vm.$el.querySelector('.js-commit-sha').textContent.trim()).toEqual(
props.commit.short_id,
);
@@ -55,6 +56,7 @@ describe('Commit block', () => {
expect(vm.$el.querySelector('.js-link-commit').getAttribute('href')).toEqual(
props.mergeRequest.path,
);
+
expect(vm.$el.querySelector('.js-link-commit').textContent.trim()).toEqual(
`!${props.mergeRequest.iid}`,
);
diff --git a/spec/javascripts/jobs/components/empty_state_spec.js b/spec/javascripts/jobs/components/empty_state_spec.js
index 73488eaab9b..0a39709221c 100644
--- a/spec/javascripts/jobs/components/empty_state_spec.js
+++ b/spec/javascripts/jobs/components/empty_state_spec.js
@@ -56,6 +56,7 @@ describe('Empty State', () => {
vm = mountComponent(Component, {
...props,
});
+
expect(vm.$el.querySelector('.js-job-empty-state-content')).toBeNull();
});
});
@@ -84,6 +85,7 @@ describe('Empty State', () => {
...props,
content,
});
+
expect(vm.$el.querySelector('.js-job-empty-state-action')).toBeNull();
});
});
diff --git a/spec/javascripts/jobs/components/environments_block_spec.js b/spec/javascripts/jobs/components/environments_block_spec.js
index 7d836129b13..0866ddd21d8 100644
--- a/spec/javascripts/jobs/components/environments_block_spec.js
+++ b/spec/javascripts/jobs/components/environments_block_spec.js
@@ -54,6 +54,7 @@ describe('Environments block', () => {
expect(vm.$el.textContent.trim()).toEqual(
'This job is an out-of-date deployment to environment. View the most recent deployment #deployment.',
);
+
expect(vm.$el.querySelector('.js-job-deployment-link').getAttribute('href')).toEqual('bar');
});
});
@@ -110,6 +111,7 @@ describe('Environments block', () => {
expect(vm.$el.textContent.trim()).toEqual(
'This job is creating a deployment to environment and will overwrite the latest deployment.',
);
+
expect(vm.$el.querySelector('.js-job-deployment-link').getAttribute('href')).toEqual('foo');
});
});
@@ -139,6 +141,7 @@ describe('Environments block', () => {
},
iconStatus: status,
});
+
expect(vm.$el.querySelector('.js-environment-link')).toBeNull();
});
});
diff --git a/spec/javascripts/jobs/components/job_app_spec.js b/spec/javascripts/jobs/components/job_app_spec.js
index e02eb9723fe..288c06d6615 100644
--- a/spec/javascripts/jobs/components/job_app_spec.js
+++ b/spec/javascripts/jobs/components/job_app_spec.js
@@ -1,75 +1,247 @@
import Vue from 'vue';
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
import jobApp from '~/jobs/components/job_app.vue';
import createStore from '~/jobs/store';
import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+import { resetStore } from '../store/helpers';
+import job from '../mock_data';
describe('Job App ', () => {
const Component = Vue.extend(jobApp);
let store;
let vm;
-
- const threeWeeksAgo = new Date();
- threeWeeksAgo.setDate(threeWeeksAgo.getDate() - 21);
-
- const twoDaysAgo = new Date();
- twoDaysAgo.setDate(twoDaysAgo.getDate() - 2);
-
- const job = {
- status: {
- group: 'failed',
- icon: 'status_failed',
- label: 'failed',
- text: 'failed',
- details_path: 'path',
- },
- id: 123,
- created_at: threeWeeksAgo.toISOString(),
- user: {
- web_url: 'path',
- name: 'Foo',
- username: 'foobar',
- email: 'foo@bar.com',
- avatar_url: 'link',
- },
- started: twoDaysAgo.toISOString(),
- new_issue_path: 'path',
- runners: {
- available: false,
- },
- tags: ['docker'],
- has_trace: true,
- };
+ let mock;
const props = {
- runnerHelpUrl: 'help/runners',
+ endpoint: `${gl.TEST_HOST}jobs/123.json`,
+ runnerHelpUrl: 'help/runner',
+ runnerSettingsUrl: 'settings/ci-cd/runners',
+ terminalPath: 'jobs/123/terminal',
+ pagePath: `${gl.TEST_HOST}jobs/123`,
+ logState:
+ 'eyJvZmZzZXQiOjE3NDUxLCJuX29wZW5fdGFncyI6MCwiZmdfY29sb3IiOm51bGwsImJnX2NvbG9yIjpudWxsLCJzdHlsZV9tYXNrIjowfQ%3D%3D',
};
beforeEach(() => {
+ mock = new MockAdapter(axios);
store = createStore();
});
afterEach(() => {
+ resetStore(store);
vm.$destroy();
+ mock.restore();
});
- describe('Header section', () => {
- describe('job callout message', () => {
- it('should not render the reason when reason is absent', () => {
- store.dispatch('receiveJobSuccess', job);
+ describe('while loading', () => {
+ beforeEach(() => {
+ mock.onGet(props.endpoint).reply(200, job, {});
+ mock.onGet(`${props.pagePath}/trace.json`).reply(200, {});
+ vm = mountComponentWithStore(Component, { props, store });
+ });
- vm = mountComponentWithStore(Component, {
- props,
- store,
+ it('renders loading icon', done => {
+ expect(vm.$el.querySelector('.js-job-loading')).not.toBeNull();
+ expect(vm.$el.querySelector('.js-job-sidebar')).toBeNull();
+ expect(vm.$el.querySelector('.js-job-content')).toBeNull();
+
+ setTimeout(() => {
+ done();
+ }, 0);
+ });
+ });
+
+ describe('with successfull request', () => {
+ beforeEach(() => {
+ mock.onGet(`${props.pagePath}/trace.json`).replyOnce(200, {});
+ });
+
+ describe('Header section', () => {
+ describe('job callout message', () => {
+ it('should not render the reason when reason is absent', done => {
+ mock.onGet(props.endpoint).replyOnce(200, job);
+ vm = mountComponentWithStore(Component, { props, store });
+
+ setTimeout(() => {
+ expect(vm.shouldRenderCalloutMessage).toBe(false);
+
+ done();
+ }, 0);
+ });
+
+ it('should render the reason when reason is present', done => {
+ mock.onGet(props.endpoint).replyOnce(
+ 200,
+ Object.assign({}, job, {
+ callout_message: 'There is an unknown failure, please try again',
+ }),
+ );
+
+ vm = mountComponentWithStore(Component, { props, store });
+ setTimeout(() => {
+ expect(vm.shouldRenderCalloutMessage).toBe(true);
+ done();
+ }, 0);
+ });
+ });
+
+ describe('triggered job', () => {
+ beforeEach(() => {
+ mock
+ .onGet(props.endpoint)
+ .replyOnce(200, Object.assign({}, job, { started: '2017-05-24T10:59:52.000+01:00' }));
+ vm = mountComponentWithStore(Component, { props, store });
+ });
+
+ it('should render provided job information', done => {
+ setTimeout(() => {
+ expect(
+ vm.$el
+ .querySelector('.header-main-content')
+ .textContent.replace(/\s+/g, ' ')
+ .trim(),
+ ).toEqual('passed Job #4757 triggered 1 year ago by Root');
+ done();
+ }, 0);
+ });
+
+ it('should render new issue link', done => {
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-new-issue').getAttribute('href')).toEqual(
+ job.new_issue_path,
+ );
+ done();
+ }, 0);
+ });
+ });
+
+ describe('created job', () => {
+ it('should render created key', done => {
+ mock.onGet(props.endpoint).replyOnce(200, job);
+ vm = mountComponentWithStore(Component, { props, store });
+
+ setTimeout(() => {
+ expect(
+ vm.$el
+ .querySelector('.header-main-content')
+ .textContent.replace(/\s+/g, ' ')
+ .trim(),
+ ).toEqual('passed Job #4757 created 3 weeks ago by Root');
+ done();
+ }, 0);
+ });
+ });
+ });
+
+ describe('stuck block', () => {
+ describe('without active runners availabl', () => {
+ it('renders stuck block when there are no runners', done => {
+ mock.onGet(props.endpoint).replyOnce(
+ 200,
+ Object.assign({}, job, {
+ status: {
+ group: 'pending',
+ icon: 'status_pending',
+ label: 'pending',
+ text: 'pending',
+ details_path: 'path',
+ },
+ stuck: true,
+ runners: {
+ available: false,
+ online: false,
+ },
+ tags: [],
+ }),
+ );
+ vm = mountComponentWithStore(Component, { props, store });
+
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-job-stuck')).not.toBeNull();
+ expect(vm.$el.querySelector('.js-job-stuck').textContent).toContain(
+ "This job is stuck, because you don't have any active runners that can run this job.",
+ );
+ done();
+ }, 0);
+ });
+ });
+
+ describe('when available runners can not run specified tag', () => {
+ it('renders tags in stuck block when there are no runners', done => {
+ mock.onGet(props.endpoint).replyOnce(
+ 200,
+ Object.assign({}, job, {
+ status: {
+ group: 'pending',
+ icon: 'status_pending',
+ label: 'pending',
+ text: 'pending',
+ details_path: 'path',
+ },
+ stuck: true,
+ runners: {
+ available: false,
+ online: false,
+ },
+ }),
+ );
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
+
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-job-stuck').textContent).toContain(job.tags[0]);
+ expect(vm.$el.querySelector('.js-job-stuck').textContent).toContain(
+ "This job is stuck, because you don't have any active runners online with any of these tags assigned to them:",
+ );
+ done();
+ }, 0);
});
+ });
- expect(vm.shouldRenderCalloutMessage).toBe(false);
+ describe('when runners are offline and build has tags', () => {
+ it('renders message about job being stuck because of no runners with the specified tags', done => {
+ mock.onGet(props.endpoint).replyOnce(
+ 200,
+ Object.assign({}, job, {
+ status: {
+ group: 'pending',
+ icon: 'status_pending',
+ label: 'pending',
+ text: 'pending',
+ details_path: 'path',
+ },
+ stuck: true,
+ runners: {
+ available: true,
+ online: true,
+ },
+ }),
+ );
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
+
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-job-stuck').textContent).toContain(job.tags[0]);
+ expect(vm.$el.querySelector('.js-job-stuck').textContent).toContain(
+ "This job is stuck, because you don't have any active runners online with any of these tags assigned to them:",
+ );
+ done();
+ }, 0);
+ })
});
- it('should render the reason when reason is present', () => {
- store.dispatch(
- 'receiveJobSuccess',
+ it('does not renders stuck block when there are no runners', done => {
+ mock.onGet(props.endpoint).replyOnce(
+ 200,
Object.assign({}, job, {
- callout_message: 'There is an unknown failure, please try again',
+ runners: { available: true },
}),
);
@@ -78,247 +250,325 @@ describe('Job App ', () => {
store,
});
- expect(vm.shouldRenderCalloutMessage).toBe(true);
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-job-stuck')).toBeNull();
+
+ done();
+ }, 0);
});
});
- describe('triggered job', () => {
- beforeEach(() => {
- store.dispatch('receiveJobSuccess', job);
+ describe('environments block', () => {
+ it('renders environment block when job has environment', done => {
+ mock.onGet(props.endpoint).replyOnce(
+ 200,
+ Object.assign({}, job, {
+ deployment_status: {
+ environment: {
+ environment_path: '/path',
+ name: 'foo',
+ },
+ },
+ }),
+ );
vm = mountComponentWithStore(Component, {
props,
store,
});
- });
- it('should render provided job information', () => {
- expect(
- vm.$el
- .querySelector('.header-main-content')
- .textContent.replace(/\s+/g, ' ')
- .trim(),
- ).toEqual('failed Job #123 triggered 2 days ago by Foo');
- });
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-job-environment')).not.toBeNull();
- it('should render new issue link', () => {
- expect(vm.$el.querySelector('.js-new-issue').getAttribute('href')).toEqual(
- job.new_issue_path,
- );
+ done();
+ }, 0);
});
- });
- describe('created job', () => {
- it('should render created key', () => {
- store.dispatch('receiveJobSuccess', Object.assign({}, job, { started: false }));
+ it('does not render environment block when job has environment', done => {
+ mock.onGet(props.endpoint).replyOnce(200, job);
vm = mountComponentWithStore(Component, {
props,
store,
});
- expect(
- vm.$el
- .querySelector('.header-main-content')
- .textContent.replace(/\s+/g, ' ')
- .trim(),
- ).toEqual('failed Job #123 created 3 weeks ago by Foo');
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-job-environment')).toBeNull();
+ done();
+ }, 0);
});
});
- });
- describe('stuck block', () => {
- it('renders stuck block when there are no runners', () => {
- store.dispatch(
- 'receiveJobSuccess',
- Object.assign({}, job, {
- status: {
- group: 'pending',
- icon: 'status_pending',
- label: 'pending',
- text: 'pending',
- details_path: 'path',
- },
- }),
- );
-
- vm = mountComponentWithStore(Component, {
- props,
- store,
- });
+ describe('erased block', () => {
+ it('renders erased block when `erased` is true', done => {
+ mock.onGet(props.endpoint).replyOnce(
+ 200,
+ Object.assign({}, job, {
+ erased_by: {
+ username: 'root',
+ web_url: 'gitlab.com/root',
+ },
+ erased_at: '2016-11-07T11:11:16.525Z',
+ }),
+ );
- expect(vm.$el.querySelector('.js-job-stuck')).not.toBeNull();
- });
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
+
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-job-erased-block')).not.toBeNull();
- it('renders tags in stuck block when there are no runners', () => {
- store.dispatch(
- 'receiveJobSuccess',
- Object.assign({}, job, {
- status: {
- group: 'pending',
- icon: 'status_pending',
- label: 'pending',
- text: 'pending',
- details_path: 'path',
- },
- }),
- );
-
- vm = mountComponentWithStore(Component, {
- props,
- store,
+ done();
+ }, 0);
});
- expect(vm.$el.querySelector('.js-job-stuck').textContent).toContain(job.tags[0]);
- });
+ it('does not render erased block when `erased` is false', done => {
+ mock.onGet(props.endpoint).replyOnce(200, Object.assign({}, job, { erased_at: null }));
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
- it(' does not renders stuck block when there are no runners', () => {
- store.dispatch('receiveJobSuccess', Object.assign({}, job, { runners: { available: true } }));
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-job-erased-block')).toBeNull();
- vm = mountComponentWithStore(Component, {
- props,
- store,
+ done();
+ }, 0);
});
-
- expect(vm.$el.querySelector('.js-job-stuck')).toBeNull();
});
- });
- describe('environments block', () => {
- it('renders environment block when job has environment', () => {
- store.dispatch(
- 'receiveJobSuccess',
- Object.assign({}, job, {
- deployment_status: {
- environment: {
- environment_path: '/path',
- name: 'foo',
+ describe('empty states block', () => {
+ it('renders empty state when job does not have trace and is not running', done => {
+ mock.onGet(props.endpoint).replyOnce(
+ 200,
+ Object.assign({}, job, {
+ has_trace: false,
+ status: {
+ group: 'pending',
+ icon: 'status_pending',
+ label: 'pending',
+ text: 'pending',
+ details_path: 'path',
+ illustration: {
+ image: 'path',
+ size: '340',
+ title: 'Empty State',
+ content: 'This is an empty state',
+ },
+ action: {
+ button_title: 'Retry job',
+ method: 'post',
+ path: '/path',
+ },
},
- },
- }),
- );
+ }),
+ );
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
- vm = mountComponentWithStore(Component, {
- props,
- store,
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-job-empty-state')).not.toBeNull();
+
+ done();
+ }, 0);
});
- expect(vm.$el.querySelector('.js-job-environment')).not.toBeNull();
- });
+ it('does not render empty state when job does not have trace but it is running', done => {
+ mock.onGet(props.endpoint).replyOnce(
+ 200,
+ Object.assign({}, job, {
+ has_trace: false,
+ status: {
+ group: 'running',
+ icon: 'status_running',
+ label: 'running',
+ text: 'running',
+ details_path: 'path',
+ },
+ }),
+ );
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
- it('does not render environment block when job has environment', () => {
- store.dispatch('receiveJobSuccess', job);
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-job-empty-state')).toBeNull();
- vm = mountComponentWithStore(Component, {
- props,
- store,
+ done();
+ }, 0);
});
- expect(vm.$el.querySelector('.js-job-environment')).toBeNull();
- });
- });
+ it('does not render empty state when job has trace but it is not running', done => {
+ mock.onGet(props.endpoint).replyOnce(200, Object.assign({}, job, { has_trace: true }));
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
- describe('erased block', () => {
- it('renders erased block when `erased` is true', () => {
- store.dispatch(
- 'receiveJobSuccess',
- Object.assign({}, job, {
- erased: true,
- erased_by: {
- username: 'root',
- web_url: 'gitlab.com/root',
- },
- erased_at: '2016-11-07T11:11:16.525Z',
- }),
- );
-
- vm = mountComponentWithStore(Component, {
- props,
- store,
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-job-empty-state')).toBeNull();
+
+ done();
+ }, 0);
});
+ });
+ });
- expect(vm.$el.querySelector('.js-job-erased')).not.toBeNull();
+ describe('trace output', () => {
+ beforeEach(() => {
+ mock.onGet(props.endpoint).reply(200, job, {});
});
- it('does not render erased block when `erased` is false', () => {
- store.dispatch('receiveJobSuccess', Object.assign({}, job, { erased: false }));
+ describe('with append flag', () => {
+ it('appends the log content to the existing one', done => {
+ mock.onGet(`${props.pagePath}/trace.json`).reply(200, {
+ html: '<span>More<span>',
+ status: 'running',
+ state: 'newstate',
+ append: true,
+ complete: true,
+ });
- vm = mountComponentWithStore(Component, {
- props,
- store,
- });
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
- expect(vm.$el.querySelector('.js-job-erased')).toBeNull();
- });
- });
+ vm.$store.state.trace = 'Update';
- describe('empty states block', () => {
- it('renders empty state when job does not have trace and is not running', () => {
- store.dispatch(
- 'receiveJobSuccess',
- Object.assign({}, job, {
- has_trace: false,
- status: {
- group: 'pending',
- icon: 'status_pending',
- label: 'pending',
- text: 'pending',
- details_path: 'path',
- illustration: {
- image: 'path',
- size: '340',
- title: 'Empty State',
- content: 'This is an empty state',
- },
- action: {
- button_title: 'Retry job',
- method: 'post',
- path: '/path',
- },
- },
- }),
- );
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-build-trace').textContent.trim()).toContain('Update');
- vm = mountComponentWithStore(Component, {
- props,
- store,
+ done();
+ }, 0);
});
+ });
+
+ describe('without append flag', () => {
+ it('replaces the trace', done => {
+ mock.onGet(`${props.pagePath}/trace.json`).reply(200, {
+ html: '<span>Different<span>',
+ status: 'running',
+ append: false,
+ complete: true,
+ });
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
+ vm.$store.state.trace = 'Update';
+
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-build-trace').textContent.trim()).not.toContain(
+ 'Update',
+ );
- expect(vm.$el.querySelector('.js-job-empty-state')).not.toBeNull();
+ expect(vm.$el.querySelector('.js-build-trace').textContent.trim()).toContain('Different');
+ done();
+ }, 0);
+ });
});
- it('does not render empty state when job does not have trace but it is running', () => {
- store.dispatch(
- 'receiveJobSuccess',
- Object.assign({}, job, {
- has_trace: false,
- status: {
- group: 'running',
- icon: 'status_running',
- label: 'running',
- text: 'running',
- details_path: 'path',
- },
- }),
- );
-
- vm = mountComponentWithStore(Component, {
- props,
- store,
+ describe('truncated information', () => {
+ describe('when size is less than total', () => {
+ it('shows information about truncated log', done => {
+ mock.onGet(`${props.pagePath}/trace.json`).reply(200, {
+ html: '<span>Update</span>',
+ status: 'success',
+ append: false,
+ size: 50,
+ total: 100,
+ complete: true,
+ });
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
+
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-truncated-info').textContent.trim()).toContain(
+ '50 bytes',
+ );
+ done();
+ }, 0);
+ });
});
- expect(vm.$el.querySelector('.js-job-empty-state')).toBeNull();
+ describe('when size is equal than total', () => {
+ it('does not show the truncated information', done => {
+ mock.onGet(`${props.pagePath}/trace.json`).reply(200, {
+ html: '<span>Update</span>',
+ status: 'success',
+ append: false,
+ size: 100,
+ total: 100,
+ complete: true,
+ });
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
+
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-truncated-info').textContent.trim()).not.toContain(
+ '50 bytes',
+ );
+ done();
+ }, 0);
+ });
+ });
});
- it('does not render empty state when job has trace but it is not running', () => {
- store.dispatch('receiveJobSuccess', Object.assign({}, job, { has_trace: true }));
+ describe('trace controls', () => {
+ beforeEach(() => {
+ mock.onGet(`${props.pagePath}/trace.json`).reply(200, {
+ html: '<span>Update</span>',
+ status: 'success',
+ append: false,
+ size: 50,
+ total: 100,
+ complete: true,
+ });
- vm = mountComponentWithStore(Component, {
- props,
- store,
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
+ });
+
+ it('should render scroll buttons', done => {
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-scroll-top')).not.toBeNull();
+ expect(vm.$el.querySelector('.js-scroll-bottom')).not.toBeNull();
+ done();
+ }, 0);
});
- expect(vm.$el.querySelector('.js-job-empty-state')).toBeNull();
+ it('should render link to raw ouput', done => {
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-raw-link-controller')).not.toBeNull();
+ done();
+ }, 0);
+ });
+
+ it('should render link to erase job', done => {
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-erase-link')).not.toBeNull();
+ done();
+ }, 0);
+ });
});
});
});
diff --git a/spec/javascripts/jobs/components/job_container_item_spec.js b/spec/javascripts/jobs/components/job_container_item_spec.js
new file mode 100644
index 00000000000..8588eda19c8
--- /dev/null
+++ b/spec/javascripts/jobs/components/job_container_item_spec.js
@@ -0,0 +1,73 @@
+import Vue from 'vue';
+import JobContainerItem from '~/jobs/components/job_container_item.vue';
+import mountComponent from 'spec/helpers/vue_mount_component_helper';
+import job from '../mock_data';
+
+describe('JobContainerItem', () => {
+ const Component = Vue.extend(JobContainerItem);
+ let vm;
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ const sharedTests = () => {
+ it('displays a status icon', () => {
+ expect(vm.$el).toHaveSpriteIcon(job.status.icon);
+ });
+
+ it('displays the job name', () => {
+ expect(vm.$el).toContainText(job.name);
+ });
+
+ it('displays a link to the job', () => {
+ const link = vm.$el.querySelector('.js-job-link');
+
+ expect(link.href).toBe(job.status.details_path);
+ });
+ };
+
+ describe('when a job is not active and not retied', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ job,
+ isActive: false,
+ });
+ });
+
+ sharedTests();
+ });
+
+ describe('when a job is active', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ job,
+ isActive: true,
+ });
+ });
+
+ sharedTests();
+
+ it('displays an arrow', () => {
+ expect(vm.$el).toHaveSpriteIcon('arrow-right');
+ });
+ });
+
+ describe('when a job is retried', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ job: {
+ ...job,
+ retried: true,
+ },
+ isActive: false,
+ });
+ });
+
+ sharedTests();
+
+ it('displays an icon', () => {
+ expect(vm.$el).toHaveSpriteIcon('retry');
+ });
+ });
+});
diff --git a/spec/javascripts/jobs/components/job_log_controllers_spec.js b/spec/javascripts/jobs/components/job_log_controllers_spec.js
index 099aca602c4..d527c6708fc 100644
--- a/spec/javascripts/jobs/components/job_log_controllers_spec.js
+++ b/spec/javascripts/jobs/components/job_log_controllers_spec.js
@@ -25,6 +25,7 @@ describe('Job log controllers', () => {
beforeEach(() => {
vm = mountComponent(Component, props);
});
+
it('renders size information', () => {
expect(vm.$el.querySelector('.js-truncated-info').textContent).toContain('499.95 KiB');
});
@@ -198,6 +199,7 @@ describe('Job log controllers', () => {
isScrollingDown: false,
isTraceSizeVisible: true,
});
+
expect(vm.$el.querySelector('.js-scroll-bottom').className).not.toContain('animate');
});
});
diff --git a/spec/javascripts/jobs/components/job_log_spec.js b/spec/javascripts/jobs/components/job_log_spec.js
index 1011512360d..dc0f77ceb80 100644
--- a/spec/javascripts/jobs/components/job_log_spec.js
+++ b/spec/javascripts/jobs/components/job_log_spec.js
@@ -1,31 +1,48 @@
import Vue from 'vue';
import component from '~/jobs/components/job_log.vue';
-import mountComponent from '../../helpers/vue_mount_component_helper';
+import createStore from '~/jobs/store';
+import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+import { resetStore } from '../store/helpers';
describe('Job Log', () => {
const Component = Vue.extend(component);
+ let store;
let vm;
- const trace = 'Running with gitlab-runner 11.1.0 (081978aa)<br> on docker-auto-scale-com d5ae8d25<br>Using Docker executor with image dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.4.4-golang-1.9-git-2.18-chrome-67.0-node-8.x-yarn-1.2-postgresql-9.6-graphicsmagick-1.3.29 ...<br>';
+ const trace =
+ 'Running with gitlab-runner 11.1.0 (081978aa)<br> on docker-auto-scale-com d5ae8d25<br>Using Docker executor with image dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.4.4-golang-1.9-git-2.18-chrome-67.0-node-8.x-yarn-1.2-postgresql-9.6-graphicsmagick-1.3.29 ...<br>';
+
+ beforeEach(() => {
+ store = createStore();
+ });
afterEach(() => {
+ resetStore(store);
vm.$destroy();
});
it('renders provided trace', () => {
- vm = mountComponent(Component, {
- trace,
- isComplete: true,
+ vm = mountComponentWithStore(Component, {
+ props: {
+ trace,
+ isComplete: true,
+ },
+ store,
});
- expect(vm.$el.querySelector('code').textContent).toContain('Running with gitlab-runner 11.1.0 (081978aa)');
+ expect(vm.$el.querySelector('code').textContent).toContain(
+ 'Running with gitlab-runner 11.1.0 (081978aa)',
+ );
});
describe('while receiving trace', () => {
it('renders animation', () => {
- vm = mountComponent(Component, {
- trace,
- isComplete: true,
+ vm = mountComponentWithStore(Component, {
+ props: {
+ trace,
+ isComplete: false,
+ },
+ store,
});
expect(vm.$el.querySelector('.js-log-animation')).not.toBeNull();
@@ -34,9 +51,12 @@ describe('Job Log', () => {
describe('when build trace has finishes', () => {
it('does not render animation', () => {
- vm = mountComponent(Component, {
- trace,
- isComplete: false,
+ vm = mountComponentWithStore(Component, {
+ props: {
+ trace,
+ isComplete: true,
+ },
+ store,
});
expect(vm.$el.querySelector('.js-log-animation')).toBeNull();
diff --git a/spec/javascripts/jobs/components/sidebar_detail_row_spec.js b/spec/javascripts/jobs/components/sidebar_detail_row_spec.js
index e6bfb0c4adc..42d11266dad 100644
--- a/spec/javascripts/jobs/components/sidebar_detail_row_spec.js
+++ b/spec/javascripts/jobs/components/sidebar_detail_row_spec.js
@@ -33,9 +33,9 @@ describe('Sidebar detail row', () => {
});
it('should render provided title and value', () => {
- expect(
- vm.$el.textContent.replace(/\s+/g, ' ').trim(),
- ).toEqual('this is the title: this is the value');
+ expect(vm.$el.textContent.replace(/\s+/g, ' ').trim()).toEqual(
+ 'this is the title: this is the value',
+ );
});
describe('when helpUrl not provided', () => {
diff --git a/spec/javascripts/jobs/components/sidebar_spec.js b/spec/javascripts/jobs/components/sidebar_spec.js
index 2f5c4245ced..424092d2d88 100644
--- a/spec/javascripts/jobs/components/sidebar_spec.js
+++ b/spec/javascripts/jobs/components/sidebar_spec.js
@@ -18,15 +18,6 @@ describe('Sidebar details block', () => {
vm.$destroy();
});
- describe('when it is loading', () => {
- it('should render a loading spinner', () => {
- store.dispatch('requestJob');
- vm = mountComponentWithStore(SidebarComponent, { store });
-
- expect(vm.$el.querySelector('.fa-spinner')).toBeDefined();
- });
- });
-
describe('when there is no retry path retry', () => {
it('should not render a retry button', () => {
const copy = Object.assign({}, job);
@@ -52,12 +43,12 @@ describe('Sidebar details block', () => {
describe('with terminal path', () => {
it('renders terminal link', () => {
- store.dispatch('receiveJobSuccess', job);
+ store.dispatch(
+ 'receiveJobSuccess',
+ Object.assign({}, job, { terminal_path: 'job/43123/terminal' }),
+ );
vm = mountComponentWithStore(SidebarComponent, {
store,
- props: {
- terminalPath: 'job/43123/terminal',
- },
});
expect(vm.$el.querySelector('.js-terminal-link')).not.toBeNull();
@@ -74,6 +65,7 @@ describe('Sidebar details block', () => {
expect(vm.$el.querySelector('.js-new-issue').getAttribute('href')).toEqual(
job.new_issue_path,
);
+
expect(vm.$el.querySelector('.js-new-issue').textContent.trim()).toEqual('New issue');
});
@@ -148,10 +140,11 @@ describe('Sidebar details block', () => {
});
describe('while fetching stages', () => {
- it('renders dropdown with More label', () => {
+ it('it does not render dropdown', () => {
+ store.dispatch('requestStages');
vm = mountComponentWithStore(SidebarComponent, { store });
- expect(vm.$el.querySelector('.js-selected-stage').textContent.trim()).toEqual('More');
+ expect(vm.$el.querySelector('.js-selected-stage')).toBeNull();
});
});
@@ -161,9 +154,9 @@ describe('Sidebar details block', () => {
vm = mountComponentWithStore(SidebarComponent, { store });
});
- it('renders first stage as selected', () => {
+ it('renders value provided as selectedStage as selected', () => {
expect(vm.$el.querySelector('.js-selected-stage').textContent.trim()).toEqual(
- stages[0].name,
+ vm.selectedStage,
);
});
});
diff --git a/spec/javascripts/jobs/components/stages_dropdown_spec.js b/spec/javascripts/jobs/components/stages_dropdown_spec.js
index aa6cc0f1b1a..9c731ae2f68 100644
--- a/spec/javascripts/jobs/components/stages_dropdown_spec.js
+++ b/spec/javascripts/jobs/components/stages_dropdown_spec.js
@@ -2,7 +2,7 @@ import Vue from 'vue';
import component from '~/jobs/components/stages_dropdown.vue';
import mountComponent from '../../helpers/vue_mount_component_helper';
-describe('Artifacts block', () => {
+describe('Stages Dropdown', () => {
const Component = Vue.extend(component);
let vm;
@@ -23,10 +23,6 @@ describe('Artifacts block', () => {
},
path: 'pipeline/28029444',
},
- ref: {
- path: 'commits/50101-truncated-job-information',
- name: '50101-truncated-job-information',
- },
stages: [
{
name: 'build',
@@ -35,6 +31,7 @@ describe('Artifacts block', () => {
name: 'test',
},
],
+ selectedStage: 'deploy',
});
});
@@ -53,17 +50,10 @@ describe('Artifacts block', () => {
});
it('renders dropdown with stages', () => {
- expect(vm.$el.querySelector('.dropdown button').textContent).toContain('build');
+ expect(vm.$el.querySelector('.dropdown .js-stage-item').textContent).toContain('build');
});
- it('updates selected stage on click', done => {
- vm.$el.querySelectorAll('.stage-item')[1].click();
- vm
- .$nextTick()
- .then(() => {
- expect(vm.$el.querySelector('.dropdown button').textContent).toContain('test');
- })
- .then(done)
- .catch(done.fail);
+ it('rendes selected stage', () => {
+ expect(vm.$el.querySelector('.dropdown .js-selected-stage').textContent).toContain('deploy');
});
});
diff --git a/spec/javascripts/jobs/components/trigger_block_spec.js b/spec/javascripts/jobs/components/trigger_block_spec.js
index e1b9898393e..7254851a9e7 100644
--- a/spec/javascripts/jobs/components/trigger_block_spec.js
+++ b/spec/javascripts/jobs/components/trigger_block_spec.js
@@ -45,13 +45,18 @@ describe('Trigger block', () => {
vm.$el.querySelector('.js-reveal-variables').click();
- vm
- .$nextTick()
+ vm.$nextTick()
.then(() => {
expect(vm.$el.querySelector('.js-build-variables')).not.toBeNull();
- expect(vm.$el.querySelector('.js-build-variables').textContent).toContain('UPLOAD_TO_GCS');
+ expect(vm.$el.querySelector('.js-build-variables').textContent).toContain(
+ 'UPLOAD_TO_GCS',
+ );
+
expect(vm.$el.querySelector('.js-build-variables').textContent).toContain('false');
- expect(vm.$el.querySelector('.js-build-variables').textContent).toContain('UPLOAD_TO_S3');
+ expect(vm.$el.querySelector('.js-build-variables').textContent).toContain(
+ 'UPLOAD_TO_S3',
+ );
+
expect(vm.$el.querySelector('.js-build-variables').textContent).toContain('true');
})
.then(done)
diff --git a/spec/javascripts/jobs/mock_data.js b/spec/javascripts/jobs/mock_data.js
index 4269b42e8b6..0398f184c0a 100644
--- a/spec/javascripts/jobs/mock_data.js
+++ b/spec/javascripts/jobs/mock_data.js
@@ -1,3 +1,5 @@
+import { TEST_HOST } from 'spec/test_constants';
+
const threeWeeksAgo = new Date();
threeWeeksAgo.setDate(threeWeeksAgo.getDate() - 21);
@@ -19,7 +21,7 @@ export default {
label: 'passed',
group: 'success',
has_details: true,
- details_path: '/root/ci-mock/-/jobs/4757',
+ details_path: `${TEST_HOST}/root/ci-mock/-/jobs/4757`,
favicon:
'/assets/ci_favicons/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.png',
action: {
@@ -31,6 +33,7 @@ export default {
},
coverage: 20,
erased_at: threeWeeksAgo.toISOString(),
+ erased: false,
duration: 6.785563,
tags: ['tag'],
user: {
@@ -131,6 +134,7 @@ export default {
path: '/root/ci-mock/merge_requests/2',
},
raw_path: '/root/ci-mock/builds/4757/raw',
+ has_trace: true,
};
export const stages = [
diff --git a/spec/javascripts/jobs/store/actions_spec.js b/spec/javascripts/jobs/store/actions_spec.js
index 5ab1f75d0d6..45130b983e7 100644
--- a/spec/javascripts/jobs/store/actions_spec.js
+++ b/spec/javascripts/jobs/store/actions_spec.js
@@ -2,9 +2,7 @@ import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import {
setJobEndpoint,
- setTraceEndpoint,
- setStagesEndpoint,
- setJobsEndpoint,
+ setTraceOptions,
clearEtagPoll,
stopPolling,
requestJob,
@@ -18,10 +16,6 @@ import {
stopPollingTrace,
receiveTraceSuccess,
receiveTraceError,
- fetchFavicon,
- requestStatusFavicon,
- receiveStatusFaviconSuccess,
- requestStatusFaviconError,
requestStages,
fetchStages,
receiveStagesSuccess,
@@ -30,6 +24,9 @@ import {
fetchJobsForStage,
receiveJobsForStageSuccess,
receiveJobsForStageError,
+ hideSidebar,
+ showSidebar,
+ toggleSidebar,
} from '~/jobs/store/actions';
import state from '~/jobs/store/state';
import * as types from '~/jobs/store/mutation_types';
@@ -56,45 +53,75 @@ describe('Job State actions', () => {
});
});
- describe('setTraceEndpoint', () => {
- it('should commit SET_TRACE_ENDPOINT mutation', done => {
+ describe('setTraceOptions', () => {
+ it('should commit SET_TRACE_OPTIONS mutation', done => {
testAction(
- setTraceEndpoint,
- 'job/872324/trace.json',
+ setTraceOptions,
+ { pagePath: 'job/872324/trace.json' },
mockedState,
- [{ type: types.SET_TRACE_ENDPOINT, payload: 'job/872324/trace.json' }],
+ [{ type: types.SET_TRACE_OPTIONS, payload: { pagePath: 'job/872324/trace.json' } }],
[],
done,
);
});
});
- describe('setStagesEndpoint', () => {
- it('should commit SET_STAGES_ENDPOINT mutation', done => {
+ describe('hideSidebar', () => {
+ it('should commit HIDE_SIDEBAR mutation', done => {
testAction(
- setStagesEndpoint,
- 'job/872324/stages.json',
+ hideSidebar,
+ null,
mockedState,
- [{ type: types.SET_STAGES_ENDPOINT, payload: 'job/872324/stages.json' }],
+ [{ type: types.HIDE_SIDEBAR }],
[],
done,
);
});
});
- describe('setJobsEndpoint', () => {
- it('should commit SET_JOBS_ENDPOINT mutation', done => {
+ describe('showSidebar', () => {
+ it('should commit HIDE_SIDEBAR mutation', done => {
testAction(
- setJobsEndpoint,
- 'job/872324/stages/build.json',
+ showSidebar,
+ null,
mockedState,
- [{ type: types.SET_JOBS_ENDPOINT, payload: 'job/872324/stages/build.json' }],
+ [{ type: types.SHOW_SIDEBAR }],
[],
done,
);
});
});
+ describe('toggleSidebar', () => {
+ describe('when isSidebarOpen is true', () => {
+ it('should dispatch hideSidebar', done => {
+ testAction(
+ toggleSidebar,
+ null,
+ mockedState,
+ [],
+ [{ type: 'hideSidebar' }],
+ done,
+ );
+ });
+ });
+
+ describe('when isSidebarOpen is false', () => {
+ it('should dispatch showSidebar', done => {
+ mockedState.isSidebarOpen = false;
+
+ testAction(
+ toggleSidebar,
+ null,
+ mockedState,
+ [],
+ [{ type: 'showSidebar' }],
+ done,
+ );
+ });
+ });
+ });
+
describe('requestJob', () => {
it('should commit REQUEST_JOB mutation', done => {
testAction(requestJob, null, mockedState, [{ type: types.REQUEST_JOB }], [], done);
@@ -183,14 +210,14 @@ describe('Job State actions', () => {
});
describe('scrollTop', () => {
- it('should commit SCROLL_TO_TOP mutation', done => {
- testAction(scrollTop, null, mockedState, [{ type: types.SCROLL_TO_TOP }], [], done);
+ it('should dispatch toggleScrollButtons action', done => {
+ testAction(scrollTop, null, mockedState, [], [{ type: 'toggleScrollButtons' }], done);
});
});
describe('scrollBottom', () => {
- it('should commit SCROLL_TO_BOTTOM mutation', done => {
- testAction(scrollBottom, null, mockedState, [{ type: types.SCROLL_TO_BOTTOM }], [], done);
+ it('should dispatch toggleScrollButtons action', done => {
+ testAction(scrollBottom, null, mockedState, [], [{ type: 'toggleScrollButtons' }], done);
});
});
@@ -215,7 +242,7 @@ describe('Job State actions', () => {
});
describe('success', () => {
- it('dispatches requestTrace, fetchFavicon, receiveTraceSuccess and stopPollingTrace when job is complete', done => {
+ it('dispatches requestTrace, receiveTraceSuccess and stopPollingTrace when job is complete', done => {
mock.onGet(`${TEST_HOST}/endpoint/trace.json`).replyOnce(200, {
html: 'I, [2018-08-17T22:57:45.707325 #1841] INFO -- :',
complete: true,
@@ -228,10 +255,8 @@ describe('Job State actions', () => {
[],
[
{
- type: 'requestTrace',
- },
- {
- type: 'fetchFavicon',
+ type: 'toggleScrollisInBottom',
+ payload: true,
},
{
payload: {
@@ -262,9 +287,6 @@ describe('Job State actions', () => {
[],
[
{
- type: 'requestTrace',
- },
- {
type: 'receiveTraceError',
},
],
@@ -313,104 +335,6 @@ describe('Job State actions', () => {
});
});
- describe('fetchFavicon', () => {
- let mock;
-
- beforeEach(() => {
- mockedState.pagePath = `${TEST_HOST}/endpoint`;
- mock = new MockAdapter(axios);
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- describe('success', () => {
- it('dispatches requestStatusFavicon and receiveStatusFaviconSuccess ', done => {
- mock.onGet(`${TEST_HOST}/endpoint/status.json`).replyOnce(200);
-
- testAction(
- fetchFavicon,
- null,
- mockedState,
- [],
- [
- {
- type: 'requestStatusFavicon',
- },
- {
- type: 'receiveStatusFaviconSuccess',
- },
- ],
- done,
- );
- });
- });
-
- describe('error', () => {
- beforeEach(() => {
- mock.onGet(`${TEST_HOST}/endpoint/status.json`).replyOnce(500);
- });
-
- it('dispatches requestStatusFavicon and requestStatusFaviconError ', done => {
- testAction(
- fetchFavicon,
- null,
- mockedState,
- [],
- [
- {
- type: 'requestStatusFavicon',
- },
- {
- type: 'requestStatusFaviconError',
- },
- ],
- done,
- );
- });
- });
- });
-
- describe('requestStatusFavicon', () => {
- it('should commit REQUEST_STATUS_FAVICON mutation ', done => {
- testAction(
- requestStatusFavicon,
- null,
- mockedState,
- [{ type: types.REQUEST_STATUS_FAVICON }],
- [],
- done,
- );
- });
- });
-
- describe('receiveStatusFaviconSuccess', () => {
- it('should commit RECEIVE_STATUS_FAVICON_SUCCESS mutation ', done => {
- testAction(
- receiveStatusFaviconSuccess,
- null,
- mockedState,
- [{ type: types.RECEIVE_STATUS_FAVICON_SUCCESS }],
- [],
- done,
- );
- });
- });
-
- describe('requestStatusFaviconError', () => {
- it('should commit RECEIVE_STATUS_FAVICON_ERROR mutation ', done => {
- testAction(
- requestStatusFaviconError,
- null,
- mockedState,
- [{ type: types.RECEIVE_STATUS_FAVICON_ERROR }],
- [],
- done,
- );
- });
- });
-
describe('requestStages', () => {
it('should commit REQUEST_STAGES mutation ', done => {
testAction(requestStages, null, mockedState, [{ type: types.REQUEST_STAGES }], [], done);
@@ -422,8 +346,9 @@ describe('Job State actions', () => {
beforeEach(() => {
mockedState.job.pipeline = {
- path: `${TEST_HOST}/endpoint.json/stages`,
+ path: `${TEST_HOST}/endpoint`,
};
+ mockedState.selectedStage = 'deploy';
mock = new MockAdapter(axios);
});
@@ -434,8 +359,8 @@ describe('Job State actions', () => {
describe('success', () => {
it('dispatches requestStages and receiveStagesSuccess, fetchJobsForStage ', done => {
mock
- .onGet(`${TEST_HOST}/endpoint.json/stages`)
- .replyOnce(200, { details: { stages: [{ id: 121212, name: 'build' }] } });
+ .onGet(`${TEST_HOST}/endpoint.json`)
+ .replyOnce(200, { details: { stages: [{ name: 'build' }, { name: 'deploy' }] } });
testAction(
fetchStages,
@@ -447,11 +372,11 @@ describe('Job State actions', () => {
type: 'requestStages',
},
{
- payload: [{ id: 121212, name: 'build' }],
+ payload: [{ name: 'build' }, { name: 'deploy' }],
type: 'receiveStagesSuccess',
},
{
- payload: { id: 121212, name: 'build' },
+ payload: { name: 'deploy' },
type: 'fetchJobsForStage',
},
],
@@ -515,9 +440,9 @@ describe('Job State actions', () => {
it('should commit REQUEST_JOBS_FOR_STAGE mutation ', done => {
testAction(
requestJobsForStage,
- null,
+ { name: 'deploy' },
mockedState,
- [{ type: types.REQUEST_JOBS_FOR_STAGE }],
+ [{ type: types.REQUEST_JOBS_FOR_STAGE, payload: { name: 'deploy' } }],
[],
done,
);
@@ -549,6 +474,7 @@ describe('Job State actions', () => {
[
{
type: 'requestJobsForStage',
+ payload: { dropdown_path: `${TEST_HOST}/jobs.json` },
},
{
payload: [{ id: 121212, name: 'build' }],
@@ -574,6 +500,7 @@ describe('Job State actions', () => {
[
{
type: 'requestJobsForStage',
+ payload: { dropdown_path: `${TEST_HOST}/jobs.json` },
},
{
type: 'receiveJobsForStageError',
diff --git a/spec/javascripts/jobs/store/getters_spec.js b/spec/javascripts/jobs/store/getters_spec.js
index 160b2f4b34a..34e9707eadd 100644
--- a/spec/javascripts/jobs/store/getters_spec.js
+++ b/spec/javascripts/jobs/store/getters_spec.js
@@ -46,6 +46,7 @@ describe('Job Store Getters', () => {
it('returns created_at key', () => {
const created = '2018-08-31T16:20:49.023Z';
localState.job.created_at = created;
+
expect(getters.headerTime(localState)).toEqual(created);
});
});
@@ -64,6 +65,7 @@ describe('Job Store Getters', () => {
describe('without status & with callout message', () => {
it('returns false', () => {
localState.job.callout_message = 'Callout message';
+
expect(getters.shouldRenderCalloutMessage(localState)).toEqual(false);
});
});
@@ -77,18 +79,20 @@ describe('Job Store Getters', () => {
});
});
- describe('jobHasStarted', () => {
- describe('when started equals false', () => {
+ describe('shouldRenderTriggeredLabel', () => {
+ describe('when started equals null', () => {
it('returns false', () => {
- localState.job.started = false;
- expect(getters.jobHasStarted(localState)).toEqual(false);
+ localState.job.started = null;
+
+ expect(getters.shouldRenderTriggeredLabel(localState)).toEqual(false);
});
});
describe('when started equals string', () => {
it('returns true', () => {
localState.job.started = '2018-08-31T16:20:49.023Z';
- expect(getters.jobHasStarted(localState)).toEqual(true);
+
+ expect(getters.shouldRenderTriggeredLabel(localState)).toEqual(true);
});
});
});
@@ -103,6 +107,7 @@ describe('Job Store Getters', () => {
describe('with an empty object for `deployment_status`', () => {
it('returns false', () => {
localState.job.deployment_status = {};
+
expect(getters.hasEnvironment(localState)).toEqual(false);
});
});
@@ -170,43 +175,37 @@ describe('Job Store Getters', () => {
});
});
- describe('isJobStuck', () => {
- describe('when job is pending and runners are not available', () => {
+ describe('hasRunnersForProject', () => {
+ describe('with available and offline runners', () => {
it('returns true', () => {
- localState.job.status = {
- group: 'pending',
- };
localState.job.runners = {
- available: false,
+ available: true,
+ online: false
};
- expect(getters.isJobStuck(localState)).toEqual(true);
+ expect(getters.hasRunnersForProject(localState)).toEqual(true);
});
});
- describe('when job is not pending', () => {
+ describe('with non available runners', () => {
it('returns false', () => {
- localState.job.status = {
- group: 'running',
- };
localState.job.runners = {
available: false,
+ online: false
};
- expect(getters.isJobStuck(localState)).toEqual(false);
+ expect(getters.hasRunnersForProject(localState)).toEqual(false);
});
});
- describe('when runners are available', () => {
+ describe('with online runners', () => {
it('returns false', () => {
- localState.job.status = {
- group: 'pending',
- };
localState.job.runners = {
- available: true,
+ available: false,
+ online: true
};
- expect(getters.isJobStuck(localState)).toEqual(false);
+ expect(getters.hasRunnersForProject(localState)).toEqual(false);
});
});
});
diff --git a/spec/javascripts/jobs/store/helpers.js b/spec/javascripts/jobs/store/helpers.js
new file mode 100644
index 00000000000..81a769b4a6e
--- /dev/null
+++ b/spec/javascripts/jobs/store/helpers.js
@@ -0,0 +1,6 @@
+import state from '~/jobs/store/state';
+
+// eslint-disable-next-line import/prefer-default-export
+export const resetStore = store => {
+ store.replaceState(state());
+};
diff --git a/spec/javascripts/jobs/store/mutations_spec.js b/spec/javascripts/jobs/store/mutations_spec.js
index 9ba543d32a8..d7908efcf13 100644
--- a/spec/javascripts/jobs/store/mutations_spec.js
+++ b/spec/javascripts/jobs/store/mutations_spec.js
@@ -15,28 +15,24 @@ describe('Jobs Store Mutations', () => {
describe('SET_JOB_ENDPOINT', () => {
it('should set jobEndpoint', () => {
mutations[types.SET_JOB_ENDPOINT](stateCopy, 'job/21312321.json');
+
expect(stateCopy.jobEndpoint).toEqual('job/21312321.json');
});
});
- describe('REQUEST_STATUS_FAVICON', () => {
- it('should set fetchingStatusFavicon to true', () => {
- mutations[types.REQUEST_STATUS_FAVICON](stateCopy);
- expect(stateCopy.fetchingStatusFavicon).toEqual(true);
- });
- });
+ describe('HIDE_SIDEBAR', () => {
+ it('should set isSidebarOpen to false', () => {
+ mutations[types.HIDE_SIDEBAR](stateCopy);
- describe('RECEIVE_STATUS_FAVICON_SUCCESS', () => {
- it('should set fetchingStatusFavicon to false', () => {
- mutations[types.RECEIVE_STATUS_FAVICON_SUCCESS](stateCopy);
- expect(stateCopy.fetchingStatusFavicon).toEqual(false);
+ expect(stateCopy.isSidebarOpen).toEqual(false);
});
});
- describe('RECEIVE_STATUS_FAVICON_ERROR', () => {
- it('should set fetchingStatusFavicon to false', () => {
- mutations[types.RECEIVE_STATUS_FAVICON_ERROR](stateCopy);
- expect(stateCopy.fetchingStatusFavicon).toEqual(false);
+ describe('SHOW_SIDEBAR', () => {
+ it('should set isSidebarOpen to true', () => {
+ mutations[types.SHOW_SIDEBAR](stateCopy);
+
+ expect(stateCopy.isSidebarOpen).toEqual(true);
});
});
@@ -48,6 +44,7 @@ describe('Jobs Store Mutations', () => {
mutations[types.RECEIVE_TRACE_SUCCESS](stateCopy, {
state: stateLog,
});
+
expect(stateCopy.traceState).toEqual(stateLog);
});
});
@@ -77,6 +74,7 @@ describe('Jobs Store Mutations', () => {
size: 511846,
complete: true,
});
+
expect(stateCopy.trace).toEqual(html);
expect(stateCopy.traceSize).toEqual(511846);
expect(stateCopy.isTraceComplete).toEqual(true);
@@ -86,6 +84,7 @@ describe('Jobs Store Mutations', () => {
describe('STOP_POLLING_TRACE', () => {
it('sets isTraceComplete to true', () => {
mutations[types.STOP_POLLING_TRACE](stateCopy);
+
expect(stateCopy.isTraceComplete).toEqual(true);
});
});
@@ -93,9 +92,8 @@ describe('Jobs Store Mutations', () => {
describe('RECEIVE_TRACE_ERROR', () => {
it('resets trace state and sets error to true', () => {
mutations[types.RECEIVE_TRACE_ERROR](stateCopy);
- expect(stateCopy.isLoadingTrace).toEqual(false);
+
expect(stateCopy.isTraceComplete).toEqual(true);
- expect(stateCopy.hasTraceError).toEqual(true);
});
});
@@ -108,64 +106,54 @@ describe('Jobs Store Mutations', () => {
});
describe('RECEIVE_JOB_SUCCESS', () => {
- beforeEach(() => {
+ it('sets is loading to false', () => {
mutations[types.RECEIVE_JOB_SUCCESS](stateCopy, { id: 1312321 });
- });
- it('sets is loading to false', () => {
expect(stateCopy.isLoading).toEqual(false);
});
it('sets hasError to false', () => {
+ mutations[types.RECEIVE_JOB_SUCCESS](stateCopy, { id: 1312321 });
+
expect(stateCopy.hasError).toEqual(false);
});
it('sets job data', () => {
+ mutations[types.RECEIVE_JOB_SUCCESS](stateCopy, { id: 1312321 });
+
expect(stateCopy.job).toEqual({ id: 1312321 });
});
- });
- describe('RECEIVE_JOB_ERROR', () => {
- it('resets job data', () => {
- mutations[types.RECEIVE_JOB_ERROR](stateCopy);
+ it('sets selectedStage when the selectedStage is empty', () => {
+ expect(stateCopy.selectedStage).toEqual('');
+ mutations[types.RECEIVE_JOB_SUCCESS](stateCopy, { id: 1312321, stage: 'deploy' });
- expect(stateCopy.isLoading).toEqual(false);
- expect(stateCopy.hasError).toEqual(true);
- expect(stateCopy.job).toEqual({});
+ expect(stateCopy.selectedStage).toEqual('deploy');
});
- });
- describe('SCROLL_TO_TOP', () => {
- beforeEach(() => {
- mutations[types.SCROLL_TO_TOP](stateCopy);
- });
+ it('does not set selectedStage when the selectedStage is not More', () => {
+ stateCopy.selectedStage = 'notify';
- it('sets isTraceScrolledToBottom to false', () => {
- expect(stateCopy.isTraceScrolledToBottom).toEqual(false);
- });
+ expect(stateCopy.selectedStage).toEqual('notify');
+ mutations[types.RECEIVE_JOB_SUCCESS](stateCopy, { id: 1312321, stage: 'deploy' });
- it('sets hasBeenScrolled to true', () => {
- expect(stateCopy.hasBeenScrolled).toEqual(true);
+ expect(stateCopy.selectedStage).toEqual('notify');
});
});
- describe('SCROLL_TO_BOTTOM', () => {
- beforeEach(() => {
- mutations[types.SCROLL_TO_BOTTOM](stateCopy);
- });
-
- it('sets isTraceScrolledToBottom to true', () => {
- expect(stateCopy.isTraceScrolledToBottom).toEqual(true);
- });
+ describe('RECEIVE_JOB_ERROR', () => {
+ it('resets job data', () => {
+ mutations[types.RECEIVE_JOB_ERROR](stateCopy);
- it('sets hasBeenScrolled to true', () => {
- expect(stateCopy.hasBeenScrolled).toEqual(true);
+ expect(stateCopy.isLoading).toEqual(false);
+ expect(stateCopy.job).toEqual({});
});
});
describe('REQUEST_STAGES', () => {
it('sets isLoadingStages to true', () => {
mutations[types.REQUEST_STAGES](stateCopy);
+
expect(stateCopy.isLoadingStages).toEqual(true);
});
});
@@ -200,9 +188,16 @@ describe('Jobs Store Mutations', () => {
describe('REQUEST_JOBS_FOR_STAGE', () => {
it('sets isLoadingStages to true', () => {
- mutations[types.REQUEST_JOBS_FOR_STAGE](stateCopy);
+ mutations[types.REQUEST_JOBS_FOR_STAGE](stateCopy, { name: 'deploy' });
+
expect(stateCopy.isLoadingJobs).toEqual(true);
});
+
+ it('sets selectedStage', () => {
+ mutations[types.REQUEST_JOBS_FOR_STAGE](stateCopy, { name: 'deploy' });
+
+ expect(stateCopy.selectedStage).toEqual('deploy');
+ });
});
describe('RECEIVE_JOBS_FOR_STAGE_SUCCESS', () => {
diff --git a/spec/javascripts/labels_issue_sidebar_spec.js b/spec/javascripts/labels_issue_sidebar_spec.js
index 5aafb6ad8f0..e5678ee5379 100644
--- a/spec/javascripts/labels_issue_sidebar_spec.js
+++ b/spec/javascripts/labels_issue_sidebar_spec.js
@@ -12,88 +12,106 @@ import '~/api';
import '~/create_label';
import '~/users_select';
-(() => {
- let saveLabelCount = 0;
- let mock;
+let saveLabelCount = 0;
+let mock;
- describe('Issue dropdown sidebar', () => {
- preloadFixtures('static/issue_sidebar_label.html.raw');
+describe('Issue dropdown sidebar', () => {
+ preloadFixtures('static/issue_sidebar_label.html.raw');
- beforeEach(() => {
- loadFixtures('static/issue_sidebar_label.html.raw');
+ beforeEach(() => {
+ loadFixtures('static/issue_sidebar_label.html.raw');
- mock = new MockAdapter(axios);
+ mock = new MockAdapter(axios);
- new IssuableContext('{"id":1,"name":"Administrator","username":"root"}');
- new LabelsSelect();
+ new IssuableContext('{"id":1,"name":"Administrator","username":"root"}');
+ new LabelsSelect();
- mock.onGet('/root/test/labels.json').reply(() => {
- const labels = Array(10).fill().map((_, i) => ({
+ mock.onGet('/root/test/labels.json').reply(() => {
+ const labels = Array(10)
+ .fill()
+ .map((_, i) => ({
id: i,
title: `test ${i}`,
color: '#5CB85C',
}));
- return [200, labels];
- });
+ return [200, labels];
+ });
- mock.onPut('/root/test/issues/2.json').reply(() => {
- const labels = Array(saveLabelCount).fill().map((_, i) => ({
+ mock.onPut('/root/test/issues/2.json').reply(() => {
+ const labels = Array(saveLabelCount)
+ .fill()
+ .map((_, i) => ({
id: i,
title: `test ${i}`,
color: '#5CB85C',
}));
- return [200, { labels }];
- });
- });
-
- afterEach(() => {
- mock.restore();
+ return [200, { labels }];
});
+ });
- it('changes collapsed tooltip when changing labels when less than 5', (done) => {
- saveLabelCount = 5;
- $('.edit-link').get(0).click();
-
- setTimeout(() => {
- expect($('.dropdown-content a').length).toBe(10);
-
- $('.dropdown-content a').each(function (i) {
- if (i < saveLabelCount) {
- $(this).get(0).click();
- }
- });
-
- $('.edit-link').get(0).click();
+ afterEach(() => {
+ mock.restore();
+ });
- setTimeout(() => {
- expect($('.sidebar-collapsed-icon').attr('data-original-title')).toBe('test 0, test 1, test 2, test 3, test 4');
- done();
- }, 0);
- }, 0);
- });
+ it('changes collapsed tooltip when changing labels when less than 5', done => {
+ saveLabelCount = 5;
+ $('.edit-link')
+ .get(0)
+ .click();
+
+ setTimeout(() => {
+ expect($('.dropdown-content a').length).toBe(10);
+
+ $('.dropdown-content a').each(function(i) {
+ if (i < saveLabelCount) {
+ $(this)
+ .get(0)
+ .click();
+ }
+ });
- it('changes collapsed tooltip when changing labels when more than 5', (done) => {
- saveLabelCount = 6;
- $('.edit-link').get(0).click();
+ $('.edit-link')
+ .get(0)
+ .click();
setTimeout(() => {
- expect($('.dropdown-content a').length).toBe(10);
+ expect($('.sidebar-collapsed-icon').attr('data-original-title')).toBe(
+ 'test 0, test 1, test 2, test 3, test 4',
+ );
+ done();
+ }, 0);
+ }, 0);
+ });
- $('.dropdown-content a').each(function (i) {
- if (i < saveLabelCount) {
- $(this).get(0).click();
- }
- });
+ it('changes collapsed tooltip when changing labels when more than 5', done => {
+ saveLabelCount = 6;
+ $('.edit-link')
+ .get(0)
+ .click();
+
+ setTimeout(() => {
+ expect($('.dropdown-content a').length).toBe(10);
+
+ $('.dropdown-content a').each(function(i) {
+ if (i < saveLabelCount) {
+ $(this)
+ .get(0)
+ .click();
+ }
+ });
- $('.edit-link').get(0).click();
+ $('.edit-link')
+ .get(0)
+ .click();
- setTimeout(() => {
- expect($('.sidebar-collapsed-icon').attr('data-original-title')).toBe('test 0, test 1, test 2, test 3, test 4, and 1 more');
- done();
- }, 0);
+ setTimeout(() => {
+ expect($('.sidebar-collapsed-icon').attr('data-original-title')).toBe(
+ 'test 0, test 1, test 2, test 3, test 4, and 1 more',
+ );
+ done();
}, 0);
- });
+ }, 0);
});
-})();
+});
diff --git a/spec/javascripts/labels_select_spec.js b/spec/javascripts/labels_select_spec.js
index 386e00bfd0c..acfdc885032 100644
--- a/spec/javascripts/labels_select_spec.js
+++ b/spec/javascripts/labels_select_spec.js
@@ -19,10 +19,12 @@ describe('LabelsSelect', () => {
let $labelEl;
beforeEach(() => {
- $labelEl = $(LabelsSelect.getLabelTemplate({
- labels: mockLabels,
- issueUpdateURL: mockUrl,
- }));
+ $labelEl = $(
+ LabelsSelect.getLabelTemplate({
+ labels: mockLabels,
+ issueUpdateURL: mockUrl,
+ }),
+ );
});
it('generated label item template has correct label URL', () => {
@@ -38,7 +40,9 @@ describe('LabelsSelect', () => {
});
it('generated label item template has correct label styles', () => {
- expect($labelEl.find('span.label').attr('style')).toBe(`background-color: ${label.color}; color: ${label.text_color};`);
+ expect($labelEl.find('span.label').attr('style')).toBe(
+ `background-color: ${label.color}; color: ${label.text_color};`,
+ );
});
it('generated label item has a badge class', () => {
diff --git a/spec/javascripts/landing_spec.js b/spec/javascripts/landing_spec.js
index 7916073190a..2fe5a47b63e 100644
--- a/spec/javascripts/landing_spec.js
+++ b/spec/javascripts/landing_spec.js
@@ -1,9 +1,9 @@
import Landing from '~/landing';
import Cookies from 'js-cookie';
-describe('Landing', function () {
- describe('class constructor', function () {
- beforeEach(function () {
+describe('Landing', function() {
+ describe('class constructor', function() {
+ beforeEach(function() {
this.landingElement = {};
this.dismissButton = {};
this.cookieName = 'cookie_name';
@@ -11,25 +11,25 @@ describe('Landing', function () {
this.landing = new Landing(this.landingElement, this.dismissButton, this.cookieName);
});
- it('should set .landing', function () {
+ it('should set .landing', function() {
expect(this.landing.landingElement).toBe(this.landingElement);
});
- it('should set .cookieName', function () {
+ it('should set .cookieName', function() {
expect(this.landing.cookieName).toBe(this.cookieName);
});
- it('should set .dismissButton', function () {
+ it('should set .dismissButton', function() {
expect(this.landing.dismissButton).toBe(this.dismissButton);
});
- it('should set .eventWrapper', function () {
+ it('should set .eventWrapper', function() {
expect(this.landing.eventWrapper).toEqual({});
});
});
- describe('toggle', function () {
- beforeEach(function () {
+ describe('toggle', function() {
+ beforeEach(function() {
this.isDismissed = false;
this.landingElement = { classList: jasmine.createSpyObj('classList', ['toggle']) };
this.landing = {
@@ -44,20 +44,20 @@ describe('Landing', function () {
Landing.prototype.toggle.call(this.landing);
});
- it('should call .isDismissed', function () {
+ it('should call .isDismissed', function() {
expect(this.landing.isDismissed).toHaveBeenCalled();
});
- it('should call .classList.toggle', function () {
+ it('should call .classList.toggle', function() {
expect(this.landingElement.classList.toggle).toHaveBeenCalledWith('hidden', this.isDismissed);
});
- it('should call .addEvents', function () {
+ it('should call .addEvents', function() {
expect(this.landing.addEvents).toHaveBeenCalled();
});
- describe('if isDismissed is true', function () {
- beforeEach(function () {
+ describe('if isDismissed is true', function() {
+ beforeEach(function() {
this.isDismissed = true;
this.landingElement = { classList: jasmine.createSpyObj('classList', ['toggle']) };
this.landing = {
@@ -74,14 +74,14 @@ describe('Landing', function () {
Landing.prototype.toggle.call(this.landing);
});
- it('should not call .addEvents', function () {
+ it('should not call .addEvents', function() {
expect(this.landing.addEvents).not.toHaveBeenCalled();
});
});
});
- describe('addEvents', function () {
- beforeEach(function () {
+ describe('addEvents', function() {
+ beforeEach(function() {
this.dismissButton = jasmine.createSpyObj('dismissButton', ['addEventListener']);
this.eventWrapper = {};
this.landing = {
@@ -93,17 +93,20 @@ describe('Landing', function () {
Landing.prototype.addEvents.call(this.landing);
});
- it('should set .eventWrapper.dismissLanding', function () {
+ it('should set .eventWrapper.dismissLanding', function() {
expect(this.eventWrapper.dismissLanding).toEqual(jasmine.any(Function));
});
- it('should call .addEventListener', function () {
- expect(this.dismissButton.addEventListener).toHaveBeenCalledWith('click', this.eventWrapper.dismissLanding);
+ it('should call .addEventListener', function() {
+ expect(this.dismissButton.addEventListener).toHaveBeenCalledWith(
+ 'click',
+ this.eventWrapper.dismissLanding,
+ );
});
});
- describe('removeEvents', function () {
- beforeEach(function () {
+ describe('removeEvents', function() {
+ beforeEach(function() {
this.dismissButton = jasmine.createSpyObj('dismissButton', ['removeEventListener']);
this.eventWrapper = { dismissLanding: () => {} };
this.landing = {
@@ -114,13 +117,16 @@ describe('Landing', function () {
Landing.prototype.removeEvents.call(this.landing);
});
- it('should call .removeEventListener', function () {
- expect(this.dismissButton.removeEventListener).toHaveBeenCalledWith('click', this.eventWrapper.dismissLanding);
+ it('should call .removeEventListener', function() {
+ expect(this.dismissButton.removeEventListener).toHaveBeenCalledWith(
+ 'click',
+ this.eventWrapper.dismissLanding,
+ );
});
});
- describe('dismissLanding', function () {
- beforeEach(function () {
+ describe('dismissLanding', function() {
+ beforeEach(function() {
this.landingElement = { classList: jasmine.createSpyObj('classList', ['add']) };
this.cookieName = 'cookie_name';
this.landing = { landingElement: this.landingElement, cookieName: this.cookieName };
@@ -130,17 +136,17 @@ describe('Landing', function () {
Landing.prototype.dismissLanding.call(this.landing);
});
- it('should call .classList.add', function () {
+ it('should call .classList.add', function() {
expect(this.landingElement.classList.add).toHaveBeenCalledWith('hidden');
});
- it('should call Cookies.set', function () {
+ it('should call Cookies.set', function() {
expect(Cookies.set).toHaveBeenCalledWith(this.cookieName, 'true', { expires: 365 });
});
});
- describe('isDismissed', function () {
- beforeEach(function () {
+ describe('isDismissed', function() {
+ beforeEach(function() {
this.cookieName = 'cookie_name';
this.landing = { cookieName: this.cookieName };
@@ -149,11 +155,11 @@ describe('Landing', function () {
this.isDismissed = Landing.prototype.isDismissed.call(this.landing);
});
- it('should call Cookies.get', function () {
+ it('should call Cookies.get', function() {
expect(Cookies.get).toHaveBeenCalledWith(this.cookieName);
});
- it('should return a boolean', function () {
+ it('should return a boolean', function() {
expect(typeof this.isDismissed).toEqual('boolean');
});
});
diff --git a/spec/javascripts/lib/utils/accessor_spec.js b/spec/javascripts/lib/utils/accessor_spec.js
index b768d6f2a68..0045330e470 100644
--- a/spec/javascripts/lib/utils/accessor_spec.js
+++ b/spec/javascripts/lib/utils/accessor_spec.js
@@ -13,7 +13,11 @@ describe('AccessorUtilities', () => {
});
it('should return `false` if access throws an error', () => {
- base = { get testProp() { throw testError; } };
+ base = {
+ get testProp() {
+ throw testError;
+ },
+ };
expect(AccessorUtilities.isPropertyAccessSafe(base, 'testProp')).toBe(false);
});
@@ -35,7 +39,9 @@ describe('AccessorUtilities', () => {
});
it('should return `false` if calling throws an error', () => {
- base.func = () => { throw new Error('test error'); };
+ base.func = () => {
+ throw new Error('test error');
+ };
expect(AccessorUtilities.isFunctionCallSafe(base, 'func')).toBe(false);
});
@@ -58,7 +64,9 @@ describe('AccessorUtilities', () => {
});
it('should return `false` if access to .setItem isnt safe', () => {
- window.localStorage.setItem.and.callFake(() => { throw testError; });
+ window.localStorage.setItem.and.callFake(() => {
+ throw testError;
+ });
expect(AccessorUtilities.isLocalStorageAccessSafe()).toBe(false);
});
diff --git a/spec/javascripts/lib/utils/ajax_cache_spec.js b/spec/javascripts/lib/utils/ajax_cache_spec.js
index 7603400b55e..dc0b04173bf 100644
--- a/spec/javascripts/lib/utils/ajax_cache_spec.js
+++ b/spec/javascripts/lib/utils/ajax_cache_spec.js
@@ -9,8 +9,8 @@ describe('AjaxCache', () => {
};
beforeEach(() => {
- AjaxCache.internalStorage = { };
- AjaxCache.pendingRequests = { };
+ AjaxCache.internalStorage = {};
+ AjaxCache.pendingRequests = {};
});
describe('get', () => {
@@ -59,7 +59,7 @@ describe('AjaxCache', () => {
it('does nothing if cache is empty', () => {
AjaxCache.remove(dummyEndpoint);
- expect(AjaxCache.internalStorage).toEqual({ });
+ expect(AjaxCache.internalStorage).toEqual({});
});
it('does nothing if cache contains no matching data', () => {
@@ -75,7 +75,7 @@ describe('AjaxCache', () => {
AjaxCache.remove(dummyEndpoint);
- expect(AjaxCache.internalStorage).toEqual({ });
+ expect(AjaxCache.internalStorage).toEqual({});
});
});
@@ -101,61 +101,61 @@ describe('AjaxCache', () => {
mock.restore();
});
- it('stores and returns data from Ajax call if cache is empty', (done) => {
+ it('stores and returns data from Ajax call if cache is empty', done => {
mock.onGet(dummyEndpoint).reply(200, dummyResponse);
AjaxCache.retrieve(dummyEndpoint)
- .then((data) => {
- expect(data).toEqual(dummyResponse);
- expect(AjaxCache.internalStorage[dummyEndpoint]).toEqual(dummyResponse);
- })
- .then(done)
- .catch(fail);
+ .then(data => {
+ expect(data).toEqual(dummyResponse);
+ expect(AjaxCache.internalStorage[dummyEndpoint]).toEqual(dummyResponse);
+ })
+ .then(done)
+ .catch(fail);
});
- it('makes no Ajax call if request is pending', (done) => {
+ it('makes no Ajax call if request is pending', done => {
mock.onGet(dummyEndpoint).reply(200, dummyResponse);
AjaxCache.retrieve(dummyEndpoint)
- .then(done)
- .catch(fail);
+ .then(done)
+ .catch(fail);
AjaxCache.retrieve(dummyEndpoint)
- .then(done)
- .catch(fail);
+ .then(done)
+ .catch(fail);
expect(axios.get.calls.count()).toBe(1);
});
- it('returns undefined if Ajax call fails and cache is empty', (done) => {
+ it('returns undefined if Ajax call fails and cache is empty', done => {
const errorMessage = 'Network Error';
mock.onGet(dummyEndpoint).networkError();
AjaxCache.retrieve(dummyEndpoint)
- .then(data => fail(`Received unexpected data: ${JSON.stringify(data)}`))
- .catch((error) => {
- expect(error.message).toBe(`${dummyEndpoint}: ${errorMessage}`);
- expect(error.textStatus).toBe(errorMessage);
- done();
- })
- .catch(fail);
+ .then(data => fail(`Received unexpected data: ${JSON.stringify(data)}`))
+ .catch(error => {
+ expect(error.message).toBe(`${dummyEndpoint}: ${errorMessage}`);
+ expect(error.textStatus).toBe(errorMessage);
+ done();
+ })
+ .catch(fail);
});
- it('makes no Ajax call if matching data exists', (done) => {
+ it('makes no Ajax call if matching data exists', done => {
AjaxCache.internalStorage[dummyEndpoint] = dummyResponse;
mock.onGet(dummyEndpoint).reply(() => {
fail(new Error('expected no Ajax call!'));
});
AjaxCache.retrieve(dummyEndpoint)
- .then((data) => {
- expect(data).toBe(dummyResponse);
- })
- .then(done)
- .catch(fail);
+ .then(data => {
+ expect(data).toBe(dummyResponse);
+ })
+ .then(done)
+ .catch(fail);
});
- it('makes Ajax call even if matching data exists when forceRequest parameter is provided', (done) => {
+ it('makes Ajax call even if matching data exists when forceRequest parameter is provided', done => {
const oldDummyResponse = {
important: 'old dummy data',
};
@@ -166,7 +166,7 @@ describe('AjaxCache', () => {
// Call without forceRetrieve param
AjaxCache.retrieve(dummyEndpoint)
- .then((data) => {
+ .then(data => {
expect(data).toBe(oldDummyResponse);
})
.then(done)
@@ -174,7 +174,7 @@ describe('AjaxCache', () => {
// Call with forceRetrieve param
AjaxCache.retrieve(dummyEndpoint, true)
- .then((data) => {
+ .then(data => {
expect(data).toEqual(dummyResponse);
})
.then(done)
diff --git a/spec/javascripts/lib/utils/common_utils_spec.js b/spec/javascripts/lib/utils/common_utils_spec.js
index 28151c7e658..514d6ddeae5 100644
--- a/spec/javascripts/lib/utils/common_utils_spec.js
+++ b/spec/javascripts/lib/utils/common_utils_spec.js
@@ -1,4 +1,3 @@
-/* eslint-disable promise/catch-or-return */
import axios from '~/lib/utils/axios_utils';
import * as commonUtils from '~/lib/utils/common_utils';
import MockAdapter from 'axios-mock-adapter';
@@ -9,6 +8,7 @@ describe('common_utils', () => {
it('returns an anchor tag with url', () => {
expect(commonUtils.parseUrl('/some/absolute/url').pathname).toContain('some/absolute/url');
});
+
it('url is escaped', () => {
// IE11 will return a relative pathname while other browsers will return a full pathname.
// parseUrl uses an anchor element for parsing an url. With relative urls, the anchor
@@ -42,7 +42,8 @@ describe('common_utils', () => {
it('should remove the question mark from the search params', () => {
const paramsArray = commonUtils.urlParamsToArray('?test=thing');
- expect(paramsArray[0][0] !== '?').toBe(true);
+
+ expect(paramsArray[0][0]).not.toBe('?');
});
});
@@ -121,6 +122,7 @@ describe('common_utils', () => {
commonUtils.handleLocationHash();
expectGetElementIdToHaveBeenCalledWith('test');
+
expect(window.scrollY).toBe(document.getElementById('test').offsetTop);
document.getElementById('parent').remove();
@@ -139,6 +141,7 @@ describe('common_utils', () => {
expectGetElementIdToHaveBeenCalledWith('test');
expectGetElementIdToHaveBeenCalledWith('user-content-test');
+
expect(window.scrollY).toBe(document.getElementById('user-content-test').offsetTop);
document.getElementById('parent').remove();
@@ -159,6 +162,7 @@ describe('common_utils', () => {
expectGetElementIdToHaveBeenCalledWith('test');
expectGetElementIdToHaveBeenCalledWith('user-content-test');
+
expect(window.scrollY).toBe(document.getElementById('user-content-test').offsetTop - 50);
expect(window.scrollBy).toHaveBeenCalledWith(0, -50);
@@ -222,20 +226,24 @@ describe('common_utils', () => {
it('should return valid parameter', () => {
const value = commonUtils.getParameterByName('scope');
+
expect(commonUtils.getParameterByName('p')).toEqual('2');
expect(value).toBe('all');
});
it('should return invalid parameter', () => {
const value = commonUtils.getParameterByName('fakeParameter');
+
expect(value).toBe(null);
});
it('should return valid paramentes if URL is provided', () => {
let value = commonUtils.getParameterByName('foo', 'http://cocteau.twins/?foo=bar');
+
expect(value).toBe('bar');
value = commonUtils.getParameterByName('manan', 'http://cocteau.twins/?foo=bar&manan=canchu');
+
expect(value).toBe('canchu');
});
});
@@ -359,10 +367,10 @@ describe('common_utils', () => {
}).then((resp) => {
stop(resp);
})
- )).then((respBackoff) => {
+ ).catch(done.fail)).then((respBackoff) => {
expect(respBackoff).toBe(expectedResponseValue);
done();
- });
+ }).catch(done.fail);
});
it('catches the rejected promise from the callback ', (done) => {
@@ -393,18 +401,20 @@ describe('common_utils', () => {
stop(resp);
}
})
- )).then((respBackoff) => {
+ ).catch(done.fail)).then((respBackoff) => {
const timeouts = window.setTimeout.calls.allArgs().map(([, timeout]) => timeout);
+
expect(timeouts).toEqual([2000, 4000]);
expect(respBackoff).toBe(expectedResponseValue);
done();
- });
+ }).catch(done.fail);
});
it('rejects the backOff promise after timing out', (done) => {
commonUtils.backOff(next => next(), 64000)
.catch((errBackoffResp) => {
const timeouts = window.setTimeout.calls.allArgs().map(([, timeout]) => timeout);
+
expect(timeouts).toEqual([2000, 4000, 8000, 16000, 32000, 32000]);
expect(errBackoffResp instanceof Error).toBe(true);
expect(errBackoffResp.message).toBe('BACKOFF_TIMEOUT');
@@ -450,6 +460,7 @@ describe('common_utils', () => {
const favicon = document.getElementById('favicon');
favicon.setAttribute('href', 'new/favicon');
commonUtils.resetFavicon();
+
expect(document.getElementById('favicon').getAttribute('href')).toEqual('default/favicon');
});
});
@@ -459,7 +470,7 @@ describe('common_utils', () => {
commonUtils.createOverlayIcon(faviconDataUrl, overlayDataUrl).then((url) => {
expect(url).toEqual(faviconWithOverlayDataUrl);
done();
- });
+ }).catch(done.fail);
});
});
@@ -479,7 +490,7 @@ describe('common_utils', () => {
commonUtils.setFaviconOverlay(overlayDataUrl).then(() => {
expect(document.getElementById('favicon').getAttribute('href')).toEqual(faviconWithOverlayDataUrl);
done();
- });
+ }).catch(done.fail);
});
});
@@ -507,6 +518,7 @@ describe('common_utils', () => {
commonUtils.setCiStatusFavicon(BUILD_URL)
.catch(() => {
const favicon = document.getElementById('favicon');
+
expect(favicon.getAttribute('href')).toEqual(faviconDataUrl);
done();
});
@@ -520,6 +532,7 @@ describe('common_utils', () => {
commonUtils.setCiStatusFavicon(BUILD_URL)
.then(() => {
const favicon = document.getElementById('favicon');
+
expect(favicon.getAttribute('href')).toEqual(faviconWithOverlayDataUrl);
done();
})
diff --git a/spec/javascripts/lib/utils/csrf_token_spec.js b/spec/javascripts/lib/utils/csrf_token_spec.js
index 81a39a97a84..867bee34ee5 100644
--- a/spec/javascripts/lib/utils/csrf_token_spec.js
+++ b/spec/javascripts/lib/utils/csrf_token_spec.js
@@ -1,9 +1,10 @@
import csrf from '~/lib/utils/csrf';
-describe('csrf', function () {
+describe('csrf', function() {
beforeEach(() => {
this.tokenKey = 'X-CSRF-Token';
- this.token = 'pH1cvjnP9grx2oKlhWEDvUZnJ8x2eXsIs1qzyHkF3DugSG5yTxR76CWeEZRhML2D1IeVB7NEW0t5l/axE4iJpQ==';
+ this.token =
+ 'pH1cvjnP9grx2oKlhWEDvUZnJ8x2eXsIs1qzyHkF3DugSG5yTxR76CWeEZRhML2D1IeVB7NEW0t5l/axE4iJpQ==';
});
it('returns the correct headerKey', () => {
diff --git a/spec/javascripts/lib/utils/datefix_spec.js b/spec/javascripts/lib/utils/datefix_spec.js
deleted file mode 100644
index a9f3abcf2a4..00000000000
--- a/spec/javascripts/lib/utils/datefix_spec.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import { pad, pikadayToString } from '~/lib/utils/datefix';
-
-describe('datefix', () => {
- describe('pad', () => {
- it('should add a 0 when length is smaller than 2', () => {
- expect(pad(2)).toEqual('02');
- });
-
- it('should not add a zero when lenght matches the default', () => {
- expect(pad(12)).toEqual('12');
- });
-
- it('should add a 0 when lenght is smaller than the provided', () => {
- expect(pad(12, 3)).toEqual('012');
- });
- });
-
- describe('parsePikadayDate', () => {
- // removed because of https://gitlab.com/gitlab-org/gitlab-ce/issues/39834
- });
-
- describe('pikadayToString', () => {
- it('should format a UTC date into yyyy-mm-dd format', () => {
- expect(pikadayToString(new Date('2020-01-29:00:00'))).toEqual('2020-01-29');
- });
- });
-});
diff --git a/spec/javascripts/lib/utils/datetime_utility_spec.js b/spec/javascripts/lib/utils/datetime_utility_spec.js
new file mode 100644
index 00000000000..de6b96aab57
--- /dev/null
+++ b/spec/javascripts/lib/utils/datetime_utility_spec.js
@@ -0,0 +1,372 @@
+import * as datetimeUtility from '~/lib/utils/datetime_utility';
+
+describe('Date time utils', () => {
+ describe('timeFor', () => {
+ it('returns `past due` when in past', () => {
+ const date = new Date();
+ date.setFullYear(date.getFullYear() - 1);
+
+ expect(datetimeUtility.timeFor(date)).toBe('Past due');
+ });
+
+ it('returns remaining time when in the future', () => {
+ const date = new Date();
+ date.setFullYear(date.getFullYear() + 1);
+
+ // Add a day to prevent a transient error. If date is even 1 second
+ // short of a full year, timeFor will return '11 months remaining'
+ date.setDate(date.getDate() + 1);
+
+ expect(datetimeUtility.timeFor(date)).toBe('1 year remaining');
+ });
+ });
+
+ describe('get day name', () => {
+ it('should return Sunday', () => {
+ const day = datetimeUtility.getDayName(new Date('07/17/2016'));
+
+ expect(day).toBe('Sunday');
+ });
+
+ it('should return Monday', () => {
+ const day = datetimeUtility.getDayName(new Date('07/18/2016'));
+
+ expect(day).toBe('Monday');
+ });
+
+ it('should return Tuesday', () => {
+ const day = datetimeUtility.getDayName(new Date('07/19/2016'));
+
+ expect(day).toBe('Tuesday');
+ });
+
+ it('should return Wednesday', () => {
+ const day = datetimeUtility.getDayName(new Date('07/20/2016'));
+
+ expect(day).toBe('Wednesday');
+ });
+
+ it('should return Thursday', () => {
+ const day = datetimeUtility.getDayName(new Date('07/21/2016'));
+
+ expect(day).toBe('Thursday');
+ });
+
+ it('should return Friday', () => {
+ const day = datetimeUtility.getDayName(new Date('07/22/2016'));
+
+ expect(day).toBe('Friday');
+ });
+
+ it('should return Saturday', () => {
+ const day = datetimeUtility.getDayName(new Date('07/23/2016'));
+
+ expect(day).toBe('Saturday');
+ });
+ });
+
+ describe('get day difference', () => {
+ it('should return 7', () => {
+ const firstDay = new Date('07/01/2016');
+ const secondDay = new Date('07/08/2016');
+ const difference = datetimeUtility.getDayDifference(firstDay, secondDay);
+
+ expect(difference).toBe(7);
+ });
+
+ it('should return 31', () => {
+ const firstDay = new Date('07/01/2016');
+ const secondDay = new Date('08/01/2016');
+ const difference = datetimeUtility.getDayDifference(firstDay, secondDay);
+
+ expect(difference).toBe(31);
+ });
+
+ it('should return 365', () => {
+ const firstDay = new Date('07/02/2015');
+ const secondDay = new Date('07/01/2016');
+ const difference = datetimeUtility.getDayDifference(firstDay, secondDay);
+
+ expect(difference).toBe(365);
+ });
+ });
+});
+
+describe('timeIntervalInWords', () => {
+ it('should return string with number of minutes and seconds', () => {
+ expect(datetimeUtility.timeIntervalInWords(9.54)).toEqual('9 seconds');
+ expect(datetimeUtility.timeIntervalInWords(1)).toEqual('1 second');
+ expect(datetimeUtility.timeIntervalInWords(200)).toEqual('3 minutes 20 seconds');
+ expect(datetimeUtility.timeIntervalInWords(6008)).toEqual('100 minutes 8 seconds');
+ });
+});
+
+describe('dateInWords', () => {
+ const date = new Date('07/01/2016');
+
+ it('should return date in words', () => {
+ expect(datetimeUtility.dateInWords(date)).toEqual('July 1, 2016');
+ });
+
+ it('should return abbreviated month name', () => {
+ expect(datetimeUtility.dateInWords(date, true)).toEqual('Jul 1, 2016');
+ });
+
+ it('should return date in words without year', () => {
+ expect(datetimeUtility.dateInWords(date, true, true)).toEqual('Jul 1');
+ });
+});
+
+describe('monthInWords', () => {
+ const date = new Date('2017-01-20');
+
+ it('returns month name from provided date', () => {
+ expect(datetimeUtility.monthInWords(date)).toBe('January');
+ });
+
+ it('returns abbreviated month name from provided date', () => {
+ expect(datetimeUtility.monthInWords(date, true)).toBe('Jan');
+ });
+});
+
+describe('totalDaysInMonth', () => {
+ it('returns number of days in a month for given date', () => {
+ // 1st Feb, 2016 (leap year)
+ expect(datetimeUtility.totalDaysInMonth(new Date(2016, 1, 1))).toBe(29);
+
+ // 1st Feb, 2017
+ expect(datetimeUtility.totalDaysInMonth(new Date(2017, 1, 1))).toBe(28);
+
+ // 1st Jan, 2017
+ expect(datetimeUtility.totalDaysInMonth(new Date(2017, 0, 1))).toBe(31);
+ });
+});
+
+describe('getSundays', () => {
+ it('returns array of dates representing all Sundays of the month', () => {
+ // December, 2017 (it has 5 Sundays)
+ const dateOfSundays = [3, 10, 17, 24, 31];
+ const sundays = datetimeUtility.getSundays(new Date(2017, 11, 1));
+
+ expect(sundays.length).toBe(5);
+ sundays.forEach((sunday, index) => {
+ expect(sunday.getDate()).toBe(dateOfSundays[index]);
+ });
+ });
+});
+
+describe('getTimeframeWindowFrom', () => {
+ it('returns array of date objects upto provided length start with provided startDate', () => {
+ const startDate = new Date(2018, 0, 1);
+ const mockTimeframe = [
+ new Date(2018, 0, 1),
+ new Date(2018, 1, 1),
+ new Date(2018, 2, 1),
+ new Date(2018, 3, 1),
+ new Date(2018, 4, 31),
+ ];
+ const timeframe = datetimeUtility.getTimeframeWindowFrom(startDate, 5);
+
+ expect(timeframe.length).toBe(5);
+ timeframe.forEach((timeframeItem, index) => {
+ expect(timeframeItem.getFullYear()).toBe(mockTimeframe[index].getFullYear());
+ expect(timeframeItem.getMonth()).toBe(mockTimeframe[index].getMonth());
+ expect(timeframeItem.getDate()).toBe(mockTimeframe[index].getDate());
+ });
+ });
+});
+
+describe('formatTime', () => {
+ const expectedTimestamps = [
+ [0, '00:00:00'],
+ [1000, '00:00:01'],
+ [42000, '00:00:42'],
+ [121000, '00:02:01'],
+ [10921000, '03:02:01'],
+ [108000000, '30:00:00'],
+ ];
+
+ expectedTimestamps.forEach(([milliseconds, expectedTimestamp]) => {
+ it(`formats ${milliseconds}ms as ${expectedTimestamp}`, () => {
+ expect(datetimeUtility.formatTime(milliseconds)).toBe(expectedTimestamp);
+ });
+ });
+});
+
+describe('datefix', () => {
+ describe('pad', () => {
+ it('should add a 0 when length is smaller than 2', () => {
+ expect(datetimeUtility.pad(2)).toEqual('02');
+ });
+
+ it('should not add a zero when lenght matches the default', () => {
+ expect(datetimeUtility.pad(12)).toEqual('12');
+ });
+
+ it('should add a 0 when lenght is smaller than the provided', () => {
+ expect(datetimeUtility.pad(12, 3)).toEqual('012');
+ });
+ });
+
+ describe('parsePikadayDate', () => {
+ // removed because of https://gitlab.com/gitlab-org/gitlab-ce/issues/39834
+ });
+
+ describe('pikadayToString', () => {
+ it('should format a UTC date into yyyy-mm-dd format', () => {
+ expect(datetimeUtility.pikadayToString(new Date('2020-01-29:00:00'))).toEqual('2020-01-29');
+ });
+ });
+});
+
+describe('prettyTime methods', () => {
+ const assertTimeUnits = (obj, minutes, hours, days, weeks) => {
+ expect(obj.minutes).toBe(minutes);
+ expect(obj.hours).toBe(hours);
+ expect(obj.days).toBe(days);
+ expect(obj.weeks).toBe(weeks);
+ };
+
+ describe('parseSeconds', () => {
+ it('should correctly parse a negative value', () => {
+ const zeroSeconds = datetimeUtility.parseSeconds(-1000);
+
+ assertTimeUnits(zeroSeconds, 16, 0, 0, 0);
+ });
+
+ it('should correctly parse a zero value', () => {
+ const zeroSeconds = datetimeUtility.parseSeconds(0);
+
+ assertTimeUnits(zeroSeconds, 0, 0, 0, 0);
+ });
+
+ it('should correctly parse a small non-zero second values', () => {
+ const subOneMinute = datetimeUtility.parseSeconds(10);
+ const aboveOneMinute = datetimeUtility.parseSeconds(100);
+ const manyMinutes = datetimeUtility.parseSeconds(1000);
+
+ assertTimeUnits(subOneMinute, 0, 0, 0, 0);
+ assertTimeUnits(aboveOneMinute, 1, 0, 0, 0);
+ assertTimeUnits(manyMinutes, 16, 0, 0, 0);
+ });
+
+ it('should correctly parse large second values', () => {
+ const aboveOneHour = datetimeUtility.parseSeconds(4800);
+ const aboveOneDay = datetimeUtility.parseSeconds(110000);
+ const aboveOneWeek = datetimeUtility.parseSeconds(25000000);
+
+ assertTimeUnits(aboveOneHour, 20, 1, 0, 0);
+ assertTimeUnits(aboveOneDay, 33, 6, 3, 0);
+ assertTimeUnits(aboveOneWeek, 26, 0, 3, 173);
+ });
+
+ it('should correctly accept a custom param for hoursPerDay', () => {
+ const config = { hoursPerDay: 24 };
+
+ const aboveOneHour = datetimeUtility.parseSeconds(4800, config);
+ const aboveOneDay = datetimeUtility.parseSeconds(110000, config);
+ const aboveOneWeek = datetimeUtility.parseSeconds(25000000, config);
+
+ assertTimeUnits(aboveOneHour, 20, 1, 0, 0);
+ assertTimeUnits(aboveOneDay, 33, 6, 1, 0);
+ assertTimeUnits(aboveOneWeek, 26, 8, 4, 57);
+ });
+
+ it('should correctly accept a custom param for daysPerWeek', () => {
+ const config = { daysPerWeek: 7 };
+
+ const aboveOneHour = datetimeUtility.parseSeconds(4800, config);
+ const aboveOneDay = datetimeUtility.parseSeconds(110000, config);
+ const aboveOneWeek = datetimeUtility.parseSeconds(25000000, config);
+
+ assertTimeUnits(aboveOneHour, 20, 1, 0, 0);
+ assertTimeUnits(aboveOneDay, 33, 6, 3, 0);
+ assertTimeUnits(aboveOneWeek, 26, 0, 0, 124);
+ });
+
+ it('should correctly accept custom params for daysPerWeek and hoursPerDay', () => {
+ const config = { daysPerWeek: 55, hoursPerDay: 14 };
+
+ const aboveOneHour = datetimeUtility.parseSeconds(4800, config);
+ const aboveOneDay = datetimeUtility.parseSeconds(110000, config);
+ const aboveOneWeek = datetimeUtility.parseSeconds(25000000, config);
+
+ assertTimeUnits(aboveOneHour, 20, 1, 0, 0);
+ assertTimeUnits(aboveOneDay, 33, 2, 2, 0);
+ assertTimeUnits(aboveOneWeek, 26, 0, 1, 9);
+ });
+ });
+
+ describe('stringifyTime', () => {
+ it('should stringify values with all non-zero units', () => {
+ const timeObject = {
+ weeks: 1,
+ days: 4,
+ hours: 7,
+ minutes: 20,
+ };
+
+ const timeString = datetimeUtility.stringifyTime(timeObject);
+
+ expect(timeString).toBe('1w 4d 7h 20m');
+ });
+
+ it('should stringify values with some non-zero units', () => {
+ const timeObject = {
+ weeks: 0,
+ days: 4,
+ hours: 0,
+ minutes: 20,
+ };
+
+ const timeString = datetimeUtility.stringifyTime(timeObject);
+
+ expect(timeString).toBe('4d 20m');
+ });
+
+ it('should stringify values with no non-zero units', () => {
+ const timeObject = {
+ weeks: 0,
+ days: 0,
+ hours: 0,
+ minutes: 0,
+ };
+
+ const timeString = datetimeUtility.stringifyTime(timeObject);
+
+ expect(timeString).toBe('0m');
+ });
+ });
+
+ describe('abbreviateTime', () => {
+ it('should abbreviate stringified times for weeks', () => {
+ const fullTimeString = '1w 3d 4h 5m';
+
+ expect(datetimeUtility.abbreviateTime(fullTimeString)).toBe('1w');
+ });
+
+ it('should abbreviate stringified times for non-weeks', () => {
+ const fullTimeString = '0w 3d 4h 5m';
+
+ expect(datetimeUtility.abbreviateTime(fullTimeString)).toBe('3d');
+ });
+ });
+});
+
+describe('calculateRemainingMilliseconds', () => {
+ beforeEach(() => {
+ spyOn(Date, 'now').and.callFake(() => new Date('2063-04-04T00:42:00Z').getTime());
+ });
+
+ it('calculates the remaining time for a given end date', () => {
+ const milliseconds = datetimeUtility.calculateRemainingMilliseconds('2063-04-04T01:44:03Z');
+
+ expect(milliseconds).toBe(3723000);
+ });
+
+ it('returns 0 if the end date has passed', () => {
+ const milliseconds = datetimeUtility.calculateRemainingMilliseconds('2063-04-03T00:00:00Z');
+
+ expect(milliseconds).toBe(0);
+ });
+});
diff --git a/spec/javascripts/lib/utils/dom_utils_spec.js b/spec/javascripts/lib/utils/dom_utils_spec.js
index 867bf5912d1..1fb2e4584a0 100644
--- a/spec/javascripts/lib/utils/dom_utils_spec.js
+++ b/spec/javascripts/lib/utils/dom_utils_spec.js
@@ -18,6 +18,7 @@ describe('DOM Utils', () => {
it('adds class if element exists', () => {
const childElement = parentElement.querySelector('.child');
+
expect(childElement).not.toBe(null);
addClassIfElementExists(childElement, className);
@@ -27,6 +28,7 @@ describe('DOM Utils', () => {
it('does not throw if element does not exist', () => {
const childElement = parentElement.querySelector('.other-child');
+
expect(childElement).toBe(null);
addClassIfElementExists(childElement, className);
diff --git a/spec/javascripts/lib/utils/mock_data.js b/spec/javascripts/lib/utils/mock_data.js
index 93d0d6259b9..c466b0cd1ed 100644
--- a/spec/javascripts/lib/utils/mock_data.js
+++ b/spec/javascripts/lib/utils/mock_data.js
@@ -1,5 +1,8 @@
-export const faviconDataUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACcFBMVEX////iQyniQyniQyniQyniQyniQyniQyniQynhRiriQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniRCniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQynhQiniQiniQiniQinhQinpUSjqUSjqTyjqTyjqTyjlSCniRCniQynjRCjqTyjsZSjrWyj8oib9kSb8pyb9pib8oyb8fyb3ZSb4Zib8fCb8oyb8oyb8oyb8pCb8cSbiQyn7bCb8cib8oyb8oSb8bSbtVSjpTij8nyb8oyb8oyb8lCb2Yyf3ZCf8mCb8oyb8oyb8oyb8iib8bSbiRCn8gyb8oyb8eCbpTinrUSj8oyb8oyb8oyb8pSb8bib4Zif0YCf8byb8oyb8oyb8oyb7oib8oyb8nCbjRSn9bib8ayb8nib8oyb8oyb8oyb8kSbpTyjpTyj8jib8oyb8oyb8oyb8fib0Xyf2ZSb8gCb8oyb6pSb8oyb8dib+cCbgQCnjRSn8cCb8oib8oyb8oyb8oybqUCjnSyn8bCb8oyb8oyb8oyb8myb2YyfyXyf8oyb8oyb8hibhQSn+bib8iSb8oyb8qCb+fSbmSSnqTyj8oib9pCb1YifxXyf7pSb8oCb8pCb+mCb0fCf8pSb7hSXvcSjiQyniQinqTyj9kCb9bib9byb+cCbqUSjiRCnsVCj+cSb8pib8bCb8bSbgQCn7bCb8bibjRSn8oyb8ayb8oib8aib8pCbjRCn8pybhQinhQSn8pSb7ayb7aSb6aib8eib///8IbM+7AAAAr3RSTlMBA3NtX2vT698HGQcRLwWLiXnv++3V+eEd/R8HE2V/Y5HjyefdFw99YWfJ+/3nwQP78/HvX1VTQ/kdA2HzbQXj9fX79/3DGf379/33T/v99/f7ba33+/f1+9/18/v59V339flzF/H9+fX3/fMhBwOh9/v5/fmvBV/z+fP3Awnp9/f38+UFgff7+/37+4c77/f7/flFz/f59dFr7/v98Wnr+/f3I5/197EDBU1ZAwUD8/kLUwAAAAFiS0dEAIgFHUgAAAAHdElNRQfhBQoLHiBV6/1lAAACHUlEQVQ4y41TZXsTQRCe4FAIUigN7m7FXY+iLRQKBG2x4g7BjhZ3Le7uMoEkFJprwyQk0CC/iZnNhUZaHt4vt6/szO7cHcD/wFKjZrJWq3YMq1M3eVc9rFzXR2yQkuA3RGxkjZLGiEk9miA2tURJs1RsnhhokYYtzaU13WZDbBVnW1sjo43J2vI6tZ0lLtFeAh1M0lECneI7dGYtrUtk3RUVIKaEJR25qw27yT0s3W0qEHuPlB4RradivXo7GX36xnbo51SQ+fWHARmCgYMGDxkaxbD3SssYPmIkwKgPLrfA87EETTg/fVaSa/SYsQDjSsd7DcGEsr+BieVKmaRNBsjUtClTfUI900y/5Mt05c8oJQKYSURZ2UqYFa0w283M588JEM2BuRwI5EqT8nmmXzZf4l8XsGNfCIv4QcHFklhiBpaqAsuC4tghj+ySyOdjeJYrP7RCCuR/E5tWAqxaLcmCNSyujdxjHZdbn8UHoA0bN/GoNm8hjQJb/ZzYpo6w3TB27JRduxxqrA7YzbWCezixN8RD2Oc2/Ptlfx7o5uT1A4XMiwzj4HfEikNe7+Ew0ZGjeuW70eEYaeHjxomTiKd++E4XnKGz8d+HDufOB3Ky3RcwdNF1qZiKLyf/B44r2tWf15wV143cwI2qfi8dbtKtX6Hbd+6G74EDqkTm/QcPH/0ufFyNLXjy9NnzF9Xb8BJevYY38C+8fZcg/AF3QTYemVkCwwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wNS0xMFQxMTozMDozMiswMjowMMzup8UAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDUtMTBUMTE6MzA6MzIrMDI6MDC9sx95AAAAAElFTkSuQmCC';
+export const faviconDataUrl =
+ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACcFBMVEX////iQyniQyniQyniQyniQyniQyniQyniQynhRiriQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniRCniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQyniQynhQiniQiniQiniQinhQinpUSjqUSjqTyjqTyjqTyjlSCniRCniQynjRCjqTyjsZSjrWyj8oib9kSb8pyb9pib8oyb8fyb3ZSb4Zib8fCb8oyb8oyb8oyb8pCb8cSbiQyn7bCb8cib8oyb8oSb8bSbtVSjpTij8nyb8oyb8oyb8lCb2Yyf3ZCf8mCb8oyb8oyb8oyb8iib8bSbiRCn8gyb8oyb8eCbpTinrUSj8oyb8oyb8oyb8pSb8bib4Zif0YCf8byb8oyb8oyb8oyb7oib8oyb8nCbjRSn9bib8ayb8nib8oyb8oyb8oyb8kSbpTyjpTyj8jib8oyb8oyb8oyb8fib0Xyf2ZSb8gCb8oyb6pSb8oyb8dib+cCbgQCnjRSn8cCb8oib8oyb8oyb8oybqUCjnSyn8bCb8oyb8oyb8oyb8myb2YyfyXyf8oyb8oyb8hibhQSn+bib8iSb8oyb8qCb+fSbmSSnqTyj8oib9pCb1YifxXyf7pSb8oCb8pCb+mCb0fCf8pSb7hSXvcSjiQyniQinqTyj9kCb9bib9byb+cCbqUSjiRCnsVCj+cSb8pib8bCb8bSbgQCn7bCb8bibjRSn8oyb8ayb8oib8aib8pCbjRCn8pybhQinhQSn8pSb7ayb7aSb6aib8eib///8IbM+7AAAAr3RSTlMBA3NtX2vT698HGQcRLwWLiXnv++3V+eEd/R8HE2V/Y5HjyefdFw99YWfJ+/3nwQP78/HvX1VTQ/kdA2HzbQXj9fX79/3DGf379/33T/v99/f7ba33+/f1+9/18/v59V339flzF/H9+fX3/fMhBwOh9/v5/fmvBV/z+fP3Awnp9/f38+UFgff7+/37+4c77/f7/flFz/f59dFr7/v98Wnr+/f3I5/197EDBU1ZAwUD8/kLUwAAAAFiS0dEAIgFHUgAAAAHdElNRQfhBQoLHiBV6/1lAAACHUlEQVQ4y41TZXsTQRCe4FAIUigN7m7FXY+iLRQKBG2x4g7BjhZ3Le7uMoEkFJprwyQk0CC/iZnNhUZaHt4vt6/szO7cHcD/wFKjZrJWq3YMq1M3eVc9rFzXR2yQkuA3RGxkjZLGiEk9miA2tURJs1RsnhhokYYtzaU13WZDbBVnW1sjo43J2vI6tZ0lLtFeAh1M0lECneI7dGYtrUtk3RUVIKaEJR25qw27yT0s3W0qEHuPlB4RradivXo7GX36xnbo51SQ+fWHARmCgYMGDxkaxbD3SssYPmIkwKgPLrfA87EETTg/fVaSa/SYsQDjSsd7DcGEsr+BieVKmaRNBsjUtClTfUI900y/5Mt05c8oJQKYSURZ2UqYFa0w283M588JEM2BuRwI5EqT8nmmXzZf4l8XsGNfCIv4QcHFklhiBpaqAsuC4tghj+ySyOdjeJYrP7RCCuR/E5tWAqxaLcmCNSyujdxjHZdbn8UHoA0bN/GoNm8hjQJb/ZzYpo6w3TB27JRduxxqrA7YzbWCezixN8RD2Oc2/Ptlfx7o5uT1A4XMiwzj4HfEikNe7+Ew0ZGjeuW70eEYaeHjxomTiKd++E4XnKGz8d+HDufOB3Ky3RcwdNF1qZiKLyf/B44r2tWf15wV143cwI2qfi8dbtKtX6Hbd+6G74EDqkTm/QcPH/0ufFyNLXjy9NnzF9Xb8BJevYY38C+8fZcg/AF3QTYemVkCwwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNy0wNS0xMFQxMTozMDozMiswMjowMMzup8UAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTctMDUtMTBUMTE6MzA6MzIrMDI6MDC9sx95AAAAAElFTkSuQmCC';
-export const overlayDataUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAA85JREFUWAntVllIVGEUPv/9b46O41KplYN7PeRkti8TjQlhCUGh3MmeQugpIsGKAi2soIcIooiohxYKK2daqDAlIpIiWwxtQaJcaHE0d5tMrbn37z9XRqfR0TvVW56Hudf//uec72zfEWBCJjIwkYGJDPzvGSD/KgExN3Oi2Q+2DJgSDYQEMwItVGH1iZGmJw/Si1y+/PwVAMYYib22MYc/8hVQFgKDEfYoId0KYzagAQebsos/ewMZoeB9wdffcTYpQSaCTWHKoqSQaDk7zkIt0+aCUR8BelEHrf3dUNv9AcqbnsHtT5UKB/hTASh0SLYjnjb/CIDRJi0XiFAaJOpCD8zLpdb4NB66b1OfelthX815dtdRRfiti2aAXLvVLiMQ6olGyztGDkSo4JGGXk8/QFdGpYzpHG2GBQTDhtgVhPEaVbbVpvI6GJz22rv4TcAfrYI1x7Rj5MWWAppomKFVVb2302SFzUkZHAbkG+0b1+Gh77yNYjrmqnWTrLBLRxdvBWv8qlFujH/kYjJYyvLkj71t78zAUvzMAMnHhpN4zf9UREJhd8omyssxu1IgazQDwDnHUcNuH6vhPIE1fmuBzHt74Hn7W89jWGtcAjoaIDOFrdcMYJBkgOCoaRF0Lj0oglddDbCj6tRvKjphEpgjkzEQs2YAKsNxMzjn3nKurhzK+Ly7xe28ua8TwgMMcHJZnvvT0BPtEEKM4tDJ+C8GvIIk4ylINIXVZ0EUKJxYuh3mhCeokbudl6TtVc88dfBdLwbyaWB6zQCYQJpBYSrDGQxBQ/ZWRM2B+VNmQnVnHWx7elyNuL2/R336co7KyJR8CL9oLgEuFlREevWUkEl6uGwpVEG4FBm0OEf9N10NMgPlvWYAuNVwsWDKvcUNYsHUWTCZ13ysyFEXe6TO6aC8CUr9IiK+A05TQrc8yjwmxARHeeMAPlfQJw+AQRwu0YhL/GDXi9NwufG+S8dYkuYMqIb4SsWthotlNMOUCOM6r+G9cqXxPmd1dqrBav/o1zJy2l5/NUjJA/VORwYuFnOUaTQcPs9wMqwV++Xv8oADxKAcZ8nLPr8AoGW+xR6HSqYk3GodAz2QNj0V+Gr26dT9ASNH5239Pf0gktVNWZca8ZvfAFBprWS6hSu1pqt++Y0PD+WIwDAhIWQGtzvSHDbcodfFUFB9hg1Gjs5LXqIdFL+acFBl+FddqYwdxsWC3I70OvgfUaA65zhq2O2c8VxYcyIGFTVlXegYtvCXANCQZJMobjVcLMjtSK/IcEgyOOe8Ve5w7ryKDefp2P3+C/5ohv8HZmVLAAAAAElFTkSuQmCC';
+export const overlayDataUrl =
+ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAA85JREFUWAntVllIVGEUPv/9b46O41KplYN7PeRkti8TjQlhCUGh3MmeQugpIsGKAi2soIcIooiohxYKK2daqDAlIpIiWwxtQaJcaHE0d5tMrbn37z9XRqfR0TvVW56Hudf//uec72zfEWBCJjIwkYGJDPzvGSD/KgExN3Oi2Q+2DJgSDYQEMwItVGH1iZGmJw/Si1y+/PwVAMYYib22MYc/8hVQFgKDEfYoId0KYzagAQebsos/ewMZoeB9wdffcTYpQSaCTWHKoqSQaDk7zkIt0+aCUR8BelEHrf3dUNv9AcqbnsHtT5UKB/hTASh0SLYjnjb/CIDRJi0XiFAaJOpCD8zLpdb4NB66b1OfelthX815dtdRRfiti2aAXLvVLiMQ6olGyztGDkSo4JGGXk8/QFdGpYzpHG2GBQTDhtgVhPEaVbbVpvI6GJz22rv4TcAfrYI1x7Rj5MWWAppomKFVVb2302SFzUkZHAbkG+0b1+Gh77yNYjrmqnWTrLBLRxdvBWv8qlFujH/kYjJYyvLkj71t78zAUvzMAMnHhpN4zf9UREJhd8omyssxu1IgazQDwDnHUcNuH6vhPIE1fmuBzHt74Hn7W89jWGtcAjoaIDOFrdcMYJBkgOCoaRF0Lj0oglddDbCj6tRvKjphEpgjkzEQs2YAKsNxMzjn3nKurhzK+Ly7xe28ua8TwgMMcHJZnvvT0BPtEEKM4tDJ+C8GvIIk4ylINIXVZ0EUKJxYuh3mhCeokbudl6TtVc88dfBdLwbyaWB6zQCYQJpBYSrDGQxBQ/ZWRM2B+VNmQnVnHWx7elyNuL2/R336co7KyJR8CL9oLgEuFlREevWUkEl6uGwpVEG4FBm0OEf9N10NMgPlvWYAuNVwsWDKvcUNYsHUWTCZ13ysyFEXe6TO6aC8CUr9IiK+A05TQrc8yjwmxARHeeMAPlfQJw+AQRwu0YhL/GDXi9NwufG+S8dYkuYMqIb4SsWthotlNMOUCOM6r+G9cqXxPmd1dqrBav/o1zJy2l5/NUjJA/VORwYuFnOUaTQcPs9wMqwV++Xv8oADxKAcZ8nLPr8AoGW+xR6HSqYk3GodAz2QNj0V+Gr26dT9ASNH5239Pf0gktVNWZca8ZvfAFBprWS6hSu1pqt++Y0PD+WIwDAhIWQGtzvSHDbcodfFUFB9hg1Gjs5LXqIdFL+acFBl+FddqYwdxsWC3I70OvgfUaA65zhq2O2c8VxYcyIGFTVlXegYtvCXANCQZJMobjVcLMjtSK/IcEgyOOe8Ve5w7ryKDefp2P3+C/5ohv8HZmVLAAAAAElFTkSuQmCC';
-export const faviconWithOverlayDataUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAGtElEQVRYR8WXf3CT9R3H35/nSdIQIktrCf0RStI0FYRjVBAccxTq5MDBKUoz4ZyjbPO87q4yBsPDMdExTjlvIsdQexyI0oMBeuKhdjsNHhwcMgpjIlublLIm/UlJKZSSJs/z/e6+T5v0CQ22wB/7/pPck8/383l9fj6fEOec8H88NAjAS1LwknsFSVLU8WXd1rtm85LUeKnwGQKzjj3s33azvsEAAEIlnn8ByHL4/Pa7BgAQLCm8QOBOh88vDQkQeMxjMkcQEYKqYsyJWWPhgs/80TsFafzROJtkNIXFfYI0pfXqPeennjqlxPUNikBoTuEmEF+lCRBV3G0aQiWFrwH8d30AWJubGdiEfZzdGqDEEwbICnADQGGHry7zTr0X94IlnnMACggwAWh0+PxOvb5EBGqmTTNkj7ySxWS62C+g5Usm1Zn95YXG24UQ+r5n75Li6Ux4LBkyc7/4t5YSLSr6Lgg9UvBLcKocMEYKON/gGB3YoA/bcGFCczzLQdieLE9bHL66FakBSjzCU0cSAHDa4at7aLhG9XLBEk8zAVnxZxyIEhBy+PwFgwAafpxvNzK5NZUhrX28JA07Cl6SmtvcOUwm4ZAouHj7ad+jMrN1dqb3iG7oS4EYPh2etQS+XiesC8TQ3ZD3yZJsHuUPgbMcI+ej5v3ncv5PasNlk1p7JJnzJL+I0/O5h+u0VCdqIDi78AQRHuirft3hYJzQPvawPydVdPI+/OnTnNNKBjYVXHRa8rFFGeb4w1he0wZ7d/84IXTEhxzxUsgitB2LPFGwvgGUfLSeZUpEXqEqrIdz0nr4iHOUfeOccb/tNMtutzWHPeWcJc0aMxm5lkxYDGloj1zB+Sv/RXXTSXzaeBwSY3j+bHNv2bdtMYCbpHtRkNFd36xFQN3tXkZhvgP1fdPi5kMEXL4oIXKVAA58M8aCVQs84BYLXi5aDq+zGJTqYr+i4PV2vHxmJ/7WUoOn2i/jz6yhW7JjrdSV8U4fQFV+I2Q4UIsedMCSSlcsgp72WtnSajOhzDsBNtsYfFD8e+Rbs4fdIG98uw9vnj+AX7FWvk4NHZOXXphF/INx2SpJIU2L8L4GDAoMwlP9kWSg6awcKVs83tyUnY5Dj75+W8bjutae3o5d9X/HTiWAuUtOS6RUOR8Hp48TxjgU/AMSeKJ1Ej/tMWXG1sxwGt98sBxe5+xhe64XVLiK2Z9XwNgdRLXyzQsC4ENwelIHAFxDBOdh1qdCdNLCoon8RnY+HZ6/+TtzPhTZweAxlJ94C5VqoI2U3a7rACzJjQqgBd24CGscos1kxPQZ38fqSU/jhQkDvN9lrKG7FeUnNuPVKcvwYOb4hGgvi2HSx8vwRKyJkVLl+hk43gdBAcfADBD1cA4RXIdZ1EN1Zjqem+DGoUc2oigjMUlvaV8YL/1qPVpuhOG+JwdH5m1Okn3m6Eacaz3V2jeI9uTbVYY6AKOSKw8MX0MBg2lXjh3r3Hk4s7ASdrMtSWxnoBpZIzIwP3e69lxv3Gay4q/F6zDJ5kq6s6amEnsafJ0Db8P9JKkx1w5wPJuY36IToojgNMzb8rLwmsuB2kW7YDWMSCgTg+YXx9+AQZKxdUaFZiju+a2Mi8uvnH0f2/2f9g4AVE4z4LlTilrlehag9xIpEam4jO4DXfdaV97nwtH5byW137VYD5Yc2YAz4YAGIYx2RLq0z1Sex8l//fUWfBI83jh4Kd1PEuAwqVGjWEwSS+nJJmt0sWu86d0frMQCR/LbWQ8hDAxlXMgUV69Q67ubv0q5FUNAlHKmVLnXE/gfREpUiaQHqAizXbO0UN98BMTSo39Cw7UW7E2Rc728qJGHP68ASbQyNYCQTkAUzCSwQ+CwvSjnsQPGLOnI/C0YO3Lwxq5yhhtqb1KNpGqT1TXvigJU0jh33xpAf7NymoGNDJ9sJtPkYuNkqTh7KnY8vGaoeZPy93+GA1joe4kzzv/SVLqvYngA/dFgVfnlb8tjtm6Ux+I39y/Gqone24IQM+GxL15UO3q7WrhsnhJatCs8PAC9md3OrPK0goaDyEj7uXsuXi0qg4HkIUGE52XHNqmXIl0RGOiHoUV7xb+v5K14SC39At79Ximdhc8ekjImuiyjsXryUszLnY40yThIhSi4bbUHsbfBJ6ZKE5dpQdz4HQOgf2a8tLvklY+M6cuvSnJummxSZ46+X+7biMzaRnSu84IauNYsE5HCOX+HDCPWi7DrKW8/BTcVZ2UN8Me57kc5448TaCYR5XJwC0BtHMwPjs/SgAP1pfuCqSL8Pxhr/wunLWAOAAAAAElFTkSuQmCC';
+export const faviconWithOverlayDataUrl =
+ 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAGtElEQVRYR8WXf3CT9R3H35/nSdIQIktrCf0RStI0FYRjVBAccxTq5MDBKUoz4ZyjbPO87q4yBsPDMdExTjlvIsdQexyI0oMBeuKhdjsNHhwcMgpjIlublLIm/UlJKZSSJs/z/e6+T5v0CQ22wB/7/pPck8/383l9fj6fEOec8H88NAjAS1LwknsFSVLU8WXd1rtm85LUeKnwGQKzjj3s33azvsEAAEIlnn8ByHL4/Pa7BgAQLCm8QOBOh88vDQkQeMxjMkcQEYKqYsyJWWPhgs/80TsFafzROJtkNIXFfYI0pfXqPeennjqlxPUNikBoTuEmEF+lCRBV3G0aQiWFrwH8d30AWJubGdiEfZzdGqDEEwbICnADQGGHry7zTr0X94IlnnMACggwAWh0+PxOvb5EBGqmTTNkj7ySxWS62C+g5Usm1Zn95YXG24UQ+r5n75Li6Ux4LBkyc7/4t5YSLSr6Lgg9UvBLcKocMEYKON/gGB3YoA/bcGFCczzLQdieLE9bHL66FakBSjzCU0cSAHDa4at7aLhG9XLBEk8zAVnxZxyIEhBy+PwFgwAafpxvNzK5NZUhrX28JA07Cl6SmtvcOUwm4ZAouHj7ad+jMrN1dqb3iG7oS4EYPh2etQS+XiesC8TQ3ZD3yZJsHuUPgbMcI+ej5v3ncv5PasNlk1p7JJnzJL+I0/O5h+u0VCdqIDi78AQRHuirft3hYJzQPvawPydVdPI+/OnTnNNKBjYVXHRa8rFFGeb4w1he0wZ7d/84IXTEhxzxUsgitB2LPFGwvgGUfLSeZUpEXqEqrIdz0nr4iHOUfeOccb/tNMtutzWHPeWcJc0aMxm5lkxYDGloj1zB+Sv/RXXTSXzaeBwSY3j+bHNv2bdtMYCbpHtRkNFd36xFQN3tXkZhvgP1fdPi5kMEXL4oIXKVAA58M8aCVQs84BYLXi5aDq+zGJTqYr+i4PV2vHxmJ/7WUoOn2i/jz6yhW7JjrdSV8U4fQFV+I2Q4UIsedMCSSlcsgp72WtnSajOhzDsBNtsYfFD8e+Rbs4fdIG98uw9vnj+AX7FWvk4NHZOXXphF/INx2SpJIU2L8L4GDAoMwlP9kWSg6awcKVs83tyUnY5Dj75+W8bjutae3o5d9X/HTiWAuUtOS6RUOR8Hp48TxjgU/AMSeKJ1Ej/tMWXG1sxwGt98sBxe5+xhe64XVLiK2Z9XwNgdRLXyzQsC4ENwelIHAFxDBOdh1qdCdNLCoon8RnY+HZ6/+TtzPhTZweAxlJ94C5VqoI2U3a7rACzJjQqgBd24CGscos1kxPQZ38fqSU/jhQkDvN9lrKG7FeUnNuPVKcvwYOb4hGgvi2HSx8vwRKyJkVLl+hk43gdBAcfADBD1cA4RXIdZ1EN1Zjqem+DGoUc2oigjMUlvaV8YL/1qPVpuhOG+JwdH5m1Okn3m6Eacaz3V2jeI9uTbVYY6AKOSKw8MX0MBg2lXjh3r3Hk4s7ASdrMtSWxnoBpZIzIwP3e69lxv3Gay4q/F6zDJ5kq6s6amEnsafJ0Db8P9JKkx1w5wPJuY36IToojgNMzb8rLwmsuB2kW7YDWMSCgTg+YXx9+AQZKxdUaFZiju+a2Mi8uvnH0f2/2f9g4AVE4z4LlTilrlehag9xIpEam4jO4DXfdaV97nwtH5byW137VYD5Yc2YAz4YAGIYx2RLq0z1Sex8l//fUWfBI83jh4Kd1PEuAwqVGjWEwSS+nJJmt0sWu86d0frMQCR/LbWQ8hDAxlXMgUV69Q67ubv0q5FUNAlHKmVLnXE/gfREpUiaQHqAizXbO0UN98BMTSo39Cw7UW7E2Rc728qJGHP68ASbQyNYCQTkAUzCSwQ+CwvSjnsQPGLOnI/C0YO3Lwxq5yhhtqb1KNpGqT1TXvigJU0jh33xpAf7NymoGNDJ9sJtPkYuNkqTh7KnY8vGaoeZPy93+GA1joe4kzzv/SVLqvYngA/dFgVfnlb8tjtm6Ux+I39y/Gqone24IQM+GxL15UO3q7WrhsnhJatCs8PAC9md3OrPK0goaDyEj7uXsuXi0qg4HkIUGE52XHNqmXIl0RGOiHoUV7xb+v5K14SC39At79Ximdhc8ekjImuiyjsXryUszLnY40yThIhSi4bbUHsbfBJ6ZKE5dpQdz4HQOgf2a8tLvklY+M6cuvSnJummxSZ46+X+7biMzaRnSu84IauNYsE5HCOX+HDCPWi7DrKW8/BTcVZ2UN8Me57kc5448TaCYR5XJwC0BtHMwPjs/SgAP1pfuCqSL8Pxhr/wunLWAOAAAAAElFTkSuQmCC';
diff --git a/spec/javascripts/lib/utils/number_utility_spec.js b/spec/javascripts/lib/utils/number_utility_spec.js
index fcf27f6805f..a5099a2a3b8 100644
--- a/spec/javascripts/lib/utils/number_utility_spec.js
+++ b/spec/javascripts/lib/utils/number_utility_spec.js
@@ -10,6 +10,7 @@ describe('Number Utils', () => {
const formattedNumber = formatRelevantDigits('1000.1234567');
const rightFromDecimal = formattedNumber.split('.')[1];
const leftFromDecimal = formattedNumber.split('.')[0];
+
expect(rightFromDecimal.length).toBe(4);
expect(leftFromDecimal.length).toBe(4);
});
@@ -18,6 +19,7 @@ describe('Number Utils', () => {
const formattedNumber = formatRelevantDigits('0.1234567');
const rightFromDecimal = formattedNumber.split('.')[1];
const leftFromDecimal = formattedNumber.split('.')[0];
+
expect(rightFromDecimal.length).toBe(3);
expect(leftFromDecimal.length).toBe(1);
});
@@ -26,6 +28,7 @@ describe('Number Utils', () => {
const formattedNumber = formatRelevantDigits('10.1234567');
const rightFromDecimal = formattedNumber.split('.')[1];
const leftFromDecimal = formattedNumber.split('.')[0];
+
expect(rightFromDecimal.length).toBe(2);
expect(leftFromDecimal.length).toBe(2);
});
@@ -34,6 +37,7 @@ describe('Number Utils', () => {
const formattedNumber = formatRelevantDigits('100.1234567');
const rightFromDecimal = formattedNumber.split('.')[1];
const leftFromDecimal = formattedNumber.split('.')[0];
+
expect(rightFromDecimal.length).toBe(1);
expect(leftFromDecimal.length).toBe(3);
});
diff --git a/spec/javascripts/lib/utils/poll_spec.js b/spec/javascripts/lib/utils/poll_spec.js
index b28a052902e..d0da659c3d7 100644
--- a/spec/javascripts/lib/utils/poll_spec.js
+++ b/spec/javascripts/lib/utils/poll_spec.js
@@ -47,7 +47,7 @@ describe('Poll', () => {
service.fetch.calls.reset();
});
- it('calls the success callback when no header for interval is provided', (done) => {
+ it('calls the success callback when no header for interval is provided', done => {
mockServiceCall(service, { status: 200 });
setup();
@@ -59,7 +59,7 @@ describe('Poll', () => {
});
});
- it('calls the error callback when the http request returns an error', (done) => {
+ it('calls the error callback when the http request returns an error', done => {
mockServiceCall(service, { status: 500 }, true);
setup();
@@ -71,7 +71,7 @@ describe('Poll', () => {
});
});
- it('skips the error callback when request is aborted', (done) => {
+ it('skips the error callback when request is aborted', done => {
mockServiceCall(service, { status: 0 }, true);
setup();
@@ -84,19 +84,21 @@ describe('Poll', () => {
});
});
- it('should call the success callback when the interval header is -1', (done) => {
+ it('should call the success callback when the interval header is -1', done => {
mockServiceCall(service, { status: 200, headers: { 'poll-interval': -1 } });
- setup().then(() => {
- expect(callbacks.success).toHaveBeenCalled();
- expect(callbacks.error).not.toHaveBeenCalled();
+ setup()
+ .then(() => {
+ expect(callbacks.success).toHaveBeenCalled();
+ expect(callbacks.error).not.toHaveBeenCalled();
- done();
- }).catch(done.fail);
+ done();
+ })
+ .catch(done.fail);
});
describe('for 2xx status code', () => {
successCodes.forEach(httpCode => {
- it(`starts polling when http status is ${httpCode} and interval header is provided`, (done) => {
+ it(`starts polling when http status is ${httpCode} and interval header is provided`, done => {
mockServiceCall(service, { status: httpCode, headers: { 'poll-interval': 1 } });
const Polling = new Poll({
@@ -124,7 +126,7 @@ describe('Poll', () => {
});
describe('stop', () => {
- it('stops polling when method is called', (done) => {
+ it('stops polling when method is called', done => {
mockServiceCall(service, { status: 200, headers: { 'poll-interval': 1 } });
const Polling = new Poll({
@@ -152,7 +154,7 @@ describe('Poll', () => {
});
describe('restart', () => {
- it('should restart polling when its called', (done) => {
+ it('should restart polling when its called', done => {
mockServiceCall(service, { status: 200, headers: { 'poll-interval': 1 } });
const Polling = new Poll({
diff --git a/spec/javascripts/lib/utils/sticky_spec.js b/spec/javascripts/lib/utils/sticky_spec.js
index b87c836654d..1b1e7da1ed3 100644
--- a/spec/javascripts/lib/utils/sticky_spec.js
+++ b/spec/javascripts/lib/utils/sticky_spec.js
@@ -22,25 +22,19 @@ describe('sticky', () => {
isSticky(el, 0, el.offsetTop);
isSticky(el, 0, el.offsetTop);
- expect(
- el.classList.contains('is-stuck'),
- ).toBeTruthy();
+ expect(el.classList.contains('is-stuck')).toBeTruthy();
});
it('adds is-stuck class', () => {
isSticky(el, 0, el.offsetTop);
- expect(
- el.classList.contains('is-stuck'),
- ).toBeTruthy();
+ expect(el.classList.contains('is-stuck')).toBeTruthy();
});
it('inserts placeholder element', () => {
isSticky(el, 0, el.offsetTop, true);
- expect(
- document.querySelector('.sticky-placeholder'),
- ).not.toBeNull();
+ expect(document.querySelector('.sticky-placeholder')).not.toBeNull();
});
});
@@ -51,29 +45,22 @@ describe('sticky', () => {
isSticky(el, 0, el.offsetTop);
isSticky(el, 0, 0);
- expect(
- el.classList.remove,
- ).toHaveBeenCalledWith('is-stuck');
- expect(
- el.classList.contains('is-stuck'),
- ).toBeFalsy();
+ expect(el.classList.remove).toHaveBeenCalledWith('is-stuck');
+
+ expect(el.classList.contains('is-stuck')).toBeFalsy();
});
it('does not add is-stuck class', () => {
isSticky(el, 0, 0);
- expect(
- el.classList.contains('is-stuck'),
- ).toBeFalsy();
+ expect(el.classList.contains('is-stuck')).toBeFalsy();
});
it('removes placeholder', () => {
isSticky(el, 0, el.offsetTop, true);
isSticky(el, 0, 0, true);
- expect(
- document.querySelector('.sticky-placeholder'),
- ).toBeNull();
+ expect(document.querySelector('.sticky-placeholder')).toBeNull();
});
});
});
diff --git a/spec/javascripts/lib/utils/text_markdown_spec.js b/spec/javascripts/lib/utils/text_markdown_spec.js
index 043dd018e0c..b9e805628f8 100644
--- a/spec/javascripts/lib/utils/text_markdown_spec.js
+++ b/spec/javascripts/lib/utils/text_markdown_spec.js
@@ -21,7 +21,14 @@ describe('init markdown', () => {
textArea.selectionStart = 0;
textArea.selectionEnd = 0;
- insertMarkdownText({ textArea, text: textArea.value, tag: '*', blockTag: null, selected: '', wrap: false });
+ insertMarkdownText({
+ textArea,
+ text: textArea.value,
+ tag: '*',
+ blockTag: null,
+ selected: '',
+ wrap: false,
+ });
expect(textArea.value).toEqual(`${initialValue}* `);
});
@@ -32,7 +39,14 @@ describe('init markdown', () => {
textArea.value = initialValue;
textArea.setSelectionRange(initialValue.length, initialValue.length);
- insertMarkdownText({ textArea, text: textArea.value, tag: '*', blockTag: null, selected: '', wrap: false });
+ insertMarkdownText({
+ textArea,
+ text: textArea.value,
+ tag: '*',
+ blockTag: null,
+ selected: '',
+ wrap: false,
+ });
expect(textArea.value).toEqual(`${initialValue}\n* `);
});
@@ -43,7 +57,14 @@ describe('init markdown', () => {
textArea.value = initialValue;
textArea.setSelectionRange(initialValue.length, initialValue.length);
- insertMarkdownText({ textArea, text: textArea.value, tag: '*', blockTag: null, selected: '', wrap: false });
+ insertMarkdownText({
+ textArea,
+ text: textArea.value,
+ tag: '*',
+ blockTag: null,
+ selected: '',
+ wrap: false,
+ });
expect(textArea.value).toEqual(`${initialValue}* `);
});
@@ -54,7 +75,14 @@ describe('init markdown', () => {
textArea.value = initialValue;
textArea.setSelectionRange(initialValue.length, initialValue.length);
- insertMarkdownText({ textArea, text: textArea.value, tag: '*', blockTag: null, selected: '', wrap: false });
+ insertMarkdownText({
+ textArea,
+ text: textArea.value,
+ tag: '*',
+ blockTag: null,
+ selected: '',
+ wrap: false,
+ });
expect(textArea.value).toEqual(`${initialValue}* `);
});
@@ -70,13 +98,27 @@ describe('init markdown', () => {
});
it('applies the tag to the selected value', () => {
- insertMarkdownText({ textArea, text: textArea.value, tag: '*', blockTag: null, selected, wrap: true });
+ insertMarkdownText({
+ textArea,
+ text: textArea.value,
+ tag: '*',
+ blockTag: null,
+ selected,
+ wrap: true,
+ });
expect(textArea.value).toEqual(text.replace(selected, `*${selected}*`));
});
it('replaces the placeholder in the tag', () => {
- insertMarkdownText({ textArea, text: textArea.value, tag: '[{text}](url)', blockTag: null, selected, wrap: false });
+ insertMarkdownText({
+ textArea,
+ text: textArea.value,
+ tag: '[{text}](url)',
+ blockTag: null,
+ selected,
+ wrap: false,
+ });
expect(textArea.value).toEqual(text.replace(selected, `[${selected}](url)`));
});
@@ -86,15 +128,18 @@ describe('init markdown', () => {
const select = 'url';
it('selects the text', () => {
- insertMarkdownText({ textArea,
+ insertMarkdownText({
+ textArea,
text: textArea.value,
tag,
blockTag: null,
selected,
wrap: false,
- select });
+ select,
+ });
const expectedText = text.replace(selected, `[${selected}](url)`);
+
expect(textArea.value).toEqual(expectedText);
expect(textArea.selectionStart).toEqual(expectedText.indexOf(select));
expect(textArea.selectionEnd).toEqual(expectedText.indexOf(select) + select.length);
@@ -105,19 +150,49 @@ describe('init markdown', () => {
textArea.value = initialValue;
const selectedIndex = initialValue.indexOf(selected);
textArea.setSelectionRange(selectedIndex, selectedIndex + selected.length);
- insertMarkdownText({ textArea,
+ insertMarkdownText({
+ textArea,
text: textArea.value,
tag,
blockTag: null,
selected,
wrap: false,
- select });
+ select,
+ });
const expectedText = initialValue.replace(selected, `[${selected}](url)`);
+
expect(textArea.value).toEqual(expectedText);
expect(textArea.selectionStart).toEqual(expectedText.lastIndexOf(select));
expect(textArea.selectionEnd).toEqual(expectedText.lastIndexOf(select) + select.length);
});
+
+ it('should support selected urls', () => {
+ const expectedUrl = 'http://www.gitlab.com';
+ const expectedSelectionText = 'text';
+ const expectedText = `text [${expectedSelectionText}](${expectedUrl}) text`;
+ const initialValue = `text ${expectedUrl} text`;
+
+ textArea.value = initialValue;
+ const selectedIndex = initialValue.indexOf(expectedUrl);
+ textArea.setSelectionRange(selectedIndex, selectedIndex + expectedUrl.length);
+
+ insertMarkdownText({
+ textArea,
+ text: textArea.value,
+ tag,
+ blockTag: null,
+ selected: expectedUrl,
+ wrap: false,
+ select,
+ });
+
+ expect(textArea.value).toEqual(expectedText);
+ expect(textArea.selectionStart).toEqual(expectedText.indexOf(expectedSelectionText, 1));
+ expect(textArea.selectionEnd).toEqual(
+ expectedText.indexOf(expectedSelectionText, 1) + expectedSelectionText.length,
+ );
+ });
});
});
});
diff --git a/spec/javascripts/lib/utils/users_cache_spec.js b/spec/javascripts/lib/utils/users_cache_spec.js
index 50371c8c5f6..6adc19bdd51 100644
--- a/spec/javascripts/lib/utils/users_cache_spec.js
+++ b/spec/javascripts/lib/utils/users_cache_spec.js
@@ -6,12 +6,12 @@ describe('UsersCache', () => {
const dummyUser = 'has a farm';
beforeEach(() => {
- UsersCache.internalStorage = { };
+ UsersCache.internalStorage = {};
});
describe('get', () => {
it('returns undefined for empty cache', () => {
- expect(UsersCache.internalStorage).toEqual({ });
+ expect(UsersCache.internalStorage).toEqual({});
const user = UsersCache.get(dummyUsername);
@@ -37,7 +37,7 @@ describe('UsersCache', () => {
describe('hasData', () => {
it('returns false for empty cache', () => {
- expect(UsersCache.internalStorage).toEqual({ });
+ expect(UsersCache.internalStorage).toEqual({});
expect(UsersCache.hasData(dummyUsername)).toBe(false);
});
@@ -57,11 +57,11 @@ describe('UsersCache', () => {
describe('remove', () => {
it('does nothing if cache is empty', () => {
- expect(UsersCache.internalStorage).toEqual({ });
+ expect(UsersCache.internalStorage).toEqual({});
UsersCache.remove(dummyUsername);
- expect(UsersCache.internalStorage).toEqual({ });
+ expect(UsersCache.internalStorage).toEqual({});
});
it('does nothing if cache contains no matching data', () => {
@@ -77,7 +77,7 @@ describe('UsersCache', () => {
UsersCache.remove(dummyUsername);
- expect(UsersCache.internalStorage).toEqual({ });
+ expect(UsersCache.internalStorage).toEqual({});
});
});
@@ -88,7 +88,7 @@ describe('UsersCache', () => {
spyOn(Api, 'users').and.callFake((query, options) => apiSpy(query, options));
});
- it('stores and returns data from API call if cache is empty', (done) => {
+ it('stores and returns data from API call if cache is empty', done => {
apiSpy = (query, options) => {
expect(query).toBe('');
expect(options).toEqual({ username: dummyUsername });
@@ -98,15 +98,15 @@ describe('UsersCache', () => {
};
UsersCache.retrieve(dummyUsername)
- .then((user) => {
- expect(user).toBe(dummyUser);
- expect(UsersCache.internalStorage[dummyUsername]).toBe(dummyUser);
- })
- .then(done)
- .catch(done.fail);
+ .then(user => {
+ expect(user).toBe(dummyUser);
+ expect(UsersCache.internalStorage[dummyUsername]).toBe(dummyUser);
+ })
+ .then(done)
+ .catch(done.fail);
});
- it('returns undefined if Ajax call fails and cache is empty', (done) => {
+ it('returns undefined if Ajax call fails and cache is empty', done => {
const dummyError = new Error('server exploded');
apiSpy = (query, options) => {
expect(query).toBe('');
@@ -115,24 +115,24 @@ describe('UsersCache', () => {
};
UsersCache.retrieve(dummyUsername)
- .then(user => fail(`Received unexpected user: ${JSON.stringify(user)}`))
- .catch((error) => {
- expect(error).toBe(dummyError);
- })
- .then(done)
- .catch(done.fail);
+ .then(user => fail(`Received unexpected user: ${JSON.stringify(user)}`))
+ .catch(error => {
+ expect(error).toBe(dummyError);
+ })
+ .then(done)
+ .catch(done.fail);
});
- it('makes no Ajax call if matching data exists', (done) => {
+ it('makes no Ajax call if matching data exists', done => {
UsersCache.internalStorage[dummyUsername] = dummyUser;
apiSpy = () => fail(new Error('expected no Ajax call!'));
UsersCache.retrieve(dummyUsername)
- .then((user) => {
- expect(user).toBe(dummyUser);
- })
- .then(done)
- .catch(done.fail);
+ .then(user => {
+ expect(user).toBe(dummyUser);
+ })
+ .then(done)
+ .catch(done.fail);
});
});
});
diff --git a/spec/javascripts/line_highlighter_spec.js b/spec/javascripts/line_highlighter_spec.js
index c32ecb17e89..4eea364bd69 100644
--- a/spec/javascripts/line_highlighter_spec.js
+++ b/spec/javascripts/line_highlighter_spec.js
@@ -1,226 +1,265 @@
-/* eslint-disable no-var, prefer-template, no-else-return, dot-notation, no-return-assign, no-new, one-var, no-underscore-dangle */
+/* eslint-disable no-var, prefer-template, no-else-return, dot-notation, no-return-assign, no-new, no-underscore-dangle */
import $ from 'jquery';
import LineHighlighter from '~/line_highlighter';
-(function() {
- describe('LineHighlighter', function() {
- var clickLine;
- preloadFixtures('static/line_highlighter.html.raw');
- clickLine = function(number, eventData = {}) {
- if ($.isEmptyObject(eventData)) {
- return $("#L" + number).click();
- } else {
- const e = $.Event('click', eventData);
- return $("#L" + number).trigger(e);
+describe('LineHighlighter', function() {
+ var clickLine;
+ preloadFixtures('static/line_highlighter.html.raw');
+ clickLine = function(number, eventData = {}) {
+ if ($.isEmptyObject(eventData)) {
+ return $('#L' + number).click();
+ } else {
+ const e = $.Event('click', eventData);
+ return $('#L' + number).trigger(e);
+ }
+ };
+ beforeEach(function() {
+ loadFixtures('static/line_highlighter.html.raw');
+ this['class'] = new LineHighlighter();
+ this.css = this['class'].highlightLineClass;
+ return (this.spies = {
+ __setLocationHash__: spyOn(this['class'], '__setLocationHash__').and.callFake(function() {}),
+ });
+ });
+
+ describe('behavior', function() {
+ it('highlights one line given in the URL hash', function() {
+ new LineHighlighter({ hash: '#L13' });
+
+ expect($('#LC13')).toHaveClass(this.css);
+ });
+
+ it('highlights one line given in the URL hash with given CSS class name', function() {
+ const hiliter = new LineHighlighter({ hash: '#L13', highlightLineClass: 'hilite' });
+
+ expect(hiliter.highlightLineClass).toBe('hilite');
+ expect($('#LC13')).toHaveClass('hilite');
+ expect($('#LC13')).not.toHaveClass('hll');
+ });
+
+ it('highlights a range of lines given in the URL hash', function() {
+ var line;
+ new LineHighlighter({ hash: '#L5-25' });
+
+ expect($('.' + this.css).length).toBe(21);
+ for (line = 5; line <= 25; line += 1) {
+ expect($('#LC' + line)).toHaveClass(this.css);
}
- };
- beforeEach(function() {
- loadFixtures('static/line_highlighter.html.raw');
- this["class"] = new LineHighlighter();
- this.css = this["class"].highlightLineClass;
- return this.spies = {
- __setLocationHash__: spyOn(this["class"], '__setLocationHash__').and.callFake(function() {})
+ });
+
+ it('scrolls to the first highlighted line on initial load', function() {
+ var spy;
+ spy = spyOn($, 'scrollTo');
+ new LineHighlighter({ hash: '#L5-25' });
+
+ expect(spy).toHaveBeenCalledWith('#L5', jasmine.anything());
+ });
+
+ it('discards click events', function() {
+ var spy;
+ spy = spyOnEvent('a[data-line-number]', 'click');
+ clickLine(13);
+
+ expect(spy).toHaveBeenPrevented();
+ });
+
+ it('handles garbage input from the hash', function() {
+ var func;
+ func = function() {
+ return new LineHighlighter({ fileHolderSelector: '#blob-content-holder' });
};
+
+ expect(func).not.toThrow();
});
- describe('behavior', function() {
- it('highlights one line given in the URL hash', function() {
- new LineHighlighter({ hash: '#L13' });
- return expect($('#LC13')).toHaveClass(this.css);
- });
- it('highlights one line given in the URL hash with given CSS class name', function() {
- const hiliter = new LineHighlighter({ hash: '#L13', highlightLineClass: 'hilite' });
- expect(hiliter.highlightLineClass).toBe('hilite');
- expect($('#LC13')).toHaveClass('hilite');
- expect($('#LC13')).not.toHaveClass('hll');
- });
- it('highlights a range of lines given in the URL hash', function() {
- var line, results;
- new LineHighlighter({ hash: '#L5-25' });
- expect($("." + this.css).length).toBe(21);
- results = [];
- for (line = 5; line <= 25; line += 1) {
- results.push(expect($("#LC" + line)).toHaveClass(this.css));
- }
- return results;
+ });
+
+ describe('clickHandler', function() {
+ it('handles clicking on a child icon element', function() {
+ var spy;
+ spy = spyOn(this['class'], 'setHash').and.callThrough();
+ $('#L13 i')
+ .mousedown()
+ .click();
+
+ expect(spy).toHaveBeenCalledWith(13);
+ expect($('#LC13')).toHaveClass(this.css);
+ });
+
+ describe('without shiftKey', function() {
+ it('highlights one line when clicked', function() {
+ clickLine(13);
+
+ expect($('#LC13')).toHaveClass(this.css);
});
- it('scrolls to the first highlighted line on initial load', function() {
- var spy;
- spy = spyOn($, 'scrollTo');
- new LineHighlighter({ hash: '#L5-25' });
- return expect(spy).toHaveBeenCalledWith('#L5', jasmine.anything());
+
+ it('unhighlights previously highlighted lines', function() {
+ clickLine(13);
+ clickLine(20);
+
+ expect($('#LC13')).not.toHaveClass(this.css);
+ expect($('#LC20')).toHaveClass(this.css);
});
- it('discards click events', function() {
+
+ it('sets the hash', function() {
var spy;
- spy = spyOnEvent('a[data-line-number]', 'click');
+ spy = spyOn(this['class'], 'setHash').and.callThrough();
clickLine(13);
- return expect(spy).toHaveBeenPrevented();
- });
- it('handles garbage input from the hash', function() {
- var func;
- func = function() {
- return new LineHighlighter({ fileHolderSelector: '#blob-content-holder' });
- };
- return expect(func).not.toThrow();
+
+ expect(spy).toHaveBeenCalledWith(13);
});
});
- describe('clickHandler', function() {
- it('handles clicking on a child icon element', function() {
+
+ describe('with shiftKey', function() {
+ it('sets the hash', function() {
var spy;
- spy = spyOn(this["class"], 'setHash').and.callThrough();
- $('#L13 i').mousedown().click();
+ spy = spyOn(this['class'], 'setHash').and.callThrough();
+ clickLine(13);
+ clickLine(20, {
+ shiftKey: true,
+ });
+
expect(spy).toHaveBeenCalledWith(13);
- return expect($('#LC13')).toHaveClass(this.css);
+ expect(spy).toHaveBeenCalledWith(13, 20);
});
- describe('without shiftKey', function() {
- it('highlights one line when clicked', function() {
- clickLine(13);
- return expect($('#LC13')).toHaveClass(this.css);
- });
- it('unhighlights previously highlighted lines', function() {
- clickLine(13);
- clickLine(20);
- expect($('#LC13')).not.toHaveClass(this.css);
- return expect($('#LC20')).toHaveClass(this.css);
- });
- return it('sets the hash', function() {
- var spy;
- spy = spyOn(this["class"], 'setHash').and.callThrough();
- clickLine(13);
- return expect(spy).toHaveBeenCalledWith(13);
+
+ describe('without existing highlight', function() {
+ it('highlights the clicked line', function() {
+ clickLine(13, {
+ shiftKey: true,
+ });
+
+ expect($('#LC13')).toHaveClass(this.css);
+ expect($('.' + this.css).length).toBe(1);
});
- });
- return describe('with shiftKey', function() {
+
it('sets the hash', function() {
var spy;
- spy = spyOn(this["class"], 'setHash').and.callThrough();
- clickLine(13);
- clickLine(20, {
- shiftKey: true
+ spy = spyOn(this['class'], 'setHash');
+ clickLine(13, {
+ shiftKey: true,
});
+
expect(spy).toHaveBeenCalledWith(13);
- return expect(spy).toHaveBeenCalledWith(13, 20);
});
- describe('without existing highlight', function() {
- it('highlights the clicked line', function() {
- clickLine(13, {
- shiftKey: true
- });
- expect($('#LC13')).toHaveClass(this.css);
- return expect($("." + this.css).length).toBe(1);
+ });
+
+ describe('with existing single-line highlight', function() {
+ it('uses existing line as last line when target is lesser', function() {
+ var line;
+ clickLine(20);
+ clickLine(15, {
+ shiftKey: true,
});
- return it('sets the hash', function() {
- var spy;
- spy = spyOn(this["class"], 'setHash');
- clickLine(13, {
- shiftKey: true
- });
- return expect(spy).toHaveBeenCalledWith(13);
+
+ expect($('.' + this.css).length).toBe(6);
+ for (line = 15; line <= 20; line += 1) {
+ expect($('#LC' + line)).toHaveClass(this.css);
+ }
+ });
+
+ it('uses existing line as first line when target is greater', function() {
+ var line;
+ clickLine(5);
+ clickLine(10, {
+ shiftKey: true,
});
+
+ expect($('.' + this.css).length).toBe(6);
+ for (line = 5; line <= 10; line += 1) {
+ expect($('#LC' + line)).toHaveClass(this.css);
+ }
});
- describe('with existing single-line highlight', function() {
- it('uses existing line as last line when target is lesser', function() {
- var line, results;
- clickLine(20);
- clickLine(15, {
- shiftKey: true
- });
- expect($("." + this.css).length).toBe(6);
- results = [];
- for (line = 15; line <= 20; line += 1) {
- results.push(expect($("#LC" + line)).toHaveClass(this.css));
- }
- return results;
+ });
+
+ describe('with existing multi-line highlight', function() {
+ beforeEach(function() {
+ clickLine(10, {
+ shiftKey: true,
});
- return it('uses existing line as first line when target is greater', function() {
- var line, results;
- clickLine(5);
- clickLine(10, {
- shiftKey: true
- });
- expect($("." + this.css).length).toBe(6);
- results = [];
- for (line = 5; line <= 10; line += 1) {
- results.push(expect($("#LC" + line)).toHaveClass(this.css));
- }
- return results;
+ clickLine(13, {
+ shiftKey: true,
});
});
- return describe('with existing multi-line highlight', function() {
- beforeEach(function() {
- clickLine(10, {
- shiftKey: true
- });
- return clickLine(13, {
- shiftKey: true
- });
- });
- it('uses target as first line when it is less than existing first line', function() {
- var line, results;
- clickLine(5, {
- shiftKey: true
- });
- expect($("." + this.css).length).toBe(6);
- results = [];
- for (line = 5; line <= 10; line += 1) {
- results.push(expect($("#LC" + line)).toHaveClass(this.css));
- }
- return results;
+
+ it('uses target as first line when it is less than existing first line', function() {
+ var line;
+ clickLine(5, {
+ shiftKey: true,
});
- return it('uses target as last line when it is greater than existing first line', function() {
- var line, results;
- clickLine(15, {
- shiftKey: true
- });
- expect($("." + this.css).length).toBe(6);
- results = [];
- for (line = 10; line <= 15; line += 1) {
- results.push(expect($("#LC" + line)).toHaveClass(this.css));
- }
- return results;
+
+ expect($('.' + this.css).length).toBe(6);
+ for (line = 5; line <= 10; line += 1) {
+ expect($('#LC' + line)).toHaveClass(this.css);
+ }
+ });
+
+ it('uses target as last line when it is greater than existing first line', function() {
+ var line;
+ clickLine(15, {
+ shiftKey: true,
});
+
+ expect($('.' + this.css).length).toBe(6);
+ for (line = 10; line <= 15; line += 1) {
+ expect($('#LC' + line)).toHaveClass(this.css);
+ }
});
});
});
- describe('hashToRange', function() {
- beforeEach(function() {
- return this.subject = this["class"].hashToRange;
- });
- it('extracts a single line number from the hash', function() {
- return expect(this.subject('#L5')).toEqual([5, null]);
- });
- it('extracts a range of line numbers from the hash', function() {
- return expect(this.subject('#L5-15')).toEqual([5, 15]);
- });
- return it('returns [null, null] when the hash is not a line number', function() {
- return expect(this.subject('#foo')).toEqual([null, null]);
- });
+ });
+
+ describe('hashToRange', function() {
+ beforeEach(function() {
+ this.subject = this['class'].hashToRange;
});
- describe('highlightLine', function() {
- beforeEach(function() {
- return this.subject = this["class"].highlightLine;
- });
- it('highlights the specified line', function() {
- this.subject(13);
- return expect($('#LC13')).toHaveClass(this.css);
- });
- return it('accepts a String-based number', function() {
- this.subject('13');
- return expect($('#LC13')).toHaveClass(this.css);
- });
+
+ it('extracts a single line number from the hash', function() {
+ expect(this.subject('#L5')).toEqual([5, null]);
});
- return describe('setHash', function() {
- beforeEach(function() {
- return this.subject = this["class"].setHash;
- });
- it('sets the location hash for a single line', function() {
- this.subject(5);
- return expect(this.spies.__setLocationHash__).toHaveBeenCalledWith('#L5');
- });
- return it('sets the location hash for a range', function() {
- this.subject(5, 15);
- return expect(this.spies.__setLocationHash__).toHaveBeenCalledWith('#L5-15');
- });
+
+ it('extracts a range of line numbers from the hash', function() {
+ expect(this.subject('#L5-15')).toEqual([5, 15]);
+ });
+
+ it('returns [null, null] when the hash is not a line number', function() {
+ expect(this.subject('#foo')).toEqual([null, null]);
+ });
+ });
+
+ describe('highlightLine', function() {
+ beforeEach(function() {
+ this.subject = this['class'].highlightLine;
+ });
+
+ it('highlights the specified line', function() {
+ this.subject(13);
+
+ expect($('#LC13')).toHaveClass(this.css);
+ });
+
+ it('accepts a String-based number', function() {
+ this.subject('13');
+
+ expect($('#LC13')).toHaveClass(this.css);
+ });
+ });
+
+ describe('setHash', function() {
+ beforeEach(function() {
+ this.subject = this['class'].setHash;
+ });
+
+ it('sets the location hash for a single line', function() {
+ this.subject(5);
+
+ expect(this.spies.__setLocationHash__).toHaveBeenCalledWith('#L5');
+ });
+
+ it('sets the location hash for a range', function() {
+ this.subject(5, 15);
+
+ expect(this.spies.__setLocationHash__).toHaveBeenCalledWith('#L5-15');
});
});
-}).call(window);
+});
diff --git a/spec/javascripts/locale/ensure_single_line_spec.js b/spec/javascripts/locale/ensure_single_line_spec.js
index bbefa8f40f3..20b04cab9c8 100644
--- a/spec/javascripts/locale/ensure_single_line_spec.js
+++ b/spec/javascripts/locale/ensure_single_line_spec.js
@@ -4,6 +4,7 @@ describe('locale', () => {
describe('ensureSingleLine', () => {
it('should remove newlines at the start of the string', () => {
const result = 'Test';
+
expect(ensureSingleLine(`\n${result}`)).toBe(result);
expect(ensureSingleLine(`\t\n\t${result}`)).toBe(result);
expect(ensureSingleLine(`\r\n${result}`)).toBe(result);
@@ -14,6 +15,7 @@ describe('locale', () => {
it('should remove newlines at the end of the string', () => {
const result = 'Test';
+
expect(ensureSingleLine(`${result}\n`)).toBe(result);
expect(ensureSingleLine(`${result}\t\n\t`)).toBe(result);
expect(ensureSingleLine(`${result}\r\n`)).toBe(result);
@@ -24,6 +26,7 @@ describe('locale', () => {
it('should replace newlines in the middle of the string with a single space', () => {
const result = 'Test';
+
expect(ensureSingleLine(`${result}\n${result}`)).toBe(`${result} ${result}`);
expect(ensureSingleLine(`${result}\t\n\t${result}`)).toBe(`${result} ${result}`);
expect(ensureSingleLine(`${result}\r\n${result}`)).toBe(`${result} ${result}`);
diff --git a/spec/javascripts/merge_request_spec.js b/spec/javascripts/merge_request_spec.js
index 7502f1fa2e1..1cb49b49ca7 100644
--- a/spec/javascripts/merge_request_spec.js
+++ b/spec/javascripts/merge_request_spec.js
@@ -7,123 +7,122 @@ import MergeRequest from '~/merge_request';
import CloseReopenReportToggle from '~/close_reopen_report_toggle';
import IssuablesHelper from '~/helpers/issuables_helper';
-(function() {
- describe('MergeRequest', function() {
- describe('task lists', function() {
- let mock;
+describe('MergeRequest', function() {
+ describe('task lists', function() {
+ let mock;
- preloadFixtures('merge_requests/merge_request_with_task_list.html.raw');
- beforeEach(function() {
- loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
+ preloadFixtures('merge_requests/merge_request_with_task_list.html.raw');
+ beforeEach(function() {
+ loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
- spyOn(axios, 'patch').and.callThrough();
- mock = new MockAdapter(axios);
+ spyOn(axios, 'patch').and.callThrough();
+ mock = new MockAdapter(axios);
- mock
- .onPatch(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`)
- .reply(200, {});
+ mock
+ .onPatch(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`)
+ .reply(200, {});
- return (this.merge = new MergeRequest());
- });
+ return (this.merge = new MergeRequest());
+ });
- afterEach(() => {
- mock.restore();
- });
+ afterEach(() => {
+ mock.restore();
+ });
- it('modifies the Markdown field', function() {
- spyOn($, 'ajax').and.stub();
- const changeEvent = document.createEvent('HTMLEvents');
- changeEvent.initEvent('change', true, true);
- $('input[type=checkbox]')
- .attr('checked', true)[0]
- .dispatchEvent(changeEvent);
- return expect($('.js-task-list-field').val()).toBe('- [x] Task List Item');
- });
+ it('modifies the Markdown field', function() {
+ spyOn($, 'ajax').and.stub();
+ const changeEvent = document.createEvent('HTMLEvents');
+ changeEvent.initEvent('change', true, true);
+ $('input[type=checkbox]')
+ .attr('checked', true)[0]
+ .dispatchEvent(changeEvent);
- it('submits an ajax request on tasklist:changed', done => {
- $('.js-task-list-field').trigger('tasklist:changed');
-
- setTimeout(() => {
- expect(axios.patch).toHaveBeenCalledWith(
- `${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`,
- {
- merge_request: { description: '- [ ] Task List Item' },
- },
- );
- done();
- });
- });
+ expect($('.js-task-list-field').val()).toBe('- [x] Task List Item');
});
- describe('class constructor', () => {
- beforeEach(() => {
- spyOn($, 'ajax').and.stub();
+ it('submits an ajax request on tasklist:changed', done => {
+ $('.js-task-list-field').trigger('tasklist:changed');
+
+ setTimeout(() => {
+ expect(axios.patch).toHaveBeenCalledWith(
+ `${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/merge_requests/1.json`,
+ {
+ merge_request: { description: '- [ ] Task List Item' },
+ },
+ );
+ done();
});
+ });
+ });
- it('calls .initCloseReopenReport', () => {
- spyOn(IssuablesHelper, 'initCloseReopenReport');
+ describe('class constructor', () => {
+ beforeEach(() => {
+ spyOn($, 'ajax').and.stub();
+ });
- new MergeRequest(); // eslint-disable-line no-new
+ it('calls .initCloseReopenReport', () => {
+ spyOn(IssuablesHelper, 'initCloseReopenReport');
- expect(IssuablesHelper.initCloseReopenReport).toHaveBeenCalled();
- });
+ new MergeRequest(); // eslint-disable-line no-new
- it('calls .initDroplab', () => {
- const container = jasmine.createSpyObj('container', ['querySelector']);
- const dropdownTrigger = {};
- const dropdownList = {};
- const button = {};
+ expect(IssuablesHelper.initCloseReopenReport).toHaveBeenCalled();
+ });
+
+ it('calls .initDroplab', () => {
+ const container = jasmine.createSpyObj('container', ['querySelector']);
+ const dropdownTrigger = {};
+ const dropdownList = {};
+ const button = {};
+
+ spyOn(CloseReopenReportToggle.prototype, 'initDroplab');
+ spyOn(document, 'querySelector').and.returnValue(container);
+ container.querySelector.and.returnValues(dropdownTrigger, dropdownList, button);
- spyOn(CloseReopenReportToggle.prototype, 'initDroplab');
- spyOn(document, 'querySelector').and.returnValue(container);
- container.querySelector.and.returnValues(dropdownTrigger, dropdownList, button);
+ new MergeRequest(); // eslint-disable-line no-new
+
+ expect(document.querySelector).toHaveBeenCalledWith('.js-issuable-close-dropdown');
+ expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-toggle');
+ expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-menu');
+ expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-button');
+ expect(CloseReopenReportToggle.prototype.initDroplab).toHaveBeenCalled();
+ });
+ });
+ describe('hideCloseButton', () => {
+ describe('merge request of another user', () => {
+ beforeEach(() => {
+ loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
+ this.el = document.querySelector('.js-issuable-actions');
new MergeRequest(); // eslint-disable-line no-new
+ MergeRequest.hideCloseButton();
+ });
- expect(document.querySelector).toHaveBeenCalledWith('.js-issuable-close-dropdown');
- expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-toggle');
- expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-menu');
- expect(container.querySelector).toHaveBeenCalledWith('.js-issuable-close-button');
- expect(CloseReopenReportToggle.prototype.initDroplab).toHaveBeenCalled();
+ it('hides the dropdown close item and selects the next item', () => {
+ const closeItem = this.el.querySelector('li.close-item');
+ const smallCloseItem = this.el.querySelector('.js-close-item');
+ const reportItem = this.el.querySelector('li.report-item');
+
+ expect(closeItem).toHaveClass('hidden');
+ expect(smallCloseItem).toHaveClass('hidden');
+ expect(reportItem).toHaveClass('droplab-item-selected');
+ expect(reportItem).not.toHaveClass('hidden');
});
});
- describe('hideCloseButton', () => {
- describe('merge request of another user', () => {
- beforeEach(() => {
- loadFixtures('merge_requests/merge_request_with_task_list.html.raw');
- this.el = document.querySelector('.js-issuable-actions');
- new MergeRequest(); // eslint-disable-line no-new
- MergeRequest.hideCloseButton();
- });
-
- it('hides the dropdown close item and selects the next item', () => {
- const closeItem = this.el.querySelector('li.close-item');
- const smallCloseItem = this.el.querySelector('.js-close-item');
- const reportItem = this.el.querySelector('li.report-item');
-
- expect(closeItem).toHaveClass('hidden');
- expect(smallCloseItem).toHaveClass('hidden');
- expect(reportItem).toHaveClass('droplab-item-selected');
- expect(reportItem).not.toHaveClass('hidden');
- });
+ describe('merge request of current_user', () => {
+ beforeEach(() => {
+ loadFixtures('merge_requests/merge_request_of_current_user.html.raw');
+ this.el = document.querySelector('.js-issuable-actions');
+ MergeRequest.hideCloseButton();
});
- describe('merge request of current_user', () => {
- beforeEach(() => {
- loadFixtures('merge_requests/merge_request_of_current_user.html.raw');
- this.el = document.querySelector('.js-issuable-actions');
- MergeRequest.hideCloseButton();
- });
-
- it('hides the close button', () => {
- const closeButton = this.el.querySelector('.btn-close');
- const smallCloseItem = this.el.querySelector('.js-close-item');
+ it('hides the close button', () => {
+ const closeButton = this.el.querySelector('.btn-close');
+ const smallCloseItem = this.el.querySelector('.js-close-item');
- expect(closeButton).toHaveClass('hidden');
- expect(smallCloseItem).toHaveClass('hidden');
- });
+ expect(closeButton).toHaveClass('hidden');
+ expect(smallCloseItem).toHaveClass('hidden');
});
});
});
-}.call(window));
+});
diff --git a/spec/javascripts/merge_request_tabs_spec.js b/spec/javascripts/merge_request_tabs_spec.js
index 7251ce19a90..7714197c821 100644
--- a/spec/javascripts/merge_request_tabs_spec.js
+++ b/spec/javascripts/merge_request_tabs_spec.js
@@ -224,6 +224,14 @@ describe('MergeRequestTabs', function() {
expect($('.content-wrapper')).not.toContainElement('.container-limited');
});
+ it('does not add container-limited when fluid layout is prefered', function() {
+ $('.content-wrapper .container-fluid').removeClass('container-limited');
+
+ this.class.expandViewContainer(false);
+
+ expect($('.content-wrapper')).not.toContainElement('.container-limited');
+ });
+
it('does remove container-limited from breadcrumbs', function() {
$('.container-limited').addClass('breadcrumbs');
this.class.expandViewContainer();
diff --git a/spec/javascripts/mini_pipeline_graph_dropdown_spec.js b/spec/javascripts/mini_pipeline_graph_dropdown_spec.js
index 1879424c629..092ca9e1dab 100644
--- a/spec/javascripts/mini_pipeline_graph_dropdown_spec.js
+++ b/spec/javascripts/mini_pipeline_graph_dropdown_spec.js
@@ -39,10 +39,9 @@ describe('Mini Pipeline Graph Dropdown', () => {
});
it('should call getBuildsList', () => {
- const getBuildsListSpy = spyOn(
- MiniPipelineGraph.prototype,
- 'getBuildsList',
- ).and.callFake(function () {});
+ const getBuildsListSpy = spyOn(MiniPipelineGraph.prototype, 'getBuildsList').and.callFake(
+ function() {},
+ );
new MiniPipelineGraph({ container: '.js-builds-dropdown-tests' }).bindEvents();
@@ -61,10 +60,11 @@ describe('Mini Pipeline Graph Dropdown', () => {
new MiniPipelineGraph({ container: '.js-builds-dropdown-tests' }).bindEvents();
document.querySelector('.js-builds-dropdown-button').click();
+
expect(ajaxSpy.calls.allArgs()[0][0]).toEqual('foobar');
});
- it('should not close when user uses cmd/ctrl + click', (done) => {
+ it('should not close when user uses cmd/ctrl + click', done => {
mock.onGet('foobar').reply(200, {
html: `<li>
<a class="mini-pipeline-graph-dropdown-item" href="#">
@@ -90,7 +90,7 @@ describe('Mini Pipeline Graph Dropdown', () => {
.catch(done.fail);
});
- it('should close the dropdown when request returns an error', (done) => {
+ it('should close the dropdown when request returns an error', done => {
mock.onGet('foobar').networkError();
new MiniPipelineGraph({ container: '.js-builds-dropdown-tests' }).bindEvents();
diff --git a/spec/javascripts/monitoring/dashboard_spec.js b/spec/javascripts/monitoring/dashboard_spec.js
index 732c37a24bf..565b87de248 100644
--- a/spec/javascripts/monitoring/dashboard_spec.js
+++ b/spec/javascripts/monitoring/dashboard_spec.js
@@ -107,11 +107,28 @@ describe('Dashboard', () => {
setTimeout(() => {
const dropdownMenuEnvironments = component.$el.querySelectorAll('.dropdown-menu ul li a');
+
expect(dropdownMenuEnvironments.length).toEqual(component.store.environmentsData.length);
done();
});
});
+ it('hides the dropdown list when there is no environments', done => {
+ const component = new DashboardComponent({
+ el: document.querySelector('.prometheus-graphs'),
+ propsData: { ...propsData, hasMetrics: true, showPanels: false },
+ });
+
+ component.store.storeEnvironmentsData([]);
+
+ setTimeout(() => {
+ const dropdownMenuEnvironments = component.$el.querySelectorAll('.dropdown-menu ul');
+
+ expect(dropdownMenuEnvironments.length).toEqual(0);
+ done();
+ });
+ });
+
it('renders the dropdown with a single is-active element', done => {
const component = new DashboardComponent({
el: document.querySelector('.prometheus-graphs'),
@@ -124,6 +141,7 @@ describe('Dashboard', () => {
const dropdownIsActiveElement = component.$el.querySelectorAll(
'.dropdown-menu ul li a.is-active',
);
+
expect(dropdownIsActiveElement.length).toEqual(1);
expect(dropdownIsActiveElement[0].textContent.trim()).toEqual(
component.currentEnvironmentName,
diff --git a/spec/javascripts/monitoring/dashboard_state_spec.js b/spec/javascripts/monitoring/dashboard_state_spec.js
index b4c5f4baa78..6b2be83aa8c 100644
--- a/spec/javascripts/monitoring/dashboard_state_spec.js
+++ b/spec/javascripts/monitoring/dashboard_state_spec.js
@@ -56,9 +56,17 @@ describe('EmptyState', () => {
});
expect(component.$el.querySelector('svg')).toBeDefined();
- expect(getTextFromNode(component, '.state-title')).toEqual(component.states.gettingStarted.title);
- expect(getTextFromNode(component, '.state-description')).toEqual(component.states.gettingStarted.description);
- expect(getTextFromNode(component, '.btn-success')).toEqual(component.states.gettingStarted.buttonText);
+ expect(getTextFromNode(component, '.state-title')).toEqual(
+ component.states.gettingStarted.title,
+ );
+
+ expect(getTextFromNode(component, '.state-description')).toEqual(
+ component.states.gettingStarted.description,
+ );
+
+ expect(getTextFromNode(component, '.btn-success')).toEqual(
+ component.states.gettingStarted.buttonText,
+ );
});
it('should show the loading state', () => {
@@ -68,7 +76,10 @@ describe('EmptyState', () => {
expect(component.$el.querySelector('svg')).toBeDefined();
expect(getTextFromNode(component, '.state-title')).toEqual(component.states.loading.title);
- expect(getTextFromNode(component, '.state-description')).toEqual(component.states.loading.description);
+ expect(getTextFromNode(component, '.state-description')).toEqual(
+ component.states.loading.description,
+ );
+
expect(getTextFromNode(component, '.btn-success')).toEqual(component.states.loading.buttonText);
});
@@ -78,8 +89,13 @@ describe('EmptyState', () => {
});
expect(component.$el.querySelector('svg')).toBeDefined();
- expect(getTextFromNode(component, '.state-title')).toEqual(component.states.unableToConnect.title);
+ expect(getTextFromNode(component, '.state-title')).toEqual(
+ component.states.unableToConnect.title,
+ );
+
expect(component.$el.querySelector('.state-description a')).toBeDefined();
- expect(getTextFromNode(component, '.btn-success')).toEqual(component.states.unableToConnect.buttonText);
+ expect(getTextFromNode(component, '.btn-success')).toEqual(
+ component.states.unableToConnect.buttonText,
+ );
});
});
diff --git a/spec/javascripts/monitoring/graph/deployment_spec.js b/spec/javascripts/monitoring/graph/deployment_spec.js
index d07db871d69..7d39c4345d2 100644
--- a/spec/javascripts/monitoring/graph/deployment_spec.js
+++ b/spec/javascripts/monitoring/graph/deployment_spec.js
@@ -2,7 +2,7 @@ import Vue from 'vue';
import GraphDeployment from '~/monitoring/components/graph/deployment.vue';
import { deploymentData } from '../mock_data';
-const createComponent = (propsData) => {
+const createComponent = propsData => {
const Component = Vue.extend(GraphDeployment);
return new Component({
@@ -33,9 +33,7 @@ describe('MonitoringDeployment', () => {
graphHeightOffset: 120,
});
- expect(
- component.transformDeploymentGroup({ xPos: 16 }),
- ).toContain('translate(11, 20)');
+ expect(component.transformDeploymentGroup({ xPos: 16 })).toContain('translate(11, 20)');
});
describe('Computed props', () => {
diff --git a/spec/javascripts/monitoring/graph_path_spec.js b/spec/javascripts/monitoring/graph_path_spec.js
index 5f270c5cfe9..fd167b83d51 100644
--- a/spec/javascripts/monitoring/graph_path_spec.js
+++ b/spec/javascripts/monitoring/graph_path_spec.js
@@ -3,7 +3,7 @@ import GraphPath from '~/monitoring/components/graph/path.vue';
import createTimeSeries from '~/monitoring/utils/multiple_time_series';
import { singleRowMetricsMultipleSeries, convertDatesMultipleSeries } from './mock_data';
-const createComponent = (propsData) => {
+const createComponent = propsData => {
const Component = Vue.extend(GraphPath);
return new Component({
@@ -45,9 +45,11 @@ describe('Monitoring Paths', () => {
});
component.lineStyle = 'dashed';
+
expect(component.strokeDashArray).toBe('3, 1');
component.lineStyle = 'dotted';
+
expect(component.strokeDashArray).toBe('1, 1');
});
});
diff --git a/spec/javascripts/monitoring/graph_spec.js b/spec/javascripts/monitoring/graph_spec.js
index 99180e4d303..4cc18afdf24 100644
--- a/spec/javascripts/monitoring/graph_spec.js
+++ b/spec/javascripts/monitoring/graph_spec.js
@@ -49,6 +49,7 @@ describe('Graph', () => {
});
const transformedHeight = `${component.graphHeight - 100}`;
+
expect(component.axisTransform.indexOf(transformedHeight)).not.toEqual(-1);
});
@@ -62,6 +63,7 @@ describe('Graph', () => {
});
const viewBoxArray = component.outerViewBox.split(' ');
+
expect(typeof component.outerViewBox).toEqual('string');
expect(viewBoxArray[2]).toEqual(component.graphWidth.toString());
expect(viewBoxArray[3]).toEqual((component.graphHeight - 50).toString());
@@ -99,6 +101,7 @@ describe('Graph', () => {
component.seriesUnderMouse = component.timeSeries;
component.positionFlag();
+
expect(component.currentData).toBe(component.timeSeries[0].values[10]);
});
});
diff --git a/spec/javascripts/monitoring/monitoring_store_spec.js b/spec/javascripts/monitoring/monitoring_store_spec.js
index ccdf4eda563..bf68c911549 100644
--- a/spec/javascripts/monitoring/monitoring_store_spec.js
+++ b/spec/javascripts/monitoring/monitoring_store_spec.js
@@ -1,7 +1,7 @@
import MonitoringStore from '~/monitoring/stores/monitoring_store';
import MonitoringMock, { deploymentData, environmentData } from './mock_data';
-describe('MonitoringStore', function () {
+describe('MonitoringStore', function() {
this.store = new MonitoringStore();
this.store.storeMetrics(MonitoringMock.data);
@@ -17,6 +17,7 @@ describe('MonitoringStore', function () {
it('contains deployment data', () => {
this.store.storeDeploymentData(deploymentData);
+
expect(this.store.deploymentData).toBeDefined();
expect(this.store.deploymentData.length).toEqual(3);
expect(typeof this.store.deploymentData[0]).toEqual('object');
@@ -24,6 +25,7 @@ describe('MonitoringStore', function () {
it('only stores environment data that contains deployments', () => {
this.store.storeEnvironmentsData(environmentData);
+
expect(this.store.environmentsData.length).toEqual(2);
});
});
diff --git a/spec/javascripts/new_branch_spec.js b/spec/javascripts/new_branch_spec.js
index e52ac686435..1d7b885e64f 100644
--- a/spec/javascripts/new_branch_spec.js
+++ b/spec/javascripts/new_branch_spec.js
@@ -1,168 +1,199 @@
-/* eslint-disable one-var, no-var, no-return-assign */
-
import $ from 'jquery';
import NewBranchForm from '~/new_branch_form';
-(function() {
- describe('Branch', function() {
- return describe('create a new branch', function() {
- var expectToHaveError, fillNameWith;
- preloadFixtures('branches/new_branch.html.raw');
- fillNameWith = function(value) {
- return $('.js-branch-name').val(value).trigger('blur');
- };
- expectToHaveError = function(error) {
- return expect($('.js-branch-name-error span').text()).toEqual(error);
- };
- beforeEach(function() {
- loadFixtures('branches/new_branch.html.raw');
- $('form').on('submit', function(e) {
- return e.preventDefault();
- });
- return this.form = new NewBranchForm($('.js-create-branch-form'), []);
- });
- it("can't start with a dot", function() {
- fillNameWith('.foo');
- return expectToHaveError("can't start with '.'");
- });
- it("can't start with a slash", function() {
- fillNameWith('/foo');
- return expectToHaveError("can't start with '/'");
- });
- it("can't have two consecutive dots", function() {
- fillNameWith('foo..bar');
- return expectToHaveError("can't contain '..'");
- });
- it("can't have spaces anywhere", function() {
- fillNameWith(' foo');
- expectToHaveError("can't contain spaces");
- fillNameWith('foo bar');
- expectToHaveError("can't contain spaces");
- fillNameWith('foo ');
- return expectToHaveError("can't contain spaces");
- });
- it("can't have ~ anywhere", function() {
- fillNameWith('~foo');
- expectToHaveError("can't contain '~'");
- fillNameWith('foo~bar');
- expectToHaveError("can't contain '~'");
- fillNameWith('foo~');
- return expectToHaveError("can't contain '~'");
- });
- it("can't have tilde anwhere", function() {
- fillNameWith('~foo');
- expectToHaveError("can't contain '~'");
- fillNameWith('foo~bar');
- expectToHaveError("can't contain '~'");
- fillNameWith('foo~');
- return expectToHaveError("can't contain '~'");
- });
- it("can't have caret anywhere", function() {
- fillNameWith('^foo');
- expectToHaveError("can't contain '^'");
- fillNameWith('foo^bar');
- expectToHaveError("can't contain '^'");
- fillNameWith('foo^');
- return expectToHaveError("can't contain '^'");
- });
- it("can't have : anywhere", function() {
- fillNameWith(':foo');
- expectToHaveError("can't contain ':'");
- fillNameWith('foo:bar');
- expectToHaveError("can't contain ':'");
- fillNameWith(':foo');
- return expectToHaveError("can't contain ':'");
- });
- it("can't have question mark anywhere", function() {
- fillNameWith('?foo');
- expectToHaveError("can't contain '?'");
- fillNameWith('foo?bar');
- expectToHaveError("can't contain '?'");
- fillNameWith('foo?');
- return expectToHaveError("can't contain '?'");
- });
- it("can't have asterisk anywhere", function() {
- fillNameWith('*foo');
- expectToHaveError("can't contain '*'");
- fillNameWith('foo*bar');
- expectToHaveError("can't contain '*'");
- fillNameWith('foo*');
- return expectToHaveError("can't contain '*'");
- });
- it("can't have open bracket anywhere", function() {
- fillNameWith('[foo');
- expectToHaveError("can't contain '['");
- fillNameWith('foo[bar');
- expectToHaveError("can't contain '['");
- fillNameWith('foo[');
- return expectToHaveError("can't contain '['");
- });
- it("can't have a backslash anywhere", function() {
- fillNameWith('\\foo');
- expectToHaveError("can't contain '\\'");
- fillNameWith('foo\\bar');
- expectToHaveError("can't contain '\\'");
- fillNameWith('foo\\');
- return expectToHaveError("can't contain '\\'");
- });
- it("can't contain a sequence @{ anywhere", function() {
- fillNameWith('@{foo');
- expectToHaveError("can't contain '@{'");
- fillNameWith('foo@{bar');
- expectToHaveError("can't contain '@{'");
- fillNameWith('foo@{');
- return expectToHaveError("can't contain '@{'");
- });
- it("can't have consecutive slashes", function() {
- fillNameWith('foo//bar');
- return expectToHaveError("can't contain consecutive slashes");
- });
- it("can't end with a slash", function() {
- fillNameWith('foo/');
- return expectToHaveError("can't end in '/'");
- });
- it("can't end with a dot", function() {
- fillNameWith('foo.');
- return expectToHaveError("can't end in '.'");
- });
- it("can't end with .lock", function() {
- fillNameWith('foo.lock');
- return expectToHaveError("can't end in '.lock'");
- });
- it("can't be the single character @", function() {
- fillNameWith('@');
- return expectToHaveError("can't be '@'");
- });
- it("concatenates all error messages", function() {
- fillNameWith('/foo bar?~.');
- return expectToHaveError("can't start with '/', can't contain spaces, '?', '~', can't end in '.'");
- });
- it("doesn't duplicate error messages", function() {
- fillNameWith('?foo?bar?zoo?');
- return expectToHaveError("can't contain '?'");
- });
- it("removes the error message when is a valid name", function() {
- fillNameWith('foo?bar');
- expect($('.js-branch-name-error span').length).toEqual(1);
- fillNameWith('foobar');
- return expect($('.js-branch-name-error span').length).toEqual(0);
- });
- it("can have dashes anywhere", function() {
- fillNameWith('-foo-bar-zoo-');
- return expect($('.js-branch-name-error span').length).toEqual(0);
- });
- it("can have underscores anywhere", function() {
- fillNameWith('_foo_bar_zoo_');
- return expect($('.js-branch-name-error span').length).toEqual(0);
- });
- it("can have numbers anywhere", function() {
- fillNameWith('1foo2bar3zoo4');
- return expect($('.js-branch-name-error span').length).toEqual(0);
- });
- return it("can be only letters", function() {
- fillNameWith('foo');
- return expect($('.js-branch-name-error span').length).toEqual(0);
+describe('Branch', function() {
+ describe('create a new branch', function() {
+ preloadFixtures('branches/new_branch.html.raw');
+
+ function fillNameWith(value) {
+ $('.js-branch-name')
+ .val(value)
+ .trigger('blur');
+ }
+
+ function expectToHaveError(error) {
+ expect($('.js-branch-name-error span').text()).toEqual(error);
+ }
+
+ beforeEach(function() {
+ loadFixtures('branches/new_branch.html.raw');
+ $('form').on('submit', function(e) {
+ return e.preventDefault();
});
+ this.form = new NewBranchForm($('.js-create-branch-form'), []);
+ });
+
+ it("can't start with a dot", function() {
+ fillNameWith('.foo');
+ expectToHaveError("can't start with '.'");
+ });
+
+ it("can't start with a slash", function() {
+ fillNameWith('/foo');
+ expectToHaveError("can't start with '/'");
+ });
+
+ it("can't have two consecutive dots", function() {
+ fillNameWith('foo..bar');
+ expectToHaveError("can't contain '..'");
+ });
+
+ it("can't have spaces anywhere", function() {
+ fillNameWith(' foo');
+ expectToHaveError("can't contain spaces");
+ fillNameWith('foo bar');
+ expectToHaveError("can't contain spaces");
+ fillNameWith('foo ');
+ expectToHaveError("can't contain spaces");
+ });
+
+ it("can't have ~ anywhere", function() {
+ fillNameWith('~foo');
+ expectToHaveError("can't contain '~'");
+ fillNameWith('foo~bar');
+ expectToHaveError("can't contain '~'");
+ fillNameWith('foo~');
+ expectToHaveError("can't contain '~'");
+ });
+
+ it("can't have tilde anwhere", function() {
+ fillNameWith('~foo');
+ expectToHaveError("can't contain '~'");
+ fillNameWith('foo~bar');
+ expectToHaveError("can't contain '~'");
+ fillNameWith('foo~');
+ expectToHaveError("can't contain '~'");
+ });
+
+ it("can't have caret anywhere", function() {
+ fillNameWith('^foo');
+ expectToHaveError("can't contain '^'");
+ fillNameWith('foo^bar');
+ expectToHaveError("can't contain '^'");
+ fillNameWith('foo^');
+ expectToHaveError("can't contain '^'");
+ });
+
+ it("can't have : anywhere", function() {
+ fillNameWith(':foo');
+ expectToHaveError("can't contain ':'");
+ fillNameWith('foo:bar');
+ expectToHaveError("can't contain ':'");
+ fillNameWith(':foo');
+ expectToHaveError("can't contain ':'");
+ });
+
+ it("can't have question mark anywhere", function() {
+ fillNameWith('?foo');
+ expectToHaveError("can't contain '?'");
+ fillNameWith('foo?bar');
+ expectToHaveError("can't contain '?'");
+ fillNameWith('foo?');
+ expectToHaveError("can't contain '?'");
+ });
+
+ it("can't have asterisk anywhere", function() {
+ fillNameWith('*foo');
+ expectToHaveError("can't contain '*'");
+ fillNameWith('foo*bar');
+ expectToHaveError("can't contain '*'");
+ fillNameWith('foo*');
+ expectToHaveError("can't contain '*'");
+ });
+
+ it("can't have open bracket anywhere", function() {
+ fillNameWith('[foo');
+ expectToHaveError("can't contain '['");
+ fillNameWith('foo[bar');
+ expectToHaveError("can't contain '['");
+ fillNameWith('foo[');
+ expectToHaveError("can't contain '['");
+ });
+
+ it("can't have a backslash anywhere", function() {
+ fillNameWith('\\foo');
+ expectToHaveError("can't contain '\\'");
+ fillNameWith('foo\\bar');
+ expectToHaveError("can't contain '\\'");
+ fillNameWith('foo\\');
+ expectToHaveError("can't contain '\\'");
+ });
+
+ it("can't contain a sequence @{ anywhere", function() {
+ fillNameWith('@{foo');
+ expectToHaveError("can't contain '@{'");
+ fillNameWith('foo@{bar');
+ expectToHaveError("can't contain '@{'");
+ fillNameWith('foo@{');
+ expectToHaveError("can't contain '@{'");
+ });
+
+ it("can't have consecutive slashes", function() {
+ fillNameWith('foo//bar');
+ expectToHaveError("can't contain consecutive slashes");
+ });
+
+ it("can't end with a slash", function() {
+ fillNameWith('foo/');
+ expectToHaveError("can't end in '/'");
+ });
+
+ it("can't end with a dot", function() {
+ fillNameWith('foo.');
+ expectToHaveError("can't end in '.'");
+ });
+
+ it("can't end with .lock", function() {
+ fillNameWith('foo.lock');
+ expectToHaveError("can't end in '.lock'");
+ });
+
+ it("can't be the single character @", function() {
+ fillNameWith('@');
+ expectToHaveError("can't be '@'");
+ });
+
+ it('concatenates all error messages', function() {
+ fillNameWith('/foo bar?~.');
+ expectToHaveError("can't start with '/', can't contain spaces, '?', '~', can't end in '.'");
+ });
+
+ it("doesn't duplicate error messages", function() {
+ fillNameWith('?foo?bar?zoo?');
+ expectToHaveError("can't contain '?'");
+ });
+
+ it('removes the error message when is a valid name', function() {
+ fillNameWith('foo?bar');
+
+ expect($('.js-branch-name-error span').length).toEqual(1);
+ fillNameWith('foobar');
+
+ expect($('.js-branch-name-error span').length).toEqual(0);
+ });
+
+ it('can have dashes anywhere', function() {
+ fillNameWith('-foo-bar-zoo-');
+
+ expect($('.js-branch-name-error span').length).toEqual(0);
+ });
+
+ it('can have underscores anywhere', function() {
+ fillNameWith('_foo_bar_zoo_');
+
+ expect($('.js-branch-name-error span').length).toEqual(0);
+ });
+
+ it('can have numbers anywhere', function() {
+ fillNameWith('1foo2bar3zoo4');
+
+ expect($('.js-branch-name-error span').length).toEqual(0);
+ });
+
+ it('can be only letters', function() {
+ fillNameWith('foo');
+
+ expect($('.js-branch-name-error span').length).toEqual(0);
});
});
-}).call(window);
+});
diff --git a/spec/javascripts/notebook/cells/code_spec.js b/spec/javascripts/notebook/cells/code_spec.js
index 0c432d73f67..4659b83d1b6 100644
--- a/spec/javascripts/notebook/cells/code_spec.js
+++ b/spec/javascripts/notebook/cells/code_spec.js
@@ -12,7 +12,7 @@ describe('Code component', () => {
});
describe('without output', () => {
- beforeEach((done) => {
+ beforeEach(done => {
vm = new Component({
propsData: {
cell: json.cells[0],
@@ -31,7 +31,7 @@ describe('Code component', () => {
});
describe('with output', () => {
- beforeEach((done) => {
+ beforeEach(done => {
vm = new Component({
propsData: {
cell: json.cells[2],
diff --git a/spec/javascripts/notebook/cells/markdown_spec.js b/spec/javascripts/notebook/cells/markdown_spec.js
index 0b1b11de1fd..540fc8a21f1 100644
--- a/spec/javascripts/notebook/cells/markdown_spec.js
+++ b/spec/javascripts/notebook/cells/markdown_spec.js
@@ -11,7 +11,7 @@ describe('Markdown component', () => {
let cell;
let json;
- beforeEach((done) => {
+ beforeEach(done => {
json = getJSONFixture('blob/notebook/basic.json');
// eslint-disable-next-line prefer-destructuring
@@ -34,18 +34,18 @@ describe('Markdown component', () => {
});
it('does not render the markdown text', () => {
- expect(
- vm.$el.querySelector('.markdown').innerHTML.trim(),
- ).not.toEqual(cell.source.join(''));
+ expect(vm.$el.querySelector('.markdown').innerHTML.trim()).not.toEqual(cell.source.join(''));
});
it('renders the markdown HTML', () => {
expect(vm.$el.querySelector('.markdown h1')).not.toBeNull();
});
- it('sanitizes output', (done) => {
+ it('sanitizes output', done => {
Object.assign(cell, {
- source: ['[XSS](data:text/html;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5kb21haW4pPC9zY3JpcHQ+Cg==)\n'],
+ source: [
+ '[XSS](data:text/html;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5kb21haW4pPC9zY3JpcHQ+Cg==)\n',
+ ],
});
Vue.nextTick(() => {
@@ -60,7 +60,7 @@ describe('Markdown component', () => {
json = getJSONFixture('blob/notebook/math.json');
});
- it('renders multi-line katex', (done) => {
+ it('renders multi-line katex', done => {
vm = new Component({
propsData: {
cell: json.cells[0],
@@ -68,15 +68,13 @@ describe('Markdown component', () => {
}).$mount();
Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('.katex'),
- ).not.toBeNull();
+ expect(vm.$el.querySelector('.katex')).not.toBeNull();
done();
});
});
- it('renders inline katex', (done) => {
+ it('renders inline katex', done => {
vm = new Component({
propsData: {
cell: json.cells[1],
@@ -84,15 +82,13 @@ describe('Markdown component', () => {
}).$mount();
Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('p:first-child .katex'),
- ).not.toBeNull();
+ expect(vm.$el.querySelector('p:first-child .katex')).not.toBeNull();
done();
});
});
- it('renders multiple inline katex', (done) => {
+ it('renders multiple inline katex', done => {
vm = new Component({
propsData: {
cell: json.cells[1],
@@ -100,9 +96,7 @@ describe('Markdown component', () => {
}).$mount();
Vue.nextTick(() => {
- expect(
- vm.$el.querySelectorAll('p:nth-child(2) .katex').length,
- ).toBe(4);
+ expect(vm.$el.querySelectorAll('p:nth-child(2) .katex').length).toBe(4);
done();
});
diff --git a/spec/javascripts/notebook/cells/output/html_sanitize_tests.js b/spec/javascripts/notebook/cells/output/html_sanitize_tests.js
index d587573fc9e..74c48f04367 100644
--- a/spec/javascripts/notebook/cells/output/html_sanitize_tests.js
+++ b/spec/javascripts/notebook/cells/output/html_sanitize_tests.js
@@ -28,7 +28,8 @@ export default {
output: '<a>foo</a>',
},
'protocol-based JS injection: long UTF-8 encoding without semicolons': {
- input: '<a href=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>foo</a>',
+ input:
+ '<a href=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>foo</a>',
output: '<a>foo</a>',
},
'protocol-based JS injection: hex encoding': {
@@ -40,7 +41,8 @@ export default {
output: '<a>foo</a>',
},
'protocol-based JS injection: hex encoding without semicolons': {
- input: '<a href=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>foo</a>',
+ input:
+ '<a href=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>foo</a>',
output: '<a>foo</a>',
},
'protocol-based JS injection: null char': {
@@ -48,7 +50,7 @@ export default {
output: '<a>foo</a>',
},
'protocol-based JS injection: invalid URL char': {
- input: '<img src=java\script:alert("XSS")>', // eslint-disable-line no-useless-escape
+ input: '<img src=javascript:alert("XSS")>',
output: '<img>',
},
'protocol-based JS injection: Unicode': {
diff --git a/spec/javascripts/notebook/cells/output/html_spec.js b/spec/javascripts/notebook/cells/output/html_spec.js
index 9c5385f2922..bea62f54634 100644
--- a/spec/javascripts/notebook/cells/output/html_spec.js
+++ b/spec/javascripts/notebook/cells/output/html_spec.js
@@ -14,7 +14,7 @@ describe('html output cell', () => {
}
describe('sanitizes output', () => {
- Object.keys(sanitizeTests).forEach((key) => {
+ Object.keys(sanitizeTests).forEach(key => {
it(key, () => {
const test = sanitizeTests[key];
const vm = createComponent(test.input);
diff --git a/spec/javascripts/notebook/cells/output/index_spec.js b/spec/javascripts/notebook/cells/output/index_spec.js
index dbf79f85c7c..feab7ad4212 100644
--- a/spec/javascripts/notebook/cells/output/index_spec.js
+++ b/spec/javascripts/notebook/cells/output/index_spec.js
@@ -7,7 +7,7 @@ describe('Output component', () => {
let vm;
let json;
- const createComponent = (output) => {
+ const createComponent = output => {
vm = new Component({
propsData: {
output,
@@ -22,7 +22,7 @@ describe('Output component', () => {
});
describe('text output', () => {
- beforeEach((done) => {
+ beforeEach(done => {
createComponent(json.cells[2].outputs[0]);
setTimeout(() => {
@@ -40,7 +40,7 @@ describe('Output component', () => {
});
describe('image output', () => {
- beforeEach((done) => {
+ beforeEach(done => {
createComponent(json.cells[3].outputs[0]);
setTimeout(() => {
@@ -58,7 +58,7 @@ describe('Output component', () => {
});
describe('html output', () => {
- beforeEach((done) => {
+ beforeEach(done => {
createComponent(json.cells[4].outputs[0]);
setTimeout(() => {
@@ -77,7 +77,7 @@ describe('Output component', () => {
});
describe('svg output', () => {
- beforeEach((done) => {
+ beforeEach(done => {
createComponent(json.cells[5].outputs[0]);
setTimeout(() => {
@@ -95,7 +95,7 @@ describe('Output component', () => {
});
describe('default to plain text', () => {
- beforeEach((done) => {
+ beforeEach(done => {
createComponent(json.cells[6].outputs[0]);
setTimeout(() => {
@@ -112,7 +112,7 @@ describe('Output component', () => {
expect(vm.$el.querySelector('.prompt span')).not.toBeNull();
});
- it('renders as plain text when doesn\'t recognise other types', (done) => {
+ it("renders as plain text when doesn't recognise other types", done => {
createComponent(json.cells[7].outputs[0]);
setTimeout(() => {
diff --git a/spec/javascripts/notebook/cells/prompt_spec.js b/spec/javascripts/notebook/cells/prompt_spec.js
index 207fa433a59..cbbcb1e68e3 100644
--- a/spec/javascripts/notebook/cells/prompt_spec.js
+++ b/spec/javascripts/notebook/cells/prompt_spec.js
@@ -7,7 +7,7 @@ describe('Prompt component', () => {
let vm;
describe('input', () => {
- beforeEach((done) => {
+ beforeEach(done => {
vm = new Component({
propsData: {
type: 'In',
@@ -31,7 +31,7 @@ describe('Prompt component', () => {
});
describe('output', () => {
- beforeEach((done) => {
+ beforeEach(done => {
vm = new Component({
propsData: {
type: 'Out',
diff --git a/spec/javascripts/notebook/index_spec.js b/spec/javascripts/notebook/index_spec.js
index bd63ab35426..2e2ea5ad8af 100644
--- a/spec/javascripts/notebook/index_spec.js
+++ b/spec/javascripts/notebook/index_spec.js
@@ -14,7 +14,7 @@ describe('Notebook component', () => {
});
describe('without JSON', () => {
- beforeEach((done) => {
+ beforeEach(done => {
vm = new Component({
propsData: {
notebook: {},
@@ -33,7 +33,7 @@ describe('Notebook component', () => {
});
describe('with JSON', () => {
- beforeEach((done) => {
+ beforeEach(done => {
vm = new Component({
propsData: {
notebook: json,
@@ -65,7 +65,7 @@ describe('Notebook component', () => {
});
describe('with worksheets', () => {
- beforeEach((done) => {
+ beforeEach(done => {
vm = new Component({
propsData: {
notebook: jsonWithWorksheet,
@@ -80,7 +80,9 @@ describe('Notebook component', () => {
});
it('renders cells', () => {
- expect(vm.$el.querySelectorAll('.cell').length).toBe(jsonWithWorksheet.worksheets[0].cells.length);
+ expect(vm.$el.querySelectorAll('.cell').length).toBe(
+ jsonWithWorksheet.worksheets[0].cells.length,
+ );
});
it('renders markdown cell', () => {
diff --git a/spec/javascripts/notes/components/comment_form_spec.js b/spec/javascripts/notes/components/comment_form_spec.js
index 155c91dcc46..3c57fe51352 100644
--- a/spec/javascripts/notes/components/comment_form_spec.js
+++ b/spec/javascripts/notes/components/comment_form_spec.js
@@ -51,6 +51,7 @@ describe('issue_comment_form component', () => {
spyOn(vm, 'stopPolling');
vm.handleSave();
+
expect(vm.isSubmitting).toEqual(true);
expect(vm.note).toEqual('');
expect(vm.saveNote).toHaveBeenCalled();
@@ -77,10 +78,14 @@ describe('issue_comment_form component', () => {
vm.handleSave();
Vue.nextTick()
- .then(() => expect(actionButton.disabled).toBeTruthy())
+ .then(() => {
+ expect(actionButton.disabled).toBeTruthy();
+ })
.then(saveNotePromise)
.then(Vue.nextTick)
- .then(() => expect(actionButton.disabled).toBeFalsy())
+ .then(() => {
+ expect(actionButton.disabled).toBeFalsy();
+ })
.then(done)
.catch(done.fail);
});
@@ -121,6 +126,7 @@ describe('issue_comment_form component', () => {
it('should link to markdown docs', () => {
const { markdownDocsPath } = notesDataMock;
+
expect(vm.$el.querySelector(`a[href="${markdownDocsPath}"]`).textContent.trim()).toEqual(
'Markdown',
);
@@ -128,6 +134,7 @@ describe('issue_comment_form component', () => {
it('should link to quick actions docs', () => {
const { quickActionsDocsPath } = notesDataMock;
+
expect(
vm.$el.querySelector(`a[href="${quickActionsDocsPath}"]`).textContent.trim(),
).toEqual('quick actions');
@@ -215,6 +222,7 @@ describe('issue_comment_form component', () => {
expect(vm.$el.querySelector('.btn-comment-and-close').textContent.trim()).toEqual(
'Comment & close issue',
);
+
expect(vm.$el.querySelector('.js-note-discard')).toBeDefined();
done();
});
diff --git a/spec/javascripts/notes/components/discussion_filter_spec.js b/spec/javascripts/notes/components/discussion_filter_spec.js
new file mode 100644
index 00000000000..70dd5bb3be5
--- /dev/null
+++ b/spec/javascripts/notes/components/discussion_filter_spec.js
@@ -0,0 +1,60 @@
+import Vue from 'vue';
+import createStore from '~/notes/stores';
+import DiscussionFilter from '~/notes/components/discussion_filter.vue';
+import { mountComponentWithStore } from '../../helpers/vue_mount_component_helper';
+import { discussionFiltersMock, discussionMock } from '../mock_data';
+
+describe('DiscussionFilter component', () => {
+ let vm;
+ let store;
+
+ beforeEach(() => {
+ store = createStore();
+
+ const discussions = [{
+ ...discussionMock,
+ id: discussionMock.id,
+ notes: [{ ...discussionMock.notes[0], resolvable: true, resolved: true }],
+ }];
+ const Component = Vue.extend(DiscussionFilter);
+ const defaultValue = discussionFiltersMock[0].value;
+
+ store.state.discussions = discussions;
+ vm = mountComponentWithStore(Component, {
+ el: null,
+ store,
+ props: {
+ filters: discussionFiltersMock,
+ defaultValue,
+ },
+ });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders the all filters', () => {
+ expect(vm.$el.querySelectorAll('.dropdown-menu li').length).toEqual(discussionFiltersMock.length);
+ });
+
+ it('renders the default selected item', () => {
+ expect(vm.$el.querySelector('#discussion-filter-dropdown').textContent.trim()).toEqual(discussionFiltersMock[0].title);
+ });
+
+ it('updates to the selected item', () => {
+ const filterItem = vm.$el.querySelector('.dropdown-menu li:last-child button');
+ filterItem.click();
+
+ expect(vm.currentFilter.title).toEqual(filterItem.textContent.trim());
+ });
+
+ it('only updates when selected filter changes', () => {
+ const filterItem = vm.$el.querySelector('.dropdown-menu li:first-child button');
+
+ spyOn(vm, 'filterDiscussion');
+ filterItem.click();
+
+ expect(vm.filterDiscussion).not.toHaveBeenCalled();
+ });
+});
diff --git a/spec/javascripts/notes/components/note_app_spec.js b/spec/javascripts/notes/components/note_app_spec.js
index 7eb4d3aed29..06b30375306 100644
--- a/spec/javascripts/notes/components/note_app_spec.js
+++ b/spec/javascripts/notes/components/note_app_spec.js
@@ -97,8 +97,7 @@ describe('note_app', () => {
});
it('should render list of notes', done => {
- const note =
- mockData.INDIVIDUAL_NOTE_RESPONSE_MAP.GET[
+ const note = mockData.INDIVIDUAL_NOTE_RESPONSE_MAP.GET[
'/gitlab-org/gitlab-ce/issues/26/discussions.json'
][0].notes[0];
@@ -223,6 +222,7 @@ describe('note_app', () => {
it('should render markdown docs url', () => {
const { markdownDocsPath } = mockData.notesDataMock;
+
expect(vm.$el.querySelector(`a[href="${markdownDocsPath}"]`).textContent.trim()).toEqual(
'Markdown',
);
@@ -230,6 +230,7 @@ describe('note_app', () => {
it('should render quick action docs url', () => {
const { quickActionsDocsPath } = mockData.notesDataMock;
+
expect(vm.$el.querySelector(`a[href="${quickActionsDocsPath}"]`).textContent.trim()).toEqual(
'quick actions',
);
diff --git a/spec/javascripts/notes/components/note_form_spec.js b/spec/javascripts/notes/components/note_form_spec.js
index 147ffcf1b81..5db20fd285f 100644
--- a/spec/javascripts/notes/components/note_form_spec.js
+++ b/spec/javascripts/notes/components/note_form_spec.js
@@ -76,6 +76,7 @@ describe('issue_note_form component', () => {
it('should link to markdown docs', () => {
const { markdownDocsPath } = notesDataMock;
+
expect(vm.$el.querySelector(`a[href="${markdownDocsPath}"]`).textContent.trim()).toEqual(
'Markdown',
);
@@ -100,6 +101,7 @@ describe('issue_note_form component', () => {
expect(vm.handleUpdate).toHaveBeenCalled();
});
+
it('should save note when ctrl+enter is pressed', () => {
spyOn(vm, 'handleUpdate').and.callThrough();
vm.$el.querySelector('textarea').value = 'Foo';
diff --git a/spec/javascripts/notes/components/noteable_discussion_spec.js b/spec/javascripts/notes/components/noteable_discussion_spec.js
index 40b5f009ceb..b447e79b0df 100644
--- a/spec/javascripts/notes/components/noteable_discussion_spec.js
+++ b/spec/javascripts/notes/components/noteable_discussion_spec.js
@@ -138,23 +138,21 @@ describe('noteable_discussion component', () => {
it('should return first note object for placeholder note', () => {
const data = {
isPlaceholderNote: true,
- notes: [
- { body: 'hello world!' },
- ],
+ notes: [{ body: 'hello world!' }],
};
const note = vm.componentData(data);
+
expect(note).toEqual(data.notes[0]);
});
it('should return given note for nonplaceholder notes', () => {
const data = {
- notes: [
- { id: 12 },
- ],
+ notes: [{ id: 12 }],
};
const note = vm.componentData(data);
+
expect(note).toEqual(data);
});
});
diff --git a/spec/javascripts/notes/components/noteable_note_spec.js b/spec/javascripts/notes/components/noteable_note_spec.js
index a31d17cacbb..8ade6fc2ced 100644
--- a/spec/javascripts/notes/components/noteable_note_spec.js
+++ b/spec/javascripts/notes/components/noteable_note_spec.js
@@ -36,6 +36,7 @@ describe('issue_note', () => {
it('should render note header content', () => {
const el = vm.$el.querySelector('.note-header .note-header-author-name');
+
expect(el.textContent.trim()).toEqual(note.author.name);
});
diff --git a/spec/javascripts/notes/helpers.js b/spec/javascripts/notes/helpers.js
index a7663710a56..3f349b40ba5 100644
--- a/spec/javascripts/notes/helpers.js
+++ b/spec/javascripts/notes/helpers.js
@@ -1,5 +1,5 @@
// eslint-disable-next-line import/prefer-default-export
-export const resetStore = (store) => {
+export const resetStore = store => {
store.replaceState({
notes: [],
targetNoteHash: null,
diff --git a/spec/javascripts/notes/mock_data.js b/spec/javascripts/notes/mock_data.js
index 9a0e7f34a9c..ad0e793b915 100644
--- a/spec/javascripts/notes/mock_data.js
+++ b/spec/javascripts/notes/mock_data.js
@@ -1244,3 +1244,18 @@ export const discussion3 = {
export const unresolvableDiscussion = {
resolvable: false,
};
+
+export const discussionFiltersMock = [
+ {
+ title: 'Show all activity',
+ value: 0,
+ },
+ {
+ title: 'Show comments only',
+ value: 1,
+ },
+ {
+ title: 'Show system notes only',
+ value: 2,
+ },
+];
diff --git a/spec/javascripts/notes/stores/collapse_utils_spec.js b/spec/javascripts/notes/stores/collapse_utils_spec.js
index 06a6aab932a..8ede9319088 100644
--- a/spec/javascripts/notes/stores/collapse_utils_spec.js
+++ b/spec/javascripts/notes/stores/collapse_utils_spec.js
@@ -4,10 +4,7 @@ import {
getTimeDifferenceMinutes,
collapseSystemNotes,
} from '~/notes/stores/collapse_utils';
-import {
- notesWithDescriptionChanges,
- collapsedSystemNotes,
-} from '../mock_data';
+import { notesWithDescriptionChanges, collapsedSystemNotes } from '../mock_data';
describe('Collapse utils', () => {
const mockSystemNote = {
@@ -22,14 +19,18 @@ describe('Collapse utils', () => {
});
it('returns false when a system note is not a description type', () => {
- expect(isDescriptionSystemNote(Object.assign({}, mockSystemNote, { note: 'foo' }))).toEqual(false);
+ expect(isDescriptionSystemNote(Object.assign({}, mockSystemNote, { note: 'foo' }))).toEqual(
+ false,
+ );
});
it('changes the description to contain the number of changed times', () => {
const changedNote = changeDescriptionNote(mockSystemNote, 3, 5);
expect(changedNote.times_updated).toEqual(3);
- expect(changedNote.note_html.trim()).toContain('<p dir="auto">changed the description 3 times within 5 minutes </p>');
+ expect(changedNote.note_html.trim()).toContain(
+ '<p dir="auto">changed the description 3 times within 5 minutes </p>',
+ );
});
it('gets the time difference between two notes', () => {
diff --git a/spec/javascripts/notes/stores/getters_spec.js b/spec/javascripts/notes/stores/getters_spec.js
index 7f8ede51508..f853f9ff088 100644
--- a/spec/javascripts/notes/stores/getters_spec.js
+++ b/spec/javascripts/notes/stores/getters_spec.js
@@ -205,6 +205,7 @@ describe('Getters Notes Store', () => {
'123',
'456',
]);
+
expect(getters.unresolvedDiscussionsIdsOrdered(state, localGetters)(undefined)).toEqual([
'123',
'456',
diff --git a/spec/javascripts/notes/stores/mutation_spec.js b/spec/javascripts/notes/stores/mutation_spec.js
index 1ecfe914859..9d652ba9f1e 100644
--- a/spec/javascripts/notes/stores/mutation_spec.js
+++ b/spec/javascripts/notes/stores/mutation_spec.js
@@ -30,11 +30,13 @@ describe('Notes Store mutations', () => {
expect(state).toEqual({
discussions: [noteData],
});
+
expect(state.discussions.length).toBe(1);
});
it('should not add the same note to the notes array', () => {
mutations.ADD_NEW_NOTE(state, note);
+
expect(state.discussions.length).toBe(1);
});
});
@@ -106,6 +108,7 @@ describe('Notes Store mutations', () => {
};
mutations.SET_NOTES_DATA(state, notesDataMock);
+
expect(state.notesData).toEqual(notesDataMock);
});
});
@@ -117,6 +120,7 @@ describe('Notes Store mutations', () => {
};
mutations.SET_NOTEABLE_DATA(state, noteableDataMock);
+
expect(state.noteableData).toEqual(noteableDataMock);
});
});
@@ -128,6 +132,7 @@ describe('Notes Store mutations', () => {
};
mutations.SET_USER_DATA(state, userDataMock);
+
expect(state.userData).toEqual(userDataMock);
});
});
@@ -151,6 +156,7 @@ describe('Notes Store mutations', () => {
};
mutations.SET_INITIAL_DISCUSSIONS(state, [note, legacyNote]);
+
expect(state.discussions[0].id).toEqual(note.id);
expect(state.discussions[1].notes[0].note).toBe(legacyNote.notes[0].note);
expect(state.discussions[2].notes[0].note).toBe(legacyNote.notes[1].note);
@@ -200,6 +206,7 @@ describe('Notes Store mutations', () => {
};
mutations.SET_LAST_FETCHED_AT(state, 'timestamp');
+
expect(state.lastFetchedAt).toEqual('timestamp');
});
});
@@ -211,6 +218,7 @@ describe('Notes Store mutations', () => {
};
mutations.SET_TARGET_NOTE_HASH(state, 'hash');
+
expect(state.targetNoteHash).toEqual('hash');
});
});
@@ -221,6 +229,7 @@ describe('Notes Store mutations', () => {
discussions: [],
};
mutations.SHOW_PLACEHOLDER_NOTE(state, note);
+
expect(state.discussions[0].isPlaceholderNote).toEqual(true);
});
});
@@ -261,6 +270,7 @@ describe('Notes Store mutations', () => {
awardName: 'bath_tone3',
};
mutations.TOGGLE_AWARD(state, data);
+
expect(state.discussions[0].award_emoji.length).toEqual(2);
});
});
@@ -316,6 +326,7 @@ describe('Notes Store mutations', () => {
};
mutations.CLOSE_ISSUE(state);
+
expect(state.noteableData.state).toEqual('closed');
});
});
@@ -333,6 +344,7 @@ describe('Notes Store mutations', () => {
};
mutations.REOPEN_ISSUE(state);
+
expect(state.noteableData.state).toEqual('reopened');
});
});
@@ -350,6 +362,7 @@ describe('Notes Store mutations', () => {
};
mutations.TOGGLE_STATE_BUTTON_LOADING(state, true);
+
expect(state.isToggleStateButtonLoading).toEqual(true);
});
@@ -365,6 +378,7 @@ describe('Notes Store mutations', () => {
};
mutations.TOGGLE_STATE_BUTTON_LOADING(state, false);
+
expect(state.isToggleStateButtonLoading).toEqual(false);
});
});
@@ -376,6 +390,7 @@ describe('Notes Store mutations', () => {
};
mutations.SET_NOTES_FETCHED_STATE(state, true);
+
expect(state.isNotesFetched).toEqual(true);
});
});
diff --git a/spec/javascripts/notes_spec.js b/spec/javascripts/notes_spec.js
index faeedae40e9..694f581150f 100644
--- a/spec/javascripts/notes_spec.js
+++ b/spec/javascripts/notes_spec.js
@@ -10,1011 +10,1024 @@ import '~/behaviors/markdown/render_gfm';
import Notes from '~/notes';
import timeoutPromise from './helpers/set_timeout_promise_helper';
-(function() {
- window.gon || (window.gon = {});
- window.gl = window.gl || {};
- gl.utils = gl.utils || {};
-
- const htmlEscape = comment => {
- const escapedString = comment.replace(/["&'<>]/g, a => {
- const escapedToken = {
- '&': '&amp;',
- '<': '&lt;',
- '>': '&gt;',
- '"': '&quot;',
- "'": '&#x27;',
- '`': '&#x60;',
- }[a];
-
- return escapedToken;
- });
-
- return escapedString;
- };
-
- describe('Notes', function() {
- const FLASH_TYPE_ALERT = 'alert';
- const NOTES_POST_PATH = /(.*)\/notes\?html=true$/;
- var fixture = 'snippets/show.html.raw';
- preloadFixtures(fixture);
+window.gon || (window.gon = {});
+window.gl = window.gl || {};
+gl.utils = gl.utils || {};
+
+const htmlEscape = comment => {
+ const escapedString = comment.replace(/["&'<>]/g, a => {
+ const escapedToken = {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&quot;',
+ "'": '&#x27;',
+ '`': '&#x60;',
+ }[a];
+
+ return escapedToken;
+ });
- beforeEach(function() {
- loadFixtures(fixture);
- gl.utils.disableButtonIfEmptyField = _.noop;
- window.project_uploads_path = 'http://test.host/uploads';
- $('body').attr('data-page', 'projects:merge_requets:show');
- });
+ return escapedString;
+};
- afterEach(() => {
- // Undo what we did to the shared <body>
- $('body').removeAttr('data-page');
- });
+describe('Notes', function() {
+ const FLASH_TYPE_ALERT = 'alert';
+ const NOTES_POST_PATH = /(.*)\/notes\?html=true$/;
+ var fixture = 'snippets/show.html.raw';
+ preloadFixtures(fixture);
- describe('addBinding', () => {
- it('calls postComment when comment button is clicked', () => {
- spyOn(Notes.prototype, 'postComment');
- this.notes = new Notes('', []);
+ beforeEach(function() {
+ loadFixtures(fixture);
+ gl.utils.disableButtonIfEmptyField = _.noop;
+ window.project_uploads_path = 'http://test.host/uploads';
+ $('body').attr('data-page', 'projects:merge_requets:show');
+ });
- $('.js-comment-button').click();
+ afterEach(() => {
+ // Undo what we did to the shared <body>
+ $('body').removeAttr('data-page');
+ });
- expect(Notes.prototype.postComment).toHaveBeenCalled();
- });
+ describe('addBinding', () => {
+ it('calls postComment when comment button is clicked', () => {
+ spyOn(Notes.prototype, 'postComment');
+ this.notes = new Notes('', []);
+
+ $('.js-comment-button').click();
+
+ expect(Notes.prototype.postComment).toHaveBeenCalled();
});
+ });
- describe('task lists', function() {
- let mock;
+ describe('task lists', function() {
+ let mock;
- beforeEach(function() {
- spyOn(axios, 'patch').and.callFake(() => new Promise(() => {}));
- mock = new MockAdapter(axios);
- mock.onAny().reply(200, {});
+ beforeEach(function() {
+ spyOn(axios, 'patch').and.callFake(() => new Promise(() => {}));
+ mock = new MockAdapter(axios);
+ mock.onAny().reply(200, {});
- $('.js-comment-button').on('click', function(e) {
- e.preventDefault();
- });
- this.notes = new Notes('', []);
+ $('.js-comment-button').on('click', function(e) {
+ e.preventDefault();
});
+ this.notes = new Notes('', []);
+ });
- afterEach(() => {
- mock.restore();
- });
+ afterEach(() => {
+ mock.restore();
+ });
- it('modifies the Markdown field', function() {
- const changeEvent = document.createEvent('HTMLEvents');
- changeEvent.initEvent('change', true, true);
- $('input[type=checkbox]')
- .attr('checked', true)[0]
- .dispatchEvent(changeEvent);
+ it('modifies the Markdown field', function() {
+ const changeEvent = document.createEvent('HTMLEvents');
+ changeEvent.initEvent('change', true, true);
+ $('input[type=checkbox]')
+ .attr('checked', true)[0]
+ .dispatchEvent(changeEvent);
- expect($('.js-task-list-field.original-task-list').val()).toBe('- [x] Task List Item');
- });
+ expect($('.js-task-list-field.original-task-list').val()).toBe('- [x] Task List Item');
+ });
- it('submits an ajax request on tasklist:changed', function(done) {
- $('.js-task-list-container').trigger('tasklist:changed');
+ it('submits an ajax request on tasklist:changed', function(done) {
+ $('.js-task-list-container').trigger('tasklist:changed');
- setTimeout(() => {
- expect(axios.patch).toHaveBeenCalled();
- done();
- });
+ setTimeout(() => {
+ expect(axios.patch).toHaveBeenCalled();
+ done();
});
});
+ });
- describe('comments', function() {
- var textarea = '.js-note-text';
+ describe('comments', function() {
+ var textarea = '.js-note-text';
- beforeEach(function() {
- this.notes = new Notes('', []);
+ beforeEach(function() {
+ this.notes = new Notes('', []);
- this.autoSizeSpy = spyOnEvent($(textarea), 'autosize:update');
- spyOn(this.notes, 'renderNote').and.stub();
+ this.autoSizeSpy = spyOnEvent($(textarea), 'autosize:update');
+ spyOn(this.notes, 'renderNote').and.stub();
- $(textarea).data('autosave', {
- reset: function() {},
- });
+ $(textarea).data('autosave', {
+ reset: function() {},
+ });
- $('.js-comment-button').on('click', e => {
- const $form = $(this);
- e.preventDefault();
- this.notes.addNote($form);
- this.notes.reenableTargetFormSubmitButton(e);
- this.notes.resetMainTargetForm(e);
- });
+ $('.js-comment-button').on('click', e => {
+ const $form = $(this);
+ e.preventDefault();
+ this.notes.addNote($form);
+ this.notes.reenableTargetFormSubmitButton(e);
+ this.notes.resetMainTargetForm(e);
});
+ });
- it('autosizes after comment submission', function() {
- $(textarea).text('This is an example comment note');
- expect(this.autoSizeSpy).not.toHaveBeenTriggered();
+ it('autosizes after comment submission', function() {
+ $(textarea).text('This is an example comment note');
- $('.js-comment-button').click();
- expect(this.autoSizeSpy).toHaveBeenTriggered();
- });
+ expect(this.autoSizeSpy).not.toHaveBeenTriggered();
- it('should not place escaped text in the comment box in case of error', function() {
- const deferred = $.Deferred();
- spyOn($, 'ajax').and.returnValue(deferred.promise());
- $(textarea).text('A comment with `markup`.');
+ $('.js-comment-button').click();
- deferred.reject();
- $('.js-comment-button').click();
- expect($(textarea).val()).toEqual('A comment with `markup`.');
- });
+ expect(this.autoSizeSpy).toHaveBeenTriggered();
});
- describe('updateNote', () => {
- let sampleComment;
- let noteEntity;
- let $form;
- let $notesContainer;
- let mock;
+ it('should not place escaped text in the comment box in case of error', function() {
+ const deferred = $.Deferred();
+ spyOn($, 'ajax').and.returnValue(deferred.promise());
+ $(textarea).text('A comment with `markup`.');
- beforeEach(() => {
- this.notes = new Notes('', []);
- window.gon.current_username = 'root';
- window.gon.current_user_fullname = 'Administrator';
- sampleComment = 'foo';
- noteEntity = {
- id: 1234,
- html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
- <div class="note-text">${sampleComment}</div>
- </li>`,
- note: sampleComment,
- valid: true,
- };
- $form = $('form.js-main-target-form');
- $notesContainer = $('ul.main-notes-list');
- $form.find('textarea.js-note-text').val(sampleComment);
+ deferred.reject();
+ $('.js-comment-button').click();
- mock = new MockAdapter(axios);
- mock.onPost(NOTES_POST_PATH).reply(200, noteEntity);
- });
+ expect($(textarea).val()).toEqual('A comment with `markup`.');
+ });
+ });
- afterEach(() => {
- mock.restore();
- });
+ describe('updateNote', () => {
+ let sampleComment;
+ let noteEntity;
+ let $form;
+ let $notesContainer;
+ let mock;
+
+ beforeEach(() => {
+ this.notes = new Notes('', []);
+ window.gon.current_username = 'root';
+ window.gon.current_user_fullname = 'Administrator';
+ sampleComment = 'foo';
+ noteEntity = {
+ id: 1234,
+ html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
+ <div class="note-text">${sampleComment}</div>
+ </li>`,
+ note: sampleComment,
+ valid: true,
+ };
+ $form = $('form.js-main-target-form');
+ $notesContainer = $('ul.main-notes-list');
+ $form.find('textarea.js-note-text').val(sampleComment);
+
+ mock = new MockAdapter(axios);
+ mock.onPost(NOTES_POST_PATH).reply(200, noteEntity);
+ });
- it('updates note and resets edit form', done => {
- spyOn(this.notes, 'revertNoteEditForm');
- spyOn(this.notes, 'setupNewNote');
+ afterEach(() => {
+ mock.restore();
+ });
- $('.js-comment-button').click();
+ it('updates note and resets edit form', done => {
+ spyOn(this.notes, 'revertNoteEditForm');
+ spyOn(this.notes, 'setupNewNote');
- setTimeout(() => {
- const $targetNote = $notesContainer.find(`#note_${noteEntity.id}`);
- const updatedNote = Object.assign({}, noteEntity);
- updatedNote.note = 'bar';
- this.notes.updateNote(updatedNote, $targetNote);
+ $('.js-comment-button').click();
- expect(this.notes.revertNoteEditForm).toHaveBeenCalledWith($targetNote);
- expect(this.notes.setupNewNote).toHaveBeenCalled();
+ setTimeout(() => {
+ const $targetNote = $notesContainer.find(`#note_${noteEntity.id}`);
+ const updatedNote = Object.assign({}, noteEntity);
+ updatedNote.note = 'bar';
+ this.notes.updateNote(updatedNote, $targetNote);
- done();
- });
+ expect(this.notes.revertNoteEditForm).toHaveBeenCalledWith($targetNote);
+ expect(this.notes.setupNewNote).toHaveBeenCalled();
+
+ done();
});
});
+ });
- describe('updateNoteTargetSelector', () => {
- const hash = 'note_foo';
- let $note;
+ describe('updateNoteTargetSelector', () => {
+ const hash = 'note_foo';
+ let $note;
- beforeEach(() => {
- $note = $(`<div id="${hash}"></div>`);
- spyOn($note, 'filter').and.callThrough();
- spyOn($note, 'toggleClass').and.callThrough();
- });
+ beforeEach(() => {
+ $note = $(`<div id="${hash}"></div>`);
+ spyOn($note, 'filter').and.callThrough();
+ spyOn($note, 'toggleClass').and.callThrough();
+ });
- it('sets target when hash matches', () => {
- spyOnDependency(Notes, 'getLocationHash').and.returnValue(hash);
+ it('sets target when hash matches', () => {
+ spyOnDependency(Notes, 'getLocationHash').and.returnValue(hash);
- Notes.updateNoteTargetSelector($note);
+ Notes.updateNoteTargetSelector($note);
- expect($note.filter).toHaveBeenCalledWith(`#${hash}`);
- expect($note.toggleClass).toHaveBeenCalledWith('target', true);
- });
+ expect($note.filter).toHaveBeenCalledWith(`#${hash}`);
+ expect($note.toggleClass).toHaveBeenCalledWith('target', true);
+ });
- it('unsets target when hash does not match', () => {
- spyOnDependency(Notes, 'getLocationHash').and.returnValue('note_doesnotexist');
+ it('unsets target when hash does not match', () => {
+ spyOnDependency(Notes, 'getLocationHash').and.returnValue('note_doesnotexist');
- Notes.updateNoteTargetSelector($note);
+ Notes.updateNoteTargetSelector($note);
- expect($note.toggleClass).toHaveBeenCalledWith('target', false);
- });
+ expect($note.toggleClass).toHaveBeenCalledWith('target', false);
+ });
- it('unsets target when there is not a hash fragment anymore', () => {
- spyOnDependency(Notes, 'getLocationHash').and.returnValue(null);
+ it('unsets target when there is not a hash fragment anymore', () => {
+ spyOnDependency(Notes, 'getLocationHash').and.returnValue(null);
- Notes.updateNoteTargetSelector($note);
+ Notes.updateNoteTargetSelector($note);
- expect($note.toggleClass).toHaveBeenCalledWith('target', false);
- });
+ expect($note.toggleClass).toHaveBeenCalledWith('target', false);
});
+ });
- describe('renderNote', () => {
- let notes;
- let note;
- let $notesList;
+ describe('renderNote', () => {
+ let notes;
+ let note;
+ let $notesList;
- beforeEach(() => {
- note = {
- id: 1,
- valid: true,
- note: 'heya',
- html: '<div>heya</div>',
- };
- $notesList = jasmine.createSpyObj('$notesList', ['find', 'append']);
-
- notes = jasmine.createSpyObj('notes', [
- 'setupNewNote',
- 'refresh',
- 'collapseLongCommitList',
- 'updateNotesCount',
- 'putConflictEditWarningInPlace',
- ]);
- notes.taskList = jasmine.createSpyObj('tasklist', ['init']);
- notes.note_ids = [];
- notes.updatedNotesTrackingMap = {};
-
- spyOn(Notes, 'isNewNote').and.callThrough();
- spyOn(Notes, 'isUpdatedNote').and.callThrough();
- spyOn(Notes, 'animateAppendNote').and.callThrough();
- spyOn(Notes, 'animateUpdateNote').and.callThrough();
+ beforeEach(() => {
+ note = {
+ id: 1,
+ valid: true,
+ note: 'heya',
+ html: '<div>heya</div>',
+ };
+ $notesList = jasmine.createSpyObj('$notesList', ['find', 'append']);
+
+ notes = jasmine.createSpyObj('notes', [
+ 'setupNewNote',
+ 'refresh',
+ 'collapseLongCommitList',
+ 'updateNotesCount',
+ 'putConflictEditWarningInPlace',
+ ]);
+ notes.taskList = jasmine.createSpyObj('tasklist', ['init']);
+ notes.note_ids = [];
+ notes.updatedNotesTrackingMap = {};
+
+ spyOn(Notes, 'isNewNote').and.callThrough();
+ spyOn(Notes, 'isUpdatedNote').and.callThrough();
+ spyOn(Notes, 'animateAppendNote').and.callThrough();
+ spyOn(Notes, 'animateUpdateNote').and.callThrough();
+ });
+
+ describe('when adding note', () => {
+ it('should call .animateAppendNote', () => {
+ Notes.isNewNote.and.returnValue(true);
+ Notes.prototype.renderNote.call(notes, note, null, $notesList);
+
+ expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.html, $notesList);
});
+ });
- describe('when adding note', () => {
- it('should call .animateAppendNote', () => {
- Notes.isNewNote.and.returnValue(true);
- Notes.prototype.renderNote.call(notes, note, null, $notesList);
+ describe('when note was edited', () => {
+ it('should call .animateUpdateNote', () => {
+ Notes.isNewNote.and.returnValue(false);
+ Notes.isUpdatedNote.and.returnValue(true);
+ const $note = $('<div>');
+ $notesList.find.and.returnValue($note);
+ const $newNote = $(note.html);
+ Notes.animateUpdateNote.and.returnValue($newNote);
- expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.html, $notesList);
- });
+ Notes.prototype.renderNote.call(notes, note, null, $notesList);
+
+ expect(Notes.animateUpdateNote).toHaveBeenCalledWith(note.html, $note);
+ expect(notes.setupNewNote).toHaveBeenCalledWith($newNote);
});
- describe('when note was edited', () => {
- it('should call .animateUpdateNote', () => {
+ describe('while editing', () => {
+ it('should update textarea if nothing has been touched', () => {
Notes.isNewNote.and.returnValue(false);
Notes.isUpdatedNote.and.returnValue(true);
- const $note = $('<div>');
+ const $note = $(`<div class="is-editing">
+ <div class="original-note-content">initial</div>
+ <textarea class="js-note-text">initial</textarea>
+ </div>`);
$notesList.find.and.returnValue($note);
- const $newNote = $(note.html);
- Notes.animateUpdateNote.and.returnValue($newNote);
-
Notes.prototype.renderNote.call(notes, note, null, $notesList);
- expect(Notes.animateUpdateNote).toHaveBeenCalledWith(note.html, $note);
- expect(notes.setupNewNote).toHaveBeenCalledWith($newNote);
+ expect($note.find('.js-note-text').val()).toEqual(note.note);
});
- describe('while editing', () => {
- it('should update textarea if nothing has been touched', () => {
- Notes.isNewNote.and.returnValue(false);
- Notes.isUpdatedNote.and.returnValue(true);
- const $note = $(`<div class="is-editing">
- <div class="original-note-content">initial</div>
- <textarea class="js-note-text">initial</textarea>
- </div>`);
- $notesList.find.and.returnValue($note);
- Notes.prototype.renderNote.call(notes, note, null, $notesList);
-
- expect($note.find('.js-note-text').val()).toEqual(note.note);
- });
-
- it('should call .putConflictEditWarningInPlace', () => {
- Notes.isNewNote.and.returnValue(false);
- Notes.isUpdatedNote.and.returnValue(true);
- const $note = $(`<div class="is-editing">
- <div class="original-note-content">initial</div>
- <textarea class="js-note-text">different</textarea>
- </div>`);
- $notesList.find.and.returnValue($note);
- Notes.prototype.renderNote.call(notes, note, null, $notesList);
-
- expect(notes.putConflictEditWarningInPlace).toHaveBeenCalledWith(note, $note);
- });
+ it('should call .putConflictEditWarningInPlace', () => {
+ Notes.isNewNote.and.returnValue(false);
+ Notes.isUpdatedNote.and.returnValue(true);
+ const $note = $(`<div class="is-editing">
+ <div class="original-note-content">initial</div>
+ <textarea class="js-note-text">different</textarea>
+ </div>`);
+ $notesList.find.and.returnValue($note);
+ Notes.prototype.renderNote.call(notes, note, null, $notesList);
+
+ expect(notes.putConflictEditWarningInPlace).toHaveBeenCalledWith(note, $note);
});
});
});
+ });
- describe('isUpdatedNote', () => {
- it('should consider same note text as the same', () => {
- const result = Notes.isUpdatedNote(
- {
- note: 'initial',
- },
- $(`<div>
- <div class="original-note-content">initial</div>
- </div>`),
- );
+ describe('isUpdatedNote', () => {
+ it('should consider same note text as the same', () => {
+ const result = Notes.isUpdatedNote(
+ {
+ note: 'initial',
+ },
+ $(`<div>
+ <div class="original-note-content">initial</div>
+ </div>`),
+ );
- expect(result).toEqual(false);
- });
+ expect(result).toEqual(false);
+ });
- it('should consider same note with trailing newline as the same', () => {
- const result = Notes.isUpdatedNote(
- {
- note: 'initial\n',
- },
- $(`<div>
- <div class="original-note-content">initial\n</div>
- </div>`),
- );
+ it('should consider same note with trailing newline as the same', () => {
+ const result = Notes.isUpdatedNote(
+ {
+ note: 'initial\n',
+ },
+ $(`<div>
+ <div class="original-note-content">initial\n</div>
+ </div>`),
+ );
- expect(result).toEqual(false);
- });
+ expect(result).toEqual(false);
+ });
- it('should consider different notes as different', () => {
- const result = Notes.isUpdatedNote(
- {
- note: 'foo',
- },
- $(`<div>
- <div class="original-note-content">bar</div>
- </div>`),
- );
+ it('should consider different notes as different', () => {
+ const result = Notes.isUpdatedNote(
+ {
+ note: 'foo',
+ },
+ $(`<div>
+ <div class="original-note-content">bar</div>
+ </div>`),
+ );
- expect(result).toEqual(true);
- });
+ expect(result).toEqual(true);
+ });
+ });
+
+ describe('renderDiscussionNote', () => {
+ let discussionContainer;
+ let note;
+ let notes;
+ let $form;
+ let row;
+
+ beforeEach(() => {
+ note = {
+ html: '<li></li>',
+ discussion_html: '<div></div>',
+ discussion_id: 1,
+ discussion_resolvable: false,
+ diff_discussion_html: false,
+ };
+ $form = jasmine.createSpyObj('$form', ['closest', 'find']);
+ $form.length = 1;
+ row = jasmine.createSpyObj('row', ['prevAll', 'first', 'find']);
+
+ notes = jasmine.createSpyObj('notes', ['isParallelView', 'updateNotesCount']);
+ notes.note_ids = [];
+
+ spyOn(Notes, 'isNewNote');
+ spyOn(Notes, 'animateAppendNote');
+ Notes.isNewNote.and.returnValue(true);
+ notes.isParallelView.and.returnValue(false);
+ row.prevAll.and.returnValue(row);
+ row.first.and.returnValue(row);
+ row.find.and.returnValue(row);
});
- describe('renderDiscussionNote', () => {
- let discussionContainer;
- let note;
- let notes;
- let $form;
- let row;
+ describe('Discussion root note', () => {
+ let body;
beforeEach(() => {
- note = {
- html: '<li></li>',
- discussion_html: '<div></div>',
- discussion_id: 1,
- discussion_resolvable: false,
- diff_discussion_html: false,
- };
- $form = jasmine.createSpyObj('$form', ['closest', 'find']);
- $form.length = 1;
- row = jasmine.createSpyObj('row', ['prevAll', 'first', 'find']);
-
- notes = jasmine.createSpyObj('notes', ['isParallelView', 'updateNotesCount']);
- notes.note_ids = [];
+ body = jasmine.createSpyObj('body', ['attr']);
+ discussionContainer = { length: 0 };
- spyOn(Notes, 'isNewNote');
- spyOn(Notes, 'animateAppendNote');
- Notes.isNewNote.and.returnValue(true);
- notes.isParallelView.and.returnValue(false);
- row.prevAll.and.returnValue(row);
- row.first.and.returnValue(row);
- row.find.and.returnValue(row);
+ $form.closest.and.returnValues(row, $form);
+ $form.find.and.returnValues(discussionContainer);
+ body.attr.and.returnValue('');
});
- describe('Discussion root note', () => {
- let body;
-
- beforeEach(() => {
- body = jasmine.createSpyObj('body', ['attr']);
- discussionContainer = { length: 0 };
+ it('should call Notes.animateAppendNote', () => {
+ Notes.prototype.renderDiscussionNote.call(notes, note, $form);
- $form.closest.and.returnValues(row, $form);
- $form.find.and.returnValues(discussionContainer);
- body.attr.and.returnValue('');
- });
-
- it('should call Notes.animateAppendNote', () => {
- Notes.prototype.renderDiscussionNote.call(notes, note, $form);
-
- expect(Notes.animateAppendNote).toHaveBeenCalledWith(
- note.discussion_html,
- $('.main-notes-list'),
- );
- });
+ expect(Notes.animateAppendNote).toHaveBeenCalledWith(
+ note.discussion_html,
+ $('.main-notes-list'),
+ );
+ });
- it('should append to row selected with line_code', () => {
- $form.length = 0;
- note.discussion_line_code = 'line_code';
- note.diff_discussion_html = '<tr></tr>';
+ it('should append to row selected with line_code', () => {
+ $form.length = 0;
+ note.discussion_line_code = 'line_code';
+ note.diff_discussion_html = '<tr></tr>';
- const line = document.createElement('div');
- line.id = note.discussion_line_code;
- document.body.appendChild(line);
+ const line = document.createElement('div');
+ line.id = note.discussion_line_code;
+ document.body.appendChild(line);
- $form.closest.and.returnValues($form);
+ $form.closest.and.returnValues($form);
- Notes.prototype.renderDiscussionNote.call(notes, note, $form);
+ Notes.prototype.renderDiscussionNote.call(notes, note, $form);
- expect(line.nextSibling.outerHTML).toEqual(note.diff_discussion_html);
- });
+ expect(line.nextSibling.outerHTML).toEqual(note.diff_discussion_html);
});
+ });
- describe('Discussion sub note', () => {
- beforeEach(() => {
- discussionContainer = { length: 1 };
+ describe('Discussion sub note', () => {
+ beforeEach(() => {
+ discussionContainer = { length: 1 };
- $form.closest.and.returnValues(row, $form);
- $form.find.and.returnValues(discussionContainer);
+ $form.closest.and.returnValues(row, $form);
+ $form.find.and.returnValues(discussionContainer);
- Notes.prototype.renderDiscussionNote.call(notes, note, $form);
- });
+ Notes.prototype.renderDiscussionNote.call(notes, note, $form);
+ });
- it('should call Notes.animateAppendNote', () => {
- expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.html, discussionContainer);
- });
+ it('should call Notes.animateAppendNote', () => {
+ expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.html, discussionContainer);
});
});
+ });
- describe('animateAppendNote', () => {
- let noteHTML;
- let $notesList;
- let $resultantNote;
+ describe('animateAppendNote', () => {
+ let noteHTML;
+ let $notesList;
+ let $resultantNote;
- beforeEach(() => {
- noteHTML = '<div></div>';
- $notesList = jasmine.createSpyObj('$notesList', ['append']);
+ beforeEach(() => {
+ noteHTML = '<div></div>';
+ $notesList = jasmine.createSpyObj('$notesList', ['append']);
- $resultantNote = Notes.animateAppendNote(noteHTML, $notesList);
- });
+ $resultantNote = Notes.animateAppendNote(noteHTML, $notesList);
+ });
- it('should have `fade-in-full` class', () => {
- expect($resultantNote.hasClass('fade-in-full')).toEqual(true);
- });
+ it('should have `fade-in-full` class', () => {
+ expect($resultantNote.hasClass('fade-in-full')).toEqual(true);
+ });
- it('should append note to the notes list', () => {
- expect($notesList.append).toHaveBeenCalledWith($resultantNote);
- });
+ it('should append note to the notes list', () => {
+ expect($notesList.append).toHaveBeenCalledWith($resultantNote);
});
+ });
- describe('animateUpdateNote', () => {
- let noteHTML;
- let $note;
- let $updatedNote;
+ describe('animateUpdateNote', () => {
+ let noteHTML;
+ let $note;
+ let $updatedNote;
- beforeEach(() => {
- noteHTML = '<div></div>';
- $note = jasmine.createSpyObj('$note', ['replaceWith']);
+ beforeEach(() => {
+ noteHTML = '<div></div>';
+ $note = jasmine.createSpyObj('$note', ['replaceWith']);
- $updatedNote = Notes.animateUpdateNote(noteHTML, $note);
- });
+ $updatedNote = Notes.animateUpdateNote(noteHTML, $note);
+ });
- it('should have `fade-in` class', () => {
- expect($updatedNote.hasClass('fade-in')).toEqual(true);
- });
+ it('should have `fade-in` class', () => {
+ expect($updatedNote.hasClass('fade-in')).toEqual(true);
+ });
- it('should call replaceWith on $note', () => {
- expect($note.replaceWith).toHaveBeenCalledWith($updatedNote);
- });
+ it('should call replaceWith on $note', () => {
+ expect($note.replaceWith).toHaveBeenCalledWith($updatedNote);
});
+ });
- describe('putEditFormInPlace', () => {
- it('should call GLForm with GFM parameter passed through', () => {
- const notes = new Notes('', []);
- const $el = $(`
- <div>
- <form></form>
- </div>
- `);
+ describe('putEditFormInPlace', () => {
+ it('should call GLForm with GFM parameter passed through', () => {
+ const notes = new Notes('', []);
+ const $el = $(`
+ <div>
+ <form></form>
+ </div>
+ `);
- notes.putEditFormInPlace($el);
+ notes.putEditFormInPlace($el);
- expect(notes.glForm.enableGFM).toBeTruthy();
- });
+ expect(notes.glForm.enableGFM).toBeTruthy();
});
+ });
- describe('postComment & updateComment', () => {
- const sampleComment = 'foo';
- const updatedComment = 'bar';
- const note = {
- id: 1234,
- html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
- <div class="note-text">${sampleComment}</div>
- </li>`,
- note: sampleComment,
- valid: true,
- };
- let $form;
- let $notesContainer;
- let mock;
+ describe('postComment & updateComment', () => {
+ const sampleComment = 'foo';
+ const updatedComment = 'bar';
+ const note = {
+ id: 1234,
+ html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
+ <div class="note-text">${sampleComment}</div>
+ </li>`,
+ note: sampleComment,
+ valid: true,
+ };
+ let $form;
+ let $notesContainer;
+ let mock;
+
+ function mockNotesPost() {
+ mock.onPost(NOTES_POST_PATH).reply(200, note);
+ }
+
+ function mockNotesPostError() {
+ mock.onPost(NOTES_POST_PATH).networkError();
+ }
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+
+ this.notes = new Notes('', []);
+ window.gon.current_username = 'root';
+ window.gon.current_user_fullname = 'Administrator';
+ $form = $('form.js-main-target-form');
+ $notesContainer = $('ul.main-notes-list');
+ $form.find('textarea.js-note-text').val(sampleComment);
+ });
- function mockNotesPost() {
- mock.onPost(NOTES_POST_PATH).reply(200, note);
- }
+ afterEach(() => {
+ mock.restore();
+ });
- function mockNotesPostError() {
- mock.onPost(NOTES_POST_PATH).networkError();
- }
+ it('should show placeholder note while new comment is being posted', () => {
+ mockNotesPost();
- beforeEach(() => {
- mock = new MockAdapter(axios);
-
- this.notes = new Notes('', []);
- window.gon.current_username = 'root';
- window.gon.current_user_fullname = 'Administrator';
- $form = $('form.js-main-target-form');
- $notesContainer = $('ul.main-notes-list');
- $form.find('textarea.js-note-text').val(sampleComment);
- });
+ $('.js-comment-button').click();
- afterEach(() => {
- mock.restore();
- });
+ expect($notesContainer.find('.note.being-posted').length).toBeGreaterThan(0);
+ });
- it('should show placeholder note while new comment is being posted', () => {
- mockNotesPost();
+ it('should remove placeholder note when new comment is done posting', done => {
+ mockNotesPost();
- $('.js-comment-button').click();
- expect($notesContainer.find('.note.being-posted').length > 0).toEqual(true);
- });
+ $('.js-comment-button').click();
- it('should remove placeholder note when new comment is done posting', done => {
- mockNotesPost();
+ setTimeout(() => {
+ expect($notesContainer.find('.note.being-posted').length).toEqual(0);
- $('.js-comment-button').click();
+ done();
+ });
+ });
- setTimeout(() => {
- expect($notesContainer.find('.note.being-posted').length).toEqual(0);
+ describe('postComment', () => {
+ it('disables the submit button', done => {
+ const $submitButton = $form.find('.js-comment-submit-button');
- done();
+ expect($submitButton).not.toBeDisabled();
+ const dummyEvent = {
+ preventDefault() {},
+ target: $submitButton,
+ };
+ mock.onPost(NOTES_POST_PATH).replyOnce(() => {
+ expect($submitButton).toBeDisabled();
+ return [200, note];
});
- });
- describe('postComment', () => {
- it('disables the submit button', done => {
- const $submitButton = $form.find('.js-comment-submit-button');
- expect($submitButton).not.toBeDisabled();
- const dummyEvent = {
- preventDefault() {},
- target: $submitButton,
- };
- mock.onPost(NOTES_POST_PATH).replyOnce(() => {
- expect($submitButton).toBeDisabled();
- return [200, note];
- });
-
- this.notes
- .postComment(dummyEvent)
- .then(() => {
- expect($submitButton).not.toBeDisabled();
- })
- .then(done)
- .catch(done.fail);
- });
+ this.notes
+ .postComment(dummyEvent)
+ .then(() => {
+ expect($submitButton).not.toBeDisabled();
+ })
+ .then(done)
+ .catch(done.fail);
});
+ });
- it('should show actual note element when new comment is done posting', done => {
- mockNotesPost();
+ it('should show actual note element when new comment is done posting', done => {
+ mockNotesPost();
- $('.js-comment-button').click();
+ $('.js-comment-button').click();
- setTimeout(() => {
- expect($notesContainer.find(`#note_${note.id}`).length > 0).toEqual(true);
+ setTimeout(() => {
+ expect($notesContainer.find(`#note_${note.id}`).length).toBeGreaterThan(0);
- done();
- });
+ done();
});
+ });
- it('should reset Form when new comment is done posting', done => {
- mockNotesPost();
+ it('should reset Form when new comment is done posting', done => {
+ mockNotesPost();
- $('.js-comment-button').click();
+ $('.js-comment-button').click();
- setTimeout(() => {
- expect($form.find('textarea.js-note-text').val()).toEqual('');
+ setTimeout(() => {
+ expect($form.find('textarea.js-note-text').val()).toEqual('');
- done();
- });
+ done();
});
+ });
- it('should show flash error message when new comment failed to be posted', done => {
- mockNotesPostError();
+ it('should show flash error message when new comment failed to be posted', done => {
+ mockNotesPostError();
- $('.js-comment-button').click();
+ $('.js-comment-button').click();
- setTimeout(() => {
- expect(
- $notesContainer
- .parent()
- .find('.flash-container .flash-text')
- .is(':visible'),
- ).toEqual(true);
+ setTimeout(() => {
+ expect(
+ $notesContainer
+ .parent()
+ .find('.flash-container .flash-text')
+ .is(':visible'),
+ ).toEqual(true);
- done();
- });
+ done();
});
+ });
- it('should show flash error message when comment failed to be updated', done => {
- mockNotesPost();
+ it('should show flash error message when comment failed to be updated', done => {
+ mockNotesPost();
- $('.js-comment-button').click();
+ $('.js-comment-button').click();
- timeoutPromise()
- .then(() => {
- const $noteEl = $notesContainer.find(`#note_${note.id}`);
- $noteEl.find('.js-note-edit').click();
- $noteEl.find('textarea.js-note-text').val(updatedComment);
+ timeoutPromise()
+ .then(() => {
+ const $noteEl = $notesContainer.find(`#note_${note.id}`);
+ $noteEl.find('.js-note-edit').click();
+ $noteEl.find('textarea.js-note-text').val(updatedComment);
- mock.restore();
+ mock.restore();
- mockNotesPostError();
+ mockNotesPostError();
- $noteEl.find('.js-comment-save-button').click();
- })
- .then(timeoutPromise)
- .then(() => {
- const $updatedNoteEl = $notesContainer.find(`#note_${note.id}`);
- expect($updatedNoteEl.hasClass('.being-posted')).toEqual(false); // Remove being-posted visuals
- expect(
- $updatedNoteEl
- .find('.note-text')
- .text()
- .trim(),
- ).toEqual(sampleComment); // See if comment reverted back to original
- expect($('.flash-container').is(':visible')).toEqual(true); // Flash error message shown
-
- done();
- })
- .catch(done.fail);
- });
+ $noteEl.find('.js-comment-save-button').click();
+ })
+ .then(timeoutPromise)
+ .then(() => {
+ const $updatedNoteEl = $notesContainer.find(`#note_${note.id}`);
+
+ expect($updatedNoteEl.hasClass('.being-posted')).toEqual(false); // Remove being-posted visuals
+ expect(
+ $updatedNoteEl
+ .find('.note-text')
+ .text()
+ .trim(),
+ ).toEqual(sampleComment); // See if comment reverted back to original
+
+ expect($('.flash-container').is(':visible')).toEqual(true); // Flash error message shown
+
+ done();
+ })
+ .catch(done.fail);
});
+ });
- describe('postComment with Slash commands', () => {
- const sampleComment = '/assign @root\n/award :100:';
- const note = {
- commands_changes: {
- assignee_id: 1,
- emoji_award: '100',
- },
- errors: {
- commands_only: ['Commands applied'],
+ describe('postComment with Slash commands', () => {
+ const sampleComment = '/assign @root\n/award :100:';
+ const note = {
+ commands_changes: {
+ assignee_id: 1,
+ emoji_award: '100',
+ },
+ errors: {
+ commands_only: ['Commands applied'],
+ },
+ valid: false,
+ };
+ let $form;
+ let $notesContainer;
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ mock.onPost(NOTES_POST_PATH).reply(200, note);
+
+ this.notes = new Notes('', []);
+ window.gon.current_username = 'root';
+ window.gon.current_user_fullname = 'Administrator';
+ gl.awardsHandler = {
+ addAwardToEmojiBar: () => {},
+ scrollToAwards: () => {},
+ };
+ gl.GfmAutoComplete = {
+ dataSources: {
+ commands: '/root/test-project/autocomplete_sources/commands',
},
- valid: false,
};
- let $form;
- let $notesContainer;
- let mock;
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- mock.onPost(NOTES_POST_PATH).reply(200, note);
-
- this.notes = new Notes('', []);
- window.gon.current_username = 'root';
- window.gon.current_user_fullname = 'Administrator';
- gl.awardsHandler = {
- addAwardToEmojiBar: () => {},
- scrollToAwards: () => {},
- };
- gl.GfmAutoComplete = {
- dataSources: {
- commands: '/root/test-project/autocomplete_sources/commands',
- },
- };
- $form = $('form.js-main-target-form');
- $notesContainer = $('ul.main-notes-list');
- $form.find('textarea.js-note-text').val(sampleComment);
- });
+ $form = $('form.js-main-target-form');
+ $notesContainer = $('ul.main-notes-list');
+ $form.find('textarea.js-note-text').val(sampleComment);
+ });
- afterEach(() => {
- mock.restore();
- });
+ afterEach(() => {
+ mock.restore();
+ });
- it('should remove slash command placeholder when comment with slash commands is done posting', done => {
- spyOn(gl.awardsHandler, 'addAwardToEmojiBar').and.callThrough();
- $('.js-comment-button').click();
+ it('should remove slash command placeholder when comment with slash commands is done posting', done => {
+ spyOn(gl.awardsHandler, 'addAwardToEmojiBar').and.callThrough();
+ $('.js-comment-button').click();
- expect($notesContainer.find('.system-note.being-posted').length).toEqual(1); // Placeholder shown
+ expect($notesContainer.find('.system-note.being-posted').length).toEqual(1); // Placeholder shown
- setTimeout(() => {
- expect($notesContainer.find('.system-note.being-posted').length).toEqual(0); // Placeholder removed
- done();
- });
+ setTimeout(() => {
+ expect($notesContainer.find('.system-note.being-posted').length).toEqual(0); // Placeholder removed
+ done();
});
});
+ });
- describe('update comment with script tags', () => {
- const sampleComment = '<script></script>';
- const updatedComment = '<script></script>';
- const note = {
- id: 1234,
- html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
- <div class="note-text">${sampleComment}</div>
- </li>`,
- note: sampleComment,
- valid: true,
- };
- let $form;
- let $notesContainer;
- let mock;
+ describe('update comment with script tags', () => {
+ const sampleComment = '<script></script>';
+ const updatedComment = '<script></script>';
+ const note = {
+ id: 1234,
+ html: `<li class="note note-row-1234 timeline-entry" id="note_1234">
+ <div class="note-text">${sampleComment}</div>
+ </li>`,
+ note: sampleComment,
+ valid: true,
+ };
+ let $form;
+ let $notesContainer;
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ mock.onPost(NOTES_POST_PATH).reply(200, note);
+
+ this.notes = new Notes('', []);
+ window.gon.current_username = 'root';
+ window.gon.current_user_fullname = 'Administrator';
+ $form = $('form.js-main-target-form');
+ $notesContainer = $('ul.main-notes-list');
+ $form.find('textarea.js-note-text').html(sampleComment);
+ });
- beforeEach(() => {
- mock = new MockAdapter(axios);
- mock.onPost(NOTES_POST_PATH).reply(200, note);
-
- this.notes = new Notes('', []);
- window.gon.current_username = 'root';
- window.gon.current_user_fullname = 'Administrator';
- $form = $('form.js-main-target-form');
- $notesContainer = $('ul.main-notes-list');
- $form.find('textarea.js-note-text').html(sampleComment);
- });
+ afterEach(() => {
+ mock.restore();
+ });
- afterEach(() => {
- mock.restore();
- });
+ it('should not render a script tag', done => {
+ $('.js-comment-button').click();
- it('should not render a script tag', done => {
- $('.js-comment-button').click();
+ setTimeout(() => {
+ const $noteEl = $notesContainer.find(`#note_${note.id}`);
+ $noteEl.find('.js-note-edit').click();
+ $noteEl.find('textarea.js-note-text').html(updatedComment);
+ $noteEl.find('.js-comment-save-button').click();
- setTimeout(() => {
- const $noteEl = $notesContainer.find(`#note_${note.id}`);
- $noteEl.find('.js-note-edit').click();
- $noteEl.find('textarea.js-note-text').html(updatedComment);
- $noteEl.find('.js-comment-save-button').click();
+ const $updatedNoteEl = $notesContainer
+ .find(`#note_${note.id}`)
+ .find('.js-task-list-container');
- const $updatedNoteEl = $notesContainer
- .find(`#note_${note.id}`)
- .find('.js-task-list-container');
- expect(
- $updatedNoteEl
- .find('.note-text')
- .text()
- .trim(),
- ).toEqual('');
+ expect(
+ $updatedNoteEl
+ .find('.note-text')
+ .text()
+ .trim(),
+ ).toEqual('');
- done();
- });
+ done();
});
});
+ });
- describe('getFormData', () => {
- let $form;
- let sampleComment;
+ describe('getFormData', () => {
+ let $form;
+ let sampleComment;
- beforeEach(() => {
- this.notes = new Notes('', []);
+ beforeEach(() => {
+ this.notes = new Notes('', []);
- $form = $('form');
- sampleComment = 'foobar';
- });
+ $form = $('form');
+ sampleComment = 'foobar';
+ });
- it('should return form metadata object from form reference', () => {
- $form.find('textarea.js-note-text').val(sampleComment);
- const { formData, formContent, formAction } = this.notes.getFormData($form);
+ it('should return form metadata object from form reference', () => {
+ $form.find('textarea.js-note-text').val(sampleComment);
+ const { formData, formContent, formAction } = this.notes.getFormData($form);
- expect(formData.indexOf(sampleComment) > -1).toBe(true);
- expect(formContent).toEqual(sampleComment);
- expect(formAction).toEqual($form.attr('action'));
- });
+ expect(formData.indexOf(sampleComment)).toBeGreaterThan(-1);
+ expect(formContent).toEqual(sampleComment);
+ expect(formAction).toEqual($form.attr('action'));
+ });
- it('should return form metadata with sanitized formContent from form reference', () => {
- spyOn(_, 'escape').and.callFake(htmlEscape);
+ it('should return form metadata with sanitized formContent from form reference', () => {
+ spyOn(_, 'escape').and.callFake(htmlEscape);
- sampleComment = '<script>alert("Boom!");</script>';
- $form.find('textarea.js-note-text').val(sampleComment);
+ sampleComment = '<script>alert("Boom!");</script>';
+ $form.find('textarea.js-note-text').val(sampleComment);
- const { formContent } = this.notes.getFormData($form);
+ const { formContent } = this.notes.getFormData($form);
- expect(_.escape).toHaveBeenCalledWith(sampleComment);
- expect(formContent).toEqual('&lt;script&gt;alert(&quot;Boom!&quot;);&lt;/script&gt;');
- });
+ expect(_.escape).toHaveBeenCalledWith(sampleComment);
+ expect(formContent).toEqual('&lt;script&gt;alert(&quot;Boom!&quot;);&lt;/script&gt;');
});
+ });
- describe('hasQuickActions', () => {
- beforeEach(() => {
- this.notes = new Notes('', []);
- });
+ describe('hasQuickActions', () => {
+ beforeEach(() => {
+ this.notes = new Notes('', []);
+ });
- it('should return true when comment begins with a quick action', () => {
- const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
- const hasQuickActions = this.notes.hasQuickActions(sampleComment);
+ it('should return true when comment begins with a quick action', () => {
+ const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
+ const hasQuickActions = this.notes.hasQuickActions(sampleComment);
- expect(hasQuickActions).toBeTruthy();
- });
+ expect(hasQuickActions).toBeTruthy();
+ });
- it('should return false when comment does NOT begin with a quick action', () => {
- const sampleComment = 'Hey, /unassign Merging this';
- const hasQuickActions = this.notes.hasQuickActions(sampleComment);
+ it('should return false when comment does NOT begin with a quick action', () => {
+ const sampleComment = 'Hey, /unassign Merging this';
+ const hasQuickActions = this.notes.hasQuickActions(sampleComment);
- expect(hasQuickActions).toBeFalsy();
- });
+ expect(hasQuickActions).toBeFalsy();
+ });
- it('should return false when comment does NOT have any quick actions', () => {
- const sampleComment = 'Looking good, Awesome!';
- const hasQuickActions = this.notes.hasQuickActions(sampleComment);
+ it('should return false when comment does NOT have any quick actions', () => {
+ const sampleComment = 'Looking good, Awesome!';
+ const hasQuickActions = this.notes.hasQuickActions(sampleComment);
- expect(hasQuickActions).toBeFalsy();
- });
+ expect(hasQuickActions).toBeFalsy();
});
+ });
- describe('stripQuickActions', () => {
- it('should strip quick actions from the comment which begins with a quick action', () => {
- this.notes = new Notes();
- const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
- const stripedComment = this.notes.stripQuickActions(sampleComment);
+ describe('stripQuickActions', () => {
+ it('should strip quick actions from the comment which begins with a quick action', () => {
+ this.notes = new Notes();
+ const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
+ const stripedComment = this.notes.stripQuickActions(sampleComment);
- expect(stripedComment).toBe('');
- });
+ expect(stripedComment).toBe('');
+ });
- it('should strip quick actions from the comment but leaves plain comment if it is present', () => {
- this.notes = new Notes();
- const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign\nMerging this';
- const stripedComment = this.notes.stripQuickActions(sampleComment);
+ it('should strip quick actions from the comment but leaves plain comment if it is present', () => {
+ this.notes = new Notes();
+ const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign\nMerging this';
+ const stripedComment = this.notes.stripQuickActions(sampleComment);
- expect(stripedComment).toBe('Merging this');
- });
+ expect(stripedComment).toBe('Merging this');
+ });
- it('should NOT strip string that has slashes within', () => {
- this.notes = new Notes();
- const sampleComment = 'http://127.0.0.1:3000/root/gitlab-shell/issues/1';
- const stripedComment = this.notes.stripQuickActions(sampleComment);
+ it('should NOT strip string that has slashes within', () => {
+ this.notes = new Notes();
+ const sampleComment = 'http://127.0.0.1:3000/root/gitlab-shell/issues/1';
+ const stripedComment = this.notes.stripQuickActions(sampleComment);
- expect(stripedComment).toBe(sampleComment);
- });
+ expect(stripedComment).toBe(sampleComment);
});
+ });
- describe('getQuickActionDescription', () => {
- const availableQuickActions = [
- { name: 'close', description: 'Close this issue', params: [] },
- { name: 'title', description: 'Change title', params: [{}] },
- { name: 'estimate', description: 'Set time estimate', params: [{}] },
- ];
+ describe('getQuickActionDescription', () => {
+ const availableQuickActions = [
+ { name: 'close', description: 'Close this issue', params: [] },
+ { name: 'title', description: 'Change title', params: [{}] },
+ { name: 'estimate', description: 'Set time estimate', params: [{}] },
+ ];
- beforeEach(() => {
- this.notes = new Notes();
- });
+ beforeEach(() => {
+ this.notes = new Notes();
+ });
- it('should return executing quick action description when note has single quick action', () => {
- const sampleComment = '/close';
- expect(this.notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe(
- 'Applying command to close this issue',
- );
- });
+ it('should return executing quick action description when note has single quick action', () => {
+ const sampleComment = '/close';
- it('should return generic multiple quick action description when note has multiple quick actions', () => {
- const sampleComment = '/close\n/title [Duplicate] Issue foobar';
- expect(this.notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe(
- 'Applying multiple commands',
- );
- });
+ expect(this.notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe(
+ 'Applying command to close this issue',
+ );
+ });
- it('should return generic quick action description when available quick actions list is not populated', () => {
- const sampleComment = '/close\n/title [Duplicate] Issue foobar';
- expect(this.notes.getQuickActionDescription(sampleComment)).toBe('Applying command');
- });
+ it('should return generic multiple quick action description when note has multiple quick actions', () => {
+ const sampleComment = '/close\n/title [Duplicate] Issue foobar';
+
+ expect(this.notes.getQuickActionDescription(sampleComment, availableQuickActions)).toBe(
+ 'Applying multiple commands',
+ );
});
- describe('createPlaceholderNote', () => {
- const sampleComment = 'foobar';
- const uniqueId = 'b1234-a4567';
- const currentUsername = 'root';
- const currentUserFullname = 'Administrator';
- const currentUserAvatar = 'avatar_url';
+ it('should return generic quick action description when available quick actions list is not populated', () => {
+ const sampleComment = '/close\n/title [Duplicate] Issue foobar';
- beforeEach(() => {
- this.notes = new Notes('', []);
- });
+ expect(this.notes.getQuickActionDescription(sampleComment)).toBe('Applying command');
+ });
+ });
- it('should return constructed placeholder element for regular note based on form contents', () => {
- const $tempNote = this.notes.createPlaceholderNote({
- formContent: sampleComment,
- uniqueId,
- isDiscussionNote: false,
- currentUsername,
- currentUserFullname,
- currentUserAvatar,
- });
- const $tempNoteHeader = $tempNote.find('.note-header');
-
- expect($tempNote.prop('nodeName')).toEqual('LI');
- expect($tempNote.attr('id')).toEqual(uniqueId);
- expect($tempNote.hasClass('being-posted')).toBeTruthy();
- expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
- $tempNote.find('.timeline-icon > a, .note-header-info > a').each(function() {
- expect($(this).attr('href')).toEqual(`/${currentUsername}`);
- });
- expect($tempNote.find('.timeline-icon .avatar').attr('src')).toEqual(currentUserAvatar);
- expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeFalsy();
- expect(
- $tempNoteHeader
- .find('.d-none.d-sm-inline-block')
- .text()
- .trim(),
- ).toEqual(currentUserFullname);
- expect(
- $tempNoteHeader
- .find('.note-headline-light')
- .text()
- .trim(),
- ).toEqual(`@${currentUsername}`);
- expect(
- $tempNote
- .find('.note-body .note-text p')
- .text()
- .trim(),
- ).toEqual(sampleComment);
- });
+ describe('createPlaceholderNote', () => {
+ const sampleComment = 'foobar';
+ const uniqueId = 'b1234-a4567';
+ const currentUsername = 'root';
+ const currentUserFullname = 'Administrator';
+ const currentUserAvatar = 'avatar_url';
- it('should return constructed placeholder element for discussion note based on form contents', () => {
- const $tempNote = this.notes.createPlaceholderNote({
- formContent: sampleComment,
- uniqueId,
- isDiscussionNote: true,
- currentUsername,
- currentUserFullname,
- });
+ beforeEach(() => {
+ this.notes = new Notes('', []);
+ });
- expect($tempNote.prop('nodeName')).toEqual('LI');
- expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeTruthy();
- });
+ it('should return constructed placeholder element for regular note based on form contents', () => {
+ const $tempNote = this.notes.createPlaceholderNote({
+ formContent: sampleComment,
+ uniqueId,
+ isDiscussionNote: false,
+ currentUsername,
+ currentUserFullname,
+ currentUserAvatar,
+ });
+ const $tempNoteHeader = $tempNote.find('.note-header');
+
+ expect($tempNote.prop('nodeName')).toEqual('LI');
+ expect($tempNote.attr('id')).toEqual(uniqueId);
+ expect($tempNote.hasClass('being-posted')).toBeTruthy();
+ expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
+ $tempNote.find('.timeline-icon > a, .note-header-info > a').each(function() {
+ expect($(this).attr('href')).toEqual(`/${currentUsername}`);
+ });
+
+ expect($tempNote.find('.timeline-icon .avatar').attr('src')).toEqual(currentUserAvatar);
+ expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeFalsy();
+ expect(
+ $tempNoteHeader
+ .find('.d-none.d-sm-inline-block')
+ .text()
+ .trim(),
+ ).toEqual(currentUserFullname);
+
+ expect(
+ $tempNoteHeader
+ .find('.note-headline-light')
+ .text()
+ .trim(),
+ ).toEqual(`@${currentUsername}`);
+
+ expect(
+ $tempNote
+ .find('.note-body .note-text p')
+ .text()
+ .trim(),
+ ).toEqual(sampleComment);
+ });
- it('should return a escaped user name', () => {
- const currentUserFullnameXSS = 'Foo <script>alert("XSS")</script>';
- const $tempNote = this.notes.createPlaceholderNote({
- formContent: sampleComment,
- uniqueId,
- isDiscussionNote: false,
- currentUsername,
- currentUserFullname: currentUserFullnameXSS,
- currentUserAvatar,
- });
- const $tempNoteHeader = $tempNote.find('.note-header');
- expect(
- $tempNoteHeader
- .find('.d-none.d-sm-inline-block')
- .text()
- .trim(),
- ).toEqual('Foo &lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;');
+ it('should return constructed placeholder element for discussion note based on form contents', () => {
+ const $tempNote = this.notes.createPlaceholderNote({
+ formContent: sampleComment,
+ uniqueId,
+ isDiscussionNote: true,
+ currentUsername,
+ currentUserFullname,
});
+
+ expect($tempNote.prop('nodeName')).toEqual('LI');
+ expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeTruthy();
});
- describe('createPlaceholderSystemNote', () => {
- const sampleCommandDescription = 'Applying command to close this issue';
- const uniqueId = 'b1234-a4567';
+ it('should return a escaped user name', () => {
+ const currentUserFullnameXSS = 'Foo <script>alert("XSS")</script>';
+ const $tempNote = this.notes.createPlaceholderNote({
+ formContent: sampleComment,
+ uniqueId,
+ isDiscussionNote: false,
+ currentUsername,
+ currentUserFullname: currentUserFullnameXSS,
+ currentUserAvatar,
+ });
+ const $tempNoteHeader = $tempNote.find('.note-header');
+
+ expect(
+ $tempNoteHeader
+ .find('.d-none.d-sm-inline-block')
+ .text()
+ .trim(),
+ ).toEqual('Foo &lt;script&gt;alert(&quot;XSS&quot;)&lt;/script&gt;');
+ });
+ });
- beforeEach(() => {
- this.notes = new Notes('', []);
- spyOn(_, 'escape').and.callFake(htmlEscape);
- });
+ describe('createPlaceholderSystemNote', () => {
+ const sampleCommandDescription = 'Applying command to close this issue';
+ const uniqueId = 'b1234-a4567';
- it('should return constructed placeholder element for system note based on form contents', () => {
- const $tempNote = this.notes.createPlaceholderSystemNote({
- formContent: sampleCommandDescription,
- uniqueId,
- });
+ beforeEach(() => {
+ this.notes = new Notes('', []);
+ spyOn(_, 'escape').and.callFake(htmlEscape);
+ });
- expect($tempNote.prop('nodeName')).toEqual('LI');
- expect($tempNote.attr('id')).toEqual(uniqueId);
- expect($tempNote.hasClass('being-posted')).toBeTruthy();
- expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
- expect(
- $tempNote
- .find('.timeline-content i')
- .text()
- .trim(),
- ).toEqual(sampleCommandDescription);
- });
+ it('should return constructed placeholder element for system note based on form contents', () => {
+ const $tempNote = this.notes.createPlaceholderSystemNote({
+ formContent: sampleCommandDescription,
+ uniqueId,
+ });
+
+ expect($tempNote.prop('nodeName')).toEqual('LI');
+ expect($tempNote.attr('id')).toEqual(uniqueId);
+ expect($tempNote.hasClass('being-posted')).toBeTruthy();
+ expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
+ expect(
+ $tempNote
+ .find('.timeline-content i')
+ .text()
+ .trim(),
+ ).toEqual(sampleCommandDescription);
});
+ });
- describe('appendFlash', () => {
- beforeEach(() => {
- this.notes = new Notes();
- });
+ describe('appendFlash', () => {
+ beforeEach(() => {
+ this.notes = new Notes();
+ });
- it('shows a flash message', () => {
- this.notes.addFlash('Error message', FLASH_TYPE_ALERT, this.notes.parentTimeline.get(0));
+ it('shows a flash message', () => {
+ this.notes.addFlash('Error message', FLASH_TYPE_ALERT, this.notes.parentTimeline.get(0));
- expect($('.flash-alert').is(':visible')).toBeTruthy();
- });
+ expect($('.flash-alert').is(':visible')).toBeTruthy();
});
+ });
- describe('clearFlash', () => {
- beforeEach(() => {
- $(document).off('ajax:success');
- this.notes = new Notes();
- });
+ describe('clearFlash', () => {
+ beforeEach(() => {
+ $(document).off('ajax:success');
+ this.notes = new Notes();
+ });
- it('hides visible flash message', () => {
- this.notes.addFlash('Error message 1', FLASH_TYPE_ALERT, this.notes.parentTimeline.get(0));
+ it('hides visible flash message', () => {
+ this.notes.addFlash('Error message 1', FLASH_TYPE_ALERT, this.notes.parentTimeline.get(0));
- this.notes.clearFlash();
+ this.notes.clearFlash();
- expect($('.flash-alert').is(':visible')).toBeFalsy();
- });
+ expect($('.flash-alert').is(':visible')).toBeFalsy();
});
});
-}.call(window));
+});
diff --git a/spec/javascripts/oauth_remember_me_spec.js b/spec/javascripts/oauth_remember_me_spec.js
index 8816fe6defb..2caa266b85f 100644
--- a/spec/javascripts/oauth_remember_me_spec.js
+++ b/spec/javascripts/oauth_remember_me_spec.js
@@ -13,8 +13,13 @@ describe('OAuthRememberMe', () => {
it('adds the "remember_me" query parameter to all OAuth login buttons', () => {
$('#oauth-container #remember_me').click();
- expect($('#oauth-container .oauth-login.twitter').attr('href')).toBe('http://example.com/?remember_me=1');
- expect($('#oauth-container .oauth-login.github').attr('href')).toBe('http://example.com/?remember_me=1');
+ expect($('#oauth-container .oauth-login.twitter').attr('href')).toBe(
+ 'http://example.com/?remember_me=1',
+ );
+
+ expect($('#oauth-container .oauth-login.github').attr('href')).toBe(
+ 'http://example.com/?remember_me=1',
+ );
});
it('removes the "remember_me" query parameter from all OAuth login buttons', () => {
diff --git a/spec/javascripts/pager_spec.js b/spec/javascripts/pager_spec.js
index 04f2e7ef4f9..93efc139254 100644
--- a/spec/javascripts/pager_spec.js
+++ b/spec/javascripts/pager_spec.js
@@ -30,6 +30,7 @@ describe('pager', () => {
const href = `${gl.TEST_HOST}/some_list.json`;
setFixtures(`<div class="content_list" data-href="${href}"></div>`);
Pager.init();
+
expect(Pager.url).toBe(href);
});
@@ -37,12 +38,14 @@ describe('pager', () => {
const href = `${gl.TEST_HOST}/some_list`;
spyOnDependency(Pager, 'removeParams').and.returnValue(href);
Pager.init();
+
expect(Pager.url).toBe(href);
});
it('should get initial offset from query parameter', () => {
window.history.replaceState({}, null, '?offset=100');
Pager.init();
+
expect(Pager.offset).toBe(100);
});
@@ -51,6 +54,7 @@ describe('pager', () => {
const href = `${gl.TEST_HOST}/some_list?filter=test`;
const removeParams = spyOnDependency(Pager, 'removeParams').and.returnValue(href);
Pager.init();
+
expect(removeParams).toHaveBeenCalledWith(['limit', 'offset']);
expect(Pager.url).toEqual(href);
});
@@ -132,6 +136,7 @@ describe('pager', () => {
offset: 100,
},
});
+
expect(url).toBe('/some_list');
done();
diff --git a/spec/javascripts/pages/admin/abuse_reports/abuse_reports_spec.js b/spec/javascripts/pages/admin/abuse_reports/abuse_reports_spec.js
index b0dc6ccc3d4..23d07056925 100644
--- a/spec/javascripts/pages/admin/abuse_reports/abuse_reports_spec.js
+++ b/spec/javascripts/pages/admin/abuse_reports/abuse_reports_spec.js
@@ -8,14 +8,15 @@ describe('Abuse Reports', () => {
let $messages;
- const assertMaxLength = $message => expect($message.text().length).toEqual(MAX_MESSAGE_LENGTH);
- const findMessage = searchText => $messages.filter(
- (index, element) => element.innerText.indexOf(searchText) > -1,
- ).first();
+ const assertMaxLength = $message => {
+ expect($message.text().length).toEqual(MAX_MESSAGE_LENGTH);
+ };
+ const findMessage = searchText =>
+ $messages.filter((index, element) => element.innerText.indexOf(searchText) > -1).first();
preloadFixtures(FIXTURE);
- beforeEach(function () {
+ beforeEach(function() {
loadFixtures(FIXTURE);
this.abuseReports = new AbuseReports();
$messages = $('.abuse-reports .message');
@@ -23,18 +24,21 @@ describe('Abuse Reports', () => {
it('should truncate long messages', () => {
const $longMessage = findMessage('LONG MESSAGE');
+
expect($longMessage.data('originalMessage')).toEqual(jasmine.anything());
assertMaxLength($longMessage);
});
it('should not truncate short messages', () => {
const $shortMessage = findMessage('SHORT MESSAGE');
+
expect($shortMessage.data('originalMessage')).not.toEqual(jasmine.anything());
});
it('should allow clicking a truncated message to expand and collapse the full message', () => {
const $longMessage = findMessage('LONG MESSAGE');
$longMessage.click();
+
expect($longMessage.data('originalMessage').length).toEqual($longMessage.text().length);
$longMessage.click();
assertMaxLength($longMessage);
diff --git a/spec/javascripts/pages/admin/application_settings/account_and_limits_spec.js b/spec/javascripts/pages/admin/application_settings/account_and_limits_spec.js
index 4dbfd8f0eaa..561bd2c96cb 100644
--- a/spec/javascripts/pages/admin/application_settings/account_and_limits_spec.js
+++ b/spec/javascripts/pages/admin/application_settings/account_and_limits_spec.js
@@ -1,6 +1,8 @@
import $ from 'jquery';
-import initUserInternalRegexPlaceholder, { PLACEHOLDER_USER_EXTERNAL_DEFAULT_FALSE,
- PLACEHOLDER_USER_EXTERNAL_DEFAULT_TRUE } from '~/pages/admin/application_settings/account_and_limits';
+import initUserInternalRegexPlaceholder, {
+ PLACEHOLDER_USER_EXTERNAL_DEFAULT_FALSE,
+ PLACEHOLDER_USER_EXTERNAL_DEFAULT_TRUE,
+} from '~/pages/admin/application_settings/account_and_limits';
describe('AccountAndLimits', () => {
const FIXTURE = 'application_settings/accounts_and_limit.html.raw';
@@ -22,8 +24,9 @@ describe('AccountAndLimits', () => {
expect($userInternalRegex.readOnly).toBeTruthy();
});
- it('is checked', (done) => {
+ it('is checked', done => {
if (!$userDefaultExternal.prop('checked')) $userDefaultExternal.click();
+
expect($userDefaultExternal.prop('checked')).toBeTruthy();
expect($userInternalRegex.placeholder).toEqual(PLACEHOLDER_USER_EXTERNAL_DEFAULT_TRUE);
expect($userInternalRegex.readOnly).toBeFalsy();
diff --git a/spec/javascripts/pages/admin/jobs/index/components/stop_jobs_modal_spec.js b/spec/javascripts/pages/admin/jobs/index/components/stop_jobs_modal_spec.js
index b69e5f9a3a0..6bfb3f5ca21 100644
--- a/spec/javascripts/pages/admin/jobs/index/components/stop_jobs_modal_spec.js
+++ b/spec/javascripts/pages/admin/jobs/index/components/stop_jobs_modal_spec.js
@@ -21,10 +21,10 @@ describe('stop_jobs_modal.vue', () => {
});
describe('onSubmit', () => {
- it('stops jobs and redirects to overview page', (done) => {
+ it('stops jobs and redirects to overview page', done => {
const responseURL = `${gl.TEST_HOST}/stop_jobs_modal.vue/jobs`;
const redirectSpy = spyOnDependency(stopJobsModal, 'redirectTo');
- spyOn(axios, 'post').and.callFake((url) => {
+ spyOn(axios, 'post').and.callFake(url => {
expect(url).toBe(props.url);
return Promise.resolve({
request: {
@@ -34,24 +34,24 @@ describe('stop_jobs_modal.vue', () => {
});
vm.onSubmit()
- .then(() => {
- expect(redirectSpy).toHaveBeenCalledWith(responseURL);
- })
- .then(done)
- .catch(done.fail);
+ .then(() => {
+ expect(redirectSpy).toHaveBeenCalledWith(responseURL);
+ })
+ .then(done)
+ .catch(done.fail);
});
- it('displays error if stopping jobs failed', (done) => {
+ it('displays error if stopping jobs failed', done => {
const dummyError = new Error('stopping jobs failed');
const redirectSpy = spyOnDependency(stopJobsModal, 'redirectTo');
- spyOn(axios, 'post').and.callFake((url) => {
+ spyOn(axios, 'post').and.callFake(url => {
expect(url).toBe(props.url);
return Promise.reject(dummyError);
});
vm.onSubmit()
.then(done.fail)
- .catch((error) => {
+ .catch(error => {
expect(error).toBe(dummyError);
expect(redirectSpy).not.toHaveBeenCalled();
})
diff --git a/spec/javascripts/pages/admin/users/new/index_spec.js b/spec/javascripts/pages/admin/users/new/index_spec.js
index 2bac3951c3a..5a849f34bc3 100644
--- a/spec/javascripts/pages/admin/users/new/index_spec.js
+++ b/spec/javascripts/pages/admin/users/new/index_spec.js
@@ -20,7 +20,7 @@ describe('UserInternalRegexHandler', () => {
});
describe('Behaviour of userExternal checkbox when', () => {
- it('matches email as internal', (done) => {
+ it('matches email as internal', done => {
expect($warningMessage.hasClass('hidden')).toBeTruthy();
$userEmail.val('test@').trigger('input');
@@ -30,7 +30,7 @@ describe('UserInternalRegexHandler', () => {
done();
});
- it('matches email as external', (done) => {
+ it('matches email as external', done => {
expect($warningMessage.hasClass('hidden')).toBeTruthy();
$userEmail.val('test.ext@').trigger('input');
diff --git a/spec/javascripts/pages/labels/components/promote_label_modal_spec.js b/spec/javascripts/pages/labels/components/promote_label_modal_spec.js
index a24f8204fe1..08a8362797b 100644
--- a/spec/javascripts/pages/labels/components/promote_label_modal_spec.js
+++ b/spec/javascripts/pages/labels/components/promote_label_modal_spec.js
@@ -25,7 +25,11 @@ describe('Promote label modal', () => {
});
it('contains the proper description', () => {
- expect(vm.text).toContain(`Promoting ${labelMockData.labelTitle} will make it available for all projects inside ${labelMockData.groupName}`);
+ expect(vm.text).toContain(
+ `Promoting ${labelMockData.labelTitle} will make it available for all projects inside ${
+ labelMockData.groupName
+ }`,
+ );
});
it('contains a label span with the color', () => {
@@ -48,11 +52,14 @@ describe('Promote label modal', () => {
vm.$destroy();
});
- it('redirects when a label is promoted', (done) => {
+ it('redirects when a label is promoted', done => {
const responseURL = `${gl.TEST_HOST}/dummy/endpoint`;
- spyOn(axios, 'post').and.callFake((url) => {
+ spyOn(axios, 'post').and.callFake(url => {
expect(url).toBe(labelMockData.url);
- expect(eventHub.$emit).toHaveBeenCalledWith('promoteLabelModal.requestStarted', labelMockData.url);
+ expect(eventHub.$emit).toHaveBeenCalledWith(
+ 'promoteLabelModal.requestStarted',
+ labelMockData.url,
+ );
return Promise.resolve({
request: {
responseURL,
@@ -62,25 +69,34 @@ describe('Promote label modal', () => {
vm.onSubmit()
.then(() => {
- expect(eventHub.$emit).toHaveBeenCalledWith('promoteLabelModal.requestFinished', { labelUrl: labelMockData.url, successful: true });
+ expect(eventHub.$emit).toHaveBeenCalledWith('promoteLabelModal.requestFinished', {
+ labelUrl: labelMockData.url,
+ successful: true,
+ });
})
.then(done)
.catch(done.fail);
});
- it('displays an error if promoting a label failed', (done) => {
+ it('displays an error if promoting a label failed', done => {
const dummyError = new Error('promoting label failed');
dummyError.response = { status: 500 };
- spyOn(axios, 'post').and.callFake((url) => {
+ spyOn(axios, 'post').and.callFake(url => {
expect(url).toBe(labelMockData.url);
- expect(eventHub.$emit).toHaveBeenCalledWith('promoteLabelModal.requestStarted', labelMockData.url);
+ expect(eventHub.$emit).toHaveBeenCalledWith(
+ 'promoteLabelModal.requestStarted',
+ labelMockData.url,
+ );
return Promise.reject(dummyError);
});
vm.onSubmit()
- .catch((error) => {
+ .catch(error => {
expect(error).toBe(dummyError);
- expect(eventHub.$emit).toHaveBeenCalledWith('promoteLabelModal.requestFinished', { labelUrl: labelMockData.url, successful: false });
+ expect(eventHub.$emit).toHaveBeenCalledWith('promoteLabelModal.requestFinished', {
+ labelUrl: labelMockData.url,
+ successful: false,
+ });
})
.then(done)
.catch(done.fail);
diff --git a/spec/javascripts/pages/milestones/shared/components/delete_milestone_modal_spec.js b/spec/javascripts/pages/milestones/shared/components/delete_milestone_modal_spec.js
index 94401beb5c9..fe293083e4c 100644
--- a/spec/javascripts/pages/milestones/shared/components/delete_milestone_modal_spec.js
+++ b/spec/javascripts/pages/milestones/shared/components/delete_milestone_modal_spec.js
@@ -27,11 +27,14 @@ describe('delete_milestone_modal.vue', () => {
spyOn(eventHub, '$emit');
});
- it('deletes milestone and redirects to overview page', (done) => {
+ it('deletes milestone and redirects to overview page', done => {
const responseURL = `${gl.TEST_HOST}/delete_milestone_modal.vue/milestoneOverview`;
- spyOn(axios, 'delete').and.callFake((url) => {
+ spyOn(axios, 'delete').and.callFake(url => {
expect(url).toBe(props.milestoneUrl);
- expect(eventHub.$emit).toHaveBeenCalledWith('deleteMilestoneModal.requestStarted', props.milestoneUrl);
+ expect(eventHub.$emit).toHaveBeenCalledWith(
+ 'deleteMilestoneModal.requestStarted',
+ props.milestoneUrl,
+ );
eventHub.$emit.calls.reset();
return Promise.resolve({
request: {
@@ -42,30 +45,39 @@ describe('delete_milestone_modal.vue', () => {
const redirectSpy = spyOnDependency(deleteMilestoneModal, 'redirectTo');
vm.onSubmit()
- .then(() => {
- expect(redirectSpy).toHaveBeenCalledWith(responseURL);
- expect(eventHub.$emit).toHaveBeenCalledWith('deleteMilestoneModal.requestFinished', { milestoneUrl: props.milestoneUrl, successful: true });
- })
- .then(done)
- .catch(done.fail);
+ .then(() => {
+ expect(redirectSpy).toHaveBeenCalledWith(responseURL);
+ expect(eventHub.$emit).toHaveBeenCalledWith('deleteMilestoneModal.requestFinished', {
+ milestoneUrl: props.milestoneUrl,
+ successful: true,
+ });
+ })
+ .then(done)
+ .catch(done.fail);
});
- it('displays error if deleting milestone failed', (done) => {
+ it('displays error if deleting milestone failed', done => {
const dummyError = new Error('deleting milestone failed');
dummyError.response = { status: 418 };
- spyOn(axios, 'delete').and.callFake((url) => {
+ spyOn(axios, 'delete').and.callFake(url => {
expect(url).toBe(props.milestoneUrl);
- expect(eventHub.$emit).toHaveBeenCalledWith('deleteMilestoneModal.requestStarted', props.milestoneUrl);
+ expect(eventHub.$emit).toHaveBeenCalledWith(
+ 'deleteMilestoneModal.requestStarted',
+ props.milestoneUrl,
+ );
eventHub.$emit.calls.reset();
return Promise.reject(dummyError);
});
const redirectSpy = spyOnDependency(deleteMilestoneModal, 'redirectTo');
vm.onSubmit()
- .catch((error) => {
+ .catch(error => {
expect(error).toBe(dummyError);
expect(redirectSpy).not.toHaveBeenCalled();
- expect(eventHub.$emit).toHaveBeenCalledWith('deleteMilestoneModal.requestFinished', { milestoneUrl: props.milestoneUrl, successful: false });
+ expect(eventHub.$emit).toHaveBeenCalledWith('deleteMilestoneModal.requestFinished', {
+ milestoneUrl: props.milestoneUrl,
+ successful: false,
+ });
})
.then(done)
.catch(done.fail);
@@ -81,7 +93,8 @@ describe('delete_milestone_modal.vue', () => {
});
it('contains neither issue nor milestone count', () => {
- vm = mountComponent(Component, { ...props,
+ vm = mountComponent(Component, {
+ ...props,
issueCount: 0,
mergeRequestCount: 0,
});
diff --git a/spec/javascripts/pages/milestones/shared/components/promote_milestone_modal_spec.js b/spec/javascripts/pages/milestones/shared/components/promote_milestone_modal_spec.js
index 8b220423637..2ac73ef3024 100644
--- a/spec/javascripts/pages/milestones/shared/components/promote_milestone_modal_spec.js
+++ b/spec/javascripts/pages/milestones/shared/components/promote_milestone_modal_spec.js
@@ -23,7 +23,11 @@ describe('Promote milestone modal', () => {
});
it('contains the proper description', () => {
- expect(vm.text).toContain(`Promoting ${milestoneMockData.milestoneTitle} will make it available for all projects inside ${milestoneMockData.groupName}.`);
+ expect(vm.text).toContain(
+ `Promoting ${
+ milestoneMockData.milestoneTitle
+ } will make it available for all projects inside ${milestoneMockData.groupName}.`,
+ );
});
it('contains the correct title', () => {
@@ -43,11 +47,14 @@ describe('Promote milestone modal', () => {
vm.$destroy();
});
- it('redirects when a milestone is promoted', (done) => {
+ it('redirects when a milestone is promoted', done => {
const responseURL = `${gl.TEST_HOST}/dummy/endpoint`;
- spyOn(axios, 'post').and.callFake((url) => {
+ spyOn(axios, 'post').and.callFake(url => {
expect(url).toBe(milestoneMockData.url);
- expect(eventHub.$emit).toHaveBeenCalledWith('promoteMilestoneModal.requestStarted', milestoneMockData.url);
+ expect(eventHub.$emit).toHaveBeenCalledWith(
+ 'promoteMilestoneModal.requestStarted',
+ milestoneMockData.url,
+ );
return Promise.resolve({
request: {
responseURL,
@@ -57,25 +64,34 @@ describe('Promote milestone modal', () => {
vm.onSubmit()
.then(() => {
- expect(eventHub.$emit).toHaveBeenCalledWith('promoteMilestoneModal.requestFinished', { milestoneUrl: milestoneMockData.url, successful: true });
+ expect(eventHub.$emit).toHaveBeenCalledWith('promoteMilestoneModal.requestFinished', {
+ milestoneUrl: milestoneMockData.url,
+ successful: true,
+ });
})
.then(done)
.catch(done.fail);
});
- it('displays an error if promoting a milestone failed', (done) => {
+ it('displays an error if promoting a milestone failed', done => {
const dummyError = new Error('promoting milestone failed');
dummyError.response = { status: 500 };
- spyOn(axios, 'post').and.callFake((url) => {
+ spyOn(axios, 'post').and.callFake(url => {
expect(url).toBe(milestoneMockData.url);
- expect(eventHub.$emit).toHaveBeenCalledWith('promoteMilestoneModal.requestStarted', milestoneMockData.url);
+ expect(eventHub.$emit).toHaveBeenCalledWith(
+ 'promoteMilestoneModal.requestStarted',
+ milestoneMockData.url,
+ );
return Promise.reject(dummyError);
});
vm.onSubmit()
- .catch((error) => {
+ .catch(error => {
expect(error).toBe(dummyError);
- expect(eventHub.$emit).toHaveBeenCalledWith('promoteMilestoneModal.requestFinished', { milestoneUrl: milestoneMockData.url, successful: false });
+ expect(eventHub.$emit).toHaveBeenCalledWith('promoteMilestoneModal.requestFinished', {
+ milestoneUrl: milestoneMockData.url,
+ successful: false,
+ });
})
.then(done)
.catch(done.fail);
diff --git a/spec/javascripts/pages/profiles/show/emoji_menu_spec.js b/spec/javascripts/pages/profiles/show/emoji_menu_spec.js
index b70368fc92f..864bda65736 100644
--- a/spec/javascripts/pages/profiles/show/emoji_menu_spec.js
+++ b/spec/javascripts/pages/profiles/show/emoji_menu_spec.js
@@ -81,6 +81,7 @@ describe('EmojiMenu', () => {
'mouseenter focus',
jasmine.anything(),
);
+
expect(emojiMenu.registerEventListener).toHaveBeenCalledWith(
'on',
jasmine.anything(),
@@ -107,6 +108,7 @@ describe('EmojiMenu', () => {
it('renders the menu with custom menu class', () => {
const menuElement = () =>
document.body.querySelector(`.emoji-menu.${dummyMenuClass} .emoji-menu-content`);
+
expect(menuElement()).toBe(null);
emojiMenu.createEmojiMenu();
diff --git a/spec/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js b/spec/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js
index 4655e29eed0..b20bc96f9be 100644
--- a/spec/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js
+++ b/spec/javascripts/pages/projects/pipeline_schedules/shared/components/interval_pattern_input_spec.js
@@ -19,10 +19,10 @@ window.gl.pipelineScheduleFieldErrors = {
updateFormValidityState: () => {},
};
-describe('Interval Pattern Input Component', function () {
- describe('when prop initialCronInterval is passed (edit)', function () {
- describe('when prop initialCronInterval is custom', function () {
- beforeEach(function () {
+describe('Interval Pattern Input Component', function() {
+ describe('when prop initialCronInterval is passed (edit)', function() {
+ describe('when prop initialCronInterval is custom', function() {
+ beforeEach(function() {
this.initialCronInterval = '1 2 3 4 5';
this.intervalPatternComponent = new IntervalPatternInputComponent({
propsData: {
@@ -31,15 +31,15 @@ describe('Interval Pattern Input Component', function () {
}).$mount();
});
- it('is initialized as a Vue component', function () {
+ it('is initialized as a Vue component', function() {
expect(this.intervalPatternComponent).toBeDefined();
});
- it('prop initialCronInterval is set', function () {
+ it('prop initialCronInterval is set', function() {
expect(this.intervalPatternComponent.initialCronInterval).toBe(this.initialCronInterval);
});
- it('sets isEditable to true', function (done) {
+ it('sets isEditable to true', function(done) {
Vue.nextTick(() => {
expect(this.intervalPatternComponent.isEditable).toBe(true);
done();
@@ -47,8 +47,8 @@ describe('Interval Pattern Input Component', function () {
});
});
- describe('when prop initialCronInterval is preset', function () {
- beforeEach(function () {
+ describe('when prop initialCronInterval is preset', function() {
+ beforeEach(function() {
this.intervalPatternComponent = new IntervalPatternInputComponent({
propsData: {
inputNameAttribute,
@@ -57,11 +57,11 @@ describe('Interval Pattern Input Component', function () {
}).$mount();
});
- it('is initialized as a Vue component', function () {
+ it('is initialized as a Vue component', function() {
expect(this.intervalPatternComponent).toBeDefined();
});
- it('sets isEditable to false', function (done) {
+ it('sets isEditable to false', function(done) {
Vue.nextTick(() => {
expect(this.intervalPatternComponent.isEditable).toBe(false);
done();
@@ -70,8 +70,8 @@ describe('Interval Pattern Input Component', function () {
});
});
- describe('when prop initialCronInterval is not passed (new)', function () {
- beforeEach(function () {
+ describe('when prop initialCronInterval is not passed (new)', function() {
+ beforeEach(function() {
this.intervalPatternComponent = new IntervalPatternInputComponent({
propsData: {
inputNameAttribute,
@@ -79,16 +79,17 @@ describe('Interval Pattern Input Component', function () {
}).$mount();
});
- it('is initialized as a Vue component', function () {
+ it('is initialized as a Vue component', function() {
expect(this.intervalPatternComponent).toBeDefined();
});
- it('prop initialCronInterval is set', function () {
+ it('prop initialCronInterval is set', function() {
const defaultInitialCronInterval = '';
+
expect(this.intervalPatternComponent.initialCronInterval).toBe(defaultInitialCronInterval);
});
- it('sets isEditable to true', function (done) {
+ it('sets isEditable to true', function(done) {
Vue.nextTick(() => {
expect(this.intervalPatternComponent.isEditable).toBe(true);
done();
@@ -96,8 +97,8 @@ describe('Interval Pattern Input Component', function () {
});
});
- describe('User Actions', function () {
- beforeEach(function () {
+ describe('User Actions', function() {
+ beforeEach(function() {
// For an unknown reason, some browsers do not propagate click events
// on radio buttons in a way Vue can register. So, we have to mount
// to a fixture.
@@ -111,66 +112,79 @@ describe('Interval Pattern Input Component', function () {
}).$mount('#my-mount');
});
- it('cronInterval is updated when everyday preset interval is selected', function (done) {
+ it('cronInterval is updated when everyday preset interval is selected', function(done) {
this.intervalPatternComponent.$el.querySelector('#every-day').click();
Vue.nextTick(() => {
expect(this.intervalPatternComponent.cronInterval).toBe(cronIntervalPresets.everyDay);
- expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').value).toBe(cronIntervalPresets.everyDay);
+ expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').value).toBe(
+ cronIntervalPresets.everyDay,
+ );
done();
});
});
- it('cronInterval is updated when everyweek preset interval is selected', function (done) {
+ it('cronInterval is updated when everyweek preset interval is selected', function(done) {
this.intervalPatternComponent.$el.querySelector('#every-week').click();
Vue.nextTick(() => {
expect(this.intervalPatternComponent.cronInterval).toBe(cronIntervalPresets.everyWeek);
- expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').value).toBe(cronIntervalPresets.everyWeek);
+ expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').value).toBe(
+ cronIntervalPresets.everyWeek,
+ );
done();
});
});
- it('cronInterval is updated when everymonth preset interval is selected', function (done) {
+ it('cronInterval is updated when everymonth preset interval is selected', function(done) {
this.intervalPatternComponent.$el.querySelector('#every-month').click();
Vue.nextTick(() => {
expect(this.intervalPatternComponent.cronInterval).toBe(cronIntervalPresets.everyMonth);
- expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').value).toBe(cronIntervalPresets.everyMonth);
+ expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').value).toBe(
+ cronIntervalPresets.everyMonth,
+ );
done();
});
});
- it('only a space is added to cronInterval (trimmed later) when custom radio is selected', function (done) {
+ it('only a space is added to cronInterval (trimmed later) when custom radio is selected', function(done) {
this.intervalPatternComponent.$el.querySelector('#every-month').click();
this.intervalPatternComponent.$el.querySelector('#custom').click();
Vue.nextTick(() => {
const intervalWithSpaceAppended = `${cronIntervalPresets.everyMonth} `;
+
expect(this.intervalPatternComponent.cronInterval).toBe(intervalWithSpaceAppended);
- expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').value).toBe(intervalWithSpaceAppended);
+ expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').value).toBe(
+ intervalWithSpaceAppended,
+ );
done();
});
});
- it('text input is disabled when preset interval is selected', function (done) {
+ it('text input is disabled when preset interval is selected', function(done) {
this.intervalPatternComponent.$el.querySelector('#every-month').click();
Vue.nextTick(() => {
expect(this.intervalPatternComponent.isEditable).toBe(false);
- expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').disabled).toBe(true);
+ expect(
+ this.intervalPatternComponent.$el.querySelector('.cron-interval-input').disabled,
+ ).toBe(true);
done();
});
});
- it('text input is enabled when custom is selected', function (done) {
+ it('text input is enabled when custom is selected', function(done) {
this.intervalPatternComponent.$el.querySelector('#every-month').click();
this.intervalPatternComponent.$el.querySelector('#custom').click();
Vue.nextTick(() => {
expect(this.intervalPatternComponent.isEditable).toBe(true);
- expect(this.intervalPatternComponent.$el.querySelector('.cron-interval-input').disabled).toBe(false);
+ expect(
+ this.intervalPatternComponent.$el.querySelector('.cron-interval-input').disabled,
+ ).toBe(false);
done();
});
});
diff --git a/spec/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedule_callout_spec.js b/spec/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedule_callout_spec.js
index fb7d2763b49..ea809e1f170 100644
--- a/spec/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedule_callout_spec.js
+++ b/spec/javascripts/pages/projects/pipeline_schedules/shared/components/pipeline_schedule_callout_spec.js
@@ -6,7 +6,7 @@ const PipelineSchedulesCalloutComponent = Vue.extend(PipelineSchedulesCallout);
const cookieKey = 'pipeline_schedules_callout_dismissed';
const docsUrl = 'help/ci/scheduled_pipelines';
-describe('Pipeline Schedule Callout', function () {
+describe('Pipeline Schedule Callout', function() {
beforeEach(() => {
setFixtures(`
<div id='pipeline-schedules-callout' data-docs-url=${docsUrl}></div>
@@ -76,7 +76,7 @@ describe('Pipeline Schedule Callout', function () {
expect(this.calloutComponent.$el.outerHTML).toContain(docsUrl);
});
- it('updates calloutDismissed when close button is clicked', (done) => {
+ it('updates calloutDismissed when close button is clicked', done => {
this.calloutComponent.$el.querySelector('#dismiss-callout-btn').click();
Vue.nextTick(() => {
@@ -85,7 +85,7 @@ describe('Pipeline Schedule Callout', function () {
});
});
- it('#dismissCallout updates calloutDismissed', (done) => {
+ it('#dismissCallout updates calloutDismissed', done => {
this.calloutComponent.dismissCallout();
Vue.nextTick(() => {
@@ -94,7 +94,7 @@ describe('Pipeline Schedule Callout', function () {
});
});
- it('is hidden when close button is clicked', (done) => {
+ it('is hidden when close button is clicked', done => {
this.calloutComponent.$el.querySelector('#dismiss-callout-btn').click();
Vue.nextTick(() => {
diff --git a/spec/javascripts/pdf/index_spec.js b/spec/javascripts/pdf/index_spec.js
index 69230bb0937..699cf4871aa 100644
--- a/spec/javascripts/pdf/index_spec.js
+++ b/spec/javascripts/pdf/index_spec.js
@@ -11,7 +11,7 @@ const Component = Vue.extend(PDFLab);
describe('PDF component', () => {
let vm;
- const checkLoaded = (done) => {
+ const checkLoaded = done => {
if (vm.loading) {
setTimeout(() => {
checkLoaded(done);
@@ -22,7 +22,7 @@ describe('PDF component', () => {
};
describe('without PDF data', () => {
- beforeEach((done) => {
+ beforeEach(done => {
vm = new Component({
propsData: {
pdf: '',
@@ -40,7 +40,7 @@ describe('PDF component', () => {
});
describe('with PDF data', () => {
- beforeEach((done) => {
+ beforeEach(done => {
vm = new Component({
propsData: {
pdf,
diff --git a/spec/javascripts/pdf/page_spec.js b/spec/javascripts/pdf/page_spec.js
index a207f2afce6..ef967210b65 100644
--- a/spec/javascripts/pdf/page_spec.js
+++ b/spec/javascripts/pdf/page_spec.js
@@ -34,6 +34,7 @@ describe('Page component', () => {
page: testPage,
number: 1,
});
+
expect(vm.rendering).toBe(true);
promise
diff --git a/spec/javascripts/performance_bar/components/detailed_metric_spec.js b/spec/javascripts/performance_bar/components/detailed_metric_spec.js
index c4611dc7662..a3b93280b4b 100644
--- a/spec/javascripts/performance_bar/components/detailed_metric_spec.js
+++ b/spec/javascripts/performance_bar/components/detailed_metric_spec.js
@@ -54,11 +54,9 @@ describe('detailedMetric', () => {
});
it('adds a modal with a table of the details', () => {
- vm.$el
- .querySelectorAll('.performance-bar-modal td strong')
- .forEach((duration, index) => {
- expect(duration.innerText).toContain(requestDetails[index].duration);
- });
+ vm.$el.querySelectorAll('.performance-bar-modal td strong').forEach((duration, index) => {
+ expect(duration.innerText).toContain(requestDetails[index].duration);
+ });
vm.$el
.querySelectorAll('.performance-bar-modal td:nth-child(2)')
diff --git a/spec/javascripts/performance_bar/components/request_selector_spec.js b/spec/javascripts/performance_bar/components/request_selector_spec.js
index 6108a29f8c4..a272e03c0e1 100644
--- a/spec/javascripts/performance_bar/components/request_selector_spec.js
+++ b/spec/javascripts/performance_bar/components/request_selector_spec.js
@@ -11,8 +11,7 @@ describe('request selector', () => {
},
{
id: '789',
- url:
- 'https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/1.json?serializer=widget',
+ url: 'https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/1.json?serializer=widget',
},
];
diff --git a/spec/javascripts/performance_bar/index_spec.js b/spec/javascripts/performance_bar/index_spec.js
index 1784bd64adb..1444d1bb3cb 100644
--- a/spec/javascripts/performance_bar/index_spec.js
+++ b/spec/javascripts/performance_bar/index_spec.js
@@ -63,10 +63,7 @@ describe('performance bar wrapper', () => {
it('adds the request immediately', () => {
vm.loadRequestDetails('123', 'https://gitlab.com/');
- expect(vm.store.addRequest).toHaveBeenCalledWith(
- '123',
- 'https://gitlab.com/',
- );
+ expect(vm.store.addRequest).toHaveBeenCalledWith('123', 'https://gitlab.com/');
});
it('makes an HTTP request for the request details', () => {
diff --git a/spec/javascripts/performance_bar/services/performance_bar_service_spec.js b/spec/javascripts/performance_bar/services/performance_bar_service_spec.js
index bc6947dbe81..cfec4b779e4 100644
--- a/spec/javascripts/performance_bar/services/performance_bar_service_spec.js
+++ b/spec/javascripts/performance_bar/services/performance_bar_service_spec.js
@@ -8,28 +8,34 @@ describe('PerformanceBarService', () => {
}
it('returns false when the request URL is the peek URL', () => {
- expect(fireCallback({ headers: { 'x-request-id': '123' }, url: '/peek' }, '/peek'))
- .toBeFalsy();
+ expect(
+ fireCallback({ headers: { 'x-request-id': '123' }, url: '/peek' }, '/peek'),
+ ).toBeFalsy();
});
it('returns false when there is no request ID', () => {
- expect(fireCallback({ headers: {}, url: '/request' }, '/peek'))
- .toBeFalsy();
+ expect(fireCallback({ headers: {}, url: '/request' }, '/peek')).toBeFalsy();
});
it('returns false when the request is an API request', () => {
- expect(fireCallback({ headers: { 'x-request-id': '123' }, url: '/api/' }, '/peek'))
- .toBeFalsy();
+ expect(
+ fireCallback({ headers: { 'x-request-id': '123' }, url: '/api/' }, '/peek'),
+ ).toBeFalsy();
});
it('returns false when the response is from the cache', () => {
- expect(fireCallback({ headers: { 'x-request-id': '123', 'x-gitlab-from-cache': 'true' }, url: '/request' }, '/peek'))
- .toBeFalsy();
+ expect(
+ fireCallback(
+ { headers: { 'x-request-id': '123', 'x-gitlab-from-cache': 'true' }, url: '/request' },
+ '/peek',
+ ),
+ ).toBeFalsy();
});
it('returns true when all conditions are met', () => {
- expect(fireCallback({ headers: { 'x-request-id': '123' }, url: '/request' }, '/peek'))
- .toBeTruthy();
+ expect(
+ fireCallback({ headers: { 'x-request-id': '123' }, url: '/request' }, '/peek'),
+ ).toBeTruthy();
});
});
@@ -39,8 +45,7 @@ describe('PerformanceBarService', () => {
}
it('gets the request ID from the headers', () => {
- expect(requestId({ headers: { 'x-request-id': '123' } }, '/peek'))
- .toEqual('123');
+ expect(requestId({ headers: { 'x-request-id': '123' } }, '/peek')).toEqual('123');
});
});
@@ -50,13 +55,13 @@ describe('PerformanceBarService', () => {
}
it('gets the request URL from the response object', () => {
- expect(requestUrl({ headers: {}, url: '/request' }, '/peek'))
- .toEqual('/request');
+ expect(requestUrl({ headers: {}, url: '/request' }, '/peek')).toEqual('/request');
});
it('gets the request URL from response.config if present', () => {
- expect(requestUrl({ headers: {}, config: { url: '/config-url' }, url: '/request' }, '/peek'))
- .toEqual('/config-url');
+ expect(
+ requestUrl({ headers: {}, config: { url: '/config-url' }, url: '/request' }, '/peek'),
+ ).toEqual('/config-url');
});
});
});
diff --git a/spec/javascripts/pipelines/blank_state_spec.js b/spec/javascripts/pipelines/blank_state_spec.js
index b7a9b60d85c..033bd5ccb73 100644
--- a/spec/javascripts/pipelines/blank_state_spec.js
+++ b/spec/javascripts/pipelines/blank_state_spec.js
@@ -9,12 +9,10 @@ describe('Pipelines Blank State', () => {
beforeEach(() => {
Component = Vue.extend(component);
- vm = mountComponent(Component,
- {
- svgPath: 'foo',
- message: 'Blank State',
- },
- );
+ vm = mountComponent(Component, {
+ svgPath: 'foo',
+ message: 'Blank State',
+ });
});
it('should render svg', () => {
@@ -22,8 +20,6 @@ describe('Pipelines Blank State', () => {
});
it('should render message', () => {
- expect(
- vm.$el.querySelector('h4').textContent.trim(),
- ).toEqual('Blank State');
+ expect(vm.$el.querySelector('h4').textContent.trim()).toEqual('Blank State');
});
});
diff --git a/spec/javascripts/pipelines/empty_state_spec.js b/spec/javascripts/pipelines/empty_state_spec.js
index 1e41a7bfe7c..e21dca45fa1 100644
--- a/spec/javascripts/pipelines/empty_state_spec.js
+++ b/spec/javascripts/pipelines/empty_state_spec.js
@@ -28,16 +28,31 @@ describe('Pipelines Empty State', () => {
expect(component.$el.querySelector('h4').textContent).toContain('Build with confidence');
expect(
- component.$el.querySelector('p').innerHTML.trim().replace(/\n+\s+/m, ' ').replace(/\s\s+/g, ' '),
+ component.$el
+ .querySelector('p')
+ .innerHTML.trim()
+ .replace(/\n+\s+/m, ' ')
+ .replace(/\s\s+/g, ' '),
).toContain('Continuous Integration can help catch bugs by running your tests automatically,');
expect(
- component.$el.querySelector('p').innerHTML.trim().replace(/\n+\s+/m, ' ').replace(/\s\s+/g, ' '),
- ).toContain('while Continuous Deployment can help you deliver code to your product environment');
+ component.$el
+ .querySelector('p')
+ .innerHTML.trim()
+ .replace(/\n+\s+/m, ' ')
+ .replace(/\s\s+/g, ' '),
+ ).toContain(
+ 'while Continuous Deployment can help you deliver code to your product environment',
+ );
});
it('should render a link with provided help path', () => {
- expect(component.$el.querySelector('.js-get-started-pipelines').getAttribute('href')).toEqual('foo');
- expect(component.$el.querySelector('.js-get-started-pipelines').textContent).toContain('Get started with Pipelines');
+ expect(component.$el.querySelector('.js-get-started-pipelines').getAttribute('href')).toEqual(
+ 'foo',
+ );
+
+ expect(component.$el.querySelector('.js-get-started-pipelines').textContent).toContain(
+ 'Get started with Pipelines',
+ );
});
});
diff --git a/spec/javascripts/pipelines/graph/action_component_spec.js b/spec/javascripts/pipelines/graph/action_component_spec.js
index 568e679abe9..027066e1d4d 100644
--- a/spec/javascripts/pipelines/graph/action_component_spec.js
+++ b/spec/javascripts/pipelines/graph/action_component_spec.js
@@ -35,12 +35,13 @@ describe('pipeline graph action component', () => {
it('should update bootstrap tooltip when title changes', done => {
component.tooltipText = 'changed';
- component.$nextTick()
- .then(() => {
- expect(component.$el.getAttribute('data-original-title')).toBe('changed');
- })
- .then(done)
- .catch(done.fail);
+ component
+ .$nextTick()
+ .then(() => {
+ expect(component.$el.getAttribute('data-original-title')).toBe('changed');
+ })
+ .then(done)
+ .catch(done.fail);
});
it('should render an svg', () => {
@@ -54,7 +55,8 @@ describe('pipeline graph action component', () => {
component.$el.click();
- component.$nextTick()
+ component
+ .$nextTick()
.then(() => {
expect(component.$emit).toHaveBeenCalledWith('pipelineActionRequestComplete');
})
diff --git a/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js b/spec/javascripts/pipelines/graph/job_group_dropdown_spec.js
index 2b47ca236b2..24631cc1c89 100644
--- a/spec/javascripts/pipelines/graph/dropdown_job_component_spec.js
+++ b/spec/javascripts/pipelines/graph/job_group_dropdown_spec.js
@@ -1,12 +1,12 @@
import Vue from 'vue';
-import component from '~/pipelines/components/graph/dropdown_job_component.vue';
+import JobGroupDropdown from '~/pipelines/components/graph/job_group_dropdown.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
-describe('dropdown job component', () => {
- const Component = Vue.extend(component);
+describe('job group dropdown component', () => {
+ const Component = Vue.extend(JobGroupDropdown);
let vm;
- const mock = {
+ const group = {
jobs: [
{
id: 4256,
@@ -71,15 +71,15 @@ describe('dropdown job component', () => {
});
beforeEach(() => {
- vm = mountComponent(Component, { job: mock });
+ vm = mountComponent(Component, { group });
});
- it('renders button with job name and size', () => {
- expect(vm.$el.querySelector('button').textContent).toContain(mock.name);
- expect(vm.$el.querySelector('button').textContent).toContain(mock.size);
+ it('renders button with group name and size', () => {
+ expect(vm.$el.querySelector('button').textContent).toContain(group.name);
+ expect(vm.$el.querySelector('button').textContent).toContain(group.size);
});
it('renders dropdown with jobs', () => {
- expect(vm.$el.querySelectorAll('.scrollable-menu>ul>li').length).toEqual(mock.jobs.length);
+ expect(vm.$el.querySelectorAll('.scrollable-menu>ul>li').length).toEqual(group.jobs.length);
});
});
diff --git a/spec/javascripts/pipelines/graph/job_component_spec.js b/spec/javascripts/pipelines/graph/job_item_spec.js
index 0ae448f2ea8..7cbcdc791e7 100644
--- a/spec/javascripts/pipelines/graph/job_component_spec.js
+++ b/spec/javascripts/pipelines/graph/job_item_spec.js
@@ -1,9 +1,9 @@
import Vue from 'vue';
-import jobComponent from '~/pipelines/components/graph/job_component.vue';
+import JobItem from '~/pipelines/components/graph/job_item.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
-describe('pipeline graph job component', () => {
- const JobComponent = Vue.extend(jobComponent);
+describe('pipeline graph job item', () => {
+ const JobComponent = Vue.extend(JobItem);
let component;
const mockJob = {
@@ -31,7 +31,7 @@ describe('pipeline graph job component', () => {
});
describe('name with link', () => {
- it('should render the job name and status with a link', (done) => {
+ it('should render the job name and status with a link', done => {
component = mountComponent(JobComponent, { job: mockJob });
Vue.nextTick(() => {
@@ -39,15 +39,15 @@ describe('pipeline graph job component', () => {
expect(link.getAttribute('href')).toEqual(mockJob.status.details_path);
- expect(
- link.getAttribute('data-original-title'),
- ).toEqual(`${mockJob.name} - ${mockJob.status.label}`);
+ expect(link.getAttribute('data-original-title')).toEqual(
+ `${mockJob.name} - ${mockJob.status.label}`,
+ );
expect(component.$el.querySelector('.js-status-icon-success')).toBeDefined();
- expect(
- component.$el.querySelector('.ci-status-text').textContent.trim(),
- ).toEqual(mockJob.name);
+ expect(component.$el.querySelector('.ci-status-text').textContent.trim()).toEqual(
+ mockJob.name,
+ );
done();
});
@@ -74,9 +74,9 @@ describe('pipeline graph job component', () => {
expect(component.$el.querySelector('.js-status-icon-success')).toBeDefined();
expect(component.$el.querySelector('a')).toBeNull();
- expect(
- component.$el.querySelector('.ci-status-text').textContent.trim(),
- ).toEqual(mockJob.name);
+ expect(component.$el.querySelector('.ci-status-text').textContent.trim()).toEqual(
+ mockJob.name,
+ );
});
});
@@ -95,9 +95,7 @@ describe('pipeline graph job component', () => {
cssClassJobName: 'css-class-job-name',
});
- expect(
- component.$el.querySelector('a').classList.contains('css-class-job-name'),
- ).toBe(true);
+ expect(component.$el.querySelector('a').classList.contains('css-class-job-name')).toBe(true);
});
describe('status label', () => {
@@ -112,7 +110,11 @@ describe('pipeline graph job component', () => {
},
});
- expect(component.$el.querySelector('.js-job-component-tooltip').getAttribute('data-original-title')).toEqual('test');
+ expect(
+ component.$el
+ .querySelector('.js-job-component-tooltip')
+ .getAttribute('data-original-title'),
+ ).toEqual('test');
});
it('should not render status label when it is provided', () => {
@@ -128,7 +130,11 @@ describe('pipeline graph job component', () => {
},
});
- expect(component.$el.querySelector('.js-job-component-tooltip').getAttribute('data-original-title')).toEqual('test - success');
+ expect(
+ component.$el
+ .querySelector('.js-job-component-tooltip')
+ .getAttribute('data-original-title'),
+ ).toEqual('test - success');
});
});
diff --git a/spec/javascripts/pipelines/graph/stage_column_component_spec.js b/spec/javascripts/pipelines/graph/stage_column_component_spec.js
index f6e6bd3132e..d0b8f877d6f 100644
--- a/spec/javascripts/pipelines/graph/stage_column_component_spec.js
+++ b/spec/javascripts/pipelines/graph/stage_column_component_spec.js
@@ -25,17 +25,16 @@ describe('stage column component', () => {
};
beforeEach(() => {
-
- const mockJobs = [];
+ const mockGroups = [];
for (let i = 0; i < 3; i += 1) {
const mockedJob = Object.assign({}, mockJob);
mockedJob.id += i;
- mockJobs.push(mockedJob);
+ mockGroups.push(mockedJob);
}
component = mountComponent(StageColumnComponent, {
title: 'foo',
- jobs: mockJobs,
+ groups: mockGroups,
});
});
@@ -43,14 +42,14 @@ describe('stage column component', () => {
expect(component.$el.querySelector('.stage-name').textContent.trim()).toEqual('foo');
});
- it('should render the provided jobs', () => {
+ it('should render the provided groups', () => {
expect(component.$el.querySelectorAll('.builds-container > ul > li').length).toEqual(3);
});
describe('jobId', () => {
it('escapes job name', () => {
component = mountComponent(StageColumnComponent, {
- jobs: [
+ groups: [
{
id: 4259,
name: '<img src=x onerror=alert(document.domain)>',
@@ -64,9 +63,9 @@ describe('stage column component', () => {
title: 'test',
});
- expect(
- component.$el.querySelector('.builds-container li').getAttribute('id'),
- ).toEqual('ci-badge-&lt;img src=x onerror=alert(document.domain)&gt;');
+ expect(component.$el.querySelector('.builds-container li').getAttribute('id')).toEqual(
+ 'ci-badge-&lt;img src=x onerror=alert(document.domain)&gt;',
+ );
});
});
});
diff --git a/spec/javascripts/pipelines/header_component_spec.js b/spec/javascripts/pipelines/header_component_spec.js
index 034d3b4957d..473a062fc40 100644
--- a/spec/javascripts/pipelines/header_component_spec.js
+++ b/spec/javascripts/pipelines/header_component_spec.js
@@ -47,13 +47,16 @@ describe('Pipeline details header', () => {
it('should render provided pipeline info', () => {
expect(
- vm.$el.querySelector('.header-main-content').textContent.replace(/\s+/g, ' ').trim(),
+ vm.$el
+ .querySelector('.header-main-content')
+ .textContent.replace(/\s+/g, ' ')
+ .trim(),
).toEqual('failed Pipeline #123 triggered 3 weeks ago by Foo');
});
describe('action buttons', () => {
it('should call postAction when button action is clicked', () => {
- eventHub.$on('headerPostAction', (action) => {
+ eventHub.$on('headerPostAction', action => {
expect(action.path).toEqual('path');
});
diff --git a/spec/javascripts/pipelines/nav_controls_spec.js b/spec/javascripts/pipelines/nav_controls_spec.js
index d6232f5c567..7806cdf1477 100644
--- a/spec/javascripts/pipelines/nav_controls_spec.js
+++ b/spec/javascripts/pipelines/nav_controls_spec.js
@@ -24,7 +24,9 @@ describe('Pipelines Nav Controls', () => {
component = mountComponent(NavControlsComponent, mockData);
expect(component.$el.querySelector('.js-run-pipeline').textContent).toContain('Run Pipeline');
- expect(component.$el.querySelector('.js-run-pipeline').getAttribute('href')).toEqual(mockData.newPipelinePath);
+ expect(component.$el.querySelector('.js-run-pipeline').getAttribute('href')).toEqual(
+ mockData.newPipelinePath,
+ );
});
it('should not render link to create pipeline if no path is provided', () => {
@@ -50,7 +52,9 @@ describe('Pipelines Nav Controls', () => {
component = mountComponent(NavControlsComponent, mockData);
expect(component.$el.querySelector('.js-ci-lint').textContent.trim()).toContain('CI Lint');
- expect(component.$el.querySelector('.js-ci-lint').getAttribute('href')).toEqual(mockData.ciLintPath);
+ expect(component.$el.querySelector('.js-ci-lint').getAttribute('href')).toEqual(
+ mockData.ciLintPath,
+ );
});
describe('Reset Runners Cache', () => {
@@ -65,7 +69,9 @@ describe('Pipelines Nav Controls', () => {
});
it('should render button for resetting runner caches', () => {
- expect(component.$el.querySelector('.js-clear-cache').textContent.trim()).toContain('Clear Runner Caches');
+ expect(component.$el.querySelector('.js-clear-cache').textContent.trim()).toContain(
+ 'Clear Runner Caches',
+ );
});
it('should emit postAction event when reset runner cache button is clicked', () => {
diff --git a/spec/javascripts/pipelines/pipeline_store_spec.js b/spec/javascripts/pipelines/pipeline_store_spec.js
index ab2287cc344..1d5754d1f05 100644
--- a/spec/javascripts/pipelines/pipeline_store_spec.js
+++ b/spec/javascripts/pipelines/pipeline_store_spec.js
@@ -20,6 +20,7 @@ describe('Pipeline Store', () => {
it('should store received object', () => {
store.storePipeline({ foo: 'bar' });
+
expect(store.state.pipeline).toEqual({ foo: 'bar' });
});
});
diff --git a/spec/javascripts/pipelines/pipeline_url_spec.js b/spec/javascripts/pipelines/pipeline_url_spec.js
index ddd580ae8b7..c9011b403b7 100644
--- a/spec/javascripts/pipelines/pipeline_url_spec.js
+++ b/spec/javascripts/pipelines/pipeline_url_spec.js
@@ -38,6 +38,7 @@ describe('Pipeline Url Component', () => {
expect(component.$el.querySelector('.js-pipeline-url-link').getAttribute('href')).toEqual(
'foo',
);
+
expect(component.$el.querySelector('.js-pipeline-url-link span').textContent).toEqual('#1');
});
@@ -66,6 +67,7 @@ describe('Pipeline Url Component', () => {
expect(component.$el.querySelector('.js-pipeline-url-user').getAttribute('href')).toEqual(
mockData.pipeline.user.web_url,
);
+
expect(image.getAttribute('data-original-title')).toEqual(mockData.pipeline.user.name);
expect(image.getAttribute('src')).toEqual(`${mockData.pipeline.user.avatar_url}?width=20`);
});
@@ -105,6 +107,7 @@ describe('Pipeline Url Component', () => {
expect(component.$el.querySelector('.js-pipeline-url-yaml').textContent).toContain(
'yaml invalid',
);
+
expect(component.$el.querySelector('.js-pipeline-url-stuck').textContent).toContain('stuck');
});
diff --git a/spec/javascripts/pipelines/pipelines_actions_spec.js b/spec/javascripts/pipelines/pipelines_actions_spec.js
index 0566bc55693..b5c62178642 100644
--- a/spec/javascripts/pipelines/pipelines_actions_spec.js
+++ b/spec/javascripts/pipelines/pipelines_actions_spec.js
@@ -31,11 +31,13 @@ describe('Pipelines Actions dropdown', () => {
it('renders a dropdown with the provided actions', () => {
const dropdownItems = vm.$el.querySelectorAll('.dropdown-menu li');
+
expect(dropdownItems.length).toEqual(actions.length);
});
it("renders a disabled action when it's not playable", () => {
const dropdownItem = vm.$el.querySelector('.dropdown-menu li:last-child button');
+
expect(dropdownItem).toBeDisabled();
});
});
diff --git a/spec/javascripts/pipelines/pipelines_artifacts_spec.js b/spec/javascripts/pipelines/pipelines_artifacts_spec.js
index a8a8e3e2cff..7705d5a19bf 100644
--- a/spec/javascripts/pipelines/pipelines_artifacts_spec.js
+++ b/spec/javascripts/pipelines/pipelines_artifacts_spec.js
@@ -23,18 +23,16 @@ describe('Pipelines Artifacts dropdown', () => {
});
it('should render a dropdown with the provided artifacts', () => {
- expect(
- component.$el.querySelectorAll('.dropdown-menu li').length,
- ).toEqual(artifacts.length);
+ expect(component.$el.querySelectorAll('.dropdown-menu li').length).toEqual(artifacts.length);
});
it('should render a link with the provided path', () => {
- expect(
- component.$el.querySelector('.dropdown-menu li a').getAttribute('href'),
- ).toEqual(artifacts[0].path);
+ expect(component.$el.querySelector('.dropdown-menu li a').getAttribute('href')).toEqual(
+ artifacts[0].path,
+ );
- expect(
- component.$el.querySelector('.dropdown-menu li a').textContent,
- ).toContain(artifacts[0].name);
+ expect(component.$el.querySelector('.dropdown-menu li a').textContent).toContain(
+ artifacts[0].name,
+ );
});
});
diff --git a/spec/javascripts/pipelines/pipelines_spec.js b/spec/javascripts/pipelines/pipelines_spec.js
index 50141bd99b4..37908153e0e 100644
--- a/spec/javascripts/pipelines/pipelines_spec.js
+++ b/spec/javascripts/pipelines/pipelines_spec.js
@@ -52,7 +52,7 @@ describe('Pipelines', () => {
describe('With permission', () => {
describe('With pipelines in main tab', () => {
- beforeEach((done) => {
+ beforeEach(done => {
mock.onGet('twitter/flight/pipelines.json').reply(200, pipelines);
vm = mountComponent(PipelinesComponent, {
@@ -72,7 +72,9 @@ describe('Pipelines', () => {
});
it('renders Run Pipeline link', () => {
- expect(vm.$el.querySelector('.js-run-pipeline').getAttribute('href')).toEqual(paths.newPipelinePath);
+ expect(vm.$el.querySelector('.js-run-pipeline').getAttribute('href')).toEqual(
+ paths.newPipelinePath,
+ );
});
it('renders CI Lint link', () => {
@@ -80,18 +82,20 @@ describe('Pipelines', () => {
});
it('renders Clear Runner Cache button', () => {
- expect(vm.$el.querySelector('.js-clear-cache').textContent.trim()).toEqual('Clear Runner Caches');
+ expect(vm.$el.querySelector('.js-clear-cache').textContent.trim()).toEqual(
+ 'Clear Runner Caches',
+ );
});
it('renders pipelines table', () => {
- expect(
- vm.$el.querySelectorAll('.gl-responsive-table-row').length,
- ).toEqual(pipelines.pipelines.length + 1);
+ expect(vm.$el.querySelectorAll('.gl-responsive-table-row').length).toEqual(
+ pipelines.pipelines.length + 1,
+ );
});
});
describe('Without pipelines on main tab with CI', () => {
- beforeEach((done) => {
+ beforeEach(done => {
mock.onGet('twitter/flight/pipelines.json').reply(200, {
pipelines: [],
count: {
@@ -118,7 +122,9 @@ describe('Pipelines', () => {
});
it('renders Run Pipeline link', () => {
- expect(vm.$el.querySelector('.js-run-pipeline').getAttribute('href')).toEqual(paths.newPipelinePath);
+ expect(vm.$el.querySelector('.js-run-pipeline').getAttribute('href')).toEqual(
+ paths.newPipelinePath,
+ );
});
it('renders CI Lint link', () => {
@@ -126,16 +132,20 @@ describe('Pipelines', () => {
});
it('renders Clear Runner Cache button', () => {
- expect(vm.$el.querySelector('.js-clear-cache').textContent.trim()).toEqual('Clear Runner Caches');
+ expect(vm.$el.querySelector('.js-clear-cache').textContent.trim()).toEqual(
+ 'Clear Runner Caches',
+ );
});
it('renders tab empty state', () => {
- expect(vm.$el.querySelector('.empty-state h4').textContent.trim()).toEqual('There are currently no pipelines.');
+ expect(vm.$el.querySelector('.empty-state h4').textContent.trim()).toEqual(
+ 'There are currently no pipelines.',
+ );
});
});
describe('Without pipelines nor CI', () => {
- beforeEach((done) => {
+ beforeEach(done => {
mock.onGet('twitter/flight/pipelines.json').reply(200, {
pipelines: [],
count: {
@@ -158,8 +168,13 @@ describe('Pipelines', () => {
});
it('renders empty state', () => {
- expect(vm.$el.querySelector('.js-empty-state h4').textContent.trim()).toEqual('Build with confidence');
- expect(vm.$el.querySelector('.js-get-started-pipelines').getAttribute('href')).toEqual(paths.helpPagePath);
+ expect(vm.$el.querySelector('.js-empty-state h4').textContent.trim()).toEqual(
+ 'Build with confidence',
+ );
+
+ expect(vm.$el.querySelector('.js-get-started-pipelines').getAttribute('href')).toEqual(
+ paths.helpPagePath,
+ );
});
it('does not render tabs nor buttons', () => {
@@ -171,7 +186,7 @@ describe('Pipelines', () => {
});
describe('When API returns error', () => {
- beforeEach((done) => {
+ beforeEach(done => {
mock.onGet('twitter/flight/pipelines.json').reply(500, {});
vm = mountComponent(PipelinesComponent, {
store: new Store(),
@@ -190,20 +205,27 @@ describe('Pipelines', () => {
});
it('renders buttons', () => {
- expect(vm.$el.querySelector('.js-run-pipeline').getAttribute('href')).toEqual(paths.newPipelinePath);
+ expect(vm.$el.querySelector('.js-run-pipeline').getAttribute('href')).toEqual(
+ paths.newPipelinePath,
+ );
+
expect(vm.$el.querySelector('.js-ci-lint').getAttribute('href')).toEqual(paths.ciLintPath);
- expect(vm.$el.querySelector('.js-clear-cache').textContent.trim()).toEqual('Clear Runner Caches');
+ expect(vm.$el.querySelector('.js-clear-cache').textContent.trim()).toEqual(
+ 'Clear Runner Caches',
+ );
});
it('renders error state', () => {
- expect(vm.$el.querySelector('.empty-state').textContent.trim()).toContain('There was an error fetching the pipelines.');
+ expect(vm.$el.querySelector('.empty-state').textContent.trim()).toContain(
+ 'There was an error fetching the pipelines.',
+ );
});
});
});
describe('Without permission', () => {
describe('With pipelines in main tab', () => {
- beforeEach((done) => {
+ beforeEach(done => {
mock.onGet('twitter/flight/pipelines.json').reply(200, pipelines);
vm = mountComponent(PipelinesComponent, {
@@ -229,14 +251,14 @@ describe('Pipelines', () => {
});
it('renders pipelines table', () => {
- expect(
- vm.$el.querySelectorAll('.gl-responsive-table-row').length,
- ).toEqual(pipelines.pipelines.length + 1);
+ expect(vm.$el.querySelectorAll('.gl-responsive-table-row').length).toEqual(
+ pipelines.pipelines.length + 1,
+ );
});
});
describe('Without pipelines on main tab with CI', () => {
- beforeEach((done) => {
+ beforeEach(done => {
mock.onGet('twitter/flight/pipelines.json').reply(200, {
pipelines: [],
count: {
@@ -270,12 +292,14 @@ describe('Pipelines', () => {
});
it('renders tab empty state', () => {
- expect(vm.$el.querySelector('.empty-state h4').textContent.trim()).toEqual('There are currently no pipelines.');
+ expect(vm.$el.querySelector('.empty-state h4').textContent.trim()).toEqual(
+ 'There are currently no pipelines.',
+ );
});
});
describe('Without pipelines nor CI', () => {
- beforeEach((done) => {
+ beforeEach(done => {
mock.onGet('twitter/flight/pipelines.json').reply(200, {
pipelines: [],
count: {
@@ -299,7 +323,10 @@ describe('Pipelines', () => {
});
it('renders empty state without button to set CI', () => {
- expect(vm.$el.querySelector('.js-empty-state').textContent.trim()).toEqual('This project is not currently set up to run pipelines.');
+ expect(vm.$el.querySelector('.js-empty-state').textContent.trim()).toEqual(
+ 'This project is not currently set up to run pipelines.',
+ );
+
expect(vm.$el.querySelector('.js-get-started-pipelines')).toBeNull();
});
@@ -312,7 +339,7 @@ describe('Pipelines', () => {
});
describe('When API returns error', () => {
- beforeEach((done) => {
+ beforeEach(done => {
mock.onGet('twitter/flight/pipelines.json').reply(500, {});
vm = mountComponent(PipelinesComponent, {
@@ -338,7 +365,9 @@ describe('Pipelines', () => {
});
it('renders error state', () => {
- expect(vm.$el.querySelector('.empty-state').textContent.trim()).toContain('There was an error fetching the pipelines.');
+ expect(vm.$el.querySelector('.empty-state').textContent.trim()).toContain(
+ 'There was an error fetching the pipelines.',
+ );
});
});
});
@@ -356,41 +385,44 @@ describe('Pipelines', () => {
});
});
- it('should render table', (done) => {
+ it('should render table', done => {
setTimeout(() => {
expect(vm.$el.querySelector('.table-holder')).toBeDefined();
- expect(
- vm.$el.querySelectorAll('.gl-responsive-table-row').length,
- ).toEqual(pipelines.pipelines.length + 1);
+ expect(vm.$el.querySelectorAll('.gl-responsive-table-row').length).toEqual(
+ pipelines.pipelines.length + 1,
+ );
done();
});
});
- it('should render navigation tabs', (done) => {
+ it('should render navigation tabs', done => {
setTimeout(() => {
- expect(
- vm.$el.querySelector('.js-pipelines-tab-pending').textContent.trim(),
- ).toContain('Pending');
- expect(
- vm.$el.querySelector('.js-pipelines-tab-all').textContent.trim(),
- ).toContain('All');
- expect(
- vm.$el.querySelector('.js-pipelines-tab-running').textContent.trim(),
- ).toContain('Running');
- expect(
- vm.$el.querySelector('.js-pipelines-tab-finished').textContent.trim(),
- ).toContain('Finished');
- expect(
- vm.$el.querySelector('.js-pipelines-tab-branches').textContent.trim(),
- ).toContain('Branches');
- expect(
- vm.$el.querySelector('.js-pipelines-tab-tags').textContent.trim(),
- ).toContain('Tags');
+ expect(vm.$el.querySelector('.js-pipelines-tab-pending').textContent.trim()).toContain(
+ 'Pending',
+ );
+
+ expect(vm.$el.querySelector('.js-pipelines-tab-all').textContent.trim()).toContain('All');
+
+ expect(vm.$el.querySelector('.js-pipelines-tab-running').textContent.trim()).toContain(
+ 'Running',
+ );
+
+ expect(vm.$el.querySelector('.js-pipelines-tab-finished').textContent.trim()).toContain(
+ 'Finished',
+ );
+
+ expect(vm.$el.querySelector('.js-pipelines-tab-branches').textContent.trim()).toContain(
+ 'Branches',
+ );
+
+ expect(vm.$el.querySelector('.js-pipelines-tab-tags').textContent.trim()).toContain(
+ 'Tags',
+ );
done();
});
});
- it('should make an API request when using tabs', (done) => {
+ it('should make an API request when using tabs', done => {
setTimeout(() => {
spyOn(vm, 'updateContent');
vm.$el.querySelector('.js-pipelines-tab-finished').click();
@@ -401,7 +433,7 @@ describe('Pipelines', () => {
});
describe('with pagination', () => {
- it('should make an API request when using pagination', (done) => {
+ it('should make an API request when using pagination', done => {
setTimeout(() => {
spyOn(vm, 'updateContent');
// Mock pagination
@@ -415,6 +447,7 @@ describe('Pipelines', () => {
vm.$nextTick(() => {
vm.$el.querySelector('.js-next-button a').click();
+
expect(vm.updateContent).toHaveBeenCalledWith({ scope: 'all', page: '2' });
done();
@@ -504,7 +537,7 @@ describe('Pipelines', () => {
});
describe('emptyTabMessage', () => {
- it('returns message with scope', (done) => {
+ it('returns message with scope', done => {
vm.scope = 'pending';
vm.$nextTick(() => {
@@ -523,7 +556,7 @@ describe('Pipelines', () => {
expect(vm.stateToRender).toEqual('loading');
});
- it('returns error state when app has error', (done) => {
+ it('returns error state when app has error', done => {
vm.hasError = true;
vm.isLoading = false;
@@ -533,7 +566,7 @@ describe('Pipelines', () => {
});
});
- it('returns table list when app has pipelines', (done) => {
+ it('returns table list when app has pipelines', done => {
vm.isLoading = false;
vm.hasError = false;
vm.state.pipelines = pipelines.pipelines;
@@ -545,7 +578,7 @@ describe('Pipelines', () => {
});
});
- it('returns empty tab when app does not have pipelines but project has pipelines', (done) => {
+ it('returns empty tab when app does not have pipelines but project has pipelines', done => {
vm.state.count.all = 10;
vm.isLoading = false;
@@ -556,7 +589,7 @@ describe('Pipelines', () => {
});
});
- it('returns empty tab when project has CI', (done) => {
+ it('returns empty tab when project has CI', done => {
vm.isLoading = false;
vm.$nextTick(() => {
expect(vm.stateToRender).toEqual('emptyTab');
@@ -565,7 +598,7 @@ describe('Pipelines', () => {
});
});
- it('returns empty state when project does not have pipelines nor CI', (done) => {
+ it('returns empty state when project does not have pipelines nor CI', done => {
vm.isLoading = false;
vm.hasGitlabCi = false;
vm.$nextTick(() => {
@@ -577,7 +610,7 @@ describe('Pipelines', () => {
});
describe('shouldRenderTabs', () => {
- it('returns true when state is loading & has already made the first request', (done) => {
+ it('returns true when state is loading & has already made the first request', done => {
vm.isLoading = true;
vm.hasMadeRequest = true;
@@ -588,7 +621,7 @@ describe('Pipelines', () => {
});
});
- it('returns true when state is tableList & has already made the first request', (done) => {
+ it('returns true when state is tableList & has already made the first request', done => {
vm.isLoading = false;
vm.state.pipelines = pipelines.pipelines;
vm.hasMadeRequest = true;
@@ -600,7 +633,7 @@ describe('Pipelines', () => {
});
});
- it('returns true when state is error & has already made the first request', (done) => {
+ it('returns true when state is error & has already made the first request', done => {
vm.isLoading = false;
vm.hasError = true;
vm.hasMadeRequest = true;
@@ -612,7 +645,7 @@ describe('Pipelines', () => {
});
});
- it('returns true when state is empty tab & has already made the first request', (done) => {
+ it('returns true when state is empty tab & has already made the first request', done => {
vm.isLoading = false;
vm.state.count.all = 10;
vm.hasMadeRequest = true;
@@ -624,7 +657,7 @@ describe('Pipelines', () => {
});
});
- it('returns false when has not made first request', (done) => {
+ it('returns false when has not made first request', done => {
vm.hasMadeRequest = false;
vm.$nextTick(() => {
@@ -634,7 +667,7 @@ describe('Pipelines', () => {
});
});
- it('returns false when state is emtpy state', (done) => {
+ it('returns false when state is emtpy state', done => {
vm.isLoading = false;
vm.hasMadeRequest = true;
vm.hasGitlabCi = false;
@@ -648,7 +681,7 @@ describe('Pipelines', () => {
});
describe('shouldRenderButtons', () => {
- it('returns true when it has paths & has made the first request', (done) => {
+ it('returns true when it has paths & has made the first request', done => {
vm.hasMadeRequest = true;
vm.$nextTick(() => {
@@ -658,7 +691,7 @@ describe('Pipelines', () => {
});
});
- it('returns false when it has not made the first request', (done) => {
+ it('returns false when it has not made the first request', done => {
vm.hasMadeRequest = false;
vm.$nextTick(() => {
@@ -675,19 +708,24 @@ describe('Pipelines', () => {
const copyPipeline = Object.assign({}, pipelineWithStages);
copyPipeline.id += 1;
mock
- .onGet('twitter/flight/pipelines.json').reply(200, {
- pipelines: [pipelineWithStages],
- count: {
- all: 1,
- finished: 1,
- pending: 0,
- running: 0,
+ .onGet('twitter/flight/pipelines.json')
+ .reply(
+ 200,
+ {
+ pipelines: [pipelineWithStages],
+ count: {
+ all: 1,
+ finished: 1,
+ pending: 0,
+ running: 0,
+ },
},
- }, {
- 'POLL-INTERVAL': 100,
- })
+ {
+ 'POLL-INTERVAL': 100,
+ },
+ )
.onGet(pipelineWithStages.details.stages[0].dropdown_path)
- .reply(200, stageReply);
+ .reply(200, stageReply);
vm = mountComponent(PipelinesComponent, {
store: new Store(),
@@ -698,7 +736,7 @@ describe('Pipelines', () => {
});
describe('when a request is being made', () => {
- it('stops polling, cancels the request, fetches pipelines & restarts polling', (done) => {
+ it('stops polling, cancels the request, fetches pipelines & restarts polling', done => {
spyOn(vm.poll, 'stop');
spyOn(vm.poll, 'restart');
spyOn(vm, 'getPipelines').and.returnValue(Promise.resolve());
@@ -706,7 +744,8 @@ describe('Pipelines', () => {
setTimeout(() => {
vm.isMakingRequest = true;
- return vm.$nextTick()
+ return vm
+ .$nextTick()
.then(() => {
vm.$el.querySelector('.js-builds-dropdown-button').click();
})
@@ -719,13 +758,14 @@ describe('Pipelines', () => {
expect(vm.poll.restart).toHaveBeenCalled();
done();
}, 0);
- });
+ })
+ .catch(done.fail);
}, 0);
});
});
describe('when no request is being made', () => {
- it('stops polling, fetches pipelines & restarts polling', (done) => {
+ it('stops polling, fetches pipelines & restarts polling', done => {
spyOn(vm.poll, 'stop');
spyOn(vm.poll, 'restart');
spyOn(vm, 'getPipelines').and.returnValue(Promise.resolve());
diff --git a/spec/javascripts/pipelines/pipelines_store_spec.js b/spec/javascripts/pipelines/pipelines_store_spec.js
index 10ff0c6bb84..ce21f788ed5 100644
--- a/spec/javascripts/pipelines/pipelines_store_spec.js
+++ b/spec/javascripts/pipelines/pipelines_store_spec.js
@@ -16,12 +16,14 @@ describe('Pipelines Store', () => {
describe('storePipelines', () => {
it('should use the default parameter if none is provided', () => {
store.storePipelines();
+
expect(store.state.pipelines).toEqual([]);
});
it('should store the provided array', () => {
const array = [{ id: 1, status: 'running' }, { id: 2, status: 'success' }];
store.storePipelines(array);
+
expect(store.state.pipelines).toEqual(array);
});
});
@@ -29,6 +31,7 @@ describe('Pipelines Store', () => {
describe('storeCount', () => {
it('should use the default parameter if none is provided', () => {
store.storeCount();
+
expect(store.state.count).toEqual({});
});
@@ -43,6 +46,7 @@ describe('Pipelines Store', () => {
describe('storePagination', () => {
it('should use the default parameter if none is provided', () => {
store.storePagination();
+
expect(store.state.pageInfo).toEqual({});
});
@@ -66,6 +70,7 @@ describe('Pipelines Store', () => {
};
store.storePagination(pagination);
+
expect(store.state.pageInfo).toEqual(expectedResult);
});
});
diff --git a/spec/javascripts/pipelines/pipelines_table_row_spec.js b/spec/javascripts/pipelines/pipelines_table_row_spec.js
index 42795f5c134..506d01f5ec1 100644
--- a/spec/javascripts/pipelines/pipelines_table_row_spec.js
+++ b/spec/javascripts/pipelines/pipelines_table_row_spec.js
@@ -37,6 +37,7 @@ describe('Pipelines Table Row', () => {
it('should render a table row', () => {
component = buildComponent(pipeline);
+
expect(component.$el.getAttribute('class')).toContain('gl-responsive-table-row');
});
@@ -97,6 +98,7 @@ describe('Pipelines Table Row', () => {
component = buildComponent(pipeline);
const commitLink = component.$el.querySelector('.branch-commit .commit-sha');
+
expect(commitLink.getAttribute('href')).toEqual(pipeline.commit.commit_path);
});
@@ -177,6 +179,7 @@ describe('Pipelines Table Row', () => {
expect(component.$el.querySelector('.js-pipelines-retry-button')).not.toBeNull();
expect(component.$el.querySelector('.js-pipelines-cancel-button')).not.toBeNull();
const dropdownMenu = component.$el.querySelectorAll('.dropdown-menu');
+
expect(dropdownMenu).toContainText(scheduledJobAction.name);
});
@@ -186,6 +189,7 @@ describe('Pipelines Table Row', () => {
});
component.$el.querySelector('.js-pipelines-retry-button').click();
+
expect(component.isRetrying).toEqual(true);
});
@@ -200,7 +204,8 @@ describe('Pipelines Table Row', () => {
it('renders a loading icon when `cancelingPipeline` matches pipeline id', done => {
component.cancelingPipeline = pipeline.id;
- component.$nextTick()
+ component
+ .$nextTick()
.then(() => {
expect(component.isCancelling).toEqual(true);
})
diff --git a/spec/javascripts/pipelines/pipelines_table_spec.js b/spec/javascripts/pipelines/pipelines_table_spec.js
index d21ba35e96d..5c3387190ab 100644
--- a/spec/javascripts/pipelines/pipelines_table_spec.js
+++ b/spec/javascripts/pipelines/pipelines_table_spec.js
@@ -38,10 +38,21 @@ describe('Pipelines Table', () => {
});
it('should render table head with correct columns', () => {
- expect(component.$el.querySelector('.table-section.js-pipeline-status').textContent.trim()).toEqual('Status');
- expect(component.$el.querySelector('.table-section.js-pipeline-info').textContent.trim()).toEqual('Pipeline');
- expect(component.$el.querySelector('.table-section.js-pipeline-commit').textContent.trim()).toEqual('Commit');
- expect(component.$el.querySelector('.table-section.js-pipeline-stages').textContent.trim()).toEqual('Stages');
+ expect(
+ component.$el.querySelector('.table-section.js-pipeline-status').textContent.trim(),
+ ).toEqual('Status');
+
+ expect(
+ component.$el.querySelector('.table-section.js-pipeline-info').textContent.trim(),
+ ).toEqual('Pipeline');
+
+ expect(
+ component.$el.querySelector('.table-section.js-pipeline-commit').textContent.trim(),
+ ).toEqual('Commit');
+
+ expect(
+ component.$el.querySelector('.table-section.js-pipeline-stages').textContent.trim(),
+ ).toEqual('Stages');
});
});
@@ -54,6 +65,7 @@ describe('Pipelines Table', () => {
viewType: 'root',
},
}).$mount();
+
expect(component.$el.querySelectorAll('.commit.gl-responsive-table-row').length).toEqual(0);
});
});
diff --git a/spec/javascripts/pipelines/stage_spec.js b/spec/javascripts/pipelines/stage_spec.js
index 3f6789759ae..a3caaeb44dc 100644
--- a/spec/javascripts/pipelines/stage_spec.js
+++ b/spec/javascripts/pipelines/stage_spec.js
@@ -53,6 +53,7 @@ describe('Pipelines stage component', () => {
expect(
component.$el.querySelector('.js-builds-dropdown-container ul').textContent.trim(),
).toContain(stageReply.latest_statuses[0].name);
+
expect(eventHub.$emit).toHaveBeenCalledWith('clickedDropdown');
done();
}, 0);
@@ -119,12 +120,13 @@ describe('Pipelines stage component', () => {
setTimeout(() => {
component.$el.querySelector('.js-ci-action').click();
- component.$nextTick()
- .then(() => {
- expect(eventHub.$emit).toHaveBeenCalledWith('refreshPipelinesTable');
- })
- .then(done)
- .catch(done.fail);
+ component
+ .$nextTick()
+ .then(() => {
+ expect(eventHub.$emit).toHaveBeenCalledWith('refreshPipelinesTable');
+ })
+ .then(done)
+ .catch(done.fail);
}, 0);
});
});
diff --git a/spec/javascripts/pipelines_spec.js b/spec/javascripts/pipelines_spec.js
index c08a73851be..6b86f9ea437 100644
--- a/spec/javascripts/pipelines_spec.js
+++ b/spec/javascripts/pipelines_spec.js
@@ -12,6 +12,8 @@ describe('Pipelines', () => {
});
it('should create a `Pipelines` instance without options', () => {
- expect(() => { new Pipelines(); }).not.toThrow(); //eslint-disable-line
+ expect(() => {
+ new Pipelines(); // eslint-disable-line no-new
+ }).not.toThrow();
});
});
diff --git a/spec/javascripts/polyfills/element_spec.js b/spec/javascripts/polyfills/element_spec.js
index ecaaf1907ea..d35df595c72 100644
--- a/spec/javascripts/polyfills/element_spec.js
+++ b/spec/javascripts/polyfills/element_spec.js
@@ -1,6 +1,6 @@
import '~/commons/polyfills/element';
-describe('Element polyfills', function () {
+describe('Element polyfills', function() {
beforeEach(() => {
this.element = document.createElement('ul');
});
diff --git a/spec/javascripts/pretty_time_spec.js b/spec/javascripts/pretty_time_spec.js
deleted file mode 100644
index 084ffe08917..00000000000
--- a/spec/javascripts/pretty_time_spec.js
+++ /dev/null
@@ -1,133 +0,0 @@
-import { parseSeconds, abbreviateTime, stringifyTime } from '~/lib/utils/pretty_time';
-
-function assertTimeUnits(obj, minutes, hours, days, weeks) {
- expect(obj.minutes).toBe(minutes);
- expect(obj.hours).toBe(hours);
- expect(obj.days).toBe(days);
- expect(obj.weeks).toBe(weeks);
-}
-
-describe('prettyTime methods', () => {
- describe('parseSeconds', () => {
- it('should correctly parse a negative value', () => {
- const zeroSeconds = parseSeconds(-1000);
-
- assertTimeUnits(zeroSeconds, 16, 0, 0, 0);
- });
-
- it('should correctly parse a zero value', () => {
- const zeroSeconds = parseSeconds(0);
-
- assertTimeUnits(zeroSeconds, 0, 0, 0, 0);
- });
-
- it('should correctly parse a small non-zero second values', () => {
- const subOneMinute = parseSeconds(10);
- const aboveOneMinute = parseSeconds(100);
- const manyMinutes = parseSeconds(1000);
-
- assertTimeUnits(subOneMinute, 0, 0, 0, 0);
- assertTimeUnits(aboveOneMinute, 1, 0, 0, 0);
- assertTimeUnits(manyMinutes, 16, 0, 0, 0);
- });
-
- it('should correctly parse large second values', () => {
- const aboveOneHour = parseSeconds(4800);
- const aboveOneDay = parseSeconds(110000);
- const aboveOneWeek = parseSeconds(25000000);
-
- assertTimeUnits(aboveOneHour, 20, 1, 0, 0);
- assertTimeUnits(aboveOneDay, 33, 6, 3, 0);
- assertTimeUnits(aboveOneWeek, 26, 0, 3, 173);
- });
-
- it('should correctly accept a custom param for hoursPerDay', () => {
- const config = { hoursPerDay: 24 };
-
- const aboveOneHour = parseSeconds(4800, config);
- const aboveOneDay = parseSeconds(110000, config);
- const aboveOneWeek = parseSeconds(25000000, config);
-
- assertTimeUnits(aboveOneHour, 20, 1, 0, 0);
- assertTimeUnits(aboveOneDay, 33, 6, 1, 0);
- assertTimeUnits(aboveOneWeek, 26, 8, 4, 57);
- });
-
- it('should correctly accept a custom param for daysPerWeek', () => {
- const config = { daysPerWeek: 7 };
-
- const aboveOneHour = parseSeconds(4800, config);
- const aboveOneDay = parseSeconds(110000, config);
- const aboveOneWeek = parseSeconds(25000000, config);
-
- assertTimeUnits(aboveOneHour, 20, 1, 0, 0);
- assertTimeUnits(aboveOneDay, 33, 6, 3, 0);
- assertTimeUnits(aboveOneWeek, 26, 0, 0, 124);
- });
-
- it('should correctly accept custom params for daysPerWeek and hoursPerDay', () => {
- const config = { daysPerWeek: 55, hoursPerDay: 14 };
-
- const aboveOneHour = parseSeconds(4800, config);
- const aboveOneDay = parseSeconds(110000, config);
- const aboveOneWeek = parseSeconds(25000000, config);
-
- assertTimeUnits(aboveOneHour, 20, 1, 0, 0);
- assertTimeUnits(aboveOneDay, 33, 2, 2, 0);
- assertTimeUnits(aboveOneWeek, 26, 0, 1, 9);
- });
- });
-
- describe('stringifyTime', () => {
- it('should stringify values with all non-zero units', () => {
- const timeObject = {
- weeks: 1,
- days: 4,
- hours: 7,
- minutes: 20,
- };
-
- const timeString = stringifyTime(timeObject);
-
- expect(timeString).toBe('1w 4d 7h 20m');
- });
-
- it('should stringify values with some non-zero units', () => {
- const timeObject = {
- weeks: 0,
- days: 4,
- hours: 0,
- minutes: 20,
- };
-
- const timeString = stringifyTime(timeObject);
-
- expect(timeString).toBe('4d 20m');
- });
-
- it('should stringify values with no non-zero units', () => {
- const timeObject = {
- weeks: 0,
- days: 0,
- hours: 0,
- minutes: 0,
- };
-
- const timeString = stringifyTime(timeObject);
-
- expect(timeString).toBe('0m');
- });
- });
-
- describe('abbreviateTime', () => {
- it('should abbreviate stringified times for weeks', () => {
- const fullTimeString = '1w 3d 4h 5m';
- expect(abbreviateTime(fullTimeString)).toBe('1w');
- });
-
- it('should abbreviate stringified times for non-weeks', () => {
- const fullTimeString = '0w 3d 4h 5m';
- expect(abbreviateTime(fullTimeString)).toBe('3d');
- });
- });
-});
diff --git a/spec/javascripts/profile/account/components/delete_account_modal_spec.js b/spec/javascripts/profile/account/components/delete_account_modal_spec.js
index a0939ff5c20..d5f5cabc63e 100644
--- a/spec/javascripts/profile/account/components/delete_account_modal_spec.js
+++ b/spec/javascripts/profile/account/components/delete_account_modal_spec.js
@@ -28,7 +28,7 @@ describe('DeleteAccountModal component', () => {
};
describe('with password confirmation', () => {
- beforeEach((done) => {
+ beforeEach(done => {
vm = mountComponent(Component, {
actionUrl,
confirmWithPassword: true,
@@ -42,7 +42,7 @@ describe('DeleteAccountModal component', () => {
.catch(done.fail);
});
- it('does not accept empty password', (done) => {
+ it('does not accept empty password', done => {
const { form, input, submitButton } = findElements();
spyOn(form, 'submit');
input.value = '';
@@ -53,13 +53,14 @@ describe('DeleteAccountModal component', () => {
expect(vm.enteredPassword).toBe(input.value);
expect(submitButton).toHaveAttr('disabled', 'disabled');
submitButton.click();
+
expect(form.submit).not.toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
});
- it('submits form with password', (done) => {
+ it('submits form with password', done => {
const { form, input, submitButton } = findElements();
spyOn(form, 'submit');
input.value = 'anything';
@@ -70,6 +71,7 @@ describe('DeleteAccountModal component', () => {
expect(vm.enteredPassword).toBe(input.value);
expect(submitButton).not.toHaveAttr('disabled', 'disabled');
submitButton.click();
+
expect(form.submit).toHaveBeenCalled();
})
.then(done)
@@ -78,7 +80,7 @@ describe('DeleteAccountModal component', () => {
});
describe('with username confirmation', () => {
- beforeEach((done) => {
+ beforeEach(done => {
vm = mountComponent(Component, {
actionUrl,
confirmWithPassword: false,
@@ -92,7 +94,7 @@ describe('DeleteAccountModal component', () => {
.catch(done.fail);
});
- it('does not accept wrong username', (done) => {
+ it('does not accept wrong username', done => {
const { form, input, submitButton } = findElements();
spyOn(form, 'submit');
input.value = 'this is wrong';
@@ -103,13 +105,14 @@ describe('DeleteAccountModal component', () => {
expect(vm.enteredUsername).toBe(input.value);
expect(submitButton).toHaveAttr('disabled', 'disabled');
submitButton.click();
+
expect(form.submit).not.toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
});
- it('submits form with correct username', (done) => {
+ it('submits form with correct username', done => {
const { form, input, submitButton } = findElements();
spyOn(form, 'submit');
input.value = username;
@@ -120,6 +123,7 @@ describe('DeleteAccountModal component', () => {
expect(vm.enteredUsername).toBe(input.value);
expect(submitButton).not.toHaveAttr('disabled', 'disabled');
submitButton.click();
+
expect(form.submit).toHaveBeenCalled();
})
.then(done)
diff --git a/spec/javascripts/profile/account/components/update_username_spec.js b/spec/javascripts/profile/account/components/update_username_spec.js
index 5311499fb73..cc07a5f6e43 100644
--- a/spec/javascripts/profile/account/components/update_username_spec.js
+++ b/spec/javascripts/profile/account/components/update_username_spec.js
@@ -113,6 +113,7 @@ describe('UpdateUsername component', () => {
Vue.nextTick()
.then(() => {
confirmModalBtn.click();
+
expect(axios.put).toHaveBeenCalledWith(actionUrl, { user: { username: newUsername } });
})
.then(done)
@@ -131,8 +132,7 @@ describe('UpdateUsername component', () => {
vm.newUsername = newUsername;
- vm
- .onConfirm()
+ vm.onConfirm()
.then(() => {
expect(vm.username).toBe(newUsername);
expect(vm.newUsername).toBe(newUsername);
@@ -157,8 +157,7 @@ describe('UpdateUsername component', () => {
const invalidUsername = 'anything.git';
vm.newUsername = invalidUsername;
- vm
- .onConfirm()
+ vm.onConfirm()
.then(() => done.fail('Expected onConfirm to throw!'))
.catch(() => {
expect(vm.username).toBe(username);
diff --git a/spec/javascripts/project_select_combo_button_spec.js b/spec/javascripts/project_select_combo_button_spec.js
index 1b65f767f96..109a5000f5d 100644
--- a/spec/javascripts/project_select_combo_button_spec.js
+++ b/spec/javascripts/project_select_combo_button_spec.js
@@ -3,10 +3,10 @@ import ProjectSelectComboButton from '~/project_select_combo_button';
const fixturePath = 'static/project_select_combo_button.html.raw';
-describe('Project Select Combo Button', function () {
+describe('Project Select Combo Button', function() {
preloadFixtures(fixturePath);
- beforeEach(function () {
+ beforeEach(function() {
this.defaults = {
label: 'Select project to create issue',
groupId: 12345,
@@ -28,43 +28,44 @@ describe('Project Select Combo Button', function () {
this.projectSelectInput = document.querySelector('.project-item-select');
});
- describe('on page load when localStorage is empty', function () {
- beforeEach(function () {
+ describe('on page load when localStorage is empty', function() {
+ beforeEach(function() {
this.comboButton = new ProjectSelectComboButton(this.projectSelectInput);
});
- it('newItemBtn href is null', function () {
+ it('newItemBtn href is null', function() {
expect(this.newItemBtn.getAttribute('href')).toBe('');
});
- it('newItemBtn text is the plain default label', function () {
+ it('newItemBtn text is the plain default label', function() {
expect(this.newItemBtn.textContent).toBe(this.defaults.label);
});
});
- describe('on page load when localStorage is filled', function () {
- beforeEach(function () {
- window.localStorage
- .setItem(this.defaults.localStorageKey, JSON.stringify(this.defaults.projectMeta));
+ describe('on page load when localStorage is filled', function() {
+ beforeEach(function() {
+ window.localStorage.setItem(
+ this.defaults.localStorageKey,
+ JSON.stringify(this.defaults.projectMeta),
+ );
this.comboButton = new ProjectSelectComboButton(this.projectSelectInput);
});
- it('newItemBtn href is correctly set', function () {
+ it('newItemBtn href is correctly set', function() {
expect(this.newItemBtn.getAttribute('href')).toBe(this.defaults.projectMeta.url);
});
- it('newItemBtn text is the cached label', function () {
- expect(this.newItemBtn.textContent)
- .toBe(`New issue in ${this.defaults.projectMeta.name}`);
+ it('newItemBtn text is the cached label', function() {
+ expect(this.newItemBtn.textContent).toBe(`New issue in ${this.defaults.projectMeta.name}`);
});
- afterEach(function () {
+ afterEach(function() {
window.localStorage.clear();
});
});
- describe('after selecting a new project', function () {
- beforeEach(function () {
+ describe('after selecting a new project', function() {
+ beforeEach(function() {
this.comboButton = new ProjectSelectComboButton(this.projectSelectInput);
// mock the effect of selecting an item from the projects dropdown (select2)
@@ -73,23 +74,21 @@ describe('Project Select Combo Button', function () {
.trigger('change');
});
- it('newItemBtn href is correctly set', function () {
- expect(this.newItemBtn.getAttribute('href'))
- .toBe('http://myothercoolproject.com/issues/new');
+ it('newItemBtn href is correctly set', function() {
+ expect(this.newItemBtn.getAttribute('href')).toBe('http://myothercoolproject.com/issues/new');
});
- it('newItemBtn text is the selected project label', function () {
- expect(this.newItemBtn.textContent)
- .toBe(`New issue in ${this.defaults.newProjectMeta.name}`);
+ it('newItemBtn text is the selected project label', function() {
+ expect(this.newItemBtn.textContent).toBe(`New issue in ${this.defaults.newProjectMeta.name}`);
});
- afterEach(function () {
+ afterEach(function() {
window.localStorage.clear();
});
});
- describe('deriveTextVariants', function () {
- beforeEach(function () {
+ describe('deriveTextVariants', function() {
+ beforeEach(function() {
this.mockExecutionContext = {
resourceType: '',
resourceLabel: '',
@@ -100,7 +99,7 @@ describe('Project Select Combo Button', function () {
this.method = this.comboButton.deriveTextVariants.bind(this.mockExecutionContext);
});
- it('correctly derives test variants for merge requests', function () {
+ it('correctly derives test variants for merge requests', function() {
this.mockExecutionContext.resourceType = 'merge_requests';
this.mockExecutionContext.resourceLabel = 'New merge request';
@@ -111,7 +110,7 @@ describe('Project Select Combo Button', function () {
expect(returnedVariants.presetTextSuffix).toBe('merge request');
});
- it('correctly derives text variants for issues', function () {
+ it('correctly derives text variants for issues', function() {
this.mockExecutionContext.resourceType = 'issues';
this.mockExecutionContext.resourceLabel = 'New issue';
@@ -123,4 +122,3 @@ describe('Project Select Combo Button', function () {
});
});
});
-
diff --git a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown_spec.js b/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown_spec.js
index 21805ef0b28..fdecb823cd2 100644
--- a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown_spec.js
+++ b/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_machine_type_dropdown_spec.js
@@ -90,14 +90,20 @@ describe('GkeMachineTypeDropdown', () => {
expect(vm.$el.querySelector('input').value).toBe('');
vm.$store.commit(SET_MACHINE_TYPES, gapiMachineTypesResponseMock.items);
- return vm.$nextTick().then(() => {
- vm.$el.querySelector('.dropdown-content button').click();
-
- return vm.$nextTick().then(() => {
- expect(vm.$el.querySelector('input').value).toBe(selectedMachineTypeMock);
- done();
- });
- });
+ return vm
+ .$nextTick()
+ .then(() => {
+ vm.$el.querySelector('.dropdown-content button').click();
+
+ return vm
+ .$nextTick()
+ .then(() => {
+ expect(vm.$el.querySelector('input').value).toBe(selectedMachineTypeMock);
+ done();
+ })
+ .catch(done.fail);
+ })
+ .catch(done.fail);
});
});
});
diff --git a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js b/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js
index d4fcb2dc8ff..030662b4d90 100644
--- a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js
+++ b/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_project_id_dropdown_spec.js
@@ -48,45 +48,61 @@ describe('GkeProjectIdDropdown', () => {
it('returns project billing validation text', () => {
vm.setIsValidatingProjectBilling(true);
+
expect(vm.toggleText).toBe(LABELS.VALIDATING_PROJECT_BILLING);
});
it('returns default toggle text', done =>
- vm.$nextTick().then(() => {
- vm.setItem(emptyProjectMock);
+ vm
+ .$nextTick()
+ .then(() => {
+ vm.setItem(emptyProjectMock);
- expect(vm.toggleText).toBe(LABELS.DEFAULT);
- done();
- }));
+ expect(vm.toggleText).toBe(LABELS.DEFAULT);
+ done();
+ })
+ .catch(done.fail));
it('returns project name if project selected', done =>
- vm.$nextTick().then(() => {
- expect(vm.toggleText).toBe(selectedProjectMock.name);
- done();
- }));
+ vm
+ .$nextTick()
+ .then(() => {
+ expect(vm.toggleText).toBe(selectedProjectMock.name);
+ done();
+ })
+ .catch(done.fail));
it('returns empty toggle text', done =>
- vm.$nextTick().then(() => {
- vm.$store.commit(SET_PROJECTS, null);
- vm.setItem(emptyProjectMock);
+ vm
+ .$nextTick()
+ .then(() => {
+ vm.$store.commit(SET_PROJECTS, null);
+ vm.setItem(emptyProjectMock);
- expect(vm.toggleText).toBe(LABELS.EMPTY);
- done();
- }));
+ expect(vm.toggleText).toBe(LABELS.EMPTY);
+ done();
+ })
+ .catch(done.fail));
});
describe('selectItem', () => {
it('reflects new value when dropdown item is clicked', done => {
expect(vm.$el.querySelector('input').value).toBe('');
- return vm.$nextTick().then(() => {
- vm.$el.querySelector('.dropdown-content button').click();
-
- return vm.$nextTick().then(() => {
- expect(vm.$el.querySelector('input').value).toBe(selectedProjectMock.projectId);
- done();
- });
- });
+ return vm
+ .$nextTick()
+ .then(() => {
+ vm.$el.querySelector('.dropdown-content button').click();
+
+ return vm
+ .$nextTick()
+ .then(() => {
+ expect(vm.$el.querySelector('input').value).toBe(selectedProjectMock.projectId);
+ done();
+ })
+ .catch(done.fail);
+ })
+ .catch(done.fail);
});
});
});
diff --git a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown_spec.js b/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown_spec.js
index 89a4a7ea2ce..95186e19ca1 100644
--- a/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown_spec.js
+++ b/spec/javascripts/projects/gke_cluster_dropdowns/components/gke_zone_dropdown_spec.js
@@ -75,14 +75,20 @@ describe('GkeZoneDropdown', () => {
expect(vm.$el.querySelector('input').value).toBe('');
vm.$store.commit(SET_ZONES, gapiZonesResponseMock.items);
- return vm.$nextTick().then(() => {
- vm.$el.querySelector('.dropdown-content button').click();
-
- return vm.$nextTick().then(() => {
- expect(vm.$el.querySelector('input').value).toBe(selectedZoneMock);
- done();
- });
- });
+ return vm
+ .$nextTick()
+ .then(() => {
+ vm.$el.querySelector('.dropdown-content button').click();
+
+ return vm
+ .$nextTick()
+ .then(() => {
+ expect(vm.$el.querySelector('input').value).toBe(selectedZoneMock);
+ done();
+ })
+ .catch(done.fail);
+ })
+ .catch(done.fail);
});
});
});
diff --git a/spec/javascripts/projects/project_new_spec.js b/spec/javascripts/projects/project_new_spec.js
index dace834a3c8..b61e0ac872f 100644
--- a/spec/javascripts/projects/project_new_spec.js
+++ b/spec/javascripts/projects/project_new_spec.js
@@ -27,7 +27,10 @@ describe('New Project', () => {
beforeEach(() => {
projectNew.bindEvents();
- $projectPath.val('').keyup().val(dummyImportUrl);
+ $projectPath
+ .val('')
+ .keyup()
+ .val(dummyImportUrl);
});
it('does not change project path for disabled $projectImportUrl', () => {
diff --git a/spec/javascripts/prometheus_metrics/prometheus_metrics_spec.js b/spec/javascripts/prometheus_metrics/prometheus_metrics_spec.js
index 955ec6a531c..94e2f959d46 100644
--- a/spec/javascripts/prometheus_metrics/prometheus_metrics_spec.js
+++ b/spec/javascripts/prometheus_metrics/prometheus_metrics_spec.js
@@ -85,9 +85,17 @@ describe('PrometheusMetrics', () => {
expect(prometheusMetrics.$monitoredMetricsLoading.hasClass('hidden')).toBeTruthy();
expect(prometheusMetrics.$monitoredMetricsList.hasClass('hidden')).toBeFalsy();
- expect(prometheusMetrics.$monitoredMetricsCount.text()).toEqual('3 exporters with 12 metrics were found');
+ expect(prometheusMetrics.$monitoredMetricsCount.text()).toEqual(
+ '3 exporters with 12 metrics were found',
+ );
+
expect($metricsListLi.length).toEqual(metrics.length);
- expect($metricsListLi.first().find('.badge').text()).toEqual(`${metrics[0].active_metrics}`);
+ expect(
+ $metricsListLi
+ .first()
+ .find('.badge')
+ .text(),
+ ).toEqual(`${metrics[0].active_metrics}`);
});
it('should show missing environment variables list', () => {
@@ -129,7 +137,7 @@ describe('PrometheusMetrics', () => {
mock.restore();
});
- it('should show loader animation while response is being loaded and hide it when request is complete', (done) => {
+ it('should show loader animation while response is being loaded and hide it when request is complete', done => {
mockSuccess();
prometheusMetrics.loadActiveMetrics();
@@ -143,7 +151,7 @@ describe('PrometheusMetrics', () => {
});
});
- it('should show empty state if response failed to load', (done) => {
+ it('should show empty state if response failed to load', done => {
mockError();
prometheusMetrics.loadActiveMetrics();
@@ -155,7 +163,7 @@ describe('PrometheusMetrics', () => {
});
});
- it('should populate metrics list once response is loaded', (done) => {
+ it('should populate metrics list once response is loaded', done => {
spyOn(prometheusMetrics, 'populateActiveMetrics');
mockSuccess();
diff --git a/spec/javascripts/raven/raven_config_spec.js b/spec/javascripts/raven/raven_config_spec.js
index c82658b9262..5cc59cc28d3 100644
--- a/spec/javascripts/raven/raven_config_spec.js
+++ b/spec/javascripts/raven/raven_config_spec.js
@@ -133,7 +133,7 @@ describe('RavenConfig', () => {
RavenConfig.setUser.call(ravenConfig);
});
- it('should call .setUserContext', function () {
+ it('should call .setUserContext', function() {
expect(Raven.setUserContext).toHaveBeenCalledWith({
id: ravenConfig.options.currentUserId,
});
diff --git a/spec/javascripts/registry/components/app_spec.js b/spec/javascripts/registry/components/app_spec.js
index cf1d0625397..92ff960277a 100644
--- a/spec/javascripts/registry/components/app_spec.js
+++ b/spec/javascripts/registry/components/app_spec.js
@@ -18,9 +18,11 @@ describe('Registry List', () => {
describe('with data', () => {
const interceptor = (request, next) => {
- next(request.respondWith(JSON.stringify(reposServerResponse), {
- status: 200,
- }));
+ next(
+ request.respondWith(JSON.stringify(reposServerResponse), {
+ status: 200,
+ }),
+ );
};
beforeEach(() => {
@@ -32,21 +34,21 @@ describe('Registry List', () => {
Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor);
});
- it('should render a list of repos', (done) => {
+ it('should render a list of repos', done => {
setTimeout(() => {
expect(vm.$store.state.repos.length).toEqual(reposServerResponse.length);
Vue.nextTick(() => {
- expect(
- vm.$el.querySelectorAll('.container-image').length,
- ).toEqual(reposServerResponse.length);
+ expect(vm.$el.querySelectorAll('.container-image').length).toEqual(
+ reposServerResponse.length,
+ );
done();
});
}, 0);
});
describe('delete repository', () => {
- it('should be possible to delete a repo', (done) => {
+ it('should be possible to delete a repo', done => {
setTimeout(() => {
Vue.nextTick(() => {
expect(vm.$el.querySelector('.container-image-head .js-remove-repo')).toBeDefined();
@@ -57,12 +59,14 @@ describe('Registry List', () => {
});
describe('toggle repository', () => {
- it('should open the container', (done) => {
+ it('should open the container', done => {
setTimeout(() => {
Vue.nextTick(() => {
vm.$el.querySelector('.js-toggle-repo').click();
Vue.nextTick(() => {
- expect(vm.$el.querySelector('.js-toggle-repo i').className).toEqual('fa fa-chevron-up');
+ expect(vm.$el.querySelector('.js-toggle-repo i').className).toEqual(
+ 'fa fa-chevron-up',
+ );
done();
});
});
@@ -73,9 +77,11 @@ describe('Registry List', () => {
describe('without data', () => {
const interceptor = (request, next) => {
- next(request.respondWith(JSON.stringify([]), {
- status: 200,
- }));
+ next(
+ request.respondWith(JSON.stringify([]), {
+ status: 200,
+ }),
+ );
};
beforeEach(() => {
@@ -87,11 +93,16 @@ describe('Registry List', () => {
Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor);
});
- it('should render empty message', (done) => {
+ it('should render empty message', done => {
setTimeout(() => {
expect(
- vm.$el.querySelector('p').textContent.trim().replace(/[\r\n]+/g, ' '),
- ).toEqual('No container images stored for this project. Add one by following the instructions above.');
+ vm.$el
+ .querySelector('p')
+ .textContent.trim()
+ .replace(/[\r\n]+/g, ' '),
+ ).toEqual(
+ 'No container images stored for this project. Add one by following the instructions above.',
+ );
done();
}, 0);
});
@@ -99,9 +110,11 @@ describe('Registry List', () => {
describe('while loading data', () => {
const interceptor = (request, next) => {
- next(request.respondWith(JSON.stringify(reposServerResponse), {
- status: 200,
- }));
+ next(
+ request.respondWith(JSON.stringify(reposServerResponse), {
+ status: 200,
+ }),
+ );
};
beforeEach(() => {
@@ -113,7 +126,7 @@ describe('Registry List', () => {
Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor);
});
- it('should render a loading spinner', (done) => {
+ it('should render a loading spinner', done => {
Vue.nextTick(() => {
expect(vm.$el.querySelector('.fa-spinner')).not.toBe(null);
done();
diff --git a/spec/javascripts/registry/components/collapsible_container_spec.js b/spec/javascripts/registry/components/collapsible_container_spec.js
index 5891921318a..256a242f784 100644
--- a/spec/javascripts/registry/components/collapsible_container_spec.js
+++ b/spec/javascripts/registry/components/collapsible_container_spec.js
@@ -24,26 +24,32 @@ describe('collapsible registry container', () => {
describe('toggle', () => {
it('should be closed by default', () => {
expect(vm.$el.querySelector('.container-image-tags')).toBe(null);
- expect(vm.$el.querySelector('.container-image-head i').className).toEqual('fa fa-chevron-right');
+ expect(vm.$el.querySelector('.container-image-head i').className).toEqual(
+ 'fa fa-chevron-right',
+ );
});
- it('should be open when user clicks on closed repo', (done) => {
+ it('should be open when user clicks on closed repo', done => {
vm.$el.querySelector('.js-toggle-repo').click();
Vue.nextTick(() => {
expect(vm.$el.querySelector('.container-image-tags')).toBeDefined();
- expect(vm.$el.querySelector('.container-image-head i').className).toEqual('fa fa-chevron-up');
+ expect(vm.$el.querySelector('.container-image-head i').className).toEqual(
+ 'fa fa-chevron-up',
+ );
done();
});
});
- it('should be closed when the user clicks on an opened repo', (done) => {
+ it('should be closed when the user clicks on an opened repo', done => {
vm.$el.querySelector('.js-toggle-repo').click();
Vue.nextTick(() => {
vm.$el.querySelector('.js-toggle-repo').click();
Vue.nextTick(() => {
expect(vm.$el.querySelector('.container-image-tags')).toBe(null);
- expect(vm.$el.querySelector('.container-image-head i').className).toEqual('fa fa-chevron-right');
+ expect(vm.$el.querySelector('.container-image-head i').className).toEqual(
+ 'fa fa-chevron-right',
+ );
done();
});
});
diff --git a/spec/javascripts/registry/components/table_registry_spec.js b/spec/javascripts/registry/components/table_registry_spec.js
index 6aa61afc445..7f5252a7d6c 100644
--- a/spec/javascripts/registry/components/table_registry_spec.js
+++ b/spec/javascripts/registry/components/table_registry_spec.js
@@ -22,13 +22,15 @@ describe('table registry', () => {
});
it('should render a table with the registry list', () => {
- expect(
- vm.$el.querySelectorAll('table tbody tr').length,
- ).toEqual(repoPropsData.list.length);
+ expect(vm.$el.querySelectorAll('table tbody tr').length).toEqual(repoPropsData.list.length);
});
it('should render registry tag', () => {
- const textRendered = vm.$el.querySelector('.table tbody tr').textContent.trim().replace(/\s\s+/g, ' ');
+ const textRendered = vm.$el
+ .querySelector('.table tbody tr')
+ .textContent.trim()
+ .replace(/\s\s+/g, ' ');
+
expect(textRendered).toContain(repoPropsData.list[0].tag);
expect(textRendered).toContain(repoPropsData.list[0].shortRevision);
expect(textRendered).toContain(repoPropsData.list[0].layers);
@@ -36,9 +38,7 @@ describe('table registry', () => {
});
it('should be possible to delete a registry', () => {
- expect(
- vm.$el.querySelector('.table tbody tr .js-delete-registry'),
- ).toBeDefined();
+ expect(vm.$el.querySelector('.table tbody tr .js-delete-registry')).toBeDefined();
});
describe('pagination', () => {
diff --git a/spec/javascripts/registry/getters_spec.js b/spec/javascripts/registry/getters_spec.js
index 3d989541881..839aa718997 100644
--- a/spec/javascripts/registry/getters_spec.js
+++ b/spec/javascripts/registry/getters_spec.js
@@ -7,25 +7,28 @@ describe('Getters Registry Store', () => {
state = {
isLoading: false,
endpoint: '/root/empty-project/container_registry.json',
- repos: [{
- canDelete: true,
- destroyPath: 'bar',
- id: '134',
- isLoading: false,
- list: [],
- location: 'foo',
- name: 'gitlab-org/omnibus-gitlab/foo',
- tagsPath: 'foo',
- }, {
- canDelete: true,
- destroyPath: 'bar',
- id: '123',
- isLoading: false,
- list: [],
- location: 'foo',
- name: 'gitlab-org/omnibus-gitlab',
- tagsPath: 'foo',
- }],
+ repos: [
+ {
+ canDelete: true,
+ destroyPath: 'bar',
+ id: '134',
+ isLoading: false,
+ list: [],
+ location: 'foo',
+ name: 'gitlab-org/omnibus-gitlab/foo',
+ tagsPath: 'foo',
+ },
+ {
+ canDelete: true,
+ destroyPath: 'bar',
+ id: '123',
+ isLoading: false,
+ list: [],
+ location: 'foo',
+ name: 'gitlab-org/omnibus-gitlab',
+ tagsPath: 'foo',
+ },
+ ],
};
});
diff --git a/spec/javascripts/registry/mock_data.js b/spec/javascripts/registry/mock_data.js
index 6bffb47be55..22db203e77f 100644
--- a/spec/javascripts/registry/mock_data.js
+++ b/spec/javascripts/registry/mock_data.js
@@ -40,7 +40,8 @@ export const registryServerResponse = [
layers: 19,
location: 'location',
created_at: 1505828744434,
- }];
+ },
+];
export const parsedReposServerResponse = [
{
diff --git a/spec/javascripts/registry/stores/mutations_spec.js b/spec/javascripts/registry/stores/mutations_spec.js
index 2e4c0659daa..e19fe7a27cf 100644
--- a/spec/javascripts/registry/stores/mutations_spec.js
+++ b/spec/javascripts/registry/stores/mutations_spec.js
@@ -18,6 +18,7 @@ describe('Mutations Registry Store', () => {
it('should set the main endpoint', () => {
const expectedState = Object.assign({}, mockState, { endpoint: 'foo' });
mutations[types.SET_MAIN_ENDPOINT](mockState, 'foo');
+
expect(mockState).toEqual(expectedState);
});
});
@@ -25,6 +26,7 @@ describe('Mutations Registry Store', () => {
describe('SET_REPOS_LIST', () => {
it('should set a parsed repository list', () => {
mutations[types.SET_REPOS_LIST](mockState, reposServerResponse);
+
expect(mockState.repos).toEqual(parsedReposServerResponse);
});
});
@@ -32,6 +34,7 @@ describe('Mutations Registry Store', () => {
describe('TOGGLE_MAIN_LOADING', () => {
it('should set a parsed repository list', () => {
mutations[types.TOGGLE_MAIN_LOADING](mockState);
+
expect(mockState.isLoading).toEqual(true);
});
});
@@ -75,6 +78,7 @@ describe('Mutations Registry Store', () => {
});
mutations[types.TOGGLE_REGISTRY_LIST_LOADING](mockState, mockState.repos[0]);
+
expect(mockState.repos[0].isLoading).toEqual(true);
});
});
diff --git a/spec/javascripts/reports/components/grouped_test_reports_app_spec.js b/spec/javascripts/reports/components/grouped_test_reports_app_spec.js
index 333cefe5f8a..f58515daa4f 100644
--- a/spec/javascripts/reports/components/grouped_test_reports_app_spec.js
+++ b/spec/javascripts/reports/components/grouped_test_reports_app_spec.js
@@ -42,6 +42,7 @@ describe('Grouped Test Reports App', () => {
expect(vm.$el.textContent).toContain(
'rspec:pg found no changed test results out of 8 total tests',
);
+
expect(vm.$el.textContent).toContain(
'java ant found no changed test results out of 3 total tests',
);
@@ -88,6 +89,7 @@ describe('Grouped Test Reports App', () => {
expect(vm.$el.textContent).toContain(
'rspec:pg found 2 failed test results out of 8 total tests',
);
+
expect(vm.$el.textContent).toContain('New');
expect(vm.$el.textContent).toContain(
'java ant found no changed test results out of 3 total tests',
@@ -115,6 +117,7 @@ describe('Grouped Test Reports App', () => {
expect(vm.$el.textContent).toContain(
'rspec:pg found 1 failed test result and 2 fixed test results out of 8 total tests',
);
+
expect(vm.$el.textContent).toContain('New');
expect(vm.$el.textContent).toContain(
' java ant found 1 failed test result out of 3 total tests',
@@ -151,6 +154,7 @@ describe('Grouped Test Reports App', () => {
expect(vm.$el.querySelector('.js-mr-code-resolved-issues').textContent).toContain(
resolvedFailures.suites[0].resolved_failures[0].name,
);
+
expect(vm.$el.querySelector('.js-mr-code-resolved-issues').textContent).toContain(
resolvedFailures.suites[0].resolved_failures[1].name,
);
diff --git a/spec/javascripts/reports/components/modal_spec.js b/spec/javascripts/reports/components/modal_spec.js
index 3a567c40eca..6b8471381de 100644
--- a/spec/javascripts/reports/components/modal_spec.js
+++ b/spec/javascripts/reports/components/modal_spec.js
@@ -27,12 +27,19 @@ describe('Grouped Test Reports Modal', () => {
});
it('renders code block', () => {
- expect(vm.$el.querySelector('code').textContent).toEqual(modalDataStructure.system_output.value);
+ expect(vm.$el.querySelector('code').textContent).toEqual(
+ modalDataStructure.system_output.value,
+ );
});
it('renders link', () => {
- expect(vm.$el.querySelector('.js-modal-link').getAttribute('href')).toEqual(modalDataStructure.class.value);
- expect(trimText(vm.$el.querySelector('.js-modal-link').textContent)).toEqual(modalDataStructure.class.value);
+ expect(vm.$el.querySelector('.js-modal-link').getAttribute('href')).toEqual(
+ modalDataStructure.class.value,
+ );
+
+ expect(trimText(vm.$el.querySelector('.js-modal-link').textContent)).toEqual(
+ modalDataStructure.class.value,
+ );
});
it('renders miliseconds', () => {
@@ -40,6 +47,8 @@ describe('Grouped Test Reports Modal', () => {
});
it('render title', () => {
- expect(trimText(vm.$el.querySelector('.modal-title').textContent)).toEqual('Test#sum when a is 1 and b is 2 returns summary');
+ expect(trimText(vm.$el.querySelector('.modal-title').textContent)).toEqual(
+ 'Test#sum when a is 1 and b is 2 returns summary',
+ );
});
});
diff --git a/spec/javascripts/reports/components/report_link_spec.js b/spec/javascripts/reports/components/report_link_spec.js
index cd6911e2f59..f879899e9c5 100644
--- a/spec/javascripts/reports/components/report_link_spec.js
+++ b/spec/javascripts/reports/components/report_link_spec.js
@@ -45,8 +45,7 @@ describe('report link', () => {
vm = mountComponent(Component, {
issue: {
path: 'Gemfile.lock',
- urlPath:
- 'https://groups.google.com/forum/#!topic/rubyonrails-security/335P1DcLG00',
+ urlPath: 'https://groups.google.com/forum/#!topic/rubyonrails-security/335P1DcLG00',
line: 22,
},
});
@@ -60,8 +59,7 @@ describe('report link', () => {
vm = mountComponent(Component, {
issue: {
path: 'Gemfile.lock',
- urlPath:
- 'https://groups.google.com/forum/#!topic/rubyonrails-security/335P1DcLG00',
+ urlPath: 'https://groups.google.com/forum/#!topic/rubyonrails-security/335P1DcLG00',
},
});
diff --git a/spec/javascripts/reports/components/report_section_spec.js b/spec/javascripts/reports/components/report_section_spec.js
index 6f6eb161d14..eb7307605d7 100644
--- a/spec/javascripts/reports/components/report_section_spec.js
+++ b/spec/javascripts/reports/components/report_section_spec.js
@@ -86,6 +86,7 @@ describe('Report section', () => {
});
});
});
+
describe('when it is loading', () => {
it('should render loading indicator', () => {
vm = mountComponent(ReportSection, {
@@ -96,6 +97,7 @@ describe('Report section', () => {
successText: 'Code quality improved on 1 point and degraded on 1 point',
hasIssues: false,
});
+
expect(vm.$el.textContent.trim()).toEqual('Loading codeclimate report');
});
});
@@ -168,6 +170,7 @@ describe('Report section', () => {
successText: 'Code quality improved on 1 point and degraded on 1 point',
hasIssues: false,
});
+
expect(vm.$el.textContent.trim()).toEqual('Failed to load codeclimate report');
});
});
diff --git a/spec/javascripts/reports/components/test_issue_body_spec.js b/spec/javascripts/reports/components/test_issue_body_spec.js
index 0ea81f714e7..32baf904ad7 100644
--- a/spec/javascripts/reports/components/test_issue_body_spec.js
+++ b/spec/javascripts/reports/components/test_issue_body_spec.js
@@ -29,6 +29,7 @@ describe('Test Issue body', () => {
spyOn(vm, 'openModal');
vm.$el.querySelector('button').click();
+
expect(vm.openModal).toHaveBeenCalledWith({
issue: commonProps.issue,
});
diff --git a/spec/javascripts/reports/store/mutations_spec.js b/spec/javascripts/reports/store/mutations_spec.js
index 7d19b16efb9..9446cd454ab 100644
--- a/spec/javascripts/reports/store/mutations_spec.js
+++ b/spec/javascripts/reports/store/mutations_spec.js
@@ -13,6 +13,7 @@ describe('Reports Store Mutations', () => {
describe('SET_ENDPOINT', () => {
it('should set endpoint', () => {
mutations[types.SET_ENDPOINT](stateCopy, 'endpoint.json');
+
expect(stateCopy.endpoint).toEqual('endpoint.json');
});
});
@@ -20,6 +21,7 @@ describe('Reports Store Mutations', () => {
describe('REQUEST_REPORTS', () => {
it('should set isLoading to true', () => {
mutations[types.REQUEST_REPORTS](stateCopy);
+
expect(stateCopy.isLoading).toEqual(true);
});
});
diff --git a/spec/javascripts/right_sidebar_spec.js b/spec/javascripts/right_sidebar_spec.js
index f9395eedfea..992e17978c1 100644
--- a/spec/javascripts/right_sidebar_spec.js
+++ b/spec/javascripts/right_sidebar_spec.js
@@ -1,124 +1,87 @@
-/* eslint-disable no-var, one-var, no-return-assign, vars-on-top, jasmine/no-unsafe-spy */
-
import $ from 'jquery';
import MockAdapter from 'axios-mock-adapter';
import '~/commons/bootstrap';
import axios from '~/lib/utils/axios_utils';
import Sidebar from '~/right_sidebar';
-(function() {
- var $aside, $icon, $labelsIcon, $page, $toggle, assertSidebarState;
-
- $aside = null;
-
- $toggle = null;
-
- $icon = null;
-
- $page = null;
-
- $labelsIcon = null;
-
- assertSidebarState = function(state) {
- var shouldBeCollapsed, shouldBeExpanded;
- shouldBeExpanded = state === 'expanded';
- shouldBeCollapsed = state === 'collapsed';
- expect($aside.hasClass('right-sidebar-expanded')).toBe(shouldBeExpanded);
- expect($page.hasClass('right-sidebar-expanded')).toBe(shouldBeExpanded);
- expect($icon.hasClass('fa-angle-double-right')).toBe(shouldBeExpanded);
- expect($aside.hasClass('right-sidebar-collapsed')).toBe(shouldBeCollapsed);
- expect($page.hasClass('right-sidebar-collapsed')).toBe(shouldBeCollapsed);
- return expect($icon.hasClass('fa-angle-double-left')).toBe(shouldBeCollapsed);
- };
-
- describe('RightSidebar', function() {
- describe('fixture tests', () => {
- var fixtureName = 'issues/open-issue.html.raw';
- preloadFixtures(fixtureName);
- loadJSONFixtures('todos/todos.json');
- let mock;
-
- beforeEach(function() {
- loadFixtures(fixtureName);
- mock = new MockAdapter(axios);
- new Sidebar(); // eslint-disable-line no-new
- $aside = $('.right-sidebar');
- $page = $('.layout-page');
- $icon = $aside.find('i');
- $toggle = $aside.find('.js-sidebar-toggle');
- return $labelsIcon = $aside.find('.sidebar-collapsed-icon');
- });
-
- afterEach(() => {
- mock.restore();
- });
-
- it('should expand/collapse the sidebar when arrow is clicked', function() {
- assertSidebarState('expanded');
- $toggle.click();
- assertSidebarState('collapsed');
- $toggle.click();
- assertSidebarState('expanded');
- });
- it('should float over the page and when sidebar icons clicked', function() {
- $labelsIcon.click();
- return assertSidebarState('expanded');
- });
- it('should collapse when the icon arrow clicked while it is floating on page', function() {
- $labelsIcon.click();
- assertSidebarState('expanded');
- $toggle.click();
- return assertSidebarState('collapsed');
- });
-
- it('should broadcast todo:toggle event when add todo clicked', function(done) {
- var todos = getJSONFixture('todos/todos.json');
- mock.onPost(/(.*)\/todos$/).reply(200, todos);
-
- var todoToggleSpy = spyOnEvent(document, 'todo:toggle');
-
- $('.issuable-sidebar-header .js-issuable-todo').click();
+let $aside = null;
+let $toggle = null;
+let $icon = null;
+let $page = null;
+let $labelsIcon = null;
+
+const assertSidebarState = function(state) {
+ const shouldBeExpanded = state === 'expanded';
+ const shouldBeCollapsed = state === 'collapsed';
+ expect($aside.hasClass('right-sidebar-expanded')).toBe(shouldBeExpanded);
+ expect($page.hasClass('right-sidebar-expanded')).toBe(shouldBeExpanded);
+ expect($icon.hasClass('fa-angle-double-right')).toBe(shouldBeExpanded);
+ expect($aside.hasClass('right-sidebar-collapsed')).toBe(shouldBeCollapsed);
+ expect($page.hasClass('right-sidebar-collapsed')).toBe(shouldBeCollapsed);
+ expect($icon.hasClass('fa-angle-double-left')).toBe(shouldBeCollapsed);
+};
+
+describe('RightSidebar', function() {
+ describe('fixture tests', () => {
+ const fixtureName = 'issues/open-issue.html.raw';
+ preloadFixtures(fixtureName);
+ loadJSONFixtures('todos/todos.json');
+ let mock;
+
+ beforeEach(function() {
+ loadFixtures(fixtureName);
+ mock = new MockAdapter(axios);
+ new Sidebar(); // eslint-disable-line no-new
+ $aside = $('.right-sidebar');
+ $page = $('.layout-page');
+ $icon = $aside.find('i');
+ $toggle = $aside.find('.js-sidebar-toggle');
+ $labelsIcon = $aside.find('.sidebar-collapsed-icon');
+ });
- setTimeout(() => {
- expect(todoToggleSpy.calls.count()).toEqual(1);
+ afterEach(() => {
+ mock.restore();
+ });
- done();
- });
- });
+ it('should expand/collapse the sidebar when arrow is clicked', function() {
+ assertSidebarState('expanded');
+ $toggle.click();
+ assertSidebarState('collapsed');
+ $toggle.click();
+ assertSidebarState('expanded');
+ });
- it('should not hide collapsed icons', () => {
- [].forEach.call(document.querySelectorAll('.sidebar-collapsed-icon'), (el) => {
- expect(el.querySelector('.fa, svg').classList.contains('hidden')).toBeFalsy();
- });
- });
+ it('should float over the page and when sidebar icons clicked', function() {
+ $labelsIcon.click();
+ assertSidebarState('expanded');
});
- describe('sidebarToggleClicked', () => {
- const event = jasmine.createSpyObj('event', ['preventDefault']);
+ it('should collapse when the icon arrow clicked while it is floating on page', function() {
+ $labelsIcon.click();
+ assertSidebarState('expanded');
+ $toggle.click();
+ assertSidebarState('collapsed');
+ });
- beforeEach(() => {
- spyOn($.fn, 'hasClass').and.returnValue(false);
- });
+ it('should broadcast todo:toggle event when add todo clicked', function(done) {
+ const todos = getJSONFixture('todos/todos.json');
+ mock.onPost(/(.*)\/todos$/).reply(200, todos);
- afterEach(() => {
- gl.lazyLoader = undefined;
- });
+ const todoToggleSpy = spyOnEvent(document, 'todo:toggle');
- it('calls loadCheck if lazyLoader is set', () => {
- gl.lazyLoader = jasmine.createSpyObj('lazyLoader', ['loadCheck']);
+ $('.issuable-sidebar-header .js-issuable-todo').click();
- Sidebar.prototype.sidebarToggleClicked(event);
+ setTimeout(() => {
+ expect(todoToggleSpy.calls.count()).toEqual(1);
- expect(gl.lazyLoader.loadCheck).toHaveBeenCalled();
+ done();
});
+ });
- it('does not throw if lazyLoader is not defined', () => {
- gl.lazyLoader = undefined;
-
- const toggle = Sidebar.prototype.sidebarToggleClicked.bind(null, event);
-
- expect(toggle).not.toThrow();
+ it('should not hide collapsed icons', () => {
+ [].forEach.call(document.querySelectorAll('.sidebar-collapsed-icon'), el => {
+ expect(el.querySelector('.fa, svg').classList.contains('hidden')).toBeFalsy();
});
});
});
-}).call(window);
+});
diff --git a/spec/javascripts/search_autocomplete_spec.js b/spec/javascripts/search_autocomplete_spec.js
index b96023a33c4..7530fd2a43b 100644
--- a/spec/javascripts/search_autocomplete_spec.js
+++ b/spec/javascripts/search_autocomplete_spec.js
@@ -111,6 +111,7 @@ describe('Search autocomplete dropdown', () => {
if (issuesPath) {
const issuesAssignedToMeLink = `a[href="${issuesPath}/?assignee_id=${userId}"]`;
const issuesIHaveCreatedLink = `a[href="${issuesPath}/?author_id=${userId}"]`;
+
expect(list.find(issuesAssignedToMeLink).length).toBe(1);
expect(list.find(issuesAssignedToMeLink).text()).toBe('Issues assigned to me');
expect(list.find(issuesIHaveCreatedLink).length).toBe(1);
@@ -118,6 +119,7 @@ describe('Search autocomplete dropdown', () => {
}
const mrsAssignedToMeLink = `a[href="${mrsPath}/?assignee_id=${userId}"]`;
const mrsIHaveCreatedLink = `a[href="${mrsPath}/?author_id=${userId}"]`;
+
expect(list.find(mrsAssignedToMeLink).length).toBe(1);
expect(list.find(mrsAssignedToMeLink).text()).toBe('Merge requests assigned to me');
expect(list.find(mrsIHaveCreatedLink).length).toBe(1);
@@ -140,6 +142,7 @@ describe('Search autocomplete dropdown', () => {
removeBodyAttributes();
window.gon = {};
});
+
it('should show Dashboard specific dropdown menu', function() {
var list;
addBodyAttributes();
@@ -148,6 +151,7 @@ describe('Search autocomplete dropdown', () => {
list = widget.wrap.find('.dropdown-menu').find('ul');
return assertLinks(list, dashboardIssuesPath, dashboardMRsPath);
});
+
it('should show Group specific dropdown menu', function() {
var list;
addBodyAttributes('group');
@@ -156,6 +160,7 @@ describe('Search autocomplete dropdown', () => {
list = widget.wrap.find('.dropdown-menu').find('ul');
return assertLinks(list, groupIssuesPath, groupMRsPath);
});
+
it('should show Project specific dropdown menu', function() {
var list;
addBodyAttributes('project');
@@ -164,6 +169,7 @@ describe('Search autocomplete dropdown', () => {
list = widget.wrap.find('.dropdown-menu').find('ul');
return assertLinks(list, projectIssuesPath, projectMRsPath);
});
+
it('should show only Project mergeRequest dropdown menu items when project issues are disabled', function() {
addBodyAttributes('project');
disableProjectIssues();
@@ -172,6 +178,7 @@ describe('Search autocomplete dropdown', () => {
const list = widget.wrap.find('.dropdown-menu').find('ul');
assertLinks(list, null, projectMRsPath);
});
+
it('should not show category related menu if there is text in the input', function() {
var link, list;
addBodyAttributes('project');
@@ -180,8 +187,10 @@ describe('Search autocomplete dropdown', () => {
widget.searchInput.triggerHandler('focus');
list = widget.wrap.find('.dropdown-menu').find('ul');
link = "a[href='" + projectIssuesPath + '/?assignee_id=' + userId + "']";
- return expect(list.find(link).length).toBe(0);
+
+ expect(list.find(link).length).toBe(0);
});
+
it('should not submit the search form when selecting an autocomplete row with the keyboard', function() {
var ENTER = 13;
var DOWN = 40;
diff --git a/spec/javascripts/search_spec.js b/spec/javascripts/search_spec.js
index 522851c584b..40bdbac7451 100644
--- a/spec/javascripts/search_spec.js
+++ b/spec/javascripts/search_spec.js
@@ -5,7 +5,7 @@ import Search from '~/pages/search/show/search';
describe('Search', () => {
const fixturePath = 'search/show.html.raw';
const searchTerm = 'some search';
- const fillDropdownInput = (dropdownSelector) => {
+ const fillDropdownInput = dropdownSelector => {
const dropdownElement = document.querySelector(dropdownSelector).parentNode;
const inputElement = dropdownElement.querySelector('.dropdown-input-field');
inputElement.value = searchTerm;
@@ -19,8 +19,8 @@ describe('Search', () => {
new Search(); // eslint-disable-line no-new
});
- it('requests groups from backend when filtering', (done) => {
- spyOn(Api, 'groups').and.callFake((term) => {
+ it('requests groups from backend when filtering', done => {
+ spyOn(Api, 'groups').and.callFake(term => {
expect(term).toBe(searchTerm);
done();
});
@@ -29,8 +29,8 @@ describe('Search', () => {
$(inputElement).trigger('input');
});
- it('requests projects from backend when filtering', (done) => {
- spyOn(Api, 'projects').and.callFake((term) => {
+ it('requests projects from backend when filtering', done => {
+ spyOn(Api, 'projects').and.callFake(term => {
expect(term).toBe(searchTerm);
done();
});
diff --git a/spec/javascripts/settings_panels_spec.js b/spec/javascripts/settings_panels_spec.js
index c1a69bd7018..3b681a9ff28 100644
--- a/spec/javascripts/settings_panels_spec.js
+++ b/spec/javascripts/settings_panels_spec.js
@@ -1,10 +1,11 @@
+import $ from 'jquery';
import initSettingsPanels from '~/settings_panels';
describe('Settings Panels', () => {
- preloadFixtures('projects/ci_cd_settings.html.raw');
+ preloadFixtures('groups/edit.html.raw');
beforeEach(() => {
- loadFixtures('projects/ci_cd_settings.html.raw');
+ loadFixtures('groups/edit.html.raw');
});
describe('initSettingsPane', () => {
@@ -13,17 +14,32 @@ describe('Settings Panels', () => {
});
it('should expand linked hash fragment panel', () => {
- window.location.hash = '#autodevops-settings';
+ window.location.hash = '#js-general-settings';
- const pipelineSettingsPanel = document.querySelector('#autodevops-settings');
+ const panel = document.querySelector('#js-general-settings');
// Our test environment automatically expands everything so we need to clear that out first
- pipelineSettingsPanel.classList.remove('expanded');
+ panel.classList.remove('expanded');
- expect(pipelineSettingsPanel.classList.contains('expanded')).toBe(false);
+ expect(panel.classList.contains('expanded')).toBe(false);
initSettingsPanels();
- expect(pipelineSettingsPanel.classList.contains('expanded')).toBe(true);
+ expect(panel.classList.contains('expanded')).toBe(true);
});
});
+
+ it('does not change the text content of triggers', () => {
+ const panel = document.querySelector('#js-general-settings');
+ const trigger = panel.querySelector('.js-settings-toggle-trigger-only');
+ const originalText = trigger.textContent;
+
+ initSettingsPanels();
+
+ expect(panel.classList.contains('expanded')).toBe(true);
+
+ $(trigger).click();
+
+ expect(panel.classList.contains('expanded')).toBe(false);
+ expect(trigger.textContent).toEqual(originalText);
+ });
});
diff --git a/spec/javascripts/shared/popover_spec.js b/spec/javascripts/shared/popover_spec.js
index 1d574c9424b..85bde075b77 100644
--- a/spec/javascripts/shared/popover_spec.js
+++ b/spec/javascripts/shared/popover_spec.js
@@ -1,9 +1,5 @@
import $ from 'jquery';
-import {
- togglePopover,
- mouseleave,
- mouseenter,
-} from '~/shared/popover';
+import { togglePopover, mouseleave, mouseenter } from '~/shared/popover';
describe('popover', () => {
describe('togglePopover', () => {
@@ -26,14 +22,14 @@ describe('popover', () => {
expect(togglePopover.call(context, true)).toEqual(false);
});
- it('shows popover', (done) => {
+ it('shows popover', done => {
const context = {
hasClass: () => false,
popover: () => {},
toggleClass: () => {},
};
- spyOn(context, 'popover').and.callFake((method) => {
+ spyOn(context, 'popover').and.callFake(method => {
expect(method).toEqual('show');
done();
});
@@ -41,7 +37,7 @@ describe('popover', () => {
togglePopover.call(context, true);
});
- it('adds disable-animation and js-popover-show class', (done) => {
+ it('adds disable-animation and js-popover-show class', done => {
const context = {
hasClass: () => false,
popover: () => {},
@@ -77,14 +73,14 @@ describe('popover', () => {
expect(togglePopover.call(context, false)).toEqual(false);
});
- it('hides popover', (done) => {
+ it('hides popover', done => {
const context = {
hasClass: () => true,
popover: () => {},
toggleClass: () => {},
};
- spyOn(context, 'popover').and.callFake((method) => {
+ spyOn(context, 'popover').and.callFake(method => {
expect(method).toEqual('hide');
done();
});
@@ -92,7 +88,7 @@ describe('popover', () => {
togglePopover.call(context, false);
});
- it('removes disable-animation and js-popover-show class', (done) => {
+ it('removes disable-animation and js-popover-show class', done => {
const context = {
hasClass: () => true,
popover: () => {},
@@ -116,9 +112,12 @@ describe('popover', () => {
length: 0,
};
- spyOn($.fn, 'init').and.callFake(selector => (selector === '.popover:hover' ? fakeJquery : $.fn));
+ spyOn($.fn, 'init').and.callFake(
+ selector => (selector === '.popover:hover' ? fakeJquery : $.fn),
+ );
spyOn(togglePopover, 'call');
mouseleave();
+
expect(togglePopover.call).toHaveBeenCalledWith(jasmine.any(Object), false);
});
@@ -127,9 +126,12 @@ describe('popover', () => {
length: 1,
};
- spyOn($.fn, 'init').and.callFake(selector => (selector === '.popover:hover' ? fakeJquery : $.fn));
+ spyOn($.fn, 'init').and.callFake(
+ selector => (selector === '.popover:hover' ? fakeJquery : $.fn),
+ );
spyOn(togglePopover, 'call');
mouseleave();
+
expect(togglePopover.call).not.toHaveBeenCalledWith(false);
});
});
@@ -140,12 +142,13 @@ describe('popover', () => {
it('shows popover', () => {
spyOn(togglePopover, 'call').and.returnValue(false);
mouseenter.call(context);
+
expect(togglePopover.call).toHaveBeenCalledWith(jasmine.any(Object), true);
});
- it('registers mouseleave event if popover is showed', (done) => {
+ it('registers mouseleave event if popover is showed', done => {
spyOn(togglePopover, 'call').and.returnValue(true);
- spyOn($.fn, 'on').and.callFake((eventName) => {
+ spyOn($.fn, 'on').and.callFake(eventName => {
expect(eventName).toEqual('mouseleave');
done();
});
@@ -156,6 +159,7 @@ describe('popover', () => {
spyOn(togglePopover, 'call').and.returnValue(false);
const spy = spyOn($.fn, 'on').and.callFake(() => {});
mouseenter.call(context);
+
expect(spy).not.toHaveBeenCalled();
});
});
diff --git a/spec/javascripts/sidebar/assignees_spec.js b/spec/javascripts/sidebar/assignees_spec.js
index 843e7002180..e7f8f4f9936 100644
--- a/spec/javascripts/sidebar/assignees_spec.js
+++ b/spec/javascripts/sidebar/assignees_spec.js
@@ -22,6 +22,7 @@ describe('Assignee component', () => {
}).$mount();
const collapsed = component.$el.querySelector('.sidebar-collapsed-icon');
+
expect(collapsed.childElementCount).toEqual(1);
expect(collapsed.children[0].getAttribute('aria-label')).toEqual('No Assignee');
expect(collapsed.children[0].classList.contains('fa')).toEqual(true);
@@ -67,6 +68,7 @@ describe('Assignee component', () => {
spyOn(component, '$emit');
component.$el.querySelector('.assign-yourself .btn-link').click();
+
expect(component.$emit).toHaveBeenCalledWith('assign-self');
});
});
@@ -85,6 +87,7 @@ describe('Assignee component', () => {
const collapsed = component.$el.querySelector('.sidebar-collapsed-icon');
const assignee = collapsed.children[0];
+
expect(collapsed.childElementCount).toEqual(1);
expect(assignee.querySelector('.avatar').getAttribute('src')).toEqual(UsersMock.user.avatar);
expect(assignee.querySelector('.avatar').getAttribute('alt')).toEqual(`${UsersMock.user.name}'s avatar`);
@@ -138,14 +141,17 @@ describe('Assignee component', () => {
}).$mount();
const collapsed = component.$el.querySelector('.sidebar-collapsed-icon');
+
expect(collapsed.childElementCount).toEqual(2);
const first = collapsed.children[0];
+
expect(first.querySelector('.avatar').getAttribute('src')).toEqual(users[0].avatar);
expect(first.querySelector('.avatar').getAttribute('alt')).toEqual(`${users[0].name}'s avatar`);
expect(first.querySelector('.author').innerText.trim()).toEqual(users[0].name);
const second = collapsed.children[1];
+
expect(second.querySelector('.avatar').getAttribute('src')).toEqual(users[1].avatar);
expect(second.querySelector('.avatar').getAttribute('alt')).toEqual(`${users[1].name}'s avatar`);
expect(second.querySelector('.author').innerText.trim()).toEqual(users[1].name);
@@ -162,14 +168,17 @@ describe('Assignee component', () => {
}).$mount();
const collapsed = component.$el.querySelector('.sidebar-collapsed-icon');
+
expect(collapsed.childElementCount).toEqual(2);
const first = collapsed.children[0];
+
expect(first.querySelector('.avatar').getAttribute('src')).toEqual(users[0].avatar);
expect(first.querySelector('.avatar').getAttribute('alt')).toEqual(`${users[0].name}'s avatar`);
expect(first.querySelector('.author').innerText.trim()).toEqual(users[0].name);
const second = collapsed.children[1];
+
expect(second.querySelector('.avatar-counter').innerText.trim()).toEqual('+2');
});
@@ -200,6 +209,7 @@ describe('Assignee component', () => {
expect(component.$el.querySelectorAll('.user-item').length).toEqual(component.defaultRenderCount);
expect(component.$el.querySelector('.user-list-more')).not.toBe(null);
const usersLabelExpectation = users.length - component.defaultRenderCount;
+
expect(component.$el.querySelector('.user-list-more .btn-link').innerText.trim())
.not.toBe(`+${usersLabelExpectation} more`);
component.toggleShowLess();
diff --git a/spec/javascripts/sidebar/components/time_tracking/time_tracker_spec.js b/spec/javascripts/sidebar/components/time_tracking/time_tracker_spec.js
index 0e30759c41d..4c3dd713589 100644
--- a/spec/javascripts/sidebar/components/time_tracking/time_tracker_spec.js
+++ b/spec/javascripts/sidebar/components/time_tracking/time_tracker_spec.js
@@ -8,10 +8,12 @@ describe('Issuable Time Tracker', () => {
let initialData;
let vm;
- const initTimeTrackingComponent = ({ timeEstimate,
- timeSpent,
- timeEstimateHumanReadable,
- timeSpentHumanReadable }) => {
+ const initTimeTrackingComponent = ({
+ timeEstimate,
+ timeSpent,
+ timeEstimateHumanReadable,
+ timeSpentHumanReadable,
+ }) => {
setFixtures(`
<div>
<div id="mock-container"></div>
@@ -88,6 +90,7 @@ describe('Issuable Time Tracker', () => {
Vue.nextTick(() => {
expect(vm.showComparisonState).toBe(true);
const $comparisonPane = vm.$el.querySelector('.time-tracking-comparison-pane');
+
expect($comparisonPane).toBeVisible();
done();
});
@@ -96,14 +99,18 @@ describe('Issuable Time Tracker', () => {
describe('Remaining meter', () => {
it('should display the remaining meter with the correct width', done => {
Vue.nextTick(() => {
- expect(vm.$el.querySelector('.time-tracking-comparison-pane .progress[value="5"]')).not.toBeNull();
+ expect(
+ vm.$el.querySelector('.time-tracking-comparison-pane .progress[value="5"]'),
+ ).not.toBeNull();
done();
});
});
it('should display the remaining meter with the correct background color when within estimate', done => {
Vue.nextTick(() => {
- expect(vm.$el.querySelector('.time-tracking-comparison-pane .progress[variant="primary"]')).not.toBeNull();
+ expect(
+ vm.$el.querySelector('.time-tracking-comparison-pane .progress[variant="primary"]'),
+ ).not.toBeNull();
done();
});
});
@@ -112,7 +119,9 @@ describe('Issuable Time Tracker', () => {
vm.timeEstimate = 10000; // 2h 46m
vm.timeSpent = 20000000; // 231 days
Vue.nextTick(() => {
- expect(vm.$el.querySelector('.time-tracking-comparison-pane .progress[variant="danger"]')).not.toBeNull();
+ expect(
+ vm.$el.querySelector('.time-tracking-comparison-pane .progress[variant="danger"]'),
+ ).not.toBeNull();
done();
});
});
diff --git a/spec/javascripts/sidebar/confidential_edit_buttons_spec.js b/spec/javascripts/sidebar/confidential_edit_buttons_spec.js
index 482be466aad..32da9f83112 100644
--- a/spec/javascripts/sidebar/confidential_edit_buttons_spec.js
+++ b/spec/javascripts/sidebar/confidential_edit_buttons_spec.js
@@ -7,8 +7,8 @@ describe('Edit Form Buttons', () => {
beforeEach(() => {
const Component = Vue.extend(editFormButtons);
- const toggleForm = () => { };
- const updateConfidentialAttribute = () => { };
+ const toggleForm = () => {};
+ const updateConfidentialAttribute = () => {};
vm1 = new Component({
propsData: {
@@ -28,12 +28,8 @@ describe('Edit Form Buttons', () => {
});
it('renders on or off text based on confidentiality', () => {
- expect(
- vm1.$el.innerHTML.includes('Turn Off'),
- ).toBe(true);
+ expect(vm1.$el.innerHTML.includes('Turn Off')).toBe(true);
- expect(
- vm2.$el.innerHTML.includes('Turn On'),
- ).toBe(true);
+ expect(vm2.$el.innerHTML.includes('Turn On')).toBe(true);
});
});
diff --git a/spec/javascripts/sidebar/confidential_edit_form_buttons_spec.js b/spec/javascripts/sidebar/confidential_edit_form_buttons_spec.js
index 724f5126945..369088cb258 100644
--- a/spec/javascripts/sidebar/confidential_edit_form_buttons_spec.js
+++ b/spec/javascripts/sidebar/confidential_edit_form_buttons_spec.js
@@ -7,8 +7,8 @@ describe('Edit Form Dropdown', () => {
beforeEach(() => {
const Component = Vue.extend(editForm);
- const toggleForm = () => { };
- const updateConfidentialAttribute = () => { };
+ const toggleForm = () => {};
+ const updateConfidentialAttribute = () => {};
vm1 = new Component({
propsData: {
@@ -28,12 +28,8 @@ describe('Edit Form Dropdown', () => {
});
it('renders on the appropriate warning text', () => {
- expect(
- vm1.$el.innerHTML.includes('You are going to turn off the confidentiality.'),
- ).toBe(true);
+ expect(vm1.$el.innerHTML.includes('You are going to turn off the confidentiality.')).toBe(true);
- expect(
- vm2.$el.innerHTML.includes('You are going to turn on the confidentiality.'),
- ).toBe(true);
+ expect(vm2.$el.innerHTML.includes('You are going to turn on the confidentiality.')).toBe(true);
});
});
diff --git a/spec/javascripts/sidebar/confidential_issue_sidebar_spec.js b/spec/javascripts/sidebar/confidential_issue_sidebar_spec.js
index 6110d5d89ac..486a7241e33 100644
--- a/spec/javascripts/sidebar/confidential_issue_sidebar_spec.js
+++ b/spec/javascripts/sidebar/confidential_issue_sidebar_spec.js
@@ -29,20 +29,14 @@ describe('Confidential Issue Sidebar Block', () => {
});
it('shows if confidential and/or editable', () => {
- expect(
- vm1.$el.innerHTML.includes('Edit'),
- ).toBe(true);
+ expect(vm1.$el.innerHTML.includes('Edit')).toBe(true);
- expect(
- vm1.$el.innerHTML.includes('This issue is confidential'),
- ).toBe(true);
+ expect(vm1.$el.innerHTML.includes('This issue is confidential')).toBe(true);
- expect(
- vm2.$el.innerHTML.includes('Not confidential'),
- ).toBe(true);
+ expect(vm2.$el.innerHTML.includes('Not confidential')).toBe(true);
});
- it('displays the edit form when editable', (done) => {
+ it('displays the edit form when editable', done => {
expect(vm1.edit).toBe(false);
vm1.$el.querySelector('.confidential-edit').click();
@@ -50,17 +44,15 @@ describe('Confidential Issue Sidebar Block', () => {
expect(vm1.edit).toBe(true);
setTimeout(() => {
- expect(
- vm1.$el
- .innerHTML
- .includes('You are going to turn off the confidentiality.'),
- ).toBe(true);
+ expect(vm1.$el.innerHTML.includes('You are going to turn off the confidentiality.')).toBe(
+ true,
+ );
done();
});
});
- it('displays the edit form when opened from collapsed state', (done) => {
+ it('displays the edit form when opened from collapsed state', done => {
expect(vm1.edit).toBe(false);
vm1.$el.querySelector('.sidebar-collapsed-icon').click();
@@ -68,11 +60,9 @@ describe('Confidential Issue Sidebar Block', () => {
expect(vm1.edit).toBe(true);
setTimeout(() => {
- expect(
- vm1.$el
- .innerHTML
- .includes('You are going to turn off the confidentiality.'),
- ).toBe(true);
+ expect(vm1.$el.innerHTML.includes('You are going to turn off the confidentiality.')).toBe(
+ true,
+ );
done();
});
diff --git a/spec/javascripts/sidebar/lock/edit_form_buttons_spec.js b/spec/javascripts/sidebar/lock/edit_form_buttons_spec.js
index deeea669de8..330f59f08b2 100644
--- a/spec/javascripts/sidebar/lock/edit_form_buttons_spec.js
+++ b/spec/javascripts/sidebar/lock/edit_form_buttons_spec.js
@@ -8,8 +8,8 @@ describe('EditFormButtons', () => {
beforeEach(() => {
const Component = Vue.extend(editFormButtons);
- const toggleForm = () => { };
- const updateLockedAttribute = () => { };
+ const toggleForm = () => {};
+ const updateLockedAttribute = () => {};
vm1 = mountComponent(Component, {
isLocked: true,
@@ -25,12 +25,8 @@ describe('EditFormButtons', () => {
});
it('renders unlock or lock text based on locked state', () => {
- expect(
- vm1.$el.innerHTML.includes('Unlock'),
- ).toBe(true);
+ expect(vm1.$el.innerHTML.includes('Unlock')).toBe(true);
- expect(
- vm2.$el.innerHTML.includes('Lock'),
- ).toBe(true);
+ expect(vm2.$el.innerHTML.includes('Lock')).toBe(true);
});
});
diff --git a/spec/javascripts/sidebar/lock/edit_form_spec.js b/spec/javascripts/sidebar/lock/edit_form_spec.js
index 7abd6997a18..ec10a999a40 100644
--- a/spec/javascripts/sidebar/lock/edit_form_spec.js
+++ b/spec/javascripts/sidebar/lock/edit_form_spec.js
@@ -7,8 +7,8 @@ describe('EditForm', () => {
beforeEach(() => {
const Component = Vue.extend(editForm);
- const toggleForm = () => { };
- const updateLockedAttribute = () => { };
+ const toggleForm = () => {};
+ const updateLockedAttribute = () => {};
vm1 = new Component({
propsData: {
@@ -30,12 +30,8 @@ describe('EditForm', () => {
});
it('renders on the appropriate warning text', () => {
- expect(
- vm1.$el.innerHTML.includes('Unlock this issue?'),
- ).toBe(true);
+ expect(vm1.$el.innerHTML.includes('Unlock this issue?')).toBe(true);
- expect(
- vm2.$el.innerHTML.includes('Lock this merge request?'),
- ).toBe(true);
+ expect(vm2.$el.innerHTML.includes('Lock this merge request?')).toBe(true);
});
});
diff --git a/spec/javascripts/sidebar/lock/lock_issue_sidebar_spec.js b/spec/javascripts/sidebar/lock/lock_issue_sidebar_spec.js
index 9abc3daf221..ca882032bdf 100644
--- a/spec/javascripts/sidebar/lock/lock_issue_sidebar_spec.js
+++ b/spec/javascripts/sidebar/lock/lock_issue_sidebar_spec.js
@@ -38,20 +38,14 @@ describe('LockIssueSidebar', () => {
});
it('shows if locked and/or editable', () => {
- expect(
- vm1.$el.innerHTML.includes('Edit'),
- ).toBe(true);
+ expect(vm1.$el.innerHTML.includes('Edit')).toBe(true);
- expect(
- vm1.$el.innerHTML.includes('Locked'),
- ).toBe(true);
+ expect(vm1.$el.innerHTML.includes('Locked')).toBe(true);
- expect(
- vm2.$el.innerHTML.includes('Unlocked'),
- ).toBe(true);
+ expect(vm2.$el.innerHTML.includes('Unlocked')).toBe(true);
});
- it('displays the edit form when editable', (done) => {
+ it('displays the edit form when editable', done => {
expect(vm1.isLockDialogOpen).toBe(false);
vm1.$el.querySelector('.lock-edit').click();
@@ -59,17 +53,13 @@ describe('LockIssueSidebar', () => {
expect(vm1.isLockDialogOpen).toBe(true);
vm1.$nextTick(() => {
- expect(
- vm1.$el
- .innerHTML
- .includes('Unlock this issue?'),
- ).toBe(true);
+ expect(vm1.$el.innerHTML.includes('Unlock this issue?')).toBe(true);
done();
});
});
- it('displays the edit form when opened from collapsed state', (done) => {
+ it('displays the edit form when opened from collapsed state', done => {
expect(vm1.isLockDialogOpen).toBe(false);
vm1.$el.querySelector('.sidebar-collapsed-icon').click();
@@ -77,11 +67,7 @@ describe('LockIssueSidebar', () => {
expect(vm1.isLockDialogOpen).toBe(true);
setTimeout(() => {
- expect(
- vm1.$el
- .innerHTML
- .includes('Unlock this issue?'),
- ).toBe(true);
+ expect(vm1.$el.innerHTML.includes('Unlock this issue?')).toBe(true);
done();
});
diff --git a/spec/javascripts/sidebar/participants_spec.js b/spec/javascripts/sidebar/participants_spec.js
index e796ddee62f..eb360fd256a 100644
--- a/spec/javascripts/sidebar/participants_spec.js
+++ b/spec/javascripts/sidebar/participants_spec.js
@@ -11,13 +11,9 @@ const PARTICIPANT = {
avatar_url: 'gravatar.com/avatar/xxx',
};
-const PARTICIPANT_LIST = [
- PARTICIPANT,
- { ...PARTICIPANT, id: 2 },
- { ...PARTICIPANT, id: 3 },
-];
+const PARTICIPANT_LIST = [PARTICIPANT, { ...PARTICIPANT, id: 2 }, { ...PARTICIPANT, id: 3 }];
-describe('Participants', function () {
+describe('Participants', function() {
let vm;
let Participants;
@@ -69,7 +65,7 @@ describe('Participants', function () {
expect(vm.$el.querySelector('.js-participants-expanded-loading-icon')).toBeDefined();
});
- it('when only showing visible participants, shows an avatar only for each participant under the limit', (done) => {
+ it('when only showing visible participants, shows an avatar only for each participant under the limit', done => {
const numberOfLessParticipants = 2;
vm = mountComponent(Participants, {
loading: false,
@@ -88,7 +84,7 @@ describe('Participants', function () {
.catch(done.fail);
});
- it('when only showing all participants, each has an avatar', (done) => {
+ it('when only showing all participants, each has an avatar', done => {
const numberOfLessParticipants = 2;
vm = mountComponent(Participants, {
loading: false,
@@ -120,7 +116,7 @@ describe('Participants', function () {
expect(moreParticipantLink).toBeNull();
});
- it('when too many participants, has more participants link to show more', (done) => {
+ it('when too many participants, has more participants link to show more', done => {
vm = mountComponent(Participants, {
loading: false,
participants: PARTICIPANT_LIST,
@@ -138,7 +134,7 @@ describe('Participants', function () {
.catch(done.fail);
});
- it('when too many participants and already showing them, has more participants link to show less', (done) => {
+ it('when too many participants and already showing them, has more participants link to show less', done => {
vm = mountComponent(Participants, {
loading: false,
participants: PARTICIPANT_LIST,
@@ -182,6 +178,7 @@ describe('Participants', function () {
const participantsIconEl = vm.$el.querySelector('.sidebar-collapsed-icon');
participantsIconEl.click();
+
expect(vm.$emit).toHaveBeenCalledWith('toggleSidebar');
});
});
diff --git a/spec/javascripts/sidebar/sidebar_assignees_spec.js b/spec/javascripts/sidebar/sidebar_assignees_spec.js
index ebaaa6e806b..3f0f67d71ca 100644
--- a/spec/javascripts/sidebar/sidebar_assignees_spec.js
+++ b/spec/javascripts/sidebar/sidebar_assignees_spec.js
@@ -24,10 +24,14 @@ describe('sidebar assignees', () => {
const SidebarAssigneeComponent = Vue.extend(SidebarAssignees);
sidebarAssigneesEl = document.querySelector('#js-vue-sidebar-assignees');
- vm = mountComponent(SidebarAssigneeComponent, {
- mediator,
- field: sidebarAssigneesEl.dataset.field,
- }, sidebarAssigneesEl);
+ vm = mountComponent(
+ SidebarAssigneeComponent,
+ {
+ mediator,
+ field: sidebarAssigneesEl.dataset.field,
+ },
+ sidebarAssigneesEl,
+ );
});
afterEach(() => {
@@ -39,6 +43,7 @@ describe('sidebar assignees', () => {
it('calls the mediator when saves the assignees', () => {
vm.saveAssignees();
+
expect(mediator.saveAssignees).toHaveBeenCalled();
});
@@ -49,8 +54,9 @@ describe('sidebar assignees', () => {
expect(mediator.store.assignees.length).toEqual(1);
});
- it('hides assignees until fetched', (done) => {
+ it('hides assignees until fetched', done => {
const currentAssignee = sidebarAssigneesEl.querySelector('.value');
+
expect(currentAssignee).toBe(null);
vm.store.isFetching.assignees = false;
diff --git a/spec/javascripts/sidebar/sidebar_mediator_spec.js b/spec/javascripts/sidebar/sidebar_mediator_spec.js
index da950258a94..2d853970fc4 100644
--- a/spec/javascripts/sidebar/sidebar_mediator_spec.js
+++ b/spec/javascripts/sidebar/sidebar_mediator_spec.js
@@ -25,20 +25,23 @@ describe('Sidebar mediator', function() {
expect(this.mediator.store.assignees[0]).toEqual(Mock.mediator.currentUser);
});
- it('saves assignees', (done) => {
- this.mediator.saveAssignees('issue[assignee_ids]')
- .then((resp) => {
+ it('saves assignees', done => {
+ this.mediator
+ .saveAssignees('issue[assignee_ids]')
+ .then(resp => {
expect(resp.status).toEqual(200);
done();
})
.catch(done.fail);
});
- it('fetches the data', (done) => {
- const mockData = Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar'];
+ it('fetches the data', done => {
+ const mockData =
+ Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar'];
spyOn(this.mediator, 'processFetchedData').and.callThrough();
- this.mediator.fetch()
+ this.mediator
+ .fetch()
.then(() => {
expect(this.mediator.processFetchedData).toHaveBeenCalledWith(mockData);
})
@@ -47,7 +50,8 @@ describe('Sidebar mediator', function() {
});
it('processes fetched data', () => {
- const mockData = Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar'];
+ const mockData =
+ Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar'];
this.mediator.processFetchedData(mockData);
expect(this.mediator.store.assignees).toEqual(mockData.assignees);
@@ -68,12 +72,13 @@ describe('Sidebar mediator', function() {
expect(this.mediator.store.setMoveToProjectId).toHaveBeenCalledWith(projectId);
});
- it('fetches autocomplete projects', (done) => {
+ it('fetches autocomplete projects', done => {
const searchTerm = 'foo';
spyOn(this.mediator.service, 'getProjectsAutocomplete').and.callThrough();
spyOn(this.mediator.store, 'setAutocompleteProjects').and.callThrough();
- this.mediator.fetchAutocompleteProjects(searchTerm)
+ this.mediator
+ .fetchAutocompleteProjects(searchTerm)
.then(() => {
expect(this.mediator.service.getProjectsAutocomplete).toHaveBeenCalledWith(searchTerm);
expect(this.mediator.store.setAutocompleteProjects).toHaveBeenCalled();
@@ -82,13 +87,14 @@ describe('Sidebar mediator', function() {
.catch(done.fail);
});
- it('moves issue', (done) => {
+ it('moves issue', done => {
const moveToProjectId = 7;
this.mediator.store.setMoveToProjectId(moveToProjectId);
spyOn(this.mediator.service, 'moveIssue').and.callThrough();
const visitUrl = spyOnDependency(SidebarMediator, 'visitUrl');
- this.mediator.moveIssue()
+ this.mediator
+ .moveIssue()
.then(() => {
expect(this.mediator.service.moveIssue).toHaveBeenCalledWith(moveToProjectId);
expect(visitUrl).toHaveBeenCalledWith('/root/some-project/issues/5');
@@ -97,11 +103,12 @@ describe('Sidebar mediator', function() {
.catch(done.fail);
});
- it('toggle subscription', (done) => {
+ it('toggle subscription', done => {
this.mediator.store.setSubscribedState(false);
spyOn(this.mediator.service, 'toggleSubscription').and.callThrough();
- this.mediator.toggleSubscription()
+ this.mediator
+ .toggleSubscription()
.then(() => {
expect(this.mediator.service.toggleSubscription).toHaveBeenCalled();
expect(this.mediator.store.subscribed).toEqual(true);
diff --git a/spec/javascripts/sidebar/sidebar_move_issue_spec.js b/spec/javascripts/sidebar/sidebar_move_issue_spec.js
index 8f35b9ca437..230e0a933a9 100644
--- a/spec/javascripts/sidebar/sidebar_move_issue_spec.js
+++ b/spec/javascripts/sidebar/sidebar_move_issue_spec.js
@@ -7,7 +7,7 @@ import SidebarService from '~/sidebar/services/sidebar_service';
import SidebarMoveIssue from '~/sidebar/lib/sidebar_move_issue';
import Mock from './mock_data';
-describe('SidebarMoveIssue', function () {
+describe('SidebarMoveIssue', function() {
beforeEach(() => {
Vue.http.interceptors.push(Mock.sidebarMockInterceptor);
this.mediator = new SidebarMediator(Mock.mediator);
@@ -72,11 +72,13 @@ describe('SidebarMoveIssue', function () {
expect($.fn.glDropdown).toHaveBeenCalled();
});
- it('escapes html from project name', (done) => {
+ it('escapes html from project name', done => {
this.$toggleButton.dropdown('toggle');
setTimeout(() => {
- expect(this.$content.find('.js-move-issue-dropdown-item')[1].innerHTML.trim()).toEqual('&lt;img src=x onerror=alert(document.domain)&gt; foo / bar');
+ expect(this.$content.find('.js-move-issue-dropdown-item')[1].innerHTML.trim()).toEqual(
+ '&lt;img src=x onerror=alert(document.domain)&gt; foo / bar',
+ );
done();
});
});
@@ -94,7 +96,7 @@ describe('SidebarMoveIssue', function () {
expect(this.$confirmButton.hasClass('is-loading')).toBe(true);
});
- it('should remove loading state from confirm button on failure', (done) => {
+ it('should remove loading state from confirm button on failure', done => {
spyOn(window, 'Flash');
spyOn(this.mediator, 'moveIssue').and.returnValue(Promise.reject());
this.mediator.setMoveToProjectId(7);
@@ -121,7 +123,7 @@ describe('SidebarMoveIssue', function () {
});
});
- it('should set moveToProjectId on dropdown item "No project" click', (done) => {
+ it('should set moveToProjectId on dropdown item "No project" click', done => {
spyOn(this.mediator, 'setMoveToProjectId');
// Open the dropdown
@@ -129,7 +131,10 @@ describe('SidebarMoveIssue', function () {
// Wait for the autocomplete request to finish
setTimeout(() => {
- this.$content.find('.js-move-issue-dropdown-item').eq(0).trigger('click');
+ this.$content
+ .find('.js-move-issue-dropdown-item')
+ .eq(0)
+ .trigger('click');
expect(this.mediator.setMoveToProjectId).toHaveBeenCalledWith(0);
expect(this.$confirmButton.prop('disabled')).toBeTruthy();
@@ -137,7 +142,7 @@ describe('SidebarMoveIssue', function () {
}, 0);
});
- it('should set moveToProjectId on dropdown item click', (done) => {
+ it('should set moveToProjectId on dropdown item click', done => {
spyOn(this.mediator, 'setMoveToProjectId');
// Open the dropdown
@@ -145,7 +150,10 @@ describe('SidebarMoveIssue', function () {
// Wait for the autocomplete request to finish
setTimeout(() => {
- this.$content.find('.js-move-issue-dropdown-item').eq(1).trigger('click');
+ this.$content
+ .find('.js-move-issue-dropdown-item')
+ .eq(1)
+ .trigger('click');
expect(this.mediator.setMoveToProjectId).toHaveBeenCalledWith(20);
expect(this.$confirmButton.attr('disabled')).toBe(undefined);
diff --git a/spec/javascripts/sidebar/sidebar_store_spec.js b/spec/javascripts/sidebar/sidebar_store_spec.js
index 08b112a54ba..85ff70fffbd 100644
--- a/spec/javascripts/sidebar/sidebar_store_spec.js
+++ b/spec/javascripts/sidebar/sidebar_store_spec.js
@@ -25,20 +25,17 @@ const PARTICIPANT = {
avatar_url: 'gravatar.com/avatar/xxx',
};
-const PARTICIPANT_LIST = [
- PARTICIPANT,
- { ...PARTICIPANT, id: 2 },
- { ...PARTICIPANT, id: 3 },
-];
+const PARTICIPANT_LIST = [PARTICIPANT, { ...PARTICIPANT, id: 2 }, { ...PARTICIPANT, id: 3 }];
-describe('Sidebar store', function () {
+describe('Sidebar store', function() {
beforeEach(() => {
this.store = new SidebarStore({
currentUser: {
id: 1,
name: 'Administrator',
username: 'root',
- avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ avatar_url:
+ 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
},
editable: true,
rootPath: '/',
@@ -56,11 +53,13 @@ describe('Sidebar store', function () {
it('adds a new assignee', () => {
this.store.addAssignee(ASSIGNEE);
+
expect(this.store.assignees.length).toEqual(1);
});
it('removes an assignee', () => {
this.store.removeAssignee(ASSIGNEE);
+
expect(this.store.assignees.length).toEqual(0);
});
@@ -69,14 +68,17 @@ describe('Sidebar store', function () {
this.store.addAssignee(ASSIGNEE);
foundAssignee = this.store.findAssignee(ASSIGNEE);
+
expect(foundAssignee).toBeDefined();
expect(foundAssignee).toEqual(ASSIGNEE);
foundAssignee = this.store.findAssignee(ANOTHER_ASSINEE);
+
expect(foundAssignee).toBeUndefined();
});
it('removes all assignees', () => {
this.store.removeAllAssignees();
+
expect(this.store.assignees.length).toEqual(0);
});
@@ -108,6 +110,7 @@ describe('Sidebar store', function () {
};
this.store.setAssigneeData(users);
+
expect(this.store.isFetching.assignees).toBe(false);
expect(this.store.assignees.length).toEqual(3);
});
@@ -128,6 +131,7 @@ describe('Sidebar store', function () {
it('set time tracking data', () => {
this.store.setTimeTrackingData(Mock.time);
+
expect(this.store.timeEstimate).toEqual(Mock.time.time_estimate);
expect(this.store.totalTimeSpent).toEqual(Mock.time.total_time_spent);
expect(this.store.humanTimeEstimate).toEqual(Mock.time.human_time_estimate);
diff --git a/spec/javascripts/sidebar/sidebar_subscriptions_spec.js b/spec/javascripts/sidebar/sidebar_subscriptions_spec.js
index af2fde0a5be..88f64244237 100644
--- a/spec/javascripts/sidebar/sidebar_subscriptions_spec.js
+++ b/spec/javascripts/sidebar/sidebar_subscriptions_spec.js
@@ -6,7 +6,7 @@ import SidebarStore from '~/sidebar/stores/sidebar_store';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
import Mock from './mock_data';
-describe('Sidebar Subscriptions', function () {
+describe('Sidebar Subscriptions', function() {
let vm;
let SidebarSubscriptions;
diff --git a/spec/javascripts/sidebar/subscriptions_spec.js b/spec/javascripts/sidebar/subscriptions_spec.js
index f0a53e573c3..32728e58b06 100644
--- a/spec/javascripts/sidebar/subscriptions_spec.js
+++ b/spec/javascripts/sidebar/subscriptions_spec.js
@@ -3,7 +3,7 @@ import subscriptions from '~/sidebar/components/subscriptions/subscriptions.vue'
import eventHub from '~/sidebar/event_hub';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
-describe('Subscriptions', function () {
+describe('Subscriptions', function() {
let vm;
let Subscriptions;
@@ -22,7 +22,9 @@ describe('Subscriptions', function () {
});
expect(vm.$refs.toggleButton.isLoading).toBe(true);
- expect(vm.$refs.toggleButton.$el.querySelector('.project-feature-toggle')).toHaveClass('is-loading');
+ expect(vm.$refs.toggleButton.$el.querySelector('.project-feature-toggle')).toHaveClass(
+ 'is-loading',
+ );
});
it('is toggled "off" when currently not subscribed', () => {
@@ -30,7 +32,9 @@ describe('Subscriptions', function () {
subscribed: false,
});
- expect(vm.$refs.toggleButton.$el.querySelector('.project-feature-toggle')).not.toHaveClass('is-checked');
+ expect(vm.$refs.toggleButton.$el.querySelector('.project-feature-toggle')).not.toHaveClass(
+ 'is-checked',
+ );
});
it('is toggled "on" when currently subscribed', () => {
@@ -38,7 +42,9 @@ describe('Subscriptions', function () {
subscribed: true,
});
- expect(vm.$refs.toggleButton.$el.querySelector('.project-feature-toggle')).toHaveClass('is-checked');
+ expect(vm.$refs.toggleButton.$el.querySelector('.project-feature-toggle')).toHaveClass(
+ 'is-checked',
+ );
});
it('toggleSubscription method emits `toggleSubscription` event on eventHub and Component', () => {
@@ -47,6 +53,7 @@ describe('Subscriptions', function () {
spyOn(vm, '$emit');
vm.toggleSubscription();
+
expect(eventHub.$emit).toHaveBeenCalledWith('toggleSubscription', jasmine.any(Object));
expect(vm.$emit).toHaveBeenCalledWith('toggleSubscription', jasmine.any(Object));
});
@@ -56,6 +63,7 @@ describe('Subscriptions', function () {
spyOn(vm, '$emit');
vm.onClickCollapsedIcon();
+
expect(vm.$emit).toHaveBeenCalledWith('toggleSidebar');
});
});
diff --git a/spec/javascripts/sidebar/todo_spec.js b/spec/javascripts/sidebar/todo_spec.js
index a929b804a29..657e88ecb96 100644
--- a/spec/javascripts/sidebar/todo_spec.js
+++ b/spec/javascripts/sidebar/todo_spec.js
@@ -42,7 +42,9 @@ describe('SidebarTodo', () => {
vm.collapsed = true;
Vue.nextTick()
.then(() => {
- expect(vm.buttonClasses).toBe('btn-blank btn-todo sidebar-collapsed-icon dont-change-state');
+ expect(vm.buttonClasses).toBe(
+ 'btn-blank btn-todo sidebar-collapsed-icon dont-change-state',
+ );
})
.then(done)
.catch(done.fail);
@@ -103,6 +105,7 @@ describe('SidebarTodo', () => {
it('emits `toggleTodo` event on component', () => {
spyOn(vm, '$emit');
vm.handleButtonClick();
+
expect(vm.$emit).toHaveBeenCalledWith('toggleTodo');
});
});
@@ -118,16 +121,18 @@ describe('SidebarTodo', () => {
container: 'body',
boundary: 'viewport',
};
+
expect(vm.$el.nodeName).toBe('BUTTON');
const elDataAttrs = vm.$el.dataset;
- Object.keys(elDataAttrs).forEach((attr) => {
+ Object.keys(elDataAttrs).forEach(attr => {
expect(elDataAttrs[attr]).toBe(dataAttributes[attr]);
});
});
it('renders button label element when `collapsed` prop is `false`', () => {
const buttonLabelEl = vm.$el.querySelector('span.issuable-todo-inner');
+
expect(buttonLabelEl).not.toBeNull();
expect(buttonLabelEl.innerText.trim()).toBe('Mark todo as done');
});
@@ -137,8 +142,11 @@ describe('SidebarTodo', () => {
Vue.nextTick()
.then(() => {
const buttonIconEl = vm.$el.querySelector('svg');
+
expect(buttonIconEl).not.toBeNull();
- expect(buttonIconEl.querySelector('use').getAttribute('xlink:href')).toContain('todo-done');
+ expect(buttonIconEl.querySelector('use').getAttribute('xlink:href')).toContain(
+ 'todo-done',
+ );
})
.then(done)
.catch(done.fail);
@@ -149,6 +157,7 @@ describe('SidebarTodo', () => {
Vue.nextTick()
.then(() => {
const loadingEl = vm.$el.querySelector('span.loading-container');
+
expect(loadingEl).not.toBeNull();
})
.then(done)
diff --git a/spec/javascripts/signin_tabs_memoizer_spec.js b/spec/javascripts/signin_tabs_memoizer_spec.js
index 9d3905fa1d8..b688a299052 100644
--- a/spec/javascripts/signin_tabs_memoizer_spec.js
+++ b/spec/javascripts/signin_tabs_memoizer_spec.js
@@ -1,164 +1,170 @@
import AccessorUtilities from '~/lib/utils/accessor';
import SigninTabsMemoizer from '~/pages/sessions/new/signin_tabs_memoizer';
-(() => {
- describe('SigninTabsMemoizer', () => {
- const fixtureTemplate = 'static/signin_tabs.html.raw';
- const tabSelector = 'ul.new-session-tabs';
- const currentTabKey = 'current_signin_tab';
- let memo;
-
- function createMemoizer() {
- memo = new SigninTabsMemoizer({
- currentTabKey,
- tabSelector,
- });
- return memo;
- }
+describe('SigninTabsMemoizer', () => {
+ const fixtureTemplate = 'static/signin_tabs.html.raw';
+ const tabSelector = 'ul.new-session-tabs';
+ const currentTabKey = 'current_signin_tab';
+ let memo;
+
+ function createMemoizer() {
+ memo = new SigninTabsMemoizer({
+ currentTabKey,
+ tabSelector,
+ });
+ return memo;
+ }
- preloadFixtures(fixtureTemplate);
+ preloadFixtures(fixtureTemplate);
- beforeEach(() => {
- loadFixtures(fixtureTemplate);
+ beforeEach(() => {
+ loadFixtures(fixtureTemplate);
- spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').and.returnValue(true);
- });
+ spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').and.returnValue(true);
+ });
- it('does nothing if no tab was previously selected', () => {
- createMemoizer();
+ it('does nothing if no tab was previously selected', () => {
+ createMemoizer();
- expect(document.querySelector(`${tabSelector} > li.active a`).getAttribute('href')).toEqual('#ldap');
- });
+ expect(document.querySelector(`${tabSelector} > li.active a`).getAttribute('href')).toEqual(
+ '#ldap',
+ );
+ });
- it('shows last selected tab on boot', () => {
- createMemoizer().saveData('#ldap');
- const fakeTab = {
- click: () => {},
- };
- spyOn(document, 'querySelector').and.returnValue(fakeTab);
- spyOn(fakeTab, 'click');
+ it('shows last selected tab on boot', () => {
+ createMemoizer().saveData('#ldap');
+ const fakeTab = {
+ click: () => {},
+ };
+ spyOn(document, 'querySelector').and.returnValue(fakeTab);
+ spyOn(fakeTab, 'click');
- memo.bootstrap();
+ memo.bootstrap();
- // verify that triggers click on the last selected tab
- expect(document.querySelector).toHaveBeenCalledWith(`${tabSelector} a[href="#ldap"]`);
- expect(fakeTab.click).toHaveBeenCalled();
- });
+ // verify that triggers click on the last selected tab
+ expect(document.querySelector).toHaveBeenCalledWith(`${tabSelector} a[href="#ldap"]`);
+ expect(fakeTab.click).toHaveBeenCalled();
+ });
- it('clicks the first tab if value in local storage is bad', () => {
- createMemoizer().saveData('#bogus');
- const fakeTab = {
- click: () => {},
- };
- spyOn(document, 'querySelector').and.callFake(selector => (selector === `${tabSelector} a[href="#bogus"]` ? null : fakeTab));
- spyOn(fakeTab, 'click');
+ it('clicks the first tab if value in local storage is bad', () => {
+ createMemoizer().saveData('#bogus');
+ const fakeTab = {
+ click: () => {},
+ };
+ spyOn(document, 'querySelector').and.callFake(
+ selector => (selector === `${tabSelector} a[href="#bogus"]` ? null : fakeTab),
+ );
+ spyOn(fakeTab, 'click');
+
+ memo.bootstrap();
+
+ // verify that triggers click on stored selector and fallback
+ expect(document.querySelector.calls.allArgs()).toEqual([
+ ['ul.new-session-tabs a[href="#bogus"]'],
+ ['ul.new-session-tabs a'],
+ ]);
+
+ expect(fakeTab.click).toHaveBeenCalled();
+ });
- memo.bootstrap();
+ it('saves last selected tab on change', () => {
+ createMemoizer();
- // verify that triggers click on stored selector and fallback
- expect(document.querySelector.calls.allArgs()).toEqual([['ul.new-session-tabs a[href="#bogus"]'], ['ul.new-session-tabs a']]);
- expect(fakeTab.click).toHaveBeenCalled();
- });
+ document.querySelector('a[href="#login-pane"]').click();
- it('saves last selected tab on change', () => {
- createMemoizer();
+ expect(memo.readData()).toEqual('#login-pane');
+ });
- document.querySelector('a[href="#login-pane"]').click();
+ it('overrides last selected tab with hash tag when given', () => {
+ window.location.hash = '#ldap';
+ createMemoizer();
- expect(memo.readData()).toEqual('#login-pane');
- });
+ expect(memo.readData()).toEqual('#ldap');
+ });
- it('overrides last selected tab with hash tag when given', () => {
- window.location.hash = '#ldap';
- createMemoizer();
+ describe('class constructor', () => {
+ beforeEach(() => {
+ memo = createMemoizer();
+ });
- expect(memo.readData()).toEqual('#ldap');
+ it('should set .isLocalStorageAvailable', () => {
+ expect(AccessorUtilities.isLocalStorageAccessSafe).toHaveBeenCalled();
+ expect(memo.isLocalStorageAvailable).toBe(true);
});
+ });
- describe('class constructor', () => {
- beforeEach(() => {
- memo = createMemoizer();
- });
+ describe('saveData', () => {
+ beforeEach(() => {
+ memo = {
+ currentTabKey,
+ };
- it('should set .isLocalStorageAvailable', () => {
- expect(AccessorUtilities.isLocalStorageAccessSafe).toHaveBeenCalled();
- expect(memo.isLocalStorageAvailable).toBe(true);
- });
+ spyOn(localStorage, 'setItem');
});
- describe('saveData', () => {
- beforeEach(() => {
- memo = {
- currentTabKey,
- };
+ describe('if .isLocalStorageAvailable is `false`', () => {
+ beforeEach(function() {
+ memo.isLocalStorageAvailable = false;
- spyOn(localStorage, 'setItem');
+ SigninTabsMemoizer.prototype.saveData.call(memo);
});
- describe('if .isLocalStorageAvailable is `false`', () => {
- beforeEach(function () {
- memo.isLocalStorageAvailable = false;
-
- SigninTabsMemoizer.prototype.saveData.call(memo);
- });
-
- it('should not call .setItem', () => {
- expect(localStorage.setItem).not.toHaveBeenCalled();
- });
+ it('should not call .setItem', () => {
+ expect(localStorage.setItem).not.toHaveBeenCalled();
});
+ });
- describe('if .isLocalStorageAvailable is `true`', () => {
- const value = 'value';
+ describe('if .isLocalStorageAvailable is `true`', () => {
+ const value = 'value';
- beforeEach(function () {
- memo.isLocalStorageAvailable = true;
+ beforeEach(function() {
+ memo.isLocalStorageAvailable = true;
- SigninTabsMemoizer.prototype.saveData.call(memo, value);
- });
+ SigninTabsMemoizer.prototype.saveData.call(memo, value);
+ });
- it('should call .setItem', () => {
- expect(localStorage.setItem).toHaveBeenCalledWith(currentTabKey, value);
- });
+ it('should call .setItem', () => {
+ expect(localStorage.setItem).toHaveBeenCalledWith(currentTabKey, value);
});
});
+ });
- describe('readData', () => {
- const itemValue = 'itemValue';
- let readData;
+ describe('readData', () => {
+ const itemValue = 'itemValue';
+ let readData;
- beforeEach(() => {
- memo = {
- currentTabKey,
- };
+ beforeEach(() => {
+ memo = {
+ currentTabKey,
+ };
- spyOn(localStorage, 'getItem').and.returnValue(itemValue);
- });
+ spyOn(localStorage, 'getItem').and.returnValue(itemValue);
+ });
- describe('if .isLocalStorageAvailable is `false`', () => {
- beforeEach(function () {
- memo.isLocalStorageAvailable = false;
+ describe('if .isLocalStorageAvailable is `false`', () => {
+ beforeEach(function() {
+ memo.isLocalStorageAvailable = false;
- readData = SigninTabsMemoizer.prototype.readData.call(memo);
- });
+ readData = SigninTabsMemoizer.prototype.readData.call(memo);
+ });
- it('should not call .getItem and should return `null`', () => {
- expect(localStorage.getItem).not.toHaveBeenCalled();
- expect(readData).toBe(null);
- });
+ it('should not call .getItem and should return `null`', () => {
+ expect(localStorage.getItem).not.toHaveBeenCalled();
+ expect(readData).toBe(null);
});
+ });
- describe('if .isLocalStorageAvailable is `true`', () => {
- beforeEach(function () {
- memo.isLocalStorageAvailable = true;
+ describe('if .isLocalStorageAvailable is `true`', () => {
+ beforeEach(function() {
+ memo.isLocalStorageAvailable = true;
- readData = SigninTabsMemoizer.prototype.readData.call(memo);
- });
+ readData = SigninTabsMemoizer.prototype.readData.call(memo);
+ });
- it('should call .getItem and return the localStorage value', () => {
- expect(window.localStorage.getItem).toHaveBeenCalledWith(currentTabKey);
- expect(readData).toBe(itemValue);
- });
+ it('should call .getItem and return the localStorage value', () => {
+ expect(window.localStorage.getItem).toHaveBeenCalledWith(currentTabKey);
+ expect(readData).toBe(itemValue);
});
});
});
-})();
+});
diff --git a/spec/javascripts/smart_interval_spec.js b/spec/javascripts/smart_interval_spec.js
index d9b6dd1d487..c2c2a965e1d 100644
--- a/spec/javascripts/smart_interval_spec.js
+++ b/spec/javascripts/smart_interval_spec.js
@@ -3,7 +3,7 @@ import _ from 'underscore';
import SmartInterval from '~/smart_interval';
import waitForPromises from 'spec/helpers/wait_for_promises';
-describe('SmartInterval', function () {
+describe('SmartInterval', function() {
const DEFAULT_MAX_INTERVAL = 100;
const DEFAULT_STARTING_INTERVAL = 5;
const DEFAULT_SHORT_TIMEOUT = 75;
@@ -35,8 +35,8 @@ describe('SmartInterval', function () {
jasmine.clock().uninstall();
});
- describe('Increment Interval', function () {
- it('should increment the interval delay', (done) => {
+ describe('Increment Interval', function() {
+ it('should increment the interval delay', done => {
const smartInterval = createDefaultSmartInterval();
jasmine.clock().tick(DEFAULT_SHORT_TIMEOUT);
@@ -45,8 +45,8 @@ describe('SmartInterval', function () {
.then(() => {
const intervalConfig = smartInterval.cfg;
const iterationCount = 4;
- const maxIntervalAfterIterations = intervalConfig.startingInterval *
- (intervalConfig.incrementByFactorOf ** iterationCount);
+ const maxIntervalAfterIterations =
+ intervalConfig.startingInterval * intervalConfig.incrementByFactorOf ** iterationCount;
const currentInterval = smartInterval.getCurrentInterval();
// Provide some flexibility for performance of testing environment
@@ -57,7 +57,7 @@ describe('SmartInterval', function () {
.catch(done.fail);
});
- it('should not increment past maxInterval', (done) => {
+ it('should not increment past maxInterval', done => {
const smartInterval = createDefaultSmartInterval({ maxInterval: DEFAULT_STARTING_INTERVAL });
jasmine.clock().tick(DEFAULT_STARTING_INTERVAL);
@@ -66,6 +66,7 @@ describe('SmartInterval', function () {
waitForPromises()
.then(() => {
const currentInterval = smartInterval.getCurrentInterval();
+
expect(currentInterval).toBe(smartInterval.cfg.maxInterval);
})
.then(done)
@@ -82,6 +83,7 @@ describe('SmartInterval', function () {
waitForPromises()
.then(() => {
const oneInterval = smartInterval.cfg.startingInterval * DEFAULT_INCREMENT_FACTOR;
+
expect(smartInterval.getCurrentInterval()).toEqual(oneInterval);
})
.then(done)
@@ -89,12 +91,12 @@ describe('SmartInterval', function () {
});
});
- describe('Public methods', function () {
- beforeEach(function () {
+ describe('Public methods', function() {
+ beforeEach(function() {
this.smartInterval = createDefaultSmartInterval();
});
- it('should cancel an interval', function (done) {
+ it('should cancel an interval', function(done) {
const interval = this.smartInterval;
jasmine.clock().tick(DEFAULT_SHORT_TIMEOUT);
@@ -114,7 +116,7 @@ describe('SmartInterval', function () {
.catch(done.fail);
});
- it('should resume an interval', function (done) {
+ it('should resume an interval', function(done) {
const interval = this.smartInterval;
jasmine.clock().tick(DEFAULT_SHORT_TIMEOUT);
@@ -126,6 +128,7 @@ describe('SmartInterval', function () {
waitForPromises()
.then(() => {
const { intervalId } = interval.state;
+
expect(intervalId).toBeTruthy();
})
.then(done)
@@ -133,15 +136,15 @@ describe('SmartInterval', function () {
});
});
- describe('DOM Events', function () {
- beforeEach(function () {
+ describe('DOM Events', function() {
+ beforeEach(function() {
// This ensures DOM and DOM events are initialized for these specs.
setFixtures('<div></div>');
this.smartInterval = createDefaultSmartInterval();
});
- it('should pause when page is not visible', function (done) {
+ it('should pause when page is not visible', function(done) {
const interval = this.smartInterval;
jasmine.clock().tick(DEFAULT_SHORT_TIMEOUT);
@@ -168,8 +171,10 @@ describe('SmartInterval', function () {
waitForPromises()
.then(() => {
expect(interval.state.intervalId).toBeTruthy();
- expect(interval.getCurrentInterval() >= DEFAULT_STARTING_INTERVAL &&
- interval.getCurrentInterval() <= DEFAULT_MAX_INTERVAL).toBeTruthy();
+ expect(
+ interval.getCurrentInterval() >= DEFAULT_STARTING_INTERVAL &&
+ interval.getCurrentInterval() <= DEFAULT_MAX_INTERVAL,
+ ).toBeTruthy();
// simulates triggering of visibilitychange event
interval.handleVisibilityChange({ target: { visibilityState: 'hidden' } });
@@ -181,7 +186,7 @@ describe('SmartInterval', function () {
.catch(done.fail);
});
- it('should resume when page is becomes visible at the previous interval', function (done) {
+ it('should resume when page is becomes visible at the previous interval', function(done) {
const interval = this.smartInterval;
jasmine.clock().tick(DEFAULT_SHORT_TIMEOUT);
@@ -204,7 +209,7 @@ describe('SmartInterval', function () {
.catch(done.fail);
});
- it('should cancel on page unload', function (done) {
+ it('should cancel on page unload', function(done) {
const interval = this.smartInterval;
jasmine.clock().tick(DEFAULT_SHORT_TIMEOUT);
@@ -212,6 +217,7 @@ describe('SmartInterval', function () {
waitForPromises()
.then(() => {
$(document).triggerHandler('beforeunload');
+
expect(interval.state.intervalId).toBeUndefined();
expect(interval.getCurrentInterval()).toBe(interval.cfg.startingInterval);
})
@@ -219,8 +225,9 @@ describe('SmartInterval', function () {
.catch(done.fail);
});
- it('should execute callback before first interval', function () {
+ it('should execute callback before first interval', function() {
const interval = createDefaultSmartInterval({ immediateExecution: true });
+
expect(interval.cfg.immediateExecution).toBeFalsy();
});
});
diff --git a/spec/javascripts/syntax_highlight_spec.js b/spec/javascripts/syntax_highlight_spec.js
index af3a5d58ba7..5438368ccbe 100644
--- a/spec/javascripts/syntax_highlight_spec.js
+++ b/spec/javascripts/syntax_highlight_spec.js
@@ -9,35 +9,44 @@ describe('Syntax Highlighter', function() {
if (window.gon == null) {
window.gon = {};
}
- return window.gon.user_color_scheme = value;
+ return (window.gon.user_color_scheme = value);
};
describe('on a js-syntax-highlight element', function() {
beforeEach(function() {
return setFixtures('<div class="js-syntax-highlight"></div>');
});
- return it('applies syntax highlighting', function() {
+
+ it('applies syntax highlighting', function() {
stubUserColorScheme('monokai');
syntaxHighlight($('.js-syntax-highlight'));
- return expect($('.js-syntax-highlight')).toHaveClass('monokai');
+
+ expect($('.js-syntax-highlight')).toHaveClass('monokai');
});
});
- return describe('on a parent element', function() {
+
+ describe('on a parent element', function() {
beforeEach(function() {
- return setFixtures("<div class=\"parent\">\n <div class=\"js-syntax-highlight\"></div>\n <div class=\"foo\"></div>\n <div class=\"js-syntax-highlight\"></div>\n</div>");
+ return setFixtures(
+ '<div class="parent">\n <div class="js-syntax-highlight"></div>\n <div class="foo"></div>\n <div class="js-syntax-highlight"></div>\n</div>',
+ );
});
+
it('applies highlighting to all applicable children', function() {
stubUserColorScheme('monokai');
syntaxHighlight($('.parent'));
+
expect($('.parent, .foo')).not.toHaveClass('monokai');
- return expect($('.monokai').length).toBe(2);
+ expect($('.monokai').length).toBe(2);
});
- return it('prevents an infinite loop when no matches exist', function() {
+
+ it('prevents an infinite loop when no matches exist', function() {
var highlight;
setFixtures('<div></div>');
highlight = function() {
return syntaxHighlight($('div'));
};
- return expect(highlight).not.toThrow();
+
+ expect(highlight).not.toThrow();
});
});
});
diff --git a/spec/javascripts/todos_spec.js b/spec/javascripts/todos_spec.js
index e74f4bdef7e..69e43274250 100644
--- a/spec/javascripts/todos_spec.js
+++ b/spec/javascripts/todos_spec.js
@@ -14,10 +14,10 @@ describe('Todos', () => {
});
describe('goToTodoUrl', () => {
- it('opens the todo url', (done) => {
+ it('opens the todo url', done => {
const todoLink = todoItem.dataset.url;
- spyOnDependency(Todos, 'visitUrl').and.callFake((url) => {
+ spyOnDependency(Todos, 'visitUrl').and.callFake(url => {
expect(url).toEqual(todoLink);
done();
});
diff --git a/spec/javascripts/toggle_buttons_spec.js b/spec/javascripts/toggle_buttons_spec.js
index 17d0b94ebe0..09756ff76ec 100644
--- a/spec/javascripts/toggle_buttons_spec.js
+++ b/spec/javascripts/toggle_buttons_spec.js
@@ -24,11 +24,14 @@ describe('ToggleButtons', () => {
it('should initialize as checked', () => {
const wrapper = setupFixture(true);
- expect(wrapper.querySelector('.js-project-feature-toggle').classList.contains('is-checked')).toEqual(true);
+ expect(
+ wrapper.querySelector('.js-project-feature-toggle').classList.contains('is-checked'),
+ ).toEqual(true);
+
expect(wrapper.querySelector('.js-project-feature-toggle-input').value).toEqual('true');
});
- it('should toggle to unchecked when clicked', (done) => {
+ it('should toggle to unchecked when clicked', done => {
const wrapper = setupFixture(true);
const toggleButton = wrapper.querySelector('.js-project-feature-toggle');
@@ -48,11 +51,14 @@ describe('ToggleButtons', () => {
it('should initialize as unchecked', () => {
const wrapper = setupFixture(false);
- expect(wrapper.querySelector('.js-project-feature-toggle').classList.contains('is-checked')).toEqual(false);
+ expect(
+ wrapper.querySelector('.js-project-feature-toggle').classList.contains('is-checked'),
+ ).toEqual(false);
+
expect(wrapper.querySelector('.js-project-feature-toggle-input').value).toEqual('false');
});
- it('should toggle to checked when clicked', (done) => {
+ it('should toggle to checked when clicked', done => {
const wrapper = setupFixture(false);
const toggleButton = wrapper.querySelector('.js-project-feature-toggle');
@@ -68,7 +74,7 @@ describe('ToggleButtons', () => {
});
});
- it('should emit `trigger-change` event', (done) => {
+ it('should emit `trigger-change` event', done => {
const changeSpy = jasmine.createSpy('changeEventHandler');
const wrapper = setupFixture(false);
const toggleButton = wrapper.querySelector('.js-project-feature-toggle');
@@ -87,7 +93,7 @@ describe('ToggleButtons', () => {
});
describe('clickCallback', () => {
- it('should show loading indicator while waiting', (done) => {
+ it('should show loading indicator while waiting', done => {
const isChecked = true;
const clickCallback = (newValue, toggleButton) => {
const input = toggleButton.querySelector('.js-project-feature-toggle-input');
diff --git a/spec/javascripts/u2f/authenticate_spec.js b/spec/javascripts/u2f/authenticate_spec.js
index 57e0caa692c..ddb09811dda 100644
--- a/spec/javascripts/u2f/authenticate_spec.js
+++ b/spec/javascripts/u2f/authenticate_spec.js
@@ -3,7 +3,7 @@ import U2FAuthenticate from '~/u2f/authenticate';
import 'vendor/u2f';
import MockU2FDevice from './mock_u2f_device';
-describe('U2FAuthenticate', function () {
+describe('U2FAuthenticate', function() {
preloadFixtures('u2f/authenticate.html.raw');
beforeEach(() => {
@@ -32,30 +32,40 @@ describe('U2FAuthenticate', function () {
window.u2f = this.oldu2f;
});
- it('falls back to normal 2fa', (done) => {
- this.component.start().then(() => {
- expect(this.component.switchToFallbackUI).toHaveBeenCalled();
- done();
- }).catch(done.fail);
+ it('falls back to normal 2fa', done => {
+ this.component
+ .start()
+ .then(() => {
+ expect(this.component.switchToFallbackUI).toHaveBeenCalled();
+ done();
+ })
+ .catch(done.fail);
});
});
describe('with u2f available', () => {
- beforeEach((done) => {
+ beforeEach(done => {
// bypass automatic form submission within renderAuthenticated
spyOn(this.component, 'renderAuthenticated').and.returnValue(true);
this.u2fDevice = new MockU2FDevice();
- this.component.start().then(done).catch(done.fail);
+ this.component
+ .start()
+ .then(done)
+ .catch(done.fail);
});
it('allows authenticating via a U2F device', () => {
const inProgressMessage = this.container.find('p');
+
expect(inProgressMessage.text()).toContain('Trying to communicate with your device');
this.u2fDevice.respondToAuthenticateRequest({
deviceData: 'this is data from the device',
});
- expect(this.component.renderAuthenticated).toHaveBeenCalledWith('{"deviceData":"this is data from the device"}');
+
+ expect(this.component.renderAuthenticated).toHaveBeenCalledWith(
+ '{"deviceData":"this is data from the device"}',
+ );
});
describe('errors', () => {
@@ -66,7 +76,8 @@ describe('U2FAuthenticate', function () {
errorCode: 'error!',
});
const errorMessage = this.container.find('p');
- return expect(errorMessage.text()).toContain('There was a problem communicating with your device');
+
+ expect(errorMessage.text()).toContain('There was a problem communicating with your device');
});
return it('allows retrying authentication after an error', () => {
let setupButton = this.container.find('#js-login-u2f-device');
@@ -81,7 +92,10 @@ describe('U2FAuthenticate', function () {
this.u2fDevice.respondToAuthenticateRequest({
deviceData: 'this is data from the device',
});
- expect(this.component.renderAuthenticated).toHaveBeenCalledWith('{"deviceData":"this is data from the device"}');
+
+ expect(this.component.renderAuthenticated).toHaveBeenCalledWith(
+ '{"deviceData":"this is data from the device"}',
+ );
});
});
});
diff --git a/spec/javascripts/u2f/mock_u2f_device.js b/spec/javascripts/u2f/mock_u2f_device.js
index a8692be3546..26ddd8ade61 100644
--- a/spec/javascripts/u2f/mock_u2f_device.js
+++ b/spec/javascripts/u2f/mock_u2f_device.js
@@ -5,14 +5,14 @@ export default class MockU2FDevice {
this.respondToAuthenticateRequest = this.respondToAuthenticateRequest.bind(this);
this.respondToRegisterRequest = this.respondToRegisterRequest.bind(this);
window.u2f || (window.u2f = {});
- window.u2f.register = (function (_this) {
- return function (appId, registerRequests, signRequests, callback) {
- return _this.registerCallback = callback;
+ window.u2f.register = (function(_this) {
+ return function(appId, registerRequests, signRequests, callback) {
+ return (_this.registerCallback = callback);
};
})(this);
- window.u2f.sign = (function (_this) {
- return function (appId, challenges, signRequests, callback) {
- return _this.authenticateCallback = callback;
+ window.u2f.sign = (function(_this) {
+ return function(appId, challenges, signRequests, callback) {
+ return (_this.authenticateCallback = callback);
};
})(this);
}
diff --git a/spec/javascripts/u2f/register_spec.js b/spec/javascripts/u2f/register_spec.js
index b774627651f..261db3d66d7 100644
--- a/spec/javascripts/u2f/register_spec.js
+++ b/spec/javascripts/u2f/register_spec.js
@@ -3,41 +3,48 @@ import U2FRegister from '~/u2f/register';
import 'vendor/u2f';
import MockU2FDevice from './mock_u2f_device';
-describe('U2FRegister', function () {
+describe('U2FRegister', function() {
preloadFixtures('u2f/register.html.raw');
- beforeEach((done) => {
+ beforeEach(done => {
loadFixtures('u2f/register.html.raw');
this.u2fDevice = new MockU2FDevice();
this.container = $('#js-register-u2f');
this.component = new U2FRegister(this.container, $('#js-register-u2f-templates'), {}, 'token');
- this.component.start().then(done).catch(done.fail);
+ this.component
+ .start()
+ .then(done)
+ .catch(done.fail);
});
it('allows registering a U2F device', () => {
const setupButton = this.container.find('#js-setup-u2f-device');
+
expect(setupButton.text()).toBe('Set up new U2F device');
setupButton.trigger('click');
const inProgressMessage = this.container.children('p');
+
expect(inProgressMessage.text()).toContain('Trying to communicate with your device');
this.u2fDevice.respondToRegisterRequest({
deviceData: 'this is data from the device',
});
const registeredMessage = this.container.find('p');
const deviceResponse = this.container.find('#js-device-response');
+
expect(registeredMessage.text()).toContain('Your device was successfully set up!');
- return expect(deviceResponse.val()).toBe('{"deviceData":"this is data from the device"}');
+ expect(deviceResponse.val()).toBe('{"deviceData":"this is data from the device"}');
});
- return describe('errors', () => {
- it('doesn\'t allow the same device to be registered twice (for the same user', () => {
+ describe('errors', () => {
+ it("doesn't allow the same device to be registered twice (for the same user", () => {
const setupButton = this.container.find('#js-setup-u2f-device');
setupButton.trigger('click');
this.u2fDevice.respondToRegisterRequest({
errorCode: 4,
});
const errorMessage = this.container.find('p');
- return expect(errorMessage.text()).toContain('already been registered with us');
+
+ expect(errorMessage.text()).toContain('already been registered with us');
});
it('displays an error message for other errors', () => {
@@ -47,10 +54,11 @@ describe('U2FRegister', function () {
errorCode: 'error!',
});
const errorMessage = this.container.find('p');
- return expect(errorMessage.text()).toContain('There was a problem communicating with your device');
+
+ expect(errorMessage.text()).toContain('There was a problem communicating with your device');
});
- return it('allows retrying registration after an error', () => {
+ it('allows retrying registration after an error', () => {
let setupButton = this.container.find('#js-setup-u2f-device');
setupButton.trigger('click');
this.u2fDevice.respondToRegisterRequest({
@@ -64,7 +72,8 @@ describe('U2FRegister', function () {
deviceData: 'this is data from the device',
});
const registeredMessage = this.container.find('p');
- return expect(registeredMessage.text()).toContain('Your device was successfully set up!');
+
+ expect(registeredMessage.text()).toContain('Your device was successfully set up!');
});
});
});
diff --git a/spec/javascripts/u2f/util_spec.js b/spec/javascripts/u2f/util_spec.js
index 4187183236f..32cd6891384 100644
--- a/spec/javascripts/u2f/util_spec.js
+++ b/spec/javascripts/u2f/util_spec.js
@@ -3,42 +3,58 @@ import { canInjectU2fApi } from '~/u2f/util';
describe('U2F Utils', () => {
describe('canInjectU2fApi', () => {
it('returns false for Chrome < 41', () => {
- const userAgent = 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.28 Safari/537.36';
+ const userAgent =
+ 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.28 Safari/537.36';
+
expect(canInjectU2fApi(userAgent)).toBe(false);
});
it('returns true for Chrome >= 41', () => {
- const userAgent = 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36';
+ const userAgent =
+ 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36';
+
expect(canInjectU2fApi(userAgent)).toBe(true);
});
it('returns false for Opera < 40', () => {
- const userAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36 OPR/32.0.1948.25';
+ const userAgent =
+ 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36 OPR/32.0.1948.25';
+
expect(canInjectU2fApi(userAgent)).toBe(false);
});
it('returns true for Opera >= 40', () => {
- const userAgent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 OPR/43.0.2442.991';
+ const userAgent =
+ 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 OPR/43.0.2442.991';
+
expect(canInjectU2fApi(userAgent)).toBe(true);
});
it('returns false for Safari', () => {
- const userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4';
+ const userAgent =
+ 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4';
+
expect(canInjectU2fApi(userAgent)).toBe(false);
});
it('returns false for Chrome on Android', () => {
- const userAgent = 'Mozilla/5.0 (Linux; Android 7.0; VS988 Build/NRD90U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3145.0 Mobile Safari/537.36';
+ const userAgent =
+ 'Mozilla/5.0 (Linux; Android 7.0; VS988 Build/NRD90U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3145.0 Mobile Safari/537.36';
+
expect(canInjectU2fApi(userAgent)).toBe(false);
});
it('returns false for Chrome on iOS', () => {
- const userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1';
+ const userAgent =
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) CriOS/56.0.2924.75 Mobile/14E5239e Safari/602.1';
+
expect(canInjectU2fApi(userAgent)).toBe(false);
});
it('returns false for Safari on iOS', () => {
- const userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A356 Safari/604.1';
+ const userAgent =
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A356 Safari/604.1';
+
expect(canInjectU2fApi(userAgent)).toBe(false);
});
});
diff --git a/spec/javascripts/version_check_image_spec.js b/spec/javascripts/version_check_image_spec.js
index 5f963e8c11e..0e69fcc4c5f 100644
--- a/spec/javascripts/version_check_image_spec.js
+++ b/spec/javascripts/version_check_image_spec.js
@@ -2,17 +2,19 @@ import $ from 'jquery';
import VersionCheckImage from '~/version_check_image';
import ClassSpecHelper from './helpers/class_spec_helper';
-describe('VersionCheckImage', function () {
- describe('bindErrorEvent', function () {
+describe('VersionCheckImage', function() {
+ describe('bindErrorEvent', function() {
ClassSpecHelper.itShouldBeAStaticMethod(VersionCheckImage, 'bindErrorEvent');
- beforeEach(function () {
+ beforeEach(function() {
this.imageElement = $('<div></div>');
});
- it('registers an error event', function () {
+ it('registers an error event', function() {
spyOn($.prototype, 'on');
- spyOn($.prototype, 'off').and.callFake(function () { return this; });
+ spyOn($.prototype, 'off').and.callFake(function() {
+ return this;
+ });
VersionCheckImage.bindErrorEvent(this.imageElement);
@@ -20,7 +22,7 @@ describe('VersionCheckImage', function () {
expect($.prototype.on).toHaveBeenCalledWith('error', jasmine.any(Function));
});
- it('hides the imageElement on error', function () {
+ it('hides the imageElement on error', function() {
spyOn($.prototype, 'hide');
VersionCheckImage.bindErrorEvent(this.imageElement);
diff --git a/spec/javascripts/vue_mr_widget/components/deployment_spec.js b/spec/javascripts/vue_mr_widget/components/deployment_spec.js
index 50c2b0e2bd0..ce850bc621e 100644
--- a/spec/javascripts/vue_mr_widget/components/deployment_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/deployment_spec.js
@@ -14,6 +14,20 @@ const deploymentMockData = {
external_url_formatted: 'diplo.',
deployed_at: '2017-03-22T22:44:42.258Z',
deployed_at_formatted: 'Mar 22, 2017 10:44pm',
+ changes: [
+ {
+ path: 'index.html',
+ external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/index.html',
+ },
+ {
+ path: 'imgs/gallery.html',
+ external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/imgs/gallery.html',
+ },
+ {
+ path: 'about/',
+ external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/about/',
+ },
+ ],
};
const createComponent = () => {
const Component = Vue.extend(deploymentComponent);
@@ -39,6 +53,7 @@ describe('Deployment component', () => {
describe('deployTimeago', () => {
it('return formatted date', () => {
const readable = getTimeago().format(deploymentMockData.deployed_at);
+
expect(vm.deployTimeago).toEqual(readable);
});
});
@@ -101,19 +116,20 @@ describe('Deployment component', () => {
describe('methods', () => {
describe('stopEnvironment', () => {
const url = '/foo/bar';
- const returnPromise = () => new Promise((resolve) => {
- resolve({
- data: {
- redirect_url: url,
- },
+ const returnPromise = () =>
+ new Promise(resolve => {
+ resolve({
+ data: {
+ redirect_url: url,
+ },
+ });
});
- });
const mockStopEnvironment = () => {
vm.stopEnvironment(deploymentMockData);
return vm;
};
- it('should show a confirm dialog and call service.stopEnvironment when confirmed', (done) => {
+ it('should show a confirm dialog and call service.stopEnvironment when confirmed', done => {
spyOn(window, 'confirm').and.returnValue(true);
spyOn(MRWidgetService, 'stopEnvironment').and.returnValue(returnPromise(true));
const visitUrl = spyOnDependency(deploymentComponent, 'visitUrl').and.returnValue(true);
@@ -147,12 +163,18 @@ describe('Deployment component', () => {
});
it('renders deployment name', () => {
- expect(el.querySelector('.js-deploy-meta').getAttribute('href')).toEqual(deploymentMockData.url);
+ expect(el.querySelector('.js-deploy-meta').getAttribute('href')).toEqual(
+ deploymentMockData.url,
+ );
+
expect(el.querySelector('.js-deploy-meta').innerText).toContain(deploymentMockData.name);
});
it('renders external URL', () => {
- expect(el.querySelector('.js-deploy-url').getAttribute('href')).toEqual(deploymentMockData.external_url);
+ expect(el.querySelector('.js-deploy-url').getAttribute('href')).toEqual(
+ deploymentMockData.external_url,
+ );
+
expect(el.querySelector('.js-deploy-url').innerText).toContain('View app');
});
@@ -168,4 +190,42 @@ describe('Deployment component', () => {
expect(el.querySelector('.js-mr-memory-usage')).not.toBeNull();
});
});
+
+ describe('with `features.ciEnvironmentsStatusChanges` enabled', () => {
+ beforeEach(() => {
+ window.gon = window.gon || {};
+ window.gon.features = window.gon.features || {};
+ window.gon.features.ciEnvironmentsStatusChanges = true;
+
+ vm = createComponent(deploymentMockData);
+ });
+
+ afterEach(() => {
+ window.gon.features = {};
+ });
+
+ it('renders dropdown with changes', () => {
+ expect(vm.$el.querySelector('.js-mr-wigdet-deployment-dropdown')).not.toBeNull();
+ expect(vm.$el.querySelector('.js-deploy-url-feature-flag')).toBeNull();
+ });
+ });
+
+ describe('with `features.ciEnvironmentsStatusChanges` disabled', () => {
+ beforeEach(() => {
+ window.gon = window.gon || {};
+ window.gon.features = window.gon.features || {};
+ window.gon.features.ciEnvironmentsStatusChanges = false;
+
+ vm = createComponent(deploymentMockData);
+ });
+
+ afterEach(() => {
+ delete window.gon.features.ciEnvironmentsStatusChanges;
+ });
+
+ it('renders the old link to the review app', () => {
+ expect(vm.$el.querySelector('.js-mr-wigdet-deployment-dropdown')).toBeNull();
+ expect(vm.$el.querySelector('.js-deploy-url-feature-flag')).not.toBeNull();
+ });
+ });
});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_author_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_author_spec.js
index 00f4f2d7c39..b69082082ba 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_author_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_author_spec.js
@@ -13,9 +13,9 @@ describe('MrWidgetAuthor', () => {
name: 'Administrator',
username: 'root',
webUrl: 'http://localhost:3000/root',
- avatarUrl: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ avatarUrl:
+ 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
},
-
});
});
@@ -28,9 +28,9 @@ describe('MrWidgetAuthor', () => {
});
it('renders image with avatar url', () => {
- expect(
- vm.$el.querySelector('img').getAttribute('src'),
- ).toEqual('http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon');
+ expect(vm.$el.querySelector('img').getAttribute('src')).toEqual(
+ 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ );
});
it('renders author name', () => {
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_author_time_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_author_time_spec.js
index 10143402acf..787f44e478d 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_author_time_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_author_time_spec.js
@@ -14,7 +14,8 @@ describe('MrWidgetAuthorTime', () => {
name: 'Administrator',
username: 'root',
webUrl: 'http://localhost:3000/root',
- avatarUrl: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ avatarUrl:
+ 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
},
dateTitle: '2017-03-23T23:02:00.807Z',
dateReadable: '12 hours ago',
@@ -34,7 +35,10 @@ describe('MrWidgetAuthorTime', () => {
});
it('renders provided time', () => {
- expect(vm.$el.querySelector('time').getAttribute('data-original-title')).toEqual('2017-03-23T23:02:00.807Z');
+ expect(vm.$el.querySelector('time').getAttribute('data-original-title')).toEqual(
+ '2017-03-23T23:02:00.807Z',
+ );
+
expect(vm.$el.querySelector('time').textContent.trim()).toEqual('12 hours ago');
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js
index 237e2fa79f2..02c476f2871 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_header_spec.js
@@ -41,6 +41,7 @@ describe('MRWidgetHeader', () => {
statusPath: 'abc',
},
});
+
expect(vm.shouldShowCommitsBehindText).toEqual(false);
});
});
@@ -58,7 +59,9 @@ describe('MRWidgetHeader', () => {
},
});
- expect(vm.commitsBehindText).toEqual('The source branch is <a href="/foo/bar/master">1 commit behind</a> the target branch');
+ expect(vm.commitsBehindText).toEqual(
+ 'The source branch is <a href="/foo/bar/master">1 commit behind</a> the target branch',
+ );
});
it('returns plural when there is more than one commit', () => {
@@ -73,7 +76,9 @@ describe('MRWidgetHeader', () => {
},
});
- expect(vm.commitsBehindText).toEqual('The source branch is <a href="/foo/bar/master">2 commits behind</a> the target branch');
+ expect(vm.commitsBehindText).toEqual(
+ 'The source branch is <a href="/foo/bar/master">2 commits behind</a> the target branch',
+ );
});
});
});
@@ -165,6 +170,7 @@ describe('MRWidgetHeader', () => {
vm = mountComponent(Component, { mr });
const link = vm.$el.querySelector('.js-web-ide');
+
expect(link.classList.contains('disabled')).toBe(true);
expect(link.getAttribute('href')).toBeNull();
});
@@ -295,9 +301,18 @@ describe('MRWidgetHeader', () => {
});
it('renders diverged commits info', () => {
- expect(vm.$el.querySelector('.diverged-commits-count').textContent).toEqual('The source branch is 12 commits behind the target branch');
- expect(vm.$el.querySelector('.diverged-commits-count a').textContent).toEqual('12 commits behind');
- expect(vm.$el.querySelector('.diverged-commits-count a')).toHaveAttr('href', vm.mr.targetBranchPath);
+ expect(vm.$el.querySelector('.diverged-commits-count').textContent).toEqual(
+ 'The source branch is 12 commits behind the target branch',
+ );
+
+ expect(vm.$el.querySelector('.diverged-commits-count a').textContent).toEqual(
+ '12 commits behind',
+ );
+
+ expect(vm.$el.querySelector('.diverged-commits-count a')).toHaveAttr(
+ 'href',
+ vm.mr.targetBranchPath,
+ );
});
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js
index 91e81a0675a..4baaea9745a 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_memory_usage_spec.js
@@ -128,16 +128,10 @@ describe('MemoryUsage', () => {
describe('computeGraphData', () => {
it('should populate sparkline graph', () => {
vm.computeGraphData(metrics, deployment_time);
- const {
- hasMetrics,
- memoryMetrics,
- deploymentTime,
- memoryFrom,
- memoryTo,
- } = vm;
+ const { hasMetrics, memoryMetrics, deploymentTime, memoryFrom, memoryTo } = vm;
expect(hasMetrics).toBeTruthy();
- expect(memoryMetrics.length > 0).toBeTruthy();
+ expect(memoryMetrics.length).toBeGreaterThan(0);
expect(deploymentTime).toEqual(deployment_time);
expect(memoryFrom).toEqual('9.13');
expect(memoryTo).toEqual('4.28');
@@ -153,18 +147,13 @@ describe('MemoryUsage', () => {
});
it('should load metrics data using MRWidgetService', done => {
- spyOn(MRWidgetService, 'fetchMetrics').and.returnValue(
- returnServicePromise(true),
- );
+ spyOn(MRWidgetService, 'fetchMetrics').and.returnValue(returnServicePromise(true));
spyOn(vm, 'computeGraphData');
vm.loadMetrics();
setTimeout(() => {
expect(MRWidgetService.fetchMetrics).toHaveBeenCalledWith(url);
- expect(vm.computeGraphData).toHaveBeenCalledWith(
- metrics,
- deployment_time,
- );
+ expect(vm.computeGraphData).toHaveBeenCalledWith(metrics, deployment_time);
done();
}, 333);
});
@@ -183,15 +172,11 @@ describe('MemoryUsage', () => {
vm.loadFailed = false;
Vue.nextTick(() => {
- expect(
- el.querySelector('.js-usage-info.usage-info-loading'),
- ).toBeDefined();
- expect(
- el.querySelector('.js-usage-info .usage-info-load-spinner'),
- ).toBeDefined();
- expect(el.querySelector('.js-usage-info').innerText).toContain(
- messages.loadingMetrics,
- );
+ expect(el.querySelector('.js-usage-info.usage-info-loading')).toBeDefined();
+
+ expect(el.querySelector('.js-usage-info .usage-info-load-spinner')).toBeDefined();
+
+ expect(el.querySelector('.js-usage-info').innerText).toContain(messages.loadingMetrics);
done();
});
});
@@ -203,9 +188,7 @@ describe('MemoryUsage', () => {
Vue.nextTick(() => {
expect(el.querySelector('.memory-graph-container')).toBeDefined();
- expect(el.querySelector('.js-usage-info').innerText).toContain(
- messages.hasMetrics,
- );
+ expect(el.querySelector('.js-usage-info').innerText).toContain(messages.hasMetrics);
done();
});
});
@@ -216,12 +199,9 @@ describe('MemoryUsage', () => {
vm.loadFailed = true;
Vue.nextTick(() => {
- expect(
- el.querySelector('.js-usage-info.usage-info-failed'),
- ).toBeDefined();
- expect(el.querySelector('.js-usage-info').innerText).toContain(
- messages.loadFailed,
- );
+ expect(el.querySelector('.js-usage-info.usage-info-failed')).toBeDefined();
+
+ expect(el.querySelector('.js-usage-info').innerText).toContain(messages.loadFailed);
done();
});
});
@@ -232,12 +212,9 @@ describe('MemoryUsage', () => {
vm.loadFailed = false;
Vue.nextTick(() => {
- expect(
- el.querySelector('.js-usage-info.usage-info-unavailable'),
- ).toBeDefined();
- expect(el.querySelector('.js-usage-info').innerText).toContain(
- messages.metricsUnavailable,
- );
+ expect(el.querySelector('.js-usage-info.usage-info-unavailable')).toBeDefined();
+
+ expect(el.querySelector('.js-usage-info').innerText).toContain(messages.metricsUnavailable);
done();
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_merge_help_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_merge_help_spec.js
index 367c499daaf..2c554f3f3ab 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_merge_help_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_merge_help_spec.js
@@ -23,15 +23,23 @@ describe('MRWidgetMergeHelp', () => {
it('renders missing branch information', () => {
expect(
- vm.$el.textContent.trim().replace(/[\r\n]+/g, ' ').replace(/\s\s+/g, ' '),
+ vm.$el.textContent
+ .trim()
+ .replace(/[\r\n]+/g, ' ')
+ .replace(/\s\s+/g, ' '),
).toEqual(
'If the this-is-not-the-branch-you-are-looking-for branch exists in your local repository, you can merge this merge request manually using the command line',
);
});
it('renders button to open help modal', () => {
- expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-target')).toEqual('#modal_merge_info');
- expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-toggle')).toEqual('modal');
+ expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-target')).toEqual(
+ '#modal_merge_info',
+ );
+
+ expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-toggle')).toEqual(
+ 'modal',
+ );
});
});
@@ -42,15 +50,21 @@ describe('MRWidgetMergeHelp', () => {
it('renders information about how to merge manually', () => {
expect(
- vm.$el.textContent.trim().replace(/[\r\n]+/g, ' ').replace(/\s\s+/g, ' '),
- ).toEqual(
- 'You can merge this merge request manually using the command line',
- );
+ vm.$el.textContent
+ .trim()
+ .replace(/[\r\n]+/g, ' ')
+ .replace(/\s\s+/g, ' '),
+ ).toEqual('You can merge this merge request manually using the command line');
});
it('renders element to open a modal', () => {
- expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-target')).toEqual('#modal_merge_info');
- expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-toggle')).toEqual('modal');
+ expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-target')).toEqual(
+ '#modal_merge_info',
+ );
+
+ expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-toggle')).toEqual(
+ 'modal',
+ );
});
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js
index b453d180a40..14d6e8d7556 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_rebase_spec.js
@@ -39,13 +39,16 @@ describe('Merge request widget rebase component', () => {
});
it('it should render rebase button and warning message', () => {
- const text = vm.$el.querySelector('.rebase-state-find-class-convention span').textContent.trim();
+ const text = vm.$el
+ .querySelector('.rebase-state-find-class-convention span')
+ .textContent.trim();
+
expect(text).toContain('Fast-forward merge is not possible.');
expect(text).toContain('Rebase the source branch onto the target branch or merge target');
expect(text).toContain('branch into source branch to allow this merge request to be merged.');
});
- it('it should render error message when it fails', (done) => {
+ it('it should render error message when it fails', done => {
vm.rebasingError = 'Something went wrong!';
Vue.nextTick(() => {
@@ -68,7 +71,9 @@ describe('Merge request widget rebase component', () => {
service: {},
});
- const text = vm.$el.querySelector('.rebase-state-find-class-convention span').textContent.trim();
+ const text = vm.$el
+ .querySelector('.rebase-state-find-class-convention span')
+ .textContent.trim();
expect(text).toContain('Fast-forward merge is not possible.');
expect(text).toContain('Rebase the source branch onto');
@@ -78,7 +83,7 @@ describe('Merge request widget rebase component', () => {
});
describe('methods', () => {
- it('checkRebaseStatus', (done) => {
+ it('checkRebaseStatus', done => {
spyOn(eventHub, '$emit');
vm = mountComponent(Component, {
mr: {},
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js
index 5de6ac4079d..7a5d0efdea5 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_related_links_spec.js
@@ -5,7 +5,7 @@ import mountComponent from 'spec/helpers/vue_mount_component_helper';
describe('MRWidgetRelatedLinks', () => {
let vm;
- const createComponent = (data) => {
+ const createComponent = data => {
const Component = Vue.extend(relatedLinksComponent);
return mountComponent(Component, data);
@@ -19,16 +19,19 @@ describe('MRWidgetRelatedLinks', () => {
describe('closesText', () => {
it('returns Closes text for open merge request', () => {
vm = createComponent({ state: 'open', relatedLinks: {} });
+
expect(vm.closesText).toEqual('Closes');
});
it('returns correct text for closed merge request', () => {
vm = createComponent({ state: 'closed', relatedLinks: {} });
+
expect(vm.closesText).toEqual('Did not close');
});
it('returns correct tense for merged request', () => {
vm = createComponent({ state: 'merged', relatedLinks: {} });
+
expect(vm.closesText).toEqual('Closed');
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js
index 0b25500caf4..a0a336ae604 100644
--- a/spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/mr_widget_status_icon_spec.js
@@ -17,6 +17,7 @@ describe('MR widget status icon component', () => {
describe('while loading', () => {
it('renders loading icon', () => {
vm = mountComponent(Component, { status: 'loading' });
+
expect(vm.$el.querySelector('.mr-widget-icon i').classList).toContain('fa-spinner');
});
});
@@ -24,6 +25,7 @@ describe('MR widget status icon component', () => {
describe('with status icon', () => {
it('renders ci status icon', () => {
vm = mountComponent(Component, { status: 'failed' });
+
expect(vm.$el.querySelector('.js-ci-status-icon-failed')).not.toBeNull();
});
});
@@ -31,6 +33,7 @@ describe('MR widget status icon component', () => {
describe('with disabled button', () => {
it('renders a disabled button', () => {
vm = mountComponent(Component, { status: 'failed', showDisabledButton: true });
+
expect(vm.$el.querySelector('.js-disabled-merge-button').textContent.trim()).toEqual('Merge');
});
});
@@ -38,6 +41,7 @@ describe('MR widget status icon component', () => {
describe('without disabled button', () => {
it('does not render a disabled button', () => {
vm = mountComponent(Component, { status: 'failed' });
+
expect(vm.$el.querySelector('.js-disabled-merge-button')).toBeNull();
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js
index e818f87b4c8..b90f5881a4d 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_archived_spec.js
@@ -24,8 +24,8 @@ describe('MRWidgetArchived', () => {
});
it('renders information', () => {
- expect(
- vm.$el.querySelector('.bold').textContent.trim(),
- ).toEqual('This project is archived, write access has been disabled');
+ expect(vm.$el.querySelector('.bold').textContent.trim()).toEqual(
+ 'This project is archived, write access has been disabled',
+ );
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js
index d069dc3fcc6..eb4fa0df727 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js
@@ -30,7 +30,7 @@ describe('MRWidgetAutoMergeFailed', () => {
expect(vm.$el.querySelector('button').textContent.trim()).toEqual('Refresh');
});
- it('emits event and shows loading icon when button is clicked', (done) => {
+ it('emits event and shows loading icon when button is clicked', done => {
spyOn(eventHub, '$emit');
vm.$el.querySelector('button').click();
@@ -38,9 +38,7 @@ describe('MRWidgetAutoMergeFailed', () => {
Vue.nextTick(() => {
expect(vm.$el.querySelector('button').getAttribute('disabled')).toEqual('disabled');
- expect(
- vm.$el.querySelector('button i').classList,
- ).toContain('fa-spinner');
+ expect(vm.$el.querySelector('button i').classList).toContain('fa-spinner');
done();
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js
index 658612aad3c..7da27bb8890 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_checking_spec.js
@@ -24,6 +24,8 @@ describe('MRWidgetChecking', () => {
});
it('renders information about merging', () => {
- expect(vm.$el.querySelector('.media-body').textContent.trim()).toEqual('Checking ability to merge automatically');
+ expect(vm.$el.querySelector('.media-body').textContent.trim()).toEqual(
+ 'Checking ability to merge automatically',
+ );
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_closed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_closed_spec.js
index 0e3c134d3ac..9523e7d5474 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_closed_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_closed_spec.js
@@ -7,23 +7,26 @@ describe('MRWidgetClosed', () => {
beforeEach(() => {
const Component = Vue.extend(closedComponent);
- vm = mountComponent(Component, { mr: {
- metrics: {
- mergedBy: {},
- closedBy: {
- name: 'Administrator',
- username: 'root',
- webUrl: 'http://localhost:3000/root',
- avatarUrl: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ vm = mountComponent(Component, {
+ mr: {
+ metrics: {
+ mergedBy: {},
+ closedBy: {
+ name: 'Administrator',
+ username: 'root',
+ webUrl: 'http://localhost:3000/root',
+ avatarUrl:
+ 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ },
+ mergedAt: 'Jan 24, 2018 1:02pm GMT+0000',
+ closedAt: 'Jan 24, 2018 1:02pm GMT+0000',
+ readableMergedAt: '',
+ readableClosedAt: 'less than a minute ago',
},
- mergedAt: 'Jan 24, 2018 1:02pm GMT+0000',
- closedAt: 'Jan 24, 2018 1:02pm GMT+0000',
- readableMergedAt: '',
- readableClosedAt: 'less than a minute ago',
+ targetBranchPath: '/twitter/flight/commits/so_long_jquery',
+ targetBranch: 'so_long_jquery',
},
- targetBranchPath: '/twitter/flight/commits/so_long_jquery',
- targetBranch: 'so_long_jquery',
- } });
+ });
});
afterEach(() => {
@@ -36,23 +39,31 @@ describe('MRWidgetClosed', () => {
it('renders closed by information with author and time', () => {
expect(
- vm.$el.querySelector('.js-mr-widget-author').textContent.trim().replace(/\s\s+/g, ' '),
- ).toContain(
- 'Closed by Administrator less than a minute ago',
- );
+ vm.$el
+ .querySelector('.js-mr-widget-author')
+ .textContent.trim()
+ .replace(/\s\s+/g, ' '),
+ ).toContain('Closed by Administrator less than a minute ago');
});
it('links to the user that closed the MR', () => {
- expect(vm.$el.querySelector('.author-link').getAttribute('href')).toEqual('http://localhost:3000/root');
+ expect(vm.$el.querySelector('.author-link').getAttribute('href')).toEqual(
+ 'http://localhost:3000/root',
+ );
});
it('renders information about the changes not being merged', () => {
expect(
- vm.$el.querySelector('.mr-info-list').textContent.trim().replace(/\s\s+/g, ' '),
+ vm.$el
+ .querySelector('.mr-info-list')
+ .textContent.trim()
+ .replace(/\s\s+/g, ' '),
).toContain('The changes were not merged into so_long_jquery');
});
it('renders link for target branch', () => {
- expect(vm.$el.querySelector('.label-branch').getAttribute('href')).toEqual('/twitter/flight/commits/so_long_jquery');
+ expect(vm.$el.querySelector('.label-branch').getAttribute('href')).toEqual(
+ '/twitter/flight/commits/so_long_jquery',
+ );
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js
index 3d05dbfa305..f9cd5c8bd3c 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_conflicts_spec.js
@@ -59,7 +59,9 @@ describe('MRWidgetConflicts', () => {
});
it('should show proper message', () => {
- expect(vm.$el.textContent.trim().replace(/\s\s+/g, ' ')).toContain('ask someone with write access');
+ expect(vm.$el.textContent.trim().replace(/\s\s+/g, ' ')).toContain(
+ 'ask someone with write access',
+ );
});
it('should not have action buttons', () => {
@@ -79,9 +81,9 @@ describe('MRWidgetConflicts', () => {
});
it('should tell you to rebase locally', () => {
- expect(
- removeBreakLine(vm.$el.textContent).trim(),
- ).toContain('Fast-forward merge is not possible. To merge this request, first rebase locally.');
+ expect(removeBreakLine(vm.$el.textContent).trim()).toContain(
+ 'Fast-forward merge is not possible. To merge this request, first rebase locally.',
+ );
});
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js
index 8de99fd3c96..3229ddd5e27 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js
@@ -43,6 +43,7 @@ describe('MRWidgetFailedToMerge', () => {
expect(vm.timerText).toEqual('Refreshing in 10 seconds to show the updated status...');
vm.timer = 1;
+
expect(vm.timerText).toEqual('Refreshing in a second to show the updated status...');
});
});
@@ -73,6 +74,7 @@ describe('MRWidgetFailedToMerge', () => {
expect(vm.isRefreshing).toEqual(false);
vm.refresh();
+
expect(vm.isRefreshing).toEqual(true);
expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
expect(eventHub.$emit).toHaveBeenCalledWith('EnablePolling');
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js
index d47815a5b5a..d46ad0acc9b 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js
@@ -42,22 +42,27 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
it('should return false when user id is not the same with who set the MWPS', () => {
vm.mr.mergeUserId = 2;
+
expect(vm.canRemoveSourceBranch).toBeFalsy();
vm.mr.currentUserId = 2;
+
expect(vm.canRemoveSourceBranch).toBeTruthy();
vm.mr.currentUserId = 3;
+
expect(vm.canRemoveSourceBranch).toBeFalsy();
});
it('should return false when shouldRemoveSourceBranch set to false', () => {
vm.mr.shouldRemoveSourceBranch = true;
+
expect(vm.canRemoveSourceBranch).toBeFalsy();
});
it('should return false if user is not able to remove the source branch', () => {
vm.mr.canRemoveSourceBranch = false;
+
expect(vm.canRemoveSourceBranch).toBeFalsy();
});
});
@@ -65,15 +70,17 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
describe('methods', () => {
describe('cancelAutomaticMerge', () => {
- it('should set flag and call service then tell main component to update the widget with data', (done) => {
+ it('should set flag and call service then tell main component to update the widget with data', done => {
const mrObj = {
is_new_mr_data: true,
};
- spyOn(vm.service, 'cancelAutomaticMerge').and.returnValue(new Promise((resolve) => {
- resolve({
- data: mrObj,
- });
- }));
+ spyOn(vm.service, 'cancelAutomaticMerge').and.returnValue(
+ new Promise(resolve => {
+ resolve({
+ data: mrObj,
+ });
+ }),
+ );
vm.cancelAutomaticMerge();
setTimeout(() => {
@@ -85,12 +92,14 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
});
describe('removeSourceBranch', () => {
- it('should set flag and call service then request main component to update the widget', (done) => {
- spyOn(vm.service, 'merge').and.returnValue(Promise.resolve({
- data: {
- status: 'merge_when_pipeline_succeeds',
- },
- }));
+ it('should set flag and call service then request main component to update the widget', done => {
+ spyOn(vm.service, 'merge').and.returnValue(
+ Promise.resolve({
+ data: {
+ status: 'merge_when_pipeline_succeeds',
+ },
+ }),
+ );
vm.removeSourceBranch();
setTimeout(() => {
@@ -113,13 +122,19 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
expect(vm.$el.innerText).toContain('The changes will be merged into');
expect(vm.$el.innerText).toContain(targetBranch);
expect(vm.$el.innerText).toContain('The source branch will not be removed');
- expect(vm.$el.querySelector('.js-cancel-auto-merge').innerText).toContain('Cancel automatic merge');
+ expect(vm.$el.querySelector('.js-cancel-auto-merge').innerText).toContain(
+ 'Cancel automatic merge',
+ );
+
expect(vm.$el.querySelector('.js-cancel-auto-merge').getAttribute('disabled')).toBeFalsy();
- expect(vm.$el.querySelector('.js-remove-source-branch').innerText).toContain('Remove source branch');
+ expect(vm.$el.querySelector('.js-remove-source-branch').innerText).toContain(
+ 'Remove source branch',
+ );
+
expect(vm.$el.querySelector('.js-remove-source-branch').getAttribute('disabled')).toBeFalsy();
});
- it('should disable cancel auto merge button when the action is in progress', (done) => {
+ it('should disable cancel auto merge button when the action is in progress', done => {
vm.isCancellingAutoMerge = true;
Vue.nextTick(() => {
@@ -128,18 +143,19 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
});
});
- it('should show source branch will be removed text when it source branch set to remove', (done) => {
+ it('should show source branch will be removed text when it source branch set to remove', done => {
vm.mr.shouldRemoveSourceBranch = true;
Vue.nextTick(() => {
const normalizedText = vm.$el.innerText.replace(/\s+/g, ' ');
+
expect(normalizedText).toContain('The source branch will be removed');
expect(normalizedText).not.toContain('The source branch will not be removed');
done();
});
});
- it('should not show remove source branch button when user not able to remove source branch', (done) => {
+ it('should not show remove source branch button when user not able to remove source branch', done => {
vm.mr.currentUserId = 4;
Vue.nextTick(() => {
@@ -148,11 +164,13 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
});
});
- it('should disable remove source branch button when the action is in progress', (done) => {
+ it('should disable remove source branch button when the action is in progress', done => {
vm.isRemovingSourceBranch = true;
Vue.nextTick(() => {
- expect(vm.$el.querySelector('.js-remove-source-branch').getAttribute('disabled')).toBeTruthy();
+ expect(
+ vm.$el.querySelector('.js-remove-source-branch').getAttribute('disabled'),
+ ).toBeTruthy();
done();
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js
index efa5c878678..d68342635ef 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merged_spec.js
@@ -30,7 +30,8 @@ describe('MRWidgetMerged', () => {
name: 'Administrator',
username: 'root',
webUrl: 'http://localhost:3000/root',
- avatarUrl: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
+ avatarUrl:
+ 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
},
mergedAt: 'Jan 24, 2018 1:02pm GMT+0000',
readableMergedAt: '',
@@ -41,7 +42,8 @@ describe('MRWidgetMerged', () => {
updatedAt: 'mergedUpdatedAt',
shortMergeCommitSha: '958c0475',
mergeCommitSha: '958c047516e182dfc52317f721f696e8a1ee85ed',
- mergeCommitPath: 'http://localhost:3000/root/nautilus/commit/f7ce827c314c9340b075657fd61c789fb01cf74d',
+ mergeCommitPath:
+ 'http://localhost:3000/root/nautilus/commit/f7ce827c314c9340b075657fd61c789fb01cf74d',
sourceBranch: 'bar',
targetBranch,
};
@@ -63,23 +65,27 @@ describe('MRWidgetMerged', () => {
describe('shouldShowRemoveSourceBranch', () => {
it('returns true when sourceBranchRemoved is false', () => {
vm.mr.sourceBranchRemoved = false;
+
expect(vm.shouldShowRemoveSourceBranch).toEqual(true);
});
it('returns false wehn sourceBranchRemoved is true', () => {
vm.mr.sourceBranchRemoved = true;
+
expect(vm.shouldShowRemoveSourceBranch).toEqual(false);
});
it('returns false when canRemoveSourceBranch is false', () => {
vm.mr.sourceBranchRemoved = false;
vm.mr.canRemoveSourceBranch = false;
+
expect(vm.shouldShowRemoveSourceBranch).toEqual(false);
});
it('returns false when is making request', () => {
vm.mr.canRemoveSourceBranch = true;
vm.isMakingRequest = true;
+
expect(vm.shouldShowRemoveSourceBranch).toEqual(false);
});
@@ -87,6 +93,7 @@ describe('MRWidgetMerged', () => {
vm.mr.isRemovingSourceBranch = true;
vm.mr.canRemoveSourceBranch = true;
vm.isMakingRequest = true;
+
expect(vm.shouldShowRemoveSourceBranch).toEqual(false);
});
});
@@ -94,17 +101,21 @@ describe('MRWidgetMerged', () => {
describe('shouldShowSourceBranchRemoving', () => {
it('should correct value when fields changed', () => {
vm.mr.sourceBranchRemoved = false;
+
expect(vm.shouldShowSourceBranchRemoving).toEqual(false);
vm.mr.sourceBranchRemoved = true;
+
expect(vm.shouldShowRemoveSourceBranch).toEqual(false);
vm.mr.sourceBranchRemoved = false;
vm.isMakingRequest = true;
+
expect(vm.shouldShowSourceBranchRemoving).toEqual(true);
vm.isMakingRequest = false;
vm.mr.isRemovingSourceBranch = true;
+
expect(vm.shouldShowSourceBranchRemoving).toEqual(true);
});
});
@@ -112,18 +123,21 @@ describe('MRWidgetMerged', () => {
describe('methods', () => {
describe('removeSourceBranch', () => {
- it('should set flag and call service then request main component to update the widget', (done) => {
- spyOn(vm.service, 'removeSourceBranch').and.returnValue(new Promise((resolve) => {
- resolve({
- data: {
- message: 'Branch was removed',
- },
- });
- }));
+ it('should set flag and call service then request main component to update the widget', done => {
+ spyOn(vm.service, 'removeSourceBranch').and.returnValue(
+ new Promise(resolve => {
+ resolve({
+ data: {
+ message: 'Branch was removed',
+ },
+ });
+ }),
+ );
vm.removeSourceBranch();
setTimeout(() => {
const args = eventHub.$emit.calls.argsFor(0);
+
expect(vm.isMakingRequest).toEqual(true);
expect(args[0]).toEqual('MRWidgetUpdateRequested');
expect(args[1]).not.toThrow();
@@ -154,7 +168,19 @@ describe('MRWidgetMerged', () => {
it('shows button to copy commit SHA to clipboard', () => {
expect(selectors.copyMergeShaButton).toExist();
- expect(selectors.copyMergeShaButton.getAttribute('data-clipboard-text')).toBe(vm.mr.mergeCommitSha);
+ expect(selectors.copyMergeShaButton.getAttribute('data-clipboard-text')).toBe(
+ vm.mr.mergeCommitSha,
+ );
+ });
+
+ it('hides button to copy commit SHA if SHA does not exist', done => {
+ vm.mr.mergeCommitSha = null;
+
+ Vue.nextTick(() => {
+ expect(selectors.copyMergeShaButton).not.toExist();
+ expect(vm.$el.querySelector('.mr-info-list').innerText).not.toContain('with');
+ done();
+ });
});
it('shows merge commit SHA link', () => {
@@ -163,7 +189,7 @@ describe('MRWidgetMerged', () => {
expect(selectors.mergeCommitShaLink.href).toBe(vm.mr.mergeCommitPath);
});
- it('should not show source branch removed text', (done) => {
+ it('should not show source branch removed text', done => {
vm.mr.sourceBranchRemoved = false;
Vue.nextTick(() => {
@@ -173,7 +199,7 @@ describe('MRWidgetMerged', () => {
});
});
- it('should show source branch removing text', (done) => {
+ it('should show source branch removing text', done => {
vm.mr.isRemovingSourceBranch = true;
vm.mr.sourceBranchRemoved = false;
@@ -186,8 +212,8 @@ describe('MRWidgetMerged', () => {
});
it('should use mergedEvent mergedAt as tooltip title', () => {
- expect(
- vm.$el.querySelector('time').getAttribute('data-original-title'),
- ).toBe('Jan 24, 2018 1:02pm GMT+0000');
+ expect(vm.$el.querySelector('time').getAttribute('data-original-title')).toBe(
+ 'Jan 24, 2018 1:02pm GMT+0000',
+ );
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merging_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merging_spec.js
index d2d219e4bdb..57773d1648a 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merging_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_merging_spec.js
@@ -7,10 +7,12 @@ describe('MRWidgetMerging', () => {
beforeEach(() => {
const Component = Vue.extend(mergingComponent);
- vm = mountComponent(Component, { mr: {
- targetBranchPath: '/branch-path',
- targetBranch: 'branch',
- } });
+ vm = mountComponent(Component, {
+ mr: {
+ targetBranchPath: '/branch-path',
+ targetBranch: 'branch',
+ },
+ });
});
afterEach(() => {
@@ -19,16 +21,23 @@ describe('MRWidgetMerging', () => {
it('renders information about merge request being merged', () => {
expect(
- vm.$el.querySelector('.media-body').textContent.trim().replace(/\s\s+/g, ' ').replace(/[\r\n]+/g, ' '),
+ vm.$el
+ .querySelector('.media-body')
+ .textContent.trim()
+ .replace(/\s\s+/g, ' ')
+ .replace(/[\r\n]+/g, ' '),
).toContain('This merge request is in the process of being merged');
});
it('renders branch information', () => {
expect(
- vm.$el.querySelector('.mr-info-list').textContent.trim().replace(/\s\s+/g, ' ').replace(/[\r\n]+/g, ' '),
+ vm.$el
+ .querySelector('.mr-info-list')
+ .textContent.trim()
+ .replace(/\s\s+/g, ' ')
+ .replace(/[\r\n]+/g, ' '),
).toEqual('The changes will be merged into branch');
- expect(
- vm.$el.querySelector('a').getAttribute('href'),
- ).toEqual('/branch-path');
+
+ expect(vm.$el.querySelector('a').getAttribute('href')).toEqual('/branch-path');
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js
index 34f76b39b28..096301837c4 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js
@@ -20,6 +20,7 @@ describe('MRWidgetMissingBranch', () => {
expect(vm.missingBranchName).toEqual('source');
vm.mr.sourceBranchRemoved = false;
+
expect(vm.missingBranchName).toEqual('target');
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js
index 9f8b96c118b..6b95ca3460b 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_not_allowed_spec.js
@@ -19,6 +19,8 @@ describe('MRWidgetNotAllowed', () => {
it('renders informative text', () => {
expect(vm.$el.innerText).toContain('Ready to be merged automatically.');
- expect(vm.$el.innerText).toContain('Ask someone with write access to this repository to merge this request');
+ expect(vm.$el.innerText).toContain(
+ 'Ask someone with write access to this repository to merge this request',
+ );
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js
index 2a762c9336e..babb8cea0ab 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js
@@ -15,7 +15,10 @@ describe('NothingToMerge', () => {
it('should have correct elements', () => {
expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
expect(vm.$el.querySelector('a').href).toContain(newBlobPath);
- expect(vm.$el.innerText).toContain('Currently there are no changes in this merge request\'s source branch');
+ expect(vm.$el.innerText).toContain(
+ "Currently there are no changes in this merge request's source branch",
+ );
+
expect(vm.$el.innerText).toContain('Please push new commits or use a different branch.');
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js
index ab096a56918..477041fa383 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_blocked_spec.js
@@ -19,8 +19,8 @@ describe('MRWidgetPipelineBlocked', () => {
});
it('renders information text', () => {
- expect(
- removeBreakLine(vm.$el.textContent).trim(),
- ).toContain('Pipeline blocked. The pipeline for this merge request requires a manual action to proceed');
+ expect(removeBreakLine(vm.$el.textContent).trim()).toContain(
+ 'Pipeline blocked. The pipeline for this merge request requires a manual action to proceed',
+ );
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
index 5573d7c5c93..f7523a01963 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
@@ -11,9 +11,9 @@ describe('PipelineFailed', () => {
it('should have correct elements', () => {
expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy();
- expect(
- removeBreakLine(vm.$el.innerText).trim(),
- ).toContain('The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure');
+ expect(removeBreakLine(vm.$el.innerText).trim()).toContain(
+ 'The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure',
+ );
});
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
index 81c16593eb4..2119a3b927a 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
@@ -76,11 +76,13 @@ describe('ReadyToMerge', () => {
describe('shouldShowMergeWhenPipelineSucceedsText', () => {
it('should return true with active pipeline', () => {
vm.mr.isPipelineActive = true;
+
expect(vm.shouldShowMergeWhenPipelineSucceedsText).toBeTruthy();
});
it('should return false with inactive pipeline', () => {
vm.mr.isPipelineActive = false;
+
expect(vm.shouldShowMergeWhenPipelineSucceedsText).toBeFalsy();
});
});
@@ -95,6 +97,7 @@ describe('ReadyToMerge', () => {
it('should return message without description', () => {
vm.useCommitMessageWithDescription = true;
+
expect(vm.commitMessageLinkTitle).toEqual(withoutDesc);
});
});
@@ -102,11 +105,13 @@ describe('ReadyToMerge', () => {
describe('status', () => {
it('defaults to success', () => {
vm.mr.pipeline = true;
+
expect(vm.status).toEqual('success');
});
it('returns failed when MR has CI but also has an unknown status', () => {
vm.mr.hasCI = true;
+
expect(vm.status).toEqual('failed');
});
@@ -117,12 +122,14 @@ describe('ReadyToMerge', () => {
it('returns pending when pipeline is active', () => {
vm.mr.pipeline = {};
vm.mr.isPipelineActive = true;
+
expect(vm.status).toEqual('pending');
});
it('returns failed when pipeline is failed', () => {
vm.mr.pipeline = {};
vm.mr.isPipelineFailed = true;
+
expect(vm.status).toEqual('failed');
});
});
@@ -138,17 +145,20 @@ describe('ReadyToMerge', () => {
it('returns success class for success status', () => {
vm.mr.pipeline = true;
+
expect(vm.mergeButtonClass).toEqual(defaultClass);
});
it('returns info class for pending status', () => {
vm.mr.pipeline = {};
vm.mr.isPipelineActive = true;
+
expect(vm.mergeButtonClass).toEqual(inActionClass);
});
it('returns failed class for failed status', () => {
vm.mr.hasCI = true;
+
expect(vm.mergeButtonClass).toEqual(failedClass);
});
});
@@ -160,22 +170,26 @@ describe('ReadyToMerge', () => {
it('shows tick for success status', () => {
vm.mr.pipeline = true;
+
expect(vm.iconClass).toEqual('success');
});
it('shows tick for pending status', () => {
vm.mr.pipeline = {};
vm.mr.isPipelineActive = true;
+
expect(vm.iconClass).toEqual('success');
});
it('shows warning icon for failed status', () => {
vm.mr.hasCI = true;
+
expect(vm.iconClass).toEqual('warning');
});
it('shows warning icon for merge not allowed', () => {
vm.mr.hasCI = true;
+
expect(vm.iconClass).toEqual('warning');
});
});
@@ -187,12 +201,14 @@ describe('ReadyToMerge', () => {
it('should return Merge in progress', () => {
vm.isMergingImmediately = true;
+
expect(vm.mergeButtonText).toEqual('Merge in progress');
});
it('should return Merge when pipeline succeeds', () => {
vm.isMergingImmediately = false;
vm.mr.isPipelineActive = true;
+
expect(vm.mergeButtonText).toEqual('Merge when pipeline succeeds');
});
});
@@ -204,12 +220,14 @@ describe('ReadyToMerge', () => {
it('should return true when pipeline active', () => {
vm.mr.isPipelineActive = true;
+
expect(vm.shouldShowMergeOptionsDropdown).toBeTruthy();
});
it('should return false when pipeline active but only merge when pipeline succeeds set in project options', () => {
vm.mr.isPipelineActive = true;
vm.mr.onlyAllowMergeIfPipelineSucceeds = true;
+
expect(vm.shouldShowMergeOptionsDropdown).toBeFalsy();
});
});
@@ -217,24 +235,28 @@ describe('ReadyToMerge', () => {
describe('isMergeButtonDisabled', () => {
it('should return false with initial data', () => {
vm.mr.isMergeAllowed = true;
+
expect(vm.isMergeButtonDisabled).toBeFalsy();
});
it('should return true when there is no commit message', () => {
vm.mr.isMergeAllowed = true;
vm.commitMessage = '';
+
expect(vm.isMergeButtonDisabled).toBeTruthy();
});
it('should return true if merge is not allowed', () => {
vm.mr.isMergeAllowed = false;
vm.mr.onlyAllowMergeIfPipelineSucceeds = true;
+
expect(vm.isMergeButtonDisabled).toBeTruthy();
});
it('should return true when the vm instance is making request', () => {
vm.mr.isMergeAllowed = true;
vm.isMakingRequest = true;
+
expect(vm.isMergeButtonDisabled).toBeTruthy();
});
});
@@ -245,24 +267,28 @@ describe('ReadyToMerge', () => {
it('should return false when an external pipeline is running and required to succeed', () => {
vm.mr.isMergeAllowed = false;
vm.mr.isPipelineActive = false;
+
expect(vm.shouldShowMergeControls()).toBeFalsy();
});
it('should return true when the build succeeded or build not required to succeed', () => {
vm.mr.isMergeAllowed = true;
vm.mr.isPipelineActive = false;
+
expect(vm.shouldShowMergeControls()).toBeTruthy();
});
it('should return true when showing the MWPS button and a pipeline is running that needs to be successful', () => {
vm.mr.isMergeAllowed = false;
vm.mr.isPipelineActive = true;
+
expect(vm.shouldShowMergeControls()).toBeTruthy();
});
it('should return true when showing the MWPS button but not required for the pipeline to succeed', () => {
vm.mr.isMergeAllowed = true;
vm.mr.isPipelineActive = true;
+
expect(vm.shouldShowMergeControls()).toBeTruthy();
});
});
@@ -272,9 +298,11 @@ describe('ReadyToMerge', () => {
expect(vm.useCommitMessageWithDescription).toBeFalsy();
expect(vm.commitMessage).toEqual(commitMessage);
vm.updateCommitMessage();
+
expect(vm.useCommitMessageWithDescription).toBeTruthy();
expect(vm.commitMessage).toEqual(commitMessageWithDescription);
vm.updateCommitMessage();
+
expect(vm.useCommitMessageWithDescription).toBeFalsy();
expect(vm.commitMessage).toEqual(commitMessage);
});
@@ -284,20 +312,22 @@ describe('ReadyToMerge', () => {
it('should toggle showCommitMessageEditor flag', () => {
expect(vm.showCommitMessageEditor).toBeFalsy();
vm.toggleCommitMessageEditor();
+
expect(vm.showCommitMessageEditor).toBeTruthy();
});
});
describe('handleMergeButtonClick', () => {
- const returnPromise = status => new Promise((resolve) => {
- resolve({
- data: {
- status,
- },
+ const returnPromise = status =>
+ new Promise(resolve => {
+ resolve({
+ data: {
+ status,
+ },
+ });
});
- });
- it('should handle merge when pipeline succeeds', (done) => {
+ it('should handle merge when pipeline succeeds', done => {
spyOn(eventHub, '$emit');
spyOn(vm.service, 'merge').and.returnValue(returnPromise('merge_when_pipeline_succeeds'));
vm.removeSourceBranch = false;
@@ -309,6 +339,7 @@ describe('ReadyToMerge', () => {
expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
const params = vm.service.merge.calls.argsFor(0)[0];
+
expect(params.sha).toEqual(vm.mr.sha);
expect(params.commit_message).toEqual(vm.mr.commitMessage);
expect(params.should_remove_source_branch).toBeFalsy();
@@ -317,7 +348,7 @@ describe('ReadyToMerge', () => {
}, 333);
});
- it('should handle merge failed', (done) => {
+ it('should handle merge failed', done => {
spyOn(eventHub, '$emit');
spyOn(vm.service, 'merge').and.returnValue(returnPromise('failed'));
vm.handleMergeButtonClick(false, true);
@@ -328,13 +359,14 @@ describe('ReadyToMerge', () => {
expect(eventHub.$emit).toHaveBeenCalledWith('FailedToMerge', undefined);
const params = vm.service.merge.calls.argsFor(0)[0];
+
expect(params.should_remove_source_branch).toBeTruthy();
expect(params.merge_when_pipeline_succeeds).toBeFalsy();
done();
}, 333);
});
- it('should handle merge action accepted case', (done) => {
+ it('should handle merge action accepted case', done => {
spyOn(vm.service, 'merge').and.returnValue(returnPromise('success'));
spyOn(vm, 'initiateMergePolling');
vm.handleMergeButtonClick();
@@ -345,6 +377,7 @@ describe('ReadyToMerge', () => {
expect(vm.initiateMergePolling).toHaveBeenCalled();
const params = vm.service.merge.calls.argsFor(0)[0];
+
expect(params.should_remove_source_branch).toBeTruthy();
expect(params.merge_when_pipeline_succeeds).toBeFalsy();
done();
@@ -356,25 +389,27 @@ describe('ReadyToMerge', () => {
it('should call simplePoll', () => {
const simplePoll = spyOnDependency(ReadyToMerge, 'simplePoll');
vm.initiateMergePolling();
+
expect(simplePoll).toHaveBeenCalled();
});
});
describe('handleMergePolling', () => {
- const returnPromise = state => new Promise((resolve) => {
- resolve({
- data: {
- state,
- source_branch_exists: true,
- },
+ const returnPromise = state =>
+ new Promise(resolve => {
+ resolve({
+ data: {
+ state,
+ source_branch_exists: true,
+ },
+ });
});
- });
beforeEach(() => {
loadFixtures('merge_requests/merge_request_of_current_user.html.raw');
});
- it('should call start and stop polling when MR merged', (done) => {
+ it('should call start and stop polling when MR merged', done => {
spyOn(eventHub, '$emit');
spyOn(vm.service, 'poll').and.returnValue(returnPromise('merged'));
spyOn(vm, 'initiateRemoveSourceBranchPolling');
@@ -382,7 +417,14 @@ describe('ReadyToMerge', () => {
let cpc = false; // continuePollingCalled
let spc = false; // stopPollingCalled
- vm.handleMergePolling(() => { cpc = true; }, () => { spc = true; });
+ vm.handleMergePolling(
+ () => {
+ cpc = true;
+ },
+ () => {
+ spc = true;
+ },
+ );
setTimeout(() => {
expect(vm.service.poll).toHaveBeenCalled();
expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
@@ -395,7 +437,7 @@ describe('ReadyToMerge', () => {
}, 333);
});
- it('updates status box', (done) => {
+ it('updates status box', done => {
spyOn(vm.service, 'poll').and.returnValue(returnPromise('merged'));
spyOn(vm, 'initiateRemoveSourceBranchPolling');
@@ -403,6 +445,7 @@ describe('ReadyToMerge', () => {
setTimeout(() => {
const statusBox = document.querySelector('.status-box');
+
expect(statusBox.classList.contains('status-box-mr-merged')).toBeTruthy();
expect(statusBox.textContent).toContain('Merged');
@@ -410,7 +453,7 @@ describe('ReadyToMerge', () => {
});
});
- it('hides close button', (done) => {
+ it('hides close button', done => {
spyOn(vm.service, 'poll').and.returnValue(returnPromise('merged'));
spyOn(vm, 'initiateRemoveSourceBranchPolling');
@@ -423,7 +466,7 @@ describe('ReadyToMerge', () => {
});
});
- it('updates merge request count badge', (done) => {
+ it('updates merge request count badge', done => {
spyOn(vm.service, 'poll').and.returnValue(returnPromise('merged'));
spyOn(vm, 'initiateRemoveSourceBranchPolling');
@@ -436,14 +479,21 @@ describe('ReadyToMerge', () => {
});
});
- it('should continue polling until MR is merged', (done) => {
+ it('should continue polling until MR is merged', done => {
spyOn(vm.service, 'poll').and.returnValue(returnPromise('some_other_state'));
spyOn(vm, 'initiateRemoveSourceBranchPolling');
let cpc = false; // continuePollingCalled
let spc = false; // stopPollingCalled
- vm.handleMergePolling(() => { cpc = true; }, () => { spc = true; });
+ vm.handleMergePolling(
+ () => {
+ cpc = true;
+ },
+ () => {
+ spc = true;
+ },
+ );
setTimeout(() => {
expect(cpc).toBeTruthy();
expect(spc).toBeFalsy();
@@ -459,35 +509,46 @@ describe('ReadyToMerge', () => {
const simplePoll = spyOnDependency(ReadyToMerge, 'simplePoll');
vm.initiateRemoveSourceBranchPolling();
+
expect(eventHub.$emit).toHaveBeenCalledWith('SetBranchRemoveFlag', [true]);
expect(simplePoll).toHaveBeenCalled();
});
});
describe('handleRemoveBranchPolling', () => {
- const returnPromise = state => new Promise((resolve) => {
- resolve({
- data: {
- source_branch_exists: state,
- },
+ const returnPromise = state =>
+ new Promise(resolve => {
+ resolve({
+ data: {
+ source_branch_exists: state,
+ },
+ });
});
- });
- it('should call start and stop polling when MR merged', (done) => {
+ it('should call start and stop polling when MR merged', done => {
spyOn(eventHub, '$emit');
spyOn(vm.service, 'poll').and.returnValue(returnPromise(false));
let cpc = false; // continuePollingCalled
let spc = false; // stopPollingCalled
- vm.handleRemoveBranchPolling(() => { cpc = true; }, () => { spc = true; });
+ vm.handleRemoveBranchPolling(
+ () => {
+ cpc = true;
+ },
+ () => {
+ spc = true;
+ },
+ );
setTimeout(() => {
expect(vm.service.poll).toHaveBeenCalled();
const args = eventHub.$emit.calls.argsFor(0);
+
expect(args[0]).toEqual('MRWidgetUpdateRequested');
expect(args[1]).toBeDefined();
args[1]();
+
expect(eventHub.$emit).toHaveBeenCalledWith('SetBranchRemoveFlag', [false]);
expect(cpc).toBeFalsy();
@@ -497,13 +558,20 @@ describe('ReadyToMerge', () => {
}, 333);
});
- it('should continue polling until MR is merged', (done) => {
+ it('should continue polling until MR is merged', done => {
spyOn(vm.service, 'poll').and.returnValue(returnPromise(true));
let cpc = false; // continuePollingCalled
let spc = false; // stopPollingCalled
- vm.handleRemoveBranchPolling(() => { cpc = true; }, () => { spc = true; });
+ vm.handleRemoveBranchPolling(
+ () => {
+ cpc = true;
+ },
+ () => {
+ spc = true;
+ },
+ );
setTimeout(() => {
expect(cpc).toBeTruthy();
expect(spc).toBeFalsy();
@@ -518,6 +586,7 @@ describe('ReadyToMerge', () => {
describe('when user can merge but cannot delete branch', () => {
it('should be disabled in the rendered output', () => {
const checkboxElement = vm.$el.querySelector('#remove-source-branch-input');
+
expect(checkboxElement).toBeNull();
});
});
@@ -537,6 +606,7 @@ describe('ReadyToMerge', () => {
it('should be enabled in rendered output', () => {
const checkboxElement = customVm.$el.querySelector('#remove-source-branch-input');
+
expect(checkboxElement).not.toBeNull();
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js
index abf642c166a..36f8c7a9683 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_sha_mismatch_spec.js
@@ -18,8 +18,8 @@ describe('ShaMismatch', () => {
it('should render information message', () => {
expect(vm.$el.querySelector('button').disabled).toEqual(true);
- expect(
- removeBreakLine(vm.$el.textContent).trim(),
- ).toContain('The source branch HEAD has recently changed. Please reload the page and review the changes before merging');
+ expect(removeBreakLine(vm.$el.textContent).trim()).toContain(
+ 'The source branch HEAD has recently changed. Please reload the page and review the changes before merging',
+ );
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js
index d797f1266df..bd64d7b2926 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js
@@ -12,13 +12,18 @@ describe('UnresolvedDiscussions', () => {
describe('with discussions path', () => {
beforeEach(() => {
- vm = mountComponent(Component, { mr: {
- createIssueToResolveDiscussionsPath: gl.TEST_HOST,
- } });
+ vm = mountComponent(Component, {
+ mr: {
+ createIssueToResolveDiscussionsPath: gl.TEST_HOST,
+ },
+ });
});
it('should have correct elements', () => {
- expect(vm.$el.innerText).toContain('There are unresolved discussions. Please resolve these discussions');
+ expect(vm.$el.innerText).toContain(
+ 'There are unresolved discussions. Please resolve these discussions',
+ );
+
expect(vm.$el.innerText).toContain('Create an issue to resolve them later');
expect(vm.$el.querySelector('.js-create-issue').getAttribute('href')).toEqual(gl.TEST_HOST);
});
@@ -30,7 +35,10 @@ describe('UnresolvedDiscussions', () => {
});
it('should not show create issue link if user cannot create issue', () => {
- expect(vm.$el.innerText).toContain('There are unresolved discussions. Please resolve these discussions');
+ expect(vm.$el.innerText).toContain(
+ 'There are unresolved discussions. Please resolve these discussions',
+ );
+
expect(vm.$el.querySelector('.js-create-issue')).toEqual(null);
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js
index cea603368bf..88937df2f7b 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_wip_spec.js
@@ -33,6 +33,7 @@ describe('Wip', () => {
describe('data', () => {
it('should have default data', () => {
const vm = createComponent();
+
expect(vm.isMakingRequest).toBeFalsy();
});
});
@@ -43,22 +44,27 @@ describe('Wip', () => {
};
describe('removeWIP', () => {
- it('should make a request to service and handle response', (done) => {
+ it('should make a request to service and handle response', done => {
const vm = createComponent();
spyOn(window, 'Flash').and.returnValue(true);
spyOn(eventHub, '$emit');
- spyOn(vm.service, 'removeWIP').and.returnValue(new Promise((resolve) => {
- resolve({
- data: mrObj,
- });
- }));
+ spyOn(vm.service, 'removeWIP').and.returnValue(
+ new Promise(resolve => {
+ resolve({
+ data: mrObj,
+ });
+ }),
+ );
vm.removeWIP();
setTimeout(() => {
expect(vm.isMakingRequest).toBeTruthy();
expect(eventHub.$emit).toHaveBeenCalledWith('UpdateWidgetData', mrObj);
- expect(window.Flash).toHaveBeenCalledWith('The merge request can now be merged.', 'notice');
+ expect(window.Flash).toHaveBeenCalledWith(
+ 'The merge request can now be merged.',
+ 'notice',
+ );
done();
}, 333);
});
@@ -82,7 +88,7 @@ describe('Wip', () => {
expect(el.querySelector('.js-remove-wip').innerText).toContain('Resolve WIP status');
});
- it('should not show removeWIP button is user cannot update MR', (done) => {
+ it('should not show removeWIP button is user cannot update MR', done => {
vm.mr.removeWIPPath = '';
Vue.nextTick(() => {
diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
index 6ac7138743b..d1a064b9f4d 100644
--- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
+++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
@@ -7,11 +7,12 @@ import mountComponent from 'spec/helpers/vue_mount_component_helper';
import mockData from './mock_data';
import { faviconDataUrl, overlayDataUrl, faviconWithOverlayDataUrl } from '../lib/utils/mock_data';
-const returnPromise = data => new Promise((resolve) => {
- resolve({
- data,
+const returnPromise = data =>
+ new Promise(resolve => {
+ resolve({
+ data,
+ });
});
-});
describe('mrWidgetOptions', () => {
let vm;
@@ -46,6 +47,7 @@ describe('mrWidgetOptions', () => {
it('should return conflicts component', () => {
vm.mr.state = 'conflicts';
+
expect(vm.componentName).toEqual('mr-widget-conflicts');
});
});
@@ -57,6 +59,7 @@ describe('mrWidgetOptions', () => {
it('should return true for a state which requires help widget', () => {
vm.mr.state = 'conflicts';
+
expect(vm.shouldRenderMergeHelp).toBeTruthy();
});
});
@@ -82,6 +85,7 @@ describe('mrWidgetOptions', () => {
it('should return true if there is relatedLinks in MR', () => {
Vue.set(vm.mr, 'relatedLinks', {});
+
expect(vm.shouldRenderRelatedLinks).toBeTruthy();
});
});
@@ -132,7 +136,7 @@ describe('mrWidgetOptions', () => {
describe('methods', () => {
describe('checkStatus', () => {
- it('should tell service to check status', (done) => {
+ it('should tell service to check status', done => {
spyOn(vm.service, 'checkStatus').and.returnValue(returnPromise(mockData));
spyOn(vm.mr, 'setData');
spyOn(vm, 'handleNotification');
@@ -182,7 +186,7 @@ describe('mrWidgetOptions', () => {
});
describe('fetchDeployments', () => {
- it('should fetch deployments', (done) => {
+ it('should fetch deployments', done => {
spyOn(vm.service, 'fetchDeployments').and.returnValue(returnPromise([{ id: 1 }]));
vm.fetchDeployments();
@@ -197,7 +201,7 @@ describe('mrWidgetOptions', () => {
});
describe('fetchActionsContent', () => {
- it('should fetch content of Cherry Pick and Revert modals', (done) => {
+ it('should fetch content of Cherry Pick and Revert modals', done => {
spyOn(vm.service, 'fetchMergeActionsContent').and.returnValue(returnPromise('hello world'));
vm.fetchActionsContent();
@@ -223,18 +227,23 @@ describe('mrWidgetOptions', () => {
vm.bindEventHubListeners();
eventHub.$emit('SetBranchRemoveFlag', ['flag']);
+
expect(vm.mr.isRemovingSourceBranch).toEqual('flag');
eventHub.$emit('FailedToMerge');
+
expect(vm.mr.state).toEqual('failedToMerge');
eventHub.$emit('UpdateWidgetData', mockData);
+
expect(vm.mr.setData).toHaveBeenCalledWith(mockData);
eventHub.$emit('EnablePolling');
+
expect(vm.resumePolling).toHaveBeenCalled();
eventHub.$emit('DisablePolling');
+
expect(vm.stopPolling).toHaveBeenCalled();
const listenersWithServiceRequest = {
@@ -243,7 +252,7 @@ describe('mrWidgetOptions', () => {
};
const allArgs = eventHub.$on.calls.allArgs();
- allArgs.forEach((params) => {
+ allArgs.forEach(params => {
const eventName = params[0];
const callback = params[1];
@@ -253,22 +262,12 @@ describe('mrWidgetOptions', () => {
});
listenersWithServiceRequest.MRWidgetUpdateRequested();
+
expect(vm.checkStatus).toHaveBeenCalled();
listenersWithServiceRequest.FetchActionsContent();
- expect(vm.fetchActionsContent).toHaveBeenCalled();
- });
- });
-
- describe('handleMounted', () => {
- it('should call required methods to do the initial kick-off', () => {
- spyOn(vm, 'initDeploymentsPolling');
- spyOn(vm, 'setFaviconHelper');
- vm.handleMounted();
-
- expect(vm.setFaviconHelper).toHaveBeenCalled();
- expect(vm.initDeploymentsPolling).toHaveBeenCalled();
+ expect(vm.fetchActionsContent).toHaveBeenCalled();
});
});
@@ -288,13 +287,14 @@ describe('mrWidgetOptions', () => {
document.body.removeChild(document.getElementById('favicon'));
});
- it('should call setFavicon method', (done) => {
+ it('should call setFavicon method', done => {
vm.mr.ciStatusFaviconPath = overlayDataUrl;
- vm.setFaviconHelper().then(() => {
- expect(faviconElement.getAttribute('href')).toEqual(faviconWithOverlayDataUrl);
- done();
- })
- .catch(done.fail);
+ vm.setFaviconHelper()
+ .then(() => {
+ expect(faviconElement.getAttribute('href')).toEqual(faviconWithOverlayDataUrl);
+ done();
+ })
+ .catch(done.fail);
});
it('should not call setFavicon when there is no ciStatusFaviconPath', () => {
@@ -352,6 +352,7 @@ describe('mrWidgetOptions', () => {
spyOn(vm.pollingInterval, 'resume');
vm.resumePolling();
+
expect(vm.pollingInterval.resume).toHaveBeenCalled();
});
});
@@ -361,13 +362,14 @@ describe('mrWidgetOptions', () => {
spyOn(vm.pollingInterval, 'stopTimer');
vm.stopPolling();
+
expect(vm.pollingInterval.stopTimer).toHaveBeenCalled();
});
});
});
describe('rendering relatedLinks', () => {
- beforeEach((done) => {
+ beforeEach(done => {
vm.mr.relatedLinks = {
assignToMe: null,
closing: `
@@ -384,7 +386,7 @@ describe('mrWidgetOptions', () => {
expect(vm.$el.querySelector('.close-related-link')).toBeDefined();
});
- it('does not render if state is nothingToMerge', (done) => {
+ it('does not render if state is nothingToMerge', done => {
vm.mr.state = stateKey.nothingToMerge;
Vue.nextTick(() => {
expect(vm.$el.querySelector('.close-related-link')).toBeNull();
@@ -394,7 +396,7 @@ describe('mrWidgetOptions', () => {
});
describe('rendering source branch removal status', () => {
- it('renders when user cannot remove branch and branch should be removed', (done) => {
+ it('renders when user cannot remove branch and branch should be removed', done => {
vm.mr.canRemoveSourceBranch = false;
vm.mr.shouldRemoveSourceBranch = true;
vm.mr.state = 'readyToMerge';
@@ -411,7 +413,7 @@ describe('mrWidgetOptions', () => {
});
});
- it('does not render in merged state', (done) => {
+ it('does not render in merged state', done => {
vm.mr.canRemoveSourceBranch = false;
vm.mr.shouldRemoveSourceBranch = true;
vm.mr.state = 'merged';
@@ -426,6 +428,20 @@ describe('mrWidgetOptions', () => {
});
describe('rendering deployments', () => {
+ const changes = [
+ {
+ path: 'index.html',
+ external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/index.html',
+ },
+ {
+ path: 'imgs/gallery.html',
+ external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/imgs/gallery.html',
+ },
+ {
+ path: 'about/',
+ external_url: 'http://root-master-patch-91341.volatile-watch.surge.sh/about/',
+ },
+ ];
const deploymentMockData = {
id: 15,
name: 'review/diplo',
@@ -437,15 +453,23 @@ describe('mrWidgetOptions', () => {
external_url_formatted: 'diplo.',
deployed_at: '2017-03-22T22:44:42.258Z',
deployed_at_formatted: 'Mar 22, 2017 10:44pm',
+ changes,
};
- beforeEach((done) => {
- vm.mr.deployments.push({
- ...deploymentMockData,
- }, {
- ...deploymentMockData,
- id: deploymentMockData.id + 1,
- });
+ beforeEach(done => {
+ window.gon = window.gon || {};
+ window.gon.features = window.gon.features || {};
+ window.gon.features.ciEnvironmentsStatusChanges = true;
+
+ vm.mr.deployments.push(
+ {
+ ...deploymentMockData,
+ },
+ {
+ ...deploymentMockData,
+ id: deploymentMockData.id + 1,
+ },
+ );
vm.$nextTick(done);
});
@@ -453,5 +477,13 @@ describe('mrWidgetOptions', () => {
it('renders multiple deployments', () => {
expect(vm.$el.querySelectorAll('.deploy-heading').length).toBe(2);
});
+
+ it('renders dropdpown with multiple file changes', () => {
+ expect(
+ vm.$el
+ .querySelector('.js-mr-wigdet-deployment-dropdown')
+ .querySelectorAll('.js-filtered-dropdown-result').length,
+ ).toEqual(changes.length);
+ });
});
});
diff --git a/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js b/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js
index 179e42a7cc4..9d34bdd1084 100644
--- a/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js
+++ b/spec/javascripts/vue_mr_widget/stores/get_state_key_spec.js
@@ -20,46 +20,60 @@ describe('getStateKey', () => {
work_in_progress: false,
};
const bound = getStateKey.bind(context, data);
+
expect(bound()).toEqual(null);
context.canBeMerged = true;
+
expect(bound()).toEqual('readyToMerge');
context.canMerge = false;
+
expect(bound()).toEqual('notAllowedToMerge');
context.mergeWhenPipelineSucceeds = true;
+
expect(bound()).toEqual('mergeWhenPipelineSucceeds');
context.hasSHAChanged = true;
+
expect(bound()).toEqual('shaMismatch');
context.isPipelineBlocked = true;
+
expect(bound()).toEqual('pipelineBlocked');
context.hasMergeableDiscussionsState = true;
+
expect(bound()).toEqual('unresolvedDiscussions');
context.onlyAllowMergeIfPipelineSucceeds = true;
context.isPipelineFailed = true;
+
expect(bound()).toEqual('pipelineFailed');
data.work_in_progress = true;
+
expect(bound()).toEqual('workInProgress');
data.has_conflicts = true;
+
expect(bound()).toEqual('conflicts');
context.mergeStatus = 'unchecked';
+
expect(bound()).toEqual('checking');
data.commits_count = 0;
+
expect(bound()).toEqual('nothingToMerge');
data.branch_missing = true;
+
expect(bound()).toEqual('missingBranch');
data.project_archived = true;
+
expect(bound()).toEqual('archived');
});
});
diff --git a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
index 33d052aceb2..f5079147f60 100644
--- a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
+++ b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
@@ -12,32 +12,38 @@ describe('MergeRequestStore', () => {
it('should set hasSHAChanged when the diff SHA changes', () => {
store.setData({ ...mockData, diff_head_sha: 'a-different-string' });
+
expect(store.hasSHAChanged).toBe(true);
});
it('should not set hasSHAChanged when other data changes', () => {
store.setData({ ...mockData, work_in_progress: !mockData.work_in_progress });
+
expect(store.hasSHAChanged).toBe(false);
});
describe('isPipelinePassing', () => {
it('is true when the CI status is `success`', () => {
store.setData({ ...mockData, ci_status: 'success' });
+
expect(store.isPipelinePassing).toBe(true);
});
it('is true when the CI status is `success_with_warnings`', () => {
store.setData({ ...mockData, ci_status: 'success_with_warnings' });
+
expect(store.isPipelinePassing).toBe(true);
});
it('is false when the CI status is `failed`', () => {
store.setData({ ...mockData, ci_status: 'failed' });
+
expect(store.isPipelinePassing).toBe(false);
});
it('is false when the CI status is anything except `success`', () => {
store.setData({ ...mockData, ci_status: 'foobarbaz' });
+
expect(store.isPipelinePassing).toBe(false);
});
});
@@ -45,11 +51,13 @@ describe('MergeRequestStore', () => {
describe('isPipelineSkipped', () => {
it('should set isPipelineSkipped=true when the CI status is `skipped`', () => {
store.setData({ ...mockData, ci_status: 'skipped' });
+
expect(store.isPipelineSkipped).toBe(true);
});
it('should set isPipelineSkipped=false when the CI status is anything except `skipped`', () => {
store.setData({ ...mockData, ci_status: 'foobarbaz' });
+
expect(store.isPipelineSkipped).toBe(false);
});
});
@@ -57,11 +65,13 @@ describe('MergeRequestStore', () => {
describe('isNothingToMergeState', () => {
it('returns true when nothingToMerge', () => {
store.state = stateKey.nothingToMerge;
+
expect(store.isNothingToMergeState).toEqual(true);
});
it('returns false when not nothingToMerge', () => {
store.state = 'state';
+
expect(store.isNothingToMergeState).toEqual(false);
});
});
diff --git a/spec/javascripts/vue_shared/components/bar_chart_spec.js b/spec/javascripts/vue_shared/components/bar_chart_spec.js
index 7e91cd6f63f..8f753876e44 100644
--- a/spec/javascripts/vue_shared/components/bar_chart_spec.js
+++ b/spec/javascripts/vue_shared/components/bar_chart_spec.js
@@ -71,12 +71,6 @@ describe('Bar chart component', () => {
expect(barChart.xAxisLocation).toEqual('translate(100, 250)');
});
- it('Contains a total of 4 ticks across the y axis', () => {
- const ticks = barChart.$el.querySelector('.y-axis').querySelectorAll('.tick').length;
-
- expect(ticks).toEqual(4);
- });
-
it('rotates the x axis labels a total of 90 degress (CCW)', () => {
const xAxisLabel = barChart.$el.querySelector('.x-axis').querySelectorAll('text')[0];
diff --git a/spec/javascripts/vue_shared/components/ci_badge_link_spec.js b/spec/javascripts/vue_shared/components/ci_badge_link_spec.js
index 668742ebaee..4b0b7ba66e5 100644
--- a/spec/javascripts/vue_shared/components/ci_badge_link_spec.js
+++ b/spec/javascripts/vue_shared/components/ci_badge_link_spec.js
@@ -81,11 +81,12 @@ describe('CI Badge Link Component', () => {
});
it('should render each status badge', () => {
- Object.keys(statuses).map((status) => {
+ Object.keys(statuses).map(status => {
vm = mountComponent(CIBadge, { status: statuses[status] });
+
expect(vm.$el.getAttribute('href')).toEqual(statuses[status].details_path);
expect(vm.$el.textContent.trim()).toEqual(statuses[status].text);
- expect(vm.$el.getAttribute('class')).toEqual(`ci-status ci-${statuses[status].group}`);
+ expect(vm.$el.getAttribute('class')).toContain(`ci-status ci-${statuses[status].group}`);
expect(vm.$el.querySelector('svg')).toBeDefined();
return vm;
});
@@ -93,6 +94,7 @@ describe('CI Badge Link Component', () => {
it('should not render label', () => {
vm = mountComponent(CIBadge, { status: statuses.canceled, showText: false });
+
expect(vm.$el.textContent.trim()).toEqual('');
});
});
diff --git a/spec/javascripts/vue_shared/components/clipboard_button_spec.js b/spec/javascripts/vue_shared/components/clipboard_button_spec.js
index ea525b1e44f..2f7ea077b54 100644
--- a/spec/javascripts/vue_shared/components/clipboard_button_spec.js
+++ b/spec/javascripts/vue_shared/components/clipboard_button_spec.js
@@ -44,6 +44,7 @@ describe('clipboard button', () => {
title: 'Copy this value into Clipboard!',
cssClass: 'btn-danger',
});
+
expect(vm.$el.getAttribute('data-clipboard-text')).toEqual(
'{"text":"copy me","gfm":"`path/to/file`"}',
);
diff --git a/spec/javascripts/vue_shared/components/commit_spec.js b/spec/javascripts/vue_shared/components/commit_spec.js
index 7189e8cfcfa..97dacec1fce 100644
--- a/spec/javascripts/vue_shared/components/commit_spec.js
+++ b/spec/javascripts/vue_shared/components/commit_spec.js
@@ -78,6 +78,7 @@ describe('Commit component', () => {
expect(component.$el.querySelector('.commit-sha').getAttribute('href')).toEqual(
props.commitUrl,
);
+
expect(component.$el.querySelector('.commit-sha').textContent).toContain(props.shortSha);
});
@@ -100,6 +101,7 @@ describe('Commit component', () => {
.querySelector('.commit-title .avatar-image-container img')
.getAttribute('data-original-title'),
).toContain(props.author.username);
+
expect(
component.$el
.querySelector('.commit-title .avatar-image-container img')
@@ -112,6 +114,7 @@ describe('Commit component', () => {
expect(component.$el.querySelector('a.commit-row-message').getAttribute('href')).toEqual(
props.commitUrl,
);
+
expect(component.$el.querySelector('a.commit-row-message').textContent).toContain(
props.title,
);
diff --git a/spec/javascripts/vue_shared/components/deprecated_modal_spec.js b/spec/javascripts/vue_shared/components/deprecated_modal_spec.js
index 59d4e549a91..be75be92158 100644
--- a/spec/javascripts/vue_shared/components/deprecated_modal_spec.js
+++ b/spec/javascripts/vue_shared/components/deprecated_modal_spec.js
@@ -47,7 +47,7 @@ describe('DeprecatedModal', () => {
});
});
- it('works with data-toggle="modal"', (done) => {
+ it('works with data-toggle="modal"', done => {
setFixtures(`
<button id="modal-button" data-toggle="modal" data-target="#my-modal"></button>
<div id="modal-container"></div>
@@ -55,9 +55,13 @@ describe('DeprecatedModal', () => {
const modalContainer = document.getElementById('modal-container');
const modalButton = document.getElementById('modal-button');
- vm = mountComponent(modalComponent, {
- id: 'my-modal',
- }, modalContainer);
+ vm = mountComponent(
+ modalComponent,
+ {
+ id: 'my-modal',
+ },
+ modalContainer,
+ );
const modalElement = vm.$el.querySelector('#my-modal');
$(modalElement).on('shown.bs.modal', () => done());
diff --git a/spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js b/spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js
index 71d9145bf22..fcd231ec693 100644
--- a/spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js
+++ b/spec/javascripts/vue_shared/components/diff_viewer/diff_viewer_spec.js
@@ -55,6 +55,7 @@ describe('DiffViewer', () => {
expect(vm.$el.querySelector('.deleted .file-info').textContent.trim()).toContain(
'testold.abc',
);
+
expect(vm.$el.querySelector('.deleted .btn.btn-default').textContent.trim()).toContain(
'Download',
);
diff --git a/spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js b/spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js
index dde49b4a5d7..380effdb669 100644
--- a/spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js
+++ b/spec/javascripts/vue_shared/components/diff_viewer/viewers/image_diff_viewer_spec.js
@@ -55,6 +55,7 @@ describe('ImageDiffViewer', () => {
expect(vm.$el.querySelector('.added .image_file img').getAttribute('src')).toBe(
GREEN_BOX_IMAGE_URL,
);
+
expect(vm.$el.querySelector('.deleted .image_file img').getAttribute('src')).toBe(
RED_BOX_IMAGE_URL,
);
@@ -63,6 +64,7 @@ describe('ImageDiffViewer', () => {
expect(vm.$el.querySelector('.view-modes-menu li:nth-child(2)').textContent.trim()).toBe(
'Swipe',
);
+
expect(vm.$el.querySelector('.view-modes-menu li:nth-child(3)').textContent.trim()).toBe(
'Onion skin',
);
diff --git a/spec/javascripts/vue_shared/components/dropdown/dropdown_button_spec.js b/spec/javascripts/vue_shared/components/dropdown/dropdown_button_spec.js
index 2796cd088c6..2fc4943de30 100644
--- a/spec/javascripts/vue_shared/components/dropdown/dropdown_button_spec.js
+++ b/spec/javascripts/vue_shared/components/dropdown/dropdown_button_spec.js
@@ -55,6 +55,7 @@ describe('DropdownButtonComponent', () => {
it('renders dropdown toggle text element', () => {
const dropdownToggleTextEl = vm.$el.querySelector('.dropdown-toggle-text');
+
expect(dropdownToggleTextEl).not.toBeNull();
expect(dropdownToggleTextEl.innerText.trim()).toBe(defaultLabel);
});
@@ -67,9 +68,12 @@ describe('DropdownButtonComponent', () => {
});
it('renders slot, if default slot exists', () => {
- vm = createComponent({}, {
- default: ['Lorem Ipsum Dolar'],
- });
+ vm = createComponent(
+ {},
+ {
+ default: ['Lorem Ipsum Dolar'],
+ },
+ );
expect(vm.$el).not.toContainElement('.dropdown-toggle-text');
expect(vm.$el).toHaveText('Lorem Ipsum Dolar');
diff --git a/spec/javascripts/vue_shared/components/file_icon_spec.js b/spec/javascripts/vue_shared/components/file_icon_spec.js
index f2a09d08829..34c9b35e02a 100644
--- a/spec/javascripts/vue_shared/components/file_icon_spec.js
+++ b/spec/javascripts/vue_shared/components/file_icon_spec.js
@@ -28,7 +28,9 @@ describe('File Icon component', () => {
fileName: 'test.js',
});
- expect(vm.$el.firstChild.firstChild.getAttribute('xlink:href')).toBe(`${gon.sprite_file_icons}#javascript`);
+ expect(vm.$el.firstChild.firstChild.getAttribute('xlink:href')).toBe(
+ `${gon.sprite_file_icons}#javascript`,
+ );
});
it('should render a image icon based on file ending', () => {
@@ -36,7 +38,9 @@ describe('File Icon component', () => {
fileName: 'test.png',
});
- expect(vm.$el.firstChild.firstChild.getAttribute('xlink:href')).toBe(`${gon.sprite_file_icons}#image`);
+ expect(vm.$el.firstChild.firstChild.getAttribute('xlink:href')).toBe(
+ `${gon.sprite_file_icons}#image`,
+ );
});
it('should render a webpack icon based on file namer', () => {
@@ -44,7 +48,9 @@ describe('File Icon component', () => {
fileName: 'webpack.js',
});
- expect(vm.$el.firstChild.firstChild.getAttribute('xlink:href')).toBe(`${gon.sprite_file_icons}#webpack`);
+ expect(vm.$el.firstChild.firstChild.getAttribute('xlink:href')).toBe(
+ `${gon.sprite_file_icons}#webpack`,
+ );
});
it('should render a standard folder icon', () => {
@@ -53,7 +59,9 @@ describe('File Icon component', () => {
folder: true,
});
- expect(vm.$el.querySelector('span > svg > use').getAttribute('xlink:href')).toBe(`${gon.sprite_file_icons}#folder`);
+ expect(vm.$el.querySelector('span > svg > use').getAttribute('xlink:href')).toBe(
+ `${gon.sprite_file_icons}#folder`,
+ );
});
it('should render a loading icon', () => {
@@ -63,6 +71,7 @@ describe('File Icon component', () => {
});
const { classList } = vm.$el.querySelector('i');
+
expect(classList.contains('fa')).toEqual(true);
expect(classList.contains('fa-spin')).toEqual(true);
expect(classList.contains('fa-spinner')).toEqual(true);
@@ -79,6 +88,7 @@ describe('File Icon component', () => {
const { classList } = vm.$el.firstChild;
const containsSizeClass = classList.contains('s120');
const containsCustomClass = classList.contains('extraclasses');
+
expect(containsSizeClass).toBe(true);
expect(containsCustomClass).toBe(true);
});
diff --git a/spec/javascripts/vue_shared/components/file_row_spec.js b/spec/javascripts/vue_shared/components/file_row_spec.js
index 9914c0b70f3..67752c1c455 100644
--- a/spec/javascripts/vue_shared/components/file_row_spec.js
+++ b/spec/javascripts/vue_shared/components/file_row_spec.js
@@ -71,4 +71,40 @@ describe('RepoFile', () => {
expect(vm.$el.querySelector('.file-row-name').style.marginLeft).toBe('32px');
});
+
+ describe('outputText', () => {
+ beforeEach(done => {
+ createComponent({
+ file: {
+ ...file(),
+ path: 'app/assets/index.js',
+ },
+ level: 0,
+ });
+
+ vm.displayTextKey = 'path';
+
+ vm.$nextTick(done);
+ });
+
+ it('returns text if truncateStart is 0', done => {
+ vm.truncateStart = 0;
+
+ vm.$nextTick(() => {
+ expect(vm.outputText).toBe('app/assets/index.js');
+
+ done();
+ });
+ });
+
+ it('returns text truncated at start', done => {
+ vm.truncateStart = 5;
+
+ vm.$nextTick(() => {
+ expect(vm.outputText).toBe('...ssets/index.js');
+
+ done();
+ });
+ });
+ });
});
diff --git a/spec/javascripts/vue_shared/components/filtered_search_dropdown_spec.js b/spec/javascripts/vue_shared/components/filtered_search_dropdown_spec.js
new file mode 100644
index 00000000000..b71cb36ecf6
--- /dev/null
+++ b/spec/javascripts/vue_shared/components/filtered_search_dropdown_spec.js
@@ -0,0 +1,91 @@
+import Vue from 'vue';
+import component from '~/vue_shared/components/filtered_search_dropdown.vue';
+import mountComponent from 'spec/helpers/vue_mount_component_helper';
+
+describe('Filtered search dropdown', () => {
+ const Component = Vue.extend(component);
+ let vm;
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('with an empty array of items', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ items: [],
+ filterKey: '',
+ });
+ });
+
+ it('renders empty list', () => {
+ expect(vm.$el.querySelectorAll('.js-filtered-dropdown-result').length).toEqual(0);
+ });
+
+ it('renders filter input', () => {
+ expect(vm.$el.querySelector('.js-filtered-dropdown-input')).not.toBeNull();
+ });
+ });
+
+ describe('when visible numbers is less than the items length', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ items: [{ title: 'One' }, { title: 'Two' }, { title: 'Three' }],
+ visibleItems: 2,
+ filterKey: 'title',
+ });
+ });
+
+ it('it renders only the maximum number provided', () => {
+ expect(vm.$el.querySelectorAll('.js-filtered-dropdown-result').length).toEqual(2);
+ });
+ });
+
+ describe('when visible number is bigger than the items lenght', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ items: [{ title: 'One' }, { title: 'Two' }, { title: 'Three' }],
+ filterKey: 'title',
+ });
+ });
+
+ it('it renders the full list of items the maximum number provided', () => {
+ expect(vm.$el.querySelectorAll('.js-filtered-dropdown-result').length).toEqual(3);
+ });
+ });
+
+ describe('while filtering', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ items: [
+ { title: 'One' },
+ { title: 'Two/three' },
+ { title: 'Three four' },
+ { title: 'Five' },
+ ],
+ filterKey: 'title',
+ });
+ });
+
+ it('updates the results to match the typed value', done => {
+ vm.$el.querySelector('.js-filtered-dropdown-input').value = 'three';
+ vm.$el.querySelector('.js-filtered-dropdown-input').dispatchEvent(new Event('input'));
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelectorAll('.js-filtered-dropdown-result').length).toEqual(2);
+ done();
+ });
+ });
+
+ describe('when no value matches the typed one', () => {
+ it('does not render any result', done => {
+ vm.$el.querySelector('.js-filtered-dropdown-input').value = 'six';
+ vm.$el.querySelector('.js-filtered-dropdown-input').dispatchEvent(new Event('input'));
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelectorAll('.js-filtered-dropdown-result').length).toEqual(0);
+ done();
+ });
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/vue_shared/components/gl_countdown_spec.js b/spec/javascripts/vue_shared/components/gl_countdown_spec.js
new file mode 100644
index 00000000000..929ffe219f4
--- /dev/null
+++ b/spec/javascripts/vue_shared/components/gl_countdown_spec.js
@@ -0,0 +1,77 @@
+import mountComponent from 'spec/helpers/vue_mount_component_helper';
+import Vue from 'vue';
+import GlCountdown from '~/vue_shared/components/gl_countdown.vue';
+
+describe('GlCountdown', () => {
+ const Component = Vue.extend(GlCountdown);
+ let vm;
+ let now = '2000-01-01T00:00:00Z';
+
+ beforeEach(() => {
+ spyOn(Date, 'now').and.callFake(() => new Date(now).getTime());
+ jasmine.clock().install();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ jasmine.clock().uninstall();
+ });
+
+ describe('when there is time remaining', () => {
+ beforeEach(done => {
+ vm = mountComponent(Component, {
+ endDateString: '2000-01-01T01:02:03Z',
+ });
+
+ Vue.nextTick()
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('displays remaining time', () => {
+ expect(vm.$el).toContainText('01:02:03');
+ });
+
+ it('updates remaining time', done => {
+ now = '2000-01-01T00:00:01Z';
+ jasmine.clock().tick(1000);
+
+ Vue.nextTick()
+ .then(() => {
+ expect(vm.$el).toContainText('01:02:02');
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
+ describe('when there is no time remaining', () => {
+ beforeEach(done => {
+ vm = mountComponent(Component, {
+ endDateString: '1900-01-01T00:00:00Z',
+ });
+
+ Vue.nextTick()
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('displays 00:00:00', () => {
+ expect(vm.$el).toContainText('00:00:00');
+ });
+ });
+
+ describe('when an invalid date is passed', () => {
+ it('throws a validation error', () => {
+ spyOn(Vue.config, 'warnHandler').and.stub();
+ vm = mountComponent(Component, {
+ endDateString: 'this is invalid',
+ });
+
+ expect(Vue.config.warnHandler).toHaveBeenCalledTimes(1);
+ const [errorMessage] = Vue.config.warnHandler.calls.argsFor(0);
+
+ expect(errorMessage).toMatch(/^Invalid prop: .* "endDateString"/);
+ });
+ });
+});
diff --git a/spec/javascripts/vue_shared/components/gl_modal_spec.js b/spec/javascripts/vue_shared/components/gl_modal_spec.js
index 263824a102a..19af8b5d2f7 100644
--- a/spec/javascripts/vue_shared/components/gl_modal_spec.js
+++ b/spec/javascripts/vue_shared/components/gl_modal_spec.js
@@ -48,6 +48,7 @@ describe('GlModal', () => {
it('sets the modal title', () => {
const modalTitle = vm.$el.querySelector('.modal-title');
+
expect(modalTitle.innerHTML.trim()).toBe(props.headerTitleText);
});
});
@@ -63,6 +64,7 @@ describe('GlModal', () => {
it('sets the primary button class', () => {
const primaryButton = vm.$el.querySelector('.modal-footer button:last-of-type');
+
expect(primaryButton).toHaveClass(`btn-${props.footerPrimaryButtonVariant}`);
});
});
@@ -78,6 +80,7 @@ describe('GlModal', () => {
it('sets the primary button text', () => {
const primaryButton = vm.$el.querySelector('.modal-footer button:last-of-type');
+
expect(primaryButton.innerHTML.trim()).toBe(props.footerPrimaryButtonText);
});
});
@@ -173,6 +176,7 @@ describe('GlModal', () => {
it('sets the modal body', () => {
const modalBody = vm.$el.querySelector('.modal-body');
+
expect(modalBody.innerHTML).toBe(slotContent);
});
});
@@ -184,6 +188,7 @@ describe('GlModal', () => {
it('sets the modal header', () => {
const modalHeader = vm.$el.querySelector('.modal-header');
+
expect(modalHeader.innerHTML).toBe(slotContent);
});
});
@@ -195,6 +200,7 @@ describe('GlModal', () => {
it('sets the modal title', () => {
const modalTitle = vm.$el.querySelector('.modal-title');
+
expect(modalTitle.innerHTML).toBe(slotContent);
});
});
@@ -206,6 +212,7 @@ describe('GlModal', () => {
it('sets the modal footer', () => {
const modalFooter = vm.$el.querySelector('.modal-footer');
+
expect(modalFooter.innerHTML).toBe(slotContent);
});
});
diff --git a/spec/javascripts/vue_shared/components/header_ci_component_spec.js b/spec/javascripts/vue_shared/components/header_ci_component_spec.js
index f17818c17c7..3bf497bc00b 100644
--- a/spec/javascripts/vue_shared/components/header_ci_component_spec.js
+++ b/spec/javascripts/vue_shared/components/header_ci_component_spec.js
@@ -59,9 +59,9 @@ describe('Header CI Component', () => {
it('should render status badge', () => {
expect(vm.$el.querySelector('.ci-failed')).toBeDefined();
expect(vm.$el.querySelector('.ci-status-icon-failed svg')).toBeDefined();
- expect(
- vm.$el.querySelector('.ci-failed').getAttribute('href'),
- ).toEqual(props.status.details_path);
+ expect(vm.$el.querySelector('.ci-failed').getAttribute('href')).toEqual(
+ props.status.details_path,
+ );
});
it('should render item name and id', () => {
@@ -84,7 +84,7 @@ describe('Header CI Component', () => {
expect(vm.$el.querySelector('.link').getAttribute('href')).toEqual(props.actions[0].path);
});
- it('should show loading icon', (done) => {
+ it('should show loading icon', done => {
vm.actions[0].isLoading = true;
Vue.nextTick(() => {
@@ -94,7 +94,7 @@ describe('Header CI Component', () => {
});
it('should render sidebar toggle button', () => {
- expect(vm.$el.querySelector('.js-sidebar-build-toggle')).toBeDefined();
+ expect(vm.$el.querySelector('.js-sidebar-build-toggle')).not.toBeNull();
});
});
diff --git a/spec/javascripts/vue_shared/components/icon_spec.js b/spec/javascripts/vue_shared/components/icon_spec.js
index 01f4649339e..45eef2ad737 100644
--- a/spec/javascripts/vue_shared/components/icon_spec.js
+++ b/spec/javascripts/vue_shared/components/icon_spec.js
@@ -2,11 +2,11 @@ import Vue from 'vue';
import Icon from '~/vue_shared/components/icon.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
-describe('Sprite Icon Component', function () {
- describe('Initialization', function () {
+describe('Sprite Icon Component', function() {
+ describe('Initialization', function() {
let icon;
- beforeEach(function () {
+ beforeEach(function() {
const IconComponent = Vue.extend(Icon);
icon = mountComponent(IconComponent, {
@@ -21,20 +21,20 @@ describe('Sprite Icon Component', function () {
icon.$destroy();
});
- it('should return a defined Vue component', function () {
+ it('should return a defined Vue component', function() {
expect(icon).toBeDefined();
});
- it('should have <svg> as a child element', function () {
+ it('should have <svg> as a child element', function() {
expect(icon.$el.tagName).toBe('svg');
});
- it('should have <use> as a child element with the correct href', function () {
+ it('should have <use> as a child element with the correct href', function() {
expect(icon.$el.firstChild.tagName).toBe('use');
expect(icon.$el.firstChild.getAttribute('xlink:href')).toBe(`${gon.sprite_icons}#commit`);
});
- it('should properly compute iconSizeClass', function () {
+ it('should properly compute iconSizeClass', function() {
expect(icon.iconSizeClass).toBe('s32');
});
@@ -44,10 +44,11 @@ describe('Sprite Icon Component', function () {
expect(icon.$options.props.size.validator(9001)).toBeFalsy();
});
- it('should properly render img css', function () {
+ it('should properly render img css', function() {
const { classList } = icon.$el;
const containsSizeClass = classList.contains('s32');
const containsCustomClass = classList.contains('extraclasses');
+
expect(containsSizeClass).toBe(true);
expect(containsCustomClass).toBe(true);
});
diff --git a/spec/javascripts/vue_shared/components/identicon_spec.js b/spec/javascripts/vue_shared/components/identicon_spec.js
index 0719800c682..0b3dbb61c96 100644
--- a/spec/javascripts/vue_shared/components/identicon_spec.js
+++ b/spec/javascripts/vue_shared/components/identicon_spec.js
@@ -1,7 +1,7 @@
import Vue from 'vue';
import identiconComponent from '~/vue_shared/components/identicon.vue';
-const createComponent = (sizeClass) => {
+const createComponent = sizeClass => {
const Component = Vue.extend(identiconComponent);
return new Component({
diff --git a/spec/javascripts/vue_shared/components/issue/issue_warning_spec.js b/spec/javascripts/vue_shared/components/issue/issue_warning_spec.js
index e6ed77dbb52..aa7d6ea2e34 100644
--- a/spec/javascripts/vue_shared/components/issue/issue_warning_spec.js
+++ b/spec/javascripts/vue_shared/components/issue/issue_warning_spec.js
@@ -6,7 +6,10 @@ const IssueWarning = Vue.extend(issueWarning);
function formatWarning(string) {
// Replace newlines with a space then replace multiple spaces with one space
- return string.trim().replace(/\n/g, ' ').replace(/\s\s+/g, ' ');
+ return string
+ .trim()
+ .replace(/\n/g, ' ')
+ .replace(/\s\s+/g, ' ');
}
describe('Issue Warning Component', () => {
@@ -17,7 +20,9 @@ describe('Issue Warning Component', () => {
});
expect(vm.$el.querySelector('.icon use').href.baseVal).toMatch(/lock$/);
- expect(formatWarning(vm.$el.querySelector('span').textContent)).toEqual('This issue is locked. Only project members can comment.');
+ expect(formatWarning(vm.$el.querySelector('span').textContent)).toEqual(
+ 'This issue is locked. Only project members can comment.',
+ );
});
});
@@ -28,7 +33,9 @@ describe('Issue Warning Component', () => {
});
expect(vm.$el.querySelector('.icon use').href.baseVal).toMatch(/eye-slash$/);
- expect(formatWarning(vm.$el.querySelector('span').textContent)).toEqual('This is a confidential issue. Your comment will not be visible to the public.');
+ expect(formatWarning(vm.$el.querySelector('span').textContent)).toEqual(
+ 'This is a confidential issue. Your comment will not be visible to the public.',
+ );
});
});
@@ -40,7 +47,9 @@ describe('Issue Warning Component', () => {
});
expect(vm.$el.querySelector('.icon')).toBeFalsy();
- expect(formatWarning(vm.$el.querySelector('span').textContent)).toEqual('This issue is confidential and locked. People without permission will never get a notification and won\'t be able to comment.');
+ expect(formatWarning(vm.$el.querySelector('span').textContent)).toEqual(
+ "This issue is confidential and locked. People without permission will never get a notification and won't be able to comment.",
+ );
});
});
});
diff --git a/spec/javascripts/vue_shared/components/loading_button_spec.js b/spec/javascripts/vue_shared/components/loading_button_spec.js
index 51c19cd4080..db89d4a934c 100644
--- a/spec/javascripts/vue_shared/components/loading_button_spec.js
+++ b/spec/javascripts/vue_shared/components/loading_button_spec.js
@@ -4,7 +4,7 @@ import mountComponent from 'spec/helpers/vue_mount_component_helper';
const LABEL = 'Hello';
-describe('LoadingButton', function () {
+describe('LoadingButton', function() {
let vm;
let LoadingButton;
@@ -69,6 +69,7 @@ describe('LoadingButton', function () {
describe('container class', () => {
it('should default to btn btn-align-content', () => {
vm = mountComponent(LoadingButton, {});
+
expect(vm.$el.classList.contains('btn')).toEqual(true);
expect(vm.$el.classList.contains('btn-align-content')).toEqual(true);
});
@@ -77,6 +78,7 @@ describe('LoadingButton', function () {
vm = mountComponent(LoadingButton, {
containerClass: 'test-class',
});
+
expect(vm.$el.classList.contains('btn')).toEqual(false);
expect(vm.$el.classList.contains('btn-align-content')).toEqual(false);
expect(vm.$el.classList.contains('test-class')).toEqual(true);
diff --git a/spec/javascripts/vue_shared/components/markdown/field_spec.js b/spec/javascripts/vue_shared/components/markdown/field_spec.js
index 0dea9278cc2..abb17440c0e 100644
--- a/spec/javascripts/vue_shared/components/markdown/field_spec.js
+++ b/spec/javascripts/vue_shared/components/markdown/field_spec.js
@@ -11,7 +11,7 @@ function assertMarkdownTabs(isWrite, writeLink, previewLink, vm) {
describe('Markdown field component', () => {
let vm;
- beforeEach((done) => {
+ beforeEach(done => {
vm = new Vue({
components: {
fieldComponent,
@@ -39,9 +39,7 @@ describe('Markdown field component', () => {
describe('mounted', () => {
it('renders textarea inside backdrop', () => {
- expect(
- vm.$el.querySelector('.zen-backdrop textarea'),
- ).not.toBeNull();
+ expect(vm.$el.querySelector('.zen-backdrop textarea')).not.toBeNull();
});
describe('markdown preview', () => {
@@ -49,73 +47,70 @@ describe('Markdown field component', () => {
let writeLink;
beforeEach(() => {
- spyOn(Vue.http, 'post').and.callFake(() => new Promise((resolve) => {
- setTimeout(() => {
- resolve({
- json() {
- return {
- body: '<p>markdown preview</p>',
- };
- },
- });
- });
- }));
+ spyOn(Vue.http, 'post').and.callFake(
+ () =>
+ new Promise(resolve => {
+ setTimeout(() => {
+ resolve({
+ json() {
+ return {
+ body: '<p>markdown preview</p>',
+ };
+ },
+ });
+ });
+ }),
+ );
previewLink = vm.$el.querySelector('.nav-links .js-preview-link');
writeLink = vm.$el.querySelector('.nav-links .js-write-link');
});
- it('sets preview link as active', (done) => {
+ it('sets preview link as active', done => {
previewLink.click();
Vue.nextTick(() => {
- expect(
- previewLink.parentNode.classList.contains('active'),
- ).toBeTruthy();
+ expect(previewLink.parentNode.classList.contains('active')).toBeTruthy();
done();
});
});
- it('shows preview loading text', (done) => {
+ it('shows preview loading text', done => {
previewLink.click();
Vue.nextTick(() => {
- expect(
- vm.$el.querySelector('.md-preview').textContent.trim(),
- ).toContain('Loading...');
+ expect(vm.$el.querySelector('.md-preview').textContent.trim()).toContain('Loading...');
done();
});
});
- it('renders markdown preview', (done) => {
+ it('renders markdown preview', done => {
previewLink.click();
setTimeout(() => {
- expect(
- vm.$el.querySelector('.md-preview').innerHTML,
- ).toContain('<p>markdown preview</p>');
+ expect(vm.$el.querySelector('.md-preview').innerHTML).toContain(
+ '<p>markdown preview</p>',
+ );
done();
});
});
- it('renders GFM with jQuery', (done) => {
+ it('renders GFM with jQuery', done => {
spyOn($.fn, 'renderGFM');
previewLink.click();
setTimeout(() => {
- expect(
- $.fn.renderGFM,
- ).toHaveBeenCalled();
+ expect($.fn.renderGFM).toHaveBeenCalled();
done();
}, 0);
});
- it('clicking already active write or preview link does nothing', (done) => {
+ it('clicking already active write or preview link does nothing', done => {
writeLink.click();
Vue.nextTick()
.then(() => assertMarkdownTabs(true, writeLink, previewLink, vm))
@@ -134,46 +129,40 @@ describe('Markdown field component', () => {
});
describe('markdown buttons', () => {
- it('converts single words', (done) => {
+ it('converts single words', done => {
const textarea = vm.$el.querySelector('textarea');
textarea.setSelectionRange(0, 7);
vm.$el.querySelector('.js-md').click();
Vue.nextTick(() => {
- expect(
- textarea.value,
- ).toContain('**testing**');
+ expect(textarea.value).toContain('**testing**');
done();
});
});
- it('converts a line', (done) => {
+ it('converts a line', done => {
const textarea = vm.$el.querySelector('textarea');
textarea.setSelectionRange(0, 0);
vm.$el.querySelectorAll('.js-md')[5].click();
Vue.nextTick(() => {
- expect(
- textarea.value,
- ).toContain('* testing');
+ expect(textarea.value).toContain('* testing');
done();
});
});
- it('converts multiple lines', (done) => {
+ it('converts multiple lines', done => {
const textarea = vm.$el.querySelector('textarea');
textarea.setSelectionRange(0, 50);
vm.$el.querySelectorAll('.js-md')[5].click();
Vue.nextTick(() => {
- expect(
- textarea.value,
- ).toContain('* testing\n* 123');
+ expect(textarea.value).toContain('* testing\n* 123');
done();
});
diff --git a/spec/javascripts/vue_shared/components/markdown/header_spec.js b/spec/javascripts/vue_shared/components/markdown/header_spec.js
index a4681617e66..59613faa49f 100644
--- a/spec/javascripts/vue_shared/components/markdown/header_spec.js
+++ b/spec/javascripts/vue_shared/components/markdown/header_spec.js
@@ -18,7 +18,18 @@ describe('Markdown field header component', () => {
});
it('renders markdown header buttons', () => {
- const buttons = ['Add bold text', 'Add italic text', 'Insert a quote', 'Insert code', 'Add a link', 'Add a bullet list', 'Add a numbered list', 'Add a task list', 'Add a table', 'Go full screen'];
+ const buttons = [
+ 'Add bold text',
+ 'Add italic text',
+ 'Insert a quote',
+ 'Insert code',
+ 'Add a link',
+ 'Add a bullet list',
+ 'Add a numbered list',
+ 'Add a task list',
+ 'Add a table',
+ 'Go full screen',
+ ];
const elements = vm.$el.querySelectorAll('.toolbar-btn');
elements.forEach((buttonEl, index) => {
@@ -56,14 +67,16 @@ describe('Markdown field header component', () => {
spyOn(vm, '$emit');
$(document).triggerHandler('markdown-preview:show', [
- $('<form><div class="js-vue-markdown-field"><textarea class="markdown-area"></textarea></div></form>'),
+ $(
+ '<form><div class="js-vue-markdown-field"><textarea class="markdown-area"></textarea></div></form>',
+ ),
]);
expect(vm.$emit).not.toHaveBeenCalled();
});
it('blurs preview link after click', done => {
- const link = vm.$el.querySelector('li:nth-child(2) a');
+ const link = vm.$el.querySelector('li:nth-child(2) button');
spyOn(HTMLElement.prototype, 'blur');
link.click();
@@ -76,6 +89,8 @@ describe('Markdown field header component', () => {
});
it('renders markdown table template', () => {
- expect(vm.mdTable).toEqual('| header | header |\n| ------ | ------ |\n| cell | cell |\n| cell | cell |');
+ expect(vm.mdTable).toEqual(
+ '| header | header |\n| ------ | ------ |\n| cell | cell |\n| cell | cell |',
+ );
});
});
diff --git a/spec/javascripts/vue_shared/components/markdown/toolbar_spec.js b/spec/javascripts/vue_shared/components/markdown/toolbar_spec.js
index 3e708f865c8..e6c7abd9d3b 100644
--- a/spec/javascripts/vue_shared/components/markdown/toolbar_spec.js
+++ b/spec/javascripts/vue_shared/components/markdown/toolbar_spec.js
@@ -25,9 +25,12 @@ describe('toolbar', () => {
describe('user cannot attach file', () => {
beforeEach(() => {
- vm = mountComponent(Toolbar, Object.assign({}, props, {
- canAttachFile: false,
- }));
+ vm = mountComponent(
+ Toolbar,
+ Object.assign({}, props, {
+ canAttachFile: false,
+ }),
+ );
});
it('should not render uploading-container', () => {
diff --git a/spec/javascripts/vue_shared/components/memory_graph_spec.js b/spec/javascripts/vue_shared/components/memory_graph_spec.js
index 65d8ed39ade..78c3ae3ddb3 100644
--- a/spec/javascripts/vue_shared/components/memory_graph_spec.js
+++ b/spec/javascripts/vue_shared/components/memory_graph_spec.js
@@ -52,8 +52,9 @@ describe('MemoryGraph', () => {
it('should show human readable median value based on provided median timestamp', () => {
vm.deploymentTime = mockMedian;
const formattedMedian = vm.getFormattedMedian;
- expect(formattedMedian.indexOf('Deployed') > -1).toBeTruthy();
- expect(formattedMedian.indexOf('ago') > -1).toBeTruthy();
+
+ expect(formattedMedian.indexOf('Deployed')).toBeGreaterThan(-1);
+ expect(formattedMedian.indexOf('ago')).toBeGreaterThan(-1);
});
});
});
@@ -62,6 +63,7 @@ describe('MemoryGraph', () => {
describe('getMedianMetricIndex', () => {
it('should return index of closest metric timestamp to that of median', () => {
const matchingIndex = vm.getMedianMetricIndex(mockMedian, mockMetrics);
+
expect(matchingIndex).toBe(mockMedianIndex);
});
});
@@ -69,6 +71,7 @@ describe('MemoryGraph', () => {
describe('getGraphPlotValues', () => {
it('should return Object containing values to plot graph', () => {
const plotValues = vm.getGraphPlotValues(mockMedian, mockMetrics);
+
expect(plotValues.pathD).toBeDefined();
expect(Array.isArray(plotValues.pathD)).toBeTruthy();
@@ -90,7 +93,7 @@ describe('MemoryGraph', () => {
expect(el.querySelector('svg')).toBeDefined();
});
- it('should render graph when renderGraph is called internally', (done) => {
+ it('should render graph when renderGraph is called internally', done => {
const { pathD, pathViewBox, dotX, dotY } = vm.getGraphPlotValues(mockMedian, mockMetrics);
vm.height = defaultHeight;
vm.width = defaultWidth;
@@ -101,16 +104,21 @@ describe('MemoryGraph', () => {
Vue.nextTick(() => {
const svgEl = el.querySelector('svg');
+
expect(svgEl).toBeDefined();
expect(svgEl.getAttribute('height')).toBe(defaultHeight);
expect(svgEl.getAttribute('width')).toBe(defaultWidth);
const pathEl = el.querySelector('path');
+
expect(pathEl).toBeDefined();
expect(pathEl.getAttribute('d')).toBe(`M ${pathD}`);
- expect(pathEl.getAttribute('viewBox')).toBe(`0 0 ${pathViewBox.lineWidth} ${pathViewBox.diff}`);
+ expect(pathEl.getAttribute('viewBox')).toBe(
+ `0 0 ${pathViewBox.lineWidth} ${pathViewBox.diff}`,
+ );
const circleEl = el.querySelector('circle');
+
expect(circleEl).toBeDefined();
expect(circleEl.getAttribute('r')).toBe('1.5');
expect(circleEl.getAttribute('transform')).toBe('translate(0 -1)');
diff --git a/spec/javascripts/vue_shared/components/navigation_tabs_spec.js b/spec/javascripts/vue_shared/components/navigation_tabs_spec.js
index 09fda95d7d3..462bfc10664 100644
--- a/spec/javascripts/vue_shared/components/navigation_tabs_spec.js
+++ b/spec/javascripts/vue_shared/components/navigation_tabs_spec.js
@@ -46,7 +46,9 @@ describe('navigation tabs component', () => {
it('should render badge', () => {
expect(vm.$el.querySelector('.js-pipelines-tab-all .badge').textContent.trim()).toEqual('1');
- expect(vm.$el.querySelector('.js-pipelines-tab-pending .badge').textContent.trim()).toEqual('0');
+ expect(vm.$el.querySelector('.js-pipelines-tab-pending .badge').textContent.trim()).toEqual(
+ '0',
+ );
});
it('should not render badge', () => {
@@ -56,6 +58,7 @@ describe('navigation tabs component', () => {
it('should trigger onTabClick', () => {
spyOn(vm, '$emit');
vm.$el.querySelector('.js-pipelines-tab-pending').click();
+
expect(vm.$emit).toHaveBeenCalledWith('onChangeTab', 'pending');
});
});
diff --git a/spec/javascripts/vue_shared/components/notes/placeholder_note_spec.js b/spec/javascripts/vue_shared/components/notes/placeholder_note_spec.js
index db665fdaad3..45f131194ca 100644
--- a/spec/javascripts/vue_shared/components/notes/placeholder_note_spec.js
+++ b/spec/javascripts/vue_shared/components/notes/placeholder_note_spec.js
@@ -26,6 +26,7 @@ describe('issue placeholder system note component', () => {
expect(vm.$el.querySelector('.user-avatar-link').getAttribute('href')).toEqual(
userDataMock.path,
);
+
expect(vm.$el.querySelector('.user-avatar-link img').getAttribute('src')).toEqual(
`${userDataMock.avatar_url}?width=40`,
);
@@ -37,6 +38,7 @@ describe('issue placeholder system note component', () => {
expect(vm.$el.querySelector('.note-header-info a').getAttribute('href')).toEqual(
userDataMock.path,
);
+
expect(
vm.$el.querySelector('.note-header-info .note-headline-light').textContent.trim(),
).toEqual(`@${userDataMock.username}`);
diff --git a/spec/javascripts/vue_shared/components/notes/placeholder_system_note_spec.js b/spec/javascripts/vue_shared/components/notes/placeholder_system_note_spec.js
index 262571efcb8..6013e85811a 100644
--- a/spec/javascripts/vue_shared/components/notes/placeholder_system_note_spec.js
+++ b/spec/javascripts/vue_shared/components/notes/placeholder_system_note_spec.js
@@ -20,6 +20,8 @@ describe('placeholder system note component', () => {
});
expect(vm.$el.tagName).toEqual('LI');
- expect(vm.$el.querySelector('.timeline-content em').textContent.trim()).toEqual('This is a placeholder');
+ expect(vm.$el.querySelector('.timeline-content em').textContent.trim()).toEqual(
+ 'This is a placeholder',
+ );
});
});
diff --git a/spec/javascripts/vue_shared/components/pagination_links_spec.js b/spec/javascripts/vue_shared/components/pagination_links_spec.js
index c9d183872b4..d0cb3731050 100644
--- a/spec/javascripts/vue_shared/components/pagination_links_spec.js
+++ b/spec/javascripts/vue_shared/components/pagination_links_spec.js
@@ -23,13 +23,10 @@ describe('Pagination links component', () => {
let destinationComponent;
beforeEach(() => {
- paginationLinks = mountComponent(
- paginationLinksComponent,
- {
- change,
- pageInfo,
- },
- );
+ paginationLinks = mountComponent(paginationLinksComponent, {
+ change,
+ pageInfo,
+ });
[glPagination] = paginationLinks.$children;
[destinationComponent] = glPagination.$children;
});
@@ -39,34 +36,24 @@ describe('Pagination links component', () => {
});
it('should provide translated text to GitLab UI pagination', () => {
- Object.entries(translations).forEach(entry =>
- expect(
- destinationComponent[entry[0]],
- ).toBe(entry[1]),
- );
+ Object.entries(translations).forEach(entry => {
+ expect(destinationComponent[entry[0]]).toBe(entry[1]);
+ });
});
it('should pass change to GitLab UI pagination', () => {
- expect(
- Object.is(glPagination.change, change),
- ).toBe(true);
+ expect(Object.is(glPagination.change, change)).toBe(true);
});
it('should pass page from pageInfo to GitLab UI pagination', () => {
- expect(
- destinationComponent.value,
- ).toBe(pageInfo.page);
+ expect(destinationComponent.value).toBe(pageInfo.page);
});
it('should pass per page from pageInfo to GitLab UI pagination', () => {
- expect(
- destinationComponent.perPage,
- ).toBe(pageInfo.perPage);
+ expect(destinationComponent.perPage).toBe(pageInfo.perPage);
});
it('should pass total items from pageInfo to GitLab UI pagination', () => {
- expect(
- destinationComponent.totalRows,
- ).toBe(pageInfo.total);
+ expect(destinationComponent.totalRows).toBe(pageInfo.total);
});
});
diff --git a/spec/javascripts/vue_shared/components/panel_resizer_spec.js b/spec/javascripts/vue_shared/components/panel_resizer_spec.js
index f1e62069462..49a580be06b 100644
--- a/spec/javascripts/vue_shared/components/panel_resizer_spec.js
+++ b/spec/javascripts/vue_shared/components/panel_resizer_spec.js
@@ -8,8 +8,23 @@ describe('Panel Resizer component', () => {
const triggerEvent = (eventName, el = vm.$el, clientX = 0) => {
const event = document.createEvent('MouseEvents');
- event.initMouseEvent(eventName, true, true, window, 1, clientX, 0, clientX, 0, false, false,
- false, false, 0, null);
+ event.initMouseEvent(
+ eventName,
+ true,
+ true,
+ window,
+ 1,
+ clientX,
+ 0,
+ clientX,
+ 0,
+ false,
+ false,
+ false,
+ false,
+ 0,
+ null,
+ );
el.dispatchEvent(event);
};
@@ -53,7 +68,13 @@ describe('Panel Resizer component', () => {
triggerEvent('mousedown', vm.$el);
triggerEvent('mousemove', document);
triggerEvent('mouseup', document);
- expect(vm.$emit.calls.allArgs()).toEqual([['resize-start', 100], ['update:size', 100], ['resize-end', 100]]);
+
+ expect(vm.$emit.calls.allArgs()).toEqual([
+ ['resize-start', 100],
+ ['update:size', 100],
+ ['resize-end', 100],
+ ]);
+
expect(vm.size).toBe(100);
});
});
diff --git a/spec/javascripts/vue_shared/components/pikaday_spec.js b/spec/javascripts/vue_shared/components/pikaday_spec.js
index b349e2a2a81..61f05e7a230 100644
--- a/spec/javascripts/vue_shared/components/pikaday_spec.js
+++ b/spec/javascripts/vue_shared/components/pikaday_spec.js
@@ -24,6 +24,7 @@ describe('datePicker', () => {
vm.$on('hidePicker', hidePicker);
vm.$el.querySelector('.dropdown-menu-toggle').click();
+
expect(hidePicker).toHaveBeenCalled();
});
});
diff --git a/spec/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon_spec.js b/spec/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon_spec.js
index 8c296af6652..6bff1521695 100644
--- a/spec/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon_spec.js
+++ b/spec/javascripts/vue_shared/components/sidebar/collapsed_calendar_icon_spec.js
@@ -30,6 +30,7 @@ describe('collapsedCalendarIcon', () => {
vm.$on('click', click);
vm.$el.click();
+
expect(click).toHaveBeenCalled();
});
});
diff --git a/spec/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker_spec.js b/spec/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker_spec.js
index 9d60f9c758f..026a0c7ea09 100644
--- a/spec/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker_spec.js
+++ b/spec/javascripts/vue_shared/components/sidebar/collapsed_grouped_date_picker_spec.js
@@ -30,11 +30,13 @@ describe('collapsedGroupedDatePicker', () => {
it('should emit when sidebar is toggled', () => {
vm.$el.querySelector('.gutter-toggle').click();
+
expect(vm.toggleSidebar).toHaveBeenCalled();
});
it('should emit when collapsed-calendar-icon is clicked', () => {
vm.$el.querySelector('.sidebar-collapsed-icon').click();
+
expect(vm.toggleSidebar).toHaveBeenCalled();
});
});
@@ -48,6 +50,7 @@ describe('collapsedGroupedDatePicker', () => {
it('should render both collapsed-calendar-icon', () => {
const icons = vm.$el.querySelectorAll('.sidebar-collapsed-icon');
+
expect(icons.length).toEqual(2);
expect(icons[0].innerText.trim()).toEqual('Jul 17 2016');
expect(icons[1].innerText.trim()).toEqual('Jul 17 2017');
@@ -62,6 +65,7 @@ describe('collapsedGroupedDatePicker', () => {
it('should render minDate in collapsed-calendar-icon', () => {
const icons = vm.$el.querySelectorAll('.sidebar-collapsed-icon');
+
expect(icons.length).toEqual(1);
expect(icons[0].innerText.trim()).toEqual('From Jul 17 2016');
});
@@ -75,6 +79,7 @@ describe('collapsedGroupedDatePicker', () => {
it('should render maxDate in collapsed-calendar-icon', () => {
const icons = vm.$el.querySelectorAll('.sidebar-collapsed-icon');
+
expect(icons.length).toEqual(1);
expect(icons[0].innerText.trim()).toEqual('Until Jul 17 2017');
});
@@ -83,6 +88,7 @@ describe('collapsedGroupedDatePicker', () => {
describe('no dates', () => {
it('should render None', () => {
const icons = vm.$el.querySelectorAll('.sidebar-collapsed-icon');
+
expect(icons.length).toEqual(1);
expect(icons[0].innerText.trim()).toEqual('None');
});
diff --git a/spec/javascripts/vue_shared/components/sidebar/date_picker_spec.js b/spec/javascripts/vue_shared/components/sidebar/date_picker_spec.js
index 8840a5a9dbf..1581f4e3eb1 100644
--- a/spec/javascripts/vue_shared/components/sidebar/date_picker_spec.js
+++ b/spec/javascripts/vue_shared/components/sidebar/date_picker_spec.js
@@ -17,6 +17,7 @@ describe('sidebarDatePicker', () => {
vm.$on('toggleCollapse', toggleCollapse);
vm.$el.querySelector('.issuable-sidebar-header .gutter-toggle').click();
+
expect(toggleCollapse).toHaveBeenCalled();
});
@@ -62,6 +63,7 @@ describe('sidebarDatePicker', () => {
vm.isLoading = false;
Vue.nextTick(() => {
vm.$el.querySelector('.title .btn-blank').click();
+
expect(vm.editing).toEqual(true);
done();
});
@@ -92,6 +94,7 @@ describe('sidebarDatePicker', () => {
vm.$on('saveDate', saveDate);
vm.$el.querySelector('.value-content .btn-blank').click();
+
expect(saveDate).toHaveBeenCalled();
});
});
@@ -111,6 +114,7 @@ describe('sidebarDatePicker', () => {
vm.$on('toggleCollapse', toggleCollapse);
vm.$el.querySelector('.title .gutter-toggle').click();
+
expect(toggleCollapse).toHaveBeenCalled();
});
});
diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/base_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/base_spec.js
index e8685ab48be..c44b04009ca 100644
--- a/spec/javascripts/vue_shared/components/sidebar/labels_select/base_spec.js
+++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/base_spec.js
@@ -33,6 +33,7 @@ describe('BaseComponent', () => {
it('returns correct string when showCreate prop is `false`', () => {
const mockConfigNonEditable = Object.assign({}, mockConfig, { showCreate: false });
const vmNonEditable = createComponent(mockConfigNonEditable);
+
expect(vmNonEditable.hiddenInputName).toBe('label_id[]');
vmNonEditable.$destroy();
});
@@ -46,6 +47,7 @@ describe('BaseComponent', () => {
it('return `Create group label` when `isProject` prop is false', () => {
const mockConfigGroup = Object.assign({}, mockConfig, { isProject: false });
const vmGroup = createComponent(mockConfigGroup);
+
expect(vmGroup.createLabelTitle).toBe('Create group label');
vmGroup.$destroy();
});
@@ -59,6 +61,7 @@ describe('BaseComponent', () => {
it('return `Manage group labels` when `isProject` prop is false', () => {
const mockConfigGroup = Object.assign({}, mockConfig, { isProject: false });
const vmGroup = createComponent(mockConfigGroup);
+
expect(vmGroup.manageLabelsTitle).toBe('Manage group labels');
vmGroup.$destroy();
});
@@ -70,6 +73,7 @@ describe('BaseComponent', () => {
it('emits onLabelClick event with label and list of labels as params', () => {
spyOn(vm, '$emit');
vm.handleClick(mockLabels[0]);
+
expect(vm.$emit).toHaveBeenCalledWith('onLabelClick', mockLabels[0]);
});
});
@@ -78,6 +82,7 @@ describe('BaseComponent', () => {
it('emits toggleCollapse event on component', () => {
spyOn(vm, '$emit');
vm.handleCollapsedValueClick();
+
expect(vm.$emit).toHaveBeenCalledWith('toggleCollapse');
});
});
@@ -86,6 +91,7 @@ describe('BaseComponent', () => {
it('emits onDropdownClose event on component', () => {
spyOn(vm, '$emit');
vm.handleDropdownHidden();
+
expect(vm.$emit).toHaveBeenCalledWith('onDropdownClose');
});
});
@@ -114,6 +120,7 @@ describe('BaseComponent', () => {
it('renders `.dropdown-menu` element', () => {
const dropdownMenuEl = vm.$el.querySelector('.dropdown-menu');
+
expect(dropdownMenuEl).not.toBeNull();
expect(dropdownMenuEl.querySelector('.dropdown-page-one')).not.toBeNull();
expect(dropdownMenuEl.querySelector('.dropdown-content')).not.toBeNull();
diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js
index f25c70db125..5cf6afebd7e 100644
--- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js
+++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_button_spec.js
@@ -34,6 +34,7 @@ describe('DropdownButtonComponent', () => {
it('returns text as `Label` when `labels` prop is empty array', () => {
const mockEmptyLabels = Object.assign({}, componentConfig, { labels: [] });
const vmEmptyLabels = createComponent(mockEmptyLabels);
+
expect(vmEmptyLabels.dropdownToggleText).toBe('Label');
vmEmptyLabels.$destroy();
});
@@ -43,6 +44,7 @@ describe('DropdownButtonComponent', () => {
labels: mockLabels.concat(mockLabels),
});
const vmMoreLabels = createComponent(mockMoreLabels);
+
expect(vmMoreLabels.dropdownToggleText).toBe('Foo Label +1 more');
vmMoreLabels.$destroy();
});
@@ -69,12 +71,14 @@ describe('DropdownButtonComponent', () => {
it('renders dropdown toggle text element', () => {
const dropdownToggleTextEl = vm.$el.querySelector('.dropdown-toggle-text');
+
expect(dropdownToggleTextEl).not.toBeNull();
expect(dropdownToggleTextEl.innerText.trim()).toBe('Foo Label');
});
it('renders dropdown button icon', () => {
const dropdownIconEl = vm.$el.querySelector('i.fa');
+
expect(dropdownIconEl).not.toBeNull();
expect(dropdownIconEl.classList.contains('fa-chevron-down')).toBe(true);
});
diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js
index ce559fe0335..b8f32f96332 100644
--- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js
+++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_create_label_spec.js
@@ -6,7 +6,7 @@ import mountComponent from 'spec/helpers/vue_mount_component_helper';
import { mockSuggestedColors } from './mock_data';
-const createComponent = (headerTitle) => {
+const createComponent = headerTitle => {
const Component = Vue.extend(dropdownCreateLabelComponent);
return mountComponent(Component, {
@@ -38,13 +38,17 @@ describe('DropdownCreateLabelComponent', () => {
});
it('renders `Go back` button on component header', () => {
- const backButtonEl = vm.$el.querySelector('.dropdown-title button.dropdown-title-button.dropdown-menu-back');
+ const backButtonEl = vm.$el.querySelector(
+ '.dropdown-title button.dropdown-title-button.dropdown-menu-back',
+ );
+
expect(backButtonEl).not.toBe(null);
expect(backButtonEl.querySelector('.fa-arrow-left')).not.toBe(null);
});
it('renders component header element as `Create new label` when `headerTitle` prop is not provided', () => {
const headerEl = vm.$el.querySelector('.dropdown-title');
+
expect(headerEl.innerText.trim()).toContain('Create new label');
});
@@ -52,12 +56,16 @@ describe('DropdownCreateLabelComponent', () => {
const headerTitle = 'Create project label';
const vmWithHeaderTitle = createComponent(headerTitle);
const headerEl = vmWithHeaderTitle.$el.querySelector('.dropdown-title');
+
expect(headerEl.innerText.trim()).toContain(headerTitle);
vmWithHeaderTitle.$destroy();
});
it('renders `Close` button on component header', () => {
- const closeButtonEl = vm.$el.querySelector('.dropdown-title button.dropdown-title-button.dropdown-menu-close');
+ const closeButtonEl = vm.$el.querySelector(
+ '.dropdown-title button.dropdown-title-button.dropdown-menu-close',
+ );
+
expect(closeButtonEl).not.toBe(null);
expect(closeButtonEl.querySelector('.fa-times.dropdown-menu-close-icon')).not.toBe(null);
});
@@ -69,23 +77,29 @@ describe('DropdownCreateLabelComponent', () => {
it('renders suggested colors list elements', () => {
const colorsListContainerEl = vm.$el.querySelector('.suggest-colors.suggest-colors-dropdown');
+
expect(colorsListContainerEl).not.toBe(null);
expect(colorsListContainerEl.querySelectorAll('a').length).toBe(mockSuggestedColors.length);
const colorItemEl = colorsListContainerEl.querySelectorAll('a')[0];
+
expect(colorItemEl.dataset.color).toBe(vm.suggestedColors[0]);
expect(colorItemEl.getAttribute('style')).toBe('background-color: rgb(0, 51, 204);');
});
it('renders color input element', () => {
expect(vm.$el.querySelector('.dropdown-label-color-input')).not.toBe(null);
- expect(vm.$el.querySelector('.dropdown-label-color-preview.js-dropdown-label-color-preview')).not.toBe(null);
+ expect(
+ vm.$el.querySelector('.dropdown-label-color-preview.js-dropdown-label-color-preview'),
+ ).not.toBe(null);
+
expect(vm.$el.querySelector('input#new_label_color.default-dropdown-input')).not.toBe(null);
});
it('renders component action buttons', () => {
const createBtnEl = vm.$el.querySelector('button.js-new-label-btn');
const cancelBtnEl = vm.$el.querySelector('button.js-cancel-label-btn');
+
expect(createBtnEl).not.toBe(null);
expect(createBtnEl.innerText.trim()).toBe('Create');
expect(cancelBtnEl.innerText.trim()).toBe('Cancel');
diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js
index debeab25bd6..3711e9dac8c 100644
--- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js
+++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_footer_spec.js
@@ -36,19 +36,24 @@ describe('DropdownFooterComponent', () => {
describe('template', () => {
it('renders link element with `Create new label` when `createLabelTitle` prop is not provided', () => {
const createLabelEl = vm.$el.querySelector('.dropdown-footer-list .dropdown-toggle-page');
+
expect(createLabelEl).not.toBeNull();
expect(createLabelEl.innerText.trim()).toBe('Create new label');
});
it('renders link element with value of `createLabelTitle` prop', () => {
const vmWithCreateLabelTitle = createComponent(mockConfig.labelsWebUrl, createLabelTitle);
- const createLabelEl = vmWithCreateLabelTitle.$el.querySelector('.dropdown-footer-list .dropdown-toggle-page');
+ const createLabelEl = vmWithCreateLabelTitle.$el.querySelector(
+ '.dropdown-footer-list .dropdown-toggle-page',
+ );
+
expect(createLabelEl.innerText.trim()).toBe(createLabelTitle);
vmWithCreateLabelTitle.$destroy();
});
it('renders link element with `Manage labels` when `manageLabelsTitle` prop is not provided', () => {
const manageLabelsEl = vm.$el.querySelector('.dropdown-footer-list .dropdown-external-link');
+
expect(manageLabelsEl).not.toBeNull();
expect(manageLabelsEl.getAttribute('href')).toBe(vm.labelsWebUrl);
expect(manageLabelsEl.innerText.trim()).toBe('Manage labels');
@@ -60,7 +65,10 @@ describe('DropdownFooterComponent', () => {
createLabelTitle,
manageLabelsTitle,
);
- const manageLabelsEl = vmWithManageLabelsTitle.$el.querySelector('.dropdown-footer-list .dropdown-external-link');
+ const manageLabelsEl = vmWithManageLabelsTitle.$el.querySelector(
+ '.dropdown-footer-list .dropdown-external-link',
+ );
+
expect(manageLabelsEl.innerText.trim()).toBe(manageLabelsTitle);
vmWithManageLabelsTitle.$destroy();
});
diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_header_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_header_spec.js
index cdf234bb0c4..115e21e4f9f 100644
--- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_header_spec.js
+++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_header_spec.js
@@ -24,11 +24,15 @@ describe('DropdownHeaderComponent', () => {
describe('template', () => {
it('renders header text element', () => {
const headerEl = vm.$el.querySelector('.dropdown-title span');
+
expect(headerEl.innerText.trim()).toBe('Assign labels');
});
it('renders `Close` button element', () => {
- const closeBtnEl = vm.$el.querySelector('.dropdown-title button.dropdown-title-button.dropdown-menu-close');
+ const closeBtnEl = vm.$el.querySelector(
+ '.dropdown-title button.dropdown-title-button.dropdown-menu-close',
+ );
+
expect(closeBtnEl).not.toBeNull();
expect(closeBtnEl.querySelector('.fa-times.dropdown-menu-close-icon')).not.toBeNull();
});
diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_search_input_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_search_input_spec.js
index 57608d957e7..c30e619e76b 100644
--- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_search_input_spec.js
+++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_search_input_spec.js
@@ -24,6 +24,7 @@ describe('DropdownSearchInputComponent', () => {
describe('template', () => {
it('renders input element with type `search`', () => {
const inputEl = vm.$el.querySelector('input.dropdown-input-field');
+
expect(inputEl).not.toBeNull();
expect(inputEl.getAttribute('type')).toBe('search');
});
@@ -33,7 +34,9 @@ describe('DropdownSearchInputComponent', () => {
});
it('renders clear search icon element', () => {
- expect(vm.$el.querySelector('.fa-times.dropdown-input-clear.js-dropdown-input-clear')).not.toBeNull();
+ expect(
+ vm.$el.querySelector('.fa-times.dropdown-input-clear.js-dropdown-input-clear'),
+ ).not.toBeNull();
});
});
});
diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title_spec.js
index 7c3d2711f65..6c84d2e167c 100644
--- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title_spec.js
+++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_title_spec.js
@@ -35,6 +35,7 @@ describe('DropdownTitleComponent', () => {
it('renders `Edit` button element', () => {
const editBtnEl = vm.$el.querySelector('button.edit-link.js-sidebar-dropdown-toggle');
+
expect(editBtnEl).not.toBeNull();
expect(editBtnEl.innerText.trim()).toBe('Edit');
});
diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js
index da74595bcdc..9a691116cf8 100644
--- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js
+++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_collapsed_spec.js
@@ -29,12 +29,14 @@ describe('DropdownValueCollapsedComponent', () => {
describe('labelsList', () => {
it('returns empty text when `labels` prop is empty array', () => {
const vmEmptyLabels = createComponent([]);
+
expect(vmEmptyLabels.labelsList).toBe('');
vmEmptyLabels.$destroy();
});
it('returns labels names separated by coma when `labels` prop has more than one item', () => {
const vmMoreLabels = createComponent(mockLabels.concat(mockLabels));
+
expect(vmMoreLabels.labelsList).toBe('Foo Label, Foo Label');
vmMoreLabels.$destroy();
});
@@ -46,6 +48,7 @@ describe('DropdownValueCollapsedComponent', () => {
}
const vmMoreLabels = createComponent(mockMoreLabels);
+
expect(vmMoreLabels.labelsList).toBe('Foo Label, Foo Label, Foo Label, Foo Label, Foo Label, and 2 more');
vmMoreLabels.$destroy();
});
@@ -61,6 +64,7 @@ describe('DropdownValueCollapsedComponent', () => {
it('emits onValueClick event on component', () => {
spyOn(vm, '$emit');
vm.handleClick();
+
expect(vm.$emit).toHaveBeenCalledWith('onValueClick');
});
});
diff --git a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js
index 370a296bd8f..3fff781594f 100644
--- a/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js
+++ b/spec/javascripts/vue_shared/components/sidebar/labels_select/dropdown_value_spec.js
@@ -33,6 +33,7 @@ describe('DropdownValueComponent', () => {
describe('isEmpty', () => {
it('returns true if `labels` prop is empty', () => {
const vmEmptyLabels = createComponent([]);
+
expect(vmEmptyLabels.isEmpty).toBe(true);
vmEmptyLabels.$destroy();
});
@@ -46,9 +47,11 @@ describe('DropdownValueComponent', () => {
describe('methods', () => {
describe('labelFilterUrl', () => {
it('returns URL string starting with labelFilterBasePath and encoded label.title', () => {
- expect(vm.labelFilterUrl({
- title: 'Foo bar',
- })).toBe('/gitlab-org/my-project/issues?label_name[]=Foo%20bar');
+ expect(
+ vm.labelFilterUrl({
+ title: 'Foo bar',
+ }),
+ ).toBe('/gitlab-org/my-project/issues?label_name[]=Foo%20bar');
});
});
@@ -68,21 +71,29 @@ describe('DropdownValueComponent', () => {
describe('template', () => {
it('renders component container element with classes `hide-collapsed value issuable-show-labels`', () => {
- expect(vm.$el.classList.contains('hide-collapsed', 'value', 'issuable-show-labels')).toBe(true);
+ expect(vm.$el.classList.contains('hide-collapsed', 'value', 'issuable-show-labels')).toBe(
+ true,
+ );
});
it('render slot content inside component when `labels` prop is empty', () => {
const vmEmptyLabels = createComponent([]);
- expect(vmEmptyLabels.$el.querySelector('.text-secondary').innerText.trim()).toBe(mockConfig.emptyValueText);
+
+ expect(vmEmptyLabels.$el.querySelector('.text-secondary').innerText.trim()).toBe(
+ mockConfig.emptyValueText,
+ );
vmEmptyLabels.$destroy();
});
it('renders label element with filter URL', () => {
- expect(vm.$el.querySelector('a').getAttribute('href')).toBe('/gitlab-org/my-project/issues?label_name[]=Foo%20Label');
+ expect(vm.$el.querySelector('a').getAttribute('href')).toBe(
+ '/gitlab-org/my-project/issues?label_name[]=Foo%20Label',
+ );
});
it('renders label element with tooltip and styles based on label details', () => {
const labelEl = vm.$el.querySelector('a span.badge.color-label');
+
expect(labelEl).not.toBeNull();
expect(labelEl.dataset.placement).toBe('bottom');
expect(labelEl.dataset.container).toBe('body');
diff --git a/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js b/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js
index f1fe2e996fc..073d111989c 100644
--- a/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js
+++ b/spec/javascripts/vue_shared/components/stacked_progress_bar_spec.js
@@ -4,16 +4,20 @@ import stackedProgressBarComponent from '~/vue_shared/components/stacked_progres
import mountComponent from 'spec/helpers/vue_mount_component_helper';
-const createComponent = (config) => {
+const createComponent = config => {
const Component = Vue.extend(stackedProgressBarComponent);
- const defaultConfig = Object.assign({}, {
- successLabel: 'Synced',
- failureLabel: 'Failed',
- neutralLabel: 'Out of sync',
- successCount: 25,
- failureCount: 10,
- totalCount: 5000,
- }, config);
+ const defaultConfig = Object.assign(
+ {},
+ {
+ successLabel: 'Synced',
+ failureLabel: 'Failed',
+ neutralLabel: 'Out of sync',
+ successCount: 25,
+ failureCount: 10,
+ totalCount: 5000,
+ },
+ config,
+ );
return mountComponent(Component, defaultConfig);
};
@@ -72,6 +76,7 @@ describe('StackedProgressBarComponent', () => {
it('renders empty state when count is unavailable', () => {
const vmX = createComponent({ totalCount: 0, successCount: 0, failureCount: 0 });
+
expect(vmX.$el.querySelectorAll('.status-unavailable').length).not.toBe(0);
vmX.$destroy();
});
diff --git a/spec/javascripts/vue_shared/components/table_pagination_spec.js b/spec/javascripts/vue_shared/components/table_pagination_spec.js
index d193667210b..0dcb712e720 100644
--- a/spec/javascripts/vue_shared/components/table_pagination_spec.js
+++ b/spec/javascripts/vue_shared/components/table_pagination_spec.js
@@ -11,7 +11,7 @@ describe('Pagination component', () => {
spy = jasmine.createSpy('spy');
PaginationComponent = Vue.extend(paginationComp);
- mountComponent = function (props) {
+ mountComponent = function(props) {
return new PaginationComponent({
propsData: props,
}).$mount();
@@ -72,6 +72,7 @@ describe('Pagination component', () => {
});
component.$el.querySelector('.js-previous-button a').click();
+
expect(spy).toHaveBeenCalledWith(1);
});
});
@@ -138,9 +139,7 @@ describe('Pagination component', () => {
change: spy,
});
- expect(
- component.$el.querySelector('.js-next-button').textContent.trim(),
- ).toEqual('Next');
+ expect(component.$el.querySelector('.js-next-button').textContent.trim()).toEqual('Next');
component.$el.querySelector('.js-next-button a').click();
diff --git a/spec/javascripts/vue_shared/components/time_ago_tooltip_spec.js b/spec/javascripts/vue_shared/components/time_ago_tooltip_spec.js
index b4fb568f1d4..745571d0a97 100644
--- a/spec/javascripts/vue_shared/components/time_ago_tooltip_spec.js
+++ b/spec/javascripts/vue_shared/components/time_ago_tooltip_spec.js
@@ -22,9 +22,10 @@ describe('Time ago with tooltip component', () => {
}).$mount();
expect(vm.$el.tagName).toEqual('TIME');
- expect(
- vm.$el.getAttribute('data-original-title'),
- ).toEqual(formatDate('2017-05-08T14:57:39.781Z'));
+ expect(vm.$el.getAttribute('data-original-title')).toEqual(
+ formatDate('2017-05-08T14:57:39.781Z'),
+ );
+
expect(vm.$el.getAttribute('data-placement')).toEqual('top');
const timeago = getTimeago();
diff --git a/spec/javascripts/vue_shared/components/toggle_button_spec.js b/spec/javascripts/vue_shared/components/toggle_button_spec.js
index 71952cc39e0..444ca451534 100644
--- a/spec/javascripts/vue_shared/components/toggle_button_spec.js
+++ b/spec/javascripts/vue_shared/components/toggle_button_spec.js
@@ -51,9 +51,11 @@ describe('Toggle Button', () => {
it('sets aria-label representing toggle state', () => {
vm.value = true;
+
expect(vm.ariaLabel).toEqual('Toggle Status: ON');
vm.value = false;
+
expect(vm.ariaLabel).toEqual('Toggle Status: OFF');
});
diff --git a/spec/javascripts/vue_shared/components/tooltip_on_truncate_spec.js b/spec/javascripts/vue_shared/components/tooltip_on_truncate_spec.js
index 8465757deb6..997d84dcc42 100644
--- a/spec/javascripts/vue_shared/components/tooltip_on_truncate_spec.js
+++ b/spec/javascripts/vue_shared/components/tooltip_on_truncate_spec.js
@@ -79,9 +79,7 @@ describe('TooltipOnTruncate component', () => {
},
};
- vm = mountTooltipOnTruncate(options, (h) => [
- h('a', { style: STYLE_TRUNCATED }, TEST_TITLE),
- ]);
+ vm = mountTooltipOnTruncate(options, h => [h('a', { style: STYLE_TRUNCATED }, TEST_TITLE)]);
vm.$nextTick()
.then(() => {
@@ -99,9 +97,7 @@ describe('TooltipOnTruncate component', () => {
},
};
- vm = mountTooltipOnTruncate(options, (h) => [
- h('a', { style: STYLE_NORMAL }, TEST_TITLE),
- ]);
+ vm = mountTooltipOnTruncate(options, h => [h('a', { style: STYLE_NORMAL }, TEST_TITLE)]);
vm.$nextTick()
.then(() => {
@@ -118,11 +114,11 @@ describe('TooltipOnTruncate component', () => {
style: STYLE_NORMAL,
props: {
title: TEST_TITLE,
- truncateTarget: (el) => el.childNodes[1],
+ truncateTarget: el => el.childNodes[1],
},
};
- vm = mountTooltipOnTruncate(options, (h) => [
+ vm = mountTooltipOnTruncate(options, h => [
h('a', { style: STYLE_NORMAL }, TEST_TITLE),
h('span', { style: STYLE_TRUNCATED }, TEST_TITLE),
]);
@@ -146,9 +142,7 @@ describe('TooltipOnTruncate component', () => {
},
};
- vm = mountTooltipOnTruncate(options, (h) => [
- h('a', { style: STYLE_TRUNCATED }, TEST_TITLE),
- ]);
+ vm = mountTooltipOnTruncate(options, h => [h('a', { style: STYLE_TRUNCATED }, TEST_TITLE)]);
vm.$nextTick()
.then(() => {
diff --git a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js
index 4c5c242cbb3..50b8d49d4bd 100644
--- a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js
+++ b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_link_spec.js
@@ -2,8 +2,8 @@ import _ from 'underscore';
import Vue from 'vue';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
-describe('User Avatar Link Component', function () {
- beforeEach(function () {
+describe('User Avatar Link Component', function() {
+ beforeEach(function() {
this.propsData = {
linkHref: 'myavatarurl.com',
imgSize: 99,
@@ -24,67 +24,76 @@ describe('User Avatar Link Component', function () {
[this.userAvatarImage] = this.userAvatarLink.$children;
});
- it('should return a defined Vue component', function () {
+ it('should return a defined Vue component', function() {
expect(this.userAvatarLink).toBeDefined();
});
- it('should have user-avatar-image registered as child component', function () {
+ it('should have user-avatar-image registered as child component', function() {
expect(this.userAvatarLink.$options.components.userAvatarImage).toBeDefined();
});
- it('user-avatar-link should have user-avatar-image as child component', function () {
+ it('user-avatar-link should have user-avatar-image as child component', function() {
expect(this.userAvatarImage).toBeDefined();
});
- it('should render <a> as a child element', function () {
+ it('should render <a> as a child element', function() {
expect(this.userAvatarLink.$el.tagName).toBe('A');
});
- it('should have <img> as a child element', function () {
+ it('should have <img> as a child element', function() {
expect(this.userAvatarLink.$el.querySelector('img')).not.toBeNull();
});
- it('should return neccessary props as defined', function () {
+ it('should return neccessary props as defined', function() {
_.each(this.propsData, (val, key) => {
expect(this.userAvatarLink[key]).toBeDefined();
});
});
- describe('no username', function () {
- beforeEach(function (done) {
+ describe('no username', function() {
+ beforeEach(function(done) {
this.userAvatarLink.username = '';
Vue.nextTick(done);
});
- it('should only render image tag in link', function () {
+ it('should only render image tag in link', function() {
const childElements = this.userAvatarLink.$el.childNodes;
+
expect(childElements[0].tagName).toBe('IMG');
// Vue will render the hidden component as <!---->
expect(childElements[1].tagName).toBeUndefined();
});
- it('should render avatar image tooltip', function () {
- expect(this.userAvatarLink.$el.querySelector('img').dataset.originalTitle).toEqual(this.propsData.tooltipText);
+ it('should render avatar image tooltip', function() {
+ expect(this.userAvatarLink.$el.querySelector('img').dataset.originalTitle).toEqual(
+ this.propsData.tooltipText,
+ );
});
});
- describe('username', function () {
- it('should not render avatar image tooltip', function () {
+ describe('username', function() {
+ it('should not render avatar image tooltip', function() {
expect(this.userAvatarLink.$el.querySelector('img').dataset.originalTitle).toEqual('');
});
- it('should render username prop in <span>', function () {
- expect(this.userAvatarLink.$el.querySelector('span').innerText.trim()).toEqual(this.propsData.username);
+ it('should render username prop in <span>', function() {
+ expect(this.userAvatarLink.$el.querySelector('span').innerText.trim()).toEqual(
+ this.propsData.username,
+ );
});
- it('should render text tooltip for <span>', function () {
- expect(this.userAvatarLink.$el.querySelector('span').dataset.originalTitle).toEqual(this.propsData.tooltipText);
+ it('should render text tooltip for <span>', function() {
+ expect(this.userAvatarLink.$el.querySelector('span').dataset.originalTitle).toEqual(
+ this.propsData.tooltipText,
+ );
});
- it('should render text tooltip placement for <span>', function () {
- expect(this.userAvatarLink.$el.querySelector('span').getAttribute('tooltip-placement')).toEqual(this.propsData.tooltipPlacement);
+ it('should render text tooltip placement for <span>', function() {
+ expect(
+ this.userAvatarLink.$el.querySelector('span').getAttribute('tooltip-placement'),
+ ).toEqual(this.propsData.tooltipPlacement);
});
});
});
diff --git a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_svg_spec.js b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_svg_spec.js
index b8d639ffbec..9152fa8e12f 100644
--- a/spec/javascripts/vue_shared/components/user_avatar/user_avatar_svg_spec.js
+++ b/spec/javascripts/vue_shared/components/user_avatar/user_avatar_svg_spec.js
@@ -4,9 +4,9 @@ import avatarSvg from 'icons/_icon_random.svg';
const UserAvatarSvgComponent = Vue.extend(UserAvatarSvg);
-describe('User Avatar Svg Component', function () {
- describe('Initialization', function () {
- beforeEach(function () {
+describe('User Avatar Svg Component', function() {
+ describe('Initialization', function() {
+ beforeEach(function() {
this.propsData = {
size: 99,
svg: avatarSvg,
@@ -17,11 +17,11 @@ describe('User Avatar Svg Component', function () {
}).$mount();
});
- it('should return a defined Vue component', function () {
+ it('should return a defined Vue component', function() {
expect(this.userAvatarSvg).toBeDefined();
});
- it('should have <svg> as a child element', function () {
+ it('should have <svg> as a child element', function() {
expect(this.userAvatarSvg.$el.tagName).toEqual('svg');
expect(this.userAvatarSvg.$el.innerHTML).toContain('<path');
});
diff --git a/spec/javascripts/vue_shared/directives/tooltip_spec.js b/spec/javascripts/vue_shared/directives/tooltip_spec.js
index 4a644913e44..1d516a280b0 100644
--- a/spec/javascripts/vue_shared/directives/tooltip_spec.js
+++ b/spec/javascripts/vue_shared/directives/tooltip_spec.js
@@ -13,24 +13,45 @@ describe('Tooltip directive', () => {
describe('with a single tooltip', () => {
beforeEach(() => {
- const SomeComponent = Vue.extend({
+ setFixtures('<div id="dummy-element"></div>');
+ vm = new Vue({
+ el: '#dummy-element',
directives: {
tooltip,
},
- template: `
- <div
- v-tooltip
- title="foo">
- </div>
- `,
+ data() {
+ return {
+ tooltip: 'some text',
+ };
+ },
+ template: '<div v-tooltip :title="tooltip"></div>',
});
-
- vm = new SomeComponent().$mount();
});
it('should have tooltip plugin applied', () => {
expect($(vm.$el).data('bs.tooltip')).toBeDefined();
});
+
+ it('displays the title as tooltip', () => {
+ $(vm.$el).tooltip('show');
+ const tooltipElement = document.querySelector('.tooltip-inner');
+
+ expect(tooltipElement.innerText).toContain('some text');
+ });
+
+ it('updates a visible tooltip', done => {
+ $(vm.$el).tooltip('show');
+ const tooltipElement = document.querySelector('.tooltip-inner');
+
+ vm.tooltip = 'other text';
+
+ Vue.nextTick()
+ .then(() => {
+ expect(tooltipElement).toContainText('other text');
+ done();
+ })
+ .catch(done.fail);
+ });
});
describe('with multiple tooltips', () => {
@@ -58,7 +79,11 @@ describe('Tooltip directive', () => {
});
it('should have tooltip plugin applied to all instances', () => {
- expect($(vm.$el).find('.js-look-for-tooltip').data('bs.tooltip')).toBeDefined();
+ expect(
+ $(vm.$el)
+ .find('.js-look-for-tooltip')
+ .data('bs.tooltip'),
+ ).toBeDefined();
});
});
});
diff --git a/spec/javascripts/zen_mode_spec.js b/spec/javascripts/zen_mode_spec.js
index bdeebe0de75..e5f1e6ae937 100644
--- a/spec/javascripts/zen_mode_spec.js
+++ b/spec/javascripts/zen_mode_spec.js
@@ -46,12 +46,14 @@ describe('ZenMode', () => {
it('should not call dropzone if element is not dropzone valid', () => {
$('.div-dropzone').addClass('js-invalid-dropzone');
exitZen();
+
expect(dropzoneForElementSpy.calls.count()).toEqual(0);
});
it('should call dropzone if element is dropzone valid', () => {
$('.div-dropzone').removeClass('js-invalid-dropzone');
exitZen();
+
expect(dropzoneForElementSpy.calls.count()).toEqual(2);
});
});
@@ -60,12 +62,14 @@ describe('ZenMode', () => {
it('pauses Mousetrap', () => {
const mouseTrapPauseSpy = spyOn(Mousetrap, 'pause');
enterZen();
+
expect(mouseTrapPauseSpy).toHaveBeenCalled();
});
it('removes textarea styling', () => {
$('.notes-form textarea').attr('style', 'height: 400px');
enterZen();
+
expect($('.notes-form textarea')).not.toHaveAttr('style');
});
});
@@ -75,6 +79,7 @@ describe('ZenMode', () => {
it('exits on Escape', () => {
escapeKeydown();
+
expect($('.notes-form .zen-backdrop')).not.toHaveClass('fullscreen');
});
});
@@ -85,12 +90,14 @@ describe('ZenMode', () => {
it('unpauses Mousetrap', () => {
const mouseTrapUnpauseSpy = spyOn(Mousetrap, 'unpause');
exitZen();
+
expect(mouseTrapUnpauseSpy).toHaveBeenCalled();
});
it('restores the scroll position', () => {
spyOn(zen, 'scrollTo');
exitZen();
+
expect(zen.scrollTo).toHaveBeenCalled();
});
});