summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-06-03 18:08:28 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-06-03 18:08:28 +0000
commit8b0ef132360c3657f05376a4725e7b03c151b46e (patch)
tree46488659b9883df9893f419542c9f9df2f6a3f25
parent3dcdea950204629bfcdcc9c0db250adab3b5c1ff (diff)
downloadgitlab-ce-8b0ef132360c3657f05376a4725e7b03c151b46e.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--CHANGELOG-EE.md4
-rw-r--r--CHANGELOG.md7
-rw-r--r--app/assets/javascripts/alert_management/components/alert_details.vue6
-rw-r--r--app/assets/javascripts/design_management/components/design_note_pin.vue2
-rw-r--r--app/assets/javascripts/design_management/components/design_notes/design_discussion.vue146
-rw-r--r--app/assets/javascripts/design_management/components/design_notes/design_note.vue40
-rw-r--r--app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue3
-rw-r--r--app/assets/javascripts/design_management/components/design_notes/toggle_replies_widget.vue70
-rw-r--r--app/assets/javascripts/design_management/components/design_overlay.vue38
-rw-r--r--app/assets/javascripts/design_management/components/design_presentation.vue10
-rw-r--r--app/assets/javascripts/design_management/components/design_sidebar.vue170
-rw-r--r--app/assets/javascripts/design_management/graphql/fragments/design.fragment.graphql2
-rw-r--r--app/assets/javascripts/design_management/graphql/fragments/designNote.fragment.graphql1
-rw-r--r--app/assets/javascripts/design_management/graphql/fragments/discussion_resolved_status.fragment.graphql9
-rw-r--r--app/assets/javascripts/design_management/graphql/mutations/toggle_resolve_discussion.mutation.graphql17
-rw-r--r--app/assets/javascripts/design_management/pages/design/index.vue94
-rw-r--r--app/assets/javascripts/design_management/utils/cache_update.js4
-rw-r--r--app/assets/javascripts/design_management/utils/design_management_utils.js3
-rw-r--r--app/assets/javascripts/registry/explorer/components/cli_commands.vue2
-rw-r--r--app/assets/javascripts/registry/explorer/components/image_list_row.vue2
-rw-r--r--app/assets/javascripts/registry/explorer/components/project_empty_state.vue7
-rw-r--r--app/assets/javascripts/registry/explorer/components/registry_header.vue2
-rw-r--r--app/assets/javascripts/registry/explorer/constants.js131
-rw-r--r--app/assets/javascripts/registry/explorer/constants/details.js49
-rw-r--r--app/assets/javascripts/registry/explorer/constants/expiration_policies.js11
-rw-r--r--app/assets/javascripts/registry/explorer/constants/index.js4
-rw-r--r--app/assets/javascripts/registry/explorer/constants/list.js48
-rw-r--r--app/assets/javascripts/registry/explorer/constants/quick_start.js9
-rw-r--r--app/assets/javascripts/registry/explorer/pages/details.vue2
-rw-r--r--app/assets/javascripts/registry/explorer/pages/list.vue2
-rw-r--r--app/assets/javascripts/registry/explorer/router.js4
-rw-r--r--app/assets/javascripts/registry/explorer/stores/actions.js2
-rw-r--r--app/assets/javascripts/registry/explorer/stores/mutations.js2
-rw-r--r--app/assets/stylesheets/components/design_management/design.scss43
-rw-r--r--app/helpers/issues_helper.rb39
-rw-r--r--app/policies/project_policy.rb1
-rw-r--r--changelogs/unreleased/13049-design-view-allow-comment-pins-on-designs-to-be-resolvable.yml5
-rw-r--r--changelogs/unreleased/220058.yml5
-rw-r--r--config/webpack.config.js2
-rw-r--r--doc/.vale/gitlab/Acronyms.yml1
-rw-r--r--doc/.vale/gitlab/Profanity.yml30
-rw-r--r--doc/administration/reference_architectures/10k_users.md7
-rw-r--r--doc/administration/reference_architectures/1k_users.md5
-rw-r--r--doc/administration/reference_architectures/25k_users.md7
-rw-r--r--doc/administration/reference_architectures/2k_users.md5
-rw-r--r--doc/administration/reference_architectures/3k_users.md7
-rw-r--r--doc/administration/reference_architectures/50k_users.md7
-rw-r--r--doc/administration/reference_architectures/5k_users.md7
-rw-r--r--doc/administration/reference_architectures/index.md5
-rw-r--r--doc/api/releases/index.md15
-rw-r--r--doc/api/releases/links.md28
-rw-r--r--doc/development/README.md2
-rw-r--r--doc/development/documentation/styleguide.md32
-rw-r--r--doc/development/emails.md15
-rw-r--r--doc/development/sidekiq_style_guide.md80
-rw-r--r--doc/user/incident_management/index.md77
-rw-r--r--doc/user/project/issues/design_management.md16
-rw-r--r--doc/user/project/issues/img/resolve_design-discussion_checkbox_v13_1.pngbin0 -> 56634 bytes
-rw-r--r--doc/user/project/issues/img/resolve_design-discussion_icon_v13_1.pngbin0 -> 36747 bytes
-rw-r--r--doc/user/project/service_desk.md3
-rw-r--r--lib/banzai/filter/external_issue_reference_filter.rb17
-rw-r--r--lib/banzai/filter/issue_reference_filter.rb12
-rw-r--r--lib/banzai/filter/reference_filter.rb6
-rw-r--r--locale/gitlab.pot30
-rw-r--r--qa/qa/resource/project_milestone.rb7
-rw-r--r--spec/controllers/instance_statistics/dev_ops_score_controller_spec.rb2
-rw-r--r--spec/controllers/invites_controller_spec.rb2
-rw-r--r--spec/controllers/ldap/omniauth_callbacks_controller_spec.rb2
-rw-r--r--spec/controllers/metrics_controller_spec.rb2
-rw-r--r--spec/controllers/notification_settings_controller_spec.rb2
-rw-r--r--spec/controllers/oauth/applications_controller_spec.rb2
-rw-r--r--spec/controllers/oauth/authorizations_controller_spec.rb2
-rw-r--r--spec/controllers/oauth/authorized_applications_controller_spec.rb2
-rw-r--r--spec/controllers/omniauth_callbacks_controller_spec.rb2
-rw-r--r--spec/controllers/passwords_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/accounts_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/avatars_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/emails_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/keys_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/notifications_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/personal_access_tokens_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/preferences_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/two_factor_auths_controller_spec.rb2
-rw-r--r--spec/controllers/profiles_controller_spec.rb2
-rw-r--r--spec/controllers/projects/alert_management_controller_spec.rb2
-rw-r--r--spec/controllers/projects/alerting/notifications_controller_spec.rb2
-rw-r--r--spec/controllers/projects/artifacts_controller_spec.rb2
-rw-r--r--spec/controllers/projects/autocomplete_sources_controller_spec.rb2
-rw-r--r--spec/controllers/projects/avatars_controller_spec.rb2
-rw-r--r--spec/controllers/projects/badges_controller_spec.rb2
-rw-r--r--spec/controllers/projects/blame_controller_spec.rb2
-rw-r--r--spec/controllers/projects/blob_controller_spec.rb2
-rw-r--r--spec/controllers/projects/boards_controller_spec.rb2
-rw-r--r--spec/controllers/projects/branches_controller_spec.rb2
-rw-r--r--spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb2
-rw-r--r--spec/controllers/projects/ci/lints_controller_spec.rb2
-rw-r--r--spec/controllers/projects/clusters/applications_controller_spec.rb2
-rw-r--r--spec/controllers/projects/clusters_controller_spec.rb2
-rw-r--r--spec/controllers/projects/commit_controller_spec.rb2
-rw-r--r--spec/controllers/projects/commits_controller_spec.rb2
-rw-r--r--spec/controllers/projects/compare_controller_spec.rb2
-rw-r--r--spec/controllers/projects/cycle_analytics/events_controller_spec.rb2
-rw-r--r--spec/controllers/projects/cycle_analytics_controller_spec.rb2
-rw-r--r--spec/controllers/projects/deploy_keys_controller_spec.rb2
-rw-r--r--spec/controllers/projects/deployments_controller_spec.rb2
-rw-r--r--spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb2
-rw-r--r--spec/controllers/projects/design_management/designs/resized_image_controller_spec.rb2
-rw-r--r--spec/controllers/projects/discussions_controller_spec.rb2
-rw-r--r--spec/controllers/projects/environments/prometheus_api_controller_spec.rb2
-rw-r--r--spec/controllers/projects/environments/sample_metrics_controller_spec.rb2
-rw-r--r--spec/controllers/projects/environments_controller_spec.rb2
-rw-r--r--spec/controllers/projects/error_tracking/projects_controller_spec.rb2
-rw-r--r--spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb2
-rw-r--r--spec/controllers/projects/error_tracking_controller_spec.rb2
-rw-r--r--spec/controllers/projects/find_file_controller_spec.rb2
-rw-r--r--spec/controllers/projects/forks_controller_spec.rb2
-rw-r--r--spec/controllers/projects/grafana_api_controller_spec.rb2
-rw-r--r--spec/controllers/projects/graphs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/group_links_controller_spec.rb2
-rw-r--r--spec/controllers/projects/hooks_controller_spec.rb2
-rw-r--r--spec/controllers/projects/import/jira_controller_spec.rb2
-rw-r--r--spec/controllers/projects/imports_controller_spec.rb2
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb2
-rw-r--r--spec/controllers/projects/jobs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/labels_controller_spec.rb2
-rw-r--r--spec/controllers/projects/logs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/mattermosts_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/conflicts_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/content_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/creations_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/diffs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests/drafts_controller_spec.rb2
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb2
-rw-r--r--spec/controllers/projects/milestones_controller_spec.rb2
-rw-r--r--spec/controllers/projects/mirrors_controller_spec.rb2
-rw-r--r--spec/controllers/projects/notes_controller_spec.rb2
-rw-r--r--spec/controllers/projects/pages_controller_spec.rb2
-rw-r--r--spec/controllers/projects/pages_domains_controller_spec.rb2
-rw-r--r--spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb2
-rw-r--r--spec/controllers/projects/pipeline_schedules_controller_spec.rb2
-rw-r--r--spec/controllers/projects/pipelines_controller_spec.rb2
-rw-r--r--spec/controllers/projects/pipelines_settings_controller_spec.rb2
-rw-r--r--spec/controllers/projects/project_members_controller_spec.rb2
-rw-r--r--spec/controllers/projects/prometheus/alerts_controller_spec.rb2
-rw-r--r--spec/controllers/projects/prometheus/metrics_controller_spec.rb2
-rw-r--r--spec/controllers/projects/protected_branches_controller_spec.rb2
-rw-r--r--spec/controllers/projects/protected_tags_controller_spec.rb2
-rw-r--r--spec/controllers/projects/raw_controller_spec.rb2
-rw-r--r--spec/controllers/projects/refs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/registry/repositories_controller_spec.rb2
-rw-r--r--spec/controllers/projects/registry/tags_controller_spec.rb2
-rw-r--r--spec/controllers/projects/releases/evidences_controller_spec.rb2
-rw-r--r--spec/controllers/projects/releases_controller_spec.rb2
-rw-r--r--spec/controllers/projects/repositories_controller_spec.rb2
-rw-r--r--spec/controllers/projects/runners_controller_spec.rb2
-rw-r--r--spec/controllers/projects/serverless/functions_controller_spec.rb2
-rw-r--r--spec/controllers/projects/service_hook_logs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/services_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/access_tokens_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/ci_cd_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/integrations_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/operations_controller_spec.rb2
-rw-r--r--spec/controllers/projects/settings/repository_controller_spec.rb2
-rw-r--r--spec/controllers/projects/snippets_controller_spec.rb2
-rw-r--r--spec/controllers/projects/stages_controller_spec.rb2
-rw-r--r--spec/controllers/projects/starrers_controller_spec.rb2
-rw-r--r--spec/controllers/projects/static_site_editor_controller_spec.rb2
-rw-r--r--spec/controllers/projects/tags/releases_controller_spec.rb2
-rw-r--r--spec/controllers/projects/tags_controller_spec.rb2
-rw-r--r--spec/controllers/projects/templates_controller_spec.rb2
-rw-r--r--spec/controllers/projects/todos_controller_spec.rb2
-rw-r--r--spec/controllers/projects/tree_controller_spec.rb2
-rw-r--r--spec/controllers/projects/uploads_controller_spec.rb2
-rw-r--r--spec/controllers/projects/usage_ping_controller_spec.rb2
-rw-r--r--spec/controllers/projects/variables_controller_spec.rb2
-rw-r--r--spec/controllers/projects/web_ide_terminals_controller_spec.rb2
-rw-r--r--spec/controllers/projects/wikis_controller_spec.rb2
-rw-r--r--spec/controllers/projects_controller_spec.rb2
-rw-r--r--spec/controllers/registrations_controller_spec.rb2
-rw-r--r--spec/controllers/repositories/git_http_controller_spec.rb2
-rw-r--r--spec/controllers/root_controller_spec.rb2
-rw-r--r--spec/controllers/search_controller_spec.rb2
-rw-r--r--spec/controllers/sent_notifications_controller_spec.rb2
-rw-r--r--spec/controllers/sessions_controller_spec.rb2
-rw-r--r--spec/controllers/snippets/notes_controller_spec.rb2
-rw-r--r--spec/controllers/snippets_controller_spec.rb2
-rw-r--r--spec/controllers/uploads_controller_spec.rb8
-rw-r--r--spec/controllers/user_callouts_controller_spec.rb2
-rw-r--r--spec/controllers/users/terms_controller_spec.rb2
-rw-r--r--spec/controllers/users_controller_spec.rb2
-rw-r--r--spec/db/development/import_common_metrics_spec.rb2
-rw-r--r--spec/db/production/import_common_metrics_spec.rb2
-rw-r--r--spec/db/production/settings_spec.rb2
-rw-r--r--spec/db/schema_spec.rb2
-rw-r--r--spec/dependencies/omniauth_saml_spec.rb2
-rw-r--r--spec/factories_spec.rb2
-rw-r--r--spec/features/abuse_report_spec.rb2
-rw-r--r--spec/features/action_cable_logging_spec.rb2
-rw-r--r--spec/features/admin/admin_abuse_reports_spec.rb2
-rw-r--r--spec/features/admin/admin_appearance_spec.rb2
-rw-r--r--spec/features/admin/admin_broadcast_messages_spec.rb2
-rw-r--r--spec/features/admin/admin_browse_spam_logs_spec.rb2
-rw-r--r--spec/features/admin/admin_builds_spec.rb2
-rw-r--r--spec/features/admin/admin_disables_git_access_protocol_spec.rb2
-rw-r--r--spec/features/admin/admin_disables_two_factor_spec.rb2
-rw-r--r--spec/features/admin/admin_groups_spec.rb2
-rw-r--r--spec/features/admin/admin_health_check_spec.rb2
-rw-r--r--spec/features/admin/admin_hook_logs_spec.rb2
-rw-r--r--spec/features/admin/admin_hooks_spec.rb2
-rw-r--r--spec/features/admin/admin_mode/login_spec.rb2
-rw-r--r--spec/features/admin/admin_mode/logout_spec.rb2
-rw-r--r--spec/features/admin/admin_mode/workers_spec.rb2
-rw-r--r--spec/features/admin/admin_mode_spec.rb2
-rw-r--r--spec/features/admin/admin_projects_spec.rb2
-rw-r--r--spec/features/admin/admin_requests_profiles_spec.rb2
-rw-r--r--spec/features/projects/pipeline_schedules_spec.rb2
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb2
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb2
-rw-r--r--spec/features/projects/raw/user_interacts_with_raw_endpoint_spec.rb2
-rw-r--r--spec/features/projects/releases/user_views_edit_release_spec.rb2
-rw-r--r--spec/features/projects/releases/user_views_release_spec.rb2
-rw-r--r--spec/features/projects/releases/user_views_releases_spec.rb2
-rw-r--r--spec/features/projects/remote_mirror_spec.rb2
-rw-r--r--spec/features/projects/serverless/functions_spec.rb2
-rw-r--r--spec/features/projects/services/disable_triggers_spec.rb2
-rw-r--r--spec/features/projects/services/prometheus_external_alerts_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_alerts_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_asana_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_assembla_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_atlassian_bamboo_ci_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_emails_on_push_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_flowdock_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_hipchat_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_irker_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_issue_tracker_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_jetbrains_teamcity_ci_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_jira_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_packagist_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_pivotaltracker_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_prometheus_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_pushover_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_slack_notifications_spec.rb2
-rw-r--r--spec/features/projects/services/user_activates_slack_slash_command_spec.rb2
-rw-r--r--spec/features/projects/services/user_views_services_spec.rb2
-rw-r--r--spec/features/projects/settings/access_tokens_spec.rb2
-rw-r--r--spec/features/projects/settings/external_authorization_service_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/forked_project_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/lfs_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/operations_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/pipelines_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/project_badges_spec.rb2
-rw-r--r--spec/features/projects/settings/project_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/registry_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/repository_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/user_archives_project_spec.rb2
-rw-r--r--spec/features/projects/settings/user_changes_avatar_spec.rb2
-rw-r--r--spec/features/projects/settings/user_changes_default_branch_spec.rb2
-rw-r--r--spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb2
-rw-r--r--spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/user_manages_project_members_spec.rb2
-rw-r--r--spec/features/projects/settings/user_renames_a_project_spec.rb2
-rw-r--r--spec/features/projects/settings/user_sees_revoke_deploy_token_modal_spec.rb2
-rw-r--r--spec/features/projects/settings/user_tags_project_spec.rb2
-rw-r--r--spec/features/projects/settings/user_transfers_a_project_spec.rb2
-rw-r--r--spec/features/projects/settings/visibility_settings_spec.rb2
-rw-r--r--spec/features/projects/settings/webhooks_settings_spec.rb2
-rw-r--r--spec/features/projects/show/developer_views_empty_project_instructions_spec.rb2
-rw-r--r--spec/features/projects/show/download_buttons_spec.rb2
-rw-r--r--spec/features/projects/show/no_password_spec.rb2
-rw-r--r--spec/features/projects/show/redirects_spec.rb2
-rw-r--r--spec/features/projects/show/rss_spec.rb2
-rw-r--r--spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb2
-rw-r--r--spec/features/projects/show/user_interacts_with_stars_spec.rb2
-rw-r--r--spec/features/projects/show/user_manages_notifications_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_collaboration_links_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_deletion_failure_message_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_git_instructions_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_readme_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb2
-rw-r--r--spec/features/projects/show/user_uploads_files_spec.rb2
-rw-r--r--spec/features/projects/snippets/create_snippet_spec.rb4
-rw-r--r--spec/features/projects/snippets/show_spec.rb2
-rw-r--r--spec/features/projects/snippets/user_comments_on_snippet_spec.rb2
-rw-r--r--spec/features/projects/snippets/user_deletes_snippet_spec.rb2
-rw-r--r--spec/features/projects/snippets/user_updates_snippet_spec.rb2
-rw-r--r--spec/features/projects/snippets/user_views_snippets_spec.rb2
-rw-r--r--spec/features/projects/sourcegraph_csp_spec.rb2
-rw-r--r--spec/features/projects/sub_group_issuables_spec.rb2
-rw-r--r--spec/features/projects/tags/download_buttons_spec.rb2
-rw-r--r--spec/features/projects/tags/user_edits_tags_spec.rb2
-rw-r--r--spec/features/projects/tags/user_views_tags_spec.rb2
-rw-r--r--spec/features/projects/tree/create_directory_spec.rb2
-rw-r--r--spec/features/projects/tree/create_file_spec.rb2
-rw-r--r--spec/features/projects/tree/rss_spec.rb2
-rw-r--r--spec/features/projects/tree/tree_show_spec.rb2
-rw-r--r--spec/features/projects/tree/upload_file_spec.rb2
-rw-r--r--spec/features/projects/user_changes_project_visibility_spec.rb2
-rw-r--r--spec/features/projects/user_creates_project_spec.rb2
-rw-r--r--spec/features/projects/user_sees_sidebar_spec.rb2
-rw-r--r--spec/features/projects/user_sees_user_popover_spec.rb2
-rw-r--r--spec/features/projects/user_uses_shortcuts_spec.rb2
-rw-r--r--spec/features/projects/user_views_empty_project_spec.rb2
-rw-r--r--spec/features/projects/view_on_env_spec.rb2
-rw-r--r--spec/features/projects/wiki/markdown_preview_spec.rb2
-rw-r--r--spec/features/projects/wiki/shortcuts_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_creates_wiki_page_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_deletes_wiki_page_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_git_access_wiki_page_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_updates_wiki_page_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_views_wiki_empty_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_views_wiki_page_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_views_wiki_pages_spec.rb2
-rw-r--r--spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb2
-rw-r--r--spec/features/projects_spec.rb2
-rw-r--r--spec/features/protected_branches_spec.rb2
-rw-r--r--spec/features/protected_tags_spec.rb2
-rw-r--r--spec/features/read_only_spec.rb2
-rw-r--r--spec/features/reportable_note/commit_spec.rb2
-rw-r--r--spec/features/reportable_note/issue_spec.rb2
-rw-r--r--spec/features/reportable_note/merge_request_spec.rb2
-rw-r--r--spec/features/reportable_note/snippets_spec.rb2
-rw-r--r--spec/features/runners_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_code_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_comments_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_commits_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_issues_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_merge_requests_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_milestones_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_projects_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_users_spec.rb2
-rw-r--r--spec/features/search/user_searches_for_wiki_pages_spec.rb2
-rw-r--r--spec/features/search/user_uses_header_search_field_spec.rb2
-rw-r--r--spec/features/search/user_uses_search_filters_spec.rb2
-rw-r--r--spec/features/security/admin_access_spec.rb2
-rw-r--r--spec/features/security/dashboard_access_spec.rb2
-rw-r--r--spec/features/security/group/internal_access_spec.rb2
-rw-r--r--spec/features/security/group/private_access_spec.rb2
-rw-r--r--spec/features/security/group/public_access_spec.rb2
-rw-r--r--spec/features/security/profile_access_spec.rb2
-rw-r--r--spec/features/security/project/internal_access_spec.rb2
-rw-r--r--spec/features/security/project/private_access_spec.rb2
-rw-r--r--spec/features/security/project/public_access_spec.rb2
-rw-r--r--spec/features/security/project/snippet/internal_access_spec.rb2
-rw-r--r--spec/features/security/project/snippet/private_access_spec.rb2
-rw-r--r--spec/features/security/project/snippet/public_access_spec.rb2
-rw-r--r--spec/features/sentry_js_spec.rb6
-rw-r--r--spec/features/signed_commits_spec.rb2
-rw-r--r--spec/features/snippets/embedded_snippet_spec.rb2
-rw-r--r--spec/features/snippets/explore_spec.rb2
-rw-r--r--spec/features/snippets/internal_snippet_spec.rb2
-rw-r--r--spec/features/snippets/notes_on_personal_snippets_spec.rb2
-rw-r--r--spec/features/snippets/private_snippets_spec.rb2
-rw-r--r--spec/features/snippets/public_snippets_spec.rb2
-rw-r--r--spec/features/snippets/search_snippets_spec.rb2
-rw-r--r--spec/features/snippets/show_spec.rb2
-rw-r--r--spec/features/snippets/spam_snippets_spec.rb4
-rw-r--r--spec/features/snippets/user_creates_snippet_spec.rb4
-rw-r--r--spec/features/snippets/user_deletes_snippet_spec.rb2
-rw-r--r--spec/features/snippets/user_edits_snippet_spec.rb2
-rw-r--r--spec/features/snippets/user_snippets_spec.rb2
-rw-r--r--spec/features/snippets_spec.rb2
-rw-r--r--spec/features/static_site_editor_spec.rb2
-rw-r--r--spec/frontend/design_management/components/design_note_pin_spec.js2
-rw-r--r--spec/frontend/design_management/components/design_notes/__snapshots__/design_note_spec.js.snap8
-rw-r--r--spec/frontend/design_management/components/design_notes/design_discussion_spec.js215
-rw-r--r--spec/frontend/design_management/components/design_notes/toggle_replies_widget_spec.js98
-rw-r--r--spec/frontend/design_management/components/design_overlay_spec.js57
-rw-r--r--spec/frontend/design_management/components/design_presentation_spec.js9
-rw-r--r--spec/frontend/design_management/components/design_sidebar_spec.js228
-rw-r--r--spec/frontend/design_management/mock_data/design.js20
-rw-r--r--spec/frontend/design_management/mock_data/notes.js14
-rw-r--r--spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap114
-rw-r--r--spec/frontend/design_management/pages/design/index_spec.js78
-rw-r--r--spec/frontend/design_management/utils/design_management_utils_spec.js8
-rw-r--r--spec/helpers/issues_helper_spec.rb53
-rw-r--r--spec/lib/banzai/filter/external_issue_reference_filter_spec.rb28
-rw-r--r--spec/lib/banzai/filter/issue_reference_filter_spec.rb34
-rw-r--r--spec/policies/project_policy_spec.rb61
-rw-r--r--spec/requests/api/markdown_spec.rb15
382 files changed, 2075 insertions, 1002 deletions
diff --git a/CHANGELOG-EE.md b/CHANGELOG-EE.md
index 33d9e2bd312..380c9fb1743 100644
--- a/CHANGELOG-EE.md
+++ b/CHANGELOG-EE.md
@@ -1,5 +1,9 @@
Please view this file on the master branch, on stable branches it's out of date.
+## 13.0.4 (2020-06-03)
+
+- No changes.
+
## 13.0.3 (2020-05-29)
- No changes.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f10b2518b5f..a35497a0582 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,13 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
+## 13.0.4 (2020-06-03)
+
+### Security (1 change)
+
+- Prevent fetching repository code with unauthorized ci token.
+
+
## 13.0.3 (2020-05-29)
### Fixed (8 changes, 1 of them is from the community)
diff --git a/app/assets/javascripts/alert_management/components/alert_details.vue b/app/assets/javascripts/alert_management/components/alert_details.vue
index 5165a2271a3..99194007551 100644
--- a/app/assets/javascripts/alert_management/components/alert_details.vue
+++ b/app/assets/javascripts/alert_management/components/alert_details.vue
@@ -177,7 +177,11 @@ export default {
{{ createIssueError }}
</gl-alert>
<div v-if="loading"><gl-loading-icon size="lg" class="gl-mt-5" /></div>
- <div v-if="alert" class="alert-management-details gl-relative">
+ <div
+ v-if="alert"
+ class="alert-management-details gl-relative"
+ :class="{ 'pr-8': sidebarCollapsed }"
+ >
<div
class="gl-display-flex gl-justify-content-space-between gl-align-items-baseline gl-px-1 py-3 py-md-4 gl-border-b-1 gl-border-b-gray-200 gl-border-b-solid flex-column flex-sm-row"
>
diff --git a/app/assets/javascripts/design_management/components/design_note_pin.vue b/app/assets/javascripts/design_management/components/design_note_pin.vue
index 7827f2ce204..0811397fbad 100644
--- a/app/assets/javascripts/design_management/components/design_note_pin.vue
+++ b/app/assets/javascripts/design_management/components/design_note_pin.vue
@@ -13,7 +13,7 @@ export default {
required: true,
},
label: {
- type: String,
+ type: Number,
required: false,
default: null,
},
diff --git a/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue b/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue
index 486211e5986..49cf7265c0d 100644
--- a/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue
+++ b/app/assets/javascripts/design_management/components/design_notes/design_discussion.vue
@@ -1,14 +1,19 @@
<script>
import { ApolloMutation } from 'vue-apollo';
+import { GlTooltipDirective, GlIcon, GlLoadingIcon, GlLink } from '@gitlab/ui';
+import { s__ } from '~/locale';
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
+import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import allVersionsMixin from '../../mixins/all_versions';
import createNoteMutation from '../../graphql/mutations/createNote.mutation.graphql';
+import toggleResolveDiscussionMutation from '../../graphql/mutations/toggle_resolve_discussion.mutation.graphql';
import getDesignQuery from '../../graphql/queries/getDesign.query.graphql';
import activeDiscussionQuery from '../../graphql/queries/active_discussion.query.graphql';
import DesignNote from './design_note.vue';
import DesignReplyForm from './design_reply_form.vue';
import { updateStoreAfterAddDiscussionComment } from '../../utils/cache_update';
import { ACTIVE_DISCUSSION_SOURCE_TYPES } from '../../constants';
+import ToggleRepliesWidget from './toggle_replies_widget.vue';
export default {
components: {
@@ -16,6 +21,14 @@ export default {
DesignNote,
ReplyPlaceholder,
DesignReplyForm,
+ GlIcon,
+ GlLoadingIcon,
+ GlLink,
+ ToggleRepliesWidget,
+ TimeAgoTooltip,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
},
mixins: [allVersionsMixin],
props: {
@@ -31,15 +44,15 @@ export default {
type: String,
required: true,
},
- discussionIndex: {
- type: Number,
- required: true,
- },
markdownPreviewPath: {
type: String,
required: false,
default: '',
},
+ resolvedDiscussionsExpanded: {
+ type: Boolean,
+ required: true,
+ },
},
apollo: {
activeDiscussion: {
@@ -49,6 +62,7 @@ export default {
// We watch any changes to the active discussion from the design pins and scroll to this discussion if it exists
// We don't want scrollIntoView to be triggered from the discussion click itself
if (
+ this.resolvedDiscussionsExpanded &&
discussionId &&
data.activeDiscussion.source === ACTIVE_DISCUSSION_SOURCE_TYPES.pin &&
discussionId === this.discussion.notes[0].id
@@ -66,6 +80,9 @@ export default {
discussionComment: '',
isFormRendered: false,
activeDiscussion: {},
+ isResolving: false,
+ shouldChangeResolvedStatus: false,
+ areRepliesCollapsed: this.discussion.resolved,
};
},
computed: {
@@ -87,6 +104,29 @@ export default {
isDiscussionHighlighted() {
return this.discussion.notes[0].id === this.activeDiscussion.id;
},
+ resolveCheckboxText() {
+ return this.discussion.resolved
+ ? s__('DesignManagement|Unresolve thread')
+ : s__('DesignManagement|Resolve thread');
+ },
+ firstNote() {
+ return this.discussion.notes[0];
+ },
+ discussionReplies() {
+ return this.discussion.notes.slice(1);
+ },
+ areRepliesShown() {
+ return !this.discussion.resolved || !this.areRepliesCollapsed;
+ },
+ resolveIconName() {
+ return this.discussion.resolved ? 'check-circle-filled' : 'check-circle';
+ },
+ isRepliesWidgetVisible() {
+ return this.discussion.resolved && this.discussionReplies.length > 0;
+ },
+ isReplyPlaceholderVisible() {
+ return this.areRepliesShown || !this.discussionReplies.length;
+ },
},
methods: {
addDiscussionComment(
@@ -106,9 +146,12 @@ export default {
onDone() {
this.discussionComment = '';
this.hideForm();
+ if (this.shouldChangeResolvedStatus) {
+ this.toggleResolvedStatus();
+ }
},
- onError(err) {
- this.$emit('error', err);
+ onCreateNoteError(err) {
+ this.$emit('createNoteError', err);
},
hideForm() {
this.isFormRendered = false;
@@ -123,6 +166,25 @@ export default {
}
this.isFormRendered = false;
},
+ toggleResolvedStatus() {
+ this.isResolving = true;
+ this.$apollo
+ .mutate({
+ mutation: toggleResolveDiscussionMutation,
+ variables: { id: this.discussion.id, resolve: !this.discussion.resolved },
+ })
+ .then(({ data }) => {
+ if (data.errors?.length > 0) {
+ this.$emit('resolveDiscussionError', data.errors[0]);
+ }
+ })
+ .catch(err => {
+ this.$emit('resolveDiscussionError', err);
+ })
+ .finally(() => {
+ this.isResolving = false;
+ });
+ },
},
createNoteMutation,
};
@@ -130,20 +192,69 @@ export default {
<template>
<div class="design-discussion-wrapper">
- <div class="badge badge-pill" type="button">{{ discussionIndex }}</div>
<div
- class="design-discussion bordered-box position-relative"
+ class="badge badge-pill gl-display-flex gl-align-items-center gl-justify-content-center"
+ :class="{ resolved: discussion.resolved }"
+ type="button"
+ >
+ {{ discussion.index }}
+ </div>
+ <ul
+ class="design-discussion bordered-box gl-relative gl-p-0 gl-list-style-none"
data-qa-selector="design_discussion_content"
>
<design-note
- v-for="note in discussion.notes"
+ :note="firstNote"
+ :markdown-preview-path="markdownPreviewPath"
+ :is-resolving="isResolving"
+ :class="{ 'gl-bg-blue-50': isDiscussionHighlighted }"
+ @error="$emit('updateNoteError', $event)"
+ >
+ <template v-if="discussion.resolvable" #resolveDiscussion>
+ <button
+ v-gl-tooltip
+ :class="{ 'is-active': discussion.resolved }"
+ :title="resolveCheckboxText"
+ :aria-label="resolveCheckboxText"
+ type="button"
+ class="line-resolve-btn note-action-button gl-mr-3"
+ data-testid="resolve-button"
+ @click.stop="toggleResolvedStatus"
+ >
+ <gl-icon v-if="!isResolving" :name="resolveIconName" data-testid="resolve-icon" />
+ <gl-loading-icon v-else inline />
+ </button>
+ </template>
+ <template v-if="discussion.resolved" #resolvedStatus>
+ <p class="gl-text-gray-700 gl-font-sm gl-m-0 gl-mt-5" data-testid="resolved-message">
+ {{ __('Resolved by') }}
+ <gl-link
+ class="gl-text-gray-700 gl-text-decoration-none gl-font-sm link-inherit-color"
+ :href="discussion.resolvedBy.webUrl"
+ target="_blank"
+ >{{ discussion.resolvedBy.name }}</gl-link
+ >
+ <time-ago-tooltip :time="discussion.resolvedAt" tooltip-placement="bottom" />
+ </p>
+ </template>
+ </design-note>
+ <toggle-replies-widget
+ v-if="isRepliesWidgetVisible"
+ :collapsed="areRepliesCollapsed"
+ :replies="discussionReplies"
+ @toggle="areRepliesCollapsed = !areRepliesCollapsed"
+ />
+ <design-note
+ v-for="note in discussionReplies"
+ v-show="areRepliesShown"
:key="note.id"
:note="note"
:markdown-preview-path="markdownPreviewPath"
+ :is-resolving="isResolving"
:class="{ 'gl-bg-blue-50': isDiscussionHighlighted }"
@error="$emit('updateNoteError', $event)"
/>
- <div class="reply-wrapper">
+ <li v-show="isReplyPlaceholderVisible" class="reply-wrapper">
<reply-placeholder
v-if="!isFormRendered"
class="qa-discussion-reply"
@@ -159,7 +270,7 @@ export default {
}"
:update="addDiscussionComment"
@done="onDone"
- @error="onError"
+ @error="onCreateNoteError"
>
<design-reply-form
v-model="discussionComment"
@@ -168,9 +279,16 @@ export default {
@submitForm="mutate"
@cancelForm="hideForm"
@onBlur="handleReplyFormBlur"
- />
+ >
+ <template v-if="discussion.resolvable" #resolveCheckbox>
+ <label data-testid="resolve-checkbox">
+ <input v-model="shouldChangeResolvedStatus" type="checkbox" />
+ {{ resolveCheckboxText }}
+ </label>
+ </template>
+ </design-reply-form>
</apollo-mutation>
- </div>
- </div>
+ </li>
+ </ul>
</div>
</template>
diff --git a/app/assets/javascripts/design_management/components/design_notes/design_note.vue b/app/assets/javascripts/design_management/components/design_notes/design_note.vue
index c1c19c0a597..b1f3a43a66d 100644
--- a/app/assets/javascripts/design_management/components/design_notes/design_note.vue
+++ b/app/assets/javascripts/design_management/components/design_notes/design_note.vue
@@ -54,6 +54,9 @@ export default {
body: this.noteText,
};
},
+ isEditButtonVisible() {
+ return !this.isEditing && this.note.userPermissions.adminNote;
+ },
},
mounted() {
if (this.isNoteLinked) {
@@ -107,23 +110,28 @@ export default {
</template>
</span>
</div>
- <button
- v-if="!isEditing && note.userPermissions.adminNote"
- v-gl-tooltip
- type="button"
- title="Edit comment"
- class="note-action-button js-note-edit btn btn-transparent qa-note-edit-button"
- @click="isEditing = true"
- >
- <gl-icon name="pencil" class="link-highlight" />
- </button>
+ <div class="gl-display-flex">
+ <slot name="resolveDiscussion"></slot>
+ <button
+ v-if="isEditButtonVisible"
+ v-gl-tooltip
+ type="button"
+ :title="__('Edit comment')"
+ class="note-action-button js-note-edit btn btn-transparent qa-note-edit-button"
+ @click="isEditing = true"
+ >
+ <gl-icon name="pencil" class="link-highlight" />
+ </button>
+ </div>
</div>
- <div
- v-if="!isEditing"
- class="note-text js-note-text md"
- data-qa-selector="note_content"
- v-html="note.bodyHtml"
- ></div>
+ <template v-if="!isEditing">
+ <div
+ class="note-text js-note-text md"
+ data-qa-selector="note_content"
+ v-html="note.bodyHtml"
+ ></div>
+ <slot name="resolvedStatus"></slot>
+ </template>
<apollo-mutation
v-else
#default="{ mutate, loading }"
diff --git a/app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue b/app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue
index f673763d538..249258c577e 100644
--- a/app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue
+++ b/app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue
@@ -108,7 +108,8 @@ export default {
</textarea>
</template>
</markdown-field>
- <div class="note-form-actions d-flex justify-content-between">
+ <slot name="resolveCheckbox"></slot>
+ <div class="note-form-actions gl-display-flex gl-justify-content-space-between">
<gl-deprecated-button
ref="submitButton"
:disabled="!hasValue || isSaving"
diff --git a/app/assets/javascripts/design_management/components/design_notes/toggle_replies_widget.vue b/app/assets/javascripts/design_management/components/design_notes/toggle_replies_widget.vue
new file mode 100644
index 00000000000..46c73e3eea8
--- /dev/null
+++ b/app/assets/javascripts/design_management/components/design_notes/toggle_replies_widget.vue
@@ -0,0 +1,70 @@
+<script>
+import { GlIcon, GlButton, GlLink } from '@gitlab/ui';
+import { __, n__ } from '~/locale';
+import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+
+export default {
+ name: 'ToggleNotesWidget',
+ components: {
+ GlIcon,
+ GlButton,
+ GlLink,
+ TimeAgoTooltip,
+ },
+ props: {
+ collapsed: {
+ type: Boolean,
+ required: true,
+ },
+ replies: {
+ type: Array,
+ required: true,
+ },
+ },
+ computed: {
+ lastReply() {
+ return this.replies[this.replies.length - 1];
+ },
+ iconName() {
+ return this.collapsed ? 'chevron-right' : 'chevron-down';
+ },
+ toggleText() {
+ return this.collapsed
+ ? `${this.replies.length} ${n__('reply', 'replies', this.replies.length)}`
+ : __('Collapse replies');
+ },
+ },
+};
+</script>
+
+<template>
+ <li
+ class="toggle-comments gl-bg-gray-50 gl-display-flex gl-align-items-center gl-py-3"
+ :class="{ expanded: !collapsed }"
+ data-testid="toggle-comments-wrapper"
+ >
+ <gl-icon :name="iconName" class="gl-ml-3" @click.stop="$emit('toggle')" />
+ <gl-button
+ variant="link"
+ class="toggle-comments-button gl-ml-2 gl-mr-2"
+ @click.stop="$emit('toggle')"
+ >
+ {{ toggleText }}
+ </gl-button>
+ <template v-if="collapsed">
+ <span class="gl-text-gray-700">{{ __('Last reply by') }}</span>
+ <gl-link
+ :href="lastReply.author.webUrl"
+ target="_blank"
+ class="link-inherit-color gl-text-black-normal gl-text-decoration-none gl-font-weight-bold gl-ml-2 gl-mr-2"
+ >
+ {{ lastReply.author.name }}
+ </gl-link>
+ <time-ago-tooltip
+ :time="lastReply.createdAt"
+ tooltip-placement="bottom"
+ class="gl-text-gray-700"
+ />
+ </template>
+ </li>
+</template>
diff --git a/app/assets/javascripts/design_management/components/design_overlay.vue b/app/assets/javascripts/design_management/components/design_overlay.vue
index beb51647821..46f5754d8d9 100644
--- a/app/assets/javascripts/design_management/components/design_overlay.vue
+++ b/app/assets/javascripts/design_management/components/design_overlay.vue
@@ -33,6 +33,10 @@ export default {
required: false,
default: false,
},
+ resolvedDiscussionsExpanded: {
+ type: Boolean,
+ required: true,
+ },
},
apollo: {
activeDiscussion: {
@@ -236,6 +240,9 @@ export default {
isNoteInactive(note) {
return this.activeDiscussion.id && this.activeDiscussion.id !== note.id;
},
+ designPinClass(note) {
+ return { inactive: this.isNoteInactive(note), resolved: note.resolved };
+ },
},
};
</script>
@@ -254,20 +261,23 @@ export default {
data-qa-selector="design_image_button"
@mouseup="onAddCommentMouseup"
></button>
- <design-note-pin
- v-for="(note, index) in notes"
- :key="note.id"
- :label="`${index + 1}`"
- :repositioning="isMovingNote(note.id)"
- :position="
- isMovingNote(note.id) && movingNoteNewPosition
- ? getNotePositionStyle(movingNoteNewPosition)
- : getNotePositionStyle(note.position)
- "
- :class="{ inactive: isNoteInactive(note) }"
- @mousedown.stop="onNoteMousedown($event, note)"
- @mouseup.stop="onNoteMouseup(note)"
- />
+ <template v-for="note in notes">
+ <design-note-pin
+ v-if="resolvedDiscussionsExpanded || !note.resolved"
+ :key="note.id"
+ :label="note.index"
+ :repositioning="isMovingNote(note.id)"
+ :position="
+ isMovingNote(note.id) && movingNoteNewPosition
+ ? getNotePositionStyle(movingNoteNewPosition)
+ : getNotePositionStyle(note.position)
+ "
+ :class="designPinClass(note)"
+ @mousedown.stop="onNoteMousedown($event, note)"
+ @mouseup.stop="onNoteMouseup(note)"
+ />
+ </template>
+
<design-note-pin
v-if="currentCommentForm"
:position="currentCommentPositionStyle"
diff --git a/app/assets/javascripts/design_management/components/design_presentation.vue b/app/assets/javascripts/design_management/components/design_presentation.vue
index 5c113b3dbed..84dbb2809d9 100644
--- a/app/assets/javascripts/design_management/components/design_presentation.vue
+++ b/app/assets/javascripts/design_management/components/design_presentation.vue
@@ -35,6 +35,10 @@ export default {
required: false,
default: 1,
},
+ resolvedDiscussionsExpanded: {
+ type: Boolean,
+ required: true,
+ },
},
data() {
return {
@@ -54,7 +58,10 @@ export default {
},
computed: {
discussionStartingNotes() {
- return this.discussions.map(discussion => discussion.notes[0]);
+ return this.discussions.map(discussion => ({
+ ...discussion.notes[0],
+ index: discussion.index,
+ }));
},
currentCommentForm() {
return (this.isAnnotating && this.currentAnnotationPosition) || null;
@@ -305,6 +312,7 @@ export default {
:notes="discussionStartingNotes"
:current-comment-form="currentCommentForm"
:disable-commenting="isDraggingDesign"
+ :resolved-discussions-expanded="resolvedDiscussionsExpanded"
@openCommentForm="openCommentForm"
@closeCommentForm="closeCommentForm"
@moveNote="moveNote"
diff --git a/app/assets/javascripts/design_management/components/design_sidebar.vue b/app/assets/javascripts/design_management/components/design_sidebar.vue
new file mode 100644
index 00000000000..1be016ae41e
--- /dev/null
+++ b/app/assets/javascripts/design_management/components/design_sidebar.vue
@@ -0,0 +1,170 @@
+<script>
+import { s__ } from '~/locale';
+import Cookies from 'js-cookie';
+import { parseBoolean } from '~/lib/utils/common_utils';
+import { GlCollapse, GlButton, GlPopover } from '@gitlab/ui';
+import updateActiveDiscussionMutation from '../graphql/mutations/update_active_discussion.mutation.graphql';
+import { extractDiscussions, extractParticipants } from '../utils/design_management_utils';
+import { ACTIVE_DISCUSSION_SOURCE_TYPES } from '../constants';
+import DesignDiscussion from './design_notes/design_discussion.vue';
+import Participants from '~/sidebar/components/participants/participants.vue';
+
+export default {
+ components: {
+ DesignDiscussion,
+ Participants,
+ GlCollapse,
+ GlButton,
+ GlPopover,
+ },
+ props: {
+ design: {
+ type: Object,
+ required: true,
+ },
+ resolvedDiscussionsExpanded: {
+ type: Boolean,
+ required: true,
+ },
+ markdownPreviewPath: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ isResolvedCommentsPopoverHidden: parseBoolean(Cookies.get(this.$options.cookieKey)),
+ };
+ },
+ computed: {
+ discussions() {
+ return extractDiscussions(this.design.discussions);
+ },
+ issue() {
+ return {
+ ...this.design.issue,
+ webPath: this.design.issue.webPath.substr(1),
+ };
+ },
+ discussionParticipants() {
+ return extractParticipants(this.issue.participants);
+ },
+ resolvedDiscussions() {
+ return this.discussions.filter(discussion => discussion.resolved);
+ },
+ unresolvedDiscussions() {
+ return this.discussions.filter(discussion => !discussion.resolved);
+ },
+ resolvedCommentsToggleIcon() {
+ return this.resolvedDiscussionsExpanded ? 'chevron-down' : 'chevron-right';
+ },
+ },
+ methods: {
+ handleSidebarClick() {
+ this.isResolvedCommentsPopoverHidden = true;
+ Cookies.set(this.$options.cookieKey, 'true', { expires: 365 * 10 });
+ this.updateActiveDiscussion();
+ },
+ updateActiveDiscussion(id) {
+ this.$apollo.mutate({
+ mutation: updateActiveDiscussionMutation,
+ variables: {
+ id,
+ source: ACTIVE_DISCUSSION_SOURCE_TYPES.discussion,
+ },
+ });
+ },
+ closeCommentForm() {
+ this.comment = '';
+ this.$emit('closeCommentForm');
+ },
+ },
+ resolveCommentsToggleText: s__('DesignManagement|Resolved Comments'),
+ cookieKey: 'hide_design_resolved_comments_popover',
+};
+</script>
+
+<template>
+ <div class="image-notes" @click="handleSidebarClick">
+ <h2 class="gl-font-weight-bold gl-mt-0">
+ {{ issue.title }}
+ </h2>
+ <a
+ class="gl-text-gray-600 gl-text-decoration-none gl-mb-6 gl-display-block"
+ :href="issue.webUrl"
+ >{{ issue.webPath }}</a
+ >
+ <participants
+ :participants="discussionParticipants"
+ :show-participant-label="false"
+ class="gl-mb-4"
+ />
+ <h2
+ v-if="unresolvedDiscussions.length === 0"
+ class="new-discussion-disclaimer gl-font-base gl-m-0 gl-mb-4"
+ data-testid="new-discussion-disclaimer"
+ >
+ {{ s__("DesignManagement|Click the image where you'd like to start a new discussion") }}
+ </h2>
+ <design-discussion
+ v-for="discussion in unresolvedDiscussions"
+ :key="discussion.id"
+ :discussion="discussion"
+ :design-id="$route.params.id"
+ :noteable-id="design.id"
+ :markdown-preview-path="markdownPreviewPath"
+ :resolved-discussions-expanded="resolvedDiscussionsExpanded"
+ data-testid="unresolved-discussion"
+ @createNoteError="$emit('onDesignDiscussionError', $event)"
+ @updateNoteError="$emit('updateNoteError', $event)"
+ @resolveDiscussionError="$emit('resolveDiscussionError', $event)"
+ @click.native.stop="updateActiveDiscussion(discussion.notes[0].id)"
+ />
+ <template v-if="resolvedDiscussions.length > 0">
+ <gl-button
+ id="resolved-comments"
+ data-testid="resolved-comments"
+ :icon="resolvedCommentsToggleIcon"
+ variant="link"
+ class="link-inherit-color gl-text-black-normal gl-text-decoration-none gl-font-weight-bold gl-mb-4"
+ @click="$emit('toggleResolvedComments')"
+ >{{ $options.resolveCommentsToggleText }} ({{ resolvedDiscussions.length }})
+ </gl-button>
+ <gl-popover
+ v-if="!isResolvedCommentsPopoverHidden"
+ :show="!isResolvedCommentsPopoverHidden"
+ target="resolved-comments"
+ container="popovercontainer"
+ placement="top"
+ :title="s__('DesignManagement|Resolved Comments')"
+ >
+ <p>
+ {{
+ s__(
+ 'DesignManagement|Comments you resolve can be viewed and unresolved by going to the "Resolved Comments" section below',
+ )
+ }}
+ </p>
+ <a href="#" rel="noopener noreferrer" target="_blank">{{
+ s__('DesignManagement|Learn more about resolving comments')
+ }}</a>
+ </gl-popover>
+ <gl-collapse :visible="resolvedDiscussionsExpanded" class="gl-mt-3">
+ <design-discussion
+ v-for="discussion in resolvedDiscussions"
+ :key="discussion.id"
+ :discussion="discussion"
+ :design-id="$route.params.id"
+ :noteable-id="design.id"
+ :markdown-preview-path="markdownPreviewPath"
+ :resolved-discussions-expanded="resolvedDiscussionsExpanded"
+ data-testid="resolved-discussion"
+ @error="$emit('onDesignDiscussionError', $event)"
+ @updateNoteError="$emit('updateNoteError', $event)"
+ @click.native.stop="updateActiveDiscussion(discussion.notes[0].id)"
+ />
+ </gl-collapse>
+ </template>
+ <slot name="replyForm"></slot>
+ </div>
+</template>
diff --git a/app/assets/javascripts/design_management/graphql/fragments/design.fragment.graphql b/app/assets/javascripts/design_management/graphql/fragments/design.fragment.graphql
index ca5b5a52c71..c1439c56ff5 100644
--- a/app/assets/javascripts/design_management/graphql/fragments/design.fragment.graphql
+++ b/app/assets/javascripts/design_management/graphql/fragments/design.fragment.graphql
@@ -1,6 +1,7 @@
#import "./designNote.fragment.graphql"
#import "./designList.fragment.graphql"
#import "./diffRefs.fragment.graphql"
+#import "./discussion_resolved_status.fragment.graphql"
fragment DesignItem on Design {
...DesignListItem
@@ -12,6 +13,7 @@ fragment DesignItem on Design {
nodes {
id
replyId
+ ...ResolvedStatus
notes {
nodes {
...DesignNote
diff --git a/app/assets/javascripts/design_management/graphql/fragments/designNote.fragment.graphql b/app/assets/javascripts/design_management/graphql/fragments/designNote.fragment.graphql
index 2ad84f9cb17..cb7cfd89abf 100644
--- a/app/assets/javascripts/design_management/graphql/fragments/designNote.fragment.graphql
+++ b/app/assets/javascripts/design_management/graphql/fragments/designNote.fragment.graphql
@@ -10,6 +10,7 @@ fragment DesignNote on Note {
body
bodyHtml
createdAt
+ resolved
position {
diffRefs {
...DesignDiffRefs
diff --git a/app/assets/javascripts/design_management/graphql/fragments/discussion_resolved_status.fragment.graphql b/app/assets/javascripts/design_management/graphql/fragments/discussion_resolved_status.fragment.graphql
new file mode 100644
index 00000000000..7483b508721
--- /dev/null
+++ b/app/assets/javascripts/design_management/graphql/fragments/discussion_resolved_status.fragment.graphql
@@ -0,0 +1,9 @@
+fragment ResolvedStatus on Discussion {
+ resolvable
+ resolved
+ resolvedAt
+ resolvedBy {
+ name
+ webUrl
+ }
+}
diff --git a/app/assets/javascripts/design_management/graphql/mutations/toggle_resolve_discussion.mutation.graphql b/app/assets/javascripts/design_management/graphql/mutations/toggle_resolve_discussion.mutation.graphql
new file mode 100644
index 00000000000..d5f54ec9b58
--- /dev/null
+++ b/app/assets/javascripts/design_management/graphql/mutations/toggle_resolve_discussion.mutation.graphql
@@ -0,0 +1,17 @@
+#import "../fragments/designNote.fragment.graphql"
+#import "../fragments/discussion_resolved_status.fragment.graphql"
+
+mutation toggleResolveDiscussion($id: ID!, $resolve: Boolean!) {
+ discussionToggleResolve(input: { id: $id, resolve: $resolve }) {
+ discussion {
+ id
+ ...ResolvedStatus
+ notes {
+ nodes {
+ ...DesignNote
+ }
+ }
+ }
+ errors
+ }
+}
diff --git a/app/assets/javascripts/design_management/pages/design/index.vue b/app/assets/javascripts/design_management/pages/design/index.vue
index f4014e3cc55..fe121b6530a 100644
--- a/app/assets/javascripts/design_management/pages/design/index.vue
+++ b/app/assets/javascripts/design_management/pages/design/index.vue
@@ -1,17 +1,16 @@
<script>
-import { ApolloMutation } from 'vue-apollo';
import Mousetrap from 'mousetrap';
import { GlLoadingIcon, GlAlert } from '@gitlab/ui';
+import { ApolloMutation } from 'vue-apollo';
import createFlash from '~/flash';
import { fetchPolicies } from '~/lib/graphql';
import allVersionsMixin from '../../mixins/all_versions';
import Toolbar from '../../components/toolbar/index.vue';
-import DesignDiscussion from '../../components/design_notes/design_discussion.vue';
-import DesignReplyForm from '../../components/design_notes/design_reply_form.vue';
import DesignDestroyer from '../../components/design_destroyer.vue';
import DesignScaler from '../../components/design_scaler.vue';
-import Participants from '~/sidebar/components/participants/participants.vue';
import DesignPresentation from '../../components/design_presentation.vue';
+import DesignReplyForm from '../../components/design_notes/design_reply_form.vue';
+import DesignSidebar from '../../components/design_sidebar.vue';
import getDesignQuery from '../../graphql/queries/getDesign.query.graphql';
import appDataQuery from '../../graphql/queries/appData.query.graphql';
import createImageDiffNoteMutation from '../../graphql/mutations/createImageDiffNote.mutation.graphql';
@@ -20,7 +19,6 @@ import updateActiveDiscussionMutation from '../../graphql/mutations/update_activ
import {
extractDiscussions,
extractDesign,
- extractParticipants,
updateImageDiffNoteOptimisticResponse,
} from '../../utils/design_management_utils';
import {
@@ -43,15 +41,14 @@ import { ACTIVE_DISCUSSION_SOURCE_TYPES } from '../../constants';
export default {
components: {
ApolloMutation,
+ DesignReplyForm,
DesignPresentation,
- DesignDiscussion,
DesignScaler,
DesignDestroyer,
Toolbar,
- DesignReplyForm,
GlLoadingIcon,
GlAlert,
- Participants,
+ DesignSidebar,
},
mixins: [allVersionsMixin],
props: {
@@ -69,6 +66,7 @@ export default {
errorMessage: '',
issueIid: '',
scale: 1,
+ resolvedDiscussionsExpanded: false,
};
},
apollo: {
@@ -103,20 +101,17 @@ export default {
return this.$apollo.queries.design.loading && !this.design.filename;
},
discussions() {
+ if (!this.design.discussions) {
+ return [];
+ }
return extractDiscussions(this.design.discussions);
},
- discussionParticipants() {
- return extractParticipants(this.design.issue.participants);
- },
markdownPreviewPath() {
return `/${this.projectPath}/preview_markdown?target_type=Issue`;
},
isSubmitButtonDisabled() {
return this.comment.trim().length === 0;
},
- renderDiscussions() {
- return this.discussions.length || this.annotationCoordinates;
- },
designVariables() {
return {
fullPath: this.projectPath,
@@ -144,15 +139,19 @@ export default {
},
};
},
- issue() {
- return {
- ...this.design.issue,
- webPath: this.design.issue.webPath.substr(1),
- };
- },
isAnnotating() {
return Boolean(this.annotationCoordinates);
},
+ resolvedDiscussions() {
+ return this.discussions.filter(discussion => discussion.resolved);
+ },
+ },
+ watch: {
+ resolvedDiscussions(val) {
+ if (!val.length) {
+ this.resolvedDiscussionsExpanded = false;
+ }
+ },
},
mounted() {
Mousetrap.bind('esc', this.closeDesign);
@@ -250,6 +249,9 @@ export default {
onDesignDeleteError(e) {
this.onError(designDeletionError({ singular: true }), e);
},
+ onResolveDiscussionError(e) {
+ this.onError(UPDATE_IMAGE_DIFF_NOTE_ERROR, e);
+ },
openCommentForm(annotationCoordinates) {
this.annotationCoordinates = annotationCoordinates;
},
@@ -281,6 +283,9 @@ export default {
},
});
},
+ toggleResolvedComments() {
+ this.resolvedDiscussionsExpanded = !this.resolvedDiscussionsExpanded;
+ },
},
createImageDiffNoteMutation,
DESIGNS_ROUTE_NAME,
@@ -323,6 +328,7 @@ export default {
:discussions="discussions"
:is-annotating="isAnnotating"
:scale="scale"
+ :resolved-discussions-expanded="resolvedDiscussionsExpanded"
@openCommentForm="openCommentForm"
@closeCommentForm="closeCommentForm"
@moveNote="onMoveNote"
@@ -332,33 +338,19 @@ export default {
<design-scaler @scale="scale = $event" />
</div>
</div>
- <div class="image-notes" @click="updateActiveDiscussion()">
- <h2 class="gl-font-size-20-deprecated-no-really-do-not-use-me font-weight-bold mt-0">
- {{ issue.title }}
- </h2>
- <a class="text-tertiary text-decoration-none mb-3 d-block" :href="issue.webUrl">{{
- issue.webPath
- }}</a>
- <participants
- :participants="discussionParticipants"
- :show-participant-label="false"
- class="mb-4"
- />
- <template v-if="renderDiscussions">
- <design-discussion
- v-for="(discussion, index) in discussions"
- :key="discussion.id"
- :discussion="discussion"
- :design-id="id"
- :noteable-id="design.id"
- :discussion-index="index + 1"
- :markdown-preview-path="markdownPreviewPath"
- @error="onDesignDiscussionError"
- @updateNoteError="onUpdateNoteError"
- @click.native.stop="updateActiveDiscussion(discussion.notes[0].id)"
- />
+ <design-sidebar
+ :design="design"
+ :resolved-discussions-expanded="resolvedDiscussionsExpanded"
+ :markdown-preview-path="markdownPreviewPath"
+ @onDesignDiscussionError="onDesignDiscussionError"
+ @onCreateImageDiffNoteError="onCreateImageDiffNoteError"
+ @updateNoteError="onUpdateNoteError"
+ @resolveDiscussionError="onResolveDiscussionError"
+ @toggleResolvedComments="toggleResolvedComments"
+ >
+ <template #replyForm>
<apollo-mutation
- v-if="annotationCoordinates"
+ v-if="isAnnotating"
#default="{ mutate, loading }"
:mutation="$options.createImageDiffNoteMutation"
:variables="{
@@ -374,13 +366,9 @@ export default {
:markdown-preview-path="markdownPreviewPath"
@submitForm="mutate"
@cancelForm="closeCommentForm"
- />
- </apollo-mutation>
- </template>
- <h2 v-else class="new-discussion-disclaimer gl-font-base m-0">
- {{ __("Click the image where you'd like to start a new discussion") }}
- </h2>
- </div>
+ /> </apollo-mutation
+ ></template>
+ </design-sidebar>
</template>
</div>
</template>
diff --git a/app/assets/javascripts/design_management/utils/cache_update.js b/app/assets/javascripts/design_management/utils/cache_update.js
index 01c073bddc2..24b374b79fd 100644
--- a/app/assets/javascripts/design_management/utils/cache_update.js
+++ b/app/assets/javascripts/design_management/utils/cache_update.js
@@ -95,6 +95,10 @@ const addImageDiffNoteToStore = (store, createImageDiffNote, query, variables) =
__typename: 'Discussion',
id: createImageDiffNote.note.discussion.id,
replyId: createImageDiffNote.note.discussion.replyId,
+ resolvable: true,
+ resolved: false,
+ resolvedAt: null,
+ resolvedBy: null,
notes: {
__typename: 'NoteConnection',
nodes: [createImageDiffNote.note],
diff --git a/app/assets/javascripts/design_management/utils/design_management_utils.js b/app/assets/javascripts/design_management/utils/design_management_utils.js
index 19d5ca147e3..22705cf67a1 100644
--- a/app/assets/javascripts/design_management/utils/design_management_utils.js
+++ b/app/assets/javascripts/design_management/utils/design_management_utils.js
@@ -21,8 +21,9 @@ export const extractNodes = elements => elements.edges.map(({ node }) => node);
*/
export const extractDiscussions = discussions =>
- discussions.nodes.map(discussion => ({
+ discussions.nodes.map((discussion, index) => ({
...discussion,
+ index: index + 1,
notes: discussion.notes.nodes,
}));
diff --git a/app/assets/javascripts/registry/explorer/components/cli_commands.vue b/app/assets/javascripts/registry/explorer/components/cli_commands.vue
index 96455496239..679d9cf7fab 100644
--- a/app/assets/javascripts/registry/explorer/components/cli_commands.vue
+++ b/app/assets/javascripts/registry/explorer/components/cli_commands.vue
@@ -11,7 +11,7 @@ import {
COPY_BUILD_TITLE,
PUSH_COMMAND_LABEL,
COPY_PUSH_TITLE,
-} from '../constants';
+} from '../constants/index';
export default {
components: {
diff --git a/app/assets/javascripts/registry/explorer/components/image_list_row.vue b/app/assets/javascripts/registry/explorer/components/image_list_row.vue
index 1b631ca36de..a2b1f615029 100644
--- a/app/assets/javascripts/registry/explorer/components/image_list_row.vue
+++ b/app/assets/javascripts/registry/explorer/components/image_list_row.vue
@@ -8,7 +8,7 @@ import {
LIST_DELETE_BUTTON_DISABLED,
REMOVE_REPOSITORY_LABEL,
ROW_SCHEDULED_FOR_DELETION,
-} from '../constants';
+} from '../constants/index';
export default {
name: 'ImageListrow',
diff --git a/app/assets/javascripts/registry/explorer/components/project_empty_state.vue b/app/assets/javascripts/registry/explorer/components/project_empty_state.vue
index 0ce38c4a9ec..87bb65ae0a9 100644
--- a/app/assets/javascripts/registry/explorer/components/project_empty_state.vue
+++ b/app/assets/javascripts/registry/explorer/components/project_empty_state.vue
@@ -3,7 +3,12 @@ import { GlEmptyState, GlSprintf, GlLink } from '@gitlab/ui';
import { mapState, mapGetters } from 'vuex';
import { s__ } from '~/locale';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
-import { COPY_LOGIN_TITLE, COPY_BUILD_TITLE, COPY_PUSH_TITLE, QUICK_START } from '../constants';
+import {
+ COPY_LOGIN_TITLE,
+ COPY_BUILD_TITLE,
+ COPY_PUSH_TITLE,
+ QUICK_START,
+} from '../constants/index';
export default {
name: 'ProjectEmptyState',
diff --git a/app/assets/javascripts/registry/explorer/components/registry_header.vue b/app/assets/javascripts/registry/explorer/components/registry_header.vue
index 6b6154e87dc..870cffa0487 100644
--- a/app/assets/javascripts/registry/explorer/components/registry_header.vue
+++ b/app/assets/javascripts/registry/explorer/components/registry_header.vue
@@ -9,7 +9,7 @@ import {
EXPIRATION_POLICY_WILL_RUN_IN,
EXPIRATION_POLICY_DISABLED_TEXT,
EXPIRATION_POLICY_DISABLED_MESSAGE,
-} from '../constants';
+} from '../constants/index';
export default {
components: {
diff --git a/app/assets/javascripts/registry/explorer/constants.js b/app/assets/javascripts/registry/explorer/constants.js
deleted file mode 100644
index 5325086b773..00000000000
--- a/app/assets/javascripts/registry/explorer/constants.js
+++ /dev/null
@@ -1,131 +0,0 @@
-import { s__ } from '~/locale';
-
-// List page
-
-export const CONTAINER_REGISTRY_TITLE = s__('ContainerRegistry|Container Registry');
-export const CONNECTION_ERROR_TITLE = s__('ContainerRegistry|Docker connection error');
-export const CONNECTION_ERROR_MESSAGE = s__(
- `ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}`,
-);
-export const LIST_INTRO_TEXT = s__(
- `ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}`,
-);
-
-export const LIST_DELETE_BUTTON_DISABLED = s__(
- 'ContainerRegistry|Missing or insufficient permission, delete button disabled',
-);
-export const REMOVE_REPOSITORY_LABEL = s__('ContainerRegistry|Remove repository');
-export const REMOVE_REPOSITORY_MODAL_TEXT = s__(
- 'ContainerRegistry|You are about to remove repository %{title}. Once you confirm, this repository will be permanently deleted.',
-);
-export const ROW_SCHEDULED_FOR_DELETION = s__(
- `ContainerRegistry|This image repository is scheduled for deletion`,
-);
-export const FETCH_IMAGES_LIST_ERROR_MESSAGE = s__(
- 'ContainerRegistry|Something went wrong while fetching the repository list.',
-);
-export const FETCH_TAGS_LIST_ERROR_MESSAGE = s__(
- 'ContainerRegistry|Something went wrong while fetching the tags list.',
-);
-export const DELETE_IMAGE_ERROR_MESSAGE = s__(
- 'ContainerRegistry|Something went wrong while scheduling %{title} for deletion. Please try again.',
-);
-export const ASYNC_DELETE_IMAGE_ERROR_MESSAGE = s__(
- `ContainerRegistry|There was an error during the deletion of this image repository, please try again.`,
-);
-export const DELETE_IMAGE_SUCCESS_MESSAGE = s__(
- 'ContainerRegistry|%{title} was successfully scheduled for deletion',
-);
-
-export const IMAGE_REPOSITORY_LIST_LABEL = s__('ContainerRegistry|Image Repositories');
-
-export const SEARCH_PLACEHOLDER_TEXT = s__('ContainerRegistry|Filter by name');
-
-export const EMPTY_RESULT_TITLE = s__('ContainerRegistry|Sorry, your filter produced no results.');
-export const EMPTY_RESULT_MESSAGE = s__(
- 'ContainerRegistry|To widen your search, change or remove the filters above.',
-);
-
-// Image details page
-
-export const DETAILS_PAGE_TITLE = s__('ContainerRegistry|%{imageName} tags');
-
-export const DELETE_TAG_ERROR_MESSAGE = s__(
- 'ContainerRegistry|Something went wrong while marking the tag for deletion.',
-);
-export const DELETE_TAG_SUCCESS_MESSAGE = s__(
- 'ContainerRegistry|Tag successfully marked for deletion.',
-);
-export const DELETE_TAGS_ERROR_MESSAGE = s__(
- 'ContainerRegistry|Something went wrong while marking the tags for deletion.',
-);
-export const DELETE_TAGS_SUCCESS_MESSAGE = s__(
- 'ContainerRegistry|Tags successfully marked for deletion.',
-);
-
-export const DEFAULT_PAGE = 1;
-export const DEFAULT_PAGE_SIZE = 10;
-
-export const GROUP_PAGE_TYPE = 'groups';
-
-export const LIST_KEY_TAG = 'name';
-export const LIST_KEY_IMAGE_ID = 'short_revision';
-export const LIST_KEY_SIZE = 'total_size';
-export const LIST_KEY_LAST_UPDATED = 'created_at';
-export const LIST_KEY_ACTIONS = 'actions';
-export const LIST_KEY_CHECKBOX = 'checkbox';
-
-export const LIST_LABEL_TAG = s__('ContainerRegistry|Tag');
-export const LIST_LABEL_IMAGE_ID = s__('ContainerRegistry|Image ID');
-export const LIST_LABEL_SIZE = s__('ContainerRegistry|Compressed Size');
-export const LIST_LABEL_LAST_UPDATED = s__('ContainerRegistry|Last Updated');
-
-export const REMOVE_TAG_BUTTON_TITLE = s__('ContainerRegistry|Remove tag');
-export const REMOVE_TAGS_BUTTON_TITLE = s__('ContainerRegistry|Remove selected tags');
-
-export const REMOVE_TAG_CONFIRMATION_TEXT = s__(
- `ContainerRegistry|You are about to remove %{item}. Are you sure?`,
-);
-export const REMOVE_TAGS_CONFIRMATION_TEXT = s__(
- `ContainerRegistry|You are about to remove %{item} tags. Are you sure?`,
-);
-
-export const EMPTY_IMAGE_REPOSITORY_TITLE = s__('ContainerRegistry|This image has no active tags');
-export const EMPTY_IMAGE_REPOSITORY_MESSAGE = s__(
- `ContainerRegistry|The last tag related to this image was recently removed.
-This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process.
-If you have any questions, contact your administrator.`,
-);
-
-export const ADMIN_GARBAGE_COLLECTION_TIP = s__(
- 'ContainerRegistry|Remember to run %{docLinkStart}garbage collection%{docLinkEnd} to remove the stale data from storage.',
-);
-
-// Expiration policies
-
-export const EXPIRATION_POLICY_WILL_RUN_IN = s__(
- 'ContainerRegistry|Expiration policy will run in %{time}',
-);
-
-export const EXPIRATION_POLICY_DISABLED_TEXT = s__(
- 'ContainerRegistry|Expiration policy is disabled',
-);
-
-export const EXPIRATION_POLICY_DISABLED_MESSAGE = s__(
- 'ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}',
-);
-
-// Quick Start
-
-export const QUICK_START = s__('ContainerRegistry|CLI Commands');
-export const LOGIN_COMMAND_LABEL = s__('ContainerRegistry|Login');
-export const COPY_LOGIN_TITLE = s__('ContainerRegistry|Copy login command');
-export const BUILD_COMMAND_LABEL = s__('ContainerRegistry|Build an image');
-export const COPY_BUILD_TITLE = s__('ContainerRegistry|Copy build command');
-export const PUSH_COMMAND_LABEL = s__('ContainerRegistry|Push an image');
-export const COPY_PUSH_TITLE = s__('ContainerRegistry|Copy push command');
-
-// Image state
-
-export const IMAGE_DELETE_SCHEDULED_STATUS = 'delete_scheduled';
-export const IMAGE_FAILED_DELETED_STATUS = 'delete_failed';
diff --git a/app/assets/javascripts/registry/explorer/constants/details.js b/app/assets/javascripts/registry/explorer/constants/details.js
new file mode 100644
index 00000000000..0eeb6001772
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/constants/details.js
@@ -0,0 +1,49 @@
+import { s__ } from '~/locale';
+
+// Translations strings
+export const DETAILS_PAGE_TITLE = s__('ContainerRegistry|%{imageName} tags');
+export const DELETE_TAG_ERROR_MESSAGE = s__(
+ 'ContainerRegistry|Something went wrong while marking the tag for deletion.',
+);
+export const DELETE_TAG_SUCCESS_MESSAGE = s__(
+ 'ContainerRegistry|Tag successfully marked for deletion.',
+);
+export const DELETE_TAGS_ERROR_MESSAGE = s__(
+ 'ContainerRegistry|Something went wrong while marking the tags for deletion.',
+);
+export const DELETE_TAGS_SUCCESS_MESSAGE = s__(
+ 'ContainerRegistry|Tags successfully marked for deletion.',
+);
+export const LIST_LABEL_TAG = s__('ContainerRegistry|Tag');
+export const LIST_LABEL_IMAGE_ID = s__('ContainerRegistry|Image ID');
+export const LIST_LABEL_SIZE = s__('ContainerRegistry|Compressed Size');
+export const LIST_LABEL_LAST_UPDATED = s__('ContainerRegistry|Last Updated');
+export const REMOVE_TAG_BUTTON_TITLE = s__('ContainerRegistry|Remove tag');
+export const REMOVE_TAGS_BUTTON_TITLE = s__('ContainerRegistry|Remove selected tags');
+export const REMOVE_TAG_CONFIRMATION_TEXT = s__(
+ `ContainerRegistry|You are about to remove %{item}. Are you sure?`,
+);
+export const REMOVE_TAGS_CONFIRMATION_TEXT = s__(
+ `ContainerRegistry|You are about to remove %{item} tags. Are you sure?`,
+);
+export const EMPTY_IMAGE_REPOSITORY_TITLE = s__('ContainerRegistry|This image has no active tags');
+export const EMPTY_IMAGE_REPOSITORY_MESSAGE = s__(
+ `ContainerRegistry|The last tag related to this image was recently removed.
+This empty image and any associated data will be automatically removed as part of the regular Garbage Collection process.
+If you have any questions, contact your administrator.`,
+);
+export const ADMIN_GARBAGE_COLLECTION_TIP = s__(
+ 'ContainerRegistry|Remember to run %{docLinkStart}garbage collection%{docLinkEnd} to remove the stale data from storage.',
+);
+
+// Parameters
+
+export const DEFAULT_PAGE = 1;
+export const DEFAULT_PAGE_SIZE = 10;
+export const GROUP_PAGE_TYPE = 'groups';
+export const LIST_KEY_TAG = 'name';
+export const LIST_KEY_IMAGE_ID = 'short_revision';
+export const LIST_KEY_SIZE = 'total_size';
+export const LIST_KEY_LAST_UPDATED = 'created_at';
+export const LIST_KEY_ACTIONS = 'actions';
+export const LIST_KEY_CHECKBOX = 'checkbox';
diff --git a/app/assets/javascripts/registry/explorer/constants/expiration_policies.js b/app/assets/javascripts/registry/explorer/constants/expiration_policies.js
new file mode 100644
index 00000000000..8af25ca6ecc
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/constants/expiration_policies.js
@@ -0,0 +1,11 @@
+import { s__ } from '~/locale';
+
+export const EXPIRATION_POLICY_WILL_RUN_IN = s__(
+ 'ContainerRegistry|Expiration policy will run in %{time}',
+);
+export const EXPIRATION_POLICY_DISABLED_TEXT = s__(
+ 'ContainerRegistry|Expiration policy is disabled',
+);
+export const EXPIRATION_POLICY_DISABLED_MESSAGE = s__(
+ 'ContainerRegistry|Expiration policies help manage the storage space used by the Container Registry, but the expiration policies for this registry are disabled. Contact your administrator to enable. %{docLinkStart}More information%{docLinkEnd}',
+);
diff --git a/app/assets/javascripts/registry/explorer/constants/index.js b/app/assets/javascripts/registry/explorer/constants/index.js
new file mode 100644
index 00000000000..10816e12ead
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/constants/index.js
@@ -0,0 +1,4 @@
+export * from './expiration_policies';
+export * from './quick_start';
+export * from './list';
+export * from './details';
diff --git a/app/assets/javascripts/registry/explorer/constants/list.js b/app/assets/javascripts/registry/explorer/constants/list.js
new file mode 100644
index 00000000000..39f63d2a153
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/constants/list.js
@@ -0,0 +1,48 @@
+import { s__ } from '~/locale';
+
+// Translations strings
+
+export const CONTAINER_REGISTRY_TITLE = s__('ContainerRegistry|Container Registry');
+export const CONNECTION_ERROR_TITLE = s__('ContainerRegistry|Docker connection error');
+export const CONNECTION_ERROR_MESSAGE = s__(
+ `ContainerRegistry|We are having trouble connecting to the Registry, which could be due to an issue with your project name or path. %{docLinkStart}More information%{docLinkEnd}`,
+);
+export const LIST_INTRO_TEXT = s__(
+ `ContainerRegistry|With the GitLab Container Registry, every project can have its own space to store images. %{docLinkStart}More information%{docLinkEnd}`,
+);
+export const LIST_DELETE_BUTTON_DISABLED = s__(
+ 'ContainerRegistry|Missing or insufficient permission, delete button disabled',
+);
+export const REMOVE_REPOSITORY_LABEL = s__('ContainerRegistry|Remove repository');
+export const REMOVE_REPOSITORY_MODAL_TEXT = s__(
+ 'ContainerRegistry|You are about to remove repository %{title}. Once you confirm, this repository will be permanently deleted.',
+);
+export const ROW_SCHEDULED_FOR_DELETION = s__(
+ `ContainerRegistry|This image repository is scheduled for deletion`,
+);
+export const FETCH_IMAGES_LIST_ERROR_MESSAGE = s__(
+ 'ContainerRegistry|Something went wrong while fetching the repository list.',
+);
+export const FETCH_TAGS_LIST_ERROR_MESSAGE = s__(
+ 'ContainerRegistry|Something went wrong while fetching the tags list.',
+);
+export const DELETE_IMAGE_ERROR_MESSAGE = s__(
+ 'ContainerRegistry|Something went wrong while scheduling %{title} for deletion. Please try again.',
+);
+export const ASYNC_DELETE_IMAGE_ERROR_MESSAGE = s__(
+ `ContainerRegistry|There was an error during the deletion of this image repository, please try again.`,
+);
+export const DELETE_IMAGE_SUCCESS_MESSAGE = s__(
+ 'ContainerRegistry|%{title} was successfully scheduled for deletion',
+);
+export const IMAGE_REPOSITORY_LIST_LABEL = s__('ContainerRegistry|Image Repositories');
+export const SEARCH_PLACEHOLDER_TEXT = s__('ContainerRegistry|Filter by name');
+export const EMPTY_RESULT_TITLE = s__('ContainerRegistry|Sorry, your filter produced no results.');
+export const EMPTY_RESULT_MESSAGE = s__(
+ 'ContainerRegistry|To widen your search, change or remove the filters above.',
+);
+
+// Parameters
+
+export const IMAGE_DELETE_SCHEDULED_STATUS = 'delete_scheduled';
+export const IMAGE_FAILED_DELETED_STATUS = 'delete_failed';
diff --git a/app/assets/javascripts/registry/explorer/constants/quick_start.js b/app/assets/javascripts/registry/explorer/constants/quick_start.js
new file mode 100644
index 00000000000..6a39c07eba2
--- /dev/null
+++ b/app/assets/javascripts/registry/explorer/constants/quick_start.js
@@ -0,0 +1,9 @@
+import { s__ } from '~/locale';
+
+export const QUICK_START = s__('ContainerRegistry|CLI Commands');
+export const LOGIN_COMMAND_LABEL = s__('ContainerRegistry|Login');
+export const COPY_LOGIN_TITLE = s__('ContainerRegistry|Copy login command');
+export const BUILD_COMMAND_LABEL = s__('ContainerRegistry|Build an image');
+export const COPY_BUILD_TITLE = s__('ContainerRegistry|Copy build command');
+export const PUSH_COMMAND_LABEL = s__('ContainerRegistry|Push an image');
+export const COPY_PUSH_TITLE = s__('ContainerRegistry|Copy push command');
diff --git a/app/assets/javascripts/registry/explorer/pages/details.vue b/app/assets/javascripts/registry/explorer/pages/details.vue
index cc2dc531dc8..9b8ae16e4cd 100644
--- a/app/assets/javascripts/registry/explorer/pages/details.vue
+++ b/app/assets/javascripts/registry/explorer/pages/details.vue
@@ -45,7 +45,7 @@ import {
EMPTY_IMAGE_REPOSITORY_TITLE,
EMPTY_IMAGE_REPOSITORY_MESSAGE,
ADMIN_GARBAGE_COLLECTION_TIP,
-} from '../constants';
+} from '../constants/index';
export default {
components: {
diff --git a/app/assets/javascripts/registry/explorer/pages/list.vue b/app/assets/javascripts/registry/explorer/pages/list.vue
index fa8b56eb76b..c3e1febe087 100644
--- a/app/assets/javascripts/registry/explorer/pages/list.vue
+++ b/app/assets/javascripts/registry/explorer/pages/list.vue
@@ -29,7 +29,7 @@ import {
IMAGE_REPOSITORY_LIST_LABEL,
EMPTY_RESULT_TITLE,
EMPTY_RESULT_MESSAGE,
-} from '../constants';
+} from '../constants/index';
export default {
name: 'RegistryListApp',
diff --git a/app/assets/javascripts/registry/explorer/router.js b/app/assets/javascripts/registry/explorer/router.js
index 478eaca1a68..f570987023b 100644
--- a/app/assets/javascripts/registry/explorer/router.js
+++ b/app/assets/javascripts/registry/explorer/router.js
@@ -1,9 +1,9 @@
import Vue from 'vue';
import VueRouter from 'vue-router';
-import { s__ } from '~/locale';
import List from './pages/list.vue';
import Details from './pages/details.vue';
import { decodeAndParse } from './utils';
+import { CONTAINER_REGISTRY_TITLE } from './constants/index';
Vue.use(VueRouter);
@@ -17,7 +17,7 @@ export default function createRouter(base) {
path: '/',
component: List,
meta: {
- nameGenerator: () => s__('ContainerRegistry|Container Registry'),
+ nameGenerator: () => CONTAINER_REGISTRY_TITLE,
root: true,
},
},
diff --git a/app/assets/javascripts/registry/explorer/stores/actions.js b/app/assets/javascripts/registry/explorer/stores/actions.js
index 7f80bc21d6e..3d73ffbd23f 100644
--- a/app/assets/javascripts/registry/explorer/stores/actions.js
+++ b/app/assets/javascripts/registry/explorer/stores/actions.js
@@ -6,7 +6,7 @@ import {
DEFAULT_PAGE,
DEFAULT_PAGE_SIZE,
FETCH_TAGS_LIST_ERROR_MESSAGE,
-} from '../constants';
+} from '../constants/index';
import { decodeAndParse } from '../utils';
export const setInitialState = ({ commit }, data) => commit(types.SET_INITIAL_STATE, data);
diff --git a/app/assets/javascripts/registry/explorer/stores/mutations.js b/app/assets/javascripts/registry/explorer/stores/mutations.js
index b25a0221dc1..848c556e738 100644
--- a/app/assets/javascripts/registry/explorer/stores/mutations.js
+++ b/app/assets/javascripts/registry/explorer/stores/mutations.js
@@ -1,6 +1,6 @@
import * as types from './mutation_types';
import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils';
-import { IMAGE_DELETE_SCHEDULED_STATUS, IMAGE_FAILED_DELETED_STATUS } from '../constants';
+import { IMAGE_DELETE_SCHEDULED_STATUS, IMAGE_FAILED_DELETED_STATUS } from '../constants/index';
export default {
[types.SET_INITIAL_STATE](state, config) {
diff --git a/app/assets/stylesheets/components/design_management/design.scss b/app/assets/stylesheets/components/design_management/design.scss
index 8a83a1612ff..380b2280490 100644
--- a/app/assets/stylesheets/components/design_management/design.scss
+++ b/app/assets/stylesheets/components/design_management/design.scss
@@ -20,6 +20,20 @@
}
}
}
+
+ .badge.badge-pill {
+ display: flex;
+ height: 28px;
+ width: 28px;
+ background-color: $blue-400;
+ color: $white;
+ border: $white 1px solid;
+ border-radius: 50%;
+
+ &.resolved {
+ background-color: $gray-700;
+ }
+ }
}
.design-presentation-wrapper {
@@ -52,14 +66,31 @@
min-width: 400px;
flex-basis: 28%;
+ .link-inherit-color {
+ &:hover,
+ &:active,
+ &:focus {
+ color: inherit;
+ text-decoration: none;
+ }
+ }
+
+ .toggle-comments {
+ line-height: 20px;
+ border-top: 1px solid $border-color;
+
+ &.expanded {
+ border-bottom: 1px solid $border-color;
+ }
+
+ .toggle-comments-button:focus {
+ text-decoration: none;
+ color: $blue-600;
+ }
+ }
+
.badge.badge-pill {
margin-left: $gl-padding;
- background-color: $blue-400;
- color: $white;
- border: $white 1px solid;
- min-height: 28px;
- padding: 7px 10px;
- border-radius: $gl-padding;
}
.design-discussion {
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 39edfeea81e..244b97c7196 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -9,40 +9,6 @@ module IssuesHelper
classes.join(' ')
end
- def url_for_issue(issue_iid, project = @project, options = {})
- return '' if project.nil?
-
- url =
- if options[:internal]
- url_for_internal_issue(issue_iid, project, options)
- else
- url_for_tracker_issue(issue_iid, project, options)
- end
-
- # Ensure we return a valid URL to prevent possible XSS.
- URI.parse(url).to_s
- rescue URI::InvalidURIError
- ''
- end
-
- def url_for_tracker_issue(issue_iid, project, options)
- if options[:only_path]
- project.issues_tracker.issue_path(issue_iid)
- else
- project.issues_tracker.issue_url(issue_iid)
- end
- end
-
- def url_for_internal_issue(issue_iid, project = @project, options = {})
- helpers = Gitlab::Routing.url_helpers
-
- if options[:only_path]
- helpers.namespace_project_issue_path(namespace_id: project.namespace, project_id: project, id: issue_iid)
- else
- helpers.namespace_project_issue_url(namespace_id: project.namespace, project_id: project, id: issue_iid)
- end
- end
-
def status_box_class(item)
if item.try(:expired?)
'status-box-expired'
@@ -168,11 +134,6 @@ module IssuesHelper
def show_moved_service_desk_issue_warning?(issue)
false
end
-
- # Required for Banzai::Filter::IssueReferenceFilter
- module_function :url_for_issue
- module_function :url_for_internal_issue
- module_function :url_for_tracker_issue
end
IssuesHelper.prepend_if_ee('EE::IssuesHelper')
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index 93f18a350ad..156a466b3f8 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -450,6 +450,7 @@ class ProjectPolicy < BasePolicy
rule { repository_disabled }.policy do
prevent :push_code
prevent :download_code
+ prevent :build_download_code
prevent :fork_project
prevent :read_commit_status
prevent :read_pipeline
diff --git a/changelogs/unreleased/13049-design-view-allow-comment-pins-on-designs-to-be-resolvable.yml b/changelogs/unreleased/13049-design-view-allow-comment-pins-on-designs-to-be-resolvable.yml
new file mode 100644
index 00000000000..579485e7488
--- /dev/null
+++ b/changelogs/unreleased/13049-design-view-allow-comment-pins-on-designs-to-be-resolvable.yml
@@ -0,0 +1,5 @@
+---
+title: "[Frontend] Resolvable design discussions"
+merge_request: 32399
+author:
+type: added
diff --git a/changelogs/unreleased/220058.yml b/changelogs/unreleased/220058.yml
new file mode 100644
index 00000000000..4327732eef7
--- /dev/null
+++ b/changelogs/unreleased/220058.yml
@@ -0,0 +1,5 @@
+---
+title: Fix sidebar spacing for alert details
+merge_request: 33630
+author:
+type: fixed
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 8d7c865e397..508407d3540 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -255,7 +255,7 @@ module.exports = {
moduleIds: 'hashed',
runtimeChunk: 'single',
splitChunks: {
- maxInitialRequests: 4,
+ maxInitialRequests: 20,
cacheGroups: {
default: false,
common: () => ({
diff --git a/doc/.vale/gitlab/Acronyms.yml b/doc/.vale/gitlab/Acronyms.yml
index 7dfbb7283c5..5be8435b99f 100644
--- a/doc/.vale/gitlab/Acronyms.yml
+++ b/doc/.vale/gitlab/Acronyms.yml
@@ -16,6 +16,7 @@ exceptions:
- AWS
- CNAME
- CSS
+ - CSV
- DNS
- GET
- GNU
diff --git a/doc/.vale/gitlab/Profanity.yml b/doc/.vale/gitlab/Profanity.yml
deleted file mode 100644
index c386b23e52c..00000000000
--- a/doc/.vale/gitlab/Profanity.yml
+++ /dev/null
@@ -1,30 +0,0 @@
----
-extends: existence
-message: "Remove profanity: '%s'"
-ignorecase: true
-level: error
-tokens:
- - 'arse(hole)?'
- - 'ass(hole)?'
- - 'bastard'
- - 'bitch'
- - 'bloody'
- - 'bollocks'
- - 'bugger'
- - 'cocksucker'
- - 'crap'
- - 'cunt'
- - 'damn'
- - 'eff(ing)?'
- - 'fart'
- - 'fuck(er|ing)?'
- - 'goddamn(it?|ed)'
- - 'hell'
- - 'horseshit'
- - 'motherfuck(ers?|ing)'
- - 'piss(ing)?'
- - 'shit'
- - 'tits'
- - 'turd'
- - 'twat'
- - 'wank(er|ing)?'
diff --git a/doc/administration/reference_architectures/10k_users.md b/doc/administration/reference_architectures/10k_users.md
index b27e941b714..a15fcf722a5 100644
--- a/doc/administration/reference_architectures/10k_users.md
+++ b/doc/administration/reference_architectures/10k_users.md
@@ -8,8 +8,8 @@ For a full list of reference architectures, see
> - **High Availability:** True
> - **Test RPS rates:** API: 200 RPS, Web: 20 RPS, Git: 20 RPS
-| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS ([9](#footnotes)) | Azure([9](#footnotes)) |
-|--------------------------------------------------------------|-------|---------------------------------|----------------|-----------------------|------------------------|
+| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS | Azure |
+|--------------------------------------------------------------|-------|---------------------------------|----------------|-----------------------|----------------|
| GitLab Rails ([1](#footnotes)) | 3 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 | c5.9xlarge | F32s v2 |
| PostgreSQL | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | D4s v3 |
| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
@@ -74,6 +74,3 @@ For a full list of reference architectures, see
or higher, are required for your CPU or Node counts accordingly. For more information, a
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
diff --git a/doc/administration/reference_architectures/1k_users.md b/doc/administration/reference_architectures/1k_users.md
index 0b5117afa8d..c6fd6b821df 100644
--- a/doc/administration/reference_architectures/1k_users.md
+++ b/doc/administration/reference_architectures/1k_users.md
@@ -7,7 +7,7 @@ For a full list of reference architectures, see
> - **Supported users (approximate):** 1,000
> - **High Availability:** False
-| Users | Configuration([8](#footnotes)) | GCP | AWS([9](#footnotes)) | Azure([9](#footnotes)) |
+| Users | Configuration([8](#footnotes)) | GCP | AWS | Azure |
|-------|--------------------------------|---------------|----------------------|------------------------|
| 100 | 2 vCPU, 7.2GB Memory | n1-standard-2 | m5.large | D2s v3 |
| 500 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | D4s v3 |
@@ -77,6 +77,3 @@ added performance and reliability at a reduced complexity cost.
or higher, are required for your CPU or Node counts accordingly. For more information, a
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
diff --git a/doc/administration/reference_architectures/25k_users.md b/doc/administration/reference_architectures/25k_users.md
index c81445434be..8f75277939d 100644
--- a/doc/administration/reference_architectures/25k_users.md
+++ b/doc/administration/reference_architectures/25k_users.md
@@ -8,8 +8,8 @@ For a full list of reference architectures, see
> - **High Availability:** True
> - **Test RPS rates:** API: 500 RPS, Web: 50 RPS, Git: 50 RPS
-| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS ([9](#footnotes)) | Azure([9](#footnotes)) |
-|--------------------------------------------------------------|-------|---------------------------------|----------------|-----------------------|------------------------|
+| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS | Azure |
+|--------------------------------------------------------------|-------|---------------------------------|----------------|-----------------------|----------------|
| GitLab Rails ([1](#footnotes)) | 5 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 | c5.9xlarge | F32s v2 |
| PostgreSQL | 3 | 8 vCPU, 30GB Memory | n1-standard-8 | m5.2xlarge | D8s v3 |
| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
@@ -74,6 +74,3 @@ For a full list of reference architectures, see
or higher, are required for your CPU or Node counts accordingly. For more information, a
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
diff --git a/doc/administration/reference_architectures/2k_users.md b/doc/administration/reference_architectures/2k_users.md
index 5cf217d5816..64082c378c6 100644
--- a/doc/administration/reference_architectures/2k_users.md
+++ b/doc/administration/reference_architectures/2k_users.md
@@ -8,7 +8,7 @@ For a full list of reference architectures, see
> - **High Availability:** False
> - **Test RPS rates:** API: 40 RPS, Web: 4 RPS, Git: 4 RPS
-| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS ([9](#footnotes)) | Azure([9](#footnotes)) |
+| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS | Azure |
|--------------------------------------------------------------|-------|---------------------------------|---------------|-----------------------|----------------|
| External load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
| Object Storage ([4](#footnotes)) | - | - | - | - | - |
@@ -85,6 +85,3 @@ For a full list of reference architectures, see
or higher, are required for your CPU or Node counts accordingly. For more information, a
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
diff --git a/doc/administration/reference_architectures/3k_users.md b/doc/administration/reference_architectures/3k_users.md
index 8a8ce85d030..4290a6ff161 100644
--- a/doc/administration/reference_architectures/3k_users.md
+++ b/doc/administration/reference_architectures/3k_users.md
@@ -14,8 +14,8 @@ following the [2,000-user reference architecture](2k_users.md).
> - **High Availability:** True
> - **Test RPS rates:** API: 60 RPS, Web: 6 RPS, Git: 6 RPS
-| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS ([9](#footnotes)) | Azure([9](#footnotes)) |
-|--------------------------------------------------------------|-------|---------------------------------|---------------|-----------------------|------------------------|
+| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS | Azure |
+|--------------------------------------------------------------|-------|---------------------------------|---------------|-----------------------|----------------|
| GitLab Rails ([1](#footnotes)) | 3 | 8 vCPU, 7.2GB Memory | n1-highcpu-8 | c5.2xlarge | F8s v2 |
| PostgreSQL | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | D2s v3 |
| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
@@ -77,6 +77,3 @@ following the [2,000-user reference architecture](2k_users.md).
or higher, are required for your CPU or Node counts accordingly. For more information, a
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
diff --git a/doc/administration/reference_architectures/50k_users.md b/doc/administration/reference_architectures/50k_users.md
index 47c5b3e2bce..08411e21604 100644
--- a/doc/administration/reference_architectures/50k_users.md
+++ b/doc/administration/reference_architectures/50k_users.md
@@ -8,8 +8,8 @@ For a full list of reference architectures, see
> - **High Availability:** True
> - **Test RPS rates:** API: 1000 RPS, Web: 100 RPS, Git: 100 RPS
-| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS ([9](#footnotes)) | Azure([9](#footnotes)) |
-|--------------------------------------------------------------|-------|---------------------------------|----------------|-----------------------|------------------------|
+| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS | Azure |
+|--------------------------------------------------------------|-------|---------------------------------|----------------|-----------------------|----------------|
| GitLab Rails ([1](#footnotes)) | 12 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 | c5.9xlarge | F32s v2 |
| PostgreSQL | 3 | 16 vCPU, 60GB Memory | n1-standard-16 | m5.4xlarge | D16s v3 |
| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
@@ -74,6 +74,3 @@ For a full list of reference architectures, see
or higher, are required for your CPU or Node counts accordingly. For more information, a
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
diff --git a/doc/administration/reference_architectures/5k_users.md b/doc/administration/reference_architectures/5k_users.md
index 34443f08c88..0997d7dfb52 100644
--- a/doc/administration/reference_architectures/5k_users.md
+++ b/doc/administration/reference_architectures/5k_users.md
@@ -8,8 +8,8 @@ For a full list of reference architectures, see
> - **High Availability:** True
> - **Test RPS rates:** API: 100 RPS, Web: 10 RPS, Git: 10 RPS
-| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS ([9](#footnotes)) | Azure([9](#footnotes)) |
-|--------------------------------------------------------------|-------|---------------------------------|---------------|-----------------------|------------------------|
+| Service | Nodes | Configuration ([8](#footnotes)) | GCP | AWS | Azure |
+|--------------------------------------------------------------|-------|---------------------------------|---------------|-----------------------|----------------|
| GitLab Rails ([1](#footnotes)) | 3 | 16 vCPU, 14.4GB Memory | n1-highcpu-16 | c5.4xlarge | F16s v2 |
| PostgreSQL | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | D2s v3 |
| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | F2s v2 |
@@ -71,6 +71,3 @@ For a full list of reference architectures, see
or higher, are required for your CPU or Node counts accordingly. For more information, a
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
diff --git a/doc/administration/reference_architectures/index.md b/doc/administration/reference_architectures/index.md
index 5a614d476ce..ff2f7b1ef90 100644
--- a/doc/administration/reference_architectures/index.md
+++ b/doc/administration/reference_architectures/index.md
@@ -163,7 +163,7 @@ column.
| Repmgr | PostgreSQL cluster management and failover | [PostgreSQL and Repmgr configuration](../high_availability/database.md) | Yes |
| [Redis](../../development/architecture.md#redis) ([3](#footnotes)) | Key/value store for fast data lookup and caching | [Redis configuration](../high_availability/redis.md) | Yes |
| Redis Sentinel | Redis | [Redis Sentinel configuration](../high_availability/redis.md) | Yes |
-| [Gitaly](../../development/architecture.md#gitaly) ([2](#footnotes)) ([7](#footnotes)) ([10](#footnotes)) | Provides access to Git repositories | [Gitaly configuration](../gitaly/index.md#running-gitaly-on-its-own-server) | Yes |
+| [Gitaly](../../development/architecture.md#gitaly) ([2](#footnotes)) ([7](#footnotes)) ([9](#footnotes)) | Provides access to Git repositories | [Gitaly configuration](../gitaly/index.md#running-gitaly-on-its-own-server) | Yes |
| [Sidekiq](../../development/architecture.md#sidekiq) | Asynchronous/background jobs | [Sidekiq configuration](../high_availability/sidekiq.md) | Yes |
| [GitLab application services](../../development/architecture.md#unicorn)([1](#footnotes)) | Puma/Unicorn, Workhorse, GitLab Shell - serves front-end requests (UI, API, Git over HTTP/SSH) | [GitLab app scaling configuration](../high_availability/gitlab.md) | Yes |
| [Prometheus](../../development/architecture.md#prometheus) and [Grafana](../../development/architecture.md#grafana) | GitLab environment monitoring | [Monitoring node for scaling](../high_availability/monitoring_node.md) | Yes |
@@ -217,9 +217,6 @@ column.
[Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found
[here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks).
-1. AWS-equivalent and Azure-equivalent configurations are rough suggestions
- and may change in the future. They have not yet been tested and validated.
-
1. From GitLab 13.0, using NFS for Git repositories is deprecated. In GitLab
14.0, support for NFS for Git repositories is scheduled to be removed.
Upgrade to [Gitaly Cluster](../gitaly/praefect.md) as soon as possible.
diff --git a/doc/api/releases/index.md b/doc/api/releases/index.md
index 6939c95144d..f7c566d8060 100644
--- a/doc/api/releases/index.md
+++ b/doc/api/releases/index.md
@@ -121,13 +121,15 @@ Example response:
"id":2,
"name":"awesome-v0.2.msi",
"url":"http://192.168.10.15:3000/msi",
- "external":true
+ "external":true,
+ "link_type":"other"
},
{
"id":1,
"name":"awesome-v0.2.dmg",
"url":"http://192.168.10.15:3000",
- "external":true
+ "external":true,
+ "link_type":"other"
}
],
"evidence_file_path":"https://gitlab.example.com/root/awesome-app/-/releases/v0.2/evidence.json"
@@ -323,7 +325,8 @@ Example response:
"id":3,
"name":"hoge",
"url":"https://gitlab.example.com/root/awesome-app/-/tags/v0.11.1/binaries/linux-amd64",
- "external":true
+ "external":true,
+ "link_type":"other"
}
]
},
@@ -357,13 +360,14 @@ POST /projects/:id/releases
| `assets:links:name`| string | required by: `assets:links` | The name of the link. |
| `assets:links:url` | string | required by: `assets:links` | The URL of the link. |
| `assets:links:filepath` | string | no | Optional path for a [Direct Asset link](../../user/project/releases.md).
+| `assets:links:link_type` | string | no | The type of the link: `other`, `runbook`, `image`, `package`. Defaults to `other`.
| `released_at` | datetime | no | The date when the release will be/was ready. Defaults to the current time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). |
Example request:
```shell
curl --header 'Content-Type: application/json' --header "PRIVATE-TOKEN: gDybLx3yrUK_HLp3qPjS" \
- --data '{ "name": "New release", "tag_name": "v0.3", "description": "Super nice release", "milestones": ["v1.0", "v1.0-rc"], "assets": { "links": [{ "name": "hoge", "url": "https://google.com", "filepath": "/binaries/linux-amd64" }] } }' \
+ --data '{ "name": "New release", "tag_name": "v0.3", "description": "Super nice release", "milestones": ["v1.0", "v1.0-rc"], "assets": { "links": [{ "name": "hoge", "url": "https://google.com", "filepath": "/binaries/linux-amd64", "link_type":"other" }] } }' \
--request POST https://gitlab.example.com/api/v4/projects/24/releases
```
@@ -465,7 +469,8 @@ Example response:
"id":3,
"name":"hoge",
"url":"https://gitlab.example.com/root/awesome-app/-/tags/v0.11.1/binaries/linux-amd64",
- "external":true
+ "external":true,
+ "link_type":"other"
}
],
"evidence_file_path":"https://gitlab.example.com/root/awesome-app/-/releases/v0.3/evidence.json"
diff --git a/doc/api/releases/links.md b/doc/api/releases/links.md
index 7c13ac59e50..9b2c0d611ac 100644
--- a/doc/api/releases/links.md
+++ b/doc/api/releases/links.md
@@ -32,13 +32,15 @@ Example response:
"id":2,
"name":"awesome-v0.2.msi",
"url":"http://192.168.10.15:3000/msi",
- "external":true
+ "external":true,
+ "link_type":"other"
},
{
"id":1,
"name":"awesome-v0.2.dmg",
"url":"http://192.168.10.15:3000",
- "external":true
+ "external":true,
+ "link_type":"other"
}
]
```
@@ -70,7 +72,8 @@ Example response:
"id":1,
"name":"awesome-v0.2.dmg",
"url":"http://192.168.10.15:3000",
- "external":true
+ "external":true,
+ "link_type":"other"
}
```
@@ -87,7 +90,8 @@ POST /projects/:id/releases/:tag_name/assets/links
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../README.md#namespaced-path-encoding). |
| `tag_name` | string | yes | The tag associated with the Release. |
| `name` | string | yes | The name of the link. |
-| `url` | string | yes | The URL of the link. |
+| `url` | string | yes | The URL of the link. |
+| `link_type` | string | no | The type of the link: `other`, `runbook`, `image`, `package`. Defaults to `other`. |
Example request:
@@ -106,7 +110,8 @@ Example response:
"id":1,
"name":"awesome-v0.2.dmg",
"url":"http://192.168.10.15:3000",
- "external":true
+ "external":true,
+ "link_type":"other"
}
```
@@ -122,9 +127,10 @@ PUT /projects/:id/releases/:tag_name/assets/links/:link_id
| ------------- | -------------- | -------- | --------------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../README.md#namespaced-path-encoding). |
| `tag_name` | string | yes | The tag associated with the Release. |
-| `link_id` | integer | yes | The ID of the link. |
+| `link_id` | integer | yes | The ID of the link. |
| `name` | string | no | The name of the link. |
-| `url` | string | no | The URL of the link. |
+| `url` | string | no | The URL of the link. |
+| `link_type` | string | no | The type of the link: `other`, `runbook`, `image`, `package`. Defaults to `other`. |
NOTE: **NOTE**
You have to specify at least one of `name` or `url`
@@ -132,7 +138,7 @@ You have to specify at least one of `name` or `url`
Example request:
```shell
-curl --request PUT --data name="new name" --header "PRIVATE-TOKEN: n671WNGecHugsdEDPsyo" "https://gitlab.example.com/api/v4/projects/24/releases/v0.1/assets/links/1"
+curl --request PUT --data name="new name" --data link_type="runbook" --header "PRIVATE-TOKEN: n671WNGecHugsdEDPsyo" "https://gitlab.example.com/api/v4/projects/24/releases/v0.1/assets/links/1"
```
Example response:
@@ -142,7 +148,8 @@ Example response:
"id":1,
"name":"new name",
"url":"http://192.168.10.15:3000",
- "external":true
+ "external":true,
+ "link_type":"runbook"
}
```
@@ -173,6 +180,7 @@ Example response:
"id":1,
"name":"new name",
"url":"http://192.168.10.15:3000",
- "external":true
+ "external":true,
+ "link_type":"other"
}
```
diff --git a/doc/development/README.md b/doc/development/README.md
index 458f5cc2350..d330d6d466e 100644
--- a/doc/development/README.md
+++ b/doc/development/README.md
@@ -63,7 +63,7 @@ Complementary reads:
- [Working with Gitaly](gitaly.md)
- [Manage feature flags](feature_flags/index.md)
- [Licensed feature availability](licensed_feature_availability.md)
-- [View sent emails or preview mailers](emails.md)
+- [Dealing with email/mailers](emails.md)
- [Shell commands](shell_commands.md) in the GitLab codebase
- [`Gemfile` guidelines](gemfile.md)
- [Pry debugging](pry_debugging.md)
diff --git a/doc/development/documentation/styleguide.md b/doc/development/documentation/styleguide.md
index 336bb92faf7..6f9a84cfbd4 100644
--- a/doc/development/documentation/styleguide.md
+++ b/doc/development/documentation/styleguide.md
@@ -1368,7 +1368,35 @@ versions back, you can consider removing the text if it's irrelevant or confusin
For example, if the current major version is 12.x, version text referencing versions of GitLab 8.x
and older are candidates for removal if necessary for clearer or cleaner docs.
-## Product badges
+## Products and features
+
+Refer to the information in this section when describing products and features
+within the GitLab product documentation.
+
+### Avoid line breaks in names
+
+When entering a product or feature name that includes a space (such as
+GitLab Community Edition) or even other companies' products (such as
+Amazon Web Services), be sure to not split the product or feature name across
+lines with an inserted line break. Splitting product or feature names across
+lines makes searching for these items more difficult, and can cause problems if
+names change.
+
+For example, the followng Markdown content is *not* formatted correctly:
+
+```markdown
+When entering a product or feature name that includes a space (such as GitLab
+Community Edition), don't split the product or feature name across lines.
+```
+
+Instead, it should appear similar to the following:
+
+```markdown
+When entering a product or feature name that includes a space (such as
+GitLab Community Edition), don't split the product or feature name across lines.
+```
+
+### Product badges
When a feature is available in EE-only tiers, add the corresponding tier according to the
feature availability:
@@ -1408,7 +1436,7 @@ For example:
The absence of tiers' mentions mean that the feature is available in GitLab Core,
GitLab.com Free, and all higher tiers.
-### How it works
+#### How it works
Introduced by [!244](https://gitlab.com/gitlab-org/gitlab-docs/-/merge_requests/244),
the special markup `**(STARTER)**` will generate a `span` element to trigger the
diff --git a/doc/development/emails.md b/doc/development/emails.md
index e6e2ea8aae7..2477a51f78f 100644
--- a/doc/development/emails.md
+++ b/doc/development/emails.md
@@ -1,5 +1,20 @@
# Dealing with email in development
+## Ensuring compatibility with mailer Sidekiq jobs
+
+A Sidekiq job is enqueued whenever `deliver_later` is called on an `ActionMailer`.
+If a mailer argument needs to be added or removed, it is important to ensure
+both backward and forward compatibility. Adhere to the Sidekiq Style Guide steps for
+[changing the arguments for a worker](sidekiq_style_guide.md#changing-the-arguments-for-a-worker).
+
+In the following example from [`NotificationService`](https://gitlab.com/gitlab-org/gitlab/-/blob/33ccb22e4fc271dbaac94b003a7a1a2915a13441/app/services/notification_service.rb#L74)
+adding or removing an argument in this mailer's definition may cause problems
+during deployment before all Rails and Sidekiq nodes have the updated code.
+
+```ruby
+mailer.unknown_sign_in_email(user, ip, time).deliver_later
+```
+
## Sent emails
To view rendered emails "sent" in your development instance, visit
diff --git a/doc/development/sidekiq_style_guide.md b/doc/development/sidekiq_style_guide.md
index 056e0b45624..a94560be78c 100644
--- a/doc/development/sidekiq_style_guide.md
+++ b/doc/development/sidekiq_style_guide.md
@@ -537,18 +537,74 @@ possible situations:
### Changing the arguments for a worker
-Jobs need to be backwards- and forwards-compatible between consecutive versions
-of the application.
-
-This can be done by following this process:
-
-1. **Do not remove arguments from the `perform` function.**. Instead, use the
- following approach
- 1. Provide a default value (usually `nil`) and use a comment to mark the
- argument as deprecated
- 1. Stop using the argument in `perform_async`.
- 1. Ignore the value in the worker class, but do not remove it until the next
- major release.
+Jobs need to be backward and forward compatible between consecutive versions
+of the application. Adding or removing an argument may cause problems
+during deployment before all Rails and Sidekiq nodes have the updated code.
+
+#### Remove an argument
+
+**Do not remove arguments from the `perform` function.**. Instead, use the
+following approach:
+
+1. Provide a default value (usually `nil`) and use a comment to mark the
+ argument as deprecated
+1. Stop using the argument in `perform_async`.
+1. Ignore the value in the worker class, but do not remove it until the next
+ major release.
+
+In the following example, if you want to remove `arg2`, first set a `nil` default value,
+and then update locations where `ExampleWorker.perform_async` is called.
+
+```ruby
+class ExampleWorker
+ def perform(object_id, arg1, arg2 = nil)
+ # ...
+ end
+end
+```
+
+#### Add an argument
+
+There are two options for safely adding new arguments to Sidekiq workers:
+
+1. Set up a [multi-step deployment](#multi-step-deployment) in which the new argument is first added to the worker
+1. Use a [parameter hash](#parameter-hash) for additional arguments. This is perhaps the most flexible option.
+1. Use a parameter hash for additional arguments. This is perhaps the most flexible option.
+
+##### Multi-step deployment
+
+This approach requires multiple merge requests and for the first merge request
+to be merged and deployed before additional changes are merged.
+
+1. In an initial merge request, add the argument to the worker with a default
+ value:
+
+ ```ruby
+ class ExampleWorker
+ def perform(object_id, new_arg = nil)
+ # ...
+ end
+ end
+ ```
+
+1. Merge and deploy the worker with the new argument.
+1. In a further merge request, update `ExampleWorker.perform_async` calls to
+ use the new argument.
+
+##### Parameter hash
+
+This approach will not require multiple deployments if an existing worker already
+utilizes a parameter hash.
+
+1. Use a parameter hash in the worker to allow for future flexibility:
+
+ ```ruby
+ class ExampleWorker
+ def perform(object_id, params = {})
+ # ...
+ end
+ end
+ ```
### Removing workers
diff --git a/doc/user/incident_management/index.md b/doc/user/incident_management/index.md
index 6c50a32f0d6..48805bda909 100644
--- a/doc/user/incident_management/index.md
+++ b/doc/user/incident_management/index.md
@@ -7,47 +7,49 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Incident Management
GitLab offers solutions for handling incidents in your applications and services,
-from setting up an alert with Prometheus, to receiving a notification through a
-monitoring tool like Slack, and [setting up Zoom calls](#zoom-integration-in-issues) with your
-support team. Incidents can display [metrics](#embed-metrics-in-incidents-and-issues)
-and [logs](#view-logs-from-metrics-panel).
+such as setting up Prometheus alerts, displaying metrics, and sending notifications.
## Configure incidents **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/4925) in GitLab Ultimate 11.11.
-You can enable or disable Incident Management features in your project's
-**{settings}** **Settings > Operations > Incidents**. Issues can be created for
-each alert triggered, and separate email notifications can be sent to users with
-[Developer permissions](../permissions.md). Appropriately configured alerts include an
-[embedded chart](../project/integrations/prometheus.md#embedding-metrics-based-on-alerts-in-incident-issues)
-for the query corresponding to the alert. You can also configure GitLab to
-[close issues](../project/integrations/prometheus.md#taking-action-on-incidents-ultimate)
-when you receive notification that the alert is resolved.
-
-![Incident Management Settings](img/incident_management_settings.png)
+You can enable or disable Incident Management features in the GitLab user interface
+to create issues when alerts are triggered:
-### Create issues from alerts
+1. Navigate to **{settings}** **Settings > Operations > Incidents** and expand
+ **Incidents**:
-You can create GitLab issues from an alert notification. These issues contain
-information about the alerts to help you diagnose the source of the alerts.
+ ![Incident Management Settings](img/incident_management_settings.png)
-1. Visit your project's **{settings}** **Settings > Operations > Incidents**.
-1. Select the **Create an issue** checkbox for GitLab to create an issue from
- the incident.
-1. Select the template from the **Issue Template** dropdown.
- You can create your own [issue templates](../project/description_templates.md#creating-issue-templates)
- to [use within Incident Management](../project/integrations/prometheus.md#taking-action-on-incidents-ultimate).
+1. For GitLab versions 11.11 and greater, you can select the **Create an issue**
+ checkbox to create an issue based on your own
+ [issue templates](../project/description_templates.md#creating-issue-templates).
+ For more information, see
+ [Taking Action on Incidents](../project/integrations/prometheus.md#taking-action-on-incidents-ultimate) **(ULTIMATE)**.
+1. To create issues from alerts, select the template in the **Issue Template**
+ select box.
+1. To send [separate email notifications](#notify-developers-of-alerts) to users
+ with [Developer permissions](../permissions.md), select
+ **Send a separate email notification to Developers**.
1. Click **Save changes**.
-## Notify developers of alerts
+Appropriately configured alerts include an
+[embedded chart](../project/integrations/prometheus.md#embedding-metrics-based-on-alerts-in-incident-issues)
+for the query corresponding to the alert. You can also configure GitLab to
+[close issues](../project/integrations/prometheus.md#taking-action-on-incidents-ultimate)
+when you receive notification that the alert is resolved.
+
+### Notify developers of alerts
GitLab can react to the alerts triggered from your applications and services
-by creating issues and alerting developers through email. GitLab sends these emails
-to [owners and maintainers](../permissions.md) of the project. They contain details
-of the alert, and a link for more information.
+by creating issues and alerting developers through email. By default, GitLab
+sends these emails to [owners and maintainers](../permissions.md) of the project.
+These emails contain details of the alert, and a link for more information.
+
+To send separate email notifications to users with
+[Developer permissions](../permissions.md), see [Configure incidents](#configure-incidents-ultimate).
-### Configure Prometheus alerts
+## Configure Prometheus alerts
You can set up Prometheus alerts in:
@@ -57,7 +59,7 @@ You can set up Prometheus alerts in:
Prometheus alerts are created by the special Alert Bot user. You can't remove this
user, but it does not count toward your license limit.
-### Configure external generic alerts
+## Configure external generic alerts
GitLab can accept alerts from any source through a generic webhook receiver. When
[configuring the generic alerts integration](../project/integrations/generic_alerts.md),
@@ -65,7 +67,7 @@ GitLab creates a unique endpoint which receives a JSON-formatted, customizable p
## Embed metrics in incidents and issues
-You can embed metrics anywhere GitLab Markdown is used, such as descriptions,
+You can embed metrics anywhere [GitLab Markdown](../markdown.md) is used, such as descriptions,
comments on issues, and merge requests. Embedding metrics helps you share them
when discussing incidents or performance issues. You can output the dashboard directly
into any issue, merge request, epic, or any other Markdown text field in GitLab
@@ -78,10 +80,9 @@ in incidents and issue templates.
### Context menu
-From each of the embedded metrics panels, you can access more details
-about the data you're viewing from a context menu. You can access the context menu
-by clicking the **{ellipsis_v}** **More actions** dropdown box above the
-upper right corner of the panel. The options are:
+You can view more details about an embedded metrics panel from the context menu.
+To access the context menu, click the **{ellipsis_v}** **More actions** dropdown box
+above the upper right corner of the panel. The options are:
- [View logs](#view-logs-from-metrics-panel).
- **Download CSV** - Data from embedded charts can be
@@ -97,16 +98,16 @@ incident and need to [explore logs](../project/integrations/prometheus.md#view-l
from across your application. These logs help you understand what is affecting
your application's performance and resolve any problems.
-## Slack integration
+## Integrate incidents with Slack
Slack slash commands allow you to control GitLab and view GitLab content without leaving Slack.
Learn how to [set up Slack slash commands](../project/integrations/slack_slash_commands.md)
and how to [use the available slash commands](../../integration/slash_commands.md).
-## Zoom integration in issues
+## Integrate issues with Zoom
GitLab enables you to [associate a Zoom meeting with an issue](../project/issues/associate_zoom_meeting.md)
for synchronous communication during incident management. After starting a Zoom
-call for an incident, you can associate the conference call with an issue, so your
-team members can join without requesting a link.
+call for an incident, you can associate the conference call with an issue. Your
+team members can join the Zoom call without requesting a link.
diff --git a/doc/user/project/issues/design_management.md b/doc/user/project/issues/design_management.md
index ac887e7d988..58efb1acc27 100644
--- a/doc/user/project/issues/design_management.md
+++ b/doc/user/project/issues/design_management.md
@@ -177,6 +177,22 @@ Different discussions have different pin numbers:
From GitLab 12.5 on, new discussions will be outputted to the issue activity,
so that everyone involved can participate in the discussion.
+## Resolve Design threads
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13049) in GitLab 13.1.
+
+Discussion threads can be resolved on Designs. You can mark a thread as resolved
+or unresolved by clicking the **Resolve thread** icon at the first comment of the
+discussion.
+
+![Resolve thread icon](img/resolve_design-discussion_icon_v13_1.png)
+
+Pinned comments can also be resolved or unresolved in their threads.
+When replying to a comment, you will see a checkbox that you can click in order to resolve or unresolve
+the thread once published.
+
+![Resolve checkbox](img/resolve_design-discussion_checkbox_v13_1.png)
+
## Referring to designs in Markdown
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217160) in **GitLab 13.1**.
diff --git a/doc/user/project/issues/img/resolve_design-discussion_checkbox_v13_1.png b/doc/user/project/issues/img/resolve_design-discussion_checkbox_v13_1.png
new file mode 100644
index 00000000000..bd9d1f7a77c
--- /dev/null
+++ b/doc/user/project/issues/img/resolve_design-discussion_checkbox_v13_1.png
Binary files differ
diff --git a/doc/user/project/issues/img/resolve_design-discussion_icon_v13_1.png b/doc/user/project/issues/img/resolve_design-discussion_icon_v13_1.png
new file mode 100644
index 00000000000..5cd005f0799
--- /dev/null
+++ b/doc/user/project/issues/img/resolve_design-discussion_icon_v13_1.png
Binary files differ
diff --git a/doc/user/project/service_desk.md b/doc/user/project/service_desk.md
index 35a61f413e8..fbecaf9ef72 100644
--- a/doc/user/project/service_desk.md
+++ b/doc/user/project/service_desk.md
@@ -68,7 +68,8 @@ If you have the correct access and a Premium license, you have the option to set
Follow these steps to do so:
1. [Set up incoming email](../../administration/incoming_email.md#set-it-up) for the GitLab instance.
- This must support [email sub-addressing](../../administration/incoming_email.md#email-sub-addressing).
+ - We recommend using [email sub-addressing](../../administration/incoming_email.md#email-sub-addressing),
+ but in GitLab 11.7 and later you can also use [catch-all mailboxes](../../administration/incoming_email.md#catch-all-mailbox).
1. Navigate to your project's **Settings > General** and locate the **Service Desk** section.
1. Enable the **Activate Service Desk** toggle. This reveals a unique email address to email issues
to the project. These issues will be [confidential](issues/confidential_issues.md), so they will
diff --git a/lib/banzai/filter/external_issue_reference_filter.rb b/lib/banzai/filter/external_issue_reference_filter.rb
index a4f1f2f11f9..74bc102320c 100644
--- a/lib/banzai/filter/external_issue_reference_filter.rb
+++ b/lib/banzai/filter/external_issue_reference_filter.rb
@@ -66,7 +66,7 @@ module Banzai
# links have `gfm` and `gfm-issue` class names attached for styling.
def issue_link_filter(text, link_content: nil)
self.class.references_in(text, issue_reference_pattern) do |match, id|
- url = url_for_issue(id, project, only_path: context[:only_path])
+ url = url_for_issue(id)
klass = reference_class(:issue)
data = data_attribute(project: project.id, external_issue: id)
content = link_content || match
@@ -77,8 +77,19 @@ module Banzai
end
end
- def url_for_issue(*args)
- IssuesHelper.url_for_issue(*args)
+ def url_for_issue(issue_id)
+ return '' if project.nil?
+
+ url = if only_path?
+ project.external_issue_tracker.issue_path(issue_id)
+ else
+ project.external_issue_tracker.issue_url(issue_id)
+ end
+
+ # Ensure we return a valid URL to prevent possible XSS.
+ URI.parse(url).to_s
+ rescue URI::InvalidURIError
+ ''
end
def default_issues_tracker?
diff --git a/lib/banzai/filter/issue_reference_filter.rb b/lib/banzai/filter/issue_reference_filter.rb
index 1a1030c2a1c..dc4b865bfb6 100644
--- a/lib/banzai/filter/issue_reference_filter.rb
+++ b/lib/banzai/filter/issue_reference_filter.rb
@@ -18,7 +18,9 @@ module Banzai
end
def url_for_object(issue, project)
- IssuesHelper.url_for_issue(issue.iid, project, only_path: context[:only_path], internal: true)
+ return issue_path(issue, project) if only_path?
+
+ issue_url(issue, project)
end
def projects_relation_for_paths(paths)
@@ -35,6 +37,14 @@ module Banzai
private
+ def issue_path(issue, project)
+ Gitlab::Routing.url_helpers.namespace_project_issue_path(namespace_id: project.namespace, project_id: project, id: issue.iid)
+ end
+
+ def issue_url(issue, project)
+ Gitlab::Routing.url_helpers.namespace_project_issue_url(namespace_id: project.namespace, project_id: project, id: issue.iid)
+ end
+
def design_link_extras(issue, path)
if path == '/designs' && read_designs?(issue)
['designs']
diff --git a/lib/banzai/filter/reference_filter.rb b/lib/banzai/filter/reference_filter.rb
index 38bbed3cf72..9e932ccf9f8 100644
--- a/lib/banzai/filter/reference_filter.rb
+++ b/lib/banzai/filter/reference_filter.rb
@@ -142,6 +142,12 @@ module Banzai
def element_node?(node)
node.is_a?(Nokogiri::XML::Element)
end
+
+ private
+
+ def only_path?
+ context[:only_path]
+ end
end
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 0e070272c33..db0751e3b6b 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -4451,9 +4451,6 @@ msgstr ""
msgid "Click the button below to begin the install process by navigating to the Kubernetes page"
msgstr ""
-msgid "Click the image where you'd like to start a new discussion"
-msgstr ""
-
msgid "Click to expand it."
msgstr ""
@@ -5528,6 +5525,9 @@ msgstr ""
msgid "Collapse child epics"
msgstr ""
+msgid "Collapse replies"
+msgstr ""
+
msgid "Collapse sidebar"
msgstr ""
@@ -7519,9 +7519,15 @@ msgstr ""
msgid "DesignManagement|Cancel comment update confirmation"
msgstr ""
+msgid "DesignManagement|Click the image where you'd like to start a new discussion"
+msgstr ""
+
msgid "DesignManagement|Comment"
msgstr ""
+msgid "DesignManagement|Comments you resolve can be viewed and unresolved by going to the \"Resolved Comments\" section below"
+msgstr ""
+
msgid "DesignManagement|Could not add a new comment. Please try again."
msgstr ""
@@ -7567,9 +7573,18 @@ msgstr ""
msgid "DesignManagement|Keep comment"
msgstr ""
+msgid "DesignManagement|Learn more about resolving comments"
+msgstr ""
+
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr ""
+msgid "DesignManagement|Resolve thread"
+msgstr ""
+
+msgid "DesignManagement|Resolved Comments"
+msgstr ""
+
msgid "DesignManagement|Save comment"
msgstr ""
@@ -7582,6 +7597,9 @@ msgstr ""
msgid "DesignManagement|To enable design management, you'll need to %{requirements_link_start}meet the requirements%{requirements_link_end}. If you need help, reach out to our %{support_link_start}support team%{support_link_end} for assistance."
msgstr ""
+msgid "DesignManagement|Unresolve thread"
+msgstr ""
+
msgid "DesignManagement|Upload designs"
msgstr ""
@@ -18657,6 +18675,9 @@ msgstr ""
msgid "Resolved all discussions."
msgstr ""
+msgid "Resolved by"
+msgstr ""
+
msgid "Resolved by %{name}"
msgstr ""
@@ -19423,6 +19444,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|The rating \"unknown\" indicates that the underlying scanner doesn’t contain or provide a severity rating."
+msgstr ""
+
msgid "SecurityReports|The security dashboard displays the latest security findings for projects you wish to monitor. Select \"Edit dashboard\" to add and remove projects."
msgstr ""
diff --git a/qa/qa/resource/project_milestone.rb b/qa/qa/resource/project_milestone.rb
index 4d6b37937b4..385b9f0c96b 100644
--- a/qa/qa/resource/project_milestone.rb
+++ b/qa/qa/resource/project_milestone.rb
@@ -3,6 +3,8 @@
module QA
module Resource
class ProjectMilestone < Base
+ attr_writer :start_date, :due_date
+
attribute :id
attribute :title
@@ -27,7 +29,10 @@ module QA
def api_post_body
{
title: title
- }
+ }.tap do |hash|
+ hash[:start_date] = @start_date if @start_date
+ hash[:due_date] = @due_date if @due_date
+ end
end
end
end
diff --git a/spec/controllers/instance_statistics/dev_ops_score_controller_spec.rb b/spec/controllers/instance_statistics/dev_ops_score_controller_spec.rb
index 5825c6295f6..d729682bef0 100644
--- a/spec/controllers/instance_statistics/dev_ops_score_controller_spec.rb
+++ b/spec/controllers/instance_statistics/dev_ops_score_controller_spec.rb
@@ -2,6 +2,6 @@
require 'spec_helper'
-describe InstanceStatistics::DevOpsScoreController do
+RSpec.describe InstanceStatistics::DevOpsScoreController do
it_behaves_like 'instance statistics availability'
end
diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb
index 9daaa258aa2..f2821bb67e8 100644
--- a/spec/controllers/invites_controller_spec.rb
+++ b/spec/controllers/invites_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe InvitesController do
+RSpec.describe InvitesController do
let(:token) { '123456' }
let(:user) { create(:user) }
let(:member) { create(:project_member, invite_token: token, invite_email: 'test@abc.com', user: user) }
diff --git a/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb b/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb
index 0242a91ac60..2de824bbf3c 100644
--- a/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb
+++ b/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Ldap::OmniauthCallbacksController do
+RSpec.describe Ldap::OmniauthCallbacksController do
include_context 'Ldap::OmniauthCallbacksController'
it 'allows sign in' do
diff --git a/spec/controllers/metrics_controller_spec.rb b/spec/controllers/metrics_controller_spec.rb
index 75509cc509f..f350d7378dc 100644
--- a/spec/controllers/metrics_controller_spec.rb
+++ b/spec/controllers/metrics_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe MetricsController, :request_store do
+RSpec.describe MetricsController, :request_store do
include StubENV
let(:metrics_multiproc_dir) { @metrics_multiproc_dir }
diff --git a/spec/controllers/notification_settings_controller_spec.rb b/spec/controllers/notification_settings_controller_spec.rb
index f3b608aee0c..c4d67df15f7 100644
--- a/spec/controllers/notification_settings_controller_spec.rb
+++ b/spec/controllers/notification_settings_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe NotificationSettingsController do
+RSpec.describe NotificationSettingsController do
let(:project) { create(:project) }
let(:group) { create(:group, :internal) }
let(:user) { create(:user) }
diff --git a/spec/controllers/oauth/applications_controller_spec.rb b/spec/controllers/oauth/applications_controller_spec.rb
index 09f8ad4332d..f20204b6718 100644
--- a/spec/controllers/oauth/applications_controller_spec.rb
+++ b/spec/controllers/oauth/applications_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Oauth::ApplicationsController do
+RSpec.describe Oauth::ApplicationsController do
let(:user) { create(:user) }
let(:application) { create(:oauth_application, owner: user) }
diff --git a/spec/controllers/oauth/authorizations_controller_spec.rb b/spec/controllers/oauth/authorizations_controller_spec.rb
index f975502ca4e..89b74675d28 100644
--- a/spec/controllers/oauth/authorizations_controller_spec.rb
+++ b/spec/controllers/oauth/authorizations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Oauth::AuthorizationsController do
+RSpec.describe Oauth::AuthorizationsController do
let!(:application) { create(:oauth_application, scopes: 'api read_user', redirect_uri: 'http://example.com') }
let(:params) do
{
diff --git a/spec/controllers/oauth/authorized_applications_controller_spec.rb b/spec/controllers/oauth/authorized_applications_controller_spec.rb
index 32be6a3ddb7..15b2969a859 100644
--- a/spec/controllers/oauth/authorized_applications_controller_spec.rb
+++ b/spec/controllers/oauth/authorized_applications_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Oauth::AuthorizedApplicationsController do
+RSpec.describe Oauth::AuthorizedApplicationsController do
let(:user) { create(:user) }
let(:guest) { create(:user) }
let(:application) { create(:oauth_application, owner: guest) }
diff --git a/spec/controllers/omniauth_callbacks_controller_spec.rb b/spec/controllers/omniauth_callbacks_controller_spec.rb
index 302c11ec0c0..0b99f28f79b 100644
--- a/spec/controllers/omniauth_callbacks_controller_spec.rb
+++ b/spec/controllers/omniauth_callbacks_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe OmniauthCallbacksController, type: :controller do
+RSpec.describe OmniauthCallbacksController, type: :controller do
include LoginHelpers
describe 'omniauth' do
diff --git a/spec/controllers/passwords_controller_spec.rb b/spec/controllers/passwords_controller_spec.rb
index 3ec8e347659..ba2c0c0455d 100644
--- a/spec/controllers/passwords_controller_spec.rb
+++ b/spec/controllers/passwords_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe PasswordsController do
+RSpec.describe PasswordsController do
describe '#check_password_authentication_available' do
before do
@request.env["devise.mapping"] = Devise.mappings[:user]
diff --git a/spec/controllers/profiles/accounts_controller_spec.rb b/spec/controllers/profiles/accounts_controller_spec.rb
index 518ea4e5c48..52a7a1609a1 100644
--- a/spec/controllers/profiles/accounts_controller_spec.rb
+++ b/spec/controllers/profiles/accounts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::AccountsController do
+RSpec.describe Profiles::AccountsController do
describe 'DELETE unlink' do
let(:user) { create(:omniauth_user) }
diff --git a/spec/controllers/profiles/avatars_controller_spec.rb b/spec/controllers/profiles/avatars_controller_spec.rb
index 1a64cb72265..d120d9ce559 100644
--- a/spec/controllers/profiles/avatars_controller_spec.rb
+++ b/spec/controllers/profiles/avatars_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::AvatarsController do
+RSpec.describe Profiles::AvatarsController do
let(:user) { create(:user, avatar: fixture_file_upload("spec/fixtures/dk.png")) }
before do
diff --git a/spec/controllers/profiles/emails_controller_spec.rb b/spec/controllers/profiles/emails_controller_spec.rb
index ffec43fea2c..246f8a6cd76 100644
--- a/spec/controllers/profiles/emails_controller_spec.rb
+++ b/spec/controllers/profiles/emails_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::EmailsController do
+RSpec.describe Profiles::EmailsController do
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/profiles/keys_controller_spec.rb b/spec/controllers/profiles/keys_controller_spec.rb
index 8582ecbb06d..258ed62262a 100644
--- a/spec/controllers/profiles/keys_controller_spec.rb
+++ b/spec/controllers/profiles/keys_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::KeysController do
+RSpec.describe Profiles::KeysController do
let(:user) { create(:user) }
describe 'POST #create' do
diff --git a/spec/controllers/profiles/notifications_controller_spec.rb b/spec/controllers/profiles/notifications_controller_spec.rb
index 343f29ef687..40b4c8f0371 100644
--- a/spec/controllers/profiles/notifications_controller_spec.rb
+++ b/spec/controllers/profiles/notifications_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::NotificationsController do
+RSpec.describe Profiles::NotificationsController do
let(:user) do
create(:user) do |user|
user.emails.create(email: 'original@example.com', confirmed_at: Time.current)
diff --git a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb
index b467ecc4af9..1fdd1200028 100644
--- a/spec/controllers/profiles/personal_access_tokens_controller_spec.rb
+++ b/spec/controllers/profiles/personal_access_tokens_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::PersonalAccessTokensController do
+RSpec.describe Profiles::PersonalAccessTokensController do
let(:user) { create(:user) }
let(:token_attributes) { attributes_for(:personal_access_token) }
diff --git a/spec/controllers/profiles/preferences_controller_spec.rb b/spec/controllers/profiles/preferences_controller_spec.rb
index 98a9c3eaec6..4a68475c37f 100644
--- a/spec/controllers/profiles/preferences_controller_spec.rb
+++ b/spec/controllers/profiles/preferences_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::PreferencesController do
+RSpec.describe Profiles::PreferencesController do
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/profiles/two_factor_auths_controller_spec.rb b/spec/controllers/profiles/two_factor_auths_controller_spec.rb
index b02af0096a5..f645081219a 100644
--- a/spec/controllers/profiles/two_factor_auths_controller_spec.rb
+++ b/spec/controllers/profiles/two_factor_auths_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Profiles::TwoFactorAuthsController do
+RSpec.describe Profiles::TwoFactorAuthsController do
before do
# `user` should be defined within the action-specific describe blocks
sign_in(user)
diff --git a/spec/controllers/profiles_controller_spec.rb b/spec/controllers/profiles_controller_spec.rb
index d6d2c73d049..e08c92da87f 100644
--- a/spec/controllers/profiles_controller_spec.rb
+++ b/spec/controllers/profiles_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe ProfilesController, :request_store do
+RSpec.describe ProfilesController, :request_store do
let(:user) { create(:user) }
describe 'POST update' do
diff --git a/spec/controllers/projects/alert_management_controller_spec.rb b/spec/controllers/projects/alert_management_controller_spec.rb
index b84376db33d..6a1952f949b 100644
--- a/spec/controllers/projects/alert_management_controller_spec.rb
+++ b/spec/controllers/projects/alert_management_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::AlertManagementController do
+RSpec.describe Projects::AlertManagementController do
let_it_be(:project) { create(:project) }
let_it_be(:role) { :developer }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/alerting/notifications_controller_spec.rb b/spec/controllers/projects/alerting/notifications_controller_spec.rb
index 9d26c2278b1..0e2d33594df 100644
--- a/spec/controllers/projects/alerting/notifications_controller_spec.rb
+++ b/spec/controllers/projects/alerting/notifications_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Alerting::NotificationsController do
+RSpec.describe Projects::Alerting::NotificationsController do
let_it_be(:project) { create(:project) }
let_it_be(:environment) { create(:environment, project: project) }
diff --git a/spec/controllers/projects/artifacts_controller_spec.rb b/spec/controllers/projects/artifacts_controller_spec.rb
index 496c810130e..69ab9873b90 100644
--- a/spec/controllers/projects/artifacts_controller_spec.rb
+++ b/spec/controllers/projects/artifacts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ArtifactsController do
+RSpec.describe Projects::ArtifactsController do
include RepoHelpers
let(:user) { project.owner }
diff --git a/spec/controllers/projects/autocomplete_sources_controller_spec.rb b/spec/controllers/projects/autocomplete_sources_controller_spec.rb
index d35192b2ccb..865b31a28d7 100644
--- a/spec/controllers/projects/autocomplete_sources_controller_spec.rb
+++ b/spec/controllers/projects/autocomplete_sources_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::AutocompleteSourcesController do
+RSpec.describe Projects::AutocompleteSourcesController do
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project, namespace: group) }
let_it_be(:issue) { create(:issue, project: project) }
diff --git a/spec/controllers/projects/avatars_controller_spec.rb b/spec/controllers/projects/avatars_controller_spec.rb
index 54c2397625f..16e9c845307 100644
--- a/spec/controllers/projects/avatars_controller_spec.rb
+++ b/spec/controllers/projects/avatars_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::AvatarsController do
+RSpec.describe Projects::AvatarsController do
let_it_be(:project) { create(:project, :repository) }
before do
diff --git a/spec/controllers/projects/badges_controller_spec.rb b/spec/controllers/projects/badges_controller_spec.rb
index 91a29833314..7e7a630921f 100644
--- a/spec/controllers/projects/badges_controller_spec.rb
+++ b/spec/controllers/projects/badges_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BadgesController do
+RSpec.describe Projects::BadgesController do
let(:project) { pipeline.project }
let!(:pipeline) { create(:ci_empty_pipeline) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/blame_controller_spec.rb b/spec/controllers/projects/blame_controller_spec.rb
index ac8394e3cd4..bf475f6135a 100644
--- a/spec/controllers/projects/blame_controller_spec.rb
+++ b/spec/controllers/projects/blame_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BlameController do
+RSpec.describe Projects::BlameController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb
index ad04c6e61e8..33faf54361a 100644
--- a/spec/controllers/projects/blob_controller_spec.rb
+++ b/spec/controllers/projects/blob_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BlobController do
+RSpec.describe Projects::BlobController do
include ProjectForksHelper
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/controllers/projects/boards_controller_spec.rb b/spec/controllers/projects/boards_controller_spec.rb
index 6634801939b..dad932f9cdf 100644
--- a/spec/controllers/projects/boards_controller_spec.rb
+++ b/spec/controllers/projects/boards_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BoardsController do
+RSpec.describe Projects::BoardsController do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb
index 174d8904481..d36de8a2176 100644
--- a/spec/controllers/projects/branches_controller_spec.rb
+++ b/spec/controllers/projects/branches_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::BranchesController do
+RSpec.describe Projects::BranchesController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:developer) { create(:user) }
diff --git a/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb b/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb
index ac31045678f..3b9a3dded1e 100644
--- a/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb
+++ b/spec/controllers/projects/ci/daily_build_group_report_results_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Ci::DailyBuildGroupReportResultsController do
+RSpec.describe Projects::Ci::DailyBuildGroupReportResultsController do
describe 'GET index' do
let(:project) { create(:project, :public, :repository) }
let(:ref_path) { 'refs/heads/master' }
diff --git a/spec/controllers/projects/ci/lints_controller_spec.rb b/spec/controllers/projects/ci/lints_controller_spec.rb
index f45b1d7ddd8..eb92385fc83 100644
--- a/spec/controllers/projects/ci/lints_controller_spec.rb
+++ b/spec/controllers/projects/ci/lints_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Ci::LintsController do
+RSpec.describe Projects::Ci::LintsController do
include StubRequests
let(:project) { create(:project, :repository) }
diff --git a/spec/controllers/projects/clusters/applications_controller_spec.rb b/spec/controllers/projects/clusters/applications_controller_spec.rb
index 6de3593be28..b50814b4790 100644
--- a/spec/controllers/projects/clusters/applications_controller_spec.rb
+++ b/spec/controllers/projects/clusters/applications_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Clusters::ApplicationsController do
+RSpec.describe Projects::Clusters::ApplicationsController do
include AccessMatchersForController
def current_application
diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb
index 262a4956ce5..5645e25b741 100644
--- a/spec/controllers/projects/clusters_controller_spec.rb
+++ b/spec/controllers/projects/clusters_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ClustersController do
+RSpec.describe Projects::ClustersController do
include AccessMatchersForController
include GoogleApi::CloudPlatformHelpers
include KubernetesHelpers
diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb
index c8ddd181d10..706bf787b2d 100644
--- a/spec/controllers/projects/commit_controller_spec.rb
+++ b/spec/controllers/projects/commit_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CommitController do
+RSpec.describe Projects::CommitController do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/commits_controller_spec.rb b/spec/controllers/projects/commits_controller_spec.rb
index 1977e92e42b..557002acbc0 100644
--- a/spec/controllers/projects/commits_controller_spec.rb
+++ b/spec/controllers/projects/commits_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CommitsController do
+RSpec.describe Projects::CommitsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/compare_controller_spec.rb b/spec/controllers/projects/compare_controller_spec.rb
index d1a4a9a0058..6aa4bfe235b 100644
--- a/spec/controllers/projects/compare_controller_spec.rb
+++ b/spec/controllers/projects/compare_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CompareController do
+RSpec.describe Projects::CompareController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/cycle_analytics/events_controller_spec.rb b/spec/controllers/projects/cycle_analytics/events_controller_spec.rb
index 942e095d669..408ce51d34b 100644
--- a/spec/controllers/projects/cycle_analytics/events_controller_spec.rb
+++ b/spec/controllers/projects/cycle_analytics/events_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CycleAnalytics::EventsController do
+RSpec.describe Projects::CycleAnalytics::EventsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/cycle_analytics_controller_spec.rb b/spec/controllers/projects/cycle_analytics_controller_spec.rb
index 65eee7b8ead..8feb964cdde 100644
--- a/spec/controllers/projects/cycle_analytics_controller_spec.rb
+++ b/spec/controllers/projects/cycle_analytics_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::CycleAnalyticsController do
+RSpec.describe Projects::CycleAnalyticsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/deploy_keys_controller_spec.rb b/spec/controllers/projects/deploy_keys_controller_spec.rb
index 9d41e2f59cb..821f7fca73d 100644
--- a/spec/controllers/projects/deploy_keys_controller_spec.rb
+++ b/spec/controllers/projects/deploy_keys_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DeployKeysController do
+RSpec.describe Projects::DeployKeysController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:admin) { create(:admin) }
diff --git a/spec/controllers/projects/deployments_controller_spec.rb b/spec/controllers/projects/deployments_controller_spec.rb
index 37dcfa78772..85dd86d91e9 100644
--- a/spec/controllers/projects/deployments_controller_spec.rb
+++ b/spec/controllers/projects/deployments_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DeploymentsController do
+RSpec.describe Projects::DeploymentsController do
include ApiHelpers
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb b/spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb
index 30d2b79a92f..f664604ac15 100644
--- a/spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb
+++ b/spec/controllers/projects/design_management/designs/raw_images_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DesignManagement::Designs::RawImagesController do
+RSpec.describe Projects::DesignManagement::Designs::RawImagesController do
include DesignManagementTestHelpers
let_it_be(:project) { create(:project, :private) }
diff --git a/spec/controllers/projects/design_management/designs/resized_image_controller_spec.rb b/spec/controllers/projects/design_management/designs/resized_image_controller_spec.rb
index 6bfec1b314e..96ecbaf55b6 100644
--- a/spec/controllers/projects/design_management/designs/resized_image_controller_spec.rb
+++ b/spec/controllers/projects/design_management/designs/resized_image_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DesignManagement::Designs::ResizedImageController do
+RSpec.describe Projects::DesignManagement::Designs::ResizedImageController do
include DesignManagementTestHelpers
let_it_be(:project) { create(:project, :private) }
diff --git a/spec/controllers/projects/discussions_controller_spec.rb b/spec/controllers/projects/discussions_controller_spec.rb
index b2e4a3b7b0d..f2efd40afdb 100644
--- a/spec/controllers/projects/discussions_controller_spec.rb
+++ b/spec/controllers/projects/discussions_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::DiscussionsController do
+RSpec.describe Projects::DiscussionsController do
let(:user) { create(:user) }
let(:merge_request) { create(:merge_request) }
let(:project) { merge_request.source_project }
diff --git a/spec/controllers/projects/environments/prometheus_api_controller_spec.rb b/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
index fb8da52930c..17952aa0683 100644
--- a/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
+++ b/spec/controllers/projects/environments/prometheus_api_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Environments::PrometheusApiController do
+RSpec.describe Projects::Environments::PrometheusApiController do
let_it_be(:project) { create(:project) }
let_it_be(:environment) { create(:environment, project: project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/environments/sample_metrics_controller_spec.rb b/spec/controllers/projects/environments/sample_metrics_controller_spec.rb
index 19b07a2ccc4..14e3ded76f2 100644
--- a/spec/controllers/projects/environments/sample_metrics_controller_spec.rb
+++ b/spec/controllers/projects/environments/sample_metrics_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Environments::SampleMetricsController do
+RSpec.describe Projects::Environments::SampleMetricsController do
include StubENV
let_it_be(:project) { create(:project) }
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb
index cd4896ede43..cca4b597f4c 100644
--- a/spec/controllers/projects/environments_controller_spec.rb
+++ b/spec/controllers/projects/environments_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::EnvironmentsController do
+RSpec.describe Projects::EnvironmentsController do
include MetricsDashboardHelpers
let_it_be(:project) { create(:project) }
diff --git a/spec/controllers/projects/error_tracking/projects_controller_spec.rb b/spec/controllers/projects/error_tracking/projects_controller_spec.rb
index 1737528b597..67947d1c9d9 100644
--- a/spec/controllers/projects/error_tracking/projects_controller_spec.rb
+++ b/spec/controllers/projects/error_tracking/projects_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ErrorTracking::ProjectsController do
+RSpec.describe Projects::ErrorTracking::ProjectsController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb b/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb
index 27d49147e99..7c080504c31 100644
--- a/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb
+++ b/spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ErrorTracking::StackTracesController do
+RSpec.describe Projects::ErrorTracking::StackTracesController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/error_tracking_controller_spec.rb b/spec/controllers/projects/error_tracking_controller_spec.rb
index 6be979418ad..5ea885e4fd6 100644
--- a/spec/controllers/projects/error_tracking_controller_spec.rb
+++ b/spec/controllers/projects/error_tracking_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ErrorTrackingController do
+RSpec.describe Projects::ErrorTrackingController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/find_file_controller_spec.rb b/spec/controllers/projects/find_file_controller_spec.rb
index 4d8933f3aaf..a6c71cff74b 100644
--- a/spec/controllers/projects/find_file_controller_spec.rb
+++ b/spec/controllers/projects/find_file_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::FindFileController do
+RSpec.describe Projects::FindFileController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/forks_controller_spec.rb b/spec/controllers/projects/forks_controller_spec.rb
index e362790cd3c..4c0fd7b8954 100644
--- a/spec/controllers/projects/forks_controller_spec.rb
+++ b/spec/controllers/projects/forks_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ForksController do
+RSpec.describe Projects::ForksController do
let(:user) { create(:user) }
let(:project) { create(:project, :public, :repository) }
let(:forked_project) { Projects::ForkService.new(project, user, name: 'Some name').execute }
diff --git a/spec/controllers/projects/grafana_api_controller_spec.rb b/spec/controllers/projects/grafana_api_controller_spec.rb
index 8502bd1ab0a..baee9705127 100644
--- a/spec/controllers/projects/grafana_api_controller_spec.rb
+++ b/spec/controllers/projects/grafana_api_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::GrafanaApiController do
+RSpec.describe Projects::GrafanaApiController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/graphs_controller_spec.rb b/spec/controllers/projects/graphs_controller_spec.rb
index e589815c45d..140af74b576 100644
--- a/spec/controllers/projects/graphs_controller_spec.rb
+++ b/spec/controllers/projects/graphs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::GraphsController do
+RSpec.describe Projects::GraphsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/group_links_controller_spec.rb b/spec/controllers/projects/group_links_controller_spec.rb
index 28999257957..762ef795f6e 100644
--- a/spec/controllers/projects/group_links_controller_spec.rb
+++ b/spec/controllers/projects/group_links_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::GroupLinksController do
+RSpec.describe Projects::GroupLinksController do
let(:group) { create(:group, :private) }
let(:group2) { create(:group, :private) }
let(:project) { create(:project, :private, group: group2) }
diff --git a/spec/controllers/projects/hooks_controller_spec.rb b/spec/controllers/projects/hooks_controller_spec.rb
index e97f602d9ab..440e6b2a74c 100644
--- a/spec/controllers/projects/hooks_controller_spec.rb
+++ b/spec/controllers/projects/hooks_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::HooksController do
+RSpec.describe Projects::HooksController do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/import/jira_controller_spec.rb b/spec/controllers/projects/import/jira_controller_spec.rb
index 9c8840b986c..200f7ef812a 100644
--- a/spec/controllers/projects/import/jira_controller_spec.rb
+++ b/spec/controllers/projects/import/jira_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Import::JiraController do
+RSpec.describe Projects::Import::JiraController do
include JiraServiceHelper
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/imports_controller_spec.rb b/spec/controllers/projects/imports_controller_spec.rb
index bdc81efe3bc..29cfd1c352e 100644
--- a/spec/controllers/projects/imports_controller_spec.rb
+++ b/spec/controllers/projects/imports_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ImportsController do
+RSpec.describe Projects::ImportsController do
let(:user) { create(:user) }
let(:project) { create(:project) }
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index e62c4ef9d94..bcd1a53bd47 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::IssuesController do
+RSpec.describe Projects::IssuesController do
include ProjectForksHelper
include_context 'includes Spam constants'
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index edf7fa0fb94..44dcb0caab2 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Projects::JobsController, :clean_gitlab_redis_shared_state do
+RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
include ApiHelpers
include HttpIOHelpers
diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb
index c6098f5934d..f213d104747 100644
--- a/spec/controllers/projects/labels_controller_spec.rb
+++ b/spec/controllers/projects/labels_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::LabelsController do
+RSpec.describe Projects::LabelsController do
let(:group) { create(:group) }
let(:project) { create(:project, namespace: group) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/logs_controller_spec.rb b/spec/controllers/projects/logs_controller_spec.rb
index e86a42b03c8..1eb5a6fcc12 100644
--- a/spec/controllers/projects/logs_controller_spec.rb
+++ b/spec/controllers/projects/logs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::LogsController do
+RSpec.describe Projects::LogsController do
include KubernetesHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/mattermosts_controller_spec.rb b/spec/controllers/projects/mattermosts_controller_spec.rb
index 693176d0cfc..001f2564698 100644
--- a/spec/controllers/projects/mattermosts_controller_spec.rb
+++ b/spec/controllers/projects/mattermosts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MattermostsController do
+RSpec.describe Projects::MattermostsController do
let!(:project) { create(:project) }
let!(:user) { create(:user) }
diff --git a/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
index 8e4ac64f7b0..5f636bd4340 100644
--- a/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequests::ConflictsController do
+RSpec.describe Projects::MergeRequests::ConflictsController do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) }
diff --git a/spec/controllers/projects/merge_requests/content_controller_spec.rb b/spec/controllers/projects/merge_requests/content_controller_spec.rb
index 72eedc837a4..7fb20b4666a 100644
--- a/spec/controllers/projects/merge_requests/content_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/content_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequests::ContentController do
+RSpec.describe Projects::MergeRequests::ContentController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:merge_request) { create(:merge_request, target_project: project, source_project: project) }
diff --git a/spec/controllers/projects/merge_requests/creations_controller_spec.rb b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
index db25ad62019..091a44130a1 100644
--- a/spec/controllers/projects/merge_requests/creations_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequests::CreationsController do
+RSpec.describe Projects::MergeRequests::CreationsController do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
let(:fork_project) { create(:forked_project_with_submodules) }
diff --git a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
index 3d9193e3e33..02b4c2d1da9 100644
--- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequests::DiffsController do
+RSpec.describe Projects::MergeRequests::DiffsController do
include ProjectForksHelper
shared_examples '404 for unexistent diffable' do
diff --git a/spec/controllers/projects/merge_requests/drafts_controller_spec.rb b/spec/controllers/projects/merge_requests/drafts_controller_spec.rb
index 067c111cb49..7d74e872d29 100644
--- a/spec/controllers/projects/merge_requests/drafts_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/drafts_controller_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe Projects::MergeRequests::DraftsController do
+RSpec.describe Projects::MergeRequests::DraftsController do
include RepoHelpers
let(:project) { create(:project, :repository) }
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 51cf65e5850..c80ba4a28e8 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MergeRequestsController do
+RSpec.describe Projects::MergeRequestsController do
include ProjectForksHelper
include Gitlab::Routing
diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb
index b6c91db8b4d..0c7391c1b9c 100644
--- a/spec/controllers/projects/milestones_controller_spec.rb
+++ b/spec/controllers/projects/milestones_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MilestonesController do
+RSpec.describe Projects::MilestonesController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:milestone) { create(:milestone, project: project) }
diff --git a/spec/controllers/projects/mirrors_controller_spec.rb b/spec/controllers/projects/mirrors_controller_spec.rb
index 8cd940978c0..7c5d14d3a22 100644
--- a/spec/controllers/projects/mirrors_controller_spec.rb
+++ b/spec/controllers/projects/mirrors_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::MirrorsController do
+RSpec.describe Projects::MirrorsController do
include ReactiveCachingHelpers
shared_examples 'only admin is allowed when mirroring is disabled' do
diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb
index f883c02af65..b3a83723189 100644
--- a/spec/controllers/projects/notes_controller_spec.rb
+++ b/spec/controllers/projects/notes_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::NotesController do
+RSpec.describe Projects::NotesController do
include ProjectForksHelper
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/pages_controller_spec.rb b/spec/controllers/projects/pages_controller_spec.rb
index 102c0b6b048..1fa8838b548 100644
--- a/spec/controllers/projects/pages_controller_spec.rb
+++ b/spec/controllers/projects/pages_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PagesController do
+RSpec.describe Projects::PagesController do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
diff --git a/spec/controllers/projects/pages_domains_controller_spec.rb b/spec/controllers/projects/pages_domains_controller_spec.rb
index 40a6f77f0d6..691508d1e14 100644
--- a/spec/controllers/projects/pages_domains_controller_spec.rb
+++ b/spec/controllers/projects/pages_domains_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PagesDomainsController do
+RSpec.describe Projects::PagesDomainsController do
let(:user) { create(:user) }
let(:project) { create(:project) }
let!(:pages_domain) { create(:pages_domain, project: project) }
diff --git a/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb b/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb
index 6a53e8f3dbf..8a344a72120 100644
--- a/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb
+++ b/spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PerformanceMonitoring::DashboardsController do
+RSpec.describe Projects::PerformanceMonitoring::DashboardsController do
let_it_be(:user) { create(:user) }
let_it_be(:namespace) { create(:namespace) }
let!(:project) { create(:project, :repository, name: 'dashboard-project', namespace: namespace) }
diff --git a/spec/controllers/projects/pipeline_schedules_controller_spec.rb b/spec/controllers/projects/pipeline_schedules_controller_spec.rb
index 635980ba93b..27a3e95896a 100644
--- a/spec/controllers/projects/pipeline_schedules_controller_spec.rb
+++ b/spec/controllers/projects/pipeline_schedules_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PipelineSchedulesController do
+RSpec.describe Projects::PipelineSchedulesController do
include AccessMatchersForController
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb
index 00d69860665..1a45ec76780 100644
--- a/spec/controllers/projects/pipelines_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PipelinesController do
+RSpec.describe Projects::PipelinesController do
include ApiHelpers
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/pipelines_settings_controller_spec.rb b/spec/controllers/projects/pipelines_settings_controller_spec.rb
index 789b2104d3c..ad631b7c3da 100644
--- a/spec/controllers/projects/pipelines_settings_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_settings_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::PipelinesSettingsController do
+RSpec.describe Projects::PipelinesSettingsController do
let_it_be(:user) { create(:user) }
let_it_be(:project_auto_devops) { create(:project_auto_devops) }
let(:project) { project_auto_devops.project }
diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb
index f354bba902a..7457e4c5023 100644
--- a/spec/controllers/projects/project_members_controller_spec.rb
+++ b/spec/controllers/projects/project_members_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::ProjectMembersController do
+RSpec.describe Projects::ProjectMembersController do
let(:user) { create(:user) }
let(:group) { create(:group, :public) }
let(:project) { create(:project, :public) }
diff --git a/spec/controllers/projects/prometheus/alerts_controller_spec.rb b/spec/controllers/projects/prometheus/alerts_controller_spec.rb
index e936cb5916e..6e3148231bd 100644
--- a/spec/controllers/projects/prometheus/alerts_controller_spec.rb
+++ b/spec/controllers/projects/prometheus/alerts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Prometheus::AlertsController do
+RSpec.describe Projects::Prometheus::AlertsController do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:environment) { create(:environment, project: project) }
diff --git a/spec/controllers/projects/prometheus/metrics_controller_spec.rb b/spec/controllers/projects/prometheus/metrics_controller_spec.rb
index 36f694cda29..c7c3be20f29 100644
--- a/spec/controllers/projects/prometheus/metrics_controller_spec.rb
+++ b/spec/controllers/projects/prometheus/metrics_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Prometheus::MetricsController do
+RSpec.describe Projects::Prometheus::MetricsController do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:prometheus_project) }
diff --git a/spec/controllers/projects/protected_branches_controller_spec.rb b/spec/controllers/projects/protected_branches_controller_spec.rb
index 262f77a7328..09eb1a45c73 100644
--- a/spec/controllers/projects/protected_branches_controller_spec.rb
+++ b/spec/controllers/projects/protected_branches_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::ProtectedBranchesController do
+RSpec.describe Projects::ProtectedBranchesController do
let(:project) { create(:project, :repository) }
let(:protected_branch) { create(:protected_branch, project: project) }
let(:project_params) { { namespace_id: project.namespace.to_param, project_id: project } }
diff --git a/spec/controllers/projects/protected_tags_controller_spec.rb b/spec/controllers/projects/protected_tags_controller_spec.rb
index a900947d82e..2c2240cb0d0 100644
--- a/spec/controllers/projects/protected_tags_controller_spec.rb
+++ b/spec/controllers/projects/protected_tags_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::ProtectedTagsController do
+RSpec.describe Projects::ProtectedTagsController do
describe "GET #index" do
let(:project) { create(:project_empty_repo, :public) }
diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb
index 4a684dcfbc6..5f10343eb76 100644
--- a/spec/controllers/projects/raw_controller_spec.rb
+++ b/spec/controllers/projects/raw_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::RawController do
+RSpec.describe Projects::RawController do
include RepoHelpers
let(:project) { create(:project, :public, :repository) }
diff --git a/spec/controllers/projects/refs_controller_spec.rb b/spec/controllers/projects/refs_controller_spec.rb
index f6024545681..a6a4aff7ce9 100644
--- a/spec/controllers/projects/refs_controller_spec.rb
+++ b/spec/controllers/projects/refs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::RefsController do
+RSpec.describe Projects::RefsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/registry/repositories_controller_spec.rb b/spec/controllers/projects/registry/repositories_controller_spec.rb
index faa0deb5f84..098fa9bac2c 100644
--- a/spec/controllers/projects/registry/repositories_controller_spec.rb
+++ b/spec/controllers/projects/registry/repositories_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Registry::RepositoriesController do
+RSpec.describe Projects::Registry::RepositoriesController do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :private) }
diff --git a/spec/controllers/projects/registry/tags_controller_spec.rb b/spec/controllers/projects/registry/tags_controller_spec.rb
index 5ab32b7d81d..6adee35b60a 100644
--- a/spec/controllers/projects/registry/tags_controller_spec.rb
+++ b/spec/controllers/projects/registry/tags_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Registry::TagsController do
+RSpec.describe Projects::Registry::TagsController do
let(:user) { create(:user) }
let(:project) { create(:project, :private) }
diff --git a/spec/controllers/projects/releases/evidences_controller_spec.rb b/spec/controllers/projects/releases/evidences_controller_spec.rb
index 37be9deda5f..d5a9665d6a5 100644
--- a/spec/controllers/projects/releases/evidences_controller_spec.rb
+++ b/spec/controllers/projects/releases/evidences_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Releases::EvidencesController do
+RSpec.describe Projects::Releases::EvidencesController do
let!(:project) { create(:project, :repository, :public) }
let_it_be(:private_project) { create(:project, :repository, :private) }
let_it_be(:developer) { create(:user) }
diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb
index 45f4433ed0a..96c38c1b726 100644
--- a/spec/controllers/projects/releases_controller_spec.rb
+++ b/spec/controllers/projects/releases_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ReleasesController do
+RSpec.describe Projects::ReleasesController do
let!(:project) { create(:project, :repository, :public) }
let_it_be(:private_project) { create(:project, :repository, :private) }
let_it_be(:developer) { create(:user) }
diff --git a/spec/controllers/projects/repositories_controller_spec.rb b/spec/controllers/projects/repositories_controller_spec.rb
index 42032b4cad0..97eea7c7e9d 100644
--- a/spec/controllers/projects/repositories_controller_spec.rb
+++ b/spec/controllers/projects/repositories_controller_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe Projects::RepositoriesController do
+RSpec.describe Projects::RepositoriesController do
let(:project) { create(:project, :repository) }
describe "GET archive" do
diff --git a/spec/controllers/projects/runners_controller_spec.rb b/spec/controllers/projects/runners_controller_spec.rb
index 1893180fe9b..66f20bd50c4 100644
--- a/spec/controllers/projects/runners_controller_spec.rb
+++ b/spec/controllers/projects/runners_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::RunnersController do
+RSpec.describe Projects::RunnersController do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:runner) { create(:ci_runner, :project, projects: [project]) }
diff --git a/spec/controllers/projects/serverless/functions_controller_spec.rb b/spec/controllers/projects/serverless/functions_controller_spec.rb
index 203e1e49994..3071d0b7f54 100644
--- a/spec/controllers/projects/serverless/functions_controller_spec.rb
+++ b/spec/controllers/projects/serverless/functions_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Serverless::FunctionsController do
+RSpec.describe Projects::Serverless::FunctionsController do
include KubernetesHelpers
include ReactiveCachingHelpers
diff --git a/spec/controllers/projects/service_hook_logs_controller_spec.rb b/spec/controllers/projects/service_hook_logs_controller_spec.rb
index a5130cd6e32..97fb31f0546 100644
--- a/spec/controllers/projects/service_hook_logs_controller_spec.rb
+++ b/spec/controllers/projects/service_hook_logs_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ServiceHookLogsController do
+RSpec.describe Projects::ServiceHookLogsController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:service) { create(:drone_ci_service, project: project) }
diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb
index b591e52d45c..04c74dfdefe 100644
--- a/spec/controllers/projects/services_controller_spec.rb
+++ b/spec/controllers/projects/services_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::ServicesController do
+RSpec.describe Projects::ServicesController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:service) { create(:jira_service, project: project) }
diff --git a/spec/controllers/projects/settings/access_tokens_controller_spec.rb b/spec/controllers/projects/settings/access_tokens_controller_spec.rb
index 884a5bc2836..4743ab2b7c1 100644
--- a/spec/controllers/projects/settings/access_tokens_controller_spec.rb
+++ b/spec/controllers/projects/settings/access_tokens_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::Settings::AccessTokensController do
+RSpec.describe Projects::Settings::AccessTokensController do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
index 6891af54eb4..8498ff49826 100644
--- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb
+++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::Settings::CiCdController do
+RSpec.describe Projects::Settings::CiCdController do
let_it_be(:user) { create(:user) }
let_it_be(:project_auto_devops) { create(:project_auto_devops) }
let(:project) { project_auto_devops.project }
diff --git a/spec/controllers/projects/settings/integrations_controller_spec.rb b/spec/controllers/projects/settings/integrations_controller_spec.rb
index 5d9fe3da912..0652786c787 100644
--- a/spec/controllers/projects/settings/integrations_controller_spec.rb
+++ b/spec/controllers/projects/settings/integrations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Settings::IntegrationsController do
+RSpec.describe Projects::Settings::IntegrationsController do
let(:project) { create(:project, :public) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/settings/operations_controller_spec.rb b/spec/controllers/projects/settings/operations_controller_spec.rb
index c9afff0b73d..6b440e910ad 100644
--- a/spec/controllers/projects/settings/operations_controller_spec.rb
+++ b/spec/controllers/projects/settings/operations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Settings::OperationsController do
+RSpec.describe Projects::Settings::OperationsController do
let_it_be(:user) { create(:user) }
let_it_be(:project, reload: true) { create(:project) }
diff --git a/spec/controllers/projects/settings/repository_controller_spec.rb b/spec/controllers/projects/settings/repository_controller_spec.rb
index fb9cdd860dc..46dba691bc4 100644
--- a/spec/controllers/projects/settings/repository_controller_spec.rb
+++ b/spec/controllers/projects/settings/repository_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Settings::RepositoryController do
+RSpec.describe Projects::Settings::RepositoryController do
let(:project) { create(:project_empty_repo, :public) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/snippets_controller_spec.rb b/spec/controllers/projects/snippets_controller_spec.rb
index b5f4929d8ce..8bbfaa8d327 100644
--- a/spec/controllers/projects/snippets_controller_spec.rb
+++ b/spec/controllers/projects/snippets_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::SnippetsController do
+RSpec.describe Projects::SnippetsController do
include Gitlab::Routing
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/stages_controller_spec.rb b/spec/controllers/projects/stages_controller_spec.rb
index c38e3d2544f..dcf8607ae18 100644
--- a/spec/controllers/projects/stages_controller_spec.rb
+++ b/spec/controllers/projects/stages_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::StagesController do
+RSpec.describe Projects::StagesController do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
diff --git a/spec/controllers/projects/starrers_controller_spec.rb b/spec/controllers/projects/starrers_controller_spec.rb
index 5774ff7c576..66888fa3024 100644
--- a/spec/controllers/projects/starrers_controller_spec.rb
+++ b/spec/controllers/projects/starrers_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::StarrersController do
+RSpec.describe Projects::StarrersController do
let(:user_1) { create(:user, name: 'John') }
let(:user_2) { create(:user, name: 'Michael') }
let(:private_user) { create(:user, name: 'Michael Douglas', private_profile: true) }
diff --git a/spec/controllers/projects/static_site_editor_controller_spec.rb b/spec/controllers/projects/static_site_editor_controller_spec.rb
index 7b470254de1..384218504b9 100644
--- a/spec/controllers/projects/static_site_editor_controller_spec.rb
+++ b/spec/controllers/projects/static_site_editor_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::StaticSiteEditorController do
+RSpec.describe Projects::StaticSiteEditorController do
let_it_be(:project) { create(:project, :public, :repository) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/tags/releases_controller_spec.rb b/spec/controllers/projects/tags/releases_controller_spec.rb
index 261c141d06f..b3d4d944440 100644
--- a/spec/controllers/projects/tags/releases_controller_spec.rb
+++ b/spec/controllers/projects/tags/releases_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::Tags::ReleasesController do
+RSpec.describe Projects::Tags::ReleasesController do
let!(:project) { create(:project, :repository) }
let!(:user) { create(:user) }
let!(:release) { create(:release, project: project) }
diff --git a/spec/controllers/projects/tags_controller_spec.rb b/spec/controllers/projects/tags_controller_spec.rb
index 15ef1c65c53..9ca56f58055 100644
--- a/spec/controllers/projects/tags_controller_spec.rb
+++ b/spec/controllers/projects/tags_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::TagsController do
+RSpec.describe Projects::TagsController do
let(:project) { create(:project, :public, :repository) }
let!(:release) { create(:release, project: project) }
let!(:invalid_release) { create(:release, project: project, tag: 'does-not-exist') }
diff --git a/spec/controllers/projects/templates_controller_spec.rb b/spec/controllers/projects/templates_controller_spec.rb
index fcd9b4aa8bd..40632e0dea7 100644
--- a/spec/controllers/projects/templates_controller_spec.rb
+++ b/spec/controllers/projects/templates_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::TemplatesController do
+RSpec.describe Projects::TemplatesController do
let(:project) { create(:project, :repository, :private) }
let(:user) { create(:user) }
let(:file_path_1) { '.gitlab/issue_templates/issue_template.md' }
diff --git a/spec/controllers/projects/todos_controller_spec.rb b/spec/controllers/projects/todos_controller_spec.rb
index b7d40d2a452..e1e1e455094 100644
--- a/spec/controllers/projects/todos_controller_spec.rb
+++ b/spec/controllers/projects/todos_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe Projects::TodosController do
+RSpec.describe Projects::TodosController do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
diff --git a/spec/controllers/projects/tree_controller_spec.rb b/spec/controllers/projects/tree_controller_spec.rb
index 96838383540..f6ec04d4dd7 100644
--- a/spec/controllers/projects/tree_controller_spec.rb
+++ b/spec/controllers/projects/tree_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::TreeController do
+RSpec.describe Projects::TreeController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/uploads_controller_spec.rb b/spec/controllers/projects/uploads_controller_spec.rb
index bb5415ee62c..dda58f06a37 100644
--- a/spec/controllers/projects/uploads_controller_spec.rb
+++ b/spec/controllers/projects/uploads_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::UploadsController do
+RSpec.describe Projects::UploadsController do
include WorkhorseHelpers
let(:model) { create(:project, :public) }
diff --git a/spec/controllers/projects/usage_ping_controller_spec.rb b/spec/controllers/projects/usage_ping_controller_spec.rb
index a68967c228f..9ace072d561 100644
--- a/spec/controllers/projects/usage_ping_controller_spec.rb
+++ b/spec/controllers/projects/usage_ping_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::UsagePingController do
+RSpec.describe Projects::UsagePingController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/projects/variables_controller_spec.rb b/spec/controllers/projects/variables_controller_spec.rb
index 21e106660d0..8bb4c2dae4b 100644
--- a/spec/controllers/projects/variables_controller_spec.rb
+++ b/spec/controllers/projects/variables_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::VariablesController do
+RSpec.describe Projects::VariablesController do
let(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects/web_ide_terminals_controller_spec.rb b/spec/controllers/projects/web_ide_terminals_controller_spec.rb
index 6ccb9f84494..2ae5899c258 100644
--- a/spec/controllers/projects/web_ide_terminals_controller_spec.rb
+++ b/spec/controllers/projects/web_ide_terminals_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::WebIdeTerminalsController do
+RSpec.describe Projects::WebIdeTerminalsController do
let_it_be(:owner) { create(:owner) }
let_it_be(:admin) { create(:admin) }
let_it_be(:maintainer) { create(:user) }
diff --git a/spec/controllers/projects/wikis_controller_spec.rb b/spec/controllers/projects/wikis_controller_spec.rb
index b4bbf76ce18..2671e3db982 100644
--- a/spec/controllers/projects/wikis_controller_spec.rb
+++ b/spec/controllers/projects/wikis_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Projects::WikisController do
+RSpec.describe Projects::WikisController do
let_it_be(:project) { create(:project, :public, :repository) }
let(:user) { project.owner }
let(:project_wiki) { ProjectWiki.new(project, user) }
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index ccd23940d41..697d1fcc5cb 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -2,7 +2,7 @@
require('spec_helper')
-describe ProjectsController do
+RSpec.describe ProjectsController do
include ExternalAuthorizationServiceHelpers
include ProjectForksHelper
diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb
index 3a6ddfb1783..1993606af04 100644
--- a/spec/controllers/registrations_controller_spec.rb
+++ b/spec/controllers/registrations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe RegistrationsController do
+RSpec.describe RegistrationsController do
include TermsHelper
before do
diff --git a/spec/controllers/repositories/git_http_controller_spec.rb b/spec/controllers/repositories/git_http_controller_spec.rb
index 1a2eee5d3a9..aafb933df32 100644
--- a/spec/controllers/repositories/git_http_controller_spec.rb
+++ b/spec/controllers/repositories/git_http_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Repositories::GitHttpController do
+RSpec.describe Repositories::GitHttpController do
include GitHttpHelpers
let_it_be(:project) { create(:project, :public, :repository) }
diff --git a/spec/controllers/root_controller_spec.rb b/spec/controllers/root_controller_spec.rb
index 4892ff43086..9eefbcb0835 100644
--- a/spec/controllers/root_controller_spec.rb
+++ b/spec/controllers/root_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe RootController do
+RSpec.describe RootController do
describe 'GET index' do
context 'when user is not logged in' do
it 'redirects to the sign-in page' do
diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb
index 19eeabf99ee..bae6bd07b67 100644
--- a/spec/controllers/search_controller_spec.rb
+++ b/spec/controllers/search_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SearchController do
+RSpec.describe SearchController do
include ExternalAuthorizationServiceHelpers
let(:user) { create(:user) }
diff --git a/spec/controllers/sent_notifications_controller_spec.rb b/spec/controllers/sent_notifications_controller_spec.rb
index a0a18f66b0c..0c4a77d5926 100644
--- a/spec/controllers/sent_notifications_controller_spec.rb
+++ b/spec/controllers/sent_notifications_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SentNotificationsController do
+RSpec.describe SentNotificationsController do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
let(:private_project) { create(:project, :private) }
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
index a65698a5b56..16a58112479 100644
--- a/spec/controllers/sessions_controller_spec.rb
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SessionsController do
+RSpec.describe SessionsController do
include DeviseHelpers
include LdapHelpers
diff --git a/spec/controllers/snippets/notes_controller_spec.rb b/spec/controllers/snippets/notes_controller_spec.rb
index 0676ed05212..487635169fc 100644
--- a/spec/controllers/snippets/notes_controller_spec.rb
+++ b/spec/controllers/snippets/notes_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Snippets::NotesController do
+RSpec.describe Snippets::NotesController do
let(:user) { create(:user) }
let(:private_snippet) { create(:personal_snippet, :private) }
diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb
index 046ee40cec2..70df1faf7dd 100644
--- a/spec/controllers/snippets_controller_spec.rb
+++ b/spec/controllers/snippets_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe SnippetsController do
+RSpec.describe SnippetsController do
let_it_be(:user) { create(:user) }
describe 'GET #index' do
diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb
index 309a8226226..043fd97f1ad 100644
--- a/spec/controllers/uploads_controller_spec.rb
+++ b/spec/controllers/uploads_controller_spec.rb
@@ -1,25 +1,25 @@
# frozen_string_literal: true
require 'spec_helper'
-shared_examples 'content 5 min private cached with revalidation' do
+RSpec.shared_examples 'content 5 min private cached with revalidation' do
it 'ensures content will not be cached without revalidation' do
expect(subject['Cache-Control']).to eq('max-age=300, private, must-revalidate')
end
end
-shared_examples 'content not cached' do
+RSpec.shared_examples 'content not cached' do
it 'ensures content will not be cached without revalidation' do
expect(subject['Cache-Control']).to eq('max-age=0, private, must-revalidate')
end
end
-shared_examples 'content publicly cached' do
+RSpec.shared_examples 'content publicly cached' do
it 'ensures content is publicly cached' do
expect(subject['Cache-Control']).to eq('max-age=300, public')
end
end
-describe UploadsController do
+RSpec.describe UploadsController do
include WorkhorseHelpers
let!(:user) { create(:user, avatar: fixture_file_upload("spec/fixtures/dk.png", "image/png")) }
diff --git a/spec/controllers/user_callouts_controller_spec.rb b/spec/controllers/user_callouts_controller_spec.rb
index 04f73749e1d..279f825e40f 100644
--- a/spec/controllers/user_callouts_controller_spec.rb
+++ b/spec/controllers/user_callouts_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe UserCalloutsController do
+RSpec.describe UserCalloutsController do
let(:user) { create(:user) }
before do
diff --git a/spec/controllers/users/terms_controller_spec.rb b/spec/controllers/users/terms_controller_spec.rb
index 99582652c39..0acc3008187 100644
--- a/spec/controllers/users/terms_controller_spec.rb
+++ b/spec/controllers/users/terms_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Users::TermsController do
+RSpec.describe Users::TermsController do
include TermsHelper
let_it_be(:user) { create(:user) }
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index 2af398e143d..bec4b24484a 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe UsersController do
+RSpec.describe UsersController do
let(:user) { create(:user) }
let(:private_user) { create(:user, private_profile: true) }
let(:public_user) { create(:user) }
diff --git a/spec/db/development/import_common_metrics_spec.rb b/spec/db/development/import_common_metrics_spec.rb
index 25061ef0887..396eae9293e 100644
--- a/spec/db/development/import_common_metrics_spec.rb
+++ b/spec/db/development/import_common_metrics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Import metrics on development seed' do
+RSpec.describe 'Import metrics on development seed' do
subject { load Rails.root.join('db', 'fixtures', 'development', '99_common_metrics.rb') }
it "imports all prometheus metrics" do
diff --git a/spec/db/production/import_common_metrics_spec.rb b/spec/db/production/import_common_metrics_spec.rb
index 1e4ff818a86..1cc0c2fd77f 100644
--- a/spec/db/production/import_common_metrics_spec.rb
+++ b/spec/db/production/import_common_metrics_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Import metrics on production seed' do
+RSpec.describe 'Import metrics on production seed' do
subject { load Rails.root.join('db', 'fixtures', 'production', '999_common_metrics.rb') }
it "imports all prometheus metrics" do
diff --git a/spec/db/production/settings_spec.rb b/spec/db/production/settings_spec.rb
index 02e25aa37e3..84f7ae12728 100644
--- a/spec/db/production/settings_spec.rb
+++ b/spec/db/production/settings_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require 'rainbow/ext/string'
-describe 'seed production settings' do
+RSpec.describe 'seed production settings' do
let(:settings_file) { Rails.root.join('db/fixtures/production/010_settings.rb') }
let(:settings) { Gitlab::CurrentSettings.current_application_settings }
diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb
index eac9eb7aa47..d4c24ab5d86 100644
--- a/spec/db/schema_spec.rb
+++ b/spec/db/schema_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require Rails.root.join('ee', 'spec', 'db', 'schema_support') if Gitlab.ee?
-describe 'Database schema' do
+RSpec.describe 'Database schema' do
prepend_if_ee('EE::DB::SchemaSupport')
let(:connection) { ActiveRecord::Base.connection }
diff --git a/spec/dependencies/omniauth_saml_spec.rb b/spec/dependencies/omniauth_saml_spec.rb
index e0ea9c38e69..fa179eb1516 100644
--- a/spec/dependencies/omniauth_saml_spec.rb
+++ b/spec/dependencies/omniauth_saml_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require 'omniauth/strategies/saml'
-describe 'processing of SAMLResponse in dependencies' do
+RSpec.describe 'processing of SAMLResponse in dependencies' do
let(:mock_saml_response) { File.read('spec/fixtures/authentication/saml_response.xml') }
let(:saml_strategy) { OmniAuth::Strategies::SAML.new({}) }
let(:session_mock) { {} }
diff --git a/spec/factories_spec.rb b/spec/factories_spec.rb
index aa72a116be2..f89aeb1c93d 100644
--- a/spec/factories_spec.rb
+++ b/spec/factories_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'factories' do
+RSpec.describe 'factories' do
FactoryBot.factories.each do |factory|
describe "#{factory.name} factory" do
it 'does not raise error when built' do
diff --git a/spec/features/abuse_report_spec.rb b/spec/features/abuse_report_spec.rb
index b1573bfb270..5959fcd6306 100644
--- a/spec/features/abuse_report_spec.rb
+++ b/spec/features/abuse_report_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Abuse reports' do
+RSpec.describe 'Abuse reports' do
let(:another_user) { create(:user) }
before do
diff --git a/spec/features/action_cable_logging_spec.rb b/spec/features/action_cable_logging_spec.rb
index f0bdb5fdd8c..ba99405a51a 100644
--- a/spec/features/action_cable_logging_spec.rb
+++ b/spec/features/action_cable_logging_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'ActionCable logging', :js do
+RSpec.describe 'ActionCable logging', :js do
let_it_be(:project) { create(:project, :public) }
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/features/admin/admin_abuse_reports_spec.rb b/spec/features/admin/admin_abuse_reports_spec.rb
index 93051a8a355..845e186dd5b 100644
--- a/spec/features/admin/admin_abuse_reports_spec.rb
+++ b/spec/features/admin/admin_abuse_reports_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Admin::AbuseReports", :js do
+RSpec.describe "Admin::AbuseReports", :js do
let(:user) { create(:user) }
context 'as an admin' do
diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb
index e711ee7d40e..48aaec6e6df 100644
--- a/spec/features/admin/admin_appearance_spec.rb
+++ b/spec/features/admin/admin_appearance_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin Appearance' do
+RSpec.describe 'Admin Appearance' do
let!(:appearance) { create(:appearance) }
it 'Create new appearance' do
diff --git a/spec/features/admin/admin_broadcast_messages_spec.rb b/spec/features/admin/admin_broadcast_messages_spec.rb
index bf7f8563e68..091ed0a3396 100644
--- a/spec/features/admin/admin_broadcast_messages_spec.rb
+++ b/spec/features/admin/admin_broadcast_messages_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin Broadcast Messages' do
+RSpec.describe 'Admin Broadcast Messages' do
before do
sign_in(create(:admin))
create(:broadcast_message, :expired, message: 'Migration to new server')
diff --git a/spec/features/admin/admin_browse_spam_logs_spec.rb b/spec/features/admin/admin_browse_spam_logs_spec.rb
index c79524a7fb3..65847876c11 100644
--- a/spec/features/admin/admin_browse_spam_logs_spec.rb
+++ b/spec/features/admin/admin_browse_spam_logs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin browse spam logs' do
+RSpec.describe 'Admin browse spam logs' do
let!(:spam_log) { create(:spam_log, description: 'abcde ' * 20) }
before do
diff --git a/spec/features/admin/admin_builds_spec.rb b/spec/features/admin/admin_builds_spec.rb
index afdf8eb0cca..85f0c44ed9c 100644
--- a/spec/features/admin/admin_builds_spec.rb
+++ b/spec/features/admin/admin_builds_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin Builds' do
+RSpec.describe 'Admin Builds' do
before do
sign_in(create(:admin))
end
diff --git a/spec/features/admin/admin_disables_git_access_protocol_spec.rb b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
index 05ebb7e90d2..d7feb21a8b3 100644
--- a/spec/features/admin/admin_disables_git_access_protocol_spec.rb
+++ b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin disables Git access protocol', :js do
+RSpec.describe 'Admin disables Git access protocol', :js do
include StubENV
include MobileHelpers
diff --git a/spec/features/admin/admin_disables_two_factor_spec.rb b/spec/features/admin/admin_disables_two_factor_spec.rb
index 7227141168e..216c8ae36c7 100644
--- a/spec/features/admin/admin_disables_two_factor_spec.rb
+++ b/spec/features/admin/admin_disables_two_factor_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin disables 2FA for a user' do
+RSpec.describe 'Admin disables 2FA for a user' do
it 'successfully', :js do
sign_in(create(:admin))
user = create(:user, :two_factor)
diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb
index 1d82650d11d..5b6c1e15917 100644
--- a/spec/features/admin/admin_groups_spec.rb
+++ b/spec/features/admin/admin_groups_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin Groups' do
+RSpec.describe 'Admin Groups' do
include Select2Helper
let(:internal) { Gitlab::VisibilityLevel::INTERNAL }
diff --git a/spec/features/admin/admin_health_check_spec.rb b/spec/features/admin/admin_health_check_spec.rb
index 9ce96fe8020..dfc7f5f6f84 100644
--- a/spec/features/admin/admin_health_check_spec.rb
+++ b/spec/features/admin/admin_health_check_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Admin Health Check", :feature do
+RSpec.describe "Admin Health Check", :feature do
include StubENV
let_it_be(:admin) { create(:admin) }
diff --git a/spec/features/admin/admin_hook_logs_spec.rb b/spec/features/admin/admin_hook_logs_spec.rb
index 98900142353..f4a70621cee 100644
--- a/spec/features/admin/admin_hook_logs_spec.rb
+++ b/spec/features/admin/admin_hook_logs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin::HookLogs' do
+RSpec.describe 'Admin::HookLogs' do
let(:project) { create(:project) }
let(:system_hook) { create(:system_hook) }
let(:hook_log) { create(:web_hook_log, web_hook: system_hook, internal_error_message: 'some error') }
diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb
index 40bcf4a31e4..1c14d65a1cd 100644
--- a/spec/features/admin/admin_hooks_spec.rb
+++ b/spec/features/admin/admin_hooks_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin::Hooks' do
+RSpec.describe 'Admin::Hooks' do
let(:user) { create(:admin) }
before do
diff --git a/spec/features/admin/admin_mode/login_spec.rb b/spec/features/admin/admin_mode/login_spec.rb
index afc6f2ddb56..4b26ceb55e2 100644
--- a/spec/features/admin/admin_mode/login_spec.rb
+++ b/spec/features/admin/admin_mode/login_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin Mode Login', :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
+RSpec.describe 'Admin Mode Login', :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
include TermsHelper
include UserLoginHelper
include LdapHelpers
diff --git a/spec/features/admin/admin_mode/logout_spec.rb b/spec/features/admin/admin_mode/logout_spec.rb
index e1b4aba5724..b4d49fe760f 100644
--- a/spec/features/admin/admin_mode/logout_spec.rb
+++ b/spec/features/admin/admin_mode/logout_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin Mode Logout', :js, :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
+RSpec.describe 'Admin Mode Logout', :js, :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
include TermsHelper
include UserLoginHelper
diff --git a/spec/features/admin/admin_mode/workers_spec.rb b/spec/features/admin/admin_mode/workers_spec.rb
index 0ca61e6c193..d037f5555dc 100644
--- a/spec/features/admin/admin_mode/workers_spec.rb
+++ b/spec/features/admin/admin_mode/workers_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
# Test an operation that triggers background jobs requiring administrative rights
-describe 'Admin mode for workers', :do_not_mock_admin_mode, :request_store, :clean_gitlab_redis_shared_state do
+RSpec.describe 'Admin mode for workers', :do_not_mock_admin_mode, :request_store, :clean_gitlab_redis_shared_state do
let(:user) { create(:user) }
let(:user_to_delete) { create(:user) }
diff --git a/spec/features/admin/admin_mode_spec.rb b/spec/features/admin/admin_mode_spec.rb
index f642d614a5d..3b4edbc1a07 100644
--- a/spec/features/admin/admin_mode_spec.rb
+++ b/spec/features/admin/admin_mode_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin mode', :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
+RSpec.describe 'Admin mode', :clean_gitlab_redis_shared_state, :do_not_mock_admin_mode do
include MobileHelpers
include StubENV
diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb
index d1889d3a89a..cbaa18509ba 100644
--- a/spec/features/admin/admin_projects_spec.rb
+++ b/spec/features/admin/admin_projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Admin::Projects" do
+RSpec.describe "Admin::Projects" do
include Select2Helper
let(:user) { create :user }
diff --git a/spec/features/admin/admin_requests_profiles_spec.rb b/spec/features/admin/admin_requests_profiles_spec.rb
index e93c0ff8b20..c649fdd8e19 100644
--- a/spec/features/admin/admin_requests_profiles_spec.rb
+++ b/spec/features/admin/admin_requests_profiles_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Admin::RequestsProfilesController' do
+RSpec.describe 'Admin::RequestsProfilesController' do
let(:tmpdir) { Dir.mktmpdir('profiler-test') }
before do
diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb
index c21b1e36f9a..921bbbfbe7d 100644
--- a/spec/features/projects/pipeline_schedules_spec.rb
+++ b/spec/features/projects/pipeline_schedules_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Pipeline Schedules', :js do
+RSpec.describe 'Pipeline Schedules', :js do
include PipelineSchedulesHelper
let!(:project) { create(:project, :repository) }
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index de81547887b..c6a002ad18b 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Pipeline', :js do
+RSpec.describe 'Pipeline', :js do
include RoutesHelpers
include ProjectForksHelper
include ::ExclusiveLeaseHelpers
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 7634100347e..8ceef4b4107 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Pipelines', :js do
+RSpec.describe 'Pipelines', :js do
include ProjectForksHelper
let(:project) { create(:project) }
diff --git a/spec/features/projects/raw/user_interacts_with_raw_endpoint_spec.rb b/spec/features/projects/raw/user_interacts_with_raw_endpoint_spec.rb
index 673766073a2..6745eb1a3fb 100644
--- a/spec/features/projects/raw/user_interacts_with_raw_endpoint_spec.rb
+++ b/spec/features/projects/raw/user_interacts_with_raw_endpoint_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Raw > User interacts with raw endpoint' do
+RSpec.describe 'Projects > Raw > User interacts with raw endpoint' do
include RepoHelpers
let(:user) { create(:user) }
diff --git a/spec/features/projects/releases/user_views_edit_release_spec.rb b/spec/features/projects/releases/user_views_edit_release_spec.rb
index 217d6a25a23..4ed1be6db6b 100644
--- a/spec/features/projects/releases/user_views_edit_release_spec.rb
+++ b/spec/features/projects/releases/user_views_edit_release_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User edits Release', :js do
+RSpec.describe 'User edits Release', :js do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:release) { create(:release, project: project, name: 'The first release' ) }
let_it_be(:user) { create(:user) }
diff --git a/spec/features/projects/releases/user_views_release_spec.rb b/spec/features/projects/releases/user_views_release_spec.rb
index 6120acb4f1f..c82588746a8 100644
--- a/spec/features/projects/releases/user_views_release_spec.rb
+++ b/spec/features/projects/releases/user_views_release_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views Release', :js do
+RSpec.describe 'User views Release', :js do
let(:project) { create(:project, :repository) }
let(:release) { create(:release, project: project, name: 'The first release' ) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/releases/user_views_releases_spec.rb b/spec/features/projects/releases/user_views_releases_spec.rb
index b37017ec310..defcb252ce4 100644
--- a/spec/features/projects/releases/user_views_releases_spec.rb
+++ b/spec/features/projects/releases/user_views_releases_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views releases', :js do
+RSpec.describe 'User views releases', :js do
let_it_be(:project) { create(:project, :repository, :private) }
let_it_be(:release) { create(:release, project: project, name: 'The first release' ) }
let_it_be(:maintainer) { create(:user) }
diff --git a/spec/features/projects/remote_mirror_spec.rb b/spec/features/projects/remote_mirror_spec.rb
index d357aabead7..26d27c914cc 100644
--- a/spec/features/projects/remote_mirror_spec.rb
+++ b/spec/features/projects/remote_mirror_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project remote mirror', :feature do
+RSpec.describe 'Project remote mirror', :feature do
let(:project) { create(:project, :repository, :remote_mirror) }
let(:remote_mirror) { project.remote_mirrors.first }
let(:user) { create(:user) }
diff --git a/spec/features/projects/serverless/functions_spec.rb b/spec/features/projects/serverless/functions_spec.rb
index 4c89af29339..a0b06d7e2a1 100644
--- a/spec/features/projects/serverless/functions_spec.rb
+++ b/spec/features/projects/serverless/functions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Functions', :js do
+RSpec.describe 'Functions', :js do
include KubernetesHelpers
include ReactiveCachingHelpers
diff --git a/spec/features/projects/services/disable_triggers_spec.rb b/spec/features/projects/services/disable_triggers_spec.rb
index d07abb94208..34ca5378117 100644
--- a/spec/features/projects/services/disable_triggers_spec.rb
+++ b/spec/features/projects/services/disable_triggers_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Disable individual triggers' do
+RSpec.describe 'Disable individual triggers' do
include_context 'project service activation'
let(:checkbox_selector) { 'input[type=checkbox][id$=_events]' }
diff --git a/spec/features/projects/services/prometheus_external_alerts_spec.rb b/spec/features/projects/services/prometheus_external_alerts_spec.rb
index 1a706f20352..4c32905a8c5 100644
--- a/spec/features/projects/services/prometheus_external_alerts_spec.rb
+++ b/spec/features/projects/services/prometheus_external_alerts_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Prometheus external alerts', :js do
+RSpec.describe 'Prometheus external alerts', :js do
include_context 'project service activation'
let(:alerts_section_selector) { '.js-prometheus-alerts' }
diff --git a/spec/features/projects/services/user_activates_alerts_spec.rb b/spec/features/projects/services/user_activates_alerts_spec.rb
index 47de7fab859..95642f49d61 100644
--- a/spec/features/projects/services/user_activates_alerts_spec.rb
+++ b/spec/features/projects/services/user_activates_alerts_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Alerts', :js do
+RSpec.describe 'User activates Alerts', :js do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
diff --git a/spec/features/projects/services/user_activates_asana_spec.rb b/spec/features/projects/services/user_activates_asana_spec.rb
index dac60fce6e9..3e24d106be0 100644
--- a/spec/features/projects/services/user_activates_asana_spec.rb
+++ b/spec/features/projects/services/user_activates_asana_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Asana' do
+RSpec.describe 'User activates Asana' do
include_context 'project service activation'
it 'activates service', :js do
diff --git a/spec/features/projects/services/user_activates_assembla_spec.rb b/spec/features/projects/services/user_activates_assembla_spec.rb
index 999a95e3e23..2e49f4caa82 100644
--- a/spec/features/projects/services/user_activates_assembla_spec.rb
+++ b/spec/features/projects/services/user_activates_assembla_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Assembla' do
+RSpec.describe 'User activates Assembla' do
include_context 'project service activation'
before do
diff --git a/spec/features/projects/services/user_activates_atlassian_bamboo_ci_spec.rb b/spec/features/projects/services/user_activates_atlassian_bamboo_ci_spec.rb
index 28ed08f71b6..e75f0bafc4b 100644
--- a/spec/features/projects/services/user_activates_atlassian_bamboo_ci_spec.rb
+++ b/spec/features/projects/services/user_activates_atlassian_bamboo_ci_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Atlassian Bamboo CI' do
+RSpec.describe 'User activates Atlassian Bamboo CI' do
include_context 'project service activation'
before do
diff --git a/spec/features/projects/services/user_activates_emails_on_push_spec.rb b/spec/features/projects/services/user_activates_emails_on_push_spec.rb
index 42c069eb29e..40947027146 100644
--- a/spec/features/projects/services/user_activates_emails_on_push_spec.rb
+++ b/spec/features/projects/services/user_activates_emails_on_push_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Emails on push' do
+RSpec.describe 'User activates Emails on push' do
include_context 'project service activation'
it 'activates service', :js do
diff --git a/spec/features/projects/services/user_activates_flowdock_spec.rb b/spec/features/projects/services/user_activates_flowdock_spec.rb
index 4762363b3fe..9581d718400 100644
--- a/spec/features/projects/services/user_activates_flowdock_spec.rb
+++ b/spec/features/projects/services/user_activates_flowdock_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Flowdock' do
+RSpec.describe 'User activates Flowdock' do
include_context 'project service activation' do
let(:project) { create(:project, :repository) }
end
diff --git a/spec/features/projects/services/user_activates_hipchat_spec.rb b/spec/features/projects/services/user_activates_hipchat_spec.rb
index 2fb056f3533..a2820c4bb0f 100644
--- a/spec/features/projects/services/user_activates_hipchat_spec.rb
+++ b/spec/features/projects/services/user_activates_hipchat_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates HipChat', :js do
+RSpec.describe 'User activates HipChat', :js do
include_context 'project service activation'
context 'with standart settings' do
diff --git a/spec/features/projects/services/user_activates_irker_spec.rb b/spec/features/projects/services/user_activates_irker_spec.rb
index 56df403499c..fad40fa6085 100644
--- a/spec/features/projects/services/user_activates_irker_spec.rb
+++ b/spec/features/projects/services/user_activates_irker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Irker (IRC gateway)' do
+RSpec.describe 'User activates Irker (IRC gateway)' do
include_context 'project service activation'
it 'activates service', :js do
diff --git a/spec/features/projects/services/user_activates_issue_tracker_spec.rb b/spec/features/projects/services/user_activates_issue_tracker_spec.rb
index 3c5005d0c0c..a2a2604c610 100644
--- a/spec/features/projects/services/user_activates_issue_tracker_spec.rb
+++ b/spec/features/projects/services/user_activates_issue_tracker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates issue tracker', :js do
+RSpec.describe 'User activates issue tracker', :js do
include_context 'project service activation'
let(:url) { 'http://tracker.example.com' }
diff --git a/spec/features/projects/services/user_activates_jetbrains_teamcity_ci_spec.rb b/spec/features/projects/services/user_activates_jetbrains_teamcity_ci_spec.rb
index 8c84a81ac89..99fcf440a82 100644
--- a/spec/features/projects/services/user_activates_jetbrains_teamcity_ci_spec.rb
+++ b/spec/features/projects/services/user_activates_jetbrains_teamcity_ci_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates JetBrains TeamCity CI' do
+RSpec.describe 'User activates JetBrains TeamCity CI' do
include_context 'project service activation'
before do
diff --git a/spec/features/projects/services/user_activates_jira_spec.rb b/spec/features/projects/services/user_activates_jira_spec.rb
index a14dbf9c14d..1da8a49699b 100644
--- a/spec/features/projects/services/user_activates_jira_spec.rb
+++ b/spec/features/projects/services/user_activates_jira_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Jira', :js do
+RSpec.describe 'User activates Jira', :js do
include_context 'project service activation'
let(:url) { 'http://jira.example.com' }
diff --git a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb
index c6825ee663a..a6b4aaccfb5 100644
--- a/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb
+++ b/spec/features/projects/services/user_activates_mattermost_slash_command_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Set up Mattermost slash commands', :js do
+RSpec.describe 'Set up Mattermost slash commands', :js do
describe 'user visits the mattermost slash command config page' do
include_context 'project service activation'
diff --git a/spec/features/projects/services/user_activates_packagist_spec.rb b/spec/features/projects/services/user_activates_packagist_spec.rb
index 274f293ebf3..70cf612bb2a 100644
--- a/spec/features/projects/services/user_activates_packagist_spec.rb
+++ b/spec/features/projects/services/user_activates_packagist_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Packagist' do
+RSpec.describe 'User activates Packagist' do
include_context 'project service activation'
before do
diff --git a/spec/features/projects/services/user_activates_pivotaltracker_spec.rb b/spec/features/projects/services/user_activates_pivotaltracker_spec.rb
index c81c5081867..8e99c6e303b 100644
--- a/spec/features/projects/services/user_activates_pivotaltracker_spec.rb
+++ b/spec/features/projects/services/user_activates_pivotaltracker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates PivotalTracker' do
+RSpec.describe 'User activates PivotalTracker' do
include_context 'project service activation'
before do
diff --git a/spec/features/projects/services/user_activates_prometheus_spec.rb b/spec/features/projects/services/user_activates_prometheus_spec.rb
index 76dc7d1bbc8..89b1f447c32 100644
--- a/spec/features/projects/services/user_activates_prometheus_spec.rb
+++ b/spec/features/projects/services/user_activates_prometheus_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Prometheus' do
+RSpec.describe 'User activates Prometheus' do
include_context 'project service activation'
before do
diff --git a/spec/features/projects/services/user_activates_pushover_spec.rb b/spec/features/projects/services/user_activates_pushover_spec.rb
index 62e03e68aee..789cc30a42e 100644
--- a/spec/features/projects/services/user_activates_pushover_spec.rb
+++ b/spec/features/projects/services/user_activates_pushover_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Pushover' do
+RSpec.describe 'User activates Pushover' do
include_context 'project service activation'
before do
diff --git a/spec/features/projects/services/user_activates_slack_notifications_spec.rb b/spec/features/projects/services/user_activates_slack_notifications_spec.rb
index 12f15699e26..3005548617a 100644
--- a/spec/features/projects/services/user_activates_slack_notifications_spec.rb
+++ b/spec/features/projects/services/user_activates_slack_notifications_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User activates Slack notifications' do
+RSpec.describe 'User activates Slack notifications' do
include_context 'project service activation'
context 'when service is not configured yet' do
diff --git a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb
index 05f1a0c6b17..c3ccbee4a2f 100644
--- a/spec/features/projects/services/user_activates_slack_slash_command_spec.rb
+++ b/spec/features/projects/services/user_activates_slack_slash_command_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Slack slash commands' do
+RSpec.describe 'Slack slash commands' do
include_context 'project service activation'
before do
diff --git a/spec/features/projects/services/user_views_services_spec.rb b/spec/features/projects/services/user_views_services_spec.rb
index 6df0123c30a..fef6b7bd991 100644
--- a/spec/features/projects/services/user_views_services_spec.rb
+++ b/spec/features/projects/services/user_views_services_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views services' do
+RSpec.describe 'User views services' do
include_context 'project service activation'
it 'shows the list of available services' do
diff --git a/spec/features/projects/settings/access_tokens_spec.rb b/spec/features/projects/settings/access_tokens_spec.rb
index 9a8a8e38164..45fe19deb8e 100644
--- a/spec/features/projects/settings/access_tokens_spec.rb
+++ b/spec/features/projects/settings/access_tokens_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project > Settings > Access Tokens', :js do
+RSpec.describe 'Project > Settings > Access Tokens', :js do
let_it_be(:user) { create(:user) }
let_it_be(:bot_user) { create(:user, :project_bot) }
let_it_be(:project) { create(:project) }
diff --git a/spec/features/projects/settings/external_authorization_service_settings_spec.rb b/spec/features/projects/settings/external_authorization_service_settings_spec.rb
index 31b2892cf6f..c236c85b773 100644
--- a/spec/features/projects/settings/external_authorization_service_settings_spec.rb
+++ b/spec/features/projects/settings/external_authorization_service_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > External Authorization Classification Label setting' do
+RSpec.describe 'Projects > Settings > External Authorization Classification Label setting' do
let(:user) { create(:user) }
let(:project) { create(:project_empty_repo) }
diff --git a/spec/features/projects/settings/forked_project_settings_spec.rb b/spec/features/projects/settings/forked_project_settings_spec.rb
index a2c6dd8e288..f6c25d483ad 100644
--- a/spec/features/projects/settings/forked_project_settings_spec.rb
+++ b/spec/features/projects/settings/forked_project_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > For a forked project', :js do
+RSpec.describe 'Projects > Settings > For a forked project', :js do
include ProjectForksHelper
let(:user) { create(:user) }
let(:original_project) { create(:project) }
diff --git a/spec/features/projects/settings/lfs_settings_spec.rb b/spec/features/projects/settings/lfs_settings_spec.rb
index 5fa3b9bba55..6e1be3c7e51 100644
--- a/spec/features/projects/settings/lfs_settings_spec.rb
+++ b/spec/features/projects/settings/lfs_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > LFS settings' do
+RSpec.describe 'Projects > Settings > LFS settings' do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:role) { :maintainer }
diff --git a/spec/features/projects/settings/operations_settings_spec.rb b/spec/features/projects/settings/operations_settings_spec.rb
index 752353cf2f5..dfbb6342173 100644
--- a/spec/features/projects/settings/operations_settings_spec.rb
+++ b/spec/features/projects/settings/operations_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > For a forked project', :js do
+RSpec.describe 'Projects > Settings > For a forked project', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, create_templates: :issue) }
let(:role) { :maintainer }
diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb
index 87e467571e6..0358acc8dcc 100644
--- a/spec/features/projects/settings/pipelines_settings_spec.rb
+++ b/spec/features/projects/settings/pipelines_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Projects > Settings > Pipelines settings" do
+RSpec.describe "Projects > Settings > Pipelines settings" do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:role) { :developer }
diff --git a/spec/features/projects/settings/project_badges_spec.rb b/spec/features/projects/settings/project_badges_spec.rb
index c419bb1868c..2c26168e3c0 100644
--- a/spec/features/projects/settings/project_badges_spec.rb
+++ b/spec/features/projects/settings/project_badges_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project Badges' do
+RSpec.describe 'Project Badges' do
include WaitForRequests
let(:user) { create(:user) }
diff --git a/spec/features/projects/settings/project_settings_spec.rb b/spec/features/projects/settings/project_settings_spec.rb
index 171c7920878..7b2b5594c22 100644
--- a/spec/features/projects/settings/project_settings_spec.rb
+++ b/spec/features/projects/settings/project_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects settings' do
+RSpec.describe 'Projects settings' do
let_it_be(:project) { create(:project) }
let(:user) { project.owner }
let(:panel) { find('.general-settings', match: :first) }
diff --git a/spec/features/projects/settings/registry_settings_spec.rb b/spec/features/projects/settings/registry_settings_spec.rb
index ba92e8bc516..f78438a75f3 100644
--- a/spec/features/projects/settings/registry_settings_spec.rb
+++ b/spec/features/projects/settings/registry_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project > Settings > CI/CD > Container registry tag expiration policy', :js do
+RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration policy', :js do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace, container_registry_enabled: container_registry_enabled) }
let(:container_registry_enabled) { true }
diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb
index b8baaa3e963..8beecedf85f 100644
--- a/spec/features/projects/settings/repository_settings_spec.rb
+++ b/spec/features/projects/settings/repository_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > Repository settings' do
+RSpec.describe 'Projects > Settings > Repository settings' do
let(:project) { create(:project_empty_repo) }
let(:user) { create(:user) }
let(:role) { :developer }
diff --git a/spec/features/projects/settings/user_archives_project_spec.rb b/spec/features/projects/settings/user_archives_project_spec.rb
index 7667fad7b03..03ea9e7c580 100644
--- a/spec/features/projects/settings/user_archives_project_spec.rb
+++ b/spec/features/projects/settings/user_archives_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > User archives a project' do
+RSpec.describe 'Projects > Settings > User archives a project' do
let(:user) { create(:user) }
before do
diff --git a/spec/features/projects/settings/user_changes_avatar_spec.rb b/spec/features/projects/settings/user_changes_avatar_spec.rb
index 67789b869da..92d5b4c1fcd 100644
--- a/spec/features/projects/settings/user_changes_avatar_spec.rb
+++ b/spec/features/projects/settings/user_changes_avatar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > User changes avatar' do
+RSpec.describe 'Projects > Settings > User changes avatar' do
let(:project) { create(:project, :repository) }
let(:user) { project.creator }
diff --git a/spec/features/projects/settings/user_changes_default_branch_spec.rb b/spec/features/projects/settings/user_changes_default_branch_spec.rb
index 411fc0c7e07..84e6c50cf61 100644
--- a/spec/features/projects/settings/user_changes_default_branch_spec.rb
+++ b/spec/features/projects/settings/user_changes_default_branch_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > User changes default branch' do
+RSpec.describe 'Projects > Settings > User changes default branch' do
include Select2Helper
let(:user) { create(:user) }
diff --git a/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb b/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb
index 45a16fda2cb..ba504624823 100644
--- a/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb
+++ b/spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User interacts with deploy keys", :js do
+RSpec.describe "User interacts with deploy keys", :js do
let(:project) { create(:project, :repository) }
let(:user) { project.owner }
diff --git a/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
index c0089e3c28c..3fc1f47d98a 100644
--- a/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
+++ b/spec/features/projects/settings/user_manages_merge_requests_settings_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe 'Projects > Settings > User manages merge request settings' do
+RSpec.describe 'Projects > Settings > User manages merge request settings' do
let(:user) { create(:user) }
let(:project) { create(:project, :public, namespace: user.namespace, path: 'gitlab', name: 'sample') }
diff --git a/spec/features/projects/settings/user_manages_project_members_spec.rb b/spec/features/projects/settings/user_manages_project_members_spec.rb
index 705c60f15ee..d32f4cb8ec7 100644
--- a/spec/features/projects/settings/user_manages_project_members_spec.rb
+++ b/spec/features/projects/settings/user_manages_project_members_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > User manages project members' do
+RSpec.describe 'Projects > Settings > User manages project members' do
let(:group) { create(:group, name: 'OpenSource') }
let(:project) { create(:project) }
let(:project2) { create(:project) }
diff --git a/spec/features/projects/settings/user_renames_a_project_spec.rb b/spec/features/projects/settings/user_renames_a_project_spec.rb
index 789c5e31748..6088ea31661 100644
--- a/spec/features/projects/settings/user_renames_a_project_spec.rb
+++ b/spec/features/projects/settings/user_renames_a_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > User renames a project' do
+RSpec.describe 'Projects > Settings > User renames a project' do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace, path: 'gitlab', name: 'sample') }
diff --git a/spec/features/projects/settings/user_sees_revoke_deploy_token_modal_spec.rb b/spec/features/projects/settings/user_sees_revoke_deploy_token_modal_spec.rb
index 0abc4b41a2b..d0f297d2067 100644
--- a/spec/features/projects/settings/user_sees_revoke_deploy_token_modal_spec.rb
+++ b/spec/features/projects/settings/user_sees_revoke_deploy_token_modal_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Repository Settings > User sees revoke deploy token modal', :js do
+RSpec.describe 'Repository Settings > User sees revoke deploy token modal', :js do
let(:project) { create(:project, :public, :repository) }
let(:user) { project.creator }
let(:role) { :developer }
diff --git a/spec/features/projects/settings/user_tags_project_spec.rb b/spec/features/projects/settings/user_tags_project_spec.rb
index a919dd0e4af..ff19ed22744 100644
--- a/spec/features/projects/settings/user_tags_project_spec.rb
+++ b/spec/features/projects/settings/user_tags_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > User tags a project' do
+RSpec.describe 'Projects > Settings > User tags a project' do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
diff --git a/spec/features/projects/settings/user_transfers_a_project_spec.rb b/spec/features/projects/settings/user_transfers_a_project_spec.rb
index 8989eac77b5..ba4c379ef0a 100644
--- a/spec/features/projects/settings/user_transfers_a_project_spec.rb
+++ b/spec/features/projects/settings/user_transfers_a_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > User transfers a project', :js do
+RSpec.describe 'Projects > Settings > User transfers a project', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, namespace: user.namespace) }
let(:group) { create(:group) }
diff --git a/spec/features/projects/settings/visibility_settings_spec.rb b/spec/features/projects/settings/visibility_settings_spec.rb
index a2b36874aea..6cecbbdb3d0 100644
--- a/spec/features/projects/settings/visibility_settings_spec.rb
+++ b/spec/features/projects/settings/visibility_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > Visibility settings', :js do
+RSpec.describe 'Projects > Settings > Visibility settings', :js do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace, visibility_level: 20) }
diff --git a/spec/features/projects/settings/webhooks_settings_spec.rb b/spec/features/projects/settings/webhooks_settings_spec.rb
index 7e22117c63c..d184f08bd89 100644
--- a/spec/features/projects/settings/webhooks_settings_spec.rb
+++ b/spec/features/projects/settings/webhooks_settings_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Settings > Webhook Settings' do
+RSpec.describe 'Projects > Settings > Webhook Settings' do
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:webhooks_path) { project_hooks_path(project) }
diff --git a/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb b/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb
index 70dc6c966ba..8d239cb2cbf 100644
--- a/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb
+++ b/spec/features/projects/show/developer_views_empty_project_instructions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > Developer views empty project instructions' do
+RSpec.describe 'Projects > Show > Developer views empty project instructions' do
let(:project) { create(:project, :empty_repo) }
let(:developer) { create(:user) }
diff --git a/spec/features/projects/show/download_buttons_spec.rb b/spec/features/projects/show/download_buttons_spec.rb
index 0d609069426..e73bb3198e6 100644
--- a/spec/features/projects/show/download_buttons_spec.rb
+++ b/spec/features/projects/show/download_buttons_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > Download buttons' do
+RSpec.describe 'Projects > Show > Download buttons' do
let(:user) { create(:user) }
let(:role) { :developer }
let(:status) { 'success' }
diff --git a/spec/features/projects/show/no_password_spec.rb b/spec/features/projects/show/no_password_spec.rb
index 0048b1bf017..79cd65e5406 100644
--- a/spec/features/projects/show/no_password_spec.rb
+++ b/spec/features/projects/show/no_password_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'No Password Alert' do
+RSpec.describe 'No Password Alert' do
let(:project) { create(:project, :repository, namespace: user.namespace) }
context 'with internal auth enabled' do
diff --git a/spec/features/projects/show/redirects_spec.rb b/spec/features/projects/show/redirects_spec.rb
index 1b579ab0121..659edda5672 100644
--- a/spec/features/projects/show/redirects_spec.rb
+++ b/spec/features/projects/show/redirects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > Redirects' do
+RSpec.describe 'Projects > Show > Redirects' do
let(:user) { create :user }
let(:public_project) { create :project, :public }
let(:private_project) { create :project, :private }
diff --git a/spec/features/projects/show/rss_spec.rb b/spec/features/projects/show/rss_spec.rb
index 4fe1fde5bdd..0bd6e9cbe3b 100644
--- a/spec/features/projects/show/rss_spec.rb
+++ b/spec/features/projects/show/rss_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > RSS' do
+RSpec.describe 'Projects > Show > RSS' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
let(:path) { project_path(project) }
diff --git a/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb b/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb
index df63856492e..59f1bc94226 100644
--- a/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb
+++ b/spec/features/projects/show/user_interacts_with_auto_devops_banner_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project > Show > User interacts with auto devops implicitly enabled banner' do
+RSpec.describe 'Project > Show > User interacts with auto devops implicitly enabled banner' do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/show/user_interacts_with_stars_spec.rb b/spec/features/projects/show/user_interacts_with_stars_spec.rb
index e4cd8294f7a..99f84c19bf3 100644
--- a/spec/features/projects/show/user_interacts_with_stars_spec.rb
+++ b/spec/features/projects/show/user_interacts_with_stars_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User interacts with project stars' do
+RSpec.describe 'Projects > Show > User interacts with project stars' do
let(:project) { create(:project, :public, :repository) }
context 'when user is signed in', :js do
diff --git a/spec/features/projects/show/user_manages_notifications_spec.rb b/spec/features/projects/show/user_manages_notifications_spec.rb
index 0cd6743304e..58a2c793b7b 100644
--- a/spec/features/projects/show/user_manages_notifications_spec.rb
+++ b/spec/features/projects/show/user_manages_notifications_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User manages notifications', :js do
+RSpec.describe 'Projects > Show > User manages notifications', :js do
let(:project) { create(:project, :public, :repository) }
before do
diff --git a/spec/features/projects/show/user_sees_collaboration_links_spec.rb b/spec/features/projects/show/user_sees_collaboration_links_spec.rb
index 63fcec4f9b3..ffdfbb9fe81 100644
--- a/spec/features/projects/show/user_sees_collaboration_links_spec.rb
+++ b/spec/features/projects/show/user_sees_collaboration_links_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > Collaboration links', :js do
+RSpec.describe 'Projects > Show > Collaboration links', :js do
using RSpec::Parameterized::TableSyntax
let(:project) { create(:project, :repository, :public) }
diff --git a/spec/features/projects/show/user_sees_deletion_failure_message_spec.rb b/spec/features/projects/show/user_sees_deletion_failure_message_spec.rb
index bdd0ab688f0..5e878411f6a 100644
--- a/spec/features/projects/show/user_sees_deletion_failure_message_spec.rb
+++ b/spec/features/projects/show/user_sees_deletion_failure_message_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User sees a deletion failure message' do
+RSpec.describe 'Projects > Show > User sees a deletion failure message' do
let(:project) { create(:project, :empty_repo, pending_delete: true) }
before do
diff --git a/spec/features/projects/show/user_sees_git_instructions_spec.rb b/spec/features/projects/show/user_sees_git_instructions_spec.rb
index 0c486056329..a35f6420bdc 100644
--- a/spec/features/projects/show/user_sees_git_instructions_spec.rb
+++ b/spec/features/projects/show/user_sees_git_instructions_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User sees Git instructions' do
+RSpec.describe 'Projects > Show > User sees Git instructions' do
let_it_be(:user) { create(:user) }
shared_examples_for 'redirects to the sign in page' do
diff --git a/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb b/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb
index c0fcd10f394..0aa0f7754c6 100644
--- a/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb
+++ b/spec/features/projects/show/user_sees_last_commit_ci_status_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User sees last commit CI status' do
+RSpec.describe 'Projects > Show > User sees last commit CI status' do
let_it_be(:project) { create(:project, :repository, :public) }
it 'shows the project README', :js do
diff --git a/spec/features/projects/show/user_sees_readme_spec.rb b/spec/features/projects/show/user_sees_readme_spec.rb
index 52745b06cd3..250f707948e 100644
--- a/spec/features/projects/show/user_sees_readme_spec.rb
+++ b/spec/features/projects/show/user_sees_readme_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User sees README' do
+RSpec.describe 'Projects > Show > User sees README' do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository, :public) }
diff --git a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
index 8e20facda15..0f10b0a4010 100644
--- a/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
+++ b/spec/features/projects/show/user_sees_setup_shortcut_buttons_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User sees setup shortcut buttons' do
+RSpec.describe 'Projects > Show > User sees setup shortcut buttons' do
# For "New file", "Add license" functionality,
# see spec/features/projects/files/project_owner_creates_license_file_spec.rb
# see spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb
diff --git a/spec/features/projects/show/user_uploads_files_spec.rb b/spec/features/projects/show/user_uploads_files_spec.rb
index e279cdf92da..053598a528e 100644
--- a/spec/features/projects/show/user_uploads_files_spec.rb
+++ b/spec/features/projects/show/user_uploads_files_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Show > User uploads files' do
+RSpec.describe 'Projects > Show > User uploads files' do
include DropzoneHelper
let(:user) { create(:user) }
diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb
index 1e8f9fa0875..73d033cbdb8 100644
--- a/spec/features/projects/snippets/create_snippet_spec.rb
+++ b/spec/features/projects/snippets/create_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-shared_examples_for 'snippet editor' do
+RSpec.shared_examples_for 'snippet editor' do
before do
stub_feature_flags(snippets_edit_vue: false)
end
@@ -138,7 +138,7 @@ shared_examples_for 'snippet editor' do
end
end
-describe 'Projects > Snippets > Create Snippet', :js do
+RSpec.describe 'Projects > Snippets > Create Snippet', :js do
include DropzoneHelper
let_it_be(:user) { create(:user) }
diff --git a/spec/features/projects/snippets/show_spec.rb b/spec/features/projects/snippets/show_spec.rb
index 9be226c017f..0f6429d49f6 100644
--- a/spec/features/projects/snippets/show_spec.rb
+++ b/spec/features/projects/snippets/show_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Snippets > Project snippet', :js do
+RSpec.describe 'Projects > Snippets > Project snippet', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:snippet) { create(:project_snippet, project: project, file_name: file_name, content: content) }
diff --git a/spec/features/projects/snippets/user_comments_on_snippet_spec.rb b/spec/features/projects/snippets/user_comments_on_snippet_spec.rb
index a7a220b926d..2784fec3dc1 100644
--- a/spec/features/projects/snippets/user_comments_on_snippet_spec.rb
+++ b/spec/features/projects/snippets/user_comments_on_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Snippets > User comments on a snippet', :js do
+RSpec.describe 'Projects > Snippets > User comments on a snippet', :js do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
let_it_be(:snippet) { create(:project_snippet, :repository, project: project, author: user) }
diff --git a/spec/features/projects/snippets/user_deletes_snippet_spec.rb b/spec/features/projects/snippets/user_deletes_snippet_spec.rb
index 7e337710e19..44fe9834484 100644
--- a/spec/features/projects/snippets/user_deletes_snippet_spec.rb
+++ b/spec/features/projects/snippets/user_deletes_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Snippets > User deletes a snippet' do
+RSpec.describe 'Projects > Snippets > User deletes a snippet' do
let(:project) { create(:project) }
let!(:snippet) { create(:project_snippet, project: project, author: user) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/snippets/user_updates_snippet_spec.rb b/spec/features/projects/snippets/user_updates_snippet_spec.rb
index d19fe9e8d38..a40113bd93e 100644
--- a/spec/features/projects/snippets/user_updates_snippet_spec.rb
+++ b/spec/features/projects/snippets/user_updates_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Snippets > User updates a snippet', :js do
+RSpec.describe 'Projects > Snippets > User updates a snippet', :js do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, namespace: user.namespace) }
let_it_be(:snippet, reload: true) { create(:project_snippet, :repository, project: project, author: user) }
diff --git a/spec/features/projects/snippets/user_views_snippets_spec.rb b/spec/features/projects/snippets/user_views_snippets_spec.rb
index 22910029ee5..bc8cba1dc31 100644
--- a/spec/features/projects/snippets/user_views_snippets_spec.rb
+++ b/spec/features/projects/snippets/user_views_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Snippets > User views snippets' do
+RSpec.describe 'Projects > Snippets > User views snippets' do
let_it_be(:project) { create(:project) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/sourcegraph_csp_spec.rb b/spec/features/projects/sourcegraph_csp_spec.rb
index f252d3cd027..25d27462aa9 100644
--- a/spec/features/projects/sourcegraph_csp_spec.rb
+++ b/spec/features/projects/sourcegraph_csp_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Sourcegraph Content Security Policy' do
+RSpec.describe 'Sourcegraph Content Security Policy' do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository, namespace: user.namespace) }
diff --git a/spec/features/projects/sub_group_issuables_spec.rb b/spec/features/projects/sub_group_issuables_spec.rb
index d6faec2078d..8c1d88276df 100644
--- a/spec/features/projects/sub_group_issuables_spec.rb
+++ b/spec/features/projects/sub_group_issuables_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Subgroup Issuables', :js do
+RSpec.describe 'Subgroup Issuables', :js do
let!(:group) { create(:group, name: 'group') }
let!(:subgroup) { create(:group, parent: group, name: 'subgroup') }
let!(:project) { create(:project, namespace: subgroup, name: 'project') }
diff --git a/spec/features/projects/tags/download_buttons_spec.rb b/spec/features/projects/tags/download_buttons_spec.rb
index 64141cf5dc9..0f1f72fd039 100644
--- a/spec/features/projects/tags/download_buttons_spec.rb
+++ b/spec/features/projects/tags/download_buttons_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Download buttons in tags page' do
+RSpec.describe 'Download buttons in tags page' do
let(:user) { create(:user) }
let(:role) { :developer }
let(:status) { 'success' }
diff --git a/spec/features/projects/tags/user_edits_tags_spec.rb b/spec/features/projects/tags/user_edits_tags_spec.rb
index 6388875a619..7a8a685f3d9 100644
--- a/spec/features/projects/tags/user_edits_tags_spec.rb
+++ b/spec/features/projects/tags/user_edits_tags_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project > Tags', :js do
+RSpec.describe 'Project > Tags', :js do
include DropzoneHelper
let(:user) { create(:user) }
diff --git a/spec/features/projects/tags/user_views_tags_spec.rb b/spec/features/projects/tags/user_views_tags_spec.rb
index 7b49b0d0f65..ef363ab6158 100644
--- a/spec/features/projects/tags/user_views_tags_spec.rb
+++ b/spec/features/projects/tags/user_views_tags_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-describe 'User views tags', :feature do
+RSpec.describe 'User views tags', :feature do
context 'rss' do
shared_examples 'has access to the tags RSS feed' do
it do
diff --git a/spec/features/projects/tree/create_directory_spec.rb b/spec/features/projects/tree/create_directory_spec.rb
index 829b01832df..54b081161e5 100644
--- a/spec/features/projects/tree/create_directory_spec.rb
+++ b/spec/features/projects/tree/create_directory_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Multi-file editor new directory', :js do
+RSpec.describe 'Multi-file editor new directory', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
diff --git a/spec/features/projects/tree/create_file_spec.rb b/spec/features/projects/tree/create_file_spec.rb
index 58ff623c9ae..cefb84e6f5e 100644
--- a/spec/features/projects/tree/create_file_spec.rb
+++ b/spec/features/projects/tree/create_file_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Multi-file editor new file', :js do
+RSpec.describe 'Multi-file editor new file', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
diff --git a/spec/features/projects/tree/rss_spec.rb b/spec/features/projects/tree/rss_spec.rb
index 4300574210f..efbfc329c9f 100644
--- a/spec/features/projects/tree/rss_spec.rb
+++ b/spec/features/projects/tree/rss_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project Tree RSS' do
+RSpec.describe 'Project Tree RSS' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
let(:path) { project_tree_path(project, :master) }
diff --git a/spec/features/projects/tree/tree_show_spec.rb b/spec/features/projects/tree/tree_show_spec.rb
index 5305936a12f..388fa39874d 100644
--- a/spec/features/projects/tree/tree_show_spec.rb
+++ b/spec/features/projects/tree/tree_show_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects tree', :js do
+RSpec.describe 'Projects tree', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:gravatar_enabled) { true }
diff --git a/spec/features/projects/tree/upload_file_spec.rb b/spec/features/projects/tree/upload_file_spec.rb
index 38c29263b1e..ce00483bc91 100644
--- a/spec/features/projects/tree/upload_file_spec.rb
+++ b/spec/features/projects/tree/upload_file_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Multi-file editor upload file', :js do
+RSpec.describe 'Multi-file editor upload file', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:txt_file) { File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt') }
diff --git a/spec/features/projects/user_changes_project_visibility_spec.rb b/spec/features/projects/user_changes_project_visibility_spec.rb
index 31da4140d35..6935ad4be02 100644
--- a/spec/features/projects/user_changes_project_visibility_spec.rb
+++ b/spec/features/projects/user_changes_project_visibility_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User changes public project visibility', :js do
+RSpec.describe 'User changes public project visibility', :js do
include ProjectForksHelper
before do
diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb
index 361367f1a3d..b204ae76e07 100644
--- a/spec/features/projects/user_creates_project_spec.rb
+++ b/spec/features/projects/user_creates_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User creates a project', :js do
+RSpec.describe 'User creates a project', :js do
let(:user) { create(:user) }
before do
diff --git a/spec/features/projects/user_sees_sidebar_spec.rb b/spec/features/projects/user_sees_sidebar_spec.rb
index 4226cdcc759..cc2a9eacbad 100644
--- a/spec/features/projects/user_sees_sidebar_spec.rb
+++ b/spec/features/projects/user_sees_sidebar_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > User sees sidebar' do
+RSpec.describe 'Projects > User sees sidebar' do
let(:user) { create(:user) }
let(:project) { create(:project, :private, public_builds: false, namespace: user.namespace) }
diff --git a/spec/features/projects/user_sees_user_popover_spec.rb b/spec/features/projects/user_sees_user_popover_spec.rb
index 6197460776d..851ce79e1c6 100644
--- a/spec/features/projects/user_sees_user_popover_spec.rb
+++ b/spec/features/projects/user_sees_user_popover_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User sees user popover', :js do
+RSpec.describe 'User sees user popover', :js do
include Spec::Support::Helpers::Features::NotesHelpers
let_it_be(:project) { create(:project, :repository) }
diff --git a/spec/features/projects/user_uses_shortcuts_spec.rb b/spec/features/projects/user_uses_shortcuts_spec.rb
index 2d629ef538a..8fa5f741a95 100644
--- a/spec/features/projects/user_uses_shortcuts_spec.rb
+++ b/spec/features/projects/user_uses_shortcuts_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User uses shortcuts', :js do
+RSpec.describe 'User uses shortcuts', :js do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/user_views_empty_project_spec.rb b/spec/features/projects/user_views_empty_project_spec.rb
index cb6b63d4dd5..9202d18b86f 100644
--- a/spec/features/projects/user_views_empty_project_spec.rb
+++ b/spec/features/projects/user_views_empty_project_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views an empty project' do
+RSpec.describe 'User views an empty project' do
let(:project) { create(:project, :empty_repo) }
let(:user) { create(:user) }
diff --git a/spec/features/projects/view_on_env_spec.rb b/spec/features/projects/view_on_env_spec.rb
index 845c7b89a71..6f78f888c12 100644
--- a/spec/features/projects/view_on_env_spec.rb
+++ b/spec/features/projects/view_on_env_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'View on environment', :js do
+RSpec.describe 'View on environment', :js do
let(:branch_name) { 'feature' }
let(:file_path) { 'files/ruby/feature.rb' }
let(:project) { create(:project, :repository) }
diff --git a/spec/features/projects/wiki/markdown_preview_spec.rb b/spec/features/projects/wiki/markdown_preview_spec.rb
index bc567d4db42..8eba2c98595 100644
--- a/spec/features/projects/wiki/markdown_preview_spec.rb
+++ b/spec/features/projects/wiki/markdown_preview_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Wiki > User previews markdown changes', :js do
+RSpec.describe 'Projects > Wiki > User previews markdown changes', :js do
let_it_be(:user) { create(:user) }
let(:project) { create(:project, :wiki_repo, namespace: user.namespace) }
let(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'home', content: '[some link](other-page)') }
diff --git a/spec/features/projects/wiki/shortcuts_spec.rb b/spec/features/projects/wiki/shortcuts_spec.rb
index c51af2526c9..170e7afb51f 100644
--- a/spec/features/projects/wiki/shortcuts_spec.rb
+++ b/spec/features/projects/wiki/shortcuts_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Wiki shortcuts', :js do
+RSpec.describe 'Wiki shortcuts', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :wiki_repo, namespace: user.namespace) }
let(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'home', content: 'Home page') }
diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
index 5678ebcb72a..eba1b63765a 100644
--- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-describe "User creates wiki page" do
+RSpec.describe "User creates wiki page" do
include WikiHelpers
let(:user) { create(:user) }
diff --git a/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb b/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb
index 38e5e292064..a5d865d581b 100644
--- a/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User deletes wiki page', :js do
+RSpec.describe 'User deletes wiki page', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :wiki_repo, namespace: user.namespace) }
let(:wiki_page) { create(:wiki_page, wiki: project.wiki) }
diff --git a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb b/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
index 6c6af1c41d2..83679c6bd1d 100644
--- a/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_git_access_wiki_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Wiki > User views Git access wiki page' do
+RSpec.describe 'Projects > Wiki > User views Git access wiki page' do
let(:user) { create(:user) }
let(:project) { create(:project, :wiki_repo, :public) }
let(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'home', content: '[some link](other-page)') }
diff --git a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
index 55509ddfa10..3191afe0e06 100644
--- a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User updates wiki page' do
+RSpec.describe 'User updates wiki page' do
include WikiHelpers
let(:user) { create(:user) }
diff --git a/spec/features/projects/wiki/user_views_wiki_empty_spec.rb b/spec/features/projects/wiki/user_views_wiki_empty_spec.rb
index ab0f9b750d2..0c9512734d8 100644
--- a/spec/features/projects/wiki/user_views_wiki_empty_spec.rb
+++ b/spec/features/projects/wiki/user_views_wiki_empty_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views empty wiki' do
+RSpec.describe 'User views empty wiki' do
let(:user) { create(:user) }
shared_examples 'empty wiki and accessible issues' do
diff --git a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb
index cb425e8b704..30b94495e3d 100644
--- a/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb
+++ b/spec/features/projects/wiki/user_views_wiki_in_project_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Projects > Wiki > User views wiki in project page' do
+RSpec.describe 'Projects > Wiki > User views wiki in project page' do
let(:user) { create(:user) }
before do
diff --git a/spec/features/projects/wiki/user_views_wiki_page_spec.rb b/spec/features/projects/wiki/user_views_wiki_page_spec.rb
index e379e7466db..59ccb83a9bb 100644
--- a/spec/features/projects/wiki/user_views_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_views_wiki_page_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views a wiki page' do
+RSpec.describe 'User views a wiki page' do
include WikiHelpers
let(:user) { create(:user) }
diff --git a/spec/features/projects/wiki/user_views_wiki_pages_spec.rb b/spec/features/projects/wiki/user_views_wiki_pages_spec.rb
index 584b2a76143..fea913b8212 100644
--- a/spec/features/projects/wiki/user_views_wiki_pages_spec.rb
+++ b/spec/features/projects/wiki/user_views_wiki_pages_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views wiki pages' do
+RSpec.describe 'User views wiki pages' do
include WikiHelpers
let(:user) { create(:user) }
diff --git a/spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb b/spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb
index 014b63fa154..5c45e34595f 100644
--- a/spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb
+++ b/spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User views AsciiDoc page with includes', :js do
+RSpec.describe 'User views AsciiDoc page with includes', :js do
let_it_be(:user) { create(:user) }
let_it_be(:wiki_content_selector) { '[data-qa-selector=wiki_page_content]' }
let(:project) { create(:project, :public, :wiki_repo) }
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
index 47f32e0113c..ab0b6725491 100644
--- a/spec/features/projects_spec.rb
+++ b/spec/features/projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Project' do
+RSpec.describe 'Project' do
include ProjectForksHelper
include MobileHelpers
diff --git a/spec/features/protected_branches_spec.rb b/spec/features/protected_branches_spec.rb
index 36c5a116b66..f0707610c3f 100644
--- a/spec/features/protected_branches_spec.rb
+++ b/spec/features/protected_branches_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Protected Branches', :js do
+RSpec.describe 'Protected Branches', :js do
include ProtectedBranchHelpers
let(:user) { create(:user) }
diff --git a/spec/features/protected_tags_spec.rb b/spec/features/protected_tags_spec.rb
index 3322a747cf5..12e4bbde293 100644
--- a/spec/features/protected_tags_spec.rb
+++ b/spec/features/protected_tags_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Protected Tags', :js do
+RSpec.describe 'Protected Tags', :js do
include ProtectedTagHelpers
let(:user) { create(:user, :admin) }
diff --git a/spec/features/read_only_spec.rb b/spec/features/read_only_spec.rb
index a33535a7b0b..eb043d2193a 100644
--- a/spec/features/read_only_spec.rb
+++ b/spec/features/read_only_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'read-only message' do
+RSpec.describe 'read-only message' do
let_it_be(:user) { create(:user) }
before do
diff --git a/spec/features/reportable_note/commit_spec.rb b/spec/features/reportable_note/commit_spec.rb
index 3502401095e..fc0df9d6113 100644
--- a/spec/features/reportable_note/commit_spec.rb
+++ b/spec/features/reportable_note/commit_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Reportable note on commit', :js do
+RSpec.describe 'Reportable note on commit', :js do
include RepoHelpers
let(:user) { create(:user) }
diff --git a/spec/features/reportable_note/issue_spec.rb b/spec/features/reportable_note/issue_spec.rb
index c45ef77df55..80c321d0f5a 100644
--- a/spec/features/reportable_note/issue_spec.rb
+++ b/spec/features/reportable_note/issue_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Reportable note on issue', :js do
+RSpec.describe 'Reportable note on issue', :js do
let(:user) { create(:user) }
let(:project) { create(:project) }
let(:issue) { create(:issue, project: project) }
diff --git a/spec/features/reportable_note/merge_request_spec.rb b/spec/features/reportable_note/merge_request_spec.rb
index 2e4d032754b..58a39bac707 100644
--- a/spec/features/reportable_note/merge_request_spec.rb
+++ b/spec/features/reportable_note/merge_request_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Reportable note on merge request', :js do
+RSpec.describe 'Reportable note on merge request', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:merge_request) { create(:merge_request, source_project: project) }
diff --git a/spec/features/reportable_note/snippets_spec.rb b/spec/features/reportable_note/snippets_spec.rb
index a4e609ce40c..4d61e5d8285 100644
--- a/spec/features/reportable_note/snippets_spec.rb
+++ b/spec/features/reportable_note/snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Reportable note on snippets', :js do
+RSpec.describe 'Reportable note on snippets', :js do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index 0049d3ca7c9..8806a363ca4 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Runners' do
+RSpec.describe 'Runners' do
let(:user) { create(:user) }
before do
diff --git a/spec/features/search/user_searches_for_code_spec.rb b/spec/features/search/user_searches_for_code_spec.rb
index 0fdc7346535..227e75088d2 100644
--- a/spec/features/search/user_searches_for_code_spec.rb
+++ b/spec/features/search/user_searches_for_code_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for code' do
+RSpec.describe 'User searches for code' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, namespace: user.namespace) }
diff --git a/spec/features/search/user_searches_for_comments_spec.rb b/spec/features/search/user_searches_for_comments_spec.rb
index 0a203a5bf2d..2a12b22b457 100644
--- a/spec/features/search/user_searches_for_comments_spec.rb
+++ b/spec/features/search/user_searches_for_comments_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for comments' do
+RSpec.describe 'User searches for comments' do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
diff --git a/spec/features/search/user_searches_for_commits_spec.rb b/spec/features/search/user_searches_for_commits_spec.rb
index 958f12d3b84..b860cd08e64 100644
--- a/spec/features/search/user_searches_for_commits_spec.rb
+++ b/spec/features/search/user_searches_for_commits_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for commits' do
+RSpec.describe 'User searches for commits' do
let(:project) { create(:project, :repository) }
let(:sha) { '6d394385cf567f80a8fd85055db1ab4c5295806f' }
let(:user) { create(:user) }
diff --git a/spec/features/search/user_searches_for_issues_spec.rb b/spec/features/search/user_searches_for_issues_spec.rb
index ae718cec7af..e9943347522 100644
--- a/spec/features/search/user_searches_for_issues_spec.rb
+++ b/spec/features/search/user_searches_for_issues_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for issues', :js do
+RSpec.describe 'User searches for issues', :js do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
let!(:issue1) { create(:issue, title: 'Foo', project: project) }
diff --git a/spec/features/search/user_searches_for_merge_requests_spec.rb b/spec/features/search/user_searches_for_merge_requests_spec.rb
index 0139ac26816..40583664958 100644
--- a/spec/features/search/user_searches_for_merge_requests_spec.rb
+++ b/spec/features/search/user_searches_for_merge_requests_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for merge requests', :js do
+RSpec.describe 'User searches for merge requests', :js do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
let!(:merge_request1) { create(:merge_request, title: 'Foo', source_project: project, target_project: project) }
diff --git a/spec/features/search/user_searches_for_milestones_spec.rb b/spec/features/search/user_searches_for_milestones_spec.rb
index 0714cfcc309..64e756db180 100644
--- a/spec/features/search/user_searches_for_milestones_spec.rb
+++ b/spec/features/search/user_searches_for_milestones_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for milestones', :js do
+RSpec.describe 'User searches for milestones', :js do
let(:user) { create(:user) }
let(:project) { create(:project, namespace: user.namespace) }
let!(:milestone1) { create(:milestone, title: 'Foo', project: project) }
diff --git a/spec/features/search/user_searches_for_projects_spec.rb b/spec/features/search/user_searches_for_projects_spec.rb
index b194ac32ff6..7bb5a4da7d0 100644
--- a/spec/features/search/user_searches_for_projects_spec.rb
+++ b/spec/features/search/user_searches_for_projects_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for projects' do
+RSpec.describe 'User searches for projects' do
let!(:project) { create(:project, :public, name: 'Shop') }
context 'when signed out' do
diff --git a/spec/features/search/user_searches_for_users_spec.rb b/spec/features/search/user_searches_for_users_spec.rb
index 6f2c5d48018..826ed73c9bf 100644
--- a/spec/features/search/user_searches_for_users_spec.rb
+++ b/spec/features/search/user_searches_for_users_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for users' do
+RSpec.describe 'User searches for users' do
let(:user1) { create(:user, username: 'gob_bluth', name: 'Gob Bluth') }
let(:user2) { create(:user, username: 'michael_bluth', name: 'Michael Bluth') }
let(:user3) { create(:user, username: 'gob_2018', name: 'George Oscar Bluth') }
diff --git a/spec/features/search/user_searches_for_wiki_pages_spec.rb b/spec/features/search/user_searches_for_wiki_pages_spec.rb
index 10c3032da8b..fc60b6244d9 100644
--- a/spec/features/search/user_searches_for_wiki_pages_spec.rb
+++ b/spec/features/search/user_searches_for_wiki_pages_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User searches for wiki pages', :js do
+RSpec.describe 'User searches for wiki pages', :js do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, :wiki_repo, namespace: user.namespace) }
let!(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'directory/title', content: 'Some Wiki content') }
diff --git a/spec/features/search/user_uses_header_search_field_spec.rb b/spec/features/search/user_uses_header_search_field_spec.rb
index 7ee70077e94..5567dcb30ec 100644
--- a/spec/features/search/user_uses_header_search_field_spec.rb
+++ b/spec/features/search/user_uses_header_search_field_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User uses header search field', :js do
+RSpec.describe 'User uses header search field', :js do
include FilteredSearchHelpers
let(:project) { create(:project) }
diff --git a/spec/features/search/user_uses_search_filters_spec.rb b/spec/features/search/user_uses_search_filters_spec.rb
index fbd7da3c643..f39a1f8fe37 100644
--- a/spec/features/search/user_uses_search_filters_spec.rb
+++ b/spec/features/search/user_uses_search_filters_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User uses search filters', :js do
+RSpec.describe 'User uses search filters', :js do
let(:group) { create(:group) }
let!(:group_project) { create(:project, group: group) }
let(:project) { create(:project, namespace: user.namespace) }
diff --git a/spec/features/security/admin_access_spec.rb b/spec/features/security/admin_access_spec.rb
index 9b2c873b2aa..38f00f399f3 100644
--- a/spec/features/security/admin_access_spec.rb
+++ b/spec/features/security/admin_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Admin::Projects" do
+RSpec.describe "Admin::Projects" do
include AccessMatchers
describe "GET /admin/projects" do
diff --git a/spec/features/security/dashboard_access_spec.rb b/spec/features/security/dashboard_access_spec.rb
index 13fafd88a4c..5ac4a5c1840 100644
--- a/spec/features/security/dashboard_access_spec.rb
+++ b/spec/features/security/dashboard_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Dashboard access" do
+RSpec.describe "Dashboard access" do
include AccessMatchers
describe "GET /dashboard" do
diff --git a/spec/features/security/group/internal_access_spec.rb b/spec/features/security/group/internal_access_spec.rb
index 114bc1a1f0c..c146ac1e8ee 100644
--- a/spec/features/security/group/internal_access_spec.rb
+++ b/spec/features/security/group/internal_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Internal Group access' do
+RSpec.describe 'Internal Group access' do
include AccessMatchers
let(:group) { create(:group, :internal) }
diff --git a/spec/features/security/group/private_access_spec.rb b/spec/features/security/group/private_access_spec.rb
index 3362b9a9e9e..de05b4d3d16 100644
--- a/spec/features/security/group/private_access_spec.rb
+++ b/spec/features/security/group/private_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Private Group access' do
+RSpec.describe 'Private Group access' do
include AccessMatchers
let(:group) { create(:group, :private) }
diff --git a/spec/features/security/group/public_access_spec.rb b/spec/features/security/group/public_access_spec.rb
index bf05f276cc6..ee72b84616a 100644
--- a/spec/features/security/group/public_access_spec.rb
+++ b/spec/features/security/group/public_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Public Group access' do
+RSpec.describe 'Public Group access' do
include AccessMatchers
let(:group) { create(:group, :public) }
diff --git a/spec/features/security/profile_access_spec.rb b/spec/features/security/profile_access_spec.rb
index 044a47567be..3aa8278866c 100644
--- a/spec/features/security/profile_access_spec.rb
+++ b/spec/features/security/profile_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Profile access" do
+RSpec.describe "Profile access" do
include AccessMatchers
describe "GET /profile/keys" do
diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb
index a6a3b427920..99f30d2f904 100644
--- a/spec/features/security/project/internal_access_spec.rb
+++ b/spec/features/security/project/internal_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Internal Project Access" do
+RSpec.describe "Internal Project Access" do
include AccessMatchers
let_it_be(:project, reload: true) { create(:project, :internal, :repository) }
diff --git a/spec/features/security/project/private_access_spec.rb b/spec/features/security/project/private_access_spec.rb
index 95c8b922bef..e891e79db70 100644
--- a/spec/features/security/project/private_access_spec.rb
+++ b/spec/features/security/project/private_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Private Project Access" do
+RSpec.describe "Private Project Access" do
include AccessMatchers
let_it_be(:project, reload: true) { create(:project, :private, :repository, public_builds: false) }
diff --git a/spec/features/security/project/public_access_spec.rb b/spec/features/security/project/public_access_spec.rb
index 814fd83bf73..ea00a59dee4 100644
--- a/spec/features/security/project/public_access_spec.rb
+++ b/spec/features/security/project/public_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Public Project Access" do
+RSpec.describe "Public Project Access" do
include AccessMatchers
let_it_be(:project, reload: true) { create(:project, :public, :repository) }
diff --git a/spec/features/security/project/snippet/internal_access_spec.rb b/spec/features/security/project/snippet/internal_access_spec.rb
index 4b6c7d2c8fb..52ae1022a4e 100644
--- a/spec/features/security/project/snippet/internal_access_spec.rb
+++ b/spec/features/security/project/snippet/internal_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Internal Project Snippets Access" do
+RSpec.describe "Internal Project Snippets Access" do
include AccessMatchers
let(:project) { create(:project, :internal) }
diff --git a/spec/features/security/project/snippet/private_access_spec.rb b/spec/features/security/project/snippet/private_access_spec.rb
index 3135d25cc10..0c97b012ad1 100644
--- a/spec/features/security/project/snippet/private_access_spec.rb
+++ b/spec/features/security/project/snippet/private_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Private Project Snippets Access" do
+RSpec.describe "Private Project Snippets Access" do
include AccessMatchers
let(:project) { create(:project, :private) }
diff --git a/spec/features/security/project/snippet/public_access_spec.rb b/spec/features/security/project/snippet/public_access_spec.rb
index 81689a7bcb5..dfe78aa7ebc 100644
--- a/spec/features/security/project/snippet/public_access_spec.rb
+++ b/spec/features/security/project/snippet/public_access_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe "Public Project Snippets Access" do
+RSpec.describe "Public Project Snippets Access" do
include AccessMatchers
let(:project) { create(:project, :public) }
diff --git a/spec/features/sentry_js_spec.rb b/spec/features/sentry_js_spec.rb
index b39c4f0a0ae..1d277ba7b3c 100644
--- a/spec/features/sentry_js_spec.rb
+++ b/spec/features/sentry_js_spec.rb
@@ -2,8 +2,8 @@
require 'spec_helper'
-describe 'Sentry' do
- let(:sentry_path) { '/sentry.chunk.js' }
+RSpec.describe 'Sentry' do
+ let(:sentry_regex_path) { '\/sentry.*\.chunk\.js' }
it 'does not load sentry if sentry is disabled' do
allow(Gitlab.config.sentry).to receive(:enabled).and_return(false)
@@ -22,7 +22,7 @@ describe 'Sentry' do
def has_requested_sentry
page.all('script', visible: false).one? do |elm|
- elm[:src] =~ /#{sentry_path}$/
+ elm[:src] =~ /#{sentry_regex_path}$/
end
end
end
diff --git a/spec/features/signed_commits_spec.rb b/spec/features/signed_commits_spec.rb
index 3c7a31ac11b..04ca8a09ca8 100644
--- a/spec/features/signed_commits_spec.rb
+++ b/spec/features/signed_commits_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'GPG signed commits' do
+RSpec.describe 'GPG signed commits' do
let(:project) { create(:project, :public, :repository) }
it 'changes from unverified to verified when the user changes their email to match the gpg key', :sidekiq_might_not_need_inline do
diff --git a/spec/features/snippets/embedded_snippet_spec.rb b/spec/features/snippets/embedded_snippet_spec.rb
index d6275b5a265..4f2ab598a6f 100644
--- a/spec/features/snippets/embedded_snippet_spec.rb
+++ b/spec/features/snippets/embedded_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Embedded Snippets' do
+RSpec.describe 'Embedded Snippets' do
let(:snippet) { create(:personal_snippet, :public, file_name: 'random_dir.rb', content: content) }
let(:content) { "require 'fileutils'\nFileUtils.mkdir_p 'some/random_dir'\n" }
diff --git a/spec/features/snippets/explore_spec.rb b/spec/features/snippets/explore_spec.rb
index 2075742eafb..b62c35bf96e 100644
--- a/spec/features/snippets/explore_spec.rb
+++ b/spec/features/snippets/explore_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Explore Snippets' do
+RSpec.describe 'Explore Snippets' do
let!(:public_snippet) { create(:personal_snippet, :public) }
let!(:internal_snippet) { create(:personal_snippet, :internal) }
let!(:private_snippet) { create(:personal_snippet, :private) }
diff --git a/spec/features/snippets/internal_snippet_spec.rb b/spec/features/snippets/internal_snippet_spec.rb
index fd7ef71db15..3ce297ab22d 100644
--- a/spec/features/snippets/internal_snippet_spec.rb
+++ b/spec/features/snippets/internal_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Internal Snippets', :js do
+RSpec.describe 'Internal Snippets', :js do
let(:internal_snippet) { create(:personal_snippet, :internal) }
before do
diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb
index 57264f97ddc..aaaa61fec62 100644
--- a/spec/features/snippets/notes_on_personal_snippets_spec.rb
+++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Comments on personal snippets', :js do
+RSpec.describe 'Comments on personal snippets', :js do
include NoteInteractionHelpers
let!(:user) { create(:user) }
diff --git a/spec/features/snippets/private_snippets_spec.rb b/spec/features/snippets/private_snippets_spec.rb
index 37f45f22a27..6b45f3485e7 100644
--- a/spec/features/snippets/private_snippets_spec.rb
+++ b/spec/features/snippets/private_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Private Snippets', :js do
+RSpec.describe 'Private Snippets', :js do
let(:user) { create(:user) }
before do
diff --git a/spec/features/snippets/public_snippets_spec.rb b/spec/features/snippets/public_snippets_spec.rb
index 295e61ffb56..4b72b33245d 100644
--- a/spec/features/snippets/public_snippets_spec.rb
+++ b/spec/features/snippets/public_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Public Snippets', :js do
+RSpec.describe 'Public Snippets', :js do
before do
stub_feature_flags(snippets_vue: false)
end
diff --git a/spec/features/snippets/search_snippets_spec.rb b/spec/features/snippets/search_snippets_spec.rb
index d3e02d43813..4f299edc9da 100644
--- a/spec/features/snippets/search_snippets_spec.rb
+++ b/spec/features/snippets/search_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Search Snippets' do
+RSpec.describe 'Search Snippets' do
it 'User searches for snippets by title' do
public_snippet = create(:personal_snippet, :public, title: 'Beginning and Middle')
private_snippet = create(:personal_snippet, :private, title: 'Middle and End')
diff --git a/spec/features/snippets/show_spec.rb b/spec/features/snippets/show_spec.rb
index 9c686be012b..9125ed74273 100644
--- a/spec/features/snippets/show_spec.rb
+++ b/spec/features/snippets/show_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Snippet', :js do
+RSpec.describe 'Snippet', :js do
let(:project) { create(:project, :repository) }
let(:snippet) { create(:personal_snippet, :public, file_name: file_name, content: content) }
diff --git a/spec/features/snippets/spam_snippets_spec.rb b/spec/features/snippets/spam_snippets_spec.rb
index d19354e7bbe..e6a9467a3d7 100644
--- a/spec/features/snippets/spam_snippets_spec.rb
+++ b/spec/features/snippets/spam_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-shared_examples_for 'snippet editor' do
+RSpec.shared_examples_for 'snippet editor' do
include_context 'includes Spam constants'
def description_field
@@ -122,7 +122,7 @@ shared_examples_for 'snippet editor' do
end
end
-describe 'User creates snippet', :js do
+RSpec.describe 'User creates snippet', :js do
let_it_be(:user) { create(:user) }
it_behaves_like "snippet editor"
diff --git a/spec/features/snippets/user_creates_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb
index dffdbcd6940..284aa77c742 100644
--- a/spec/features/snippets/user_creates_snippet_spec.rb
+++ b/spec/features/snippets/user_creates_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-shared_examples_for 'snippet editor' do
+RSpec.shared_examples_for 'snippet editor' do
before do
stub_feature_flags(snippets_vue: false)
stub_feature_flags(snippets_edit_vue: false)
@@ -180,7 +180,7 @@ shared_examples_for 'snippet editor' do
end
end
-describe 'User creates snippet', :js do
+RSpec.describe 'User creates snippet', :js do
include DropzoneHelper
let_it_be(:user) { create(:user) }
diff --git a/spec/features/snippets/user_deletes_snippet_spec.rb b/spec/features/snippets/user_deletes_snippet_spec.rb
index 35619b92561..d7cfc67df13 100644
--- a/spec/features/snippets/user_deletes_snippet_spec.rb
+++ b/spec/features/snippets/user_deletes_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User deletes snippet' do
+RSpec.describe 'User deletes snippet' do
let(:user) { create(:user) }
let(:content) { 'puts "test"' }
let(:snippet) { create(:personal_snippet, :public, content: content, author: user) }
diff --git a/spec/features/snippets/user_edits_snippet_spec.rb b/spec/features/snippets/user_edits_snippet_spec.rb
index 40b0113cf39..3692b0d1ad8 100644
--- a/spec/features/snippets/user_edits_snippet_spec.rb
+++ b/spec/features/snippets/user_edits_snippet_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User edits snippet', :js do
+RSpec.describe 'User edits snippet', :js do
include DropzoneHelper
let_it_be(:file_name) { 'test.rb' }
diff --git a/spec/features/snippets/user_snippets_spec.rb b/spec/features/snippets/user_snippets_spec.rb
index d9faea55b29..a313dc3b26a 100644
--- a/spec/features/snippets/user_snippets_spec.rb
+++ b/spec/features/snippets/user_snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'User Snippets' do
+RSpec.describe 'User Snippets' do
let(:author) { create(:user) }
let!(:public_snippet) { create(:personal_snippet, :public, author: author, title: "This is a public snippet") }
let!(:internal_snippet) { create(:personal_snippet, :internal, author: author, title: "This is an internal snippet") }
diff --git a/spec/features/snippets_spec.rb b/spec/features/snippets_spec.rb
index bc7fa161e87..75309ca3e7c 100644
--- a/spec/features/snippets_spec.rb
+++ b/spec/features/snippets_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Snippets' do
+RSpec.describe 'Snippets' do
context 'when the project has snippets' do
let(:project) { create(:project, :public) }
let!(:snippets) { create_list(:project_snippet, 2, :public, author: project.owner, project: project) }
diff --git a/spec/features/static_site_editor_spec.rb b/spec/features/static_site_editor_spec.rb
index de000ee2b9f..9ae23b4bdec 100644
--- a/spec/features/static_site_editor_spec.rb
+++ b/spec/features/static_site_editor_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Static Site Editor' do
+RSpec.describe 'Static Site Editor' do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public, :repository) }
diff --git a/spec/frontend/design_management/components/design_note_pin_spec.js b/spec/frontend/design_management/components/design_note_pin_spec.js
index 76fe5402053..4e045b58a35 100644
--- a/spec/frontend/design_management/components/design_note_pin_spec.js
+++ b/spec/frontend/design_management/components/design_note_pin_spec.js
@@ -26,7 +26,7 @@ describe('Design note pin component', () => {
});
it('should match the snapshot of note with index', () => {
- createComponent({ label: '1' });
+ createComponent({ label: 1 });
expect(wrapper.element).toMatchSnapshot();
});
diff --git a/spec/frontend/design_management/components/design_notes/__snapshots__/design_note_spec.js.snap b/spec/frontend/design_management/components/design_notes/__snapshots__/design_note_spec.js.snap
index e071274cc81..b55bacb6fc5 100644
--- a/spec/frontend/design_management/components/design_notes/__snapshots__/design_note_spec.js.snap
+++ b/spec/frontend/design_management/components/design_notes/__snapshots__/design_note_spec.js.snap
@@ -50,12 +50,18 @@ exports[`Design note component should match the snapshot 1`] = `
</span>
</div>
- <!---->
+ <div
+ class="gl-display-flex"
+ >
+
+ <!---->
+ </div>
</div>
<div
class="note-text js-note-text md"
data-qa-selector="note_content"
/>
+
</timeline-entry-item-stub>
`;
diff --git a/spec/frontend/design_management/components/design_notes/design_discussion_spec.js b/spec/frontend/design_management/components/design_notes/design_discussion_spec.js
index 3b398275f7a..1b1cfe69f1b 100644
--- a/spec/frontend/design_management/components/design_notes/design_discussion_spec.js
+++ b/spec/frontend/design_management/components/design_notes/design_discussion_spec.js
@@ -1,16 +1,33 @@
-import { shallowMount } from '@vue/test-utils';
-import { ApolloMutation } from 'vue-apollo';
+import { mount } from '@vue/test-utils';
+import { GlLoadingIcon } from '@gitlab/ui';
+import notes from '../../mock_data/notes';
import DesignDiscussion from '~/design_management/components/design_notes/design_discussion.vue';
import DesignNote from '~/design_management/components/design_notes/design_note.vue';
import DesignReplyForm from '~/design_management/components/design_notes/design_reply_form.vue';
import createNoteMutation from '~/design_management/graphql/mutations/createNote.mutation.graphql';
+import toggleResolveDiscussionMutation from '~/design_management/graphql/mutations/toggle_resolve_discussion.mutation.graphql';
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
+import ToggleRepliesWidget from '~/design_management/components/design_notes/toggle_replies_widget.vue';
+
+const discussion = {
+ id: '0',
+ resolved: false,
+ resolvable: true,
+ notes,
+};
describe('Design discussions component', () => {
let wrapper;
+ const findDesignNotes = () => wrapper.findAll(DesignNote);
const findReplyPlaceholder = () => wrapper.find(ReplyPlaceholder);
const findReplyForm = () => wrapper.find(DesignReplyForm);
+ const findRepliesWidget = () => wrapper.find(ToggleRepliesWidget);
+ const findResolveButton = () => wrapper.find('[data-testid="resolve-button"]');
+ const findResolveIcon = () => wrapper.find('[data-testid="resolve-icon"]');
+ const findResolvedMessage = () => wrapper.find('[data-testid="resolved-message"]');
+ const findResolveLoadingIcon = () => wrapper.find(GlLoadingIcon);
+ const findResolveCheckbox = () => wrapper.find('[data-testid="resolve-checkbox"]');
const mutationVariables = {
mutation: createNoteMutation,
@@ -29,19 +46,10 @@ describe('Design discussions component', () => {
};
function createComponent(props = {}, data = {}) {
- wrapper = shallowMount(DesignDiscussion, {
+ wrapper = mount(DesignDiscussion, {
propsData: {
- discussion: {
- id: '0',
- notes: [
- {
- id: '1',
- },
- {
- id: '2',
- },
- ],
- },
+ resolvedDiscussionsExpanded: true,
+ discussion,
noteableId: 'noteable-id',
designId: 'design-id',
discussionIndex: 1,
@@ -52,11 +60,12 @@ describe('Design discussions component', () => {
...data,
};
},
- stubs: {
- ReplyPlaceholder,
- ApolloMutation,
+ mocks: {
+ $apollo,
+ $route: {
+ hash: '#note_1',
+ },
},
- mocks: { $apollo },
});
}
@@ -64,14 +73,139 @@ describe('Design discussions component', () => {
wrapper.destroy();
});
- it('renders correct amount of discussion notes', () => {
- createComponent();
- expect(wrapper.findAll(DesignNote)).toHaveLength(2);
+ describe('when discussion is not resolvable', () => {
+ beforeEach(() => {
+ createComponent({
+ discussion: {
+ ...discussion,
+ resolvable: false,
+ },
+ });
+ });
+
+ it('does not render an icon to resolve a thread', () => {
+ expect(findResolveIcon().exists()).toBe(false);
+ });
+
+ it('does not render a checkbox in reply form', () => {
+ findReplyPlaceholder().vm.$emit('onMouseDown');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findResolveCheckbox().exists()).toBe(false);
+ });
+ });
});
- it('renders reply placeholder by default', () => {
- createComponent();
- expect(findReplyPlaceholder().exists()).toBe(true);
+ describe('when discussion is unresolved', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders correct amount of discussion notes', () => {
+ expect(findDesignNotes()).toHaveLength(2);
+ expect(findDesignNotes().wrappers.every(w => w.isVisible())).toBe(true);
+ });
+
+ it('renders reply placeholder', () => {
+ expect(findReplyPlaceholder().isVisible()).toBe(true);
+ });
+
+ it('does not render toggle replies widget', () => {
+ expect(findRepliesWidget().exists()).toBe(false);
+ });
+
+ it('renders a correct icon to resolve a thread', () => {
+ expect(findResolveIcon().props('name')).toBe('check-circle');
+ });
+
+ it('renders a checkbox with Resolve thread text in reply form', () => {
+ findReplyPlaceholder().vm.$emit('onMouseDown');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findResolveCheckbox().text()).toBe('Resolve thread');
+ });
+ });
+
+ it('does not render resolved message', () => {
+ expect(findResolvedMessage().exists()).toBe(false);
+ });
+ });
+
+ describe('when discussion is resolved', () => {
+ beforeEach(() => {
+ createComponent({
+ discussion: {
+ ...discussion,
+ resolved: true,
+ resolvedBy: notes[0].author,
+ resolvedAt: '2020-05-08T07:10:45Z',
+ },
+ });
+ });
+
+ it('shows only the first note', () => {
+ expect(
+ findDesignNotes()
+ .at(0)
+ .isVisible(),
+ ).toBe(true);
+ expect(
+ findDesignNotes()
+ .at(1)
+ .isVisible(),
+ ).toBe(false);
+ });
+
+ it('renders resolved message', () => {
+ expect(findResolvedMessage().exists()).toBe(true);
+ });
+
+ it('does not show renders reply placeholder', () => {
+ expect(findReplyPlaceholder().isVisible()).toBe(false);
+ });
+
+ it('renders toggle replies widget with correct props', () => {
+ expect(findRepliesWidget().exists()).toBe(true);
+ expect(findRepliesWidget().props()).toEqual({
+ collapsed: true,
+ replies: notes.slice(1),
+ });
+ });
+
+ it('renders a correct icon to resolve a thread', () => {
+ expect(findResolveIcon().props('name')).toBe('check-circle-filled');
+ });
+
+ describe('when replies are expanded', () => {
+ beforeEach(() => {
+ findRepliesWidget().vm.$emit('toggle');
+ return wrapper.vm.$nextTick();
+ });
+
+ it('renders replies widget with collapsed prop equal to false', () => {
+ expect(findRepliesWidget().props('collapsed')).toBe(false);
+ });
+
+ it('renders the second note', () => {
+ expect(
+ findDesignNotes()
+ .at(1)
+ .isVisible(),
+ ).toBe(true);
+ });
+
+ it('renders a reply placeholder', () => {
+ expect(findReplyPlaceholder().isVisible()).toBe(true);
+ });
+
+ it('renders a checkbox with Unresolve thread text in reply form', () => {
+ findReplyPlaceholder().vm.$emit('onMouseDown');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findResolveCheckbox().text()).toBe('Unresolve thread');
+ });
+ });
+ });
});
it('hides reply placeholder and opens form on placeholder click', () => {
@@ -120,7 +254,7 @@ describe('Design discussions component', () => {
{},
{
activeDiscussion: {
- id: '1',
+ id: notes[0].id,
source: 'pin',
},
},
@@ -148,4 +282,35 @@ describe('Design discussions component', () => {
expect(findReplyForm().exists()).toBe(true);
});
});
+
+ it('calls toggleResolveDiscussion mutation on resolve thread button click', () => {
+ createComponent();
+ findResolveButton().trigger('click');
+ expect(mutate).toHaveBeenCalledWith({
+ mutation: toggleResolveDiscussionMutation,
+ variables: {
+ id: discussion.id,
+ resolve: true,
+ },
+ });
+ return wrapper.vm.$nextTick(() => {
+ expect(findResolveLoadingIcon().exists()).toBe(true);
+ });
+ });
+
+ it('calls toggleResolveDiscussion mutation after adding a note if checkbox was checked', () => {
+ createComponent({}, { discussionComment: 'test', isFormRendered: true });
+ findResolveButton().trigger('click');
+ findReplyForm().vm.$emit('submitForm');
+
+ return mutate().then(() => {
+ expect(mutate).toHaveBeenCalledWith({
+ mutation: toggleResolveDiscussionMutation,
+ variables: {
+ id: discussion.id,
+ resolve: true,
+ },
+ });
+ });
+ });
});
diff --git a/spec/frontend/design_management/components/design_notes/toggle_replies_widget_spec.js b/spec/frontend/design_management/components/design_notes/toggle_replies_widget_spec.js
new file mode 100644
index 00000000000..7eda294d2d3
--- /dev/null
+++ b/spec/frontend/design_management/components/design_notes/toggle_replies_widget_spec.js
@@ -0,0 +1,98 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlIcon, GlButton, GlLink } from '@gitlab/ui';
+import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+import ToggleRepliesWidget from '~/design_management/components/design_notes/toggle_replies_widget.vue';
+import notes from '../../mock_data/notes';
+
+describe('Toggle replies widget component', () => {
+ let wrapper;
+
+ const findToggleWrapper = () => wrapper.find('[data-testid="toggle-comments-wrapper"]');
+ const findIcon = () => wrapper.find(GlIcon);
+ const findButton = () => wrapper.find(GlButton);
+ const findAuthorLink = () => wrapper.find(GlLink);
+ const findTimeAgo = () => wrapper.find(TimeAgoTooltip);
+
+ function createComponent(props = {}) {
+ wrapper = shallowMount(ToggleRepliesWidget, {
+ propsData: {
+ collapsed: true,
+ replies: notes,
+ ...props,
+ },
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when replies are collapsed', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('should not have expanded class', () => {
+ expect(findToggleWrapper().classes()).not.toContain('expanded');
+ });
+
+ it('should render chevron-right icon', () => {
+ expect(findIcon().props('name')).toBe('chevron-right');
+ });
+
+ it('should have replies length on button', () => {
+ expect(findButton().text()).toBe('2 replies');
+ });
+
+ it('should render a link to the last reply author', () => {
+ expect(findAuthorLink().exists()).toBe(true);
+ expect(findAuthorLink().text()).toBe(notes[1].author.name);
+ expect(findAuthorLink().attributes('href')).toBe(notes[1].author.webUrl);
+ });
+
+ it('should render correct time ago tooltip', () => {
+ expect(findTimeAgo().exists()).toBe(true);
+ expect(findTimeAgo().props('time')).toBe(notes[1].createdAt);
+ });
+ });
+
+ describe('when replies are expanded', () => {
+ beforeEach(() => {
+ createComponent({ collapsed: false });
+ });
+
+ it('should have expanded class', () => {
+ expect(findToggleWrapper().classes()).toContain('expanded');
+ });
+
+ it('should render chevron-down icon', () => {
+ expect(findIcon().props('name')).toBe('chevron-down');
+ });
+
+ it('should have Collapse replies text on button', () => {
+ expect(findButton().text()).toBe('Collapse replies');
+ });
+
+ it('should not have a link to the last reply author', () => {
+ expect(findAuthorLink().exists()).toBe(false);
+ });
+
+ it('should not render time ago tooltip', () => {
+ expect(findTimeAgo().exists()).toBe(false);
+ });
+ });
+
+ it('should emit toggle event on icon click', () => {
+ createComponent();
+ findIcon().vm.$emit('click', new MouseEvent('click'));
+
+ expect(wrapper.emitted('toggle')).toHaveLength(1);
+ });
+
+ it('should emit toggle event on button click', () => {
+ createComponent();
+ findButton().vm.$emit('click', new MouseEvent('click'));
+
+ expect(wrapper.emitted('toggle')).toHaveLength(1);
+ });
+});
diff --git a/spec/frontend/design_management/components/design_overlay_spec.js b/spec/frontend/design_management/components/design_overlay_spec.js
index 1c9b130aca6..8062f71b693 100644
--- a/spec/frontend/design_management/components/design_overlay_spec.js
+++ b/spec/frontend/design_management/components/design_overlay_spec.js
@@ -12,6 +12,7 @@ describe('Design overlay component', () => {
const mockDimensions = { width: 100, height: 100 };
const mockNoteNotAuthorised = {
id: 'note-not-authorised',
+ index: 1,
discussion: { id: 'discussion-not-authorised' },
position: {
x: 1,
@@ -19,6 +20,7 @@ describe('Design overlay component', () => {
...mockDimensions,
},
userPermissions: {},
+ resolved: false,
};
const findOverlay = () => wrapper.find('.image-diff-overlay');
@@ -43,6 +45,7 @@ describe('Design overlay component', () => {
top: '0',
left: '0',
},
+ resolvedDiscussionsExpanded: false,
...props,
},
data() {
@@ -88,19 +91,46 @@ describe('Design overlay component', () => {
});
describe('with notes', () => {
- beforeEach(() => {
+ it('should render only the first note', () => {
createComponent({
notes,
});
+ expect(findAllNotes()).toHaveLength(1);
});
- it('should render a correct amount of notes', () => {
- expect(findAllNotes()).toHaveLength(notes.length);
- });
+ describe('with resolved discussions toggle expanded', () => {
+ beforeEach(() => {
+ createComponent({
+ notes,
+ resolvedDiscussionsExpanded: true,
+ });
+ });
+
+ it('should render all notes', () => {
+ expect(findAllNotes()).toHaveLength(notes.length);
+ });
+
+ it('should have set the correct position for each note badge', () => {
+ expect(findFirstBadge().attributes().style).toBe('left: 10px; top: 15px;');
+ expect(findSecondBadge().attributes().style).toBe('left: 50px; top: 50px;');
+ });
+
+ it('should apply resolved class to the resolved note pin', () => {
+ expect(findSecondBadge().classes()).toContain('resolved');
+ });
+
+ it('when there is an active discussion, should apply inactive class to all pins besides the active one', () => {
+ wrapper.setData({
+ activeDiscussion: {
+ id: notes[0].id,
+ source: 'discussion',
+ },
+ });
- it('should have a correct style for each note badge', () => {
- expect(findFirstBadge().attributes().style).toBe('left: 10px; top: 15px;');
- expect(findSecondBadge().attributes().style).toBe('left: 50px; top: 50px;');
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findSecondBadge().classes()).toContain('inactive');
+ });
+ });
});
it('should recalculate badges positions on window resize', () => {
@@ -144,19 +174,6 @@ describe('Design overlay component', () => {
expect(mutate).toHaveBeenCalledWith(mutationVariables);
});
});
-
- it('when there is an active discussion, should apply inactive class to all pins besides the active one', () => {
- wrapper.setData({
- activeDiscussion: {
- id: notes[0].id,
- source: 'discussion',
- },
- });
-
- return wrapper.vm.$nextTick().then(() => {
- expect(findSecondBadge().classes()).toContain('inactive');
- });
- });
});
describe('when moving notes', () => {
diff --git a/spec/frontend/design_management/components/design_presentation_spec.js b/spec/frontend/design_management/components/design_presentation_spec.js
index 8a709393d92..7e513182589 100644
--- a/spec/frontend/design_management/components/design_presentation_spec.js
+++ b/spec/frontend/design_management/components/design_presentation_spec.js
@@ -17,7 +17,13 @@ describe('Design management design presentation component', () => {
let wrapper;
function createComponent(
- { image, imageName, discussions = [], isAnnotating = false } = {},
+ {
+ image,
+ imageName,
+ discussions = [],
+ isAnnotating = false,
+ resolvedDiscussionsExpanded = false,
+ } = {},
data = {},
stubs = {},
) {
@@ -27,6 +33,7 @@ describe('Design management design presentation component', () => {
imageName,
discussions,
isAnnotating,
+ resolvedDiscussionsExpanded,
},
stubs,
});
diff --git a/spec/frontend/design_management/components/design_sidebar_spec.js b/spec/frontend/design_management/components/design_sidebar_spec.js
new file mode 100644
index 00000000000..631c5ded5f4
--- /dev/null
+++ b/spec/frontend/design_management/components/design_sidebar_spec.js
@@ -0,0 +1,228 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlCollapse, GlPopover } from '@gitlab/ui';
+import Cookies from 'js-cookie';
+import DesignSidebar from '~/design_management/components/design_sidebar.vue';
+import Participants from '~/sidebar/components/participants/participants.vue';
+import DesignDiscussion from '~/design_management/components/design_notes/design_discussion.vue';
+import design from '../mock_data/design';
+import updateActiveDiscussionMutation from '~/design_management/graphql/mutations/update_active_discussion.mutation.graphql';
+
+const updateActiveDiscussionMutationVariables = {
+ mutation: updateActiveDiscussionMutation,
+ variables: {
+ id: design.discussions.nodes[0].notes.nodes[0].id,
+ source: 'discussion',
+ },
+};
+
+const $route = {
+ params: {
+ id: '1',
+ },
+};
+
+const cookieKey = 'hide_design_resolved_comments_popover';
+
+const mutate = jest.fn().mockResolvedValue();
+
+describe('Design management design sidebar component', () => {
+ let wrapper;
+
+ const findDiscussions = () => wrapper.findAll(DesignDiscussion);
+ const findFirstDiscussion = () => findDiscussions().at(0);
+ const findUnresolvedDiscussions = () => wrapper.findAll('[data-testid="unresolved-discussion"]');
+ const findResolvedDiscussions = () => wrapper.findAll('[data-testid="resolved-discussion"]');
+ const findParticipants = () => wrapper.find(Participants);
+ const findCollapsible = () => wrapper.find(GlCollapse);
+ const findToggleResolvedCommentsButton = () => wrapper.find('[data-testid="resolved-comments"]');
+ const findPopover = () => wrapper.find(GlPopover);
+ const findNewDiscussionDisclaimer = () =>
+ wrapper.find('[data-testid="new-discussion-disclaimer"]');
+
+ function createComponent(props = {}) {
+ wrapper = shallowMount(DesignSidebar, {
+ propsData: {
+ design,
+ resolvedDiscussionsExpanded: false,
+ markdownPreviewPath: '',
+ ...props,
+ },
+ mocks: {
+ $route,
+ $apollo: {
+ mutate,
+ },
+ },
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders participants', () => {
+ createComponent();
+
+ expect(findParticipants().exists()).toBe(true);
+ });
+
+ it('passes the correct amount of participants to the Participants component', () => {
+ createComponent();
+
+ expect(findParticipants().props('participants')).toHaveLength(1);
+ });
+
+ describe('when has no discussions', () => {
+ beforeEach(() => {
+ createComponent({
+ design: {
+ ...design,
+ discussions: {
+ nodes: [],
+ },
+ },
+ });
+ });
+
+ it('does not render discussions', () => {
+ expect(findDiscussions().exists()).toBe(false);
+ });
+
+ it('renders a message about possibility to create a new discussion', () => {
+ expect(findNewDiscussionDisclaimer().exists()).toBe(true);
+ });
+ });
+
+ describe('when has discussions', () => {
+ beforeEach(() => {
+ Cookies.set(cookieKey, true);
+ createComponent();
+ });
+
+ it('renders correct amount of unresolved discussions', () => {
+ expect(findUnresolvedDiscussions()).toHaveLength(1);
+ });
+
+ it('renders correct amount of resolved discussions', () => {
+ expect(findResolvedDiscussions()).toHaveLength(1);
+ });
+
+ it('has resolved comments collapsible collapsed', () => {
+ expect(findCollapsible().attributes('visible')).toBeUndefined();
+ });
+
+ it('emits toggleResolveComments event on resolve comments button click', () => {
+ findToggleResolvedCommentsButton().vm.$emit('click');
+ expect(wrapper.emitted('toggleResolvedComments')).toHaveLength(1);
+ });
+
+ it('opens a collapsible when resolvedDiscussionsExpanded prop changes to true', () => {
+ expect(findCollapsible().attributes('visible')).toBeUndefined();
+ wrapper.setProps({
+ resolvedDiscussionsExpanded: true,
+ });
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findCollapsible().attributes('visible')).toBe('true');
+ });
+ });
+
+ it('does not popover about resolved comments', () => {
+ expect(findPopover().exists()).toBe(false);
+ });
+
+ it('sends a mutation to set an active discussion when clicking on a discussion', () => {
+ findFirstDiscussion().trigger('click');
+
+ expect(mutate).toHaveBeenCalledWith(updateActiveDiscussionMutationVariables);
+ });
+
+ it('sends a mutation to reset an active discussion when clicking outside of discussion', () => {
+ wrapper.trigger('click');
+
+ expect(mutate).toHaveBeenCalledWith({
+ ...updateActiveDiscussionMutationVariables,
+ variables: { id: undefined, source: 'discussion' },
+ });
+ });
+
+ it('emits correct event on discussion create note error', () => {
+ findFirstDiscussion().vm.$emit('createNoteError', 'payload');
+ expect(wrapper.emitted('onDesignDiscussionError')).toEqual([['payload']]);
+ });
+
+ it('emits correct event on discussion update note error', () => {
+ findFirstDiscussion().vm.$emit('updateNoteError', 'payload');
+ expect(wrapper.emitted('updateNoteError')).toEqual([['payload']]);
+ });
+
+ it('emits correct event on discussion resolve error', () => {
+ findFirstDiscussion().vm.$emit('resolveDiscussionError', 'payload');
+ expect(wrapper.emitted('resolveDiscussionError')).toEqual([['payload']]);
+ });
+ });
+
+ describe('when all discussions are resolved', () => {
+ beforeEach(() => {
+ createComponent({
+ design: {
+ ...design,
+ discussions: {
+ nodes: [
+ {
+ id: 'discussion-id',
+ replyId: 'discussion-reply-id',
+ resolved: true,
+ notes: {
+ nodes: [
+ {
+ id: 'note-id',
+ body: '123',
+ author: {
+ name: 'Administrator',
+ username: 'root',
+ webUrl: 'link-to-author',
+ avatarUrl: 'link-to-avatar',
+ },
+ },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ });
+ });
+
+ it('renders a message about possibility to create a new discussion', () => {
+ expect(findNewDiscussionDisclaimer().exists()).toBe(true);
+ });
+
+ it('does not render unresolved discussions', () => {
+ expect(findUnresolvedDiscussions()).toHaveLength(0);
+ });
+ });
+
+ describe('when showing resolved discussions for the first time', () => {
+ beforeEach(() => {
+ Cookies.set(cookieKey, false);
+ createComponent();
+ });
+
+ it('renders a popover if we show resolved comments collapsible for the first time', () => {
+ expect(findPopover().exists()).toBe(true);
+ });
+
+ it('dismisses a popover on the outside click', () => {
+ wrapper.trigger('click');
+ return wrapper.vm.$nextTick(() => {
+ expect(findPopover().exists()).toBe(false);
+ });
+ });
+
+ it(`sets a ${cookieKey} cookie on clicking outside the popover`, () => {
+ jest.spyOn(Cookies, 'set');
+ wrapper.trigger('click');
+ expect(Cookies.set).toHaveBeenCalledWith(cookieKey, 'true', { expires: 365 * 10 });
+ });
+ });
+});
diff --git a/spec/frontend/design_management/mock_data/design.js b/spec/frontend/design_management/mock_data/design.js
index 34e3077f4a2..675198b9408 100644
--- a/spec/frontend/design_management/mock_data/design.js
+++ b/spec/frontend/design_management/mock_data/design.js
@@ -29,6 +29,7 @@ export default {
{
id: 'discussion-id',
replyId: 'discussion-reply-id',
+ resolved: false,
notes: {
nodes: [
{
@@ -44,6 +45,25 @@ export default {
],
},
},
+ {
+ id: 'discussion-resolved',
+ replyId: 'discussion-reply-resolved',
+ resolved: true,
+ notes: {
+ nodes: [
+ {
+ id: 'note-resolved',
+ body: '123',
+ author: {
+ name: 'Administrator',
+ username: 'root',
+ webUrl: 'link-to-author',
+ avatarUrl: 'link-to-avatar',
+ },
+ },
+ ],
+ },
+ },
],
},
diffRefs: {
diff --git a/spec/frontend/design_management/mock_data/notes.js b/spec/frontend/design_management/mock_data/notes.js
index db4624c8524..80cb3944786 100644
--- a/spec/frontend/design_management/mock_data/notes.js
+++ b/spec/frontend/design_management/mock_data/notes.js
@@ -1,32 +1,46 @@
export default [
{
id: 'note-id-1',
+ index: 1,
position: {
height: 100,
width: 100,
x: 10,
y: 15,
},
+ author: {
+ name: 'John',
+ webUrl: 'link-to-john-profile',
+ },
+ createdAt: '2020-05-08T07:10:45Z',
userPermissions: {
adminNote: true,
},
discussion: {
id: 'discussion-id-1',
},
+ resolved: false,
},
{
id: 'note-id-2',
+ index: 2,
position: {
height: 50,
width: 50,
x: 25,
y: 25,
},
+ author: {
+ name: 'Mary',
+ webUrl: 'link-to-mary-profile',
+ },
+ createdAt: '2020-05-08T07:10:45Z',
userPermissions: {
adminNote: true,
},
discussion: {
id: 'discussion-id-2',
},
+ resolved: true,
},
];
diff --git a/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap b/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap
index 76e481ee518..73fbc7201e9 100644
--- a/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap
+++ b/spec/frontend/design_management/pages/design/__snapshots__/index_spec.js.snap
@@ -16,7 +16,7 @@ exports[`Design management design index page renders design index 1`] = `
<!---->
<design-presentation-stub
- discussions="[object Object]"
+ discussions="[object Object],[object Object]"
image="test.jpg"
imagename="test.jpg"
scale="1"
@@ -33,58 +33,84 @@ exports[`Design management design index page renders design index 1`] = `
class="image-notes"
>
<h2
- class="gl-font-size-20-deprecated-no-really-do-not-use-me font-weight-bold mt-0"
+ class="gl-font-weight-bold gl-mt-0"
>
- My precious issue
-
+ My precious issue
+
</h2>
<a
- class="text-tertiary text-decoration-none mb-3 d-block"
+ class="gl-text-gray-600 gl-text-decoration-none gl-mb-6 gl-display-block"
href="full-issue-url"
>
ull-issue-path
</a>
<participants-stub
- class="mb-4"
+ class="gl-mb-4"
numberoflessparticipants="7"
participants="[object Object]"
/>
- <div
- class="design-discussion-wrapper"
+ <!---->
+
+ <design-discussion-stub
+ data-testid="unresolved-discussion"
+ designid="test"
+ discussion="[object Object]"
+ markdownpreviewpath="//preview_markdown?target_type=Issue"
+ noteableid="design-id"
+ />
+
+ <gl-button-stub
+ category="tertiary"
+ class="link-inherit-color gl-text-black-normal gl-text-decoration-none gl-font-weight-bold gl-mb-4"
+ data-testid="resolved-comments"
+ icon="chevron-right"
+ id="resolved-comments"
+ size="medium"
+ variant="link"
>
- <div
- class="badge badge-pill"
- type="button"
- >
- 1
- </div>
+ Resolved Comments (1)
+
+ </gl-button-stub>
+
+ <gl-popover-stub
+ container="popovercontainer"
+ cssclasses=""
+ placement="top"
+ show="true"
+ target="resolved-comments"
+ title="Resolved Comments"
+ >
+ <p>
+
+ Comments you resolve can be viewed and unresolved by going to the "Resolved Comments" section below
+
+ </p>
- <div
- class="design-discussion bordered-box position-relative"
- data-qa-selector="design_discussion_content"
+ <a
+ href="#"
+ rel="noopener noreferrer"
+ target="_blank"
>
- <design-note-stub
- class=""
- markdownpreviewpath="//preview_markdown?target_type=Issue"
- note="[object Object]"
- />
-
- <div
- class="reply-wrapper"
- >
- <reply-placeholder-stub
- buttontext="Reply..."
- class="qa-discussion-reply"
- />
- </div>
- </div>
- </div>
+ Learn more about resolving comments
+ </a>
+ </gl-popover-stub>
+
+ <gl-collapse-stub
+ class="gl-mt-3"
+ >
+ <design-discussion-stub
+ data-testid="resolved-discussion"
+ designid="test"
+ discussion="[object Object]"
+ markdownpreviewpath="//preview_markdown?target_type=Issue"
+ noteableid="design-id"
+ />
+ </gl-collapse-stub>
- <!---->
</div>
</div>
`;
@@ -152,33 +178,37 @@ exports[`Design management design index page with error GlAlert is rendered in c
class="image-notes"
>
<h2
- class="gl-font-size-20-deprecated-no-really-do-not-use-me font-weight-bold mt-0"
+ class="gl-font-weight-bold gl-mt-0"
>
- My precious issue
-
+ My precious issue
+
</h2>
<a
- class="text-tertiary text-decoration-none mb-3 d-block"
+ class="gl-text-gray-600 gl-text-decoration-none gl-mb-6 gl-display-block"
href="full-issue-url"
>
ull-issue-path
</a>
<participants-stub
- class="mb-4"
+ class="gl-mb-4"
numberoflessparticipants="7"
participants="[object Object]"
/>
<h2
- class="new-discussion-disclaimer gl-font-base m-0"
+ class="new-discussion-disclaimer gl-font-base gl-m-0 gl-mb-4"
+ data-testid="new-discussion-disclaimer"
>
- Click the image where you'd like to start a new discussion
-
+ Click the image where you'd like to start a new discussion
+
</h2>
+
+ <!---->
+
</div>
</div>
`;
diff --git a/spec/frontend/design_management/pages/design/index_spec.js b/spec/frontend/design_management/pages/design/index_spec.js
index 17fdfb6c14f..430cf8722fe 100644
--- a/spec/frontend/design_management/pages/design/index_spec.js
+++ b/spec/frontend/design_management/pages/design/index_spec.js
@@ -4,11 +4,9 @@ import { GlAlert } from '@gitlab/ui';
import { ApolloMutation } from 'vue-apollo';
import createFlash from '~/flash';
import DesignIndex from '~/design_management/pages/design/index.vue';
-import DesignDiscussion from '~/design_management/components/design_notes/design_discussion.vue';
+import DesignSidebar from '~/design_management/components/design_sidebar.vue';
import DesignReplyForm from '~/design_management/components/design_notes/design_reply_form.vue';
-import Participants from '~/sidebar/components/participants/participants.vue';
import createImageDiffNoteMutation from '~/design_management/graphql/mutations/createImageDiffNote.mutation.graphql';
-import updateActiveDiscussionMutation from '~/design_management/graphql/mutations/update_active_discussion.mutation.graphql';
import design from '../../mock_data/design';
import mockResponseWithDesigns from '../../mock_data/designs';
import mockResponseNoDesigns from '../../mock_data/no_designs';
@@ -62,20 +60,10 @@ describe('Design management design index page', () => {
},
};
- const updateActiveDiscussionMutationVariables = {
- mutation: updateActiveDiscussionMutation,
- variables: {
- id: design.discussions.nodes[0].notes.nodes[0].id,
- source: 'discussion',
- },
- };
-
const mutate = jest.fn().mockResolvedValue();
- const findDiscussions = () => wrapper.findAll(DesignDiscussion);
const findDiscussionForm = () => wrapper.find(DesignReplyForm);
- const findParticipants = () => wrapper.find(Participants);
- const findDiscussionsWrapper = () => wrapper.find('.image-notes');
+ const findSidebar = () => wrapper.find(DesignSidebar);
function createComponent(loading = false, data = {}) {
const $apollo = {
@@ -94,7 +82,7 @@ describe('Design management design index page', () => {
mocks: { $apollo },
stubs: {
ApolloMutation,
- DesignDiscussion,
+ DesignSidebar,
},
data() {
return {
@@ -145,63 +133,13 @@ describe('Design management design index page', () => {
expect(wrapper.find(GlAlert).exists()).toBe(false);
});
- it('renders participants', () => {
+ it('passes correct props to sidebar component', () => {
createComponent(false, { design });
- expect(findParticipants().exists()).toBe(true);
- });
-
- it('passes the correct amount of participants to the Participants component', () => {
- createComponent(false, { design });
-
- expect(findParticipants().props('participants')).toHaveLength(1);
- });
-
- describe('when has no discussions', () => {
- beforeEach(() => {
- createComponent(false, {
- design: {
- ...design,
- discussions: {
- nodes: [],
- },
- },
- });
- });
-
- it('does not render discussions', () => {
- expect(findDiscussions().exists()).toBe(false);
- });
-
- it('renders a message about possibility to create a new discussion', () => {
- expect(wrapper.find('.new-discussion-disclaimer').exists()).toBe(true);
- });
- });
-
- describe('when has discussions', () => {
- beforeEach(() => {
- createComponent(false, { design });
- });
-
- it('renders correct amount of discussions', () => {
- expect(findDiscussions()).toHaveLength(1);
- });
-
- it('sends a mutation to set an active discussion when clicking on a discussion', () => {
- findDiscussions()
- .at(0)
- .trigger('click');
-
- expect(mutate).toHaveBeenCalledWith(updateActiveDiscussionMutationVariables);
- });
-
- it('sends a mutation to reset an active discussion when clicking outside of discussion', () => {
- findDiscussionsWrapper().trigger('click');
-
- expect(mutate).toHaveBeenCalledWith({
- ...updateActiveDiscussionMutationVariables,
- variables: { id: undefined, source: 'discussion' },
- });
+ expect(findSidebar().props()).toEqual({
+ design,
+ markdownPreviewPath: '//preview_markdown?target_type=Issue',
+ resolvedDiscussionsExpanded: false,
});
});
diff --git a/spec/frontend/design_management/utils/design_management_utils_spec.js b/spec/frontend/design_management/utils/design_management_utils_spec.js
index af631073df6..478ebadc8f6 100644
--- a/spec/frontend/design_management/utils/design_management_utils_spec.js
+++ b/spec/frontend/design_management/utils/design_management_utils_spec.js
@@ -53,10 +53,10 @@ describe('extractDiscussions', () => {
it('discards the edges.node artifacts of GraphQL', () => {
expect(extractDiscussions(discussions)).toEqual([
- { id: 1, notes: ['a'] },
- { id: 2, notes: ['b'] },
- { id: 3, notes: ['c'] },
- { id: 4, notes: ['d'] },
+ { id: 1, notes: ['a'], index: 1 },
+ { id: 2, notes: ['b'], index: 2 },
+ { id: 3, notes: ['c'], index: 3 },
+ { id: 4, notes: ['d'], index: 4 },
]);
});
});
diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb
index dad740d3b80..3ef6745958c 100644
--- a/spec/helpers/issues_helper_spec.rb
+++ b/spec/helpers/issues_helper_spec.rb
@@ -7,59 +7,6 @@ describe IssuesHelper do
let(:issue) { create :issue, project: project }
let(:ext_project) { create :redmine_project }
- describe "url_for_issue" do
- let(:issues_url) { ext_project.external_issue_tracker.issues_url}
- let(:ext_expected) { issues_url.gsub(':id', issue.iid.to_s).gsub(':project_id', ext_project.id.to_s) }
- let(:int_expected) { polymorphic_path([@project.namespace, @project, issue]) }
-
- it "returns internal path if used internal tracker" do
- @project = project
-
- expect(url_for_issue(issue.iid)).to match(int_expected)
- end
-
- it "returns path to external tracker" do
- @project = ext_project
-
- expect(url_for_issue(issue.iid)).to match(ext_expected)
- end
-
- it "returns path to internal issue when internal option passed" do
- @project = ext_project
-
- expect(url_for_issue(issue.iid, ext_project, internal: true)).to match(int_expected)
- end
-
- it "returns empty string if project nil" do
- @project = nil
-
- expect(url_for_issue(issue.iid)).to eq ""
- end
-
- it 'returns an empty string if issue_url is invalid' do
- expect(project).to receive_message_chain('issues_tracker.issue_url') { 'javascript:alert("foo");' }
-
- expect(url_for_issue(issue.iid, project)).to eq ''
- end
-
- it 'returns an empty string if issue_path is invalid' do
- expect(project).to receive_message_chain('issues_tracker.issue_path') { 'javascript:alert("foo");' }
-
- expect(url_for_issue(issue.iid, project, only_path: true)).to eq ''
- end
-
- describe "when external tracker was enabled and then config removed" do
- before do
- @project = ext_project
- allow(Gitlab.config).to receive(:issues_tracker).and_return(nil)
- end
-
- it "returns external path" do
- expect(url_for_issue(issue.iid)).to match(ext_expected)
- end
- end
- end
-
describe '#award_user_list' do
it "returns a comma-separated list of the first X users" do
user = build_stubbed(:user, name: 'Joe')
diff --git a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb
index 78795a157f8..502ab07baa9 100644
--- a/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/external_issue_reference_filter_spec.rb
@@ -5,10 +5,6 @@ require 'spec_helper'
describe Banzai::Filter::ExternalIssueReferenceFilter do
include FilterSpecHelper
- def helper
- IssuesHelper
- end
-
shared_examples_for "external issue tracker" do
it_behaves_like 'a reference containing an element node'
@@ -36,7 +32,7 @@ describe Banzai::Filter::ExternalIssueReferenceFilter do
issue_id = doc.css('a').first.attr("data-external-issue")
expect(doc.css('a').first.attr('href'))
- .to eq helper.url_for_issue(issue_id, project)
+ .to eq project.external_issue_tracker.issue_url(issue_id)
end
it 'links to the external tracker' do
@@ -45,7 +41,7 @@ describe Banzai::Filter::ExternalIssueReferenceFilter do
link = doc.css('a').first.attr('href')
issue_id = doc.css('a').first.attr("data-external-issue")
- expect(link).to eq(helper.url_for_issue(issue_id, project))
+ expect(link).to eq(project.external_issue_tracker.issue_url(issue_id))
end
it 'links with adjacent text' do
@@ -78,7 +74,25 @@ describe Banzai::Filter::ExternalIssueReferenceFilter do
link = doc.css('a').first.attr('href')
issue_id = doc.css('a').first["data-external-issue"]
- expect(link).to eq helper.url_for_issue(issue_id, project, only_path: true)
+ expect(link).to eq project.external_issue_tracker.issue_path(issue_id)
+ end
+
+ it 'has an empty link if issue_url is invalid' do
+ expect_any_instance_of(project.external_issue_tracker.class).to receive(:issue_url) { 'javascript:alert("foo");' }
+
+ doc = filter("Issue #{reference}")
+ link = doc.css('a').first.attr('href')
+
+ expect(link).to eq ''
+ end
+
+ it 'has an empty link if issue_path is invalid' do
+ expect_any_instance_of(project.external_issue_tracker.class).to receive(:issue_path) { 'javascript:alert("foo");' }
+
+ doc = filter("Issue #{reference}", only_path: true)
+ link = doc.css('a').first.attr('href')
+
+ expect(link).to eq ''
end
context 'with RequestStore enabled', :request_store do
diff --git a/spec/lib/banzai/filter/issue_reference_filter_spec.rb b/spec/lib/banzai/filter/issue_reference_filter_spec.rb
index 0f0d4af55ea..603da2b4421 100644
--- a/spec/lib/banzai/filter/issue_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/issue_reference_filter_spec.rb
@@ -11,7 +11,9 @@ describe Banzai::Filter::IssueReferenceFilter do
end
let(:project) { create(:project, :public) }
- let(:issue) { create(:issue, project: project) }
+ let(:issue) { create(:issue, project: project) }
+ let(:issue_path) { "/#{issue.project.namespace.path}/#{issue.project.path}/-/issues/#{issue.iid}" }
+ let(:issue_url) { "http://#{Gitlab.config.gitlab.host}#{issue_path}" }
it 'requires project context' do
expect { described_class.call('') }.to raise_error(ArgumentError, /:project/)
@@ -46,7 +48,7 @@ describe Banzai::Filter::IssueReferenceFilter do
doc = reference_filter("Fixed #{reference}")
expect(doc.css('a').first.attr('href'))
- .to eq helper.url_for_issue(issue.iid, project)
+ .to eq issue_url
end
it 'links with adjacent text' do
@@ -113,7 +115,7 @@ describe Banzai::Filter::IssueReferenceFilter do
link = doc.css('a').first.attr('href')
expect(link).not_to match %r(https?://)
- expect(link).to eq helper.url_for_issue(issue.iid, project, only_path: true)
+ expect(link).to eq issue_path
end
it 'does not process links containing issue numbers followed by text' do
@@ -145,7 +147,7 @@ describe Banzai::Filter::IssueReferenceFilter do
doc = reference_filter("See #{reference}")
expect(doc.css('a').first.attr('href'))
- .to eq helper.url_for_issue(issue.iid, project2)
+ .to eq issue_url
end
it 'link has valid text' do
@@ -195,7 +197,7 @@ describe Banzai::Filter::IssueReferenceFilter do
doc = reference_filter("See #{reference}")
expect(doc.css('a').first.attr('href'))
- .to eq helper.url_for_issue(issue.iid, project2)
+ .to eq issue_url
end
it 'link has valid text' do
@@ -245,7 +247,7 @@ describe Banzai::Filter::IssueReferenceFilter do
doc = reference_filter("See #{reference}")
expect(doc.css('a').first.attr('href'))
- .to eq helper.url_for_issue(issue.iid, project2)
+ .to eq issue_url
end
it 'link has valid text' do
@@ -279,7 +281,7 @@ describe Banzai::Filter::IssueReferenceFilter do
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:project, :public, namespace: namespace) }
let(:issue) { create(:issue, project: project2) }
- let(:reference) { helper.url_for_issue(issue.iid, project2) + "#note_123" }
+ let(:reference) { issue_url + "#note_123" }
it 'links to a valid reference' do
doc = reference_filter("See #{reference}")
@@ -314,7 +316,7 @@ describe Banzai::Filter::IssueReferenceFilter do
doc = reference_filter("See #{reference_link}")
expect(doc.css('a').first.attr('href'))
- .to eq helper.url_for_issue(issue.iid, project2)
+ .to eq issue_url
end
it 'links with adjacent text' do
@@ -336,14 +338,14 @@ describe Banzai::Filter::IssueReferenceFilter do
let(:namespace) { create(:namespace, name: 'cross-reference') }
let(:project2) { create(:project, :public, namespace: namespace) }
let(:issue) { create(:issue, project: project2) }
- let(:reference) { "#{helper.url_for_issue(issue.iid, project2) + "#note_123"}" }
+ let(:reference) { "#{issue_url + "#note_123"}" }
let(:reference_link) { %{<a href="#{reference}">Reference</a>} }
it 'links to a valid reference' do
doc = reference_filter("See #{reference_link}")
expect(doc.css('a').first.attr('href'))
- .to eq helper.url_for_issue(issue.iid, project2) + "#note_123"
+ .to eq issue_url + "#note_123"
end
it 'links with adjacent text' do
@@ -413,7 +415,7 @@ describe Banzai::Filter::IssueReferenceFilter do
doc = reference_filter("See #{reference}", context)
link = doc.css('a').first
- expect(link.attr('href')).to eq(helper.url_for_issue(issue.iid, project))
+ expect(link.attr('href')).to eq(issue_url)
expect(link.text).to include("#{project.full_path}##{issue.iid}")
end
@@ -425,23 +427,23 @@ describe Banzai::Filter::IssueReferenceFilter do
end
it 'links to a valid reference for url cross-reference' do
- reference = helper.url_for_issue(issue.iid, project) + "#note_123"
+ reference = issue_url + "#note_123"
doc = reference_filter("See #{reference}", context)
link = doc.css('a').first
- expect(link.attr('href')).to eq(helper.url_for_issue(issue.iid, project) + "#note_123")
+ expect(link.attr('href')).to eq(issue_url + "#note_123")
expect(link.text).to include("#{project.full_path}##{issue.iid}")
end
it 'links to a valid reference for cross-reference in link href' do
- reference = "#{helper.url_for_issue(issue.iid, project) + "#note_123"}"
+ reference = "#{issue_url + "#note_123"}"
reference_link = %{<a href="#{reference}">Reference</a>}
doc = reference_filter("See #{reference_link}", context)
link = doc.css('a').first
- expect(link.attr('href')).to eq(helper.url_for_issue(issue.iid, project) + "#note_123")
+ expect(link.attr('href')).to eq(issue_url + "#note_123")
expect(link.text).to include('Reference')
end
@@ -451,7 +453,7 @@ describe Banzai::Filter::IssueReferenceFilter do
doc = reference_filter("See #{reference_link}", context)
link = doc.css('a').first
- expect(link.attr('href')).to eq(helper.url_for_issue(issue.iid, project))
+ expect(link.attr('href')).to eq(issue_url)
expect(link.text).to include('Reference')
end
end
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index 0e2234d7299..053b5c3a793 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -5,6 +5,7 @@ require 'spec_helper'
describe ProjectPolicy do
include ExternalAuthorizationServiceHelpers
include_context 'ProjectPolicy context'
+ let_it_be(:other_user) { create(:user) }
let_it_be(:guest) { create(:user) }
let_it_be(:reporter) { create(:user) }
let_it_be(:developer) { create(:user) }
@@ -163,7 +164,7 @@ describe ProjectPolicy do
subject { described_class.new(owner, project) }
it 'disallows all permissions when the feature is disabled' do
- project.project_feature.update(merge_requests_access_level: ProjectFeature::DISABLED)
+ project.project_feature.update!(merge_requests_access_level: ProjectFeature::DISABLED)
mr_permissions = [:create_merge_request_from, :read_merge_request,
:update_merge_request, :admin_merge_request,
@@ -215,7 +216,7 @@ describe ProjectPolicy do
subject { described_class.new(owner, project) }
before do
- project.project_feature.update(builds_access_level: ProjectFeature::DISABLED)
+ project.project_feature.update!(builds_access_level: ProjectFeature::DISABLED)
end
it 'disallows all permissions except pipeline when the feature is disabled' do
@@ -235,7 +236,7 @@ describe ProjectPolicy do
subject { described_class.new(guest, project) }
before do
- project.project_feature.update(builds_access_level: ProjectFeature::PRIVATE)
+ project.project_feature.update!(builds_access_level: ProjectFeature::PRIVATE)
end
it 'disallows pipeline and commit_status permissions' do
@@ -250,22 +251,54 @@ describe ProjectPolicy do
end
context 'repository feature' do
- subject { described_class.new(owner, project) }
-
- it 'disallows all permissions when the feature is disabled' do
- project.project_feature.update(repository_access_level: ProjectFeature::DISABLED)
-
- repository_permissions = [
+ let(:repository_permissions) do
+ [
:create_pipeline, :update_pipeline, :admin_pipeline, :destroy_pipeline,
:create_build, :read_build, :update_build, :admin_build, :destroy_build,
:create_pipeline_schedule, :read_pipeline_schedule, :update_pipeline_schedule, :admin_pipeline_schedule, :destroy_pipeline_schedule,
:create_environment, :read_environment, :update_environment, :admin_environment, :destroy_environment,
:create_cluster, :read_cluster, :update_cluster, :admin_cluster,
:create_deployment, :read_deployment, :update_deployment, :admin_deployment, :destroy_deployment,
- :destroy_release
+ :destroy_release, :download_code, :build_download_code
]
+ end
+
+ context 'when user is a project member' do
+ subject { described_class.new(owner, project) }
+
+ context 'when it is disabled' do
+ before do
+ project.project_feature.update!(
+ repository_access_level: ProjectFeature::DISABLED,
+ merge_requests_access_level: ProjectFeature::DISABLED,
+ builds_access_level: ProjectFeature::DISABLED,
+ forking_access_level: ProjectFeature::DISABLED
+ )
+ end
- expect_disallowed(*repository_permissions)
+ it 'disallows all permissions' do
+ expect_disallowed(*repository_permissions)
+ end
+ end
+ end
+
+ context 'when user is some other user' do
+ subject { described_class.new(other_user, project) }
+
+ context 'when access level is private' do
+ before do
+ project.project_feature.update!(
+ repository_access_level: ProjectFeature::PRIVATE,
+ merge_requests_access_level: ProjectFeature::PRIVATE,
+ builds_access_level: ProjectFeature::PRIVATE,
+ forking_access_level: ProjectFeature::PRIVATE
+ )
+ end
+
+ it 'disallows all permissions' do
+ expect_disallowed(*repository_permissions)
+ end
+ end
end
end
@@ -547,7 +580,7 @@ describe ProjectPolicy do
context 'feature enabled' do
before do
- project.project_feature.update(metrics_dashboard_access_level: ProjectFeature::ENABLED)
+ project.project_feature.update!(metrics_dashboard_access_level: ProjectFeature::ENABLED)
end
context 'with reporter' do
@@ -611,7 +644,7 @@ describe ProjectPolicy do
context 'feature enabled' do
before do
- project.project_feature.update(metrics_dashboard_access_level: ProjectFeature::ENABLED)
+ project.project_feature.update!(metrics_dashboard_access_level: ProjectFeature::ENABLED)
end
context 'with reporter' do
@@ -696,7 +729,7 @@ describe ProjectPolicy do
context 'feature disabled' do
before do
- project.project_feature.update(metrics_dashboard_access_level: ProjectFeature::DISABLED)
+ project.project_feature.update!(metrics_dashboard_access_level: ProjectFeature::DISABLED)
end
context 'with reporter' do
diff --git a/spec/requests/api/markdown_spec.rb b/spec/requests/api/markdown_spec.rb
index 09342b06744..53e43430b1f 100644
--- a/spec/requests/api/markdown_spec.rb
+++ b/spec/requests/api/markdown_spec.rb
@@ -52,6 +52,7 @@ describe API::Markdown do
context "when arguments are valid" do
let_it_be(:project) { create(:project) }
let_it_be(:issue) { create(:issue, project: project) }
+ let(:issue_url) { "http://#{Gitlab.config.gitlab.host}/#{issue.project.namespace.path}/#{issue.project.path}/-/issues/#{issue.iid}" }
let(:text) { ":tada: Hello world! :100: #{issue.to_reference}" }
context "when not using gfm" do
@@ -88,7 +89,7 @@ describe API::Markdown do
.and include('data-name="tada"')
.and include('data-name="100"')
.and include("#1")
- .and exclude("<a href=\"#{IssuesHelper.url_for_issue(issue.iid, project)}\"")
+ .and exclude("<a href=\"#{issue_url}\"")
.and exclude("#1</a>")
end
end
@@ -104,16 +105,16 @@ describe API::Markdown do
expect(json_response["html"]).to include("Hello world!")
.and include('data-name="tada"')
.and include('data-name="100"')
- .and include("<a href=\"#{IssuesHelper.url_for_issue(issue.iid, project)}\"")
+ .and include("<a href=\"#{issue_url}\"")
.and include("#1</a>")
end
end
context 'with a public project and confidential issue' do
- let(:public_project) { create(:project, :public) }
- let(:confidential_issue) { create(:issue, :confidential, project: public_project, title: 'Confidential title') }
+ let(:public_project) { create(:project, :public) }
+ let(:issue) { create(:issue, :confidential, project: public_project, title: 'Confidential title') }
- let(:text) { ":tada: Hello world! :100: #{confidential_issue.to_reference}" }
+ let(:text) { ":tada: Hello world! :100: #{issue.to_reference}" }
let(:params) { { text: text, gfm: true, project: public_project.full_path } }
shared_examples 'user without proper access' do
@@ -141,7 +142,7 @@ describe API::Markdown do
end
context 'when logged in as author' do
- let(:user) { confidential_issue.author }
+ let(:user) { issue.author }
it 'renders the title or link' do
expect(response).to have_gitlab_http_status(:created)
@@ -149,7 +150,7 @@ describe API::Markdown do
expect(json_response["html"]).to include('Hello world!')
.and include('data-name="tada"')
.and include('data-name="100"')
- .and include("<a href=\"#{IssuesHelper.url_for_issue(confidential_issue.iid, public_project)}\"")
+ .and include("<a href=\"#{issue_url}\"")
.and include("#1</a>")
end
end